From dcbc9eb1919359719be0ef652afe1d90b0fa98ed Mon Sep 17 00:00:00 2001 From: Peter Seiderer Date: Sun, 8 Dec 2013 22:03:58 +0100 Subject: drm/imx: parallel-display: fix imxpd-->edid memleak If edid was allocated during bind, it must be freed again during unbind. Signed-off-by: Peter Seiderer Acked-by: Sascha Hauer Signed-off-by: Philipp Zabel --- drivers/gpu/drm/imx/parallel-display.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c index 796c3c1c170a..88cf7ca1e886 100644 --- a/drivers/gpu/drm/imx/parallel-display.c +++ b/drivers/gpu/drm/imx/parallel-display.c @@ -257,6 +257,8 @@ static void imx_pd_unbind(struct device *dev, struct device *master, imxpd->encoder.funcs->destroy(&imxpd->encoder); imxpd->connector.funcs->destroy(&imxpd->connector); + + kfree(imxpd->edid); } static const struct component_ops imx_pd_ops = { @@ -272,6 +274,7 @@ static int imx_pd_probe(struct platform_device *pdev) static int imx_pd_remove(struct platform_device *pdev) { component_del(&pdev->dev, &imx_pd_ops); + return 0; } -- cgit v1.2.3 From f4876ffea6f310e1c7ee015687f913248a0d5f9c Mon Sep 17 00:00:00 2001 From: Peter Seiderer Date: Sun, 8 Dec 2013 22:03:57 +0100 Subject: drm/imx: imx-ldb: fix channel->edid memleak If edid was allocated during bind, it must be freed again during unbind. Signed-off-by: Peter Seiderer Acked-by: Sascha Hauer Signed-off-by: Philipp Zabel --- drivers/gpu/drm/imx/imx-ldb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index c60460043e24..4ff62a517c75 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c @@ -574,6 +574,8 @@ static void imx_ldb_unbind(struct device *dev, struct device *master, channel->connector.funcs->destroy(&channel->connector); channel->encoder.funcs->destroy(&channel->encoder); + + kfree(channel->edid); } } -- cgit v1.2.3 From 6457b9716bca99b95a07e85ff8b00f9bf471ac2c Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 3 Jul 2014 17:52:57 +0100 Subject: drm/imx: convert imx-drm to use the generic DRM OF helper Use the generic DRM OF helper to locate the possible CRTCs for the encoder, thereby shrinking the imx-drm driver some more. Signed-off-by: Russell King Signed-off-by: Philipp Zabel --- drivers/gpu/drm/imx/imx-drm-core.c | 84 +++++++++----------------------------- 1 file changed, 19 insertions(+), 65 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index b250130debc8..06cd2e516db6 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "imx-drm.h" @@ -46,7 +47,6 @@ struct imx_drm_crtc { struct drm_crtc *crtc; int pipe; struct imx_drm_crtc_helper_funcs imx_drm_helper_funcs; - struct device_node *port; }; static int legacyfb_depth = 16; @@ -365,9 +365,10 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, imx_drm_crtc->imx_drm_helper_funcs = *imx_drm_helper_funcs; imx_drm_crtc->pipe = imxdrm->pipes++; - imx_drm_crtc->port = port; imx_drm_crtc->crtc = crtc; + crtc->port = port; + imxdrm->crtc[imx_drm_crtc->pipe] = imx_drm_crtc; *new_crtc = imx_drm_crtc; @@ -408,33 +409,28 @@ int imx_drm_remove_crtc(struct imx_drm_crtc *imx_drm_crtc) } EXPORT_SYMBOL_GPL(imx_drm_remove_crtc); -/* - * Find the DRM CRTC possible mask for the connected endpoint. - * - * The encoder possible masks are defined by their position in the - * mode_config crtc_list. This means that CRTCs must not be added - * or removed once the DRM device has been fully initialised. - */ -static uint32_t imx_drm_find_crtc_mask(struct imx_drm_device *imxdrm, - struct device_node *endpoint) +int imx_drm_encoder_parse_of(struct drm_device *drm, + struct drm_encoder *encoder, struct device_node *np) { - struct device_node *port; - unsigned i; + uint32_t crtc_mask = drm_of_find_possible_crtcs(drm, np); - port = of_graph_get_remote_port(endpoint); - if (!port) - return 0; - of_node_put(port); + /* + * If we failed to find the CRTC(s) which this encoder is + * supposed to be connected to, it's because the CRTC has + * not been registered yet. Defer probing, and hope that + * the required CRTC is added later. + */ + if (crtc_mask == 0) + return -EPROBE_DEFER; - for (i = 0; i < MAX_CRTC; i++) { - struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[i]; + encoder->possible_crtcs = crtc_mask; - if (imx_drm_crtc && imx_drm_crtc->port == port) - return drm_crtc_mask(imx_drm_crtc->crtc); - } + /* FIXME: this is the mask of outputs which can clone this output. */ + encoder->possible_clones = ~0; return 0; } +EXPORT_SYMBOL_GPL(imx_drm_encoder_parse_of); static struct device_node *imx_drm_of_get_next_endpoint( const struct device_node *parent, struct device_node *prev) @@ -445,48 +441,6 @@ static struct device_node *imx_drm_of_get_next_endpoint( return node; } -int imx_drm_encoder_parse_of(struct drm_device *drm, - struct drm_encoder *encoder, struct device_node *np) -{ - struct imx_drm_device *imxdrm = drm->dev_private; - struct device_node *ep = NULL; - uint32_t crtc_mask = 0; - int i; - - for (i = 0; ; i++) { - u32 mask; - - ep = imx_drm_of_get_next_endpoint(np, ep); - if (!ep) - break; - - mask = imx_drm_find_crtc_mask(imxdrm, ep); - - /* - * If we failed to find the CRTC(s) which this encoder is - * supposed to be connected to, it's because the CRTC has - * not been registered yet. Defer probing, and hope that - * the required CRTC is added later. - */ - if (mask == 0) - return -EPROBE_DEFER; - - crtc_mask |= mask; - } - - of_node_put(ep); - if (i == 0) - return -ENOENT; - - encoder->possible_crtcs = crtc_mask; - - /* FIXME: this is the mask of outputs which can clone this output. */ - encoder->possible_clones = ~0; - - return 0; -} -EXPORT_SYMBOL_GPL(imx_drm_encoder_parse_of); - /* * @node: device tree node containing encoder input ports * @encoder: drm_encoder @@ -510,7 +464,7 @@ int imx_drm_encoder_get_mux_id(struct device_node *node, port = of_graph_get_remote_port(ep); of_node_put(port); - if (port == imx_crtc->port) { + if (port == imx_crtc->crtc->port) { ret = of_graph_parse_endpoint(ep, &endpoint); return ret ? ret : endpoint.port; } -- cgit v1.2.3 From f853f3daac748daa339bc8b64ba39db82160524a Mon Sep 17 00:00:00 2001 From: Steve Longerbeam Date: Mon, 26 Aug 2013 11:42:09 -0700 Subject: gpu: ipu-v3: Implement use counter for ipu_dc_enable(), ipu_dc_disable() The functions ipu_dc_enable() and ipu_dc_disable() enable/disable the DC globally in the IPU_CONF register, but the DC is used by multiple clients on different DC channels. So make sure to only disable/enable the DC globally based on a use counter. Signed-off-by: Steve Longerbeam Signed-off-by: Philipp Zabel --- drivers/gpu/ipu-v3/ipu-dc.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/ipu-v3/ipu-dc.c b/drivers/gpu/ipu-v3/ipu-dc.c index 2326c752d89b..323203d0503a 100644 --- a/drivers/gpu/ipu-v3/ipu-dc.c +++ b/drivers/gpu/ipu-v3/ipu-dc.c @@ -114,6 +114,7 @@ struct ipu_dc_priv { struct completion comp; int dc_irq; int dp_irq; + int use_count; }; static void dc_link_event(struct ipu_dc *dc, int event, int addr, int priority) @@ -232,7 +233,16 @@ EXPORT_SYMBOL_GPL(ipu_dc_init_sync); void ipu_dc_enable(struct ipu_soc *ipu) { - ipu_module_enable(ipu, IPU_CONF_DC_EN); + struct ipu_dc_priv *priv = ipu->dc_priv; + + mutex_lock(&priv->mutex); + + if (!priv->use_count) + ipu_module_enable(priv->ipu, IPU_CONF_DC_EN); + + priv->use_count++; + + mutex_unlock(&priv->mutex); } EXPORT_SYMBOL_GPL(ipu_dc_enable); @@ -294,7 +304,18 @@ EXPORT_SYMBOL_GPL(ipu_dc_disable_channel); void ipu_dc_disable(struct ipu_soc *ipu) { - ipu_module_disable(ipu, IPU_CONF_DC_EN); + struct ipu_dc_priv *priv = ipu->dc_priv; + + mutex_lock(&priv->mutex); + + priv->use_count--; + if (!priv->use_count) + ipu_module_disable(priv->ipu, IPU_CONF_DC_EN); + + if (priv->use_count < 0) + priv->use_count = 0; + + mutex_unlock(&priv->mutex); } EXPORT_SYMBOL_GPL(ipu_dc_disable); -- cgit v1.2.3 From b587833933de39e21b314e3b392ac0f1ec94a97e Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Fri, 5 Dec 2014 14:23:52 +0800 Subject: drm: imx: imx-hdmi: make checkpatch happy CHECK: Alignment should match open parenthesis + if ((hdmi->vic == 10) || (hdmi->vic == 11) || + (hdmi->vic == 12) || (hdmi->vic == 13) || CHECK: braces {} should be used on all arms of this statement + if (hdmi->hdmi_data.video_mode.mdvi) [...] + else { [...] Signed-off-by: Andy Yan Reviewed-by: Daniel Kurtz Tested-by: Russell King Acked-by: Russell King Signed-off-by: Philipp Zabel --- drivers/gpu/drm/imx/imx-hdmi.c | 109 ++++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/imx/imx-hdmi.c b/drivers/gpu/drm/imx/imx-hdmi.c index ddc53e039530..3f96a5e6670d 100644 --- a/drivers/gpu/drm/imx/imx-hdmi.c +++ b/drivers/gpu/drm/imx/imx-hdmi.c @@ -163,7 +163,7 @@ static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg) } static void hdmi_mask_writeb(struct imx_hdmi *hdmi, u8 data, unsigned int reg, - u8 shift, u8 mask) + u8 shift, u8 mask) { hdmi_modb(hdmi, data << shift, mask, reg); } @@ -327,7 +327,7 @@ static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk, } static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi, - unsigned long pixel_clk) + unsigned long pixel_clk) { unsigned int clk_n, clk_cts; @@ -338,7 +338,7 @@ static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi, if (!clk_cts) { dev_dbg(hdmi->dev, "%s: pixel clock not supported: %lu\n", - __func__, pixel_clk); + __func__, pixel_clk); return; } @@ -477,13 +477,11 @@ static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi) u16 coeff_b = (*csc_coeff)[1][i]; u16 coeff_c = (*csc_coeff)[2][i]; - hdmi_writeb(hdmi, coeff_a & 0xff, - HDMI_CSC_COEF_A1_LSB + i * 2); + hdmi_writeb(hdmi, coeff_a & 0xff, HDMI_CSC_COEF_A1_LSB + i * 2); hdmi_writeb(hdmi, coeff_a >> 8, HDMI_CSC_COEF_A1_MSB + i * 2); hdmi_writeb(hdmi, coeff_b & 0xff, HDMI_CSC_COEF_B1_LSB + i * 2); hdmi_writeb(hdmi, coeff_b >> 8, HDMI_CSC_COEF_B1_MSB + i * 2); - hdmi_writeb(hdmi, coeff_c & 0xff, - HDMI_CSC_COEF_C1_LSB + i * 2); + hdmi_writeb(hdmi, coeff_c & 0xff, HDMI_CSC_COEF_C1_LSB + i * 2); hdmi_writeb(hdmi, coeff_c >> 8, HDMI_CSC_COEF_C1_MSB + i * 2); } @@ -535,21 +533,22 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi) struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data; u8 val, vp_conf; - if (hdmi_data->enc_out_format == RGB - || hdmi_data->enc_out_format == YCBCR444) { - if (!hdmi_data->enc_color_depth) + if (hdmi_data->enc_out_format == RGB || + hdmi_data->enc_out_format == YCBCR444) { + if (!hdmi_data->enc_color_depth) { output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; - else if (hdmi_data->enc_color_depth == 8) { + } else if (hdmi_data->enc_color_depth == 8) { color_depth = 4; output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; - } else if (hdmi_data->enc_color_depth == 10) + } else if (hdmi_data->enc_color_depth == 10) { color_depth = 5; - else if (hdmi_data->enc_color_depth == 12) + } else if (hdmi_data->enc_color_depth == 12) { color_depth = 6; - else if (hdmi_data->enc_color_depth == 16) + } else if (hdmi_data->enc_color_depth == 16) { color_depth = 7; - else + } else { return; + } } else if (hdmi_data->enc_out_format == YCBCR422_8BITS) { if (!hdmi_data->enc_color_depth || hdmi_data->enc_color_depth == 8) @@ -561,8 +560,9 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi) else return; output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422; - } else + } else { return; + } /* set the packetizer registers */ val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) & @@ -623,34 +623,34 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi) } static inline void hdmi_phy_test_clear(struct imx_hdmi *hdmi, - unsigned char bit) + unsigned char bit) { hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLR_OFFSET, HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0); } static inline void hdmi_phy_test_enable(struct imx_hdmi *hdmi, - unsigned char bit) + unsigned char bit) { hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTEN_OFFSET, HDMI_PHY_TST0_TSTEN_MASK, HDMI_PHY_TST0); } static inline void hdmi_phy_test_clock(struct imx_hdmi *hdmi, - unsigned char bit) + unsigned char bit) { hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLK_OFFSET, HDMI_PHY_TST0_TSTCLK_MASK, HDMI_PHY_TST0); } static inline void hdmi_phy_test_din(struct imx_hdmi *hdmi, - unsigned char bit) + unsigned char bit) { hdmi_writeb(hdmi, bit, HDMI_PHY_TST1); } static inline void hdmi_phy_test_dout(struct imx_hdmi *hdmi, - unsigned char bit) + unsigned char bit) { hdmi_writeb(hdmi, bit, HDMI_PHY_TST2); } @@ -666,21 +666,21 @@ static bool hdmi_phy_wait_i2c_done(struct imx_hdmi *hdmi, int msec) } static void __hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data, - unsigned char addr) + unsigned char addr) { hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0); hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR); hdmi_writeb(hdmi, (unsigned char)(data >> 8), - HDMI_PHY_I2CM_DATAO_1_ADDR); + HDMI_PHY_I2CM_DATAO_1_ADDR); hdmi_writeb(hdmi, (unsigned char)(data >> 0), - HDMI_PHY_I2CM_DATAO_0_ADDR); + HDMI_PHY_I2CM_DATAO_0_ADDR); hdmi_writeb(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE, - HDMI_PHY_I2CM_OPERATION_ADDR); + HDMI_PHY_I2CM_OPERATION_ADDR); hdmi_phy_wait_i2c_done(hdmi, 1000); } static int hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data, - unsigned char addr) + unsigned char addr) { __hdmi_phy_i2c_write(hdmi, data, addr); return 0; @@ -839,7 +839,7 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep, hdmi_phy_test_clear(hdmi, 1); hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2, - HDMI_PHY_I2CM_SLAVE_ADDR); + HDMI_PHY_I2CM_SLAVE_ADDR); hdmi_phy_test_clear(hdmi, 0); /* PLL/MPLL Cfg - always match on final entry */ @@ -857,9 +857,8 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep, break; if (i >= ARRAY_SIZE(curr_ctrl)) { - dev_err(hdmi->dev, - "Pixel clock %d - unsupported by HDMI\n", - hdmi->hdmi_data.video_mode.mpixelclock); + dev_err(hdmi->dev, "Pixel clock %d - unsupported by HDMI\n", + hdmi->hdmi_data.video_mode.mpixelclock); return -EINVAL; } @@ -1223,21 +1222,21 @@ static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode) } if ((hdmi->vic == 6) || (hdmi->vic == 7) || - (hdmi->vic == 21) || (hdmi->vic == 22) || - (hdmi->vic == 2) || (hdmi->vic == 3) || - (hdmi->vic == 17) || (hdmi->vic == 18)) + (hdmi->vic == 21) || (hdmi->vic == 22) || + (hdmi->vic == 2) || (hdmi->vic == 3) || + (hdmi->vic == 17) || (hdmi->vic == 18)) hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601; else hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709; if ((hdmi->vic == 10) || (hdmi->vic == 11) || - (hdmi->vic == 12) || (hdmi->vic == 13) || - (hdmi->vic == 14) || (hdmi->vic == 15) || - (hdmi->vic == 25) || (hdmi->vic == 26) || - (hdmi->vic == 27) || (hdmi->vic == 28) || - (hdmi->vic == 29) || (hdmi->vic == 30) || - (hdmi->vic == 35) || (hdmi->vic == 36) || - (hdmi->vic == 37) || (hdmi->vic == 38)) + (hdmi->vic == 12) || (hdmi->vic == 13) || + (hdmi->vic == 14) || (hdmi->vic == 15) || + (hdmi->vic == 25) || (hdmi->vic == 26) || + (hdmi->vic == 27) || (hdmi->vic == 28) || + (hdmi->vic == 29) || (hdmi->vic == 30) || + (hdmi->vic == 35) || (hdmi->vic == 36) || + (hdmi->vic == 37) || (hdmi->vic == 38)) hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 1; else hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0; @@ -1266,9 +1265,9 @@ static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode) imx_hdmi_enable_video_path(hdmi); /* not for DVI mode */ - if (hdmi->hdmi_data.video_mode.mdvi) + if (hdmi->hdmi_data.video_mode.mdvi) { dev_dbg(hdmi->dev, "%s DVI mode\n", __func__); - else { + } else { dev_dbg(hdmi->dev, "%s CEA mode\n", __func__); /* HDMI Initialization Step E - Configure audio */ @@ -1525,7 +1524,7 @@ static irqreturn_t imx_hdmi_irq(int irq, void *dev_id) dev_dbg(hdmi->dev, "EVENT=plugout\n"); hdmi_modb(hdmi, HDMI_PHY_HPD, HDMI_PHY_HPD, - HDMI_PHY_POL0); + HDMI_PHY_POL0); imx_hdmi_poweroff(hdmi); } @@ -1554,7 +1553,7 @@ static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi) DRM_MODE_ENCODER_TMDS); drm_connector_helper_add(&hdmi->connector, - &imx_hdmi_connector_helper_funcs); + &imx_hdmi_connector_helper_funcs); drm_connector_init(drm, &hdmi->connector, &imx_hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA); @@ -1642,40 +1641,36 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data) hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr"); if (IS_ERR(hdmi->isfr_clk)) { ret = PTR_ERR(hdmi->isfr_clk); - dev_err(hdmi->dev, - "Unable to get HDMI isfr clk: %d\n", ret); + dev_err(hdmi->dev, "Unable to get HDMI isfr clk: %d\n", ret); return ret; } ret = clk_prepare_enable(hdmi->isfr_clk); if (ret) { - dev_err(hdmi->dev, - "Cannot enable HDMI isfr clock: %d\n", ret); + dev_err(hdmi->dev, "Cannot enable HDMI isfr clock: %d\n", ret); return ret; } hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb"); if (IS_ERR(hdmi->iahb_clk)) { ret = PTR_ERR(hdmi->iahb_clk); - dev_err(hdmi->dev, - "Unable to get HDMI iahb clk: %d\n", ret); + dev_err(hdmi->dev, "Unable to get HDMI iahb clk: %d\n", ret); goto err_isfr; } ret = clk_prepare_enable(hdmi->iahb_clk); if (ret) { - dev_err(hdmi->dev, - "Cannot enable HDMI iahb clock: %d\n", ret); + dev_err(hdmi->dev, "Cannot enable HDMI iahb clock: %d\n", ret); goto err_isfr; } /* Product and revision IDs */ dev_info(dev, - "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n", - hdmi_readb(hdmi, HDMI_DESIGN_ID), - hdmi_readb(hdmi, HDMI_REVISION_ID), - hdmi_readb(hdmi, HDMI_PRODUCT_ID0), - hdmi_readb(hdmi, HDMI_PRODUCT_ID1)); + "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n", + hdmi_readb(hdmi, HDMI_DESIGN_ID), + hdmi_readb(hdmi, HDMI_REVISION_ID), + hdmi_readb(hdmi, HDMI_PRODUCT_ID0), + hdmi_readb(hdmi, HDMI_PRODUCT_ID1)); initialize_hdmi_ih_mutes(hdmi); -- cgit v1.2.3 From c2c3848851a723a0e5e0fec22df395a885edf459 Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Fri, 5 Dec 2014 14:24:28 +0800 Subject: drm: imx: imx-hdmi: return defer if can't get ddc i2c adapter drm driver may probe before the i2c bus, so the driver should defer probing until it is available Signed-off-by: Andy Yan Reviewed-by: Daniel Kurtz Tested-by: Russell King Acked-by: Russell King Signed-off-by: Philipp Zabel --- drivers/gpu/drm/imx/imx-hdmi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/imx/imx-hdmi.c b/drivers/gpu/drm/imx/imx-hdmi.c index 3f96a5e6670d..3118dde3ea62 100644 --- a/drivers/gpu/drm/imx/imx-hdmi.c +++ b/drivers/gpu/drm/imx/imx-hdmi.c @@ -1611,10 +1611,12 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data) ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0); if (ddc_node) { hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node); - if (!hdmi->ddc) + of_node_put(ddc_node); + if (!hdmi->ddc) { dev_dbg(hdmi->dev, "failed to read ddc node\n"); + return -EPROBE_DEFER; + } - of_node_put(ddc_node); } else { dev_dbg(hdmi->dev, "no ddc property found\n"); } -- cgit v1.2.3 From 3d1b35a3d9f3d6de690b237995d5aa858e349648 Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Fri, 5 Dec 2014 14:25:05 +0800 Subject: drm: imx: imx-hdmi: convert imx-hdmi to drm_bridge mode IMX6 and Rockchip RK3288 and JZ4780 (Ingenic Xburst/MIPS) use the interface compatible Designware HDMI IP, but they also have some lightly differences, such as phy pll configuration, register width, 4K support, clk useage, and the crtc mux configuration is also platform specific. To reuse the imx hdmi driver, convert it to drm_bridge handle encoder in imx-hdmi_pltfm.c, as most of the encoder operation are platform specific such as crtc select and panel format set This patch depends on Russell King's patch: drm: imx: convert imx-drm to use the generic DRM OF helper http://driverdev.linuxdriverproject.org/pipermail/driverdev-devel/2014-July/053484.html Signed-off-by: Andy Yan Signed-off-by: Yakir Yang Tested-by: Russell King Acked-by: Russell King Signed-off-by: Philipp Zabel --- drivers/gpu/drm/imx/Makefile | 2 +- drivers/gpu/drm/imx/imx-hdmi.c | 257 +++++++++++++---------------------- drivers/gpu/drm/imx/imx-hdmi.h | 15 ++ drivers/gpu/drm/imx/imx-hdmi_pltfm.c | 203 +++++++++++++++++++++++++++ 4 files changed, 315 insertions(+), 162 deletions(-) create mode 100644 drivers/gpu/drm/imx/imx-hdmi_pltfm.c (limited to 'drivers') diff --git a/drivers/gpu/drm/imx/Makefile b/drivers/gpu/drm/imx/Makefile index 582c438d8cbd..63cf56ad5c61 100644 --- a/drivers/gpu/drm/imx/Makefile +++ b/drivers/gpu/drm/imx/Makefile @@ -9,4 +9,4 @@ obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o imx-ipuv3-crtc-objs := ipuv3-crtc.o ipuv3-plane.o obj-$(CONFIG_DRM_IMX_IPUV3) += imx-ipuv3-crtc.o -obj-$(CONFIG_DRM_IMX_HDMI) += imx-hdmi.o +obj-$(CONFIG_DRM_IMX_HDMI) += imx-hdmi.o imx-hdmi_pltfm.o diff --git a/drivers/gpu/drm/imx/imx-hdmi.c b/drivers/gpu/drm/imx/imx-hdmi.c index 3118dde3ea62..9f2f0feb7b75 100644 --- a/drivers/gpu/drm/imx/imx-hdmi.c +++ b/drivers/gpu/drm/imx/imx-hdmi.c @@ -12,25 +12,20 @@ * Copyright (C) 2010, Guennadi Liakhovetski */ -#include #include #include #include #include #include -#include -#include -#include #include +#include #include #include #include #include -#include