Skip to content

Commit

Permalink
drm/exynos: fixed pm feature for fimd module.
Browse files Browse the repository at this point in the history
this patch separates fimd specific power on/off function from pm function
and the pm interfaces will call that function for power on or off.
and also removes unnecessary codes of resume function.

Signed-off-by: Inki Dae <[email protected]>
Signed-off-by: Kyungmin Park <[email protected]>
  • Loading branch information
daeinki committed Jan 27, 2012
1 parent f150130 commit 373af0c
Showing 1 changed file with 59 additions and 50 deletions.
109 changes: 59 additions & 50 deletions drivers/gpu/drm/exynos/exynos_drm_fimd.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ static void fimd_dpms(struct device *subdrv_dev, int mode)
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
pm_runtime_put_sync(subdrv_dev);
if (!ctx->suspended)
pm_runtime_put_sync(subdrv_dev);
break;
default:
DRM_DEBUG_KMS("unspecified mode %d\n", mode);
Expand Down Expand Up @@ -734,6 +735,46 @@ static void fimd_clear_win(struct fimd_context *ctx, int win)
writel(val, ctx->regs + SHADOWCON);
}

static int fimd_power_on(struct fimd_context *ctx, bool enable)
{
struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
struct device *dev = subdrv->manager.dev;

DRM_DEBUG_KMS("%s\n", __FILE__);

if (enable != false && enable != true)
return -EINVAL;

if (enable) {
int ret;

ret = clk_enable(ctx->bus_clk);
if (ret < 0)
return ret;

ret = clk_enable(ctx->lcd_clk);
if (ret < 0) {
clk_disable(ctx->bus_clk);
return ret;
}

ctx->suspended = false;

/* if vblank was enabled status, enable it again. */
if (test_and_clear_bit(0, &ctx->irq_flags))
fimd_enable_vblank(dev);

fimd_apply(dev);
} else {
clk_disable(ctx->lcd_clk);
clk_disable(ctx->bus_clk);

ctx->suspended = true;
}

return 0;
}

static int __devinit fimd_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
Expand Down Expand Up @@ -911,39 +952,30 @@ static int __devexit fimd_remove(struct platform_device *pdev)
#ifdef CONFIG_PM_SLEEP
static int fimd_suspend(struct device *dev)
{
int ret;
struct fimd_context *ctx = get_fimd_context(dev);

if (pm_runtime_suspended(dev))
return 0;

ret = pm_runtime_suspend(dev);
if (ret < 0)
return ret;

return 0;
/*
* do not use pm_runtime_suspend(). if pm_runtime_suspend() is
* called here, an error would be returned by that interface
* because the usage_count of pm runtime is more than 1.
*/
return fimd_power_on(ctx, false);
}

static int fimd_resume(struct device *dev)
{
int ret;

ret = pm_runtime_resume(dev);
if (ret < 0) {
DRM_ERROR("failed to resume runtime pm.\n");
return ret;
}

pm_runtime_disable(dev);

ret = pm_runtime_set_active(dev);
if (ret < 0) {
DRM_ERROR("failed to active runtime pm.\n");
pm_runtime_enable(dev);
pm_runtime_suspend(dev);
return ret;
}
struct fimd_context *ctx = get_fimd_context(dev);

pm_runtime_enable(dev);
/*
* if entered to sleep when lcd panel was on, the usage_count
* of pm runtime would still be 1 so in this case, fimd driver
* should be on directly not drawing on pm runtime interface.
*/
if (!pm_runtime_suspended(dev))
return fimd_power_on(ctx, true);

return 0;
}
Expand All @@ -956,39 +988,16 @@ static int fimd_runtime_suspend(struct device *dev)

DRM_DEBUG_KMS("%s\n", __FILE__);

clk_disable(ctx->lcd_clk);
clk_disable(ctx->bus_clk);

ctx->suspended = true;
return 0;
return fimd_power_on(ctx, false);
}

static int fimd_runtime_resume(struct device *dev)
{
struct fimd_context *ctx = get_fimd_context(dev);
int ret;

DRM_DEBUG_KMS("%s\n", __FILE__);

ret = clk_enable(ctx->bus_clk);
if (ret < 0)
return ret;

ret = clk_enable(ctx->lcd_clk);
if (ret < 0) {
clk_disable(ctx->bus_clk);
return ret;
}

ctx->suspended = false;

/* if vblank was enabled status, enable it again. */
if (test_and_clear_bit(0, &ctx->irq_flags))
fimd_enable_vblank(dev);

fimd_apply(dev);

return 0;
return fimd_power_on(ctx, true);
}
#endif

Expand Down

0 comments on commit 373af0c

Please sign in to comment.