From 56dd3761ca6517a4562ced288df8874bfb3e38c2 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Thu, 24 Apr 2014 21:03:56 +0900 Subject: [PATCH] drm/exynos: Pass exynos_drm_manager in manager ops instead of dev This patch changes the manager ops callbacks from accepting the subdrv device pointer to taking a pointer to the manager. This will allow us to move closer to decoupling manager/display from subdrv, and subsequently decoupling the crtc/plane from the encoder. Signed-off-by: Sean Paul Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_connector.c | 2 +- drivers/gpu/drm/exynos/exynos_drm_drv.h | 35 +++--- drivers/gpu/drm/exynos/exynos_drm_encoder.c | 27 ++-- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 170 +++++++++++++------------- drivers/gpu/drm/exynos/exynos_drm_hdmi.c | 72 ++++++----- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 80 ++++++------ 6 files changed, 202 insertions(+), 184 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c index 964d553..e952861 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_connector.c +++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c @@ -225,7 +225,7 @@ static int exynos_drm_connector_fill_modes(struct drm_connector *connector, * resolution then get max width and height from that driver. */ if (ops && ops->get_max_resol) - ops->get_max_resol(manager->dev, &width, &height); + ops->get_max_resol(manager, &width, &height); return drm_helper_probe_single_connector_modes(connector, width, height); diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 09bfe60..8eb8b83 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -161,27 +161,28 @@ struct exynos_drm_display_ops { * @win_enable: enable hardware specific overlay. * @win_disable: disable hardware specific overlay. */ +struct exynos_drm_manager; struct exynos_drm_manager_ops { - int (*initialize)(struct device *subdrv_dev, - struct drm_device *drm_dev); - void (*dpms)(struct device *subdrv_dev, int mode); - void (*apply)(struct device *subdrv_dev); - void (*mode_fixup)(struct device *subdrv_dev, + int (*initialize)(struct exynos_drm_manager *mgr, + struct drm_device *drm_dev); + void (*dpms)(struct exynos_drm_manager *mgr, int mode); + void (*apply)(struct exynos_drm_manager *mgr); + void (*mode_fixup)(struct exynos_drm_manager *mgr, struct drm_connector *connector, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); - void (*mode_set)(struct device *subdrv_dev, void *mode); - void (*get_max_resol)(struct device *subdrv_dev, unsigned int *width, - unsigned int *height); - void (*commit)(struct device *subdrv_dev); - int (*enable_vblank)(struct device *subdrv_dev); - void (*disable_vblank)(struct device *subdrv_dev); - void (*wait_for_vblank)(struct device *subdrv_dev); - void (*win_mode_set)(struct device *subdrv_dev, + void (*mode_set)(struct exynos_drm_manager *mgr, void *mode); + void (*get_max_resol)(struct exynos_drm_manager *mgr, + unsigned int *width, unsigned int *height); + void (*commit)(struct exynos_drm_manager *mgr); + int (*enable_vblank)(struct exynos_drm_manager *mgr); + void (*disable_vblank)(struct exynos_drm_manager *mgr); + void (*wait_for_vblank)(struct exynos_drm_manager *mgr); + void (*win_mode_set)(struct exynos_drm_manager *mgr, struct exynos_drm_overlay *overlay); - void (*win_commit)(struct device *subdrv_dev, int zpos); - void (*win_enable)(struct device *subdrv_dev, int zpos); - void (*win_disable)(struct device *subdrv_dev, int zpos); + void (*win_commit)(struct exynos_drm_manager *mgr, int zpos); + void (*win_enable)(struct exynos_drm_manager *mgr, int zpos); + void (*win_disable)(struct exynos_drm_manager *mgr, int zpos); }; /* @@ -197,12 +198,14 @@ struct exynos_drm_manager_ops { * these callbacks should be set by specific drivers such fimd * or hdmi driver and are used to control display devices such as * analog tv, digital tv and lcd panel and also get timing data for them. + * @ctx: A pointer to the manager's implementation specific context */ struct exynos_drm_manager { struct device *dev; int pipe; struct exynos_drm_manager_ops *ops; struct exynos_drm_display_ops *display_ops; + void *ctx; }; struct exynos_drm_g2d_private { diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c index a9eb2b0..ec627fa 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c @@ -74,7 +74,7 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) case DRM_MODE_DPMS_ON: if (manager_ops && manager_ops->apply) if (!exynos_encoder->updated) - manager_ops->apply(manager->dev); + manager_ops->apply(manager); exynos_drm_connector_power(encoder, mode); exynos_encoder->dpms = mode; @@ -107,7 +107,7 @@ exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder, list_for_each_entry(connector, &dev->mode_config.connector_list, head) { if (connector->encoder == encoder) if (manager_ops && manager_ops->mode_fixup) - manager_ops->mode_fixup(manager->dev, connector, + manager_ops->mode_fixup(manager, connector, mode, adjusted_mode); } @@ -175,8 +175,7 @@ static void exynos_drm_encoder_mode_set(struct drm_encoder *encoder, manager_ops = manager->ops; if (manager_ops && manager_ops->mode_set) - manager_ops->mode_set(manager->dev, - adjusted_mode); + manager_ops->mode_set(manager, adjusted_mode); exynos_encoder->old_crtc = encoder->crtc; } @@ -195,7 +194,7 @@ static void exynos_drm_encoder_commit(struct drm_encoder *encoder) struct exynos_drm_manager_ops *manager_ops = manager->ops; if (manager_ops && manager_ops->commit) - manager_ops->commit(manager->dev); + manager_ops->commit(manager); /* * this will avoid one issue that overlay data is updated to @@ -233,7 +232,7 @@ void exynos_drm_encoder_complete_scanout(struct drm_framebuffer *fb) * real hardware. */ if (ops->wait_for_vblank) - ops->wait_for_vblank(exynos_encoder->manager->dev); + ops->wait_for_vblank(exynos_encoder->manager); } } @@ -341,7 +340,7 @@ exynos_drm_encoder_create(struct drm_device *dev, drm_encoder_helper_add(encoder, &exynos_encoder_helper_funcs); if (manager->ops && manager->ops->initialize) { - ret = manager->ops->initialize(manager->dev, dev); + ret = manager->ops->initialize(manager, dev); if (ret) { DRM_ERROR("Manager initialize failed %d\n", ret); goto error; @@ -408,7 +407,7 @@ void exynos_drm_enable_vblank(struct drm_encoder *encoder, void *data) return; if (manager_ops->enable_vblank) - manager_ops->enable_vblank(manager->dev); + manager_ops->enable_vblank(manager); } void exynos_drm_disable_vblank(struct drm_encoder *encoder, void *data) @@ -422,7 +421,7 @@ void exynos_drm_disable_vblank(struct drm_encoder *encoder, void *data) return; if (manager_ops->disable_vblank) - manager_ops->disable_vblank(manager->dev); + manager_ops->disable_vblank(manager); } void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data) @@ -433,7 +432,7 @@ void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data) int mode = *(int *)data; if (manager_ops && manager_ops->dpms) - manager_ops->dpms(manager->dev, mode); + manager_ops->dpms(manager, mode); /* * if this condition is ok then it means that the crtc is already @@ -467,7 +466,7 @@ void exynos_drm_encoder_plane_mode_set(struct drm_encoder *encoder, void *data) struct exynos_drm_overlay *overlay = data; if (manager_ops && manager_ops->win_mode_set) - manager_ops->win_mode_set(manager->dev, overlay); + manager_ops->win_mode_set(manager, overlay); } void exynos_drm_encoder_plane_commit(struct drm_encoder *encoder, void *data) @@ -481,7 +480,7 @@ void exynos_drm_encoder_plane_commit(struct drm_encoder *encoder, void *data) zpos = *(int *)data; if (manager_ops && manager_ops->win_commit) - manager_ops->win_commit(manager->dev, zpos); + manager_ops->win_commit(manager, zpos); } void exynos_drm_encoder_plane_enable(struct drm_encoder *encoder, void *data) @@ -495,7 +494,7 @@ void exynos_drm_encoder_plane_enable(struct drm_encoder *encoder, void *data) zpos = *(int *)data; if (manager_ops && manager_ops->win_enable) - manager_ops->win_enable(manager->dev, zpos); + manager_ops->win_enable(manager, zpos); } void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data) @@ -509,5 +508,5 @@ void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data) zpos = *(int *)data; if (manager_ops && manager_ops->win_disable) - manager_ops->win_disable(manager->dev, zpos); + manager_ops->win_disable(manager, zpos); } diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 7508fd5..0ade7b0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -62,7 +62,7 @@ /* FIMD has totally five hardware windows. */ #define WINDOWS_NR 5 -#define get_fimd_context(dev) platform_get_drvdata(to_platform_device(dev)) +#define get_fimd_manager(mgr) platform_get_drvdata(to_platform_device(dev)) struct fimd_driver_data { unsigned int timing_base; @@ -112,6 +112,7 @@ struct fimd_win_data { struct fimd_context { struct exynos_drm_subdrv subdrv; + struct device *dev; struct drm_device *drm_dev; int irq; struct drm_crtc *crtc; @@ -170,7 +171,8 @@ static bool fimd_display_is_connected(struct device *dev) static void *fimd_get_panel(struct device *dev) { - struct fimd_context *ctx = get_fimd_context(dev); + struct exynos_drm_manager *mgr = get_fimd_manager(dev); + struct fimd_context *ctx = mgr->ctx; return ctx->panel; } @@ -211,10 +213,9 @@ static struct exynos_drm_display_ops fimd_display_ops = { .power_on = fimd_display_power_on, }; -static void fimd_apply(struct device *subdrv_dev) +static void fimd_apply(struct exynos_drm_manager *mgr) { - struct fimd_context *ctx = get_fimd_context(subdrv_dev); - struct exynos_drm_manager *mgr = ctx->subdrv.manager; + struct fimd_context *ctx = mgr->ctx; struct exynos_drm_manager_ops *mgr_ops = mgr->ops; struct fimd_win_data *win_data; int i; @@ -222,16 +223,16 @@ static void fimd_apply(struct device *subdrv_dev) for (i = 0; i < WINDOWS_NR; i++) { win_data = &ctx->win_data[i]; if (win_data->enabled && (mgr_ops && mgr_ops->win_commit)) - mgr_ops->win_commit(subdrv_dev, i); + mgr_ops->win_commit(mgr, i); } if (mgr_ops && mgr_ops->commit) - mgr_ops->commit(subdrv_dev); + mgr_ops->commit(mgr); } -static void fimd_commit(struct device *dev) +static void fimd_commit(struct exynos_drm_manager *mgr) { - struct fimd_context *ctx = get_fimd_context(dev); + struct fimd_context *ctx = mgr->ctx; struct exynos_drm_panel_info *panel = ctx->panel; struct fb_videomode *timing = &panel->timing; struct fimd_driver_data *driver_data; @@ -295,9 +296,9 @@ static void fimd_commit(struct device *dev) writel(val, ctx->regs + VIDCON0); } -static int fimd_enable_vblank(struct device *dev) +static int fimd_enable_vblank(struct exynos_drm_manager *mgr) { - struct fimd_context *ctx = get_fimd_context(dev); + struct fimd_context *ctx = mgr->ctx; u32 val; if (ctx->suspended) @@ -320,9 +321,9 @@ static int fimd_enable_vblank(struct device *dev) return 0; } -static void fimd_disable_vblank(struct device *dev) +static void fimd_disable_vblank(struct exynos_drm_manager *mgr) { - struct fimd_context *ctx = get_fimd_context(dev); + struct fimd_context *ctx = mgr->ctx; u32 val; if (ctx->suspended) @@ -338,9 +339,9 @@ static void fimd_disable_vblank(struct device *dev) } } -static void fimd_wait_for_vblank(struct device *dev) +static void fimd_wait_for_vblank(struct exynos_drm_manager *mgr) { - struct fimd_context *ctx = get_fimd_context(dev); + struct fimd_context *ctx = mgr->ctx; if (ctx->suspended) return; @@ -357,16 +358,16 @@ static void fimd_wait_for_vblank(struct device *dev) DRM_DEBUG_KMS("vblank wait timed out.\n"); } -static void fimd_win_mode_set(struct device *dev, - struct exynos_drm_overlay *overlay) +static void fimd_win_mode_set(struct exynos_drm_manager *mgr, + struct exynos_drm_overlay *overlay) { - struct fimd_context *ctx = get_fimd_context(dev); + struct fimd_context *ctx = mgr->ctx; struct fimd_win_data *win_data; int win; unsigned long offset; if (!overlay) { - dev_err(dev, "overlay is NULL\n"); + DRM_ERROR("overlay is NULL\n"); return; } @@ -406,9 +407,8 @@ static void fimd_win_mode_set(struct device *dev, overlay->fb_width, overlay->crtc_width); } -static void fimd_win_set_pixfmt(struct device *dev, unsigned int win) +static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win) { - struct fimd_context *ctx = get_fimd_context(dev); struct fimd_win_data *win_data = &ctx->win_data[win]; unsigned long val; @@ -464,9 +464,8 @@ static void fimd_win_set_pixfmt(struct device *dev, unsigned int win) writel(val, ctx->regs + WINCON(win)); } -static void fimd_win_set_colkey(struct device *dev, unsigned int win) +static void fimd_win_set_colkey(struct fimd_context *ctx, unsigned int win) { - struct fimd_context *ctx = get_fimd_context(dev); unsigned int keycon0 = 0, keycon1 = 0; keycon0 = ~(WxKEYCON0_KEYBL_EN | WxKEYCON0_KEYEN_F | @@ -505,9 +504,9 @@ static void fimd_shadow_protect_win(struct fimd_context *ctx, writel(val, ctx->regs + reg); } -static void fimd_win_commit(struct device *dev, int zpos) +static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos) { - struct fimd_context *ctx = get_fimd_context(dev); + struct fimd_context *ctx = mgr->ctx; struct fimd_win_data *win_data; int win = zpos; unsigned long val, alpha, size; @@ -602,11 +601,11 @@ static void fimd_win_commit(struct device *dev, int zpos) DRM_DEBUG_KMS("osd size = 0x%x\n", (unsigned int)val); } - fimd_win_set_pixfmt(dev, win); + fimd_win_set_pixfmt(ctx, win); /* hardware window 0 doesn't support color key. */ if (win != 0) - fimd_win_set_colkey(dev, win); + fimd_win_set_colkey(ctx, win); /* wincon */ val = readl(ctx->regs + WINCON(win)); @@ -625,9 +624,9 @@ static void fimd_win_commit(struct device *dev, int zpos) win_data->enabled = true; } -static void fimd_win_disable(struct device *dev, int zpos) +static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos) { - struct fimd_context *ctx = get_fimd_context(dev); + struct fimd_context *ctx = mgr->ctx; struct fimd_win_data *win_data; int win = zpos; u32 val; @@ -697,7 +696,8 @@ out: static void fimd_clear_channel(struct device *dev) { - struct fimd_context *ctx = get_fimd_context(dev); + struct exynos_drm_manager *mgr = get_fimd_manager(dev); + struct fimd_context *ctx = mgr->ctx; int win, ch_enabled = 0; DRM_DEBUG_KMS("%s\n", __FILE__); @@ -714,7 +714,7 @@ static void fimd_clear_channel(struct device *dev) /* Wait for vsync, as disable channel takes effect at next vsync */ if (ch_enabled) - fimd_wait_for_vblank(dev); + fimd_wait_for_vblank(mgr); } static int fimd_subdrv_probe(struct drm_device *drm_dev, struct device *dev) @@ -823,21 +823,23 @@ static int fimd_clock(struct fimd_context *ctx, bool enable) static void fimd_window_suspend(struct device *dev) { - struct fimd_context *ctx = get_fimd_context(dev); + struct exynos_drm_manager *mgr = get_fimd_manager(dev); + struct fimd_context *ctx = mgr->ctx; struct fimd_win_data *win_data; int i; for (i = 0; i < WINDOWS_NR; i++) { win_data = &ctx->win_data[i]; win_data->resume = win_data->enabled; - fimd_win_disable(dev, i); + fimd_win_disable(mgr, i); } - fimd_wait_for_vblank(dev); + fimd_wait_for_vblank(mgr); } static void fimd_window_resume(struct device *dev) { - struct fimd_context *ctx = get_fimd_context(dev); + struct exynos_drm_manager *mgr = get_fimd_manager(dev); + struct fimd_context *ctx = mgr->ctx; struct fimd_win_data *win_data; int i; @@ -848,8 +850,9 @@ static void fimd_window_resume(struct device *dev) } } -static int fimd_activate(struct fimd_context *ctx, bool enable) +static int fimd_activate(struct exynos_drm_manager *mgr, bool enable) { + struct fimd_context *ctx = mgr->ctx; struct device *dev = ctx->subdrv.dev; if (enable) { int ret; @@ -862,7 +865,7 @@ static int fimd_activate(struct fimd_context *ctx, bool enable) /* if vblank was enabled status, enable it again. */ if (test_and_clear_bit(0, &ctx->irq_flags)) - fimd_enable_vblank(dev); + fimd_enable_vblank(mgr); fimd_window_resume(dev); } else { @@ -875,19 +878,19 @@ static int fimd_activate(struct fimd_context *ctx, bool enable) return 0; } -static int fimd_mgr_initialize(struct device *subdrv_dev, - struct drm_device *drm_dev) +static int fimd_mgr_initialize(struct exynos_drm_manager *mgr, + struct drm_device *drm_dev) { - struct fimd_context *ctx = get_fimd_context(subdrv_dev); + struct fimd_context *ctx = mgr->ctx; ctx->drm_dev = drm_dev; return 0; } -static void fimd_dpms(struct device *subdrv_dev, int mode) +static void fimd_dpms(struct exynos_drm_manager *mgr, int mode) { - struct fimd_context *ctx = get_fimd_context(subdrv_dev); + struct fimd_context *ctx = mgr->ctx; DRM_DEBUG_KMS("%d\n", mode); @@ -902,14 +905,14 @@ static void fimd_dpms(struct device *subdrv_dev, int mode) * clk_enable could be called double time. */ if (ctx->suspended) - pm_runtime_get_sync(subdrv_dev); + pm_runtime_get_sync(ctx->dev); break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: if (!ctx->suspended) - pm_runtime_put_sync(subdrv_dev); + pm_runtime_put_sync(ctx->dev); break; default: @@ -946,42 +949,36 @@ static int fimd_probe(struct platform_device *pdev) struct exynos_drm_subdrv *subdrv; struct exynos_drm_fimd_pdata *pdata; struct exynos_drm_panel_info *panel; + struct device_node *display_np; struct resource *res; int win; int ret = -EINVAL; - if (dev->of_node) { - struct device_node *display_np; + if(!dev->of_node) + return -ENODEV; - display_np = of_parse_phandle(dev->of_node, - "samsung,fimd-display", 0); - if (!display_np) - display_np = dev->of_node; + display_np = of_parse_phandle(dev->of_node, + "samsung,fimd-display", 0); + if (!display_np) + display_np = dev->of_node; - pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return -ENOMEM; - - ret = of_get_fb_videomode(display_np, - &pdata->panel.timing, OF_USE_NATIVE_MODE); - if (ret) { - DRM_ERROR("failed: of_get_fb_videomode() : %d\n", ret); - return ret; - } + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; - /* FIXME */ - of_property_read_u32(display_np, "samsung,panel-width-mm", - &pdata->panel.width_mm); - of_property_read_u32(display_np, "samsung,panel-height-mm", - &pdata->panel.height_mm); - } else { - pdata = dev->platform_data; - if (!pdata) { - DRM_ERROR("no platform data specified\n"); - return -EINVAL; - } + ret = of_get_fb_videomode(display_np, + &pdata->panel.timing, OF_USE_NATIVE_MODE); + if (ret) { + DRM_ERROR("failed: of_get_fb_videomode() : %d\n", ret); + return ret; } + /* FIXME */ + of_property_read_u32(display_np, "samsung,panel-width-mm", + &pdata->panel.width_mm); + of_property_read_u32(display_np, "samsung,panel-height-mm", + &pdata->panel.height_mm); + panel = &pdata->panel; if (!panel) { dev_err(dev, "panel is null.\n"); @@ -992,6 +989,8 @@ static int fimd_probe(struct platform_device *pdev) if (!ctx) return -ENOMEM; + ctx->dev = dev; + ctx->bus_clk = devm_clk_get(dev, "fimd"); if (IS_ERR(ctx->bus_clk)) { dev_err(dev, "failed to get bus clock\n"); @@ -1038,6 +1037,8 @@ static int fimd_probe(struct platform_device *pdev) DRM_INIT_WAITQUEUE(&ctx->wait_vsync_queue); atomic_set(&ctx->wait_vsync_event, 0); + fimd_manager.ctx = ctx; + subdrv = &ctx->subdrv; subdrv->dev = dev; @@ -1047,7 +1048,7 @@ static int fimd_probe(struct platform_device *pdev) mutex_init(&ctx->lock); - platform_set_drvdata(pdev, ctx); + platform_set_drvdata(pdev, &fimd_manager); pm_runtime_enable(dev); pm_runtime_get_sync(dev); @@ -1060,9 +1061,9 @@ static int fimd_probe(struct platform_device *pdev) for (win = 0; win < WINDOWS_NR; win++) { fimd_clear_win(ctx, win); - fimd_win_disable(dev, win); + fimd_win_disable(&fimd_manager, win); } - fimd_wait_for_vblank(dev); + fimd_wait_for_vblank(&fimd_manager); exynos_drm_subdrv_register(subdrv); @@ -1072,7 +1073,8 @@ static int fimd_probe(struct platform_device *pdev) static int fimd_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct fimd_context *ctx = platform_get_drvdata(pdev); + struct exynos_drm_manager *mgr = platform_get_drvdata(pdev); + struct fimd_context *ctx = mgr->ctx; exynos_drm_subdrv_unregister(&ctx->subdrv); @@ -1091,7 +1093,7 @@ out: #ifdef CONFIG_PM_SLEEP static int fimd_suspend(struct device *dev) { - struct fimd_context *ctx = get_fimd_context(dev); + struct exynos_drm_manager *mgr = get_fimd_manager(dev); /* * do not use pm_runtime_suspend(). if pm_runtime_suspend() is @@ -1099,14 +1101,14 @@ static int fimd_suspend(struct device *dev) * because the usage_count of pm runtime is more than 1. */ if (!pm_runtime_suspended(dev)) - return fimd_activate(ctx, false); + return fimd_activate(mgr, false); return 0; } static int fimd_resume(struct device *dev) { - struct fimd_context *ctx = get_fimd_context(dev); + struct exynos_drm_manager *mgr = get_fimd_manager(dev); /* * if entered to sleep when lcd panel was on, the usage_count @@ -1116,7 +1118,7 @@ static int fimd_resume(struct device *dev) if (!pm_runtime_suspended(dev)) { int ret; - ret = fimd_activate(ctx, true); + ret = fimd_activate(mgr, true); if (ret < 0) return ret; @@ -1126,7 +1128,7 @@ static int fimd_resume(struct device *dev) * registers but in case of sleep wakeup, it's not. * so fimd_apply function should be called at here. */ - fimd_apply(dev); + fimd_apply(mgr); } return 0; @@ -1136,16 +1138,16 @@ static int fimd_resume(struct device *dev) #ifdef CONFIG_PM_RUNTIME static int fimd_runtime_suspend(struct device *dev) { - struct fimd_context *ctx = get_fimd_context(dev); + struct exynos_drm_manager *mgr = get_fimd_manager(dev); - return fimd_activate(ctx, false); + return fimd_activate(mgr, false); } static int fimd_runtime_resume(struct device *dev) { - struct fimd_context *ctx = get_fimd_context(dev); + struct exynos_drm_manager *mgr = get_fimd_manager(dev); - return fimd_activate(ctx, true); + return fimd_activate(mgr, true); } #endif diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c index ef19945..ff12ab9 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c @@ -129,11 +129,9 @@ static struct edid *drm_hdmi_get_edid(struct device *dev, return NULL; } - -static int drm_hdmi_check_mode(struct device *dev, +static int drm_hdmi_check_mode_ctx(struct drm_hdmi_context *ctx, struct drm_display_mode *mode) { - struct drm_hdmi_context *ctx = to_context(dev); int ret = 0; /* @@ -153,6 +151,14 @@ static int drm_hdmi_check_mode(struct device *dev, return 0; } +static int drm_hdmi_check_mode(struct device *dev, + struct drm_display_mode *mode) +{ + struct drm_hdmi_context *ctx = to_context(dev); + + return drm_hdmi_check_mode_ctx(ctx, mode); +} + static int drm_hdmi_power_on(struct device *dev, int mode) { struct drm_hdmi_context *ctx = to_context(dev); @@ -172,9 +178,9 @@ static struct exynos_drm_display_ops drm_hdmi_display_ops = { .power_on = drm_hdmi_power_on, }; -static int drm_hdmi_enable_vblank(struct device *subdrv_dev) +static int drm_hdmi_enable_vblank(struct exynos_drm_manager *mgr) { - struct drm_hdmi_context *ctx = to_context(subdrv_dev); + struct drm_hdmi_context *ctx = mgr->ctx; struct exynos_drm_subdrv *subdrv = &ctx->subdrv; struct exynos_drm_manager *manager = subdrv->manager; @@ -185,33 +191,34 @@ static int drm_hdmi_enable_vblank(struct device *subdrv_dev) return 0; } -static void drm_hdmi_disable_vblank(struct device *subdrv_dev) +static void drm_hdmi_disable_vblank(struct exynos_drm_manager *mgr) { - struct drm_hdmi_context *ctx = to_context(subdrv_dev); + struct drm_hdmi_context *ctx = mgr->ctx; if (mixer_ops && mixer_ops->disable_vblank) return mixer_ops->disable_vblank(ctx->mixer_ctx->ctx); } -static void drm_hdmi_wait_for_vblank(struct device *subdrv_dev) +static void drm_hdmi_wait_for_vblank(struct exynos_drm_manager *mgr) { - struct drm_hdmi_context *ctx = to_context(subdrv_dev); + struct drm_hdmi_context *ctx = mgr->ctx; if (mixer_ops && mixer_ops->wait_for_vblank) mixer_ops->wait_for_vblank(ctx->mixer_ctx->ctx); } -static void drm_hdmi_mode_fixup(struct device *subdrv_dev, +static void drm_hdmi_mode_fixup(struct exynos_drm_manager *mgr, struct drm_connector *connector, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { + struct drm_hdmi_context *ctx = mgr->ctx; struct drm_display_mode *m; int mode_ok; drm_mode_set_crtcinfo(adjusted_mode, 0); - mode_ok = drm_hdmi_check_mode(subdrv_dev, adjusted_mode); + mode_ok = drm_hdmi_check_mode_ctx(ctx, adjusted_mode); /* just return if user desired mode exists. */ if (mode_ok == 0) @@ -222,7 +229,7 @@ static void drm_hdmi_mode_fixup(struct device *subdrv_dev, * to adjusted_mode. */ list_for_each_entry(m, &connector->modes, head) { - mode_ok = drm_hdmi_check_mode(subdrv_dev, m); + mode_ok = drm_hdmi_check_mode_ctx(ctx, m); if (mode_ok == 0) { struct drm_mode_object base; @@ -245,35 +252,34 @@ static void drm_hdmi_mode_fixup(struct device *subdrv_dev, } } -static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode) +static void drm_hdmi_mode_set(struct exynos_drm_manager *mgr, void *mode) { - struct drm_hdmi_context *ctx = to_context(subdrv_dev); + struct drm_hdmi_context *ctx = mgr->ctx; if (hdmi_ops && hdmi_ops->mode_set) hdmi_ops->mode_set(ctx->hdmi_ctx->ctx, mode); } -static void drm_hdmi_get_max_resol(struct device *subdrv_dev, +static void drm_hdmi_get_max_resol(struct exynos_drm_manager *mgr, unsigned int *width, unsigned int *height) { - struct drm_hdmi_context *ctx = to_context(subdrv_dev); + struct drm_hdmi_context *ctx = mgr->ctx; if (hdmi_ops && hdmi_ops->get_max_resol) hdmi_ops->get_max_resol(ctx->hdmi_ctx->ctx, width, height); } -static void drm_hdmi_commit(struct device *subdrv_dev) +static void drm_hdmi_commit(struct exynos_drm_manager *mgr) { - struct drm_hdmi_context *ctx = to_context(subdrv_dev); + struct drm_hdmi_context *ctx = mgr->ctx; if (hdmi_ops && hdmi_ops->commit) hdmi_ops->commit(ctx->hdmi_ctx->ctx); } -static int drm_hdmi_mgr_initialize(struct device *subdrv_dev, - struct drm_device *drm_dev) +static int drm_hdmi_mgr_initialize(struct exynos_drm_manager *mgr, struct drm_device *drm_dev) { - struct drm_hdmi_context *ctx = to_context(subdrv_dev); + struct drm_hdmi_context *ctx = mgr->ctx; int ret = 0; if (mixer_ops && mixer_ops->initialize) @@ -285,9 +291,9 @@ static int drm_hdmi_mgr_initialize(struct device *subdrv_dev, return ret; } -static void drm_hdmi_dpms(struct device *subdrv_dev, int mode) +static void drm_hdmi_dpms(struct exynos_drm_manager *mgr, int mode) { - struct drm_hdmi_context *ctx = to_context(subdrv_dev); + struct drm_hdmi_context *ctx = mgr->ctx; if (mixer_ops && mixer_ops->dpms) mixer_ops->dpms(ctx->mixer_ctx->ctx, mode); @@ -296,9 +302,9 @@ static void drm_hdmi_dpms(struct device *subdrv_dev, int mode) hdmi_ops->dpms(ctx->hdmi_ctx->ctx, mode); } -static void drm_hdmi_apply(struct device *subdrv_dev) +static void drm_hdmi_apply(struct exynos_drm_manager *mgr) { - struct drm_hdmi_context *ctx = to_context(subdrv_dev); + struct drm_hdmi_context *ctx = mgr->ctx; int i; for (i = 0; i < MIXER_WIN_NR; i++) { @@ -312,18 +318,18 @@ static void drm_hdmi_apply(struct device *subdrv_dev) hdmi_ops->commit(ctx->hdmi_ctx->ctx); } -static void drm_mixer_win_mode_set(struct device *subdrv_dev, - struct exynos_drm_overlay *overlay) +static void drm_mixer_win_mode_set(struct exynos_drm_manager *mgr, + struct exynos_drm_overlay *overlay) { - struct drm_hdmi_context *ctx = to_context(subdrv_dev); + struct drm_hdmi_context *ctx = mgr->ctx; if (mixer_ops && mixer_ops->win_mode_set) mixer_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay); } -static void drm_mixer_win_commit(struct device *subdrv_dev, int zpos) +static void drm_mixer_win_commit(struct exynos_drm_manager *mgr, int zpos) { - struct drm_hdmi_context *ctx = to_context(subdrv_dev); + struct drm_hdmi_context *ctx = mgr->ctx; int win = (zpos == DEFAULT_ZPOS) ? MIXER_DEFAULT_WIN : zpos; if (win < 0 || win > MIXER_WIN_NR) { @@ -337,9 +343,9 @@ static void drm_mixer_win_commit(struct device *subdrv_dev, int zpos) ctx->enabled[win] = true; } -static void drm_mixer_win_disable(struct device *subdrv_dev, int zpos) +static void drm_mixer_win_disable(struct exynos_drm_manager *mgr, int zpos) { - struct drm_hdmi_context *ctx = to_context(subdrv_dev); + struct drm_hdmi_context *ctx = mgr->ctx; int win = (zpos == DEFAULT_ZPOS) ? MIXER_DEFAULT_WIN : zpos; if (win < 0 || win > MIXER_WIN_NR) { @@ -425,6 +431,8 @@ static int exynos_drm_hdmi_probe(struct platform_device *pdev) if (!ctx) return -ENOMEM; + hdmi_manager.ctx = ctx; + subdrv = &ctx->subdrv; subdrv->dev = dev; diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 538886f..b3ea5e7 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -28,7 +28,7 @@ /* vidi has totally three virtual windows. */ #define WINDOWS_NR 3 -#define get_vidi_context(dev) platform_get_drvdata(to_platform_device(dev)) +#define get_vidi_mgr(dev) platform_get_drvdata(to_platform_device(dev)) struct vidi_win_data { unsigned int offset_x; @@ -94,7 +94,8 @@ static const struct of_device_id vidi_driver_dt_match[] = { static bool vidi_display_is_connected(struct device *dev) { - struct vidi_context *ctx = get_vidi_context(dev); + struct exynos_drm_manager *mgr = get_vidi_mgr(dev); + struct vidi_context *ctx = mgr->ctx; /* * connection request would come from user side @@ -106,7 +107,8 @@ static bool vidi_display_is_connected(struct device *dev) static struct edid *vidi_get_edid(struct device *dev, struct drm_connector *connector) { - struct vidi_context *ctx = get_vidi_context(dev); + struct exynos_drm_manager *mgr = get_vidi_mgr(dev); + struct vidi_context *ctx = mgr->ctx; struct edid *edid; int edid_len; @@ -159,9 +161,9 @@ static struct exynos_drm_display_ops vidi_display_ops = { .power_on = vidi_display_power_on, }; -static void vidi_dpms(struct device *subdrv_dev, int mode) +static void vidi_dpms(struct exynos_drm_manager *mgr, int mode) { - struct vidi_context *ctx = get_vidi_context(subdrv_dev); + struct vidi_context *ctx = mgr->ctx; DRM_DEBUG_KMS("%d\n", mode); @@ -184,10 +186,9 @@ static void vidi_dpms(struct device *subdrv_dev, int mode) mutex_unlock(&ctx->lock); } -static void vidi_apply(struct device *subdrv_dev) +static void vidi_apply(struct exynos_drm_manager *mgr) { - struct vidi_context *ctx = get_vidi_context(subdrv_dev); - struct exynos_drm_manager *mgr = ctx->subdrv.manager; + struct vidi_context *ctx = mgr->ctx; struct exynos_drm_manager_ops *mgr_ops = mgr->ops; struct vidi_win_data *win_data; int i; @@ -195,24 +196,24 @@ static void vidi_apply(struct device *subdrv_dev) for (i = 0; i < WINDOWS_NR; i++) { win_data = &ctx->win_data[i]; if (win_data->enabled && (mgr_ops && mgr_ops->win_commit)) - mgr_ops->win_commit(subdrv_dev, i); + mgr_ops->win_commit(mgr, i); } if (mgr_ops && mgr_ops->commit) - mgr_ops->commit(subdrv_dev); + mgr_ops->commit(mgr); } -static void vidi_commit(struct device *dev) +static void vidi_commit(struct exynos_drm_manager *mgr) { - struct vidi_context *ctx = get_vidi_context(dev); + struct vidi_context *ctx = mgr->ctx; if (ctx->suspended) return; } -static int vidi_enable_vblank(struct device *dev) +static int vidi_enable_vblank(struct exynos_drm_manager *mgr) { - struct vidi_context *ctx = get_vidi_context(dev); + struct vidi_context *ctx = mgr->ctx; if (ctx->suspended) return -EPERM; @@ -232,9 +233,9 @@ static int vidi_enable_vblank(struct device *dev) return 0; } -static void vidi_disable_vblank(struct device *dev) +static void vidi_disable_vblank(struct exynos_drm_manager *mgr) { - struct vidi_context *ctx = get_vidi_context(dev); + struct vidi_context *ctx = mgr->ctx; if (ctx->suspended) return; @@ -243,16 +244,16 @@ static void vidi_disable_vblank(struct device *dev) ctx->vblank_on = false; } -static void vidi_win_mode_set(struct device *dev, - struct exynos_drm_overlay *overlay) +static void vidi_win_mode_set(struct exynos_drm_manager *mgr, + struct exynos_drm_overlay *overlay) { - struct vidi_context *ctx = get_vidi_context(dev); + struct vidi_context *ctx = mgr->ctx; struct vidi_win_data *win_data; int win; unsigned long offset; if (!overlay) { - dev_err(dev, "overlay is NULL\n"); + DRM_ERROR("overlay is NULL\n"); return; } @@ -296,9 +297,9 @@ static void vidi_win_mode_set(struct device *dev, overlay->fb_width, overlay->crtc_width); } -static void vidi_win_commit(struct device *dev, int zpos) +static void vidi_win_commit(struct exynos_drm_manager *mgr, int zpos) { - struct vidi_context *ctx = get_vidi_context(dev); + struct vidi_context *ctx = mgr->ctx; struct vidi_win_data *win_data; int win = zpos; @@ -321,9 +322,9 @@ static void vidi_win_commit(struct device *dev, int zpos) schedule_work(&ctx->work); } -static void vidi_win_disable(struct device *dev, int zpos) +static void vidi_win_disable(struct exynos_drm_manager *mgr, int zpos) { - struct vidi_context *ctx = get_vidi_context(dev); + struct vidi_context *ctx = mgr->ctx; struct vidi_win_data *win_data; int win = zpos; @@ -400,10 +401,11 @@ static void vidi_subdrv_remove(struct drm_device *drm_dev, struct device *dev) /* TODO. */ } -static int vidi_power_on(struct vidi_context *ctx, bool enable) +static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable) { - struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct device *dev = subdrv->dev; + struct vidi_context *ctx = mgr->ctx; + + DRM_DEBUG_KMS("%s\n", __FILE__); if (enable != false && enable != true) return -EINVAL; @@ -413,9 +415,9 @@ static int vidi_power_on(struct vidi_context *ctx, bool enable) /* if vblank was enabled status, enable it again. */ if (test_and_clear_bit(0, &ctx->irq_flags)) - vidi_enable_vblank(dev); + vidi_enable_vblank(mgr); - vidi_apply(dev); + vidi_apply(mgr); } else { ctx->suspended = true; } @@ -427,7 +429,8 @@ static int vidi_show_connection(struct device *dev, struct device_attribute *attr, char *buf) { int rc; - struct vidi_context *ctx = get_vidi_context(dev); + struct exynos_drm_manager *mgr = get_vidi_mgr(dev); + struct vidi_context *ctx = mgr->ctx; mutex_lock(&ctx->lock); @@ -442,7 +445,8 @@ static int vidi_store_connection(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct vidi_context *ctx = get_vidi_context(dev); + struct exynos_drm_manager *mgr = get_vidi_mgr(dev); + struct vidi_context *ctx = mgr->ctx; int ret; ret = kstrtoint(buf, 0, &ctx->connected); @@ -498,7 +502,7 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, display_ops = manager->display_ops; if (display_ops->type == EXYNOS_DISPLAY_TYPE_VIDI) { - ctx = get_vidi_context(manager->dev); + ctx = manager->ctx; break; } } @@ -558,6 +562,8 @@ static int vidi_probe(struct platform_device *pdev) INIT_WORK(&ctx->work, vidi_fake_vblank_handler); + vidi_manager.ctx = ctx; + subdrv = &ctx->subdrv; subdrv->dev = dev; subdrv->manager = &vidi_manager; @@ -566,7 +572,7 @@ static int vidi_probe(struct platform_device *pdev) mutex_init(&ctx->lock); - platform_set_drvdata(pdev, ctx); + platform_set_drvdata(pdev, &vidi_manager); ret = device_create_file(dev, &dev_attr_connection); if (ret < 0) @@ -594,16 +600,16 @@ static int vidi_remove(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP static int vidi_suspend(struct device *dev) { - struct vidi_context *ctx = get_vidi_context(dev); + struct exynos_drm_manager *mgr = get_vidi_mgr(dev); - return vidi_power_on(ctx, false); + return vidi_power_on(mgr, false); } static int vidi_resume(struct device *dev) { - struct vidi_context *ctx = get_vidi_context(dev); + struct exynos_drm_manager *mgr = get_vidi_mgr(dev); - return vidi_power_on(ctx, true); + return vidi_power_on(mgr, true); } #endif -- 2.7.4