From 032003c5cd744e8e0baf5430fc5b3fd5462208e4 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Fri, 8 Jul 2016 17:40:58 +0800 Subject: [PATCH] drm/imx: Remove encoders' ->prepare callbacks The main task of imx encoders' ->prepare callbacks is to set bus_format, bus_flags, di_vsync_pin and di_hsync_pin. We may create a structure named imx_encoder to cache them. The atomic encoder callback ->disable may replace ->prepare later, so let's remove ->prepare. Signed-off-by: Liu Ying Acked-by: Daniel Vetter Signed-off-by: Philipp Zabel --- drivers/gpu/drm/imx/dw_hdmi-imx.c | 18 ++-- drivers/gpu/drm/imx/imx-drm-core.c | 39 -------- drivers/gpu/drm/imx/imx-drm.h | 18 ++-- drivers/gpu/drm/imx/imx-ldb.c | 118 +++++++++++++------------ drivers/gpu/drm/imx/imx-tve.c | 58 +++++------- drivers/gpu/drm/imx/ipuv3-crtc.c | 38 +++----- drivers/gpu/drm/imx/parallel-display.c | 56 ++++++------ 7 files changed, 142 insertions(+), 203 deletions(-) diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c index a24631fdf4ad..5f646748960a 100644 --- a/drivers/gpu/drm/imx/dw_hdmi-imx.c +++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c @@ -22,9 +22,11 @@ #include "imx-drm.h" +#define imx_enc_to_imx_hdmi(x) container_of(x, struct imx_hdmi, imx_encoder) + struct imx_hdmi { struct device *dev; - struct drm_encoder encoder; + struct imx_drm_encoder imx_encoder; struct regmap *regmap; }; @@ -117,7 +119,8 @@ static void dw_hdmi_imx_encoder_mode_set(struct drm_encoder *encoder, static void dw_hdmi_imx_encoder_commit(struct drm_encoder *encoder) { - struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_hdmi *hdmi = imx_enc_to_imx_hdmi(imx_encoder); int mux = drm_of_encoder_active_port_id(hdmi->dev->of_node, encoder); regmap_update_bits(hdmi->regmap, IOMUXC_GPR3, @@ -125,14 +128,8 @@ static void dw_hdmi_imx_encoder_commit(struct drm_encoder *encoder) mux << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT); } -static void dw_hdmi_imx_encoder_prepare(struct drm_encoder *encoder) -{ - imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_RGB888_1X24); -} - static const struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs = { .mode_set = dw_hdmi_imx_encoder_mode_set, - .prepare = dw_hdmi_imx_encoder_prepare, .commit = dw_hdmi_imx_encoder_commit, .disable = dw_hdmi_imx_encoder_disable, }; @@ -215,7 +212,10 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master, match = of_match_node(dw_hdmi_imx_dt_ids, pdev->dev.of_node); plat_data = match->data; hdmi->dev = &pdev->dev; - encoder = &hdmi->encoder; + encoder = &hdmi->imx_encoder.encoder; + hdmi->imx_encoder.bus_format = MEDIA_BUS_FMT_RGB888_1X24; + hdmi->imx_encoder.di_hsync_pin = 2; + hdmi->imx_encoder.di_vsync_pin = 3; irq = platform_get_irq(pdev, 0); if (irq < 0) diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index b5a5173b05af..f6e44c220874 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c @@ -85,45 +85,6 @@ static int imx_drm_driver_unload(struct drm_device *drm) return 0; } -static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc) -{ - struct imx_drm_device *imxdrm = crtc->dev->dev_private; - unsigned i; - - for (i = 0; i < MAX_CRTC; i++) - if (imxdrm->crtc[i] && imxdrm->crtc[i]->crtc == crtc) - return imxdrm->crtc[i]; - - return NULL; -} - -int imx_drm_set_bus_config(struct drm_encoder *encoder, u32 bus_format, - int hsync_pin, int vsync_pin, u32 bus_flags) -{ - struct imx_drm_crtc_helper_funcs *helper; - struct imx_drm_crtc *imx_crtc; - - imx_crtc = imx_drm_find_crtc(encoder->crtc); - if (!imx_crtc) - return -EINVAL; - - helper = &imx_crtc->imx_drm_helper_funcs; - if (helper->set_interface_pix_fmt) - return helper->set_interface_pix_fmt(encoder->crtc, - bus_format, hsync_pin, vsync_pin, - bus_flags); - return 0; -} -EXPORT_SYMBOL_GPL(imx_drm_set_bus_config); - -int imx_drm_set_bus_format(struct drm_encoder *encoder, u32 bus_format) -{ - return imx_drm_set_bus_config(encoder, bus_format, 2, 3, - DRM_BUS_FLAG_DE_HIGH | - DRM_BUS_FLAG_PIXDATA_NEGEDGE); -} -EXPORT_SYMBOL_GPL(imx_drm_set_bus_format); - int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc) { return drm_crtc_vblank_get(imx_drm_crtc->crtc); diff --git a/drivers/gpu/drm/imx/imx-drm.h b/drivers/gpu/drm/imx/imx-drm.h index 74320a1723b7..39cef15c699b 100644 --- a/drivers/gpu/drm/imx/imx-drm.h +++ b/drivers/gpu/drm/imx/imx-drm.h @@ -15,12 +15,19 @@ struct platform_device; unsigned int imx_drm_crtc_id(struct imx_drm_crtc *crtc); +struct imx_drm_encoder { + struct drm_encoder encoder; + u32 bus_format; + u32 bus_flags; + int di_hsync_pin; + int di_vsync_pin; +}; + +#define enc_to_imx_enc(x) container_of(x, struct imx_drm_encoder, encoder) + struct imx_drm_crtc_helper_funcs { int (*enable_vblank)(struct drm_crtc *crtc); void (*disable_vblank)(struct drm_crtc *crtc); - int (*set_interface_pix_fmt)(struct drm_crtc *crtc, - u32 bus_format, int hsync_pin, int vsync_pin, - u32 bus_flags); const struct drm_crtc_helper_funcs *crtc_helper_funcs; const struct drm_crtc_funcs *crtc_funcs; }; @@ -42,11 +49,6 @@ void imx_drm_mode_config_init(struct drm_device *drm); struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb); -int imx_drm_set_bus_config(struct drm_encoder *encoder, u32 bus_format, - int hsync_pin, int vsync_pin, u32 bus_flags); -int imx_drm_set_bus_format(struct drm_encoder *encoder, - u32 bus_format); - int imx_drm_encoder_parse_of(struct drm_device *drm, struct drm_encoder *encoder, struct device_node *np); diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index 12bf368ae6df..6e110bba35cb 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c @@ -51,14 +51,15 @@ #define LDB_BGREF_RMODE_INT (1 << 15) #define con_to_imx_ldb_ch(x) container_of(x, struct imx_ldb_channel, connector) -#define enc_to_imx_ldb_ch(x) container_of(x, struct imx_ldb_channel, encoder) +#define imx_enc_to_imx_ldb_ch(x) \ + container_of(x, struct imx_ldb_channel, imx_encoder) struct imx_ldb; struct imx_ldb_channel { struct imx_ldb *ldb; struct drm_connector connector; - struct drm_encoder encoder; + struct imx_drm_encoder imx_encoder; struct drm_panel *panel; struct device_node *child; struct i2c_adapter *ddc; @@ -67,7 +68,6 @@ struct imx_ldb_channel { int edid_len; struct drm_display_mode mode; int mode_valid; - int bus_format; }; struct bus_mux { @@ -94,6 +94,35 @@ static enum drm_connector_status imx_ldb_connector_detect( return connector_status_connected; } +static void imx_ldb_bus_format_translation(struct imx_ldb_channel *imx_ldb_ch, + u32 bus_format) +{ + struct imx_ldb *ldb = imx_ldb_ch->ldb; + int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; + + switch (bus_format) { + case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: + imx_ldb_ch->imx_encoder.bus_format = MEDIA_BUS_FMT_RGB666_1X18; + break; + case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: + imx_ldb_ch->imx_encoder.bus_format = MEDIA_BUS_FMT_RGB888_1X24; + if (imx_ldb_ch->chno == 0 || dual) + ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24; + if (imx_ldb_ch->chno == 1 || dual) + ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24; + break; + case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: + imx_ldb_ch->imx_encoder.bus_format = MEDIA_BUS_FMT_RGB888_1X24; + if (imx_ldb_ch->chno == 0 || dual) + ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24 | + LDB_BIT_MAP_CH0_JEIDA; + if (imx_ldb_ch->chno == 1 || dual) + ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 | + LDB_BIT_MAP_CH1_JEIDA; + break; + } +} + static int imx_ldb_connector_get_modes(struct drm_connector *connector) { struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector); @@ -104,8 +133,9 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector) struct drm_display_info *di = &connector->display_info; num_modes = imx_ldb_ch->panel->funcs->get_modes(imx_ldb_ch->panel); - if (!imx_ldb_ch->bus_format && di->num_bus_formats) - imx_ldb_ch->bus_format = di->bus_formats[0]; + if (!imx_ldb_ch->imx_encoder.bus_format && di->num_bus_formats) + imx_ldb_bus_format_translation(imx_ldb_ch, + di->bus_formats[0]); if (num_modes > 0) return num_modes; } @@ -139,7 +169,7 @@ static struct drm_encoder *imx_ldb_connector_best_encoder( { struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector); - return &imx_ldb_ch->encoder; + return &imx_ldb_ch->imx_encoder.encoder; } static void imx_ldb_encoder_dpms(struct drm_encoder *encoder, int mode) @@ -174,45 +204,10 @@ static void imx_ldb_set_clock(struct imx_ldb *ldb, int mux, int chno, chno); } -static void imx_ldb_encoder_prepare(struct drm_encoder *encoder) -{ - struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); - struct imx_ldb *ldb = imx_ldb_ch->ldb; - int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; - u32 bus_format; - - switch (imx_ldb_ch->bus_format) { - default: - dev_warn(ldb->dev, - "could not determine data mapping, default to 18-bit \"spwg\"\n"); - /* fallthrough */ - case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: - bus_format = MEDIA_BUS_FMT_RGB666_1X18; - break; - case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: - bus_format = MEDIA_BUS_FMT_RGB888_1X24; - if (imx_ldb_ch->chno == 0 || dual) - ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24; - if (imx_ldb_ch->chno == 1 || dual) - ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24; - break; - case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: - bus_format = MEDIA_BUS_FMT_RGB888_1X24; - if (imx_ldb_ch->chno == 0 || dual) - ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24 | - LDB_BIT_MAP_CH0_JEIDA; - if (imx_ldb_ch->chno == 1 || dual) - ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 | - LDB_BIT_MAP_CH1_JEIDA; - break; - } - - imx_drm_set_bus_format(encoder, bus_format); -} - static void imx_ldb_encoder_commit(struct drm_encoder *encoder) { - struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_ldb_channel *imx_ldb_ch = imx_enc_to_imx_ldb_ch(imx_encoder); struct imx_ldb *ldb = imx_ldb_ch->ldb; int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; int mux = drm_of_encoder_active_port_id(imx_ldb_ch->child, encoder); @@ -260,7 +255,8 @@ static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder, struct drm_display_mode *orig_mode, struct drm_display_mode *mode) { - struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_ldb_channel *imx_ldb_ch = imx_enc_to_imx_ldb_ch(imx_encoder); struct imx_ldb *ldb = imx_ldb_ch->ldb; int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; unsigned long serial_clk; @@ -303,7 +299,8 @@ static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder, static void imx_ldb_encoder_disable(struct drm_encoder *encoder) { - struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_ldb_channel *imx_ldb_ch = imx_enc_to_imx_ldb_ch(imx_encoder); struct imx_ldb *ldb = imx_ldb_ch->ldb; int mux, ret; @@ -379,7 +376,6 @@ static const struct drm_encoder_funcs imx_ldb_encoder_funcs = { static const struct drm_encoder_helper_funcs imx_ldb_encoder_helper_funcs = { .dpms = imx_ldb_encoder_dpms, - .prepare = imx_ldb_encoder_prepare, .commit = imx_ldb_encoder_commit, .mode_set = imx_ldb_encoder_mode_set, .disable = imx_ldb_encoder_disable, @@ -406,7 +402,7 @@ static int imx_ldb_register(struct drm_device *drm, struct imx_ldb *ldb = imx_ldb_ch->ldb; int ret; - ret = imx_drm_encoder_parse_of(drm, &imx_ldb_ch->encoder, + ret = imx_drm_encoder_parse_of(drm, &imx_ldb_ch->imx_encoder.encoder, imx_ldb_ch->child); if (ret) return ret; @@ -421,10 +417,10 @@ static int imx_ldb_register(struct drm_device *drm, return ret; } - drm_encoder_helper_add(&imx_ldb_ch->encoder, + drm_encoder_helper_add(&imx_ldb_ch->imx_encoder.encoder, &imx_ldb_encoder_helper_funcs); - drm_encoder_init(drm, &imx_ldb_ch->encoder, &imx_ldb_encoder_funcs, - DRM_MODE_ENCODER_LVDS, NULL); + drm_encoder_init(drm, &imx_ldb_ch->imx_encoder.encoder, + &imx_ldb_encoder_funcs, DRM_MODE_ENCODER_LVDS, NULL); drm_connector_helper_add(&imx_ldb_ch->connector, &imx_ldb_connector_helper_funcs); @@ -435,7 +431,7 @@ static int imx_ldb_register(struct drm_device *drm, drm_panel_attach(imx_ldb_ch->panel, &imx_ldb_ch->connector); drm_mode_connector_attach_encoder(&imx_ldb_ch->connector, - &imx_ldb_ch->encoder); + &imx_ldb_ch->imx_encoder.encoder); return 0; } @@ -564,6 +560,7 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) struct imx_ldb_channel *channel; struct device_node *ddc_node; struct device_node *ep; + int bus_format; ret = of_property_read_u32(child, "reg", &i); if (ret || i < 0 || i > 1) @@ -636,21 +633,25 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) } } - channel->bus_format = of_get_bus_format(dev, child); - if (channel->bus_format == -EINVAL) { + bus_format = of_get_bus_format(dev, child); + if (bus_format == -EINVAL) { /* * If no bus format was specified in the device tree, * we can still get it from the connected panel later. */ if (channel->panel && channel->panel->funcs && channel->panel->funcs->get_modes) - channel->bus_format = 0; + bus_format = 0; } - if (channel->bus_format < 0) { + if (bus_format < 0) { dev_err(dev, "could not determine data mapping: %d\n", - channel->bus_format); - return channel->bus_format; + bus_format); + return bus_format; } + imx_ldb_bus_format_translation(channel, bus_format); + + channel->imx_encoder.di_hsync_pin = 2; + channel->imx_encoder.di_vsync_pin = 3; ret = imx_ldb_register(drm, channel); if (ret) @@ -675,7 +676,8 @@ static void imx_ldb_unbind(struct device *dev, struct device *master, continue; channel->connector.funcs->destroy(&channel->connector); - channel->encoder.funcs->destroy(&channel->encoder); + channel->imx_encoder.encoder.funcs->destroy( + &channel->imx_encoder.encoder); kfree(channel->edid); i2c_put_adapter(channel->ddc); diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c index 0b0aeee5c5f0..82a1edd74f20 100644 --- a/drivers/gpu/drm/imx/imx-tve.c +++ b/drivers/gpu/drm/imx/imx-tve.c @@ -99,7 +99,7 @@ #define TVE_TVDAC_TEST_MODE_MASK (0x7 << 0) #define con_to_tve(x) container_of(x, struct imx_tve, connector) -#define enc_to_tve(x) container_of(x, struct imx_tve, encoder) +#define imx_enc_to_tve(x) container_of(x, struct imx_tve, imx_encoder) enum { TVE_MODE_TVOUT, @@ -108,7 +108,7 @@ enum { struct imx_tve { struct drm_connector connector; - struct drm_encoder encoder; + struct imx_drm_encoder imx_encoder; struct device *dev; spinlock_t lock; /* register lock */ bool enabled; @@ -121,8 +121,6 @@ struct imx_tve { struct clk *di_sel_clk; struct clk_hw clk_hw_di; struct clk *di_clk; - int vsync_pin; - int hsync_pin; }; static void tve_lock(void *__tve) @@ -273,12 +271,13 @@ static struct drm_encoder *imx_tve_connector_best_encoder( { struct imx_tve *tve = con_to_tve(connector); - return &tve->encoder; + return &tve->imx_encoder.encoder; } static void imx_tve_encoder_dpms(struct drm_encoder *encoder, int mode) { - struct imx_tve *tve = enc_to_tve(encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_tve *tve = imx_enc_to_tve(imx_encoder); int ret; ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG, @@ -287,30 +286,12 @@ static void imx_tve_encoder_dpms(struct drm_encoder *encoder, int mode) dev_err(tve->dev, "failed to disable TVOUT: %d\n", ret); } -static void imx_tve_encoder_prepare(struct drm_encoder *encoder) -{ - struct imx_tve *tve = enc_to_tve(encoder); - - tve_disable(tve); - - switch (tve->mode) { - case TVE_MODE_VGA: - imx_drm_set_bus_config(encoder, MEDIA_BUS_FMT_GBR888_1X24, - tve->hsync_pin, tve->vsync_pin, - DRM_BUS_FLAG_DE_HIGH | - DRM_BUS_FLAG_PIXDATA_NEGEDGE); - break; - case TVE_MODE_TVOUT: - imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_YUV8_1X24); - break; - } -} - static void imx_tve_encoder_mode_set(struct drm_encoder *encoder, struct drm_display_mode *orig_mode, struct drm_display_mode *mode) { - struct imx_tve *tve = enc_to_tve(encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_tve *tve = imx_enc_to_tve(imx_encoder); unsigned long rounded_rate; unsigned long rate; int div = 1; @@ -344,14 +325,16 @@ static void imx_tve_encoder_mode_set(struct drm_encoder *encoder, static void imx_tve_encoder_commit(struct drm_encoder *encoder) { - struct imx_tve *tve = enc_to_tve(encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_tve *tve = imx_enc_to_tve(imx_encoder); tve_enable(tve); } static void imx_tve_encoder_disable(struct drm_encoder *encoder) { - struct imx_tve *tve = enc_to_tve(encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_tve *tve = imx_enc_to_tve(imx_encoder); tve_disable(tve); } @@ -378,7 +361,6 @@ static const struct drm_encoder_funcs imx_tve_encoder_funcs = { static const struct drm_encoder_helper_funcs imx_tve_encoder_helper_funcs = { .dpms = imx_tve_encoder_dpms, - .prepare = imx_tve_encoder_prepare, .mode_set = imx_tve_encoder_mode_set, .commit = imx_tve_encoder_commit, .disable = imx_tve_encoder_disable, @@ -499,13 +481,14 @@ static int imx_tve_register(struct drm_device *drm, struct imx_tve *tve) encoder_type = tve->mode == TVE_MODE_VGA ? DRM_MODE_ENCODER_DAC : DRM_MODE_ENCODER_TVDAC; - ret = imx_drm_encoder_parse_of(drm, &tve->encoder, + ret = imx_drm_encoder_parse_of(drm, &tve->imx_encoder.encoder, tve->dev->of_node); if (ret) return ret; - drm_encoder_helper_add(&tve->encoder, &imx_tve_encoder_helper_funcs); - drm_encoder_init(drm, &tve->encoder, &imx_tve_encoder_funcs, + drm_encoder_helper_add(&tve->imx_encoder.encoder, + &imx_tve_encoder_helper_funcs); + drm_encoder_init(drm, &tve->imx_encoder.encoder, &imx_tve_encoder_funcs, encoder_type, NULL); drm_connector_helper_add(&tve->connector, @@ -513,7 +496,8 @@ static int imx_tve_register(struct drm_device *drm, struct imx_tve *tve) drm_connector_init(drm, &tve->connector, &imx_tve_connector_funcs, DRM_MODE_CONNECTOR_VGA); - drm_mode_connector_attach_encoder(&tve->connector, &tve->encoder); + drm_mode_connector_attach_encoder(&tve->connector, + &tve->imx_encoder.encoder); return 0; } @@ -591,7 +575,7 @@ static int imx_tve_bind(struct device *dev, struct device *master, void *data) if (tve->mode == TVE_MODE_VGA) { ret = of_property_read_u32(np, "fsl,hsync-pin", - &tve->hsync_pin); + &tve->imx_encoder.di_hsync_pin); if (ret < 0) { dev_err(dev, "failed to get vsync pin\n"); @@ -599,12 +583,14 @@ static int imx_tve_bind(struct device *dev, struct device *master, void *data) } ret |= of_property_read_u32(np, "fsl,vsync-pin", - &tve->vsync_pin); + &tve->imx_encoder.di_vsync_pin); if (ret < 0) { dev_err(dev, "failed to get vsync pin\n"); return ret; } + + tve->imx_encoder.bus_format = MEDIA_BUS_FMT_GBR888_1X24; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -693,7 +679,7 @@ static void imx_tve_unbind(struct device *dev, struct device *master, struct imx_tve *tve = dev_get_drvdata(dev); tve->connector.funcs->destroy(&tve->connector); - tve->encoder.funcs->destroy(&tve->encoder); + tve->imx_encoder.encoder.funcs->destroy(&tve->imx_encoder.encoder); if (!IS_ERR(tve->dac_reg)) regulator_disable(tve->dac_reg); diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c index 7df51e81d895..f9d5d7c5cd79 100644 --- a/drivers/gpu/drm/imx/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3-crtc.c @@ -67,10 +67,6 @@ struct ipu_crtc { struct workqueue_struct *flip_queue; struct ipu_flip_work *flip_work; int irq; - u32 bus_format; - u32 bus_flags; - int di_hsync_pin; - int di_vsync_pin; }; #define to_ipu_crtc(x) container_of(x, struct ipu_crtc, base) @@ -321,6 +317,7 @@ static void ipu_crtc_mode_set_nofb(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; struct drm_encoder *encoder; + struct imx_drm_encoder *imx_encoder = NULL; struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); struct drm_display_mode *mode = &crtc->state->adjusted_mode; struct ipu_di_signal_cfg sig_cfg = {}; @@ -331,9 +328,12 @@ static void ipu_crtc_mode_set_nofb(struct drm_crtc *crtc) dev_dbg(ipu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__, mode->vdisplay); - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) - if (encoder->crtc == crtc) + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { + if (encoder->crtc == crtc) { encoder_types |= BIT(encoder->encoder_type); + imx_encoder = enc_to_imx_enc(encoder); + } + } dev_dbg(ipu_crtc->dev, "%s: attached to encoder types 0x%lx\n", __func__, encoder_types); @@ -351,20 +351,20 @@ static void ipu_crtc_mode_set_nofb(struct drm_crtc *crtc) else sig_cfg.clkflags = 0; - sig_cfg.enable_pol = !(ipu_crtc->bus_flags & DRM_BUS_FLAG_DE_LOW); + sig_cfg.enable_pol = !(imx_encoder->bus_flags & DRM_BUS_FLAG_DE_LOW); /* Default to driving pixel data on negative clock edges */ - sig_cfg.clk_pol = !!(ipu_crtc->bus_flags & + sig_cfg.clk_pol = !!(imx_encoder->bus_flags & DRM_BUS_FLAG_PIXDATA_POSEDGE); - sig_cfg.bus_format = ipu_crtc->bus_format; + sig_cfg.bus_format = imx_encoder->bus_format; sig_cfg.v_to_h_sync = 0; - sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin; - sig_cfg.vsync_pin = ipu_crtc->di_vsync_pin; + sig_cfg.hsync_pin = imx_encoder->di_hsync_pin; + sig_cfg.vsync_pin = imx_encoder->di_vsync_pin; drm_display_mode_to_videomode(mode, &sig_cfg.mode); ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di, mode->flags & DRM_MODE_FLAG_INTERLACE, - ipu_crtc->bus_format, mode->hdisplay); + imx_encoder->bus_format, mode->hdisplay); ipu_di_init_sync_panel(ipu_crtc->di, &sig_cfg); } @@ -402,23 +402,9 @@ static void ipu_disable_vblank(struct drm_crtc *crtc) disable_irq_nosync(ipu_crtc->irq); } -static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, - u32 bus_format, int hsync_pin, int vsync_pin, u32 bus_flags) -{ - struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); - - ipu_crtc->bus_format = bus_format; - ipu_crtc->bus_flags = bus_flags; - ipu_crtc->di_hsync_pin = hsync_pin; - ipu_crtc->di_vsync_pin = vsync_pin; - - return 0; -} - static const struct imx_drm_crtc_helper_funcs ipu_crtc_helper_funcs = { .enable_vblank = ipu_enable_vblank, .disable_vblank = ipu_disable_vblank, - .set_interface_pix_fmt = ipu_set_interface_pix_fmt, .crtc_funcs = &ipu_crtc_funcs, .crtc_helper_funcs = &ipu_helper_funcs, }; diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c index 9fe88c9b4b0d..7374d824a6d1 100644 --- a/drivers/gpu/drm/imx/parallel-display.c +++ b/drivers/gpu/drm/imx/parallel-display.c @@ -27,15 +27,15 @@ #include "imx-drm.h" #define con_to_imxpd(x) container_of(x, struct imx_parallel_display, connector) -#define enc_to_imxpd(x) container_of(x, struct imx_parallel_display, encoder) +#define imx_enc_to_imxpd(x) \ + container_of(x, struct imx_parallel_display, imx_encoder) struct imx_parallel_display { struct drm_connector connector; - struct drm_encoder encoder; + struct imx_drm_encoder imx_encoder; struct device *dev; void *edid; int edid_len; - u32 bus_format; struct drm_display_mode mode; struct drm_panel *panel; }; @@ -57,8 +57,9 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector) struct drm_display_info *di = &connector->display_info; num_modes = imxpd->panel->funcs->get_modes(imxpd->panel); - if (!imxpd->bus_format && di->num_bus_formats) - imxpd->bus_format = di->bus_formats[0]; + if (!imxpd->imx_encoder.bus_format && di->num_bus_formats) + imxpd->imx_encoder.bus_format = di->bus_formats[0]; + imxpd->imx_encoder.bus_flags = di->bus_flags; if (num_modes > 0) return num_modes; } @@ -88,12 +89,13 @@ static struct drm_encoder *imx_pd_connector_best_encoder( { struct imx_parallel_display *imxpd = con_to_imxpd(connector); - return &imxpd->encoder; + return &imxpd->imx_encoder.encoder; } static void imx_pd_encoder_dpms(struct drm_encoder *encoder, int mode) { - struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_parallel_display *imxpd = imx_enc_to_imxpd(imx_encoder); if (mode != DRM_MODE_DPMS_ON) drm_panel_disable(imxpd->panel); @@ -101,16 +103,10 @@ static void imx_pd_encoder_dpms(struct drm_encoder *encoder, int mode) drm_panel_enable(imxpd->panel); } -static void imx_pd_encoder_prepare(struct drm_encoder *encoder) -{ - struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); - imx_drm_set_bus_config(encoder, imxpd->bus_format, 2, 3, - imxpd->connector.display_info.bus_flags); -} - static void imx_pd_encoder_commit(struct drm_encoder *encoder) { - struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_parallel_display *imxpd = imx_enc_to_imxpd(imx_encoder); drm_panel_prepare(imxpd->panel); drm_panel_enable(imxpd->panel); @@ -124,7 +120,8 @@ static void imx_pd_encoder_mode_set(struct drm_encoder *encoder, static void imx_pd_encoder_disable(struct drm_encoder *encoder) { - struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_parallel_display *imxpd = imx_enc_to_imxpd(imx_encoder); drm_panel_disable(imxpd->panel); drm_panel_unprepare(imxpd->panel); @@ -151,7 +148,6 @@ static const struct drm_encoder_funcs imx_pd_encoder_funcs = { static const struct drm_encoder_helper_funcs imx_pd_encoder_helper_funcs = { .dpms = imx_pd_encoder_dpms, - .prepare = imx_pd_encoder_prepare, .commit = imx_pd_encoder_commit, .mode_set = imx_pd_encoder_mode_set, .disable = imx_pd_encoder_disable, @@ -162,7 +158,7 @@ static int imx_pd_register(struct drm_device *drm, { int ret; - ret = imx_drm_encoder_parse_of(drm, &imxpd->encoder, + ret = imx_drm_encoder_parse_of(drm, &imxpd->imx_encoder.encoder, imxpd->dev->of_node); if (ret) return ret; @@ -174,9 +170,10 @@ static int imx_pd_register(struct drm_device *drm, */ imxpd->connector.dpms = DRM_MODE_DPMS_OFF; - drm_encoder_helper_add(&imxpd->encoder, &imx_pd_encoder_helper_funcs); - drm_encoder_init(drm, &imxpd->encoder, &imx_pd_encoder_funcs, - DRM_MODE_ENCODER_NONE, NULL); + drm_encoder_helper_add(&imxpd->imx_encoder.encoder, + &imx_pd_encoder_helper_funcs); + drm_encoder_init(drm, &imxpd->imx_encoder.encoder, + &imx_pd_encoder_funcs, DRM_MODE_ENCODER_NONE, NULL); drm_connector_helper_add(&imxpd->connector, &imx_pd_connector_helper_funcs); @@ -186,7 +183,8 @@ static int imx_pd_register(struct drm_device *drm, if (imxpd->panel) drm_panel_attach(imxpd->panel, &imxpd->connector); - drm_mode_connector_attach_encoder(&imxpd->connector, &imxpd->encoder); + drm_mode_connector_attach_encoder(&imxpd->connector, + &imxpd->imx_encoder.encoder); return 0; } @@ -199,6 +197,7 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) const u8 *edidp; struct imx_parallel_display *imxpd; int ret; + u32 bus_format = 0; const char *fmt; imxpd = devm_kzalloc(dev, sizeof(*imxpd), GFP_KERNEL); @@ -212,14 +211,17 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) ret = of_property_read_string(np, "interface-pix-fmt", &fmt); if (!ret) { if (!strcmp(fmt, "rgb24")) - imxpd->bus_format = MEDIA_BUS_FMT_RGB888_1X24; + bus_format = MEDIA_BUS_FMT_RGB888_1X24; else if (!strcmp(fmt, "rgb565")) - imxpd->bus_format = MEDIA_BUS_FMT_RGB565_1X16; + bus_format = MEDIA_BUS_FMT_RGB565_1X16; else if (!strcmp(fmt, "bgr666")) - imxpd->bus_format = MEDIA_BUS_FMT_RGB666_1X18; + bus_format = MEDIA_BUS_FMT_RGB666_1X18; else if (!strcmp(fmt, "lvds666")) - imxpd->bus_format = MEDIA_BUS_FMT_RGB666_1X24_CPADHI; + bus_format = MEDIA_BUS_FMT_RGB666_1X24_CPADHI; } + imxpd->imx_encoder.bus_format = bus_format; + imxpd->imx_encoder.di_hsync_pin = 2; + imxpd->imx_encoder.di_vsync_pin = 3; /* port@1 is the output port */ ep = of_graph_get_endpoint_by_regs(np, 1, -1); @@ -252,7 +254,7 @@ static void imx_pd_unbind(struct device *dev, struct device *master, { struct imx_parallel_display *imxpd = dev_get_drvdata(dev); - imxpd->encoder.funcs->destroy(&imxpd->encoder); + imxpd->imx_encoder.encoder.funcs->destroy(&imxpd->imx_encoder.encoder); imxpd->connector.funcs->destroy(&imxpd->connector); kfree(imxpd->edid);