diff options
| -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 = { |
