diff options
Diffstat (limited to 'drivers/gpu/drm/omapdrm/dss/hdmi4.c')
| -rw-r--r-- | drivers/gpu/drm/omapdrm/dss/hdmi4.c | 60 |
1 files changed, 31 insertions, 29 deletions
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index 35b750cebaeb..3cd612af2449 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -29,6 +29,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_state_helper.h> +#include <drm/drm_edid.h> #include "omapdss.h" #include "hdmi4_core.h" @@ -313,6 +314,7 @@ void hdmi4_core_disable(struct hdmi_core_data *core) */ static int hdmi4_bridge_attach(struct drm_bridge *bridge, + struct drm_encoder *encoder, enum drm_bridge_attach_flags flags) { struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge); @@ -320,7 +322,7 @@ static int hdmi4_bridge_attach(struct drm_bridge *bridge, if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) return -EINVAL; - return drm_bridge_attach(bridge->encoder, hdmi->output.next_bridge, + return drm_bridge_attach(encoder, hdmi->output.next_bridge, bridge, flags); } @@ -340,10 +342,9 @@ static void hdmi4_bridge_mode_set(struct drm_bridge *bridge, } static void hdmi4_bridge_enable(struct drm_bridge *bridge, - struct drm_bridge_state *bridge_state) + struct drm_atomic_state *state) { struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge); - struct drm_atomic_state *state = bridge_state->base.state; struct drm_connector_state *conn_state; struct drm_connector *connector; struct drm_crtc_state *crtc_state; @@ -409,7 +410,7 @@ done: } static void hdmi4_bridge_disable(struct drm_bridge *bridge, - struct drm_bridge_state *bridge_state) + struct drm_atomic_state *state) { struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge); unsigned long flags; @@ -435,11 +436,11 @@ static void hdmi4_bridge_hpd_notify(struct drm_bridge *bridge, hdmi4_cec_set_phys_addr(&hdmi->core, CEC_PHYS_ADDR_INVALID); } -static struct edid *hdmi4_bridge_get_edid(struct drm_bridge *bridge, - struct drm_connector *connector) +static const struct drm_edid *hdmi4_bridge_edid_read(struct drm_bridge *bridge, + struct drm_connector *connector) { struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge); - struct edid *edid = NULL; + const struct drm_edid *drm_edid = NULL; unsigned int cec_addr; bool need_enable; int r; @@ -460,13 +461,21 @@ static struct edid *hdmi4_bridge_get_edid(struct drm_bridge *bridge, if (r) goto done; - edid = drm_do_get_edid(connector, hdmi4_core_ddc_read, &hdmi->core); + drm_edid = drm_edid_read_custom(connector, hdmi4_core_ddc_read, &hdmi->core); done: hdmi_runtime_put(hdmi); mutex_unlock(&hdmi->lock); - if (edid && edid->extensions) { + if (drm_edid) { + /* + * FIXME: The CEC physical address should be set using + * hdmi4_cec_set_phys_addr(&hdmi->core, + * connector->display_info.source_physical_address) from a path + * that has read the EDID and called + * drm_edid_connector_update(). + */ + const struct edid *edid = drm_edid_raw(drm_edid); unsigned int len = (edid->extensions + 1) * EDID_LENGTH; cec_addr = cec_get_edid_phys_addr((u8 *)edid, len, NULL); @@ -479,7 +488,7 @@ done: if (need_enable) hdmi4_core_disable(&hdmi->core); - return edid; + return drm_edid; } static const struct drm_bridge_funcs hdmi4_bridge_funcs = { @@ -491,12 +500,11 @@ static const struct drm_bridge_funcs hdmi4_bridge_funcs = { .atomic_enable = hdmi4_bridge_enable, .atomic_disable = hdmi4_bridge_disable, .hpd_notify = hdmi4_bridge_hpd_notify, - .get_edid = hdmi4_bridge_get_edid, + .edid_read = hdmi4_bridge_edid_read, }; static void hdmi4_bridge_init(struct omap_hdmi *hdmi) { - hdmi->bridge.funcs = &hdmi4_bridge_funcs; hdmi->bridge.of_node = hdmi->pdev->dev.of_node; hdmi->bridge.ops = DRM_BRIDGE_OP_EDID; hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA; @@ -752,9 +760,9 @@ static int hdmi4_probe(struct platform_device *pdev) int irq; int r; - hdmi = kzalloc(sizeof(*hdmi), GFP_KERNEL); - if (!hdmi) - return -ENOMEM; + hdmi = devm_drm_bridge_alloc(&pdev->dev, struct omap_hdmi, bridge, &hdmi4_bridge_funcs); + if (IS_ERR(hdmi)) + return PTR_ERR(hdmi); hdmi->pdev = pdev; @@ -765,25 +773,24 @@ static int hdmi4_probe(struct platform_device *pdev) r = hdmi4_probe_of(hdmi); if (r) - goto err_free; + return r; r = hdmi_wp_init(pdev, &hdmi->wp, 4); if (r) - goto err_free; + return r; r = hdmi_phy_init(pdev, &hdmi->phy, 4); if (r) - goto err_free; + return r; r = hdmi4_core_init(pdev, &hdmi->core); if (r) - goto err_free; + return r; irq = platform_get_irq(pdev, 0); if (irq < 0) { DSSERR("platform_get_irq failed\n"); - r = -ENODEV; - goto err_free; + return -ENODEV; } r = devm_request_threaded_irq(&pdev->dev, irq, @@ -791,7 +798,7 @@ static int hdmi4_probe(struct platform_device *pdev) IRQF_ONESHOT, "OMAP HDMI", hdmi); if (r) { DSSERR("HDMI IRQ request failed\n"); - goto err_free; + return r; } hdmi->vdda_reg = devm_regulator_get(&pdev->dev, "vdda"); @@ -799,7 +806,7 @@ static int hdmi4_probe(struct platform_device *pdev) r = PTR_ERR(hdmi->vdda_reg); if (r != -EPROBE_DEFER) DSSERR("can't get VDDA regulator\n"); - goto err_free; + return r; } pm_runtime_enable(&pdev->dev); @@ -818,12 +825,10 @@ err_uninit_output: hdmi4_uninit_output(hdmi); err_pm_disable: pm_runtime_disable(&pdev->dev); -err_free: - kfree(hdmi); return r; } -static int hdmi4_remove(struct platform_device *pdev) +static void hdmi4_remove(struct platform_device *pdev) { struct omap_hdmi *hdmi = platform_get_drvdata(pdev); @@ -832,9 +837,6 @@ static int hdmi4_remove(struct platform_device *pdev) hdmi4_uninit_output(hdmi); pm_runtime_disable(&pdev->dev); - - kfree(hdmi); - return 0; } static const struct of_device_id hdmi_of_match[] = { |
