Commit 396464df authored by Joonyoung Shim's avatar Joonyoung Shim Committed by Inki Dae

drm/exynos: Add disable of manager

Signed-off-by: default avatarJoonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: default avatarInki Dae <inki.dae@samsung.com>
parent 4f9eb94f
...@@ -147,12 +147,14 @@ struct exynos_drm_display_ops { ...@@ -147,12 +147,14 @@ struct exynos_drm_display_ops {
* @mode_set: convert drm_display_mode to hw specific display mode and * @mode_set: convert drm_display_mode to hw specific display mode and
* would be called by encoder->mode_set(). * would be called by encoder->mode_set().
* @commit: set current hw specific display mode to hw. * @commit: set current hw specific display mode to hw.
* @disable: disable hardware specific display mode.
* @enable_vblank: specific driver callback for enabling vblank interrupt. * @enable_vblank: specific driver callback for enabling vblank interrupt.
* @disable_vblank: specific driver callback for disabling vblank interrupt. * @disable_vblank: specific driver callback for disabling vblank interrupt.
*/ */
struct exynos_drm_manager_ops { struct exynos_drm_manager_ops {
void (*mode_set)(struct device *subdrv_dev, void *mode); void (*mode_set)(struct device *subdrv_dev, void *mode);
void (*commit)(struct device *subdrv_dev); void (*commit)(struct device *subdrv_dev);
void (*disable)(struct device *subdrv_dev);
int (*enable_vblank)(struct device *subdrv_dev); int (*enable_vblank)(struct device *subdrv_dev);
void (*disable_vblank)(struct device *subdrv_dev); void (*disable_vblank)(struct device *subdrv_dev);
}; };
......
...@@ -53,9 +53,27 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) ...@@ -53,9 +53,27 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct drm_connector *connector; struct drm_connector *connector;
struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); 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); 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) { list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (connector->encoder == encoder) { if (connector->encoder == encoder) {
struct exynos_drm_display_ops *display_ops = struct exynos_drm_display_ops *display_ops =
......
...@@ -177,6 +177,40 @@ static void fimd_commit(struct device *dev) ...@@ -177,6 +177,40 @@ static void fimd_commit(struct device *dev)
writel(val, ctx->regs + VIDCON0); 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) static int fimd_enable_vblank(struct device *dev)
{ {
struct fimd_context *ctx = get_fimd_context(dev); struct fimd_context *ctx = get_fimd_context(dev);
...@@ -220,6 +254,7 @@ static void fimd_disable_vblank(struct device *dev) ...@@ -220,6 +254,7 @@ static void fimd_disable_vblank(struct device *dev)
static struct exynos_drm_manager_ops fimd_manager_ops = { static struct exynos_drm_manager_ops fimd_manager_ops = {
.commit = fimd_commit, .commit = fimd_commit,
.disable = fimd_disable,
.enable_vblank = fimd_enable_vblank, .enable_vblank = fimd_enable_vblank,
.disable_vblank = fimd_disable_vblank, .disable_vblank = fimd_disable_vblank,
}; };
...@@ -447,9 +482,6 @@ static void fimd_win_commit(struct device *dev) ...@@ -447,9 +482,6 @@ static void fimd_win_commit(struct device *dev)
static void fimd_win_disable(struct device *dev) static void fimd_win_disable(struct device *dev)
{ {
struct fimd_context *ctx = get_fimd_context(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; int win = ctx->default_win;
u32 val; u32 val;
...@@ -473,29 +505,6 @@ static void fimd_win_disable(struct device *dev) ...@@ -473,29 +505,6 @@ static void fimd_win_disable(struct device *dev)
val &= ~SHADOWCON_CHx_ENABLE(win); val &= ~SHADOWCON_CHx_ENABLE(win);
val &= ~SHADOWCON_WINx_PROTECT(win); val &= ~SHADOWCON_WINx_PROTECT(win);
writel(val, ctx->regs + SHADOWCON); 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 = { static struct exynos_drm_overlay_ops fimd_overlay_ops = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment