* 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);
* @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);
};
/*
* 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 {
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;
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);
}
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;
}
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
* real hardware.
*/
if (ops->wait_for_vblank)
- ops->wait_for_vblank(exynos_encoder->manager->dev);
+ ops->wait_for_vblank(exynos_encoder->manager);
}
}
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;
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)
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)
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
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)
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)
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)
zpos = *(int *)data;
if (manager_ops && manager_ops->win_disable)
- manager_ops->win_disable(manager->dev, zpos);
+ manager_ops->win_disable(manager, zpos);
}
/* 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;
struct fimd_context {
struct exynos_drm_subdrv subdrv;
+ struct device *dev;
struct drm_device *drm_dev;
int irq;
struct drm_crtc *crtc;
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;
}
.power_on = fimd_display_power_on,
};
-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);
* 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:
DRM_DEBUG_KMS("unspecified mode %d\n", mode);
mutex_unlock(&ctx->lock);
}
-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;
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 videomode *vm = &panel->vm;
struct fimd_driver_data *driver_data;
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)
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)
}
}
-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;
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;
}
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;
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 |
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;
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));
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;
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;
}
}
-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;
/* 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 {
if (!ctx)
return -ENOMEM;
+ ctx->dev = dev;
+
ret = fimd_get_platform_data(ctx, dev);
if (ret)
return ret;
init_waitqueue_head(&ctx->wait_vsync_queue);
atomic_set(&ctx->wait_vsync_event, 0);
+ fimd_manager.ctx = ctx;
+
subdrv = &ctx->subdrv;
subdrv->dev = dev;
mutex_init(&ctx->lock);
- platform_set_drvdata(pdev, ctx);
+ platform_set_drvdata(pdev, &fimd_manager);
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
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);
#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
* 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
if (!pm_runtime_suspended(dev)) {
int ret;
- ret = fimd_activate(ctx, true);
+ ret = fimd_activate(mgr, true);
if (ret < 0)
return ret;
* 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;
#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
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;
/*
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);
.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;
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)
* 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;
}
}
-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)
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);
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++) {
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) {
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) {
if (!ctx)
return -ENOMEM;
+ hdmi_manager.ctx = ctx;
+
subdrv = &ctx->subdrv;
subdrv->dev = dev;
/* 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;
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
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;
/*
.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);
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;
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;
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;
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;
}
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;
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;
/* 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;
if (enable) {
ctx->suspended = false;
/* 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;
}
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);
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);
display_ops = manager->display_ops;
if (display_ops->type == EXYNOS_DISPLAY_TYPE_VIDI) {
- ctx = get_vidi_context(manager->dev);
+ ctx = manager->ctx;
break;
}
}
INIT_WORK(&ctx->work, vidi_fake_vblank_handler);
+ vidi_manager.ctx = ctx;
+
subdrv = &ctx->subdrv;
subdrv->dev = dev;
subdrv->manager = &vidi_manager;
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)
#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