aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 1517d15d5fa6..7e660322feaf 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -83,6 +83,7 @@ struct fimd_win_data {
83 unsigned int buf_offsize; 83 unsigned int buf_offsize;
84 unsigned int line_size; /* bytes */ 84 unsigned int line_size; /* bytes */
85 bool enabled; 85 bool enabled;
86 bool resume;
86}; 87};
87 88
88struct fimd_context { 89struct fimd_context {
@@ -596,6 +597,12 @@ static void fimd_win_disable(struct device *dev, int zpos)
596 597
597 win_data = &ctx->win_data[win]; 598 win_data = &ctx->win_data[win];
598 599
600 if (ctx->suspended) {
601 /* do not resume this window*/
602 win_data->resume = false;
603 return;
604 }
605
599 /* protect windows */ 606 /* protect windows */
600 val = readl(ctx->regs + SHADOWCON); 607 val = readl(ctx->regs + SHADOWCON);
601 val |= SHADOWCON_WINx_PROTECT(win); 608 val |= SHADOWCON_WINx_PROTECT(win);
@@ -809,11 +816,38 @@ static int fimd_clock(struct fimd_context *ctx, bool enable)
809 return 0; 816 return 0;
810} 817}
811 818
819static void fimd_window_suspend(struct device *dev)
820{
821 struct fimd_context *ctx = get_fimd_context(dev);
822 struct fimd_win_data *win_data;
823 int i;
824
825 for (i = 0; i < WINDOWS_NR; i++) {
826 win_data = &ctx->win_data[i];
827 win_data->resume = win_data->enabled;
828 fimd_win_disable(dev, i);
829 }
830 fimd_wait_for_vblank(dev);
831}
832
833static void fimd_window_resume(struct device *dev)
834{
835 struct fimd_context *ctx = get_fimd_context(dev);
836 struct fimd_win_data *win_data;
837 int i;
838
839 for (i = 0; i < WINDOWS_NR; i++) {
840 win_data = &ctx->win_data[i];
841 win_data->enabled = win_data->resume;
842 win_data->resume = false;
843 }
844}
845
812static int fimd_activate(struct fimd_context *ctx, bool enable) 846static int fimd_activate(struct fimd_context *ctx, bool enable)
813{ 847{
848 struct device *dev = ctx->subdrv.dev;
814 if (enable) { 849 if (enable) {
815 int ret; 850 int ret;
816 struct device *dev = ctx->subdrv.dev;
817 851
818 ret = fimd_clock(ctx, true); 852 ret = fimd_clock(ctx, true);
819 if (ret < 0) 853 if (ret < 0)
@@ -824,7 +858,11 @@ static int fimd_activate(struct fimd_context *ctx, bool enable)
824 /* if vblank was enabled status, enable it again. */ 858 /* if vblank was enabled status, enable it again. */
825 if (test_and_clear_bit(0, &ctx->irq_flags)) 859 if (test_and_clear_bit(0, &ctx->irq_flags))
826 fimd_enable_vblank(dev); 860 fimd_enable_vblank(dev);
861
862 fimd_window_resume(dev);
827 } else { 863 } else {
864 fimd_window_suspend(dev);
865
828 fimd_clock(ctx, false); 866 fimd_clock(ctx, false);
829 ctx->suspended = true; 867 ctx->suspended = true;
830 } 868 }