1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd 4 * Author: Jacob Chen <jacob-chen@iotwrt.com> 5 */ 6 7 #include <linux/pm_runtime.h> 8 9 #include "rga-hw.h" 10 #include "rga.h" 11 12 enum e_rga_start_pos { 13 LT = 0, 14 LB = 1, 15 RT = 2, 16 RB = 3, 17 }; 18 19 struct rga_corners_addr_offset { 20 struct rga_addr_offset left_top; 21 struct rga_addr_offset right_top; 22 struct rga_addr_offset left_bottom; 23 struct rga_addr_offset right_bottom; 24 }; 25 26 static unsigned int rga_get_scaling(unsigned int src, unsigned int dst) 27 { 28 /* 29 * The rga hw scaling factor is a normalized inverse of the 30 * scaling factor. 31 * For example: When source width is 100 and destination width is 200 32 * (scaling of 2x), then the hw factor is NC * 100 / 200. 33 * The normalization factor (NC) is 2^16 = 0x10000. 34 */ 35 36 return (src > dst) ? ((dst << 16) / src) : ((src << 16) / dst); 37 } 38 39 static struct rga_corners_addr_offset 40 rga_get_addr_offset(struct rga_frame *frm, struct rga_addr_offset *offset, 41 unsigned int x, unsigned int y, unsigned int w, unsigned int h) 42 { 43 struct rga_corners_addr_offset offsets; 44 struct rga_addr_offset *lt, *lb, *rt, *rb; 45 unsigned int x_div = 0, 46 y_div = 0, uv_stride = 0, pixel_width = 0; 47 48 lt = &offsets.left_top; 49 lb = &offsets.left_bottom; 50 rt = &offsets.right_top; 51 rb = &offsets.right_bottom; 52 53 x_div = frm->fmt->x_div; 54 y_div = frm->fmt->y_div; 55 uv_stride = frm->stride / x_div; 56 pixel_width = frm->stride / frm->width; 57 58 lt->y_off = offset->y_off + y * frm->stride + x * pixel_width; 59 lt->u_off = offset->u_off + (y / y_div) * uv_stride + x / x_div; 60 lt->v_off = offset->v_off + (y / y_div) * uv_stride + x / x_div; 61 62 lb->y_off = lt->y_off + (h - 1) * frm->stride; 63 lb->u_off = lt->u_off + (h / y_div - 1) * uv_stride; 64 lb->v_off = lt->v_off + (h / y_div - 1) * uv_stride; 65 66 rt->y_off = lt->y_off + (w - 1) * pixel_width; 67 rt->u_off = lt->u_off + w / x_div - 1; 68 rt->v_off = lt->v_off + w / x_div - 1; 69 70 rb->y_off = lb->y_off + (w - 1) * pixel_width; 71 rb->u_off = lb->u_off + w / x_div - 1; 72 rb->v_off = lb->v_off + w / x_div - 1; 73 74 return offsets; 75 } 76 77 static struct rga_addr_offset *rga_lookup_draw_pos(struct 78 rga_corners_addr_offset 79 * offsets, u32 rotate_mode, 80 u32 mirr_mode) 81 { 82 static enum e_rga_start_pos rot_mir_point_matrix[4][4] = { 83 { 84 LT, RT, LB, RB, 85 }, 86 { 87 RT, LT, RB, LB, 88 }, 89 { 90 RB, LB, RT, LT, 91 }, 92 { 93 LB, RB, LT, RT, 94 }, 95 }; 96 97 if (!offsets) 98 return NULL; 99 100 switch (rot_mir_point_matrix[rotate_mode][mirr_mode]) { 101 case LT: 102 return &offsets->left_top; 103 case LB: 104 return &offsets->left_bottom; 105 case RT: 106 return &offsets->right_top; 107 case RB: 108 return &offsets->right_bottom; 109 } 110 111 return NULL; 112 } 113 114 static void rga_cmd_set_src_addr(struct rga_ctx *ctx, dma_addr_t dma_addr) 115 { 116 struct rockchip_rga *rga = ctx->rga; 117 u32 *dest = rga->cmdbuf_virt; 118 unsigned int reg; 119 120 reg = RGA_MMU_SRC_BASE - RGA_MODE_BASE_REG; 121 dest[reg >> 2] = dma_addr >> 4; 122 123 reg = RGA_MMU_CTRL1 - RGA_MODE_BASE_REG; 124 dest[reg >> 2] |= 0x7; 125 } 126 127 static void rga_cmd_set_src1_addr(struct rga_ctx *ctx, dma_addr_t dma_addr) 128 { 129 struct rockchip_rga *rga = ctx->rga; 130 u32 *dest = rga->cmdbuf_virt; 131 unsigned int reg; 132 133 reg = RGA_MMU_SRC1_BASE - RGA_MODE_BASE_REG; 134 dest[reg >> 2] = dma_addr >> 4; 135 136 reg = RGA_MMU_CTRL1 - RGA_MODE_BASE_REG; 137 dest[reg >> 2] |= 0x7 << 4; 138 } 139 140 static void rga_cmd_set_dst_addr(struct rga_ctx *ctx, dma_addr_t dma_addr) 141 { 142 struct rockchip_rga *rga = ctx->rga; 143 u32 *dest = rga->cmdbuf_virt; 144 unsigned int reg; 145 146 reg = RGA_MMU_DST_BASE - RGA_MODE_BASE_REG; 147 dest[reg >> 2] = dma_addr >> 4; 148 149 reg = RGA_MMU_CTRL1 - RGA_MODE_BASE_REG; 150 dest[reg >> 2] |= 0x7 << 8; 151 } 152 153 static void rga_cmd_set_trans_info(struct rga_ctx *ctx) 154 { 155 struct rockchip_rga *rga = ctx->rga; 156 u32 *dest = rga->cmdbuf_virt; 157 unsigned int scale_dst_w, scale_dst_h; 158 unsigned int src_h, src_w, dst_h, dst_w; 159 union rga_src_info src_info; 160 union rga_dst_info dst_info; 161 union rga_src_x_factor x_factor; 162 union rga_src_y_factor y_factor; 163 union rga_src_vir_info src_vir_info; 164 union rga_src_act_info src_act_info; 165 union rga_dst_vir_info dst_vir_info; 166 union rga_dst_act_info dst_act_info; 167 168 src_h = ctx->in.crop.height; 169 src_w = ctx->in.crop.width; 170 dst_h = ctx->out.crop.height; 171 dst_w = ctx->out.crop.width; 172 173 src_info.val = dest[(RGA_SRC_INFO - RGA_MODE_BASE_REG) >> 2]; 174 dst_info.val = dest[(RGA_DST_INFO - RGA_MODE_BASE_REG) >> 2]; 175 x_factor.val = dest[(RGA_SRC_X_FACTOR - RGA_MODE_BASE_REG) >> 2]; 176 y_factor.val = dest[(RGA_SRC_Y_FACTOR - RGA_MODE_BASE_REG) >> 2]; 177 src_vir_info.val = dest[(RGA_SRC_VIR_INFO - RGA_MODE_BASE_REG) >> 2]; 178 src_act_info.val = dest[(RGA_SRC_ACT_INFO - RGA_MODE_BASE_REG) >> 2]; 179 dst_vir_info.val = dest[(RGA_DST_VIR_INFO - RGA_MODE_BASE_REG) >> 2]; 180 dst_act_info.val = dest[(RGA_DST_ACT_INFO - RGA_MODE_BASE_REG) >> 2]; 181 182 src_info.data.format = ctx->in.fmt->hw_format; 183 src_info.data.swap = ctx->in.fmt->color_swap; 184 dst_info.data.format = ctx->out.fmt->hw_format; 185 dst_info.data.swap = ctx->out.fmt->color_swap; 186 187 /* 188 * CSC mode must only be set when the colorspace families differ between 189 * input and output. It must remain unset (zeroed) if both are the same. 190 */ 191 192 if (RGA_COLOR_FMT_IS_YUV(ctx->in.fmt->hw_format) && 193 RGA_COLOR_FMT_IS_RGB(ctx->out.fmt->hw_format)) { 194 switch (ctx->in.colorspace) { 195 case V4L2_COLORSPACE_REC709: 196 src_info.data.csc_mode = RGA_SRC_CSC_MODE_BT709_R0; 197 break; 198 default: 199 src_info.data.csc_mode = RGA_SRC_CSC_MODE_BT601_R0; 200 break; 201 } 202 } 203 204 if (RGA_COLOR_FMT_IS_RGB(ctx->in.fmt->hw_format) && 205 RGA_COLOR_FMT_IS_YUV(ctx->out.fmt->hw_format)) { 206 switch (ctx->out.colorspace) { 207 case V4L2_COLORSPACE_REC709: 208 dst_info.data.csc_mode = RGA_SRC_CSC_MODE_BT709_R0; 209 break; 210 default: 211 dst_info.data.csc_mode = RGA_DST_CSC_MODE_BT601_R0; 212 break; 213 } 214 } 215 216 if (ctx->vflip) 217 src_info.data.mir_mode |= RGA_SRC_MIRR_MODE_X; 218 219 if (ctx->hflip) 220 src_info.data.mir_mode |= RGA_SRC_MIRR_MODE_Y; 221 222 switch (ctx->rotate) { 223 case 90: 224 src_info.data.rot_mode = RGA_SRC_ROT_MODE_90_DEGREE; 225 break; 226 case 180: 227 src_info.data.rot_mode = RGA_SRC_ROT_MODE_180_DEGREE; 228 break; 229 case 270: 230 src_info.data.rot_mode = RGA_SRC_ROT_MODE_270_DEGREE; 231 break; 232 default: 233 src_info.data.rot_mode = RGA_SRC_ROT_MODE_0_DEGREE; 234 break; 235 } 236 237 /* 238 * Calculate the up/down scaling mode/factor. 239 * 240 * RGA used to scale the picture first, and then rotate second, 241 * so we need to swap the w/h when rotate degree is 90/270. 242 */ 243 if (src_info.data.rot_mode == RGA_SRC_ROT_MODE_90_DEGREE || 244 src_info.data.rot_mode == RGA_SRC_ROT_MODE_270_DEGREE) { 245 if (rga->version.major == 0 || rga->version.minor == 0) { 246 if (dst_w == src_h) 247 src_h -= 8; 248 if (abs(src_w - dst_h) < 16) 249 src_w -= 16; 250 } 251 252 scale_dst_h = dst_w; 253 scale_dst_w = dst_h; 254 } else { 255 scale_dst_w = dst_w; 256 scale_dst_h = dst_h; 257 } 258 259 if (src_w == scale_dst_w) { 260 src_info.data.hscl_mode = RGA_SRC_HSCL_MODE_NO; 261 x_factor.val = 0; 262 } else if (src_w > scale_dst_w) { 263 src_info.data.hscl_mode = RGA_SRC_HSCL_MODE_DOWN; 264 x_factor.data.down_scale_factor = 265 rga_get_scaling(src_w, scale_dst_w) + 1; 266 } else { 267 src_info.data.hscl_mode = RGA_SRC_HSCL_MODE_UP; 268 x_factor.data.up_scale_factor = 269 rga_get_scaling(src_w - 1, scale_dst_w - 1); 270 } 271 272 if (src_h == scale_dst_h) { 273 src_info.data.vscl_mode = RGA_SRC_VSCL_MODE_NO; 274 y_factor.val = 0; 275 } else if (src_h > scale_dst_h) { 276 src_info.data.vscl_mode = RGA_SRC_VSCL_MODE_DOWN; 277 y_factor.data.down_scale_factor = 278 rga_get_scaling(src_h, scale_dst_h) + 1; 279 } else { 280 src_info.data.vscl_mode = RGA_SRC_VSCL_MODE_UP; 281 y_factor.data.up_scale_factor = 282 rga_get_scaling(src_h - 1, scale_dst_h - 1); 283 } 284 285 /* 286 * Calculate the framebuffer virtual strides and active size, 287 * note that the step of vir_stride / vir_width is 4 byte words 288 */ 289 src_vir_info.data.vir_stride = ctx->in.stride >> 2; 290 src_vir_info.data.vir_width = ctx->in.stride >> 2; 291 292 src_act_info.data.act_height = src_h - 1; 293 src_act_info.data.act_width = src_w - 1; 294 295 dst_vir_info.data.vir_stride = ctx->out.stride >> 2; 296 dst_act_info.data.act_height = dst_h - 1; 297 dst_act_info.data.act_width = dst_w - 1; 298 299 dest[(RGA_SRC_X_FACTOR - RGA_MODE_BASE_REG) >> 2] = x_factor.val; 300 dest[(RGA_SRC_Y_FACTOR - RGA_MODE_BASE_REG) >> 2] = y_factor.val; 301 dest[(RGA_SRC_VIR_INFO - RGA_MODE_BASE_REG) >> 2] = src_vir_info.val; 302 dest[(RGA_SRC_ACT_INFO - RGA_MODE_BASE_REG) >> 2] = src_act_info.val; 303 304 dest[(RGA_SRC_INFO - RGA_MODE_BASE_REG) >> 2] = src_info.val; 305 306 dest[(RGA_DST_VIR_INFO - RGA_MODE_BASE_REG) >> 2] = dst_vir_info.val; 307 dest[(RGA_DST_ACT_INFO - RGA_MODE_BASE_REG) >> 2] = dst_act_info.val; 308 309 dest[(RGA_DST_INFO - RGA_MODE_BASE_REG) >> 2] = dst_info.val; 310 } 311 312 static void rga_cmd_set_src_info(struct rga_ctx *ctx, 313 struct rga_addr_offset *offset) 314 { 315 struct rga_corners_addr_offset src_offsets; 316 struct rockchip_rga *rga = ctx->rga; 317 u32 *dest = rga->cmdbuf_virt; 318 unsigned int src_h, src_w, src_x, src_y; 319 320 src_h = ctx->in.crop.height; 321 src_w = ctx->in.crop.width; 322 src_x = ctx->in.crop.left; 323 src_y = ctx->in.crop.top; 324 325 /* 326 * Calculate the source framebuffer base address with offset pixel. 327 */ 328 src_offsets = rga_get_addr_offset(&ctx->in, offset, 329 src_x, src_y, src_w, src_h); 330 331 dest[(RGA_SRC_Y_RGB_BASE_ADDR - RGA_MODE_BASE_REG) >> 2] = 332 src_offsets.left_top.y_off; 333 dest[(RGA_SRC_CB_BASE_ADDR - RGA_MODE_BASE_REG) >> 2] = 334 src_offsets.left_top.u_off; 335 dest[(RGA_SRC_CR_BASE_ADDR - RGA_MODE_BASE_REG) >> 2] = 336 src_offsets.left_top.v_off; 337 } 338 339 static void rga_cmd_set_dst_info(struct rga_ctx *ctx, 340 struct rga_addr_offset *offset) 341 { 342 struct rga_addr_offset *dst_offset; 343 struct rga_corners_addr_offset offsets; 344 struct rockchip_rga *rga = ctx->rga; 345 u32 *dest = rga->cmdbuf_virt; 346 unsigned int dst_h, dst_w, dst_x, dst_y; 347 unsigned int mir_mode = 0; 348 unsigned int rot_mode = 0; 349 350 dst_h = ctx->out.crop.height; 351 dst_w = ctx->out.crop.width; 352 dst_x = ctx->out.crop.left; 353 dst_y = ctx->out.crop.top; 354 355 if (ctx->vflip) 356 mir_mode |= RGA_SRC_MIRR_MODE_X; 357 if (ctx->hflip) 358 mir_mode |= RGA_SRC_MIRR_MODE_Y; 359 360 switch (ctx->rotate) { 361 case 90: 362 rot_mode = RGA_SRC_ROT_MODE_90_DEGREE; 363 break; 364 case 180: 365 rot_mode = RGA_SRC_ROT_MODE_180_DEGREE; 366 break; 367 case 270: 368 rot_mode = RGA_SRC_ROT_MODE_270_DEGREE; 369 break; 370 default: 371 rot_mode = RGA_SRC_ROT_MODE_0_DEGREE; 372 break; 373 } 374 375 /* 376 * Configure the dest framebuffer base address with pixel offset. 377 */ 378 offsets = rga_get_addr_offset(&ctx->out, offset, dst_x, dst_y, dst_w, dst_h); 379 dst_offset = rga_lookup_draw_pos(&offsets, mir_mode, rot_mode); 380 381 dest[(RGA_DST_Y_RGB_BASE_ADDR - RGA_MODE_BASE_REG) >> 2] = 382 dst_offset->y_off; 383 dest[(RGA_DST_CB_BASE_ADDR - RGA_MODE_BASE_REG) >> 2] = 384 dst_offset->u_off; 385 dest[(RGA_DST_CR_BASE_ADDR - RGA_MODE_BASE_REG) >> 2] = 386 dst_offset->v_off; 387 } 388 389 static void rga_cmd_set_mode(struct rga_ctx *ctx) 390 { 391 struct rockchip_rga *rga = ctx->rga; 392 u32 *dest = rga->cmdbuf_virt; 393 union rga_mode_ctrl mode; 394 union rga_alpha_ctrl0 alpha_ctrl0; 395 union rga_alpha_ctrl1 alpha_ctrl1; 396 397 mode.val = 0; 398 alpha_ctrl0.val = 0; 399 alpha_ctrl1.val = 0; 400 401 mode.data.gradient_sat = 1; 402 mode.data.render = RGA_MODE_RENDER_BITBLT; 403 mode.data.bitblt = RGA_MODE_BITBLT_MODE_SRC_TO_DST; 404 405 /* disable alpha blending */ 406 dest[(RGA_ALPHA_CTRL0 - RGA_MODE_BASE_REG) >> 2] = alpha_ctrl0.val; 407 dest[(RGA_ALPHA_CTRL1 - RGA_MODE_BASE_REG) >> 2] = alpha_ctrl1.val; 408 409 dest[(RGA_MODE_CTRL - RGA_MODE_BASE_REG) >> 2] = mode.val; 410 } 411 412 static void rga_cmd_set(struct rga_ctx *ctx, 413 struct rga_vb_buffer *src, struct rga_vb_buffer *dst) 414 { 415 struct rockchip_rga *rga = ctx->rga; 416 417 memset(rga->cmdbuf_virt, 0, RGA_CMDBUF_SIZE * 4); 418 419 rga_cmd_set_src_addr(ctx, src->dma_desc_pa); 420 /* 421 * Due to hardware bug, 422 * src1 mmu also should be configured when using alpha blending. 423 */ 424 rga_cmd_set_src1_addr(ctx, dst->dma_desc_pa); 425 426 rga_cmd_set_dst_addr(ctx, dst->dma_desc_pa); 427 rga_cmd_set_mode(ctx); 428 429 rga_cmd_set_src_info(ctx, &src->offset); 430 rga_cmd_set_dst_info(ctx, &dst->offset); 431 rga_cmd_set_trans_info(ctx); 432 433 rga_write(rga, RGA_CMD_BASE, rga->cmdbuf_phy); 434 435 /* sync CMD buf for RGA */ 436 dma_sync_single_for_device(rga->dev, rga->cmdbuf_phy, 437 PAGE_SIZE, DMA_BIDIRECTIONAL); 438 } 439 440 void rga_hw_start(struct rockchip_rga *rga, 441 struct rga_vb_buffer *src, struct rga_vb_buffer *dst) 442 { 443 struct rga_ctx *ctx = rga->curr; 444 445 rga_cmd_set(ctx, src, dst); 446 447 rga_write(rga, RGA_SYS_CTRL, 0x00); 448 449 rga_write(rga, RGA_SYS_CTRL, 0x22); 450 451 rga_write(rga, RGA_INT, 0x600); 452 453 rga_write(rga, RGA_CMD_CTRL, 0x1); 454 } 455