diff options
Diffstat (limited to 'drivers/gpu/drm/exynos')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_mixer.c | 88 |
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; |