diff options
author | Inki Dae <inki.dae@samsung.com> | 2012-08-17 04:08:04 -0400 |
---|---|---|
committer | Inki Dae <inki.dae@samsung.com> | 2012-10-03 21:05:59 -0400 |
commit | 5d55393a85f9a3c9ce93d17ae85b53c4f9f33bff (patch) | |
tree | 7fe34c6abc483c969f0c2595251a6429f0e1af5e /drivers/gpu/drm/exynos | |
parent | 41fecf3e8268b8f285c91620c20895e946db9177 (diff) |
drm/exynos: separeated fimd_power_on into some parts.
Changelog v2:
fix pm operation when resume.
Changelog v1:
this patch separetes fimd_power_on into fimd_activate and fimd_clock and
fimd_activate function will call fimd_clock to control fimd power and
vsync interrupt.
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Diffstat (limited to 'drivers/gpu/drm/exynos')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fimd.c | 60 |
1 files changed, 40 insertions, 20 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 47396e13b460..28733cd52745 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c | |||
@@ -747,16 +747,10 @@ static void fimd_clear_win(struct fimd_context *ctx, int win) | |||
747 | writel(val, ctx->regs + SHADOWCON); | 747 | writel(val, ctx->regs + SHADOWCON); |
748 | } | 748 | } |
749 | 749 | ||
750 | static int fimd_power_on(struct fimd_context *ctx, bool enable) | 750 | static int fimd_clock(struct fimd_context *ctx, bool enable) |
751 | { | 751 | { |
752 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; | ||
753 | struct device *dev = subdrv->dev; | ||
754 | |||
755 | DRM_DEBUG_KMS("%s\n", __FILE__); | 752 | DRM_DEBUG_KMS("%s\n", __FILE__); |
756 | 753 | ||
757 | if (enable != false && enable != true) | ||
758 | return -EINVAL; | ||
759 | |||
760 | if (enable) { | 754 | if (enable) { |
761 | int ret; | 755 | int ret; |
762 | 756 | ||
@@ -769,18 +763,31 @@ static int fimd_power_on(struct fimd_context *ctx, bool enable) | |||
769 | clk_disable(ctx->bus_clk); | 763 | clk_disable(ctx->bus_clk); |
770 | return ret; | 764 | return ret; |
771 | } | 765 | } |
766 | } else { | ||
767 | clk_disable(ctx->lcd_clk); | ||
768 | clk_disable(ctx->bus_clk); | ||
769 | } | ||
770 | |||
771 | return 0; | ||
772 | } | ||
773 | |||
774 | static int fimd_activate(struct fimd_context *ctx, bool enable) | ||
775 | { | ||
776 | if (enable) { | ||
777 | int ret; | ||
778 | struct device *dev = ctx->subdrv.dev; | ||
779 | |||
780 | ret = fimd_clock(ctx, true); | ||
781 | if (ret < 0) | ||
782 | return ret; | ||
772 | 783 | ||
773 | ctx->suspended = false; | 784 | ctx->suspended = false; |
774 | 785 | ||
775 | /* if vblank was enabled status, enable it again. */ | 786 | /* if vblank was enabled status, enable it again. */ |
776 | if (test_and_clear_bit(0, &ctx->irq_flags)) | 787 | if (test_and_clear_bit(0, &ctx->irq_flags)) |
777 | fimd_enable_vblank(dev); | 788 | fimd_enable_vblank(dev); |
778 | |||
779 | fimd_apply(dev); | ||
780 | } else { | 789 | } else { |
781 | clk_disable(ctx->lcd_clk); | 790 | fimd_clock(ctx, false); |
782 | clk_disable(ctx->bus_clk); | ||
783 | |||
784 | ctx->suspended = true; | 791 | ctx->suspended = true; |
785 | } | 792 | } |
786 | 793 | ||
@@ -930,15 +937,15 @@ static int fimd_suspend(struct device *dev) | |||
930 | { | 937 | { |
931 | struct fimd_context *ctx = get_fimd_context(dev); | 938 | struct fimd_context *ctx = get_fimd_context(dev); |
932 | 939 | ||
933 | if (pm_runtime_suspended(dev)) | ||
934 | return 0; | ||
935 | |||
936 | /* | 940 | /* |
937 | * do not use pm_runtime_suspend(). if pm_runtime_suspend() is | 941 | * do not use pm_runtime_suspend(). if pm_runtime_suspend() is |
938 | * called here, an error would be returned by that interface | 942 | * called here, an error would be returned by that interface |
939 | * because the usage_count of pm runtime is more than 1. | 943 | * because the usage_count of pm runtime is more than 1. |
940 | */ | 944 | */ |
941 | return fimd_power_on(ctx, false); | 945 | if (!pm_runtime_suspended(dev)) |
946 | return fimd_activate(ctx, false); | ||
947 | |||
948 | return 0; | ||
942 | } | 949 | } |
943 | 950 | ||
944 | static int fimd_resume(struct device *dev) | 951 | static int fimd_resume(struct device *dev) |
@@ -950,8 +957,21 @@ static int fimd_resume(struct device *dev) | |||
950 | * of pm runtime would still be 1 so in this case, fimd driver | 957 | * of pm runtime would still be 1 so in this case, fimd driver |
951 | * should be on directly not drawing on pm runtime interface. | 958 | * should be on directly not drawing on pm runtime interface. |
952 | */ | 959 | */ |
953 | if (!pm_runtime_suspended(dev)) | 960 | if (pm_runtime_suspended(dev)) { |
954 | return fimd_power_on(ctx, true); | 961 | int ret; |
962 | |||
963 | ret = fimd_activate(ctx, true); | ||
964 | if (ret < 0) | ||
965 | return ret; | ||
966 | |||
967 | /* | ||
968 | * in case of dpms on(standby), fimd_apply function will | ||
969 | * be called by encoder's dpms callback to update fimd's | ||
970 | * registers but in case of sleep wakeup, it's not. | ||
971 | * so fimd_apply function should be called at here. | ||
972 | */ | ||
973 | fimd_apply(dev); | ||
974 | } | ||
955 | 975 | ||
956 | return 0; | 976 | return 0; |
957 | } | 977 | } |
@@ -964,7 +984,7 @@ static int fimd_runtime_suspend(struct device *dev) | |||
964 | 984 | ||
965 | DRM_DEBUG_KMS("%s\n", __FILE__); | 985 | DRM_DEBUG_KMS("%s\n", __FILE__); |
966 | 986 | ||
967 | return fimd_power_on(ctx, false); | 987 | return fimd_activate(ctx, false); |
968 | } | 988 | } |
969 | 989 | ||
970 | static int fimd_runtime_resume(struct device *dev) | 990 | static int fimd_runtime_resume(struct device *dev) |
@@ -973,7 +993,7 @@ static int fimd_runtime_resume(struct device *dev) | |||
973 | 993 | ||
974 | DRM_DEBUG_KMS("%s\n", __FILE__); | 994 | DRM_DEBUG_KMS("%s\n", __FILE__); |
975 | 995 | ||
976 | return fimd_power_on(ctx, true); | 996 | return fimd_activate(ctx, true); |
977 | } | 997 | } |
978 | #endif | 998 | #endif |
979 | 999 | ||