aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c88
1 files changed, 33 insertions, 55 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 3bc01a6b5e95..68ef01028375 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -54,6 +54,8 @@ struct hdmi_win_data {
54 unsigned int fb_y; 54 unsigned int fb_y;
55 unsigned int fb_width; 55 unsigned int fb_width;
56 unsigned int fb_height; 56 unsigned int fb_height;
57 unsigned int src_width;
58 unsigned int src_height;
57 unsigned int mode_width; 59 unsigned int mode_width;
58 unsigned int mode_height; 60 unsigned int mode_height;
59 unsigned int scan_flags; 61 unsigned int scan_flags;
@@ -351,10 +353,7 @@ static void vp_video_buffer(struct mixer_context *ctx, int win)
351 struct mixer_resources *res = &ctx->mixer_res; 353 struct mixer_resources *res = &ctx->mixer_res;
352 unsigned long flags; 354 unsigned long flags;
353 struct hdmi_win_data *win_data; 355 struct hdmi_win_data *win_data;
354 unsigned int full_width, full_height, width, height;
355 unsigned int x_ratio, y_ratio; 356 unsigned int x_ratio, y_ratio;
356 unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset;
357 unsigned int mode_width, mode_height;
358 unsigned int buf_num; 357 unsigned int buf_num;
359 dma_addr_t luma_addr[2], chroma_addr[2]; 358 dma_addr_t luma_addr[2], chroma_addr[2];
360 bool tiled_mode = false; 359 bool tiled_mode = false;
@@ -381,21 +380,9 @@ static void vp_video_buffer(struct mixer_context *ctx, int win)
381 return; 380 return;
382 } 381 }
383 382
384 full_width = win_data->fb_width;
385 full_height = win_data->fb_height;
386 width = win_data->crtc_width;
387 height = win_data->crtc_height;
388 mode_width = win_data->mode_width;
389 mode_height = win_data->mode_height;
390
391 /* scaling feature: (src << 16) / dst */ 383 /* scaling feature: (src << 16) / dst */
392 x_ratio = (width << 16) / width; 384 x_ratio = (win_data->src_width << 16) / win_data->crtc_width;
393 y_ratio = (height << 16) / height; 385 y_ratio = (win_data->src_height << 16) / win_data->crtc_height;
394
395 src_x_offset = win_data->fb_x;
396 src_y_offset = win_data->fb_y;
397 dst_x_offset = win_data->crtc_x;
398 dst_y_offset = win_data->crtc_y;
399 386
400 if (buf_num == 2) { 387 if (buf_num == 2) {
401 luma_addr[0] = win_data->dma_addr; 388 luma_addr[0] = win_data->dma_addr;
@@ -403,7 +390,7 @@ static void vp_video_buffer(struct mixer_context *ctx, int win)
403 } else { 390 } else {
404 luma_addr[0] = win_data->dma_addr; 391 luma_addr[0] = win_data->dma_addr;
405 chroma_addr[0] = win_data->dma_addr 392 chroma_addr[0] = win_data->dma_addr
406 + (full_width * full_height); 393 + (win_data->fb_width * win_data->fb_height);
407 } 394 }
408 395
409 if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE) { 396 if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE) {
@@ -412,8 +399,8 @@ static void vp_video_buffer(struct mixer_context *ctx, int win)
412 luma_addr[1] = luma_addr[0] + 0x40; 399 luma_addr[1] = luma_addr[0] + 0x40;
413 chroma_addr[1] = chroma_addr[0] + 0x40; 400 chroma_addr[1] = chroma_addr[0] + 0x40;
414 } else { 401 } else {
415 luma_addr[1] = luma_addr[0] + full_width; 402 luma_addr[1] = luma_addr[0] + win_data->fb_width;
416 chroma_addr[1] = chroma_addr[0] + full_width; 403 chroma_addr[1] = chroma_addr[0] + win_data->fb_width;
417 } 404 }
418 } else { 405 } else {
419 ctx->interlace = false; 406 ctx->interlace = false;
@@ -434,26 +421,26 @@ static void vp_video_buffer(struct mixer_context *ctx, int win)
434 vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK); 421 vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK);
435 422
436 /* setting size of input image */ 423 /* setting size of input image */
437 vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(full_width) | 424 vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(win_data->fb_width) |
438 VP_IMG_VSIZE(full_height)); 425 VP_IMG_VSIZE(win_data->fb_height));
439 /* chroma height has to reduced by 2 to avoid chroma distorions */ 426 /* chroma height has to reduced by 2 to avoid chroma distorions */
440 vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(full_width) | 427 vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(win_data->fb_width) |
441 VP_IMG_VSIZE(full_height / 2)); 428 VP_IMG_VSIZE(win_data->fb_height / 2));
442 429
443 vp_reg_write(res, VP_SRC_WIDTH, width); 430 vp_reg_write(res, VP_SRC_WIDTH, win_data->src_width);
444 vp_reg_write(res, VP_SRC_HEIGHT, height); 431 vp_reg_write(res, VP_SRC_HEIGHT, win_data->src_height);
445 vp_reg_write(res, VP_SRC_H_POSITION, 432 vp_reg_write(res, VP_SRC_H_POSITION,
446 VP_SRC_H_POSITION_VAL(src_x_offset)); 433 VP_SRC_H_POSITION_VAL(win_data->fb_x));
447 vp_reg_write(res, VP_SRC_V_POSITION, src_y_offset); 434 vp_reg_write(res, VP_SRC_V_POSITION, win_data->fb_y);
448 435
449 vp_reg_write(res, VP_DST_WIDTH, width); 436 vp_reg_write(res, VP_DST_WIDTH, win_data->crtc_width);
450 vp_reg_write(res, VP_DST_H_POSITION, dst_x_offset); 437 vp_reg_write(res, VP_DST_H_POSITION, win_data->crtc_x);
451 if (ctx->interlace) { 438 if (ctx->interlace) {
452 vp_reg_write(res, VP_DST_HEIGHT, height / 2); 439 vp_reg_write(res, VP_DST_HEIGHT, win_data->crtc_height / 2);
453 vp_reg_write(res, VP_DST_V_POSITION, dst_y_offset / 2); 440 vp_reg_write(res, VP_DST_V_POSITION, win_data->crtc_y / 2);
454 } else { 441 } else {
455 vp_reg_write(res, VP_DST_HEIGHT, height); 442 vp_reg_write(res, VP_DST_HEIGHT, win_data->crtc_height);
456 vp_reg_write(res, VP_DST_V_POSITION, dst_y_offset); 443 vp_reg_write(res, VP_DST_V_POSITION, win_data->crtc_y);
457 } 444 }
458 445
459 vp_reg_write(res, VP_H_RATIO, x_ratio); 446 vp_reg_write(res, VP_H_RATIO, x_ratio);
@@ -467,8 +454,8 @@ static void vp_video_buffer(struct mixer_context *ctx, int win)
467 vp_reg_write(res, VP_TOP_C_PTR, chroma_addr[0]); 454 vp_reg_write(res, VP_TOP_C_PTR, chroma_addr[0]);
468 vp_reg_write(res, VP_BOT_C_PTR, chroma_addr[1]); 455 vp_reg_write(res, VP_BOT_C_PTR, chroma_addr[1]);
469 456
470 mixer_cfg_scan(ctx, mode_height); 457 mixer_cfg_scan(ctx, win_data->mode_height);
471 mixer_cfg_rgb_fmt(ctx, mode_height); 458 mixer_cfg_rgb_fmt(ctx, win_data->mode_height);
472 mixer_cfg_layer(ctx, win, true); 459 mixer_cfg_layer(ctx, win, true);
473 mixer_run(ctx); 460 mixer_run(ctx);
474 461
@@ -483,10 +470,8 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win)
483 struct mixer_resources *res = &ctx->mixer_res; 470 struct mixer_resources *res = &ctx->mixer_res;
484 unsigned long flags; 471 unsigned long flags;
485 struct hdmi_win_data *win_data; 472 struct hdmi_win_data *win_data;
486 unsigned int full_width, width, height;
487 unsigned int x_ratio, y_ratio; 473 unsigned int x_ratio, y_ratio;
488 unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset; 474 unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset;
489 unsigned int mode_width, mode_height;
490 dma_addr_t dma_addr; 475 dma_addr_t dma_addr;
491 unsigned int fmt; 476 unsigned int fmt;
492 u32 val; 477 u32 val;
@@ -509,26 +494,17 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win)
509 fmt = ARGB8888; 494 fmt = ARGB8888;
510 } 495 }
511 496
512 dma_addr = win_data->dma_addr;
513 full_width = win_data->fb_width;
514 width = win_data->crtc_width;
515 height = win_data->crtc_height;
516 mode_width = win_data->mode_width;
517 mode_height = win_data->mode_height;
518
519 /* 2x scaling feature */ 497 /* 2x scaling feature */
520 x_ratio = 0; 498 x_ratio = 0;
521 y_ratio = 0; 499 y_ratio = 0;
522 500
523 src_x_offset = win_data->fb_x;
524 src_y_offset = win_data->fb_y;
525 dst_x_offset = win_data->crtc_x; 501 dst_x_offset = win_data->crtc_x;
526 dst_y_offset = win_data->crtc_y; 502 dst_y_offset = win_data->crtc_y;
527 503
528 /* converting dma address base and source offset */ 504 /* converting dma address base and source offset */
529 dma_addr = dma_addr 505 dma_addr = win_data->dma_addr
530 + (src_x_offset * win_data->bpp >> 3) 506 + (win_data->fb_x * win_data->bpp >> 3)
531 + (src_y_offset * full_width * win_data->bpp >> 3); 507 + (win_data->fb_y * win_data->fb_width * win_data->bpp >> 3);
532 src_x_offset = 0; 508 src_x_offset = 0;
533 src_y_offset = 0; 509 src_y_offset = 0;
534 510
@@ -545,10 +521,10 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win)
545 MXR_GRP_CFG_FORMAT_VAL(fmt), MXR_GRP_CFG_FORMAT_MASK); 521 MXR_GRP_CFG_FORMAT_VAL(fmt), MXR_GRP_CFG_FORMAT_MASK);
546 522
547 /* setup geometry */ 523 /* setup geometry */
548 mixer_reg_write(res, MXR_GRAPHIC_SPAN(win), full_width); 524 mixer_reg_write(res, MXR_GRAPHIC_SPAN(win), win_data->fb_width);
549 525
550 val = MXR_GRP_WH_WIDTH(width); 526 val = MXR_GRP_WH_WIDTH(win_data->crtc_width);
551 val |= MXR_GRP_WH_HEIGHT(height); 527 val |= MXR_GRP_WH_HEIGHT(win_data->crtc_height);
552 val |= MXR_GRP_WH_H_SCALE(x_ratio); 528 val |= MXR_GRP_WH_H_SCALE(x_ratio);
553 val |= MXR_GRP_WH_V_SCALE(y_ratio); 529 val |= MXR_GRP_WH_V_SCALE(y_ratio);
554 mixer_reg_write(res, MXR_GRAPHIC_WH(win), val); 530 mixer_reg_write(res, MXR_GRAPHIC_WH(win), val);
@@ -566,8 +542,8 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win)
566 /* set buffer address to mixer */ 542 /* set buffer address to mixer */
567 mixer_reg_write(res, MXR_GRAPHIC_BASE(win), dma_addr); 543 mixer_reg_write(res, MXR_GRAPHIC_BASE(win), dma_addr);
568 544
569 mixer_cfg_scan(ctx, mode_height); 545 mixer_cfg_scan(ctx, win_data->mode_height);
570 mixer_cfg_rgb_fmt(ctx, mode_height); 546 mixer_cfg_rgb_fmt(ctx, win_data->mode_height);
571 mixer_cfg_layer(ctx, win, true); 547 mixer_cfg_layer(ctx, win, true);
572 mixer_run(ctx); 548 mixer_run(ctx);
573 549
@@ -795,6 +771,8 @@ static void mixer_win_mode_set(void *ctx,
795 win_data->fb_y = overlay->fb_y; 771 win_data->fb_y = overlay->fb_y;
796 win_data->fb_width = overlay->fb_width; 772 win_data->fb_width = overlay->fb_width;
797 win_data->fb_height = overlay->fb_height; 773 win_data->fb_height = overlay->fb_height;
774 win_data->src_width = overlay->src_width;
775 win_data->src_height = overlay->src_height;
798 776
799 win_data->mode_width = overlay->mode_width; 777 win_data->mode_width = overlay->mode_width;
800 win_data->mode_height = overlay->mode_height; 778 win_data->mode_height = overlay->mode_height;