1*61890ccaSMoudy Ho // SPDX-License-Identifier: GPL-2.0-only 2*61890ccaSMoudy Ho /* 3*61890ccaSMoudy Ho * Copyright (c) 2022 MediaTek Inc. 4*61890ccaSMoudy Ho * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com> 5*61890ccaSMoudy Ho */ 6*61890ccaSMoudy Ho 7*61890ccaSMoudy Ho #include <media/v4l2-common.h> 8*61890ccaSMoudy Ho #include <media/videobuf2-v4l2.h> 9*61890ccaSMoudy Ho #include <media/videobuf2-dma-contig.h> 10*61890ccaSMoudy Ho #include "mtk-mdp3-core.h" 11*61890ccaSMoudy Ho #include "mtk-mdp3-regs.h" 12*61890ccaSMoudy Ho #include "mtk-mdp3-m2m.h" 13*61890ccaSMoudy Ho 14*61890ccaSMoudy Ho /* 15*61890ccaSMoudy Ho * All 10-bit related formats are not added in the basic format list, 16*61890ccaSMoudy Ho * please add the corresponding format settings before use. 17*61890ccaSMoudy Ho */ 18*61890ccaSMoudy Ho static const struct mdp_format mdp_formats[] = { 19*61890ccaSMoudy Ho { 20*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_GREY, 21*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_GREY, 22*61890ccaSMoudy Ho .depth = { 8 }, 23*61890ccaSMoudy Ho .row_depth = { 8 }, 24*61890ccaSMoudy Ho .num_planes = 1, 25*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, 26*61890ccaSMoudy Ho }, { 27*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_RGB565X, 28*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_BGR565, 29*61890ccaSMoudy Ho .depth = { 16 }, 30*61890ccaSMoudy Ho .row_depth = { 16 }, 31*61890ccaSMoudy Ho .num_planes = 1, 32*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, 33*61890ccaSMoudy Ho }, { 34*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_RGB565, 35*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_RGB565, 36*61890ccaSMoudy Ho .depth = { 16 }, 37*61890ccaSMoudy Ho .row_depth = { 16 }, 38*61890ccaSMoudy Ho .num_planes = 1, 39*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, 40*61890ccaSMoudy Ho }, { 41*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_RGB24, 42*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_RGB888, 43*61890ccaSMoudy Ho .depth = { 24 }, 44*61890ccaSMoudy Ho .row_depth = { 24 }, 45*61890ccaSMoudy Ho .num_planes = 1, 46*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, 47*61890ccaSMoudy Ho }, { 48*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_BGR24, 49*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_BGR888, 50*61890ccaSMoudy Ho .depth = { 24 }, 51*61890ccaSMoudy Ho .row_depth = { 24 }, 52*61890ccaSMoudy Ho .num_planes = 1, 53*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, 54*61890ccaSMoudy Ho }, { 55*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_ABGR32, 56*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_BGRA8888, 57*61890ccaSMoudy Ho .depth = { 32 }, 58*61890ccaSMoudy Ho .row_depth = { 32 }, 59*61890ccaSMoudy Ho .num_planes = 1, 60*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, 61*61890ccaSMoudy Ho }, { 62*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_ARGB32, 63*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_ARGB8888, 64*61890ccaSMoudy Ho .depth = { 32 }, 65*61890ccaSMoudy Ho .row_depth = { 32 }, 66*61890ccaSMoudy Ho .num_planes = 1, 67*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, 68*61890ccaSMoudy Ho }, { 69*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_UYVY, 70*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_UYVY, 71*61890ccaSMoudy Ho .depth = { 16 }, 72*61890ccaSMoudy Ho .row_depth = { 16 }, 73*61890ccaSMoudy Ho .num_planes = 1, 74*61890ccaSMoudy Ho .walign = 1, 75*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, 76*61890ccaSMoudy Ho }, { 77*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_VYUY, 78*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_VYUY, 79*61890ccaSMoudy Ho .depth = { 16 }, 80*61890ccaSMoudy Ho .row_depth = { 16 }, 81*61890ccaSMoudy Ho .num_planes = 1, 82*61890ccaSMoudy Ho .walign = 1, 83*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, 84*61890ccaSMoudy Ho }, { 85*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_YUYV, 86*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_YUYV, 87*61890ccaSMoudy Ho .depth = { 16 }, 88*61890ccaSMoudy Ho .row_depth = { 16 }, 89*61890ccaSMoudy Ho .num_planes = 1, 90*61890ccaSMoudy Ho .walign = 1, 91*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, 92*61890ccaSMoudy Ho }, { 93*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_YVYU, 94*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_YVYU, 95*61890ccaSMoudy Ho .depth = { 16 }, 96*61890ccaSMoudy Ho .row_depth = { 16 }, 97*61890ccaSMoudy Ho .num_planes = 1, 98*61890ccaSMoudy Ho .walign = 1, 99*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, 100*61890ccaSMoudy Ho }, { 101*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_YUV420, 102*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_I420, 103*61890ccaSMoudy Ho .depth = { 12 }, 104*61890ccaSMoudy Ho .row_depth = { 8 }, 105*61890ccaSMoudy Ho .num_planes = 1, 106*61890ccaSMoudy Ho .walign = 1, 107*61890ccaSMoudy Ho .halign = 1, 108*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, 109*61890ccaSMoudy Ho }, { 110*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_YVU420, 111*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_YV12, 112*61890ccaSMoudy Ho .depth = { 12 }, 113*61890ccaSMoudy Ho .row_depth = { 8 }, 114*61890ccaSMoudy Ho .num_planes = 1, 115*61890ccaSMoudy Ho .walign = 1, 116*61890ccaSMoudy Ho .halign = 1, 117*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, 118*61890ccaSMoudy Ho }, { 119*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_NV12, 120*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_NV12, 121*61890ccaSMoudy Ho .depth = { 12 }, 122*61890ccaSMoudy Ho .row_depth = { 8 }, 123*61890ccaSMoudy Ho .num_planes = 1, 124*61890ccaSMoudy Ho .walign = 1, 125*61890ccaSMoudy Ho .halign = 1, 126*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, 127*61890ccaSMoudy Ho }, { 128*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_NV21, 129*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_NV21, 130*61890ccaSMoudy Ho .depth = { 12 }, 131*61890ccaSMoudy Ho .row_depth = { 8 }, 132*61890ccaSMoudy Ho .num_planes = 1, 133*61890ccaSMoudy Ho .walign = 1, 134*61890ccaSMoudy Ho .halign = 1, 135*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, 136*61890ccaSMoudy Ho }, { 137*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_NV16, 138*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_NV16, 139*61890ccaSMoudy Ho .depth = { 16 }, 140*61890ccaSMoudy Ho .row_depth = { 8 }, 141*61890ccaSMoudy Ho .num_planes = 1, 142*61890ccaSMoudy Ho .walign = 1, 143*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT, 144*61890ccaSMoudy Ho }, { 145*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_NV61, 146*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_NV61, 147*61890ccaSMoudy Ho .depth = { 16 }, 148*61890ccaSMoudy Ho .row_depth = { 8 }, 149*61890ccaSMoudy Ho .num_planes = 1, 150*61890ccaSMoudy Ho .walign = 1, 151*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT, 152*61890ccaSMoudy Ho }, { 153*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_NV24, 154*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_NV24, 155*61890ccaSMoudy Ho .depth = { 24 }, 156*61890ccaSMoudy Ho .row_depth = { 8 }, 157*61890ccaSMoudy Ho .num_planes = 1, 158*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT, 159*61890ccaSMoudy Ho }, { 160*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_NV42, 161*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_NV42, 162*61890ccaSMoudy Ho .depth = { 24 }, 163*61890ccaSMoudy Ho .row_depth = { 8 }, 164*61890ccaSMoudy Ho .num_planes = 1, 165*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT, 166*61890ccaSMoudy Ho }, { 167*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_MT21C, 168*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_420_BLK_UFO, 169*61890ccaSMoudy Ho .depth = { 8, 4 }, 170*61890ccaSMoudy Ho .row_depth = { 8, 8 }, 171*61890ccaSMoudy Ho .num_planes = 2, 172*61890ccaSMoudy Ho .walign = 4, 173*61890ccaSMoudy Ho .halign = 5, 174*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT, 175*61890ccaSMoudy Ho }, { 176*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_MM21, 177*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_420_BLK, 178*61890ccaSMoudy Ho .depth = { 8, 4 }, 179*61890ccaSMoudy Ho .row_depth = { 8, 8 }, 180*61890ccaSMoudy Ho .num_planes = 2, 181*61890ccaSMoudy Ho .walign = 4, 182*61890ccaSMoudy Ho .halign = 5, 183*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT, 184*61890ccaSMoudy Ho }, { 185*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_NV12M, 186*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_NV12, 187*61890ccaSMoudy Ho .depth = { 8, 4 }, 188*61890ccaSMoudy Ho .row_depth = { 8, 8 }, 189*61890ccaSMoudy Ho .num_planes = 2, 190*61890ccaSMoudy Ho .walign = 1, 191*61890ccaSMoudy Ho .halign = 1, 192*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, 193*61890ccaSMoudy Ho }, { 194*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_NV21M, 195*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_NV21, 196*61890ccaSMoudy Ho .depth = { 8, 4 }, 197*61890ccaSMoudy Ho .row_depth = { 8, 8 }, 198*61890ccaSMoudy Ho .num_planes = 2, 199*61890ccaSMoudy Ho .walign = 1, 200*61890ccaSMoudy Ho .halign = 1, 201*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, 202*61890ccaSMoudy Ho }, { 203*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_NV16M, 204*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_NV16, 205*61890ccaSMoudy Ho .depth = { 8, 8 }, 206*61890ccaSMoudy Ho .row_depth = { 8, 8 }, 207*61890ccaSMoudy Ho .num_planes = 2, 208*61890ccaSMoudy Ho .walign = 1, 209*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT, 210*61890ccaSMoudy Ho }, { 211*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_NV61M, 212*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_NV61, 213*61890ccaSMoudy Ho .depth = { 8, 8 }, 214*61890ccaSMoudy Ho .row_depth = { 8, 8 }, 215*61890ccaSMoudy Ho .num_planes = 2, 216*61890ccaSMoudy Ho .walign = 1, 217*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT, 218*61890ccaSMoudy Ho }, { 219*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_YUV420M, 220*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_I420, 221*61890ccaSMoudy Ho .depth = { 8, 2, 2 }, 222*61890ccaSMoudy Ho .row_depth = { 8, 4, 4 }, 223*61890ccaSMoudy Ho .num_planes = 3, 224*61890ccaSMoudy Ho .walign = 1, 225*61890ccaSMoudy Ho .halign = 1, 226*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, 227*61890ccaSMoudy Ho }, { 228*61890ccaSMoudy Ho .pixelformat = V4L2_PIX_FMT_YVU420M, 229*61890ccaSMoudy Ho .mdp_color = MDP_COLOR_YV12, 230*61890ccaSMoudy Ho .depth = { 8, 2, 2 }, 231*61890ccaSMoudy Ho .row_depth = { 8, 4, 4 }, 232*61890ccaSMoudy Ho .num_planes = 3, 233*61890ccaSMoudy Ho .walign = 1, 234*61890ccaSMoudy Ho .halign = 1, 235*61890ccaSMoudy Ho .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, 236*61890ccaSMoudy Ho } 237*61890ccaSMoudy Ho }; 238*61890ccaSMoudy Ho 239*61890ccaSMoudy Ho static const struct mdp_limit mdp_def_limit = { 240*61890ccaSMoudy Ho .out_limit = { 241*61890ccaSMoudy Ho .wmin = 16, 242*61890ccaSMoudy Ho .hmin = 16, 243*61890ccaSMoudy Ho .wmax = 8176, 244*61890ccaSMoudy Ho .hmax = 8176, 245*61890ccaSMoudy Ho }, 246*61890ccaSMoudy Ho .cap_limit = { 247*61890ccaSMoudy Ho .wmin = 2, 248*61890ccaSMoudy Ho .hmin = 2, 249*61890ccaSMoudy Ho .wmax = 8176, 250*61890ccaSMoudy Ho .hmax = 8176, 251*61890ccaSMoudy Ho }, 252*61890ccaSMoudy Ho .h_scale_up_max = 32, 253*61890ccaSMoudy Ho .v_scale_up_max = 32, 254*61890ccaSMoudy Ho .h_scale_down_max = 20, 255*61890ccaSMoudy Ho .v_scale_down_max = 128, 256*61890ccaSMoudy Ho }; 257*61890ccaSMoudy Ho 258*61890ccaSMoudy Ho static const struct mdp_format *mdp_find_fmt(u32 pixelformat, u32 type) 259*61890ccaSMoudy Ho { 260*61890ccaSMoudy Ho u32 i, flag; 261*61890ccaSMoudy Ho 262*61890ccaSMoudy Ho flag = V4L2_TYPE_IS_OUTPUT(type) ? MDP_FMT_FLAG_OUTPUT : 263*61890ccaSMoudy Ho MDP_FMT_FLAG_CAPTURE; 264*61890ccaSMoudy Ho for (i = 0; i < ARRAY_SIZE(mdp_formats); ++i) { 265*61890ccaSMoudy Ho if (!(mdp_formats[i].flags & flag)) 266*61890ccaSMoudy Ho continue; 267*61890ccaSMoudy Ho if (mdp_formats[i].pixelformat == pixelformat) 268*61890ccaSMoudy Ho return &mdp_formats[i]; 269*61890ccaSMoudy Ho } 270*61890ccaSMoudy Ho return NULL; 271*61890ccaSMoudy Ho } 272*61890ccaSMoudy Ho 273*61890ccaSMoudy Ho static const struct mdp_format *mdp_find_fmt_by_index(u32 index, u32 type) 274*61890ccaSMoudy Ho { 275*61890ccaSMoudy Ho u32 i, flag, num = 0; 276*61890ccaSMoudy Ho 277*61890ccaSMoudy Ho flag = V4L2_TYPE_IS_OUTPUT(type) ? MDP_FMT_FLAG_OUTPUT : 278*61890ccaSMoudy Ho MDP_FMT_FLAG_CAPTURE; 279*61890ccaSMoudy Ho for (i = 0; i < ARRAY_SIZE(mdp_formats); ++i) { 280*61890ccaSMoudy Ho if (!(mdp_formats[i].flags & flag)) 281*61890ccaSMoudy Ho continue; 282*61890ccaSMoudy Ho if (index == num) 283*61890ccaSMoudy Ho return &mdp_formats[i]; 284*61890ccaSMoudy Ho num++; 285*61890ccaSMoudy Ho } 286*61890ccaSMoudy Ho return NULL; 287*61890ccaSMoudy Ho } 288*61890ccaSMoudy Ho 289*61890ccaSMoudy Ho enum mdp_ycbcr_profile mdp_map_ycbcr_prof_mplane(struct v4l2_format *f, 290*61890ccaSMoudy Ho u32 mdp_color) 291*61890ccaSMoudy Ho { 292*61890ccaSMoudy Ho struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; 293*61890ccaSMoudy Ho 294*61890ccaSMoudy Ho if (MDP_COLOR_IS_RGB(mdp_color)) 295*61890ccaSMoudy Ho return MDP_YCBCR_PROFILE_FULL_BT601; 296*61890ccaSMoudy Ho 297*61890ccaSMoudy Ho switch (pix_mp->colorspace) { 298*61890ccaSMoudy Ho case V4L2_COLORSPACE_JPEG: 299*61890ccaSMoudy Ho return MDP_YCBCR_PROFILE_JPEG; 300*61890ccaSMoudy Ho case V4L2_COLORSPACE_REC709: 301*61890ccaSMoudy Ho case V4L2_COLORSPACE_DCI_P3: 302*61890ccaSMoudy Ho if (pix_mp->quantization == V4L2_QUANTIZATION_FULL_RANGE) 303*61890ccaSMoudy Ho return MDP_YCBCR_PROFILE_FULL_BT709; 304*61890ccaSMoudy Ho return MDP_YCBCR_PROFILE_BT709; 305*61890ccaSMoudy Ho case V4L2_COLORSPACE_BT2020: 306*61890ccaSMoudy Ho if (pix_mp->quantization == V4L2_QUANTIZATION_FULL_RANGE) 307*61890ccaSMoudy Ho return MDP_YCBCR_PROFILE_FULL_BT2020; 308*61890ccaSMoudy Ho return MDP_YCBCR_PROFILE_BT2020; 309*61890ccaSMoudy Ho default: 310*61890ccaSMoudy Ho if (pix_mp->quantization == V4L2_QUANTIZATION_FULL_RANGE) 311*61890ccaSMoudy Ho return MDP_YCBCR_PROFILE_FULL_BT601; 312*61890ccaSMoudy Ho return MDP_YCBCR_PROFILE_BT601; 313*61890ccaSMoudy Ho } 314*61890ccaSMoudy Ho } 315*61890ccaSMoudy Ho 316*61890ccaSMoudy Ho static void mdp_bound_align_image(u32 *w, u32 *h, 317*61890ccaSMoudy Ho struct v4l2_frmsize_stepwise *s, 318*61890ccaSMoudy Ho unsigned int salign) 319*61890ccaSMoudy Ho { 320*61890ccaSMoudy Ho unsigned int org_w, org_h; 321*61890ccaSMoudy Ho 322*61890ccaSMoudy Ho org_w = *w; 323*61890ccaSMoudy Ho org_h = *h; 324*61890ccaSMoudy Ho v4l_bound_align_image(w, s->min_width, s->max_width, s->step_width, 325*61890ccaSMoudy Ho h, s->min_height, s->max_height, s->step_height, 326*61890ccaSMoudy Ho salign); 327*61890ccaSMoudy Ho 328*61890ccaSMoudy Ho s->min_width = org_w; 329*61890ccaSMoudy Ho s->min_height = org_h; 330*61890ccaSMoudy Ho v4l2_apply_frmsize_constraints(w, h, s); 331*61890ccaSMoudy Ho } 332*61890ccaSMoudy Ho 333*61890ccaSMoudy Ho static int mdp_clamp_align(s32 *x, int min, int max, unsigned int align) 334*61890ccaSMoudy Ho { 335*61890ccaSMoudy Ho unsigned int mask; 336*61890ccaSMoudy Ho 337*61890ccaSMoudy Ho if (min < 0 || max < 0) 338*61890ccaSMoudy Ho return -ERANGE; 339*61890ccaSMoudy Ho 340*61890ccaSMoudy Ho /* Bits that must be zero to be aligned */ 341*61890ccaSMoudy Ho mask = ~((1 << align) - 1); 342*61890ccaSMoudy Ho 343*61890ccaSMoudy Ho min = 0 ? 0 : ((min + ~mask) & mask); 344*61890ccaSMoudy Ho max = max & mask; 345*61890ccaSMoudy Ho if ((unsigned int)min > (unsigned int)max) 346*61890ccaSMoudy Ho return -ERANGE; 347*61890ccaSMoudy Ho 348*61890ccaSMoudy Ho /* Clamp to aligned min and max */ 349*61890ccaSMoudy Ho *x = clamp(*x, min, max); 350*61890ccaSMoudy Ho 351*61890ccaSMoudy Ho /* Round to nearest aligned value */ 352*61890ccaSMoudy Ho if (align) 353*61890ccaSMoudy Ho *x = (*x + (1 << (align - 1))) & mask; 354*61890ccaSMoudy Ho return 0; 355*61890ccaSMoudy Ho } 356*61890ccaSMoudy Ho 357*61890ccaSMoudy Ho int mdp_enum_fmt_mplane(struct v4l2_fmtdesc *f) 358*61890ccaSMoudy Ho { 359*61890ccaSMoudy Ho const struct mdp_format *fmt; 360*61890ccaSMoudy Ho 361*61890ccaSMoudy Ho fmt = mdp_find_fmt_by_index(f->index, f->type); 362*61890ccaSMoudy Ho if (!fmt) 363*61890ccaSMoudy Ho return -EINVAL; 364*61890ccaSMoudy Ho 365*61890ccaSMoudy Ho f->pixelformat = fmt->pixelformat; 366*61890ccaSMoudy Ho return 0; 367*61890ccaSMoudy Ho } 368*61890ccaSMoudy Ho 369*61890ccaSMoudy Ho const struct mdp_format *mdp_try_fmt_mplane(struct v4l2_format *f, 370*61890ccaSMoudy Ho struct mdp_frameparam *param, 371*61890ccaSMoudy Ho u32 ctx_id) 372*61890ccaSMoudy Ho { 373*61890ccaSMoudy Ho struct device *dev = ¶m->ctx->mdp_dev->pdev->dev; 374*61890ccaSMoudy Ho struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; 375*61890ccaSMoudy Ho const struct mdp_format *fmt; 376*61890ccaSMoudy Ho const struct mdp_pix_limit *pix_limit; 377*61890ccaSMoudy Ho struct v4l2_frmsize_stepwise s; 378*61890ccaSMoudy Ho u32 org_w, org_h; 379*61890ccaSMoudy Ho unsigned int i; 380*61890ccaSMoudy Ho 381*61890ccaSMoudy Ho fmt = mdp_find_fmt(pix_mp->pixelformat, f->type); 382*61890ccaSMoudy Ho if (!fmt) { 383*61890ccaSMoudy Ho fmt = mdp_find_fmt_by_index(0, f->type); 384*61890ccaSMoudy Ho if (!fmt) { 385*61890ccaSMoudy Ho dev_dbg(dev, "%d: pixelformat %c%c%c%c invalid", ctx_id, 386*61890ccaSMoudy Ho (pix_mp->pixelformat & 0xff), 387*61890ccaSMoudy Ho (pix_mp->pixelformat >> 8) & 0xff, 388*61890ccaSMoudy Ho (pix_mp->pixelformat >> 16) & 0xff, 389*61890ccaSMoudy Ho (pix_mp->pixelformat >> 24) & 0xff); 390*61890ccaSMoudy Ho return NULL; 391*61890ccaSMoudy Ho } 392*61890ccaSMoudy Ho } 393*61890ccaSMoudy Ho 394*61890ccaSMoudy Ho pix_mp->field = V4L2_FIELD_NONE; 395*61890ccaSMoudy Ho pix_mp->flags = 0; 396*61890ccaSMoudy Ho pix_mp->pixelformat = fmt->pixelformat; 397*61890ccaSMoudy Ho if (V4L2_TYPE_IS_CAPTURE(f->type)) { 398*61890ccaSMoudy Ho pix_mp->colorspace = param->colorspace; 399*61890ccaSMoudy Ho pix_mp->xfer_func = param->xfer_func; 400*61890ccaSMoudy Ho pix_mp->ycbcr_enc = param->ycbcr_enc; 401*61890ccaSMoudy Ho pix_mp->quantization = param->quant; 402*61890ccaSMoudy Ho } 403*61890ccaSMoudy Ho 404*61890ccaSMoudy Ho pix_limit = V4L2_TYPE_IS_OUTPUT(f->type) ? ¶m->limit->out_limit : 405*61890ccaSMoudy Ho ¶m->limit->cap_limit; 406*61890ccaSMoudy Ho s.min_width = pix_limit->wmin; 407*61890ccaSMoudy Ho s.max_width = pix_limit->wmax; 408*61890ccaSMoudy Ho s.step_width = fmt->walign; 409*61890ccaSMoudy Ho s.min_height = pix_limit->hmin; 410*61890ccaSMoudy Ho s.max_height = pix_limit->hmax; 411*61890ccaSMoudy Ho s.step_height = fmt->halign; 412*61890ccaSMoudy Ho org_w = pix_mp->width; 413*61890ccaSMoudy Ho org_h = pix_mp->height; 414*61890ccaSMoudy Ho 415*61890ccaSMoudy Ho mdp_bound_align_image(&pix_mp->width, &pix_mp->height, &s, fmt->salign); 416*61890ccaSMoudy Ho if (org_w != pix_mp->width || org_h != pix_mp->height) 417*61890ccaSMoudy Ho dev_dbg(dev, "%d: size change: %ux%u to %ux%u", ctx_id, 418*61890ccaSMoudy Ho org_w, org_h, pix_mp->width, pix_mp->height); 419*61890ccaSMoudy Ho 420*61890ccaSMoudy Ho if (pix_mp->num_planes && pix_mp->num_planes != fmt->num_planes) 421*61890ccaSMoudy Ho dev_dbg(dev, "%d num of planes change: %u to %u", ctx_id, 422*61890ccaSMoudy Ho pix_mp->num_planes, fmt->num_planes); 423*61890ccaSMoudy Ho pix_mp->num_planes = fmt->num_planes; 424*61890ccaSMoudy Ho 425*61890ccaSMoudy Ho for (i = 0; i < pix_mp->num_planes; ++i) { 426*61890ccaSMoudy Ho u32 min_bpl = (pix_mp->width * fmt->row_depth[i]) >> 3; 427*61890ccaSMoudy Ho u32 max_bpl = (pix_limit->wmax * fmt->row_depth[i]) >> 3; 428*61890ccaSMoudy Ho u32 bpl = pix_mp->plane_fmt[i].bytesperline; 429*61890ccaSMoudy Ho u32 min_si, max_si; 430*61890ccaSMoudy Ho u32 si = pix_mp->plane_fmt[i].sizeimage; 431*61890ccaSMoudy Ho 432*61890ccaSMoudy Ho bpl = clamp(bpl, min_bpl, max_bpl); 433*61890ccaSMoudy Ho pix_mp->plane_fmt[i].bytesperline = bpl; 434*61890ccaSMoudy Ho 435*61890ccaSMoudy Ho min_si = (bpl * pix_mp->height * fmt->depth[i]) / 436*61890ccaSMoudy Ho fmt->row_depth[i]; 437*61890ccaSMoudy Ho max_si = (bpl * s.max_height * fmt->depth[i]) / 438*61890ccaSMoudy Ho fmt->row_depth[i]; 439*61890ccaSMoudy Ho 440*61890ccaSMoudy Ho si = clamp(si, min_si, max_si); 441*61890ccaSMoudy Ho pix_mp->plane_fmt[i].sizeimage = si; 442*61890ccaSMoudy Ho 443*61890ccaSMoudy Ho dev_dbg(dev, "%d: p%u, bpl:%u [%u, %u], sizeimage:%u [%u, %u]", 444*61890ccaSMoudy Ho ctx_id, i, bpl, min_bpl, max_bpl, si, min_si, max_si); 445*61890ccaSMoudy Ho } 446*61890ccaSMoudy Ho 447*61890ccaSMoudy Ho return fmt; 448*61890ccaSMoudy Ho } 449*61890ccaSMoudy Ho 450*61890ccaSMoudy Ho static int mdp_clamp_start(s32 *x, int min, int max, unsigned int align, 451*61890ccaSMoudy Ho u32 flags) 452*61890ccaSMoudy Ho { 453*61890ccaSMoudy Ho if (flags & V4L2_SEL_FLAG_GE) 454*61890ccaSMoudy Ho max = *x; 455*61890ccaSMoudy Ho if (flags & V4L2_SEL_FLAG_LE) 456*61890ccaSMoudy Ho min = *x; 457*61890ccaSMoudy Ho return mdp_clamp_align(x, min, max, align); 458*61890ccaSMoudy Ho } 459*61890ccaSMoudy Ho 460*61890ccaSMoudy Ho static int mdp_clamp_end(s32 *x, int min, int max, unsigned int align, 461*61890ccaSMoudy Ho u32 flags) 462*61890ccaSMoudy Ho { 463*61890ccaSMoudy Ho if (flags & V4L2_SEL_FLAG_GE) 464*61890ccaSMoudy Ho min = *x; 465*61890ccaSMoudy Ho if (flags & V4L2_SEL_FLAG_LE) 466*61890ccaSMoudy Ho max = *x; 467*61890ccaSMoudy Ho return mdp_clamp_align(x, min, max, align); 468*61890ccaSMoudy Ho } 469*61890ccaSMoudy Ho 470*61890ccaSMoudy Ho int mdp_try_crop(struct mdp_m2m_ctx *ctx, struct v4l2_rect *r, 471*61890ccaSMoudy Ho const struct v4l2_selection *s, struct mdp_frame *frame) 472*61890ccaSMoudy Ho { 473*61890ccaSMoudy Ho struct device *dev = &ctx->mdp_dev->pdev->dev; 474*61890ccaSMoudy Ho s32 left, top, right, bottom; 475*61890ccaSMoudy Ho u32 framew, frameh, walign, halign; 476*61890ccaSMoudy Ho int ret; 477*61890ccaSMoudy Ho 478*61890ccaSMoudy Ho dev_dbg(dev, "%d target:%d, set:(%d,%d) %ux%u", ctx->id, 479*61890ccaSMoudy Ho s->target, s->r.left, s->r.top, s->r.width, s->r.height); 480*61890ccaSMoudy Ho 481*61890ccaSMoudy Ho left = s->r.left; 482*61890ccaSMoudy Ho top = s->r.top; 483*61890ccaSMoudy Ho right = s->r.left + s->r.width; 484*61890ccaSMoudy Ho bottom = s->r.top + s->r.height; 485*61890ccaSMoudy Ho framew = frame->format.fmt.pix_mp.width; 486*61890ccaSMoudy Ho frameh = frame->format.fmt.pix_mp.height; 487*61890ccaSMoudy Ho 488*61890ccaSMoudy Ho if (mdp_target_is_crop(s->target)) { 489*61890ccaSMoudy Ho walign = 1; 490*61890ccaSMoudy Ho halign = 1; 491*61890ccaSMoudy Ho } else { 492*61890ccaSMoudy Ho walign = frame->mdp_fmt->walign; 493*61890ccaSMoudy Ho halign = frame->mdp_fmt->halign; 494*61890ccaSMoudy Ho } 495*61890ccaSMoudy Ho 496*61890ccaSMoudy Ho dev_dbg(dev, "%d align:%u,%u, bound:%ux%u", ctx->id, 497*61890ccaSMoudy Ho walign, halign, framew, frameh); 498*61890ccaSMoudy Ho 499*61890ccaSMoudy Ho ret = mdp_clamp_start(&left, 0, right, walign, s->flags); 500*61890ccaSMoudy Ho if (ret) 501*61890ccaSMoudy Ho return ret; 502*61890ccaSMoudy Ho ret = mdp_clamp_start(&top, 0, bottom, halign, s->flags); 503*61890ccaSMoudy Ho if (ret) 504*61890ccaSMoudy Ho return ret; 505*61890ccaSMoudy Ho ret = mdp_clamp_end(&right, left, framew, walign, s->flags); 506*61890ccaSMoudy Ho if (ret) 507*61890ccaSMoudy Ho return ret; 508*61890ccaSMoudy Ho ret = mdp_clamp_end(&bottom, top, frameh, halign, s->flags); 509*61890ccaSMoudy Ho if (ret) 510*61890ccaSMoudy Ho return ret; 511*61890ccaSMoudy Ho 512*61890ccaSMoudy Ho r->left = left; 513*61890ccaSMoudy Ho r->top = top; 514*61890ccaSMoudy Ho r->width = right - left; 515*61890ccaSMoudy Ho r->height = bottom - top; 516*61890ccaSMoudy Ho 517*61890ccaSMoudy Ho dev_dbg(dev, "%d crop:(%d,%d) %ux%u", ctx->id, 518*61890ccaSMoudy Ho r->left, r->top, r->width, r->height); 519*61890ccaSMoudy Ho return 0; 520*61890ccaSMoudy Ho } 521*61890ccaSMoudy Ho 522*61890ccaSMoudy Ho int mdp_check_scaling_ratio(const struct v4l2_rect *crop, 523*61890ccaSMoudy Ho const struct v4l2_rect *compose, s32 rotation, 524*61890ccaSMoudy Ho const struct mdp_limit *limit) 525*61890ccaSMoudy Ho { 526*61890ccaSMoudy Ho u32 crop_w, crop_h, comp_w, comp_h; 527*61890ccaSMoudy Ho 528*61890ccaSMoudy Ho crop_w = crop->width; 529*61890ccaSMoudy Ho crop_h = crop->height; 530*61890ccaSMoudy Ho if (90 == rotation || 270 == rotation) { 531*61890ccaSMoudy Ho comp_w = compose->height; 532*61890ccaSMoudy Ho comp_h = compose->width; 533*61890ccaSMoudy Ho } else { 534*61890ccaSMoudy Ho comp_w = compose->width; 535*61890ccaSMoudy Ho comp_h = compose->height; 536*61890ccaSMoudy Ho } 537*61890ccaSMoudy Ho 538*61890ccaSMoudy Ho if ((crop_w / comp_w) > limit->h_scale_down_max || 539*61890ccaSMoudy Ho (crop_h / comp_h) > limit->v_scale_down_max || 540*61890ccaSMoudy Ho (comp_w / crop_w) > limit->h_scale_up_max || 541*61890ccaSMoudy Ho (comp_h / crop_h) > limit->v_scale_up_max) 542*61890ccaSMoudy Ho return -ERANGE; 543*61890ccaSMoudy Ho return 0; 544*61890ccaSMoudy Ho } 545*61890ccaSMoudy Ho 546*61890ccaSMoudy Ho /* Stride that is accepted by MDP HW */ 547*61890ccaSMoudy Ho static u32 mdp_fmt_get_stride(const struct mdp_format *fmt, 548*61890ccaSMoudy Ho u32 bytesperline, unsigned int plane) 549*61890ccaSMoudy Ho { 550*61890ccaSMoudy Ho enum mdp_color c = fmt->mdp_color; 551*61890ccaSMoudy Ho u32 stride; 552*61890ccaSMoudy Ho 553*61890ccaSMoudy Ho stride = (bytesperline * MDP_COLOR_BITS_PER_PIXEL(c)) 554*61890ccaSMoudy Ho / fmt->row_depth[0]; 555*61890ccaSMoudy Ho if (plane == 0) 556*61890ccaSMoudy Ho return stride; 557*61890ccaSMoudy Ho if (plane < MDP_COLOR_GET_PLANE_COUNT(c)) { 558*61890ccaSMoudy Ho if (MDP_COLOR_IS_BLOCK_MODE(c)) 559*61890ccaSMoudy Ho stride = stride / 2; 560*61890ccaSMoudy Ho return stride; 561*61890ccaSMoudy Ho } 562*61890ccaSMoudy Ho return 0; 563*61890ccaSMoudy Ho } 564*61890ccaSMoudy Ho 565*61890ccaSMoudy Ho /* Stride that is accepted by MDP HW of format with contiguous planes */ 566*61890ccaSMoudy Ho static u32 mdp_fmt_get_stride_contig(const struct mdp_format *fmt, 567*61890ccaSMoudy Ho u32 pix_stride, unsigned int plane) 568*61890ccaSMoudy Ho { 569*61890ccaSMoudy Ho enum mdp_color c = fmt->mdp_color; 570*61890ccaSMoudy Ho u32 stride = pix_stride; 571*61890ccaSMoudy Ho 572*61890ccaSMoudy Ho if (plane == 0) 573*61890ccaSMoudy Ho return stride; 574*61890ccaSMoudy Ho if (plane < MDP_COLOR_GET_PLANE_COUNT(c)) { 575*61890ccaSMoudy Ho stride = stride >> MDP_COLOR_GET_H_SUBSAMPLE(c); 576*61890ccaSMoudy Ho if (MDP_COLOR_IS_UV_COPLANE(c) && !MDP_COLOR_IS_BLOCK_MODE(c)) 577*61890ccaSMoudy Ho stride = stride * 2; 578*61890ccaSMoudy Ho return stride; 579*61890ccaSMoudy Ho } 580*61890ccaSMoudy Ho return 0; 581*61890ccaSMoudy Ho } 582*61890ccaSMoudy Ho 583*61890ccaSMoudy Ho /* Plane size that is accepted by MDP HW */ 584*61890ccaSMoudy Ho static u32 mdp_fmt_get_plane_size(const struct mdp_format *fmt, 585*61890ccaSMoudy Ho u32 stride, u32 height, unsigned int plane) 586*61890ccaSMoudy Ho { 587*61890ccaSMoudy Ho enum mdp_color c = fmt->mdp_color; 588*61890ccaSMoudy Ho u32 bytesperline; 589*61890ccaSMoudy Ho 590*61890ccaSMoudy Ho bytesperline = (stride * fmt->row_depth[0]) 591*61890ccaSMoudy Ho / MDP_COLOR_BITS_PER_PIXEL(c); 592*61890ccaSMoudy Ho if (plane == 0) 593*61890ccaSMoudy Ho return bytesperline * height; 594*61890ccaSMoudy Ho if (plane < MDP_COLOR_GET_PLANE_COUNT(c)) { 595*61890ccaSMoudy Ho height = height >> MDP_COLOR_GET_V_SUBSAMPLE(c); 596*61890ccaSMoudy Ho if (MDP_COLOR_IS_BLOCK_MODE(c)) 597*61890ccaSMoudy Ho bytesperline = bytesperline * 2; 598*61890ccaSMoudy Ho return bytesperline * height; 599*61890ccaSMoudy Ho } 600*61890ccaSMoudy Ho return 0; 601*61890ccaSMoudy Ho } 602*61890ccaSMoudy Ho 603*61890ccaSMoudy Ho static void mdp_prepare_buffer(struct img_image_buffer *b, 604*61890ccaSMoudy Ho struct mdp_frame *frame, struct vb2_buffer *vb) 605*61890ccaSMoudy Ho { 606*61890ccaSMoudy Ho struct v4l2_pix_format_mplane *pix_mp = &frame->format.fmt.pix_mp; 607*61890ccaSMoudy Ho unsigned int i; 608*61890ccaSMoudy Ho 609*61890ccaSMoudy Ho b->format.colorformat = frame->mdp_fmt->mdp_color; 610*61890ccaSMoudy Ho b->format.ycbcr_prof = frame->ycbcr_prof; 611*61890ccaSMoudy Ho for (i = 0; i < pix_mp->num_planes; ++i) { 612*61890ccaSMoudy Ho u32 stride = mdp_fmt_get_stride(frame->mdp_fmt, 613*61890ccaSMoudy Ho pix_mp->plane_fmt[i].bytesperline, i); 614*61890ccaSMoudy Ho 615*61890ccaSMoudy Ho b->format.plane_fmt[i].stride = stride; 616*61890ccaSMoudy Ho b->format.plane_fmt[i].size = 617*61890ccaSMoudy Ho mdp_fmt_get_plane_size(frame->mdp_fmt, stride, 618*61890ccaSMoudy Ho pix_mp->height, i); 619*61890ccaSMoudy Ho b->iova[i] = vb2_dma_contig_plane_dma_addr(vb, i); 620*61890ccaSMoudy Ho } 621*61890ccaSMoudy Ho for (; i < MDP_COLOR_GET_PLANE_COUNT(b->format.colorformat); ++i) { 622*61890ccaSMoudy Ho u32 stride = mdp_fmt_get_stride_contig(frame->mdp_fmt, 623*61890ccaSMoudy Ho b->format.plane_fmt[0].stride, i); 624*61890ccaSMoudy Ho 625*61890ccaSMoudy Ho b->format.plane_fmt[i].stride = stride; 626*61890ccaSMoudy Ho b->format.plane_fmt[i].size = 627*61890ccaSMoudy Ho mdp_fmt_get_plane_size(frame->mdp_fmt, stride, 628*61890ccaSMoudy Ho pix_mp->height, i); 629*61890ccaSMoudy Ho b->iova[i] = b->iova[i - 1] + b->format.plane_fmt[i - 1].size; 630*61890ccaSMoudy Ho } 631*61890ccaSMoudy Ho b->usage = frame->usage; 632*61890ccaSMoudy Ho } 633*61890ccaSMoudy Ho 634*61890ccaSMoudy Ho void mdp_set_src_config(struct img_input *in, 635*61890ccaSMoudy Ho struct mdp_frame *frame, struct vb2_buffer *vb) 636*61890ccaSMoudy Ho { 637*61890ccaSMoudy Ho in->buffer.format.width = frame->format.fmt.pix_mp.width; 638*61890ccaSMoudy Ho in->buffer.format.height = frame->format.fmt.pix_mp.height; 639*61890ccaSMoudy Ho mdp_prepare_buffer(&in->buffer, frame, vb); 640*61890ccaSMoudy Ho } 641*61890ccaSMoudy Ho 642*61890ccaSMoudy Ho static u32 mdp_to_fixed(u32 *r, struct v4l2_fract *f) 643*61890ccaSMoudy Ho { 644*61890ccaSMoudy Ho u32 q; 645*61890ccaSMoudy Ho 646*61890ccaSMoudy Ho if (f->denominator == 0) { 647*61890ccaSMoudy Ho *r = 0; 648*61890ccaSMoudy Ho return 0; 649*61890ccaSMoudy Ho } 650*61890ccaSMoudy Ho 651*61890ccaSMoudy Ho q = f->numerator / f->denominator; 652*61890ccaSMoudy Ho *r = div_u64(((u64)f->numerator - q * f->denominator) << 653*61890ccaSMoudy Ho IMG_SUBPIXEL_SHIFT, f->denominator); 654*61890ccaSMoudy Ho return q; 655*61890ccaSMoudy Ho } 656*61890ccaSMoudy Ho 657*61890ccaSMoudy Ho static void mdp_set_src_crop(struct img_crop *c, struct mdp_crop *crop) 658*61890ccaSMoudy Ho { 659*61890ccaSMoudy Ho c->left = crop->c.left 660*61890ccaSMoudy Ho + mdp_to_fixed(&c->left_subpix, &crop->left_subpix); 661*61890ccaSMoudy Ho c->top = crop->c.top 662*61890ccaSMoudy Ho + mdp_to_fixed(&c->top_subpix, &crop->top_subpix); 663*61890ccaSMoudy Ho c->width = crop->c.width 664*61890ccaSMoudy Ho + mdp_to_fixed(&c->width_subpix, &crop->width_subpix); 665*61890ccaSMoudy Ho c->height = crop->c.height 666*61890ccaSMoudy Ho + mdp_to_fixed(&c->height_subpix, &crop->height_subpix); 667*61890ccaSMoudy Ho } 668*61890ccaSMoudy Ho 669*61890ccaSMoudy Ho static void mdp_set_orientation(struct img_output *out, 670*61890ccaSMoudy Ho s32 rotation, bool hflip, bool vflip) 671*61890ccaSMoudy Ho { 672*61890ccaSMoudy Ho u8 flip = 0; 673*61890ccaSMoudy Ho 674*61890ccaSMoudy Ho if (hflip) 675*61890ccaSMoudy Ho flip ^= 1; 676*61890ccaSMoudy Ho if (vflip) { 677*61890ccaSMoudy Ho /* 678*61890ccaSMoudy Ho * A vertical flip is equivalent to 679*61890ccaSMoudy Ho * a 180-degree rotation with a horizontal flip 680*61890ccaSMoudy Ho */ 681*61890ccaSMoudy Ho rotation += 180; 682*61890ccaSMoudy Ho flip ^= 1; 683*61890ccaSMoudy Ho } 684*61890ccaSMoudy Ho 685*61890ccaSMoudy Ho out->rotation = rotation % 360; 686*61890ccaSMoudy Ho if (flip != 0) 687*61890ccaSMoudy Ho out->flags |= IMG_CTRL_FLAG_HFLIP; 688*61890ccaSMoudy Ho else 689*61890ccaSMoudy Ho out->flags &= ~IMG_CTRL_FLAG_HFLIP; 690*61890ccaSMoudy Ho } 691*61890ccaSMoudy Ho 692*61890ccaSMoudy Ho void mdp_set_dst_config(struct img_output *out, 693*61890ccaSMoudy Ho struct mdp_frame *frame, struct vb2_buffer *vb) 694*61890ccaSMoudy Ho { 695*61890ccaSMoudy Ho out->buffer.format.width = frame->compose.width; 696*61890ccaSMoudy Ho out->buffer.format.height = frame->compose.height; 697*61890ccaSMoudy Ho mdp_prepare_buffer(&out->buffer, frame, vb); 698*61890ccaSMoudy Ho mdp_set_src_crop(&out->crop, &frame->crop); 699*61890ccaSMoudy Ho mdp_set_orientation(out, frame->rotation, frame->hflip, frame->vflip); 700*61890ccaSMoudy Ho } 701*61890ccaSMoudy Ho 702*61890ccaSMoudy Ho int mdp_frameparam_init(struct mdp_frameparam *param) 703*61890ccaSMoudy Ho { 704*61890ccaSMoudy Ho struct mdp_frame *frame; 705*61890ccaSMoudy Ho 706*61890ccaSMoudy Ho if (!param) 707*61890ccaSMoudy Ho return -EINVAL; 708*61890ccaSMoudy Ho 709*61890ccaSMoudy Ho INIT_LIST_HEAD(¶m->list); 710*61890ccaSMoudy Ho param->limit = &mdp_def_limit; 711*61890ccaSMoudy Ho param->type = MDP_STREAM_TYPE_BITBLT; 712*61890ccaSMoudy Ho 713*61890ccaSMoudy Ho frame = ¶m->output; 714*61890ccaSMoudy Ho frame->format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 715*61890ccaSMoudy Ho frame->mdp_fmt = mdp_try_fmt_mplane(&frame->format, param, 0); 716*61890ccaSMoudy Ho frame->ycbcr_prof = 717*61890ccaSMoudy Ho mdp_map_ycbcr_prof_mplane(&frame->format, 718*61890ccaSMoudy Ho frame->mdp_fmt->mdp_color); 719*61890ccaSMoudy Ho frame->usage = MDP_BUFFER_USAGE_HW_READ; 720*61890ccaSMoudy Ho 721*61890ccaSMoudy Ho param->num_captures = 1; 722*61890ccaSMoudy Ho frame = ¶m->captures[0]; 723*61890ccaSMoudy Ho frame->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 724*61890ccaSMoudy Ho frame->mdp_fmt = mdp_try_fmt_mplane(&frame->format, param, 0); 725*61890ccaSMoudy Ho frame->ycbcr_prof = 726*61890ccaSMoudy Ho mdp_map_ycbcr_prof_mplane(&frame->format, 727*61890ccaSMoudy Ho frame->mdp_fmt->mdp_color); 728*61890ccaSMoudy Ho frame->usage = MDP_BUFFER_USAGE_MDP; 729*61890ccaSMoudy Ho frame->crop.c.width = param->output.format.fmt.pix_mp.width; 730*61890ccaSMoudy Ho frame->crop.c.height = param->output.format.fmt.pix_mp.height; 731*61890ccaSMoudy Ho frame->compose.width = frame->format.fmt.pix_mp.width; 732*61890ccaSMoudy Ho frame->compose.height = frame->format.fmt.pix_mp.height; 733*61890ccaSMoudy Ho 734*61890ccaSMoudy Ho return 0; 735*61890ccaSMoudy Ho } 736