drm/exynos: Add disable of manager
Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com>
This commit is contained in:
parent
4f9eb94f7b
commit
396464dfbb
@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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 = {
|
||||||
|
Loading…
Reference in New Issue
Block a user