diff options
author | Dave Airlie <airlied@redhat.com> | 2018-05-09 21:27:04 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2018-05-09 21:27:04 -0400 |
commit | 87bf742b080f4f23e5005e24db4c99c23715a780 (patch) | |
tree | f1482a4cb827189b855e480895bb9b20f416064f | |
parent | dec60f3a9b7251f2657d743d96ba9a83dca02351 (diff) | |
parent | 6f2db7dc901a1b89fbc50f7b38f0f7ee17205703 (diff) |
Merge tag 'exynos-drm-fixes-for-v4.17-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-fixes
Fixup pagefault issue of mixer driver
- it makes sure to check shadow register for interlace scan.
- it corrects chroma_addr[1], height and vertical position values.
And trivial cleanup
- it just removes duplicated drm_bridge_attach.
* tag 'exynos-drm-fixes-for-v4.17-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos:
drm/exynos: hdmi: avoid duplicating drm_bridge_attach
drm/exynos: mixer: avoid Oops in vp_video_buffer()
drm/exynos/mixer: fix synchronization check in interlaced mode
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_hdmi.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_mixer.c | 22 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/regs-mixer.h | 1 |
3 files changed, 18 insertions, 7 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index abd84cbcf1c2..09c4bc0b1859 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
@@ -954,8 +954,6 @@ static int hdmi_create_connector(struct drm_encoder *encoder) | |||
954 | drm_mode_connector_attach_encoder(connector, encoder); | 954 | drm_mode_connector_attach_encoder(connector, encoder); |
955 | 955 | ||
956 | if (hdata->bridge) { | 956 | if (hdata->bridge) { |
957 | encoder->bridge = hdata->bridge; | ||
958 | hdata->bridge->encoder = encoder; | ||
959 | ret = drm_bridge_attach(encoder, hdata->bridge, NULL); | 957 | ret = drm_bridge_attach(encoder, hdata->bridge, NULL); |
960 | if (ret) | 958 | if (ret) |
961 | DRM_ERROR("Failed to attach bridge\n"); | 959 | DRM_ERROR("Failed to attach bridge\n"); |
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 257299ec95c4..272c79f5f5bf 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c | |||
@@ -473,7 +473,7 @@ static void vp_video_buffer(struct mixer_context *ctx, | |||
473 | chroma_addr[1] = chroma_addr[0] + 0x40; | 473 | chroma_addr[1] = chroma_addr[0] + 0x40; |
474 | } else { | 474 | } else { |
475 | luma_addr[1] = luma_addr[0] + fb->pitches[0]; | 475 | luma_addr[1] = luma_addr[0] + fb->pitches[0]; |
476 | chroma_addr[1] = chroma_addr[0] + fb->pitches[0]; | 476 | chroma_addr[1] = chroma_addr[0] + fb->pitches[1]; |
477 | } | 477 | } |
478 | } else { | 478 | } else { |
479 | luma_addr[1] = 0; | 479 | luma_addr[1] = 0; |
@@ -482,6 +482,7 @@ static void vp_video_buffer(struct mixer_context *ctx, | |||
482 | 482 | ||
483 | spin_lock_irqsave(&ctx->reg_slock, flags); | 483 | spin_lock_irqsave(&ctx->reg_slock, flags); |
484 | 484 | ||
485 | vp_reg_write(ctx, VP_SHADOW_UPDATE, 1); | ||
485 | /* interlace or progressive scan mode */ | 486 | /* interlace or progressive scan mode */ |
486 | val = (test_bit(MXR_BIT_INTERLACE, &ctx->flags) ? ~0 : 0); | 487 | val = (test_bit(MXR_BIT_INTERLACE, &ctx->flags) ? ~0 : 0); |
487 | vp_reg_writemask(ctx, VP_MODE, val, VP_MODE_LINE_SKIP); | 488 | vp_reg_writemask(ctx, VP_MODE, val, VP_MODE_LINE_SKIP); |
@@ -495,21 +496,23 @@ static void vp_video_buffer(struct mixer_context *ctx, | |||
495 | vp_reg_write(ctx, VP_IMG_SIZE_Y, VP_IMG_HSIZE(fb->pitches[0]) | | 496 | vp_reg_write(ctx, VP_IMG_SIZE_Y, VP_IMG_HSIZE(fb->pitches[0]) | |
496 | VP_IMG_VSIZE(fb->height)); | 497 | VP_IMG_VSIZE(fb->height)); |
497 | /* chroma plane for NV12/NV21 is half the height of the luma plane */ | 498 | /* chroma plane for NV12/NV21 is half the height of the luma plane */ |
498 | vp_reg_write(ctx, VP_IMG_SIZE_C, VP_IMG_HSIZE(fb->pitches[0]) | | 499 | vp_reg_write(ctx, VP_IMG_SIZE_C, VP_IMG_HSIZE(fb->pitches[1]) | |
499 | VP_IMG_VSIZE(fb->height / 2)); | 500 | VP_IMG_VSIZE(fb->height / 2)); |
500 | 501 | ||
501 | vp_reg_write(ctx, VP_SRC_WIDTH, state->src.w); | 502 | vp_reg_write(ctx, VP_SRC_WIDTH, state->src.w); |
502 | vp_reg_write(ctx, VP_SRC_HEIGHT, state->src.h); | ||
503 | vp_reg_write(ctx, VP_SRC_H_POSITION, | 503 | vp_reg_write(ctx, VP_SRC_H_POSITION, |
504 | VP_SRC_H_POSITION_VAL(state->src.x)); | 504 | VP_SRC_H_POSITION_VAL(state->src.x)); |
505 | vp_reg_write(ctx, VP_SRC_V_POSITION, state->src.y); | ||
506 | |||
507 | vp_reg_write(ctx, VP_DST_WIDTH, state->crtc.w); | 505 | vp_reg_write(ctx, VP_DST_WIDTH, state->crtc.w); |
508 | vp_reg_write(ctx, VP_DST_H_POSITION, state->crtc.x); | 506 | vp_reg_write(ctx, VP_DST_H_POSITION, state->crtc.x); |
507 | |||
509 | if (test_bit(MXR_BIT_INTERLACE, &ctx->flags)) { | 508 | if (test_bit(MXR_BIT_INTERLACE, &ctx->flags)) { |
509 | vp_reg_write(ctx, VP_SRC_HEIGHT, state->src.h / 2); | ||
510 | vp_reg_write(ctx, VP_SRC_V_POSITION, state->src.y / 2); | ||
510 | vp_reg_write(ctx, VP_DST_HEIGHT, state->crtc.h / 2); | 511 | vp_reg_write(ctx, VP_DST_HEIGHT, state->crtc.h / 2); |
511 | vp_reg_write(ctx, VP_DST_V_POSITION, state->crtc.y / 2); | 512 | vp_reg_write(ctx, VP_DST_V_POSITION, state->crtc.y / 2); |
512 | } else { | 513 | } else { |
514 | vp_reg_write(ctx, VP_SRC_HEIGHT, state->src.h); | ||
515 | vp_reg_write(ctx, VP_SRC_V_POSITION, state->src.y); | ||
513 | vp_reg_write(ctx, VP_DST_HEIGHT, state->crtc.h); | 516 | vp_reg_write(ctx, VP_DST_HEIGHT, state->crtc.h); |
514 | vp_reg_write(ctx, VP_DST_V_POSITION, state->crtc.y); | 517 | vp_reg_write(ctx, VP_DST_V_POSITION, state->crtc.y); |
515 | } | 518 | } |
@@ -699,6 +702,15 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg) | |||
699 | 702 | ||
700 | /* interlace scan need to check shadow register */ | 703 | /* interlace scan need to check shadow register */ |
701 | if (test_bit(MXR_BIT_INTERLACE, &ctx->flags)) { | 704 | if (test_bit(MXR_BIT_INTERLACE, &ctx->flags)) { |
705 | if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags) && | ||
706 | vp_reg_read(ctx, VP_SHADOW_UPDATE)) | ||
707 | goto out; | ||
708 | |||
709 | base = mixer_reg_read(ctx, MXR_CFG); | ||
710 | shadow = mixer_reg_read(ctx, MXR_CFG_S); | ||
711 | if (base != shadow) | ||
712 | goto out; | ||
713 | |||
702 | base = mixer_reg_read(ctx, MXR_GRAPHIC_BASE(0)); | 714 | base = mixer_reg_read(ctx, MXR_GRAPHIC_BASE(0)); |
703 | shadow = mixer_reg_read(ctx, MXR_GRAPHIC_BASE_S(0)); | 715 | shadow = mixer_reg_read(ctx, MXR_GRAPHIC_BASE_S(0)); |
704 | if (base != shadow) | 716 | if (base != shadow) |
diff --git a/drivers/gpu/drm/exynos/regs-mixer.h b/drivers/gpu/drm/exynos/regs-mixer.h index c311f571bdf9..189cfa2470a8 100644 --- a/drivers/gpu/drm/exynos/regs-mixer.h +++ b/drivers/gpu/drm/exynos/regs-mixer.h | |||
@@ -47,6 +47,7 @@ | |||
47 | #define MXR_MO 0x0304 | 47 | #define MXR_MO 0x0304 |
48 | #define MXR_RESOLUTION 0x0310 | 48 | #define MXR_RESOLUTION 0x0310 |
49 | 49 | ||
50 | #define MXR_CFG_S 0x2004 | ||
50 | #define MXR_GRAPHIC0_BASE_S 0x2024 | 51 | #define MXR_GRAPHIC0_BASE_S 0x2024 |
51 | #define MXR_GRAPHIC1_BASE_S 0x2044 | 52 | #define MXR_GRAPHIC1_BASE_S 0x2044 |
52 | 53 | ||