aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/exynos
diff options
context:
space:
mode:
authorJoonyoung Shim <jy0922.shim@samsung.com>2011-11-14 01:20:49 -0500
committerInki Dae <inki.dae@samsung.com>2011-11-16 20:05:39 -0500
commit396464dfbba8f734c57346489b871e7ed64dcdd1 (patch)
treeb862472543faa424af6fe537d5759660844115d7 /drivers/gpu/drm/exynos
parent4f9eb94f7be3d357e811ec74a53027bd27f1748f (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/drm/exynos')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.h2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_encoder.c18
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c61
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 */
153struct exynos_drm_manager_ops { 154struct 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
180static 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
180static int fimd_enable_vblank(struct device *dev) 214static 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
221static struct exynos_drm_manager_ops fimd_manager_ops = { 255static 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)
447static void fimd_win_disable(struct device *dev) 482static 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
501static struct exynos_drm_overlay_ops fimd_overlay_ops = { 510static struct exynos_drm_overlay_ops fimd_overlay_ops = {