atomic_t wait_vsync_event;
struct exynos_drm_panel_info panel;
- struct exynos_drm_display *display;
+ struct exynos_drm_encoder *encoder;
};
static const struct of_device_id decon_driver_dt_match[] = {
return PTR_ERR(ctx->crtc);
}
- if (ctx->display)
- exynos_drm_create_enc_conn(drm_dev, ctx->display);
+ if (ctx->encoder)
+ exynos_drm_create_enc_conn(drm_dev, ctx->encoder,
+ EXYNOS_DISPLAY_TYPE_LCD);
return 0;
decon_disable(ctx->crtc);
- if (ctx->display)
- exynos_dpi_remove(ctx->display);
+ if (ctx->encoder)
+ exynos_dpi_remove(ctx->encoder);
decon_ctx_remove(ctx);
}
platform_set_drvdata(pdev, ctx);
- ctx->display = exynos_dpi_probe(dev);
- if (IS_ERR(ctx->display)) {
- ret = PTR_ERR(ctx->display);
+ ctx->encoder = exynos_dpi_probe(dev);
+ if (IS_ERR(ctx->encoder)) {
+ ret = PTR_ERR(ctx->encoder);
goto err_iounmap;
}
static inline struct exynos_drm_crtc *dp_to_crtc(struct exynos_dp_device *dp)
{
- return to_exynos_crtc(dp->encoder->crtc);
+ return to_exynos_crtc(dp->encoder.base.crtc);
}
-static inline struct exynos_dp_device *
-display_to_dp(struct exynos_drm_display *d)
+static inline struct exynos_dp_device *encoder_to_dp(
+ struct exynos_drm_encoder *e)
{
- return container_of(d, struct exynos_dp_device, display);
+ return container_of(e, struct exynos_dp_device, encoder);
}
struct bridge_init {
drm_helper_hpd_irq_event(dp->drm_dev);
}
-static void exynos_dp_commit(struct exynos_drm_display *display)
+static void exynos_dp_commit(struct exynos_drm_encoder *encoder)
{
- struct exynos_dp_device *dp = display_to_dp(display);
+ struct exynos_dp_device *dp = encoder_to_dp(encoder);
int ret;
/* Keep the panel disabled while we configure video */
{
struct exynos_dp_device *dp = ctx_from_connector(connector);
- return dp->encoder;
+ return &dp->encoder.base;
}
static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
return 0;
}
-static int exynos_dp_create_connector(struct exynos_drm_display *display,
- struct drm_encoder *encoder)
+static int exynos_dp_create_connector(struct exynos_drm_encoder *exynos_encoder)
{
- struct exynos_dp_device *dp = display_to_dp(display);
+ struct exynos_dp_device *dp = encoder_to_dp(exynos_encoder);
+ struct drm_encoder *encoder = &exynos_encoder->base;
struct drm_connector *connector = &dp->connector;
int ret;
- dp->encoder = encoder;
-
/* Pre-empt DP connector creation if there's a bridge */
if (dp->bridge) {
ret = exynos_drm_attach_lcd_bridge(dp, encoder);
return ret;
}
-static void exynos_dp_enable(struct exynos_drm_display *display)
+static void exynos_dp_enable(struct exynos_drm_encoder *encoder)
{
- struct exynos_dp_device *dp = display_to_dp(display);
+ struct exynos_dp_device *dp = encoder_to_dp(encoder);
struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
if (dp->dpms_mode == DRM_MODE_DPMS_ON)
phy_power_on(dp->phy);
exynos_dp_init_dp(dp);
enable_irq(dp->irq);
- exynos_dp_commit(&dp->display);
+ exynos_dp_commit(&dp->encoder);
dp->dpms_mode = DRM_MODE_DPMS_ON;
}
-static void exynos_dp_disable(struct exynos_drm_display *display)
+static void exynos_dp_disable(struct exynos_drm_encoder *encoder)
{
- struct exynos_dp_device *dp = display_to_dp(display);
+ struct exynos_dp_device *dp = encoder_to_dp(encoder);
struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
if (dp->dpms_mode != DRM_MODE_DPMS_ON)
dp->dpms_mode = DRM_MODE_DPMS_OFF;
}
-static struct exynos_drm_display_ops exynos_dp_display_ops = {
+static struct exynos_drm_encoder_ops exynos_dp_encoder_ops = {
.create_connector = exynos_dp_create_connector,
.enable = exynos_dp_enable,
.disable = exynos_dp_disable,
dp->drm_dev = drm_dev;
- return exynos_drm_create_enc_conn(drm_dev, &dp->display);
+ return exynos_drm_create_enc_conn(drm_dev, &dp->encoder,
+ EXYNOS_DISPLAY_TYPE_LCD);
}
static void exynos_dp_unbind(struct device *dev, struct device *master,
{
struct exynos_dp_device *dp = dev_get_drvdata(dev);
- exynos_dp_disable(&dp->display);
+ exynos_dp_disable(&dp->encoder);
}
static const struct component_ops exynos_dp_ops = {
if (!dp)
return -ENOMEM;
- dp->display.type = EXYNOS_DISPLAY_TYPE_LCD;
- dp->display.ops = &exynos_dp_display_ops;
+ dp->encoder.ops = &exynos_dp_encoder_ops;
platform_set_drvdata(pdev, dp);
panel_node = of_parse_phandle(dev->of_node, "panel", 0);
{
struct exynos_dp_device *dp = dev_get_drvdata(dev);
- exynos_dp_disable(&dp->display);
+ exynos_dp_disable(&dp->encoder);
return 0;
}
{
struct exynos_dp_device *dp = dev_get_drvdata(dev);
- exynos_dp_enable(&dp->display);
+ exynos_dp_enable(&dp->encoder);
return 0;
}
#endif
};
struct exynos_dp_device {
- struct exynos_drm_display display;
+ struct exynos_drm_encoder encoder;
struct device *dev;
struct drm_device *drm_dev;
struct drm_connector connector;
- struct drm_encoder *encoder;
struct drm_panel *panel;
struct drm_bridge *bridge;
struct clk *clock;
static LIST_HEAD(exynos_drm_subdrv_list);
int exynos_drm_create_enc_conn(struct drm_device *dev,
- struct exynos_drm_display *display)
+ struct exynos_drm_encoder *exynos_encoder,
+ enum exynos_drm_output_type type)
{
- struct drm_encoder *encoder;
int ret;
unsigned long possible_crtcs = 0;
- ret = exynos_drm_crtc_get_pipe_from_type(dev, display->type);
+ ret = exynos_drm_crtc_get_pipe_from_type(dev, type);
if (ret < 0)
return ret;
possible_crtcs |= 1 << ret;
/* create and initialize a encoder for this sub driver. */
- encoder = exynos_drm_encoder_create(dev, display, possible_crtcs);
- if (!encoder) {
+ ret = exynos_drm_encoder_create(dev, exynos_encoder, possible_crtcs);
+ if (ret) {
DRM_ERROR("failed to create encoder\n");
- return -EFAULT;
+ return ret;
}
- display->encoder = encoder;
-
- ret = display->ops->create_connector(display, encoder);
+ ret = exynos_encoder->ops->create_connector(exynos_encoder);
if (ret) {
DRM_ERROR("failed to create connector ret = %d\n", ret);
- goto err_destroy_encoder;
+ drm_encoder_cleanup(&exynos_encoder->base);
+ return ret;
}
return 0;
-
-err_destroy_encoder:
- encoder->funcs->destroy(encoder);
- return ret;
}
int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv)
}
int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
- unsigned int out_type)
+ enum exynos_drm_output_type out_type)
{
struct drm_crtc *crtc;
/* This function gets pipe value to crtc device matched with out_type. */
int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
- unsigned int out_type);
+ enum exynos_drm_output_type out_type);
/*
* This function calls the crtc device(manager)'s te_handler() callback
#include "exynos_drm_drv.h"
struct exynos_dpi {
- struct exynos_drm_display display;
+ struct exynos_drm_encoder encoder;
struct device *dev;
struct device_node *panel_node;
struct drm_panel *panel;
struct drm_connector connector;
- struct drm_encoder *encoder;
struct videomode *vm;
};
#define connector_to_dpi(c) container_of(c, struct exynos_dpi, connector)
-static inline struct exynos_dpi *display_to_dpi(struct exynos_drm_display *d)
+static inline struct exynos_dpi *encoder_to_dpi(struct exynos_drm_encoder *e)
{
- return container_of(d, struct exynos_dpi, display);
+ return container_of(e, struct exynos_dpi, encoder);
}
static enum drm_connector_status
{
struct exynos_dpi *ctx = connector_to_dpi(connector);
- return ctx->encoder;
+ return &ctx->encoder.base;
}
static struct drm_connector_helper_funcs exynos_dpi_connector_helper_funcs = {
.best_encoder = exynos_dpi_best_encoder,
};
-static int exynos_dpi_create_connector(struct exynos_drm_display *display,
- struct drm_encoder *encoder)
+static int exynos_dpi_create_connector(
+ struct exynos_drm_encoder *exynos_encoder)
{
- struct exynos_dpi *ctx = display_to_dpi(display);
+ struct exynos_dpi *ctx = encoder_to_dpi(exynos_encoder);
+ struct drm_encoder *encoder = &exynos_encoder->base;
struct drm_connector *connector = &ctx->connector;
int ret;
- ctx->encoder = encoder;
-
connector->polled = DRM_CONNECTOR_POLL_HPD;
ret = drm_connector_init(encoder->dev, connector,
return 0;
}
-static void exynos_dpi_enable(struct exynos_drm_display *display)
+static void exynos_dpi_enable(struct exynos_drm_encoder *encoder)
{
- struct exynos_dpi *ctx = display_to_dpi(display);
+ struct exynos_dpi *ctx = encoder_to_dpi(encoder);
if (ctx->panel) {
drm_panel_prepare(ctx->panel);
}
}
-static void exynos_dpi_disable(struct exynos_drm_display *display)
+static void exynos_dpi_disable(struct exynos_drm_encoder *encoder)
{
- struct exynos_dpi *ctx = display_to_dpi(display);
+ struct exynos_dpi *ctx = encoder_to_dpi(encoder);
if (ctx->panel) {
drm_panel_disable(ctx->panel);
}
}
-static struct exynos_drm_display_ops exynos_dpi_display_ops = {
+static struct exynos_drm_encoder_ops exynos_dpi_encoder_ops = {
.create_connector = exynos_dpi_create_connector,
.enable = exynos_dpi_enable,
.disable = exynos_dpi_disable,
return 0;
}
-struct exynos_drm_display *exynos_dpi_probe(struct device *dev)
+struct exynos_drm_encoder *exynos_dpi_probe(struct device *dev)
{
struct exynos_dpi *ctx;
int ret;
if (!ctx)
return ERR_PTR(-ENOMEM);
- ctx->display.type = EXYNOS_DISPLAY_TYPE_LCD;
- ctx->display.ops = &exynos_dpi_display_ops;
+ ctx->encoder.ops = &exynos_dpi_encoder_ops;
ctx->dev = dev;
ret = exynos_dpi_parse_dt(ctx);
return ERR_PTR(-EPROBE_DEFER);
}
- return &ctx->display;
+ return &ctx->encoder;
}
-int exynos_dpi_remove(struct exynos_drm_display *display)
+int exynos_dpi_remove(struct exynos_drm_encoder *encoder)
{
- struct exynos_dpi *ctx = display_to_dpi(display);
+ struct exynos_dpi *ctx = encoder_to_dpi(encoder);
- exynos_dpi_disable(&ctx->display);
+ exynos_dpi_disable(&ctx->encoder);
if (ctx->panel)
drm_panel_detach(ctx->panel);
#define MAX_PLANE 5
#define MAX_FB_BUFFER 4
+#define to_exynos_encoder(x) container_of(x, struct exynos_drm_encoder, base)
#define to_exynos_crtc(x) container_of(x, struct exynos_drm_crtc, base)
#define to_exynos_plane(x) container_of(x, struct exynos_drm_plane, base)
};
/*
- * Exynos DRM Display Structure.
+ * Exynos DRM Encoder Structure.
* - this structure is common to analog tv, digital tv and lcd panel.
*
* @create_connector: initialize and register a new connector
* @disable: display device off.
* @commit: apply changes to hw
*/
-struct exynos_drm_display;
-struct exynos_drm_display_ops {
- int (*create_connector)(struct exynos_drm_display *display,
- struct drm_encoder *encoder);
- void (*mode_fixup)(struct exynos_drm_display *display,
+struct exynos_drm_encoder;
+struct exynos_drm_encoder_ops {
+ int (*create_connector)(struct exynos_drm_encoder *encoder);
+ void (*mode_fixup)(struct exynos_drm_encoder *encoder,
struct drm_connector *connector,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
- void (*mode_set)(struct exynos_drm_display *display,
+ void (*mode_set)(struct exynos_drm_encoder *encoder,
struct drm_display_mode *mode);
- void (*enable)(struct exynos_drm_display *display);
- void (*disable)(struct exynos_drm_display *display);
- void (*commit)(struct exynos_drm_display *display);
+ void (*enable)(struct exynos_drm_encoder *encoder);
+ void (*disable)(struct exynos_drm_encoder *encoder);
+ void (*commit)(struct exynos_drm_encoder *encoder);
};
/*
- * Exynos drm display structure, maps 1:1 with an encoder/connector
+ * exynos specific encoder structure.
*
- * @list: the list entry for this manager
+ * @drm_encoder: encoder object.
* @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI.
- * @encoder: encoder object this display maps to
- * @connector: connector object this display maps to
* @ops: pointer to callbacks for exynos drm specific functionality
- * @ctx: A pointer to the display's implementation specific context
*/
-struct exynos_drm_display {
- struct list_head list;
- enum exynos_drm_output_type type;
- struct drm_encoder *encoder;
- struct drm_connector *connector;
- struct exynos_drm_display_ops *ops;
+struct exynos_drm_encoder {
+ struct drm_encoder base;
+ struct exynos_drm_encoder_ops *ops;
};
/*
void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file);
#ifdef CONFIG_DRM_EXYNOS_DPI
-struct exynos_drm_display * exynos_dpi_probe(struct device *dev);
-int exynos_dpi_remove(struct exynos_drm_display *display);
+struct exynos_drm_encoder *exynos_dpi_probe(struct device *dev);
+int exynos_dpi_remove(struct exynos_drm_encoder *encoder);
#else
-static inline struct exynos_drm_display *
+static inline struct exynos_drm_encoder *
exynos_dpi_probe(struct device *dev) { return NULL; }
-static inline int exynos_dpi_remove(struct exynos_drm_display *display)
+static inline int exynos_dpi_remove(struct exynos_drm_encoder *encoder)
{
return 0;
}
/* This function creates a encoder and a connector, and initializes them. */
int exynos_drm_create_enc_conn(struct drm_device *dev,
- struct exynos_drm_display *display);
+ struct exynos_drm_encoder *encoder,
+ enum exynos_drm_output_type type);
extern struct platform_driver fimd_driver;
extern struct platform_driver exynos5433_decon_driver;
};
struct exynos_dsi {
- struct exynos_drm_display display;
+ struct exynos_drm_encoder encoder;
struct mipi_dsi_host dsi_host;
struct drm_connector connector;
struct device_node *panel_node;
#define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
#define connector_to_dsi(c) container_of(c, struct exynos_dsi, connector)
-static inline struct exynos_dsi *display_to_dsi(struct exynos_drm_display *d)
+static inline struct exynos_dsi *encoder_to_dsi(struct exynos_drm_encoder *e)
{
- return container_of(d, struct exynos_dsi, display);
+ return container_of(e, struct exynos_dsi, encoder);
}
enum reg_idx {
static irqreturn_t exynos_dsi_te_irq_handler(int irq, void *dev_id)
{
struct exynos_dsi *dsi = (struct exynos_dsi *)dev_id;
- struct drm_encoder *encoder = dsi->display.encoder;
+ struct drm_encoder *encoder = &dsi->encoder.base;
if (dsi->state & DSIM_STATE_VIDOUT_AVAILABLE)
exynos_drm_crtc_te_handler(encoder->crtc);
dev_err(dsi->dev, "cannot disable regulators %d\n", ret);
}
-static void exynos_dsi_enable(struct exynos_drm_display *display)
+static void exynos_dsi_enable(struct exynos_drm_encoder *encoder)
{
- struct exynos_dsi *dsi = display_to_dsi(display);
+ struct exynos_dsi *dsi = encoder_to_dsi(encoder);
int ret;
if (dsi->state & DSIM_STATE_ENABLED)
dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
}
-static void exynos_dsi_disable(struct exynos_drm_display *display)
+static void exynos_dsi_disable(struct exynos_drm_encoder *encoder)
{
- struct exynos_dsi *dsi = display_to_dsi(display);
+ struct exynos_dsi *dsi = encoder_to_dsi(encoder);
if (!(dsi->state & DSIM_STATE_ENABLED))
return;
if (dsi->panel)
drm_panel_attach(dsi->panel, &dsi->connector);
} else if (!dsi->panel_node) {
- struct exynos_drm_display *display;
+ struct exynos_drm_encoder *encoder;
- display = platform_get_drvdata(to_platform_device(dsi->dev));
- exynos_dsi_disable(display);
+ encoder = platform_get_drvdata(to_platform_device(dsi->dev));
+ exynos_dsi_disable(encoder);
drm_panel_detach(dsi->panel);
dsi->panel = NULL;
}
{
struct exynos_dsi *dsi = connector_to_dsi(connector);
- return dsi->display.encoder;
+ return &dsi->encoder.base;
}
static struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs = {
.best_encoder = exynos_dsi_best_encoder,
};
-static int exynos_dsi_create_connector(struct exynos_drm_display *display,
- struct drm_encoder *encoder)
+static int exynos_dsi_create_connector(
+ struct exynos_drm_encoder *exynos_encoder)
{
- struct exynos_dsi *dsi = display_to_dsi(display);
+ struct exynos_dsi *dsi = encoder_to_dsi(exynos_encoder);
+ struct drm_encoder *encoder = &exynos_encoder->base;
struct drm_connector *connector = &dsi->connector;
int ret;
return 0;
}
-static void exynos_dsi_mode_set(struct exynos_drm_display *display,
+static void exynos_dsi_mode_set(struct exynos_drm_encoder *encoder,
struct drm_display_mode *mode)
{
- struct exynos_dsi *dsi = display_to_dsi(display);
+ struct exynos_dsi *dsi = encoder_to_dsi(encoder);
struct videomode *vm = &dsi->vm;
vm->hactive = mode->hdisplay;
vm->hsync_len = mode->hsync_end - mode->hsync_start;
}
-static struct exynos_drm_display_ops exynos_dsi_display_ops = {
+static struct exynos_drm_encoder_ops exynos_dsi_encoder_ops = {
.create_connector = exynos_dsi_create_connector,
.mode_set = exynos_dsi_mode_set,
.enable = exynos_dsi_enable,
static int exynos_dsi_bind(struct device *dev, struct device *master,
void *data)
{
- struct exynos_drm_display *display = dev_get_drvdata(dev);
- struct exynos_dsi *dsi = display_to_dsi(display);
+ struct exynos_drm_encoder *encoder = dev_get_drvdata(dev);
+ struct exynos_dsi *dsi = encoder_to_dsi(encoder);
struct drm_device *drm_dev = data;
struct drm_bridge *bridge;
int ret;
- ret = exynos_drm_create_enc_conn(drm_dev, display);
+ ret = exynos_drm_create_enc_conn(drm_dev, encoder,
+ EXYNOS_DISPLAY_TYPE_LCD);
if (ret) {
DRM_ERROR("Encoder create [%d] failed with %d\n",
- display->type, ret);
+ EXYNOS_DISPLAY_TYPE_LCD, ret);
return ret;
}
bridge = of_drm_find_bridge(dsi->bridge_node);
if (bridge) {
- display->encoder->bridge = bridge;
drm_bridge_attach(drm_dev, bridge);
}
static void exynos_dsi_unbind(struct device *dev, struct device *master,
void *data)
{
- struct exynos_drm_display *display = dev_get_drvdata(dev);
- struct exynos_dsi *dsi = display_to_dsi(display);
+ struct exynos_drm_encoder *encoder = dev_get_drvdata(dev);
+ struct exynos_dsi *dsi = encoder_to_dsi(encoder);
- exynos_dsi_disable(display);
+ exynos_dsi_disable(encoder);
mipi_dsi_host_unregister(&dsi->dsi_host);
}
if (!dsi)
return -ENOMEM;
- dsi->display.type = EXYNOS_DISPLAY_TYPE_LCD;
- dsi->display.ops = &exynos_dsi_display_ops;
+ dsi->encoder.ops = &exynos_dsi_encoder_ops;
/* To be checked as invalid one */
dsi->te_gpio = -ENOENT;
return ret;
}
- platform_set_drvdata(pdev, &dsi->display);
+ platform_set_drvdata(pdev, &dsi->encoder);
return component_add(dev, &exynos_dsi_component_ops);
}
#include "exynos_drm_drv.h"
#include "exynos_drm_encoder.h"
-#define to_exynos_encoder(x) container_of(x, struct exynos_drm_encoder,\
- drm_encoder)
-
-/*
- * exynos specific encoder structure.
- *
- * @drm_encoder: encoder object.
- * @display: the display structure that maps to this encoder
- */
-struct exynos_drm_encoder {
- struct drm_encoder drm_encoder;
- struct exynos_drm_display *display;
-};
-
static bool
exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
{
struct drm_device *dev = encoder->dev;
struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
- struct exynos_drm_display *display = exynos_encoder->display;
struct drm_connector *connector;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (connector->encoder != encoder)
continue;
- if (display->ops->mode_fixup)
- display->ops->mode_fixup(display, connector, mode,
- adjusted_mode);
+ if (exynos_encoder->ops->mode_fixup)
+ exynos_encoder->ops->mode_fixup(exynos_encoder,
+ connector, mode,
+ adjusted_mode);
}
return true;
struct drm_display_mode *adjusted_mode)
{
struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
- struct exynos_drm_display *display = exynos_encoder->display;
- if (display->ops->mode_set)
- display->ops->mode_set(display, adjusted_mode);
+ if (exynos_encoder->ops->mode_set)
+ exynos_encoder->ops->mode_set(exynos_encoder, adjusted_mode);
}
static void exynos_drm_encoder_enable(struct drm_encoder *encoder)
{
struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
- struct exynos_drm_display *display = exynos_encoder->display;
- if (display->ops->enable)
- display->ops->enable(display);
+ if (exynos_encoder->ops->enable)
+ exynos_encoder->ops->enable(exynos_encoder);
- if (display->ops->commit)
- display->ops->commit(display);
+ if (exynos_encoder->ops->commit)
+ exynos_encoder->ops->commit(exynos_encoder);
}
static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
{
struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
- struct exynos_drm_display *display = exynos_encoder->display;
- if (display->ops->disable)
- display->ops->disable(display);
+ if (exynos_encoder->ops->disable)
+ exynos_encoder->ops->disable(exynos_encoder);
}
static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = {
.disable = exynos_drm_encoder_disable,
};
-static void exynos_drm_encoder_destroy(struct drm_encoder *encoder)
-{
- struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
-
- drm_encoder_cleanup(encoder);
- kfree(exynos_encoder);
-}
-
static struct drm_encoder_funcs exynos_encoder_funcs = {
- .destroy = exynos_drm_encoder_destroy,
+ .destroy = drm_encoder_cleanup,
};
void exynos_drm_encoder_setup(struct drm_device *dev)
encoder->possible_clones = clone_mask;
}
-struct drm_encoder *
-exynos_drm_encoder_create(struct drm_device *dev,
- struct exynos_drm_display *display,
- unsigned long possible_crtcs)
+int exynos_drm_encoder_create(struct drm_device *dev,
+ struct exynos_drm_encoder *exynos_encoder,
+ unsigned long possible_crtcs)
{
struct drm_encoder *encoder;
- struct exynos_drm_encoder *exynos_encoder;
if (!possible_crtcs)
- return NULL;
-
- exynos_encoder = kzalloc(sizeof(*exynos_encoder), GFP_KERNEL);
- if (!exynos_encoder)
- return NULL;
+ return -EINVAL;
- exynos_encoder->display = display;
- encoder = &exynos_encoder->drm_encoder;
+ encoder = &exynos_encoder->base;
encoder->possible_crtcs = possible_crtcs;
DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
DRM_DEBUG_KMS("encoder has been created\n");
- return encoder;
-}
-
-struct exynos_drm_display *exynos_drm_get_display(struct drm_encoder *encoder)
-{
- return to_exynos_encoder(encoder)->display;
+ return 0;
}
#define _EXYNOS_DRM_ENCODER_H_
void exynos_drm_encoder_setup(struct drm_device *dev);
-struct drm_encoder *exynos_drm_encoder_create(struct drm_device *dev,
- struct exynos_drm_display *mgr,
- unsigned long possible_crtcs);
-struct exynos_drm_display *exynos_drm_get_display(struct drm_encoder *encoder);
+int exynos_drm_encoder_create(struct drm_device *dev, struct exynos_drm_encoder
+ *encoder, unsigned long possible_crtcs);
#endif
struct exynos_drm_panel_info panel;
struct fimd_driver_data *driver_data;
- struct exynos_drm_display *display;
+ struct exynos_drm_encoder *encoder;
};
static const struct of_device_id fimd_driver_dt_match[] = {
if (IS_ERR(ctx->crtc))
return PTR_ERR(ctx->crtc);
- if (ctx->display)
- exynos_drm_create_enc_conn(drm_dev, ctx->display);
+ if (ctx->encoder)
+ exynos_drm_create_enc_conn(drm_dev, ctx->encoder,
+ EXYNOS_DISPLAY_TYPE_LCD);
if (is_drm_iommu_supported(drm_dev))
fimd_clear_channels(ctx->crtc);
drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
- if (ctx->display)
- exynos_dpi_remove(ctx->display);
+ if (ctx->encoder)
+ exynos_dpi_remove(ctx->encoder);
}
static const struct component_ops fimd_component_ops = {
platform_set_drvdata(pdev, ctx);
- ctx->display = exynos_dpi_probe(dev);
- if (IS_ERR(ctx->display)) {
- return PTR_ERR(ctx->display);
- }
+ ctx->encoder = exynos_dpi_probe(dev);
+ if (IS_ERR(ctx->encoder))
+ return PTR_ERR(ctx->encoder);
pm_runtime_enable(dev);
connector)
struct vidi_context {
- struct exynos_drm_display display;
+ struct exynos_drm_encoder encoder;
struct platform_device *pdev;
struct drm_device *drm_dev;
struct exynos_drm_crtc *crtc;
- struct drm_encoder *encoder;
struct drm_connector connector;
struct exynos_drm_plane planes[WINDOWS_NR];
struct edid *raw_edid;
int pipe;
};
-static inline struct vidi_context *display_to_vidi(struct exynos_drm_display *d)
+static inline struct vidi_context *encoder_to_vidi(struct exynos_drm_encoder *e)
{
- return container_of(d, struct vidi_context, display);
+ return container_of(e, struct vidi_context, encoder);
}
static const char fake_edid_info[] = {
int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
struct drm_file *file_priv)
{
- struct vidi_context *ctx = NULL;
- struct drm_encoder *encoder;
- struct exynos_drm_display *display;
+ struct vidi_context *ctx = dev_get_drvdata(drm_dev->dev);
struct drm_exynos_vidi_connection *vidi = data;
if (!vidi) {
return -EINVAL;
}
- list_for_each_entry(encoder, &drm_dev->mode_config.encoder_list,
- head) {
- display = exynos_drm_get_display(encoder);
-
- if (display->type == EXYNOS_DISPLAY_TYPE_VIDI) {
- ctx = display_to_vidi(display);
- break;
- }
- }
-
- if (!ctx) {
- DRM_DEBUG_KMS("not found virtual device type encoder.\n");
- return -EINVAL;
- }
-
if (ctx->connected == vidi->connection) {
DRM_DEBUG_KMS("same connection request.\n");
return -EINVAL;
{
struct vidi_context *ctx = ctx_from_connector(connector);
- return ctx->encoder;
+ return &ctx->encoder.base;
}
static struct drm_connector_helper_funcs vidi_connector_helper_funcs = {
.best_encoder = vidi_best_encoder,
};
-static int vidi_create_connector(struct exynos_drm_display *display,
- struct drm_encoder *encoder)
+static int vidi_create_connector(struct exynos_drm_encoder *exynos_encoder)
{
- struct vidi_context *ctx = display_to_vidi(display);
+ struct vidi_context *ctx = encoder_to_vidi(exynos_encoder);
+ struct drm_encoder *encoder = &exynos_encoder->base;
struct drm_connector *connector = &ctx->connector;
int ret;
- ctx->encoder = encoder;
connector->polled = DRM_CONNECTOR_POLL_HPD;
ret = drm_connector_init(ctx->drm_dev, connector,
}
-static struct exynos_drm_display_ops vidi_display_ops = {
+static struct exynos_drm_encoder_ops vidi_encoder_ops = {
.create_connector = vidi_create_connector,
};
return PTR_ERR(ctx->crtc);
}
- ret = exynos_drm_create_enc_conn(drm_dev, &ctx->display);
+ ret = exynos_drm_create_enc_conn(drm_dev, &ctx->encoder,
+ EXYNOS_DISPLAY_TYPE_VIDI);
if (ret) {
ctx->crtc->base.funcs->destroy(&ctx->crtc->base);
return ret;
if (!ctx)
return -ENOMEM;
- ctx->display.type = EXYNOS_DISPLAY_TYPE_VIDI;
- ctx->display.ops = &vidi_display_ops;
+ ctx->encoder.ops = &vidi_encoder_ops;
ctx->default_win = 0;
ctx->pdev = pdev;
};
struct hdmi_context {
- struct exynos_drm_display display;
+ struct exynos_drm_encoder encoder;
struct device *dev;
struct drm_device *drm_dev;
struct drm_connector connector;
- struct drm_encoder *encoder;
+ bool hpd;
bool powered;
bool dvi_mode;
struct regmap *pmureg;
};
-static inline struct hdmi_context *display_to_hdmi(struct exynos_drm_display *d)
+static inline struct hdmi_context *encoder_to_hdmi(struct exynos_drm_encoder *e)
{
- return container_of(d, struct hdmi_context, display);
+ return container_of(e, struct hdmi_context, encoder);
}
struct hdmiphy_config {
{
struct hdmi_context *hdata = ctx_from_connector(connector);
- return hdata->encoder;
+ return &hdata->encoder.base;
}
static struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
.best_encoder = hdmi_best_encoder,
};
-static int hdmi_create_connector(struct exynos_drm_display *display,
- struct drm_encoder *encoder)
+static int hdmi_create_connector(struct exynos_drm_encoder *exynos_encoder)
{
- struct hdmi_context *hdata = display_to_hdmi(display);
+ struct hdmi_context *hdata = encoder_to_hdmi(exynos_encoder);
struct drm_connector *connector = &hdata->connector;
int ret;
- hdata->encoder = encoder;
connector->interlace_allowed = true;
connector->polled = DRM_CONNECTOR_POLL_HPD;
drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
drm_connector_register(connector);
- drm_mode_connector_attach_encoder(connector, encoder);
+ drm_mode_connector_attach_encoder(connector, &exynos_encoder->base);
return 0;
}
-static void hdmi_mode_fixup(struct exynos_drm_display *display,
+static void hdmi_mode_fixup(struct exynos_drm_encoder *encoder,
struct drm_connector *connector,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
hdmi_regs_dump(hdata, "start");
}
-static void hdmi_mode_set(struct exynos_drm_display *display,
+static void hdmi_mode_set(struct exynos_drm_encoder *encoder,
struct drm_display_mode *mode)
{
- struct hdmi_context *hdata = display_to_hdmi(display);
+ struct hdmi_context *hdata = encoder_to_hdmi(encoder);
struct drm_display_mode *m = mode;
DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%s\n",
hdata->cea_video_id = drm_match_cea_mode(mode);
}
-static void hdmi_commit(struct exynos_drm_display *display)
+static void hdmi_commit(struct exynos_drm_encoder *encoder)
{
- struct hdmi_context *hdata = display_to_hdmi(display);
+ struct hdmi_context *hdata = encoder_to_hdmi(encoder);
if (!hdata->powered)
return;
hdmi_conf_apply(hdata);
}
-static void hdmi_enable(struct exynos_drm_display *display)
+static void hdmi_enable(struct exynos_drm_encoder *encoder)
{
- struct hdmi_context *hdata = display_to_hdmi(display);
+ struct hdmi_context *hdata = encoder_to_hdmi(encoder);
struct hdmi_resources *res = &hdata->res;
if (hdata->powered)
clk_prepare_enable(res->sclk_hdmi);
hdmiphy_poweron(hdata);
- hdmi_commit(display);
+ hdmi_commit(encoder);
}
-static void hdmi_disable(struct exynos_drm_display *display)
+static void hdmi_disable(struct exynos_drm_encoder *encoder)
{
- struct hdmi_context *hdata = display_to_hdmi(display);
+ struct hdmi_context *hdata = encoder_to_hdmi(encoder);
struct hdmi_resources *res = &hdata->res;
- struct drm_crtc *crtc = hdata->encoder->crtc;
+ struct drm_crtc *crtc = hdata->encoder.base.crtc;
const struct drm_crtc_helper_funcs *funcs = NULL;
if (!hdata->powered)
hdata->powered = false;
}
-static struct exynos_drm_display_ops hdmi_display_ops = {
+static struct exynos_drm_encoder_ops hdmi_encoder_ops = {
.create_connector = hdmi_create_connector,
.mode_fixup = hdmi_mode_fixup,
.mode_set = hdmi_mode_set,
hdata->drm_dev = drm_dev;
- return exynos_drm_create_enc_conn(drm_dev, &hdata->display);
+ return exynos_drm_create_enc_conn(drm_dev, &hdata->encoder,
+ EXYNOS_DISPLAY_TYPE_HDMI);
}
static void hdmi_unbind(struct device *dev, struct device *master, void *data)
return -ENODEV;
hdata->drv_data = match->data;
- hdata->display.type = EXYNOS_DISPLAY_TYPE_HDMI;
- hdata->display.ops = &hdmi_display_ops;
+ hdata->encoder.ops = &hdmi_encoder_ops;
platform_set_drvdata(pdev, hdata);