diff options
author | Joonyoung Shim <jy0922.shim@samsung.com> | 2011-11-14 01:20:49 -0500 |
---|---|---|
committer | Inki Dae <inki.dae@samsung.com> | 2011-11-16 20:05:39 -0500 |
commit | 396464dfbba8f734c57346489b871e7ed64dcdd1 (patch) | |
tree | b862472543faa424af6fe537d5759660844115d7 /drivers/gpu | |
parent | 4f9eb94f7be3d357e811ec74a53027bd27f1748f (diff) |
drm/exynos: Add disable of manager
Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_encoder.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fimd.c | 61 |
3 files changed, 55 insertions, 26 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 2d74f8550e20..5e02e6ecc2e0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h | |||
@@ -147,12 +147,14 @@ struct exynos_drm_display_ops { | |||
147 | * @mode_set: convert drm_display_mode to hw specific display mode and | 147 | * @mode_set: convert drm_display_mode to hw specific display mode and |
148 | * would be called by encoder->mode_set(). | 148 | * would be called by encoder->mode_set(). |
149 | * @commit: set current hw specific display mode to hw. | 149 | * @commit: set current hw specific display mode to hw. |
150 | * @disable: disable hardware specific display mode. | ||
150 | * @enable_vblank: specific driver callback for enabling vblank interrupt. | 151 | * @enable_vblank: specific driver callback for enabling vblank interrupt. |
151 | * @disable_vblank: specific driver callback for disabling vblank interrupt. | 152 | * @disable_vblank: specific driver callback for disabling vblank interrupt. |
152 | */ | 153 | */ |
153 | struct exynos_drm_manager_ops { | 154 | struct exynos_drm_manager_ops { |
154 | void (*mode_set)(struct device *subdrv_dev, void *mode); | 155 | void (*mode_set)(struct device *subdrv_dev, void *mode); |
155 | void (*commit)(struct device *subdrv_dev); | 156 | void (*commit)(struct device *subdrv_dev); |
157 | void (*disable)(struct device *subdrv_dev); | ||
156 | int (*enable_vblank)(struct device *subdrv_dev); | 158 | int (*enable_vblank)(struct device *subdrv_dev); |
157 | void (*disable_vblank)(struct device *subdrv_dev); | 159 | void (*disable_vblank)(struct device *subdrv_dev); |
158 | }; | 160 | }; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c index 866f419f485b..153061415baf 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c | |||
@@ -53,9 +53,27 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
53 | struct drm_device *dev = encoder->dev; | 53 | struct drm_device *dev = encoder->dev; |
54 | struct drm_connector *connector; | 54 | struct drm_connector *connector; |
55 | struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); | 55 | struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); |
56 | struct exynos_drm_manager_ops *manager_ops = manager->ops; | ||
56 | 57 | ||
57 | DRM_DEBUG_KMS("%s, encoder dpms: %d\n", __FILE__, mode); | 58 | DRM_DEBUG_KMS("%s, encoder dpms: %d\n", __FILE__, mode); |
58 | 59 | ||
60 | switch (mode) { | ||
61 | case DRM_MODE_DPMS_ON: | ||
62 | if (manager_ops && manager_ops->commit) | ||
63 | manager_ops->commit(manager->dev); | ||
64 | break; | ||
65 | case DRM_MODE_DPMS_STANDBY: | ||
66 | case DRM_MODE_DPMS_SUSPEND: | ||
67 | case DRM_MODE_DPMS_OFF: | ||
68 | /* TODO */ | ||
69 | if (manager_ops && manager_ops->disable) | ||
70 | manager_ops->disable(manager->dev); | ||
71 | break; | ||
72 | default: | ||
73 | DRM_ERROR("unspecified mode %d\n", mode); | ||
74 | break; | ||
75 | } | ||
76 | |||
59 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 77 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
60 | if (connector->encoder == encoder) { | 78 | if (connector->encoder == encoder) { |
61 | struct exynos_drm_display_ops *display_ops = | 79 | struct exynos_drm_display_ops *display_ops = |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 272c3b53c062..db3b3d9e731d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c | |||
@@ -177,6 +177,40 @@ static void fimd_commit(struct device *dev) | |||
177 | writel(val, ctx->regs + VIDCON0); | 177 | writel(val, ctx->regs + VIDCON0); |
178 | } | 178 | } |
179 | 179 | ||
180 | static void fimd_disable(struct device *dev) | ||
181 | { | ||
182 | struct fimd_context *ctx = get_fimd_context(dev); | ||
183 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; | ||
184 | struct drm_device *drm_dev = subdrv->drm_dev; | ||
185 | struct exynos_drm_manager *manager = &subdrv->manager; | ||
186 | u32 val; | ||
187 | |||
188 | DRM_DEBUG_KMS("%s\n", __FILE__); | ||
189 | |||
190 | /* fimd dma off */ | ||
191 | val = readl(ctx->regs + VIDCON0); | ||
192 | val &= ~(VIDCON0_ENVID | VIDCON0_ENVID_F); | ||
193 | writel(val, ctx->regs + VIDCON0); | ||
194 | |||
195 | /* | ||
196 | * if vblank is enabled status with dma off then | ||
197 | * it disables vsync interrupt. | ||
198 | */ | ||
199 | if (drm_dev->vblank_enabled[manager->pipe] && | ||
200 | atomic_read(&drm_dev->vblank_refcount[manager->pipe])) { | ||
201 | drm_vblank_put(drm_dev, manager->pipe); | ||
202 | |||
203 | /* | ||
204 | * if vblank_disable_allowed is 0 then disable | ||
205 | * vsync interrupt right now else the vsync interrupt | ||
206 | * would be disabled by drm timer once a current process | ||
207 | * gives up ownershop of vblank event. | ||
208 | */ | ||
209 | if (!drm_dev->vblank_disable_allowed) | ||
210 | drm_vblank_off(drm_dev, manager->pipe); | ||
211 | } | ||
212 | } | ||
213 | |||
180 | static int fimd_enable_vblank(struct device *dev) | 214 | static int fimd_enable_vblank(struct device *dev) |
181 | { | 215 | { |
182 | struct fimd_context *ctx = get_fimd_context(dev); | 216 | struct fimd_context *ctx = get_fimd_context(dev); |
@@ -220,6 +254,7 @@ static void fimd_disable_vblank(struct device *dev) | |||
220 | 254 | ||
221 | static struct exynos_drm_manager_ops fimd_manager_ops = { | 255 | static struct exynos_drm_manager_ops fimd_manager_ops = { |
222 | .commit = fimd_commit, | 256 | .commit = fimd_commit, |
257 | .disable = fimd_disable, | ||
223 | .enable_vblank = fimd_enable_vblank, | 258 | .enable_vblank = fimd_enable_vblank, |
224 | .disable_vblank = fimd_disable_vblank, | 259 | .disable_vblank = fimd_disable_vblank, |
225 | }; | 260 | }; |
@@ -447,9 +482,6 @@ static void fimd_win_commit(struct device *dev) | |||
447 | static void fimd_win_disable(struct device *dev) | 482 | static void fimd_win_disable(struct device *dev) |
448 | { | 483 | { |
449 | struct fimd_context *ctx = get_fimd_context(dev); | 484 | struct fimd_context *ctx = get_fimd_context(dev); |
450 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; | ||
451 | struct drm_device *drm_dev = subdrv->drm_dev; | ||
452 | struct exynos_drm_manager *manager = &subdrv->manager; | ||
453 | int win = ctx->default_win; | 485 | int win = ctx->default_win; |
454 | u32 val; | 486 | u32 val; |
455 | 487 | ||
@@ -473,29 +505,6 @@ static void fimd_win_disable(struct device *dev) | |||
473 | val &= ~SHADOWCON_CHx_ENABLE(win); | 505 | val &= ~SHADOWCON_CHx_ENABLE(win); |
474 | val &= ~SHADOWCON_WINx_PROTECT(win); | 506 | val &= ~SHADOWCON_WINx_PROTECT(win); |
475 | writel(val, ctx->regs + SHADOWCON); | 507 | writel(val, ctx->regs + SHADOWCON); |
476 | |||
477 | /* fimd dma off. */ | ||
478 | val = readl(ctx->regs + VIDCON0); | ||
479 | val &= ~(VIDCON0_ENVID | VIDCON0_ENVID_F); | ||
480 | writel(val, ctx->regs + VIDCON0); | ||
481 | |||
482 | /* | ||
483 | * if vblank is enabled status with dma off then | ||
484 | * it disables vsync interrupt. | ||
485 | */ | ||
486 | if (drm_dev->vblank_enabled[manager->pipe] && | ||
487 | atomic_read(&drm_dev->vblank_refcount[manager->pipe])) { | ||
488 | drm_vblank_put(drm_dev, manager->pipe); | ||
489 | |||
490 | /* | ||
491 | * if vblank_disable_allowed is 0 then disable vsync interrupt | ||
492 | * right now else the vsync interrupt would be disabled by drm | ||
493 | * timer once a current process gives up ownershop of | ||
494 | * vblank event. | ||
495 | */ | ||
496 | if (!drm_dev->vblank_disable_allowed) | ||
497 | drm_vblank_off(drm_dev, manager->pipe); | ||
498 | } | ||
499 | } | 508 | } |
500 | 509 | ||
501 | static struct exynos_drm_overlay_ops fimd_overlay_ops = { | 510 | static struct exynos_drm_overlay_ops fimd_overlay_ops = { |