Message ID | 20180214200906.31509-1-jernej.skrabec@siol.net |
---|---|
Headers | show |
Series | drm/sun4i: Add A83T HDMI support | expand |
On Wed, Feb 14, 2018 at 9:09 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote: > A83T has DW HDMI IP block with a custom PHY similar to Synopsys gen2 > HDMI PHY. > > Only video output was tested, while HW also supports audio and CEC. > Support for them will be added later. > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net> ... > --- /dev/null > +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h > @@ -0,0 +1,44 @@ > +// SPDX-License-Identifier: GPL-2.0+ This should be /* SPDX-License-Identifier: GPL-2.0+ /* in a .h per [1] [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/license-rules.rst
On Wed, Feb 14, 2018 at 09:08:54PM +0100, Jernej Skrabec wrote: > This patch series implements support for A83T DW HDMI and PHY. Contrary to > v1 series, this one is based on latest linux-next, since all needed patches > were merged. > > While exactly this combination of HDMI controller and PHY is not common in > Allwinner SoCs, this patch series nevertheless makes groundwork for other > SoCs, which have same DW HDMI IP block, but different PHYs, like H3 and H5. > > Please take a look. I've applied the two clk patches. I'm waiting for some review from Archit on the synopsys bridge before merging anything else. Maxime
On Thursday 15 February 2018 01:38 AM, Jernej Skrabec wrote: > Allwinner SoCs have dw hdmi controller v1.32a which exhibits same > magenta line issue as i.MX6Q and i.MX6DL. Enable workaround for it. > > Tests show that one iteration is enough. > > Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Archit Taneja <architt@codeaurora.org> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net> > --- > drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 8 +++++--- > 1 file changed, 5 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > index a38db40ce990..7ca14d7325b5 100644 > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > @@ -1634,9 +1634,10 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi) > * then write one of the FC registers several times. > * > * The number of iterations matters and depends on the HDMI TX revision > - * (and possibly on the platform). So far only i.MX6Q (v1.30a) and > - * i.MX6DL (v1.31a) have been identified as needing the workaround, with > - * 4 and 1 iterations respectively. > + * (and possibly on the platform). So far i.MX6Q (v1.30a), i.MX6DL > + * (v1.31a) and multiple Allwinner SoCs (v1.32a) have been identified > + * as needing the workaround, with 4 iterations for v1.30a and 1 > + * iteration for others. > */ > > switch (hdmi->version) { > @@ -1644,6 +1645,7 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi) > count = 4; > break; > case 0x131a: > + case 0x132a: > count = 1; > break; > default: > -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thursday 15 February 2018 01:38 AM, Jernej Skrabec wrote: > Parts of PHY code could be useful also for custom PHYs. For example, > Allwinner A83T has custom PHY which is probably Synopsys gen2 PHY > with few additional memory mapped registers, so most of the Synopsys PHY > related code could be reused. > > Functions exported here are actually not specific to Synopsys PHYs but > to DWC HDMI controller PHY interface. This means that even if the PHY is > completely custom, i.e. not designed by Synopsys, exported functions can > be useful. Reviewed-by: Archit Taneja <architt@codeaurora.org> > > Reviewed-by: Neil Armstrong <narmstrong@baylibre.com> > Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net> > --- > drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 44 +++++++++++++++++++++---------- > drivers/gpu/drm/meson/meson_dw_hdmi.c | 8 +++--- > include/drm/bridge/dw_hdmi.h | 11 ++++++++ > 3 files changed, 45 insertions(+), 18 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > index 7ca14d7325b5..7d80f4b56683 100644 > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > @@ -1037,19 +1037,21 @@ static void dw_hdmi_phy_enable_svsret(struct dw_hdmi *hdmi, u8 enable) > HDMI_PHY_CONF0_SVSRET_MASK); > } > > -static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable) > +void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable) > { > hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, > HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET, > HDMI_PHY_CONF0_GEN2_PDDQ_MASK); > } > +EXPORT_SYMBOL_GPL(dw_hdmi_phy_gen2_pddq); > > -static void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable) > +void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable) > { > hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, > HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET, > HDMI_PHY_CONF0_GEN2_TXPWRON_MASK); > } > +EXPORT_SYMBOL_GPL(dw_hdmi_phy_gen2_txpwron); > > static void dw_hdmi_phy_sel_data_en_pol(struct dw_hdmi *hdmi, u8 enable) > { > @@ -1065,6 +1067,22 @@ static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable) > HDMI_PHY_CONF0_SELDIPIF_MASK); > } > > +void dw_hdmi_phy_reset(struct dw_hdmi *hdmi) > +{ > + /* PHY reset. The reset signal is active high on Gen2 PHYs. */ > + hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ); > + hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ); > +} > +EXPORT_SYMBOL_GPL(dw_hdmi_phy_reset); > + > +void dw_hdmi_phy_i2c_set_addr(struct dw_hdmi *hdmi, u8 address) > +{ > + hdmi_phy_test_clear(hdmi, 1); > + hdmi_writeb(hdmi, address, HDMI_PHY_I2CM_SLAVE_ADDR); > + hdmi_phy_test_clear(hdmi, 0); > +} > +EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_set_addr); > + > static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi) > { > const struct dw_hdmi_phy_data *phy = hdmi->phy.data; > @@ -1203,16 +1221,11 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi) > if (phy->has_svsret) > dw_hdmi_phy_enable_svsret(hdmi, 1); > > - /* PHY reset. The reset signal is active high on Gen2 PHYs. */ > - hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ); > - hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ); > + dw_hdmi_phy_reset(hdmi); > > hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST); > > - hdmi_phy_test_clear(hdmi, 1); > - hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2, > - HDMI_PHY_I2CM_SLAVE_ADDR); > - hdmi_phy_test_clear(hdmi, 0); > + dw_hdmi_phy_i2c_set_addr(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2); > > /* Write to the PHY as configured by the platform */ > if (pdata->configure_phy) > @@ -1251,15 +1264,16 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data) > dw_hdmi_phy_power_off(hdmi); > } > > -static enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi, > - void *data) > +enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi, > + void *data) > { > return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ? > connector_status_connected : connector_status_disconnected; > } > +EXPORT_SYMBOL_GPL(dw_hdmi_phy_read_hpd); > > -static void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data, > - bool force, bool disabled, bool rxsense) > +void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data, > + bool force, bool disabled, bool rxsense) > { > u8 old_mask = hdmi->phy_mask; > > @@ -1271,8 +1285,9 @@ static void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data, > if (old_mask != hdmi->phy_mask) > hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0); > } > +EXPORT_SYMBOL_GPL(dw_hdmi_phy_update_hpd); > > -static void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data) > +void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data) > { > /* > * Configure the PHY RX SENSE and HPD interrupts polarities and clear > @@ -1291,6 +1306,7 @@ static void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data) > hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE), > HDMI_IH_MUTE_PHY_STAT0); > } > +EXPORT_SYMBOL_GPL(dw_hdmi_phy_setup_hpd); > > static const struct dw_hdmi_phy_ops dw_hdmi_synopsys_phy_ops = { > .init = dw_hdmi_phy_init, > diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c > index 17de3afd98f6..e8c3ef8a94ce 100644 > --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c > +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c > @@ -302,7 +302,7 @@ static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi, > } > } > > -static inline void dw_hdmi_phy_reset(struct meson_dw_hdmi *dw_hdmi) > +static inline void meson_dw_hdmi_phy_reset(struct meson_dw_hdmi *dw_hdmi) > { > struct meson_drm *priv = dw_hdmi->priv; > > @@ -409,9 +409,9 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, > msleep(100); > > /* Reset PHY 3 times in a row */ > - dw_hdmi_phy_reset(dw_hdmi); > - dw_hdmi_phy_reset(dw_hdmi); > - dw_hdmi_phy_reset(dw_hdmi); > + meson_dw_hdmi_phy_reset(dw_hdmi); > + meson_dw_hdmi_phy_reset(dw_hdmi); > + meson_dw_hdmi_phy_reset(dw_hdmi); > > /* Temporary Disable VENC video stream */ > if (priv->venc.hdmi_use_enci) > diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h > index 182f83283e24..f3f3f0e1b2d3 100644 > --- a/include/drm/bridge/dw_hdmi.h > +++ b/include/drm/bridge/dw_hdmi.h > @@ -157,7 +157,18 @@ void dw_hdmi_audio_enable(struct dw_hdmi *hdmi); > void dw_hdmi_audio_disable(struct dw_hdmi *hdmi); > > /* PHY configuration */ > +void dw_hdmi_phy_i2c_set_addr(struct dw_hdmi *hdmi, u8 address); > void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, > unsigned char addr); > > +void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable); > +void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable); > +void dw_hdmi_phy_reset(struct dw_hdmi *hdmi); > + > +enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi, > + void *data); > +void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data, > + bool force, bool disabled, bool rxsense); > +void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data); > + > #endif /* __IMX_HDMI_H__ */ > -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thursday 15 February 2018 01:38 AM, Jernej Skrabec wrote: > dw_hdmi shouldn't set drvdata since some drivers might need to store > it's own data there. Rework dw_hdmi in a way to return struct dw_hdmi > instead to store it in drvdata. This way drivers are responsible to > store and pass structure when needed. > > Idea was taken from the following commit: > 8242ecbd597d ("drm/bridge/synopsys: stop clobbering drvdata") Reviewed-by: Archit Taneja <architt@codeaurora.org> > > Cc: p.zabel@pengutronix.de > Cc: narmstrong@baylibre.com > Cc: Laurent.pinchart@ideasonboard.com > Cc: hjc@rock-chips.com > Cc: heiko@sntech.de > Acked-by: Neil Armstrong <narmstrong@baylibre.com> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net> > --- > drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 31 ++++++++++++----------------- > drivers/gpu/drm/imx/dw_hdmi-imx.c | 13 +++++++++--- > drivers/gpu/drm/meson/meson_dw_hdmi.c | 14 +++++++++---- > drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c | 12 +++++++++-- > drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 13 +++++++++--- > include/drm/bridge/dw_hdmi.h | 13 ++++++------ > 6 files changed, 60 insertions(+), 36 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > index 7d80f4b56683..f9802399cc0d 100644 > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > @@ -2543,8 +2543,6 @@ __dw_hdmi_probe(struct platform_device *pdev, > if (hdmi->i2c) > dw_hdmi_i2c_init(hdmi); > > - platform_set_drvdata(pdev, hdmi); > - > return hdmi; > > err_iahb: > @@ -2594,25 +2592,23 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi) > /* ----------------------------------------------------------------------------- > * Probe/remove API, used from platforms based on the DRM bridge API. > */ > -int dw_hdmi_probe(struct platform_device *pdev, > - const struct dw_hdmi_plat_data *plat_data) > +struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, > + const struct dw_hdmi_plat_data *plat_data) > { > struct dw_hdmi *hdmi; > > hdmi = __dw_hdmi_probe(pdev, plat_data); > if (IS_ERR(hdmi)) > - return PTR_ERR(hdmi); > + return hdmi; > > drm_bridge_add(&hdmi->bridge); > > - return 0; > + return hdmi; > } > EXPORT_SYMBOL_GPL(dw_hdmi_probe); > > -void dw_hdmi_remove(struct platform_device *pdev) > +void dw_hdmi_remove(struct dw_hdmi *hdmi) > { > - struct dw_hdmi *hdmi = platform_get_drvdata(pdev); > - > drm_bridge_remove(&hdmi->bridge); > > __dw_hdmi_remove(hdmi); > @@ -2622,31 +2618,30 @@ EXPORT_SYMBOL_GPL(dw_hdmi_remove); > /* ----------------------------------------------------------------------------- > * Bind/unbind API, used from platforms based on the component framework. > */ > -int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, > - const struct dw_hdmi_plat_data *plat_data) > +struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev, > + struct drm_encoder *encoder, > + const struct dw_hdmi_plat_data *plat_data) > { > struct dw_hdmi *hdmi; > int ret; > > hdmi = __dw_hdmi_probe(pdev, plat_data); > if (IS_ERR(hdmi)) > - return PTR_ERR(hdmi); > + return hdmi; > > ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL); > if (ret) { > - dw_hdmi_remove(pdev); > + dw_hdmi_remove(hdmi); > DRM_ERROR("Failed to initialize bridge with drm\n"); > - return ret; > + return ERR_PTR(ret); > } > > - return 0; > + return hdmi; > } > EXPORT_SYMBOL_GPL(dw_hdmi_bind); > > -void dw_hdmi_unbind(struct device *dev) > +void dw_hdmi_unbind(struct dw_hdmi *hdmi) > { > - struct dw_hdmi *hdmi = dev_get_drvdata(dev); > - > __dw_hdmi_remove(hdmi); > } > EXPORT_SYMBOL_GPL(dw_hdmi_unbind); > diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c > index b62763aa8706..fe6becdcc29e 100644 > --- a/drivers/gpu/drm/imx/dw_hdmi-imx.c > +++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c > @@ -25,6 +25,7 @@ > struct imx_hdmi { > struct device *dev; > struct drm_encoder encoder; > + struct dw_hdmi *hdmi; > struct regmap *regmap; > }; > > @@ -239,14 +240,18 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master, > drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs, > DRM_MODE_ENCODER_TMDS, NULL); > > - ret = dw_hdmi_bind(pdev, encoder, plat_data); > + platform_set_drvdata(pdev, hdmi); > + > + hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data); > > /* > * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), > * which would have called the encoder cleanup. Do it manually. > */ > - if (ret) > + if (IS_ERR(hdmi->hdmi)) { > + ret = PTR_ERR(hdmi->hdmi); > drm_encoder_cleanup(encoder); > + } > > return ret; > } > @@ -254,7 +259,9 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master, > static void dw_hdmi_imx_unbind(struct device *dev, struct device *master, > void *data) > { > - return dw_hdmi_unbind(dev); > + struct imx_hdmi *hdmi = dev_get_drvdata(dev); > + > + dw_hdmi_unbind(hdmi->hdmi); > } > > static const struct component_ops dw_hdmi_imx_ops = { > diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c > index e8c3ef8a94ce..d49af17310c9 100644 > --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c > +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c > @@ -140,6 +140,7 @@ struct meson_dw_hdmi { > struct clk *venci_clk; > struct regulator *hdmi_supply; > u32 irq_stat; > + struct dw_hdmi *hdmi; > }; > #define encoder_to_meson_dw_hdmi(x) \ > container_of(x, struct meson_dw_hdmi, encoder) > @@ -878,9 +879,12 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, > dw_plat_data->input_bus_format = MEDIA_BUS_FMT_YUV8_1X24; > dw_plat_data->input_bus_encoding = V4L2_YCBCR_ENC_709; > > - ret = dw_hdmi_bind(pdev, encoder, &meson_dw_hdmi->dw_plat_data); > - if (ret) > - return ret; > + platform_set_drvdata(pdev, meson_dw_hdmi); > + > + meson_dw_hdmi->hdmi = dw_hdmi_bind(pdev, encoder, > + &meson_dw_hdmi->dw_plat_data); > + if (IS_ERR(meson_dw_hdmi->hdmi)) > + return PTR_ERR(meson_dw_hdmi->hdmi); > > DRM_DEBUG_DRIVER("HDMI controller initialized\n"); > > @@ -890,7 +894,9 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, > static void meson_dw_hdmi_unbind(struct device *dev, struct device *master, > void *data) > { > - dw_hdmi_unbind(dev); > + struct meson_dw_hdmi *meson_dw_hdmi = dev_get_drvdata(dev); > + > + dw_hdmi_unbind(meson_dw_hdmi->hdmi); > } > > static const struct component_ops meson_dw_hdmi_ops = { > diff --git a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c > index dc85b53d58ef..3bebc6821e9c 100644 > --- a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c > +++ b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c > @@ -68,12 +68,20 @@ static const struct dw_hdmi_plat_data rcar_dw_hdmi_plat_data = { > > static int rcar_dw_hdmi_probe(struct platform_device *pdev) > { > - return dw_hdmi_probe(pdev, &rcar_dw_hdmi_plat_data); > + struct dw_hdmi *hdmi; > + > + hdmi = dw_hdmi_probe(pdev, &rcar_dw_hdmi_plat_data); > + if (IS_ERR(hdmi)) > + return PTR_ERR(hdmi); > + > + platform_set_drvdata(pdev, hdmi); > } > > static int rcar_dw_hdmi_remove(struct platform_device *pdev) > { > - dw_hdmi_remove(pdev); > + struct dw_hdmi *hdmi = platform_get_drvdata(dev); > + > + dw_hdmi_remove(hdmi); > > return 0; > } > diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c > index 1eb02a82fd91..3574b0ae2ad1 100644 > --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c > +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c > @@ -48,6 +48,7 @@ struct rockchip_hdmi { > const struct rockchip_hdmi_chip_data *chip_data; > struct clk *vpll_clk; > struct clk *grf_clk; > + struct dw_hdmi *hdmi; > }; > > #define to_rockchip_hdmi(x) container_of(x, struct rockchip_hdmi, x) > @@ -377,14 +378,18 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, > drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs, > DRM_MODE_ENCODER_TMDS, NULL); > > - ret = dw_hdmi_bind(pdev, encoder, plat_data); > + platform_set_drvdata(pdev, hdmi); > + > + hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data); > > /* > * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), > * which would have called the encoder cleanup. Do it manually. > */ > - if (ret) > + if (IS_ERR(hdmi->hdmi)) { > + ret = PTR_ERR(hdmi->hdmi); > drm_encoder_cleanup(encoder); > + } > > return ret; > } > @@ -392,7 +397,9 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, > static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master, > void *data) > { > - return dw_hdmi_unbind(dev); > + struct rockchip_hdmi *hdmi = dev_get_drvdata(dev); > + > + dw_hdmi_unbind(hdmi->hdmi); > } > > static const struct component_ops dw_hdmi_rockchip_ops = { > diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h > index f3f3f0e1b2d3..dd2a8cf7d20b 100644 > --- a/include/drm/bridge/dw_hdmi.h > +++ b/include/drm/bridge/dw_hdmi.h > @@ -143,12 +143,13 @@ struct dw_hdmi_plat_data { > unsigned long mpixelclock); > }; > > -int dw_hdmi_probe(struct platform_device *pdev, > - const struct dw_hdmi_plat_data *plat_data); > -void dw_hdmi_remove(struct platform_device *pdev); > -void dw_hdmi_unbind(struct device *dev); > -int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, > - const struct dw_hdmi_plat_data *plat_data); > +struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, > + const struct dw_hdmi_plat_data *plat_data); > +void dw_hdmi_remove(struct dw_hdmi *hdmi); > +void dw_hdmi_unbind(struct dw_hdmi *hdmi); > +struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev, > + struct drm_encoder *encoder, > + const struct dw_hdmi_plat_data *plat_data); > > void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense); > > -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Am Mittwoch, 14. Februar 2018, 21:08:59 CET schrieb Jernej Skrabec: > dw_hdmi shouldn't set drvdata since some drivers might need to store > it's own data there. Rework dw_hdmi in a way to return struct dw_hdmi > instead to store it in drvdata. This way drivers are responsible to > store and pass structure when needed. > > Idea was taken from the following commit: > 8242ecbd597d ("drm/bridge/synopsys: stop clobbering drvdata") > > Cc: p.zabel@pengutronix.de > Cc: narmstrong@baylibre.com > Cc: Laurent.pinchart@ideasonboard.com > Cc: hjc@rock-chips.com > Cc: heiko@sntech.de > Acked-by: Neil Armstrong <narmstrong@baylibre.com> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net> For the Rockchip-part Tested-by: Heiko Stuebner <heiko@sntech.de> Acked-by: Heiko Stuebner <heiko@sntech.de> -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, Feb 14, 2018 at 09:08:54PM +0100, Jernej Skrabec wrote: > This patch series implements support for A83T DW HDMI and PHY. Contrary to > v1 series, this one is based on latest linux-next, since all needed patches > were merged. > > While exactly this combination of HDMI controller and PHY is not common in > Allwinner SoCs, this patch series nevertheless makes groundwork for other > SoCs, which have same DW HDMI IP block, but different PHYs, like H3 and H5. > > Please take a look. Applied and pushed everything, thanks! Maxime
On Wed, 2018-02-14 at 21:08 +0100, Jernej Skrabec wrote: > dw_hdmi shouldn't set drvdata since some drivers might need to store > it's own data there. Rework dw_hdmi in a way to return struct dw_hdmi > instead to store it in drvdata. This way drivers are responsible to > store and pass structure when needed. > > Idea was taken from the following commit: > 8242ecbd597d ("drm/bridge/synopsys: stop clobbering drvdata") > > Cc: p.zabel@pengutronix.de > Cc: narmstrong@baylibre.com > Cc: Laurent.pinchart@ideasonboard.com > Cc: hjc@rock-chips.com > Cc: heiko@sntech.de > Acked-by: Neil Armstrong <narmstrong@baylibre.com> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net> For i.MX: Tested-by: Philipp Zabel <p.zabel@pengutronix.de> Acked-by: Philipp Zabel <p.zabel@pengutronix.de> regards Philipp -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html