writel(val, ctx->regs + SHADOWCON);
}
-static void fimd_clear_channel(struct exynos_drm_crtc *crtc)
+static void fimd_clear_channel(struct fimd_context *ctx)
{
- struct fimd_context *ctx = crtc->ctx;
int win, ch_enabled = 0;
DRM_DEBUG_KMS("%s\n", __FILE__);
unsigned int state = ctx->suspended;
ctx->suspended = 0;
- fimd_wait_for_vblank(crtc);
+ fimd_wait_for_vblank(ctx->crtc);
ctx->suspended = state;
}
}
-static int fimd_ctx_initialize(struct fimd_context *ctx,
+static int fimd_iommu_attach_devices(struct fimd_context *ctx,
struct drm_device *drm_dev)
{
- struct exynos_drm_private *priv;
- priv = drm_dev->dev_private;
-
- ctx->drm_dev = drm_dev;
- ctx->pipe = priv->pipe++;
/* attach this sub driver to iommu mapping if supported. */
if (is_drm_iommu_supported(ctx->drm_dev)) {
* If any channel is already active, iommu will throw
* a PAGE FAULT when enabled. So clear any channel if enabled.
*/
- fimd_clear_channel(ctx->crtc);
+ fimd_clear_channel(ctx);
ret = drm_iommu_attach_device(ctx->drm_dev, ctx->dev);
if (ret) {
DRM_ERROR("drm_iommu_attach failed.\n");
return 0;
}
-static void fimd_ctx_remove(struct fimd_context *ctx)
+static void fimd_iommu_detach_devices(struct fimd_context *ctx)
{
/* detach this sub driver from iommu mapping if supported. */
if (is_drm_iommu_supported(ctx->drm_dev))
win_data->enabled = false;
}
-static void fimd_window_suspend(struct exynos_drm_crtc *crtc)
+static void fimd_window_suspend(struct fimd_context *ctx)
{
- struct fimd_context *ctx = crtc->ctx;
struct fimd_win_data *win_data;
int i;
win_data = &ctx->win_data[i];
win_data->resume = win_data->enabled;
if (win_data->enabled)
- fimd_win_disable(crtc, i);
+ fimd_win_disable(ctx->crtc, i);
}
}
-static void fimd_window_resume(struct exynos_drm_crtc *crtc)
+static void fimd_window_resume(struct fimd_context *ctx)
{
- struct fimd_context *ctx = crtc->ctx;
struct fimd_win_data *win_data;
int i;
}
}
-static void fimd_apply(struct exynos_drm_crtc *crtc)
+static void fimd_apply(struct fimd_context *ctx)
{
- struct fimd_context *ctx = crtc->ctx;
struct fimd_win_data *win_data;
int i;
for (i = 0; i < WINDOWS_NR; i++) {
win_data = &ctx->win_data[i];
if (win_data->enabled)
- fimd_win_commit(crtc, i);
+ fimd_win_commit(ctx->crtc, i);
else
- fimd_win_disable(crtc, i);
+ fimd_win_disable(ctx->crtc, i);
}
- fimd_commit(crtc);
+ fimd_commit(ctx->crtc);
}
-static int fimd_poweron(struct exynos_drm_crtc *crtc)
+static int fimd_poweron(struct fimd_context *ctx)
{
- struct fimd_context *ctx = crtc->ctx;
int ret;
if (!ctx->suspended)
/* if vblank was enabled status, enable it again. */
if (test_and_clear_bit(0, &ctx->irq_flags)) {
- ret = fimd_enable_vblank(crtc);
+ ret = fimd_enable_vblank(ctx->crtc);
if (ret) {
DRM_ERROR("Failed to re-enable vblank [%d]\n", ret);
goto enable_vblank_err;
}
}
- fimd_window_resume(crtc);
+ fimd_window_resume(ctx);
- fimd_apply(crtc);
+ fimd_apply(ctx);
return 0;
return ret;
}
-static int fimd_poweroff(struct exynos_drm_crtc *crtc)
+static int fimd_poweroff(struct fimd_context *ctx)
{
- struct fimd_context *ctx = crtc->ctx;
-
if (ctx->suspended)
return 0;
* suspend that connector. Otherwise we might try to scan from
* a destroyed buffer later.
*/
- fimd_window_suspend(crtc);
+ fimd_window_suspend(ctx);
clk_disable_unprepare(ctx->lcd_clk);
clk_disable_unprepare(ctx->bus_clk);
switch (mode) {
case DRM_MODE_DPMS_ON:
- fimd_poweron(crtc);
+ fimd_poweron(crtc->ctx);
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
- fimd_poweroff(crtc);
+ fimd_poweroff(crtc->ctx);
break;
default:
DRM_DEBUG_KMS("unspecified mode %d\n", mode);
{
struct fimd_context *ctx = dev_get_drvdata(dev);
struct drm_device *drm_dev = data;
+ struct exynos_drm_private *priv = drm_dev->dev_private;
int ret;
+ ctx->drm_dev = drm_dev;
+ ctx->pipe = priv->pipe++;
+
ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe,
EXYNOS_DISPLAY_TYPE_LCD,
&fimd_crtc_ops, ctx);
- if (IS_ERR(ctx->crtc))
- return PTR_ERR(ctx->crtc);
-
- ret = fimd_ctx_initialize(ctx, drm_dev);
- if (ret) {
- DRM_ERROR("fimd_ctx_initialize failed.\n");
- return ret;
- }
-
if (ctx->display)
exynos_drm_create_enc_conn(drm_dev, ctx->display);
+ ret = fimd_iommu_attach_devices(ctx, drm_dev);
+ if (ret)
+ return ret;
+
return 0;
}
fimd_dpms(ctx->crtc, DRM_MODE_DPMS_OFF);
+ fimd_iommu_detach_devices(ctx);
+
if (ctx->display)
exynos_dpi_remove(ctx->display);
-
- fimd_ctx_remove(ctx);
}
static const struct component_ops fimd_component_ops = {