drm/exynos: Add disable of manager
authorJoonyoung Shim <jy0922.shim@samsung.com>
Mon, 14 Nov 2011 06:20:49 +0000 (15:20 +0900)
committerInki Dae <inki.dae@samsung.com>
Thu, 17 Nov 2011 01:05:39 +0000 (10:05 +0900)
Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
drivers/gpu/drm/exynos/exynos_drm_drv.h
drivers/gpu/drm/exynos/exynos_drm_encoder.c
drivers/gpu/drm/exynos/exynos_drm_fimd.c

index 2d74f85..5e02e6e 100644 (file)
@@ -147,12 +147,14 @@ struct exynos_drm_display_ops {
  * @mode_set: convert drm_display_mode to hw specific display mode and
  *           would be called by encoder->mode_set().
  * @commit: set current hw specific display mode to hw.
+ * @disable: disable hardware specific display mode.
  * @enable_vblank: specific driver callback for enabling vblank interrupt.
  * @disable_vblank: specific driver callback for disabling vblank interrupt.
  */
 struct exynos_drm_manager_ops {
        void (*mode_set)(struct device *subdrv_dev, void *mode);
        void (*commit)(struct device *subdrv_dev);
+       void (*disable)(struct device *subdrv_dev);
        int (*enable_vblank)(struct device *subdrv_dev);
        void (*disable_vblank)(struct device *subdrv_dev);
 };
index 866f419..1530614 100644 (file)
@@ -53,9 +53,27 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
        struct drm_device *dev = encoder->dev;
        struct drm_connector *connector;
        struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
+       struct exynos_drm_manager_ops *manager_ops = manager->ops;
 
        DRM_DEBUG_KMS("%s, encoder dpms: %d\n", __FILE__, mode);
 
+       switch (mode) {
+       case DRM_MODE_DPMS_ON:
+               if (manager_ops && manager_ops->commit)
+                       manager_ops->commit(manager->dev);
+               break;
+       case DRM_MODE_DPMS_STANDBY:
+       case DRM_MODE_DPMS_SUSPEND:
+       case DRM_MODE_DPMS_OFF:
+               /* TODO */
+               if (manager_ops && manager_ops->disable)
+                       manager_ops->disable(manager->dev);
+               break;
+       default:
+               DRM_ERROR("unspecified mode %d\n", mode);
+               break;
+       }
+
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
                if (connector->encoder == encoder) {
                        struct exynos_drm_display_ops *display_ops =
index 272c3b5..db3b3d9 100644 (file)
@@ -177,6 +177,40 @@ static void fimd_commit(struct device *dev)
        writel(val, ctx->regs + VIDCON0);
 }
 
+static void fimd_disable(struct device *dev)
+{
+       struct fimd_context *ctx = get_fimd_context(dev);
+       struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
+       struct drm_device *drm_dev = subdrv->drm_dev;
+       struct exynos_drm_manager *manager = &subdrv->manager;
+       u32 val;
+
+       DRM_DEBUG_KMS("%s\n", __FILE__);
+
+       /* fimd dma off */
+       val = readl(ctx->regs + VIDCON0);
+       val &= ~(VIDCON0_ENVID | VIDCON0_ENVID_F);
+       writel(val, ctx->regs + VIDCON0);
+
+       /*
+        * if vblank is enabled status with dma off then
+        * it disables vsync interrupt.
+        */
+       if (drm_dev->vblank_enabled[manager->pipe] &&
+               atomic_read(&drm_dev->vblank_refcount[manager->pipe])) {
+               drm_vblank_put(drm_dev, manager->pipe);
+
+               /*
+                * if vblank_disable_allowed is 0 then disable
+                * vsync interrupt right now else the vsync interrupt
+                * would be disabled by drm timer once a current process
+                * gives up ownershop of vblank event.
+                */
+               if (!drm_dev->vblank_disable_allowed)
+                       drm_vblank_off(drm_dev, manager->pipe);
+       }
+}
+
 static int fimd_enable_vblank(struct device *dev)
 {
        struct fimd_context *ctx = get_fimd_context(dev);
@@ -220,6 +254,7 @@ static void fimd_disable_vblank(struct device *dev)
 
 static struct exynos_drm_manager_ops fimd_manager_ops = {
        .commit = fimd_commit,
+       .disable = fimd_disable,
        .enable_vblank = fimd_enable_vblank,
        .disable_vblank = fimd_disable_vblank,
 };
@@ -447,9 +482,6 @@ static void fimd_win_commit(struct device *dev)
 static void fimd_win_disable(struct device *dev)
 {
        struct fimd_context *ctx = get_fimd_context(dev);
-       struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
-       struct drm_device *drm_dev = subdrv->drm_dev;
-       struct exynos_drm_manager *manager = &subdrv->manager;
        int win = ctx->default_win;
        u32 val;
 
@@ -473,29 +505,6 @@ static void fimd_win_disable(struct device *dev)
        val &= ~SHADOWCON_CHx_ENABLE(win);
        val &= ~SHADOWCON_WINx_PROTECT(win);
        writel(val, ctx->regs + SHADOWCON);
-
-       /* fimd dma off. */
-       val = readl(ctx->regs + VIDCON0);
-       val &= ~(VIDCON0_ENVID | VIDCON0_ENVID_F);
-       writel(val, ctx->regs + VIDCON0);
-
-       /*
-        * if vblank is enabled status with dma off then
-        * it disables vsync interrupt.
-        */
-       if (drm_dev->vblank_enabled[manager->pipe] &&
-                       atomic_read(&drm_dev->vblank_refcount[manager->pipe])) {
-               drm_vblank_put(drm_dev, manager->pipe);
-
-               /*
-                * if vblank_disable_allowed is 0 then disable vsync interrupt
-                * right now else the vsync interrupt would be disabled by drm
-                * timer once a current process gives up ownershop of
-                * vblank event.
-                */
-               if (!drm_dev->vblank_disable_allowed)
-                       drm_vblank_off(drm_dev, manager->pipe);
-       }
 }
 
 static struct exynos_drm_overlay_ops fimd_overlay_ops = {