Hello,
This patch series reworks all the HPD-related operations (detection, EDID read, HPD callback (un)registration and HPD enable/disable) as a step toward moving from omap_dss_device to drm_bridge.
All HPD-related operations are called by the omapdrm driver on the omap_dss_device at the end of display pipeline, and the operations are then handled directly or forwarded to the previous omap_dss_device in the pipeline. This causes an issue in our quest to move to drm_bridge: there are currently no HPD-related operations in the drm_bridge API, as they are implemented internally by bridge drivers for the drm_connector created by the bridges.
To solve this, we will need to extend the drm_bridge API with HPD-related operations. This patch series is a prototype of such an API, still local to omap_dss_device for now.
HPD operations can be implemented by multiple components in a display pipeline. For instance, the DDC bus of an HDMI connector can be wired to an I2C bus of the SoC, or to the DDC pins of an HDMI encoder. In the first case the HDMI connector component will provide EDID access, while in the second case EDID will be read through the HDMI encoder component. Both components will thus implement the EDID read operation, but on a particular system only one of them will be able to provide the feature.
Determining which component provides a feature at runtime is thus required, and is currently performed through recursive calls. This requires all components to cooperate in a way that can be implemented locally in the omapdrm driver but would be too complex for the more generic drm_bridge API. Our solution is to use flags in the omap_dss_device structure to tell, at runtime, which features are available. The top-level code can then locate the component providing a particular feature and then use that component directly.
The series starts with removal of dead or unneeded code in patches 01/21 to 03/21. Patch 04/21 prepares for the merge of the omap_dss_driver and omap_dss_device_ops structures. Patches then 05/21 to 10/21 convert the driver from the GPIO API to the GPIO descriptors API (drive-by cleanup).
Patch 11/21 is where the real refactoring starts. It moves most operations from the omap_dss_driver structure to the omap_dss_device_ops structure in order to simplify code iterating over pipelines. Patch 12/21 defines the operation flags, and patches 13/21 and 14/21 make use of them to rework the .detect(), .register_hpd_cb() and .unregister_hpd_cb() operations. Patches 15/21 and 16/21 remove the unneeded .enable_hpd() and .disable_hpd() operations. Patch 17/21 moves DSS-specific HPD-related code from omap_dss_device instances to the omapdrm driver, and patch 18/21 reworks the .read_edid() operation. Patch 19/21 simplifies the component handling in the CRTC mode set code, and patches 20/21 and 21/21 finally rework the .set_hdmi_mode() and .set_infoframe() operations.
Laurent Pinchart (21): drm/omap: dss: Remove unused omap_dss_driver operations drm/omap: dss: Remove omap_dss_driver .[gs]et_mirror operations drm/omap: Remove unnecessary display output sanity checks drm/omap: Check omap_dss_device type based on the output_type field drm/omap: connector-hdmi: Convert to the GPIO descriptors API drm/omap: encoder-tfp410: Convert to the GPIO descriptors API drm/omap: panel-nec-nl8048hl11: Convert to the GPIO descriptors API drm/omap: panel-sony-acx565akm: Convert to the GPIO descriptors API drm/omap: panel-tpo-td028ttec1: Drop unneeded linux/gpio.h header drm/omap: panel-tpo-td043mtea1: Convert to the GPIO descriptors API drm/omap: Move most omap_dss_driver operations to omap_dss_device_ops drm/omap: dss: Add device operations flags drm/omap: Don't call .detect() operation recursively drm/omap: Don't call HPD registration operations recursively drm/omap: Remove unneeded safety checks in the HPD operations drm/omap: Merge HPD enable operation with HPD callback registration drm/omap: Move HPD disconnection handling to omap_connector drm/omap: Don't call EDID read operation recursively drm/omap: Get from CRTC to display device directly drm/omap: Pass both output and display omap_dss_device to encoder init drm/omap: Don't call HDMI mode and infoframe operations recursively
.../gpu/drm/omapdrm/displays/connector-analog-tv.c | 4 +- drivers/gpu/drm/omapdrm/displays/connector-dvi.c | 52 +--- drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 160 +++---------- drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c | 51 +--- .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 79 +----- drivers/gpu/drm/omapdrm/displays/panel-dpi.c | 4 +- drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c | 12 +- .../omapdrm/displays/panel-lgphilips-lb035q02.c | 4 +- .../drm/omapdrm/displays/panel-nec-nl8048hl11.c | 58 +---- .../drm/omapdrm/displays/panel-sharp-ls037v7dw01.c | 4 +- .../drm/omapdrm/displays/panel-sony-acx565akm.c | 60 ++--- .../drm/omapdrm/displays/panel-tpo-td028ttec1.c | 5 +- .../drm/omapdrm/displays/panel-tpo-td043mtea1.c | 81 ++----- drivers/gpu/drm/omapdrm/dss/base.c | 16 +- drivers/gpu/drm/omapdrm/dss/dss.c | 5 +- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 4 +- drivers/gpu/drm/omapdrm/dss/hdmi5.c | 4 +- drivers/gpu/drm/omapdrm/dss/omapdss.h | 81 +++---- drivers/gpu/drm/omapdrm/omap_connector.c | 265 +++++++++++++-------- drivers/gpu/drm/omapdrm/omap_connector.h | 2 + drivers/gpu/drm/omapdrm/omap_crtc.c | 25 +- drivers/gpu/drm/omapdrm/omap_drv.c | 28 +-- drivers/gpu/drm/omapdrm/omap_encoder.c | 49 ++-- drivers/gpu/drm/omapdrm/omap_encoder.h | 6 +- 24 files changed, 386 insertions(+), 673 deletions(-)
The .probe(), .remove(), .run_test(), .get_rotate() and .set_rotate() omap_dss_driver operations are not used. Remove them.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/omapdrm/dss/omapdss.h | 7 ------- 1 file changed, 7 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index 882a2f8f7ac5..77ba8ace6795 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -429,9 +429,6 @@ struct omap_dss_device { };
struct omap_dss_driver { - int (*probe)(struct omap_dss_device *); - void (*remove)(struct omap_dss_device *); - int (*connect)(struct omap_dss_device *src, struct omap_dss_device *dst); void (*disconnect)(struct omap_dss_device *src, @@ -439,7 +436,6 @@ struct omap_dss_driver {
int (*enable)(struct omap_dss_device *display); void (*disable)(struct omap_dss_device *display); - int (*run_test)(struct omap_dss_device *display, int test);
int (*update)(struct omap_dss_device *dssdev, u16 x, u16 y, u16 w, u16 h); @@ -448,9 +444,6 @@ struct omap_dss_driver { int (*enable_te)(struct omap_dss_device *dssdev, bool enable); int (*get_te)(struct omap_dss_device *dssdev);
- u8 (*get_rotate)(struct omap_dss_device *dssdev); - int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate); - bool (*get_mirror)(struct omap_dss_device *dssdev); int (*set_mirror)(struct omap_dss_device *dssdev, bool enable);
Hi,
On Wed, Jun 06, 2018 at 12:36:30PM +0300, Laurent Pinchart wrote:
The .probe(), .remove(), .run_test(), .get_rotate() and .set_rotate() omap_dss_driver operations are not used. Remove them.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com
Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.co.uk
-- Sebastian
drivers/gpu/drm/omapdrm/dss/omapdss.h | 7 ------- 1 file changed, 7 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index 882a2f8f7ac5..77ba8ace6795 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -429,9 +429,6 @@ struct omap_dss_device { };
struct omap_dss_driver {
- int (*probe)(struct omap_dss_device *);
- void (*remove)(struct omap_dss_device *);
- int (*connect)(struct omap_dss_device *src, struct omap_dss_device *dst); void (*disconnect)(struct omap_dss_device *src,
@@ -439,7 +436,6 @@ struct omap_dss_driver {
int (*enable)(struct omap_dss_device *display); void (*disable)(struct omap_dss_device *display);
int (*run_test)(struct omap_dss_device *display, int test);
int (*update)(struct omap_dss_device *dssdev, u16 x, u16 y, u16 w, u16 h);
@@ -448,9 +444,6 @@ struct omap_dss_driver { int (*enable_te)(struct omap_dss_device *dssdev, bool enable); int (*get_te)(struct omap_dss_device *dssdev);
- u8 (*get_rotate)(struct omap_dss_device *dssdev);
- int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate);
- bool (*get_mirror)(struct omap_dss_device *dssdev); int (*set_mirror)(struct omap_dss_device *dssdev, bool enable);
-- Regards,
Laurent Pinchart
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
The .get_mirror() and .set_mirror() omap_dss_driver operations are implemented by the panel-tpo-td043mtea1 driver but are never used. Remove them.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com --- .../drm/omapdrm/displays/panel-tpo-td043mtea1.c | 25 ++-------------------- drivers/gpu/drm/omapdrm/dss/omapdss.h | 3 --- 2 files changed, 2 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c index cb6f19f8a0da..34531169c166 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c @@ -62,7 +62,6 @@ struct panel_drv_data { int nreset_gpio; u16 gamma[12]; u32 mode; - u32 hmirror:1; u32 vmirror:1; u32 powered_on:1; u32 spi_suspended:1; @@ -151,22 +150,6 @@ static int tpo_td043_write_mirror(struct spi_device *spi, bool h, bool v) return tpo_td043_write(spi, 4, reg4); }
-static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable) -{ - struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); - - ddata->hmirror = enable; - return tpo_td043_write_mirror(ddata->spi, ddata->hmirror, - ddata->vmirror); -} - -static bool tpo_td043_get_hmirror(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); - - return ddata->hmirror; -} - static ssize_t tpo_td043_vmirror_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -188,7 +171,7 @@ static ssize_t tpo_td043_vmirror_store(struct device *dev,
val = !!val;
- ret = tpo_td043_write_mirror(ddata->spi, ddata->hmirror, val); + ret = tpo_td043_write_mirror(ddata->spi, false, val); if (ret < 0) return ret;
@@ -307,8 +290,7 @@ static int tpo_td043_power_on(struct panel_drv_data *ddata) tpo_td043_write(ddata->spi, 3, TPO_R03_VAL_NORMAL); tpo_td043_write(ddata->spi, 0x20, 0xf0); tpo_td043_write(ddata->spi, 0x21, 0xf0); - tpo_td043_write_mirror(ddata->spi, ddata->hmirror, - ddata->vmirror); + tpo_td043_write_mirror(ddata->spi, false, ddata->vmirror); tpo_td043_write_gamma(ddata->spi, ddata->gamma);
ddata->powered_on = 1; @@ -435,9 +417,6 @@ static const struct omap_dss_driver tpo_td043_ops = { .set_timings = tpo_td043_set_timings, .get_timings = tpo_td043_get_timings, .check_timings = tpo_td043_check_timings, - - .set_mirror = tpo_td043_set_hmirror, - .get_mirror = tpo_td043_get_hmirror, };
static int tpo_td043_probe_of(struct spi_device *spi) diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index 77ba8ace6795..3bfb62b28a77 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -444,9 +444,6 @@ struct omap_dss_driver { int (*enable_te)(struct omap_dss_device *dssdev, bool enable); int (*get_te)(struct omap_dss_device *dssdev);
- bool (*get_mirror)(struct omap_dss_device *dssdev); - int (*set_mirror)(struct omap_dss_device *dssdev, bool enable); - int (*memory_read)(struct omap_dss_device *dssdev, void *buf, size_t size, u16 x, u16 y, u16 w, u16 h);
Hi,
On Wed, Jun 06, 2018 at 12:36:31PM +0300, Laurent Pinchart wrote:
The .get_mirror() and .set_mirror() omap_dss_driver operations are implemented by the panel-tpo-td043mtea1 driver but are never used. Remove them.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com
Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.co.uk
-- Sebastian
.../drm/omapdrm/displays/panel-tpo-td043mtea1.c | 25 ++-------------------- drivers/gpu/drm/omapdrm/dss/omapdss.h | 3 --- 2 files changed, 2 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c index cb6f19f8a0da..34531169c166 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c @@ -62,7 +62,6 @@ struct panel_drv_data { int nreset_gpio; u16 gamma[12]; u32 mode;
- u32 hmirror:1; u32 vmirror:1; u32 powered_on:1; u32 spi_suspended:1;
@@ -151,22 +150,6 @@ static int tpo_td043_write_mirror(struct spi_device *spi, bool h, bool v) return tpo_td043_write(spi, 4, reg4); }
-static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable) -{
- struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
- ddata->hmirror = enable;
- return tpo_td043_write_mirror(ddata->spi, ddata->hmirror,
ddata->vmirror);
-}
-static bool tpo_td043_get_hmirror(struct omap_dss_device *dssdev) -{
- struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
- return ddata->hmirror;
-}
static ssize_t tpo_td043_vmirror_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -188,7 +171,7 @@ static ssize_t tpo_td043_vmirror_store(struct device *dev,
val = !!val;
- ret = tpo_td043_write_mirror(ddata->spi, ddata->hmirror, val);
- ret = tpo_td043_write_mirror(ddata->spi, false, val); if (ret < 0) return ret;
@@ -307,8 +290,7 @@ static int tpo_td043_power_on(struct panel_drv_data *ddata) tpo_td043_write(ddata->spi, 3, TPO_R03_VAL_NORMAL); tpo_td043_write(ddata->spi, 0x20, 0xf0); tpo_td043_write(ddata->spi, 0x21, 0xf0);
- tpo_td043_write_mirror(ddata->spi, ddata->hmirror,
ddata->vmirror);
tpo_td043_write_mirror(ddata->spi, false, ddata->vmirror); tpo_td043_write_gamma(ddata->spi, ddata->gamma);
ddata->powered_on = 1;
@@ -435,9 +417,6 @@ static const struct omap_dss_driver tpo_td043_ops = { .set_timings = tpo_td043_set_timings, .get_timings = tpo_td043_get_timings, .check_timings = tpo_td043_check_timings,
- .set_mirror = tpo_td043_set_hmirror,
- .get_mirror = tpo_td043_get_hmirror,
};
static int tpo_td043_probe_of(struct spi_device *spi) diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index 77ba8ace6795..3bfb62b28a77 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -444,9 +444,6 @@ struct omap_dss_driver { int (*enable_te)(struct omap_dss_device *dssdev, bool enable); int (*get_te)(struct omap_dss_device *dssdev);
- bool (*get_mirror)(struct omap_dss_device *dssdev);
- int (*set_mirror)(struct omap_dss_device *dssdev, bool enable);
- int (*memory_read)(struct omap_dss_device *dssdev, void *buf, size_t size, u16 x, u16 y, u16 w, u16 h);
-- Regards,
Laurent Pinchart
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
The omapdrm driver checks at suspend and resume time whether the displays it operates on have their driver operations set. This check is unneeded, as all display drivers set the driver operations field at probe time and never touch it afterwards. This is furthermore proven by the dereferencing of the driver field without checking it first in several locations.
The omapdss driver performs a similar check at shutdown time. This is unneeded as well, as the for_each_dss_display() macro it uses to iterate over displays locates the displays by checking the driver field internally.
As those checks are unnecessary, remove them.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/omapdrm/dss/dss.c | 3 --- drivers/gpu/drm/omapdrm/omap_drv.c | 6 ------ 2 files changed, 9 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index d2760107ccf2..6118159dd571 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -1552,9 +1552,6 @@ static void dss_shutdown(struct platform_device *pdev) DSSDBG("shutdown\n");
for_each_dss_display(dssdev) { - if (!dssdev->driver) - continue; - if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) dssdev->driver->disable(dssdev); } diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index c3c657d90029..e5b52fd4203e 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -723,9 +723,6 @@ static int omap_drm_suspend_all_displays(struct drm_device *ddev) for (i = 0; i < priv->num_pipes; i++) { struct omap_dss_device *display = priv->pipes[i].display;
- if (!display->driver) - continue; - if (display->state == OMAP_DSS_DISPLAY_ACTIVE) { display->driver->disable(display); display->activate_after_resume = true; @@ -745,9 +742,6 @@ static int omap_drm_resume_all_displays(struct drm_device *ddev) for (i = 0; i < priv->num_pipes; i++) { struct omap_dss_device *display = priv->pipes[i].display;
- if (!display->driver) - continue; - if (display->activate_after_resume) { display->driver->enable(display); display->activate_after_resume = false;
Hi,
On Wed, Jun 06, 2018 at 12:36:32PM +0300, Laurent Pinchart wrote:
The omapdrm driver checks at suspend and resume time whether the displays it operates on have their driver operations set. This check is unneeded, as all display drivers set the driver operations field at probe time and never touch it afterwards. This is furthermore proven by the dereferencing of the driver field without checking it first in several locations.
The omapdss driver performs a similar check at shutdown time. This is unneeded as well, as the for_each_dss_display() macro it uses to iterate over displays locates the displays by checking the driver field internally.
As those checks are unnecessary, remove them.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com
Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.co.uk
-- Sebastian
drivers/gpu/drm/omapdrm/dss/dss.c | 3 --- drivers/gpu/drm/omapdrm/omap_drv.c | 6 ------ 2 files changed, 9 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index d2760107ccf2..6118159dd571 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -1552,9 +1552,6 @@ static void dss_shutdown(struct platform_device *pdev) DSSDBG("shutdown\n");
for_each_dss_display(dssdev) {
if (!dssdev->driver)
continue;
- if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) dssdev->driver->disable(dssdev); }
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index c3c657d90029..e5b52fd4203e 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -723,9 +723,6 @@ static int omap_drm_suspend_all_displays(struct drm_device *ddev) for (i = 0; i < priv->num_pipes; i++) { struct omap_dss_device *display = priv->pipes[i].display;
if (!display->driver)
continue;
- if (display->state == OMAP_DSS_DISPLAY_ACTIVE) { display->driver->disable(display); display->activate_after_resume = true;
@@ -745,9 +742,6 @@ static int omap_drm_resume_all_displays(struct drm_device *ddev) for (i = 0; i < priv->num_pipes; i++) { struct omap_dss_device *display = priv->pipes[i].display;
if (!display->driver)
continue;
- if (display->activate_after_resume) { display->driver->enable(display); display->activate_after_resume = false;
-- Regards,
Laurent Pinchart
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Various functions that need to differentiate between omap_dss_device instances corresponding to displays and to internal encoders use the omap_dss_device.driver field, which is only set for display instances. This gets in the way of the omap_dss_device operations refactoring. Replace that with a check based on the output_type field which is set for all omap_dss_device instances but displays.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/omapdrm/dss/base.c | 4 ++-- drivers/gpu/drm/omapdrm/dss/omapdss.h | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/dss/base.c b/drivers/gpu/drm/omapdrm/dss/base.c index cce09a48d769..6a73d3559257 100644 --- a/drivers/gpu/drm/omapdrm/dss/base.c +++ b/drivers/gpu/drm/omapdrm/dss/base.c @@ -165,7 +165,7 @@ struct omap_dss_device *omapdss_device_get_next(struct omap_dss_device *from, * Filter out non-display entries if display_only is set, and * non-output entries if output_only is set. */ - if (display_only && !dssdev->driver) + if (display_only && dssdev->output_type) continue; if (output_only && (!dssdev->id || !dssdev->next)) continue; @@ -224,7 +224,7 @@ void omapdss_device_disconnect(struct omap_dss_device *src, dev_dbg(src->dev, "disconnect\n");
if (!omapdss_device_is_connected(dst)) { - WARN_ON(!dst->driver); + WARN_ON(dst->output_type); return; }
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index 3bfb62b28a77..ae30802f2151 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -401,6 +401,12 @@ struct omap_dss_device { unsigned int alias_id;
enum omap_display_type type; + /* + * DSS output type that this device generates (for DSS internal devices) + * or requires (for external encoders). Must be OMAP_DISPLAY_TYPE_NONE + * for display devices (connectors and panels) and to non-zero value for + * all other devices. + */ enum omap_display_type output_type;
const char *name;
Hi,
On Wed, Jun 06, 2018 at 12:36:33PM +0300, Laurent Pinchart wrote:
Various functions that need to differentiate between omap_dss_device instances corresponding to displays and to internal encoders use the omap_dss_device.driver field, which is only set for display instances. This gets in the way of the omap_dss_device operations refactoring. Replace that with a check based on the output_type field which is set for all omap_dss_device instances but displays.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com
Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.co.uk
-- Sebastian
drivers/gpu/drm/omapdrm/dss/base.c | 4 ++-- drivers/gpu/drm/omapdrm/dss/omapdss.h | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/dss/base.c b/drivers/gpu/drm/omapdrm/dss/base.c index cce09a48d769..6a73d3559257 100644 --- a/drivers/gpu/drm/omapdrm/dss/base.c +++ b/drivers/gpu/drm/omapdrm/dss/base.c @@ -165,7 +165,7 @@ struct omap_dss_device *omapdss_device_get_next(struct omap_dss_device *from, * Filter out non-display entries if display_only is set, and * non-output entries if output_only is set. */
if (display_only && !dssdev->driver)
if (output_only && (!dssdev->id || !dssdev->next)) continue;if (display_only && dssdev->output_type) continue;
@@ -224,7 +224,7 @@ void omapdss_device_disconnect(struct omap_dss_device *src, dev_dbg(src->dev, "disconnect\n");
if (!omapdss_device_is_connected(dst)) {
WARN_ON(!dst->driver);
return; }WARN_ON(dst->output_type);
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index 3bfb62b28a77..ae30802f2151 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -401,6 +401,12 @@ struct omap_dss_device { unsigned int alias_id;
enum omap_display_type type;
/*
* DSS output type that this device generates (for DSS internal devices)
* or requires (for external encoders). Must be OMAP_DISPLAY_TYPE_NONE
* for display devices (connectors and panels) and to non-zero value for
* all other devices.
*/
enum omap_display_type output_type;
const char *name;
-- Regards,
Laurent Pinchart
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
The GPIO descriptor API is favoured over the plain GPIO API for consumer drivers. Using it simplifies the driver code.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 57 ++++++++--------------- 1 file changed, 20 insertions(+), 37 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index e9878da5bfdb..d39480b8cf6b 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c @@ -10,12 +10,10 @@ */
#include <linux/gpio/consumer.h> -#include <linux/slab.h> #include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/of.h> -#include <linux/of_gpio.h> #include <linux/mutex.h> +#include <linux/platform_device.h> +#include <linux/slab.h>
#include <drm/drm_edid.h>
@@ -46,7 +44,7 @@ struct panel_drv_data {
struct videomode vm;
- int hpd_gpio; + struct gpio_desc *hpd_gpio; };
#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev) @@ -143,8 +141,8 @@ static bool hdmic_detect(struct omap_dss_device *dssdev) struct omap_dss_device *src = dssdev->src; bool connected;
- if (gpio_is_valid(ddata->hpd_gpio)) - connected = gpio_get_value_cansleep(ddata->hpd_gpio); + if (ddata->hpd_gpio) + connected = gpiod_get_value_cansleep(ddata->hpd_gpio); else connected = src->ops->hdmi.detect(src); if (!connected && src->ops->hdmi.lost_hotplug) @@ -160,7 +158,7 @@ static int hdmic_register_hpd_cb(struct omap_dss_device *dssdev, struct panel_drv_data *ddata = to_panel_data(dssdev); struct omap_dss_device *src = dssdev->src;
- if (gpio_is_valid(ddata->hpd_gpio)) { + if (ddata->hpd_gpio) { mutex_lock(&ddata->hpd_lock); ddata->hpd_cb = cb; ddata->hpd_cb_data = cb_data; @@ -178,7 +176,7 @@ static void hdmic_unregister_hpd_cb(struct omap_dss_device *dssdev) struct panel_drv_data *ddata = to_panel_data(dssdev); struct omap_dss_device *src = dssdev->src;
- if (gpio_is_valid(ddata->hpd_gpio)) { + if (ddata->hpd_gpio) { mutex_lock(&ddata->hpd_lock); ddata->hpd_cb = NULL; ddata->hpd_cb_data = NULL; @@ -193,7 +191,7 @@ static void hdmic_enable_hpd(struct omap_dss_device *dssdev) struct panel_drv_data *ddata = to_panel_data(dssdev); struct omap_dss_device *src = dssdev->src;
- if (gpio_is_valid(ddata->hpd_gpio)) { + if (ddata->hpd_gpio) { mutex_lock(&ddata->hpd_lock); ddata->hpd_enabled = true; mutex_unlock(&ddata->hpd_lock); @@ -207,7 +205,7 @@ static void hdmic_disable_hpd(struct omap_dss_device *dssdev) struct panel_drv_data *ddata = to_panel_data(dssdev); struct omap_dss_device *src = dssdev->src;
- if (gpio_is_valid(ddata->hpd_gpio)) { + if (ddata->hpd_gpio) { mutex_lock(&ddata->hpd_lock); ddata->hpd_enabled = false; mutex_unlock(&ddata->hpd_lock); @@ -272,26 +270,11 @@ static irqreturn_t hdmic_hpd_isr(int irq, void *data) return IRQ_HANDLED; }
-static int hdmic_probe_of(struct platform_device *pdev) -{ - struct panel_drv_data *ddata = platform_get_drvdata(pdev); - struct device_node *node = pdev->dev.of_node; - int gpio; - - /* HPD GPIO */ - gpio = of_get_named_gpio(node, "hpd-gpios", 0); - if (gpio_is_valid(gpio)) - ddata->hpd_gpio = gpio; - else - ddata->hpd_gpio = -ENODEV; - - return 0; -} - static int hdmic_probe(struct platform_device *pdev) { struct panel_drv_data *ddata; struct omap_dss_device *dssdev; + struct gpio_desc *gpio; int r;
ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL); @@ -301,20 +284,20 @@ static int hdmic_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ddata); ddata->dev = &pdev->dev;
- r = hdmic_probe_of(pdev); - if (r) - return r; - mutex_init(&ddata->hpd_lock);
- if (gpio_is_valid(ddata->hpd_gpio)) { - r = devm_gpio_request_one(&pdev->dev, ddata->hpd_gpio, - GPIOF_DIR_IN, "hdmi_hpd"); - if (r) - return r; + /* HPD GPIO */ + gpio = devm_gpiod_get_optional(&pdev->dev, "hpd", GPIOD_IN); + if (IS_ERR(gpio)) { + dev_err(&pdev->dev, "failed to parse HPD gpio\n"); + return PTR_ERR(gpio); + } + + ddata->hpd_gpio = gpio;
+ if (ddata->hpd_gpio) { r = devm_request_threaded_irq(&pdev->dev, - gpio_to_irq(ddata->hpd_gpio), + gpiod_to_irq(ddata->hpd_gpio), NULL, hdmic_hpd_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
Hi,
On Wed, Jun 06, 2018 at 12:36:34PM +0300, Laurent Pinchart wrote:
The GPIO descriptor API is favoured over the plain GPIO API for consumer drivers. Using it simplifies the driver code.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com
Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.co.uk
-- Sebastian
drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 57 ++++++++--------------- 1 file changed, 20 insertions(+), 37 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index e9878da5bfdb..d39480b8cf6b 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c @@ -10,12 +10,10 @@ */
#include <linux/gpio/consumer.h> -#include <linux/slab.h> #include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/of.h> -#include <linux/of_gpio.h> #include <linux/mutex.h> +#include <linux/platform_device.h> +#include <linux/slab.h>
#include <drm/drm_edid.h>
@@ -46,7 +44,7 @@ struct panel_drv_data {
struct videomode vm;
- int hpd_gpio;
- struct gpio_desc *hpd_gpio;
};
#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev) @@ -143,8 +141,8 @@ static bool hdmic_detect(struct omap_dss_device *dssdev) struct omap_dss_device *src = dssdev->src; bool connected;
- if (gpio_is_valid(ddata->hpd_gpio))
connected = gpio_get_value_cansleep(ddata->hpd_gpio);
- if (ddata->hpd_gpio)
else connected = src->ops->hdmi.detect(src); if (!connected && src->ops->hdmi.lost_hotplug)connected = gpiod_get_value_cansleep(ddata->hpd_gpio);
@@ -160,7 +158,7 @@ static int hdmic_register_hpd_cb(struct omap_dss_device *dssdev, struct panel_drv_data *ddata = to_panel_data(dssdev); struct omap_dss_device *src = dssdev->src;
- if (gpio_is_valid(ddata->hpd_gpio)) {
- if (ddata->hpd_gpio) { mutex_lock(&ddata->hpd_lock); ddata->hpd_cb = cb; ddata->hpd_cb_data = cb_data;
@@ -178,7 +176,7 @@ static void hdmic_unregister_hpd_cb(struct omap_dss_device *dssdev) struct panel_drv_data *ddata = to_panel_data(dssdev); struct omap_dss_device *src = dssdev->src;
- if (gpio_is_valid(ddata->hpd_gpio)) {
- if (ddata->hpd_gpio) { mutex_lock(&ddata->hpd_lock); ddata->hpd_cb = NULL; ddata->hpd_cb_data = NULL;
@@ -193,7 +191,7 @@ static void hdmic_enable_hpd(struct omap_dss_device *dssdev) struct panel_drv_data *ddata = to_panel_data(dssdev); struct omap_dss_device *src = dssdev->src;
- if (gpio_is_valid(ddata->hpd_gpio)) {
- if (ddata->hpd_gpio) { mutex_lock(&ddata->hpd_lock); ddata->hpd_enabled = true; mutex_unlock(&ddata->hpd_lock);
@@ -207,7 +205,7 @@ static void hdmic_disable_hpd(struct omap_dss_device *dssdev) struct panel_drv_data *ddata = to_panel_data(dssdev); struct omap_dss_device *src = dssdev->src;
- if (gpio_is_valid(ddata->hpd_gpio)) {
- if (ddata->hpd_gpio) { mutex_lock(&ddata->hpd_lock); ddata->hpd_enabled = false; mutex_unlock(&ddata->hpd_lock);
@@ -272,26 +270,11 @@ static irqreturn_t hdmic_hpd_isr(int irq, void *data) return IRQ_HANDLED; }
-static int hdmic_probe_of(struct platform_device *pdev) -{
- struct panel_drv_data *ddata = platform_get_drvdata(pdev);
- struct device_node *node = pdev->dev.of_node;
- int gpio;
- /* HPD GPIO */
- gpio = of_get_named_gpio(node, "hpd-gpios", 0);
- if (gpio_is_valid(gpio))
ddata->hpd_gpio = gpio;
- else
ddata->hpd_gpio = -ENODEV;
- return 0;
-}
static int hdmic_probe(struct platform_device *pdev) { struct panel_drv_data *ddata; struct omap_dss_device *dssdev;
struct gpio_desc *gpio; int r;
ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
@@ -301,20 +284,20 @@ static int hdmic_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ddata); ddata->dev = &pdev->dev;
r = hdmic_probe_of(pdev);
if (r)
return r;
mutex_init(&ddata->hpd_lock);
if (gpio_is_valid(ddata->hpd_gpio)) {
r = devm_gpio_request_one(&pdev->dev, ddata->hpd_gpio,
GPIOF_DIR_IN, "hdmi_hpd");
if (r)
return r;
/* HPD GPIO */
gpio = devm_gpiod_get_optional(&pdev->dev, "hpd", GPIOD_IN);
if (IS_ERR(gpio)) {
dev_err(&pdev->dev, "failed to parse HPD gpio\n");
return PTR_ERR(gpio);
}
ddata->hpd_gpio = gpio;
if (ddata->hpd_gpio) { r = devm_request_threaded_irq(&pdev->dev,
gpio_to_irq(ddata->hpd_gpio),
gpiod_to_irq(ddata->hpd_gpio), NULL, hdmic_hpd_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
-- Regards,
Laurent Pinchart
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
The GPIO descriptor API is favoured over the plain GPIO API for consumer drivers. Using it simplifies the driver code.
As the descriptor API handles the active-low flag internally we need to invert the polarity of all GPIO operations in the driver.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c | 51 ++++++----------------- 1 file changed, 13 insertions(+), 38 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c index c7398428228f..b91e45c0bfdd 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c @@ -13,14 +13,13 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/slab.h> -#include <linux/of_gpio.h>
#include "../dss/omapdss.h"
struct panel_drv_data { struct omap_dss_device dssdev;
- int pd_gpio; + struct gpio_desc *pd_gpio;
struct videomode vm; }; @@ -57,8 +56,8 @@ static int tfp410_enable(struct omap_dss_device *dssdev) if (r) return r;
- if (gpio_is_valid(ddata->pd_gpio)) - gpio_set_value_cansleep(ddata->pd_gpio, 1); + if (ddata->pd_gpio) + gpiod_set_value_cansleep(ddata->pd_gpio, 0);
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
@@ -73,8 +72,8 @@ static void tfp410_disable(struct omap_dss_device *dssdev) if (!omapdss_device_is_enabled(dssdev)) return;
- if (gpio_is_valid(ddata->pd_gpio)) - gpio_set_value_cansleep(ddata->pd_gpio, 0); + if (ddata->pd_gpio) + gpiod_set_value_cansleep(ddata->pd_gpio, 0);
src->ops->disable(src);
@@ -119,30 +118,11 @@ static const struct omap_dss_device_ops tfp410_ops = { .set_timings = tfp410_set_timings, };
-static int tfp410_probe_of(struct platform_device *pdev) -{ - struct panel_drv_data *ddata = platform_get_drvdata(pdev); - struct device_node *node = pdev->dev.of_node; - int gpio; - - gpio = of_get_named_gpio(node, "powerdown-gpios", 0); - - if (gpio_is_valid(gpio) || gpio == -ENOENT) { - ddata->pd_gpio = gpio; - } else { - if (gpio != -EPROBE_DEFER) - dev_err(&pdev->dev, "failed to parse PD gpio\n"); - return gpio; - } - - return 0; -} - static int tfp410_probe(struct platform_device *pdev) { struct panel_drv_data *ddata; struct omap_dss_device *dssdev; - int r; + struct gpio_desc *gpio;
ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL); if (!ddata) @@ -150,20 +130,15 @@ static int tfp410_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ddata);
- r = tfp410_probe_of(pdev); - if (r) - return r; - - if (gpio_is_valid(ddata->pd_gpio)) { - r = devm_gpio_request_one(&pdev->dev, ddata->pd_gpio, - GPIOF_OUT_INIT_LOW, "tfp410 PD"); - if (r) { - dev_err(&pdev->dev, "Failed to request PD GPIO %d\n", - ddata->pd_gpio); - return r; - } + /* Powerdown GPIO */ + gpio = devm_gpiod_get_optional(&pdev->dev, "powerdown", GPIOD_OUT_HIGH); + if (IS_ERR(gpio)) { + dev_err(&pdev->dev, "failed to parse powerdown gpio\n"); + return PTR_ERR(gpio); }
+ ddata->pd_gpio = gpio; + dssdev = &ddata->dssdev; dssdev->ops = &tfp410_ops; dssdev->dev = &pdev->dev;
Hi,
On Wed, Jun 06, 2018 at 12:36:35PM +0300, Laurent Pinchart wrote:
The GPIO descriptor API is favoured over the plain GPIO API for consumer drivers. Using it simplifies the driver code.
As the descriptor API handles the active-low flag internally we need to invert the polarity of all GPIO operations in the driver.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com
Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.co.uk
-- Sebastian
drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c | 51 ++++++----------------- 1 file changed, 13 insertions(+), 38 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c index c7398428228f..b91e45c0bfdd 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c @@ -13,14 +13,13 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/slab.h> -#include <linux/of_gpio.h>
#include "../dss/omapdss.h"
struct panel_drv_data { struct omap_dss_device dssdev;
- int pd_gpio;
struct gpio_desc *pd_gpio;
struct videomode vm;
}; @@ -57,8 +56,8 @@ static int tfp410_enable(struct omap_dss_device *dssdev) if (r) return r;
- if (gpio_is_valid(ddata->pd_gpio))
gpio_set_value_cansleep(ddata->pd_gpio, 1);
if (ddata->pd_gpio)
gpiod_set_value_cansleep(ddata->pd_gpio, 0);
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
@@ -73,8 +72,8 @@ static void tfp410_disable(struct omap_dss_device *dssdev) if (!omapdss_device_is_enabled(dssdev)) return;
- if (gpio_is_valid(ddata->pd_gpio))
gpio_set_value_cansleep(ddata->pd_gpio, 0);
if (ddata->pd_gpio)
gpiod_set_value_cansleep(ddata->pd_gpio, 0);
src->ops->disable(src);
@@ -119,30 +118,11 @@ static const struct omap_dss_device_ops tfp410_ops = { .set_timings = tfp410_set_timings, };
-static int tfp410_probe_of(struct platform_device *pdev) -{
- struct panel_drv_data *ddata = platform_get_drvdata(pdev);
- struct device_node *node = pdev->dev.of_node;
- int gpio;
- gpio = of_get_named_gpio(node, "powerdown-gpios", 0);
- if (gpio_is_valid(gpio) || gpio == -ENOENT) {
ddata->pd_gpio = gpio;
- } else {
if (gpio != -EPROBE_DEFER)
dev_err(&pdev->dev, "failed to parse PD gpio\n");
return gpio;
- }
- return 0;
-}
static int tfp410_probe(struct platform_device *pdev) { struct panel_drv_data *ddata; struct omap_dss_device *dssdev;
- int r;
struct gpio_desc *gpio;
ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL); if (!ddata)
@@ -150,20 +130,15 @@ static int tfp410_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ddata);
- r = tfp410_probe_of(pdev);
- if (r)
return r;
- if (gpio_is_valid(ddata->pd_gpio)) {
r = devm_gpio_request_one(&pdev->dev, ddata->pd_gpio,
GPIOF_OUT_INIT_LOW, "tfp410 PD");
if (r) {
dev_err(&pdev->dev, "Failed to request PD GPIO %d\n",
ddata->pd_gpio);
return r;
}
/* Powerdown GPIO */
gpio = devm_gpiod_get_optional(&pdev->dev, "powerdown", GPIOD_OUT_HIGH);
if (IS_ERR(gpio)) {
dev_err(&pdev->dev, "failed to parse powerdown gpio\n");
return PTR_ERR(gpio);
}
ddata->pd_gpio = gpio;
dssdev = &ddata->dssdev; dssdev->ops = &tfp410_ops; dssdev->dev = &pdev->dev;
-- Regards,
Laurent Pinchart
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
The GPIO descriptor API is favoured over the plain GPIO API for consumer drivers. Using it simplifies the driver code.
The reset GPIO is mandatory, so drop conditional tests through the driver. The qvga GPIO is unused, so drop it completely.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com --- .../drm/omapdrm/displays/panel-nec-nl8048hl11.c | 54 +++++----------------- 1 file changed, 11 insertions(+), 43 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c index b4dba55b678b..767ffd2fa0f4 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c @@ -11,11 +11,10 @@ * (at your option) any later version. */
-#include <linux/module.h> #include <linux/delay.h> -#include <linux/spi/spi.h> #include <linux/gpio/consumer.h> -#include <linux/of_gpio.h> +#include <linux/module.h> +#include <linux/spi/spi.h>
#include "../dss/omapdss.h"
@@ -24,8 +23,7 @@ struct panel_drv_data {
struct videomode vm;
- int res_gpio; - int qvga_gpio; + struct gpio_desc *res_gpio;
struct spi_device *spi; }; @@ -140,8 +138,7 @@ static int nec_8048_enable(struct omap_dss_device *dssdev) if (r) return r;
- if (gpio_is_valid(ddata->res_gpio)) - gpio_set_value_cansleep(ddata->res_gpio, 1); + gpiod_set_value_cansleep(ddata->res_gpio, 1);
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
@@ -156,8 +153,7 @@ static void nec_8048_disable(struct omap_dss_device *dssdev) if (!omapdss_device_is_enabled(dssdev)) return;
- if (gpio_is_valid(ddata->res_gpio)) - gpio_set_value_cansleep(ddata->res_gpio, 0); + gpiod_set_value_cansleep(ddata->res_gpio, 0);
src->ops->disable(src);
@@ -203,29 +199,11 @@ static const struct omap_dss_driver nec_8048_ops = { .check_timings = nec_8048_check_timings, };
-static int nec_8048_probe_of(struct spi_device *spi) -{ - struct device_node *node = spi->dev.of_node; - struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev); - int gpio; - - gpio = of_get_named_gpio(node, "reset-gpios", 0); - if (!gpio_is_valid(gpio)) { - dev_err(&spi->dev, "failed to parse enable gpio\n"); - return gpio; - } - ddata->res_gpio = gpio; - - /* XXX the panel spec doesn't mention any QVGA pin?? */ - ddata->qvga_gpio = -ENOENT; - - return 0; -} - static int nec_8048_probe(struct spi_device *spi) { struct panel_drv_data *ddata; struct omap_dss_device *dssdev; + struct gpio_desc *gpio; int r;
dev_dbg(&spi->dev, "%s\n", __func__); @@ -249,23 +227,13 @@ static int nec_8048_probe(struct spi_device *spi)
ddata->spi = spi;
- r = nec_8048_probe_of(spi); - if (r) - return r; - - if (gpio_is_valid(ddata->qvga_gpio)) { - r = devm_gpio_request_one(&spi->dev, ddata->qvga_gpio, - GPIOF_OUT_INIT_HIGH, "lcd QVGA"); - if (r) - return r; + gpio = devm_gpiod_get(&spi->dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(gpio)) { + dev_err(&spi->dev, "failed to get reset gpio\n"); + return PTR_ERR(gpio); }
- if (gpio_is_valid(ddata->res_gpio)) { - r = devm_gpio_request_one(&spi->dev, ddata->res_gpio, - GPIOF_OUT_INIT_LOW, "lcd RES"); - if (r) - return r; - } + ddata->res_gpio = gpio;
ddata->vm = nec_8048_panel_vm;
Hi,
On Wed, Jun 06, 2018 at 12:36:36PM +0300, Laurent Pinchart wrote:
The GPIO descriptor API is favoured over the plain GPIO API for consumer drivers. Using it simplifies the driver code.
The reset GPIO is mandatory, so drop conditional tests through the driver. The qvga GPIO is unused, so drop it completely.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com
Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.co.uk
-- Sebastian
.../drm/omapdrm/displays/panel-nec-nl8048hl11.c | 54 +++++----------------- 1 file changed, 11 insertions(+), 43 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c index b4dba55b678b..767ffd2fa0f4 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c @@ -11,11 +11,10 @@
- (at your option) any later version.
*/
-#include <linux/module.h> #include <linux/delay.h> -#include <linux/spi/spi.h> #include <linux/gpio/consumer.h> -#include <linux/of_gpio.h> +#include <linux/module.h> +#include <linux/spi/spi.h>
#include "../dss/omapdss.h"
@@ -24,8 +23,7 @@ struct panel_drv_data {
struct videomode vm;
- int res_gpio;
- int qvga_gpio;
struct gpio_desc *res_gpio;
struct spi_device *spi;
}; @@ -140,8 +138,7 @@ static int nec_8048_enable(struct omap_dss_device *dssdev) if (r) return r;
- if (gpio_is_valid(ddata->res_gpio))
gpio_set_value_cansleep(ddata->res_gpio, 1);
gpiod_set_value_cansleep(ddata->res_gpio, 1);
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
@@ -156,8 +153,7 @@ static void nec_8048_disable(struct omap_dss_device *dssdev) if (!omapdss_device_is_enabled(dssdev)) return;
- if (gpio_is_valid(ddata->res_gpio))
gpio_set_value_cansleep(ddata->res_gpio, 0);
gpiod_set_value_cansleep(ddata->res_gpio, 0);
src->ops->disable(src);
@@ -203,29 +199,11 @@ static const struct omap_dss_driver nec_8048_ops = { .check_timings = nec_8048_check_timings, };
-static int nec_8048_probe_of(struct spi_device *spi) -{
- struct device_node *node = spi->dev.of_node;
- struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
- int gpio;
- gpio = of_get_named_gpio(node, "reset-gpios", 0);
- if (!gpio_is_valid(gpio)) {
dev_err(&spi->dev, "failed to parse enable gpio\n");
return gpio;
- }
- ddata->res_gpio = gpio;
- /* XXX the panel spec doesn't mention any QVGA pin?? */
- ddata->qvga_gpio = -ENOENT;
- return 0;
-}
static int nec_8048_probe(struct spi_device *spi) { struct panel_drv_data *ddata; struct omap_dss_device *dssdev;
struct gpio_desc *gpio; int r;
dev_dbg(&spi->dev, "%s\n", __func__);
@@ -249,23 +227,13 @@ static int nec_8048_probe(struct spi_device *spi)
ddata->spi = spi;
- r = nec_8048_probe_of(spi);
- if (r)
return r;
- if (gpio_is_valid(ddata->qvga_gpio)) {
r = devm_gpio_request_one(&spi->dev, ddata->qvga_gpio,
GPIOF_OUT_INIT_HIGH, "lcd QVGA");
if (r)
return r;
- gpio = devm_gpiod_get(&spi->dev, "reset", GPIOD_OUT_LOW);
- if (IS_ERR(gpio)) {
dev_err(&spi->dev, "failed to get reset gpio\n");
}return PTR_ERR(gpio);
- if (gpio_is_valid(ddata->res_gpio)) {
r = devm_gpio_request_one(&spi->dev, ddata->res_gpio,
GPIOF_OUT_INIT_LOW, "lcd RES");
if (r)
return r;
- }
ddata->res_gpio = gpio;
ddata->vm = nec_8048_panel_vm;
-- Regards,
Laurent Pinchart
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
The GPIO descriptor API is favoured over the plain GPIO API for consumer drivers. Using it simplifies the driver code.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com --- .../drm/omapdrm/displays/panel-sony-acx565akm.c | 56 ++++++++-------------- 1 file changed, 21 insertions(+), 35 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c index c501a06207af..f5f3e5e5f3dc 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c @@ -20,17 +20,15 @@ * this program. If not, see http://www.gnu.org/licenses/. */
+#include <linux/backlight.h> +#include <linux/delay.h> +#include <linux/gpio/consumer.h> +#include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/platform_device.h> -#include <linux/delay.h> -#include <linux/spi/spi.h> -#include <linux/jiffies.h> #include <linux/sched.h> -#include <linux/backlight.h> -#include <linux/gpio/consumer.h> -#include <linux/of.h> -#include <linux/of_gpio.h> +#include <linux/spi/spi.h>
#include "../dss/omapdss.h"
@@ -65,7 +63,7 @@ struct panel_drv_data { struct omap_dss_device dssdev;
- int reset_gpio; + struct gpio_desc *reset_gpio;
struct videomode vm;
@@ -536,8 +534,8 @@ static int acx565akm_panel_power_on(struct omap_dss_device *dssdev) /*FIXME tweak me */ msleep(50);
- if (gpio_is_valid(ddata->reset_gpio)) - gpio_set_value(ddata->reset_gpio, 1); + if (ddata->reset_gpio) + gpiod_set_value(ddata->reset_gpio, 1);
if (ddata->enabled) { dev_dbg(&ddata->spi->dev, "panel already enabled\n"); @@ -586,8 +584,8 @@ static void acx565akm_panel_power_off(struct omap_dss_device *dssdev) */ msleep(50);
- if (gpio_is_valid(ddata->reset_gpio)) - gpio_set_value(ddata->reset_gpio, 0); + if (ddata->reset_gpio) + gpiod_set_value(ddata->reset_gpio, 0);
/* FIXME need to tweak this delay */ msleep(100); @@ -674,16 +672,6 @@ static const struct omap_dss_driver acx565akm_ops = { .check_timings = acx565akm_check_timings, };
-static int acx565akm_probe_of(struct spi_device *spi) -{ - struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev); - struct device_node *np = spi->dev.of_node; - - ddata->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0); - - return 0; -} - static int acx565akm_probe(struct spi_device *spi) { struct panel_drv_data *ddata; @@ -691,6 +679,7 @@ static int acx565akm_probe(struct spi_device *spi) struct backlight_device *bldev; int max_brightness, brightness; struct backlight_properties props; + struct gpio_desc *gpio; int r;
dev_dbg(&spi->dev, "%s\n", __func__); @@ -707,19 +696,16 @@ static int acx565akm_probe(struct spi_device *spi)
mutex_init(&ddata->mutex);
- r = acx565akm_probe_of(spi); - if (r) - return r; - - if (gpio_is_valid(ddata->reset_gpio)) { - r = devm_gpio_request_one(&spi->dev, ddata->reset_gpio, - GPIOF_OUT_INIT_LOW, "lcd reset"); - if (r) - return r; + gpio = devm_gpiod_get_optional(&spi->dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(gpio)) { + dev_err(&spi->dev, "failed to parse reset gpio\n"); + return PTR_ERR(gpio); }
- if (gpio_is_valid(ddata->reset_gpio)) - gpio_set_value(ddata->reset_gpio, 1); + ddata->reset_gpio = gpio; + + if (ddata->reset_gpio) + gpiod_set_value(ddata->reset_gpio, 1);
/* * After reset we have to wait 5 msec before the first @@ -731,8 +717,8 @@ static int acx565akm_probe(struct spi_device *spi)
r = panel_detect(ddata);
- if (!ddata->enabled && gpio_is_valid(ddata->reset_gpio)) - gpio_set_value(ddata->reset_gpio, 0); + if (!ddata->enabled && ddata->reset_gpio) + gpiod_set_value(ddata->reset_gpio, 0);
if (r) { dev_err(&spi->dev, "%s panel detect error\n", __func__);
Hi,
On Wed, Jun 06, 2018 at 12:36:37PM +0300, Laurent Pinchart wrote:
The GPIO descriptor API is favoured over the plain GPIO API for consumer drivers. Using it simplifies the driver code.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com
Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.co.uk
-- Sebastian
.../drm/omapdrm/displays/panel-sony-acx565akm.c | 56 ++++++++-------------- 1 file changed, 21 insertions(+), 35 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c index c501a06207af..f5f3e5e5f3dc 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c @@ -20,17 +20,15 @@
- this program. If not, see http://www.gnu.org/licenses/.
*/
+#include <linux/backlight.h> +#include <linux/delay.h> +#include <linux/gpio/consumer.h> +#include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/platform_device.h> -#include <linux/delay.h> -#include <linux/spi/spi.h> -#include <linux/jiffies.h> #include <linux/sched.h> -#include <linux/backlight.h> -#include <linux/gpio/consumer.h> -#include <linux/of.h> -#include <linux/of_gpio.h> +#include <linux/spi/spi.h>
#include "../dss/omapdss.h"
@@ -65,7 +63,7 @@ struct panel_drv_data { struct omap_dss_device dssdev;
- int reset_gpio;
struct gpio_desc *reset_gpio;
struct videomode vm;
@@ -536,8 +534,8 @@ static int acx565akm_panel_power_on(struct omap_dss_device *dssdev) /*FIXME tweak me */ msleep(50);
- if (gpio_is_valid(ddata->reset_gpio))
gpio_set_value(ddata->reset_gpio, 1);
if (ddata->reset_gpio)
gpiod_set_value(ddata->reset_gpio, 1);
if (ddata->enabled) { dev_dbg(&ddata->spi->dev, "panel already enabled\n");
@@ -586,8 +584,8 @@ static void acx565akm_panel_power_off(struct omap_dss_device *dssdev) */ msleep(50);
- if (gpio_is_valid(ddata->reset_gpio))
gpio_set_value(ddata->reset_gpio, 0);
if (ddata->reset_gpio)
gpiod_set_value(ddata->reset_gpio, 0);
/* FIXME need to tweak this delay */ msleep(100);
@@ -674,16 +672,6 @@ static const struct omap_dss_driver acx565akm_ops = { .check_timings = acx565akm_check_timings, };
-static int acx565akm_probe_of(struct spi_device *spi) -{
- struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
- struct device_node *np = spi->dev.of_node;
- ddata->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0);
- return 0;
-}
static int acx565akm_probe(struct spi_device *spi) { struct panel_drv_data *ddata; @@ -691,6 +679,7 @@ static int acx565akm_probe(struct spi_device *spi) struct backlight_device *bldev; int max_brightness, brightness; struct backlight_properties props;
struct gpio_desc *gpio; int r;
dev_dbg(&spi->dev, "%s\n", __func__);
@@ -707,19 +696,16 @@ static int acx565akm_probe(struct spi_device *spi)
mutex_init(&ddata->mutex);
- r = acx565akm_probe_of(spi);
- if (r)
return r;
- if (gpio_is_valid(ddata->reset_gpio)) {
r = devm_gpio_request_one(&spi->dev, ddata->reset_gpio,
GPIOF_OUT_INIT_LOW, "lcd reset");
if (r)
return r;
- gpio = devm_gpiod_get_optional(&spi->dev, "reset", GPIOD_OUT_LOW);
- if (IS_ERR(gpio)) {
dev_err(&spi->dev, "failed to parse reset gpio\n");
}return PTR_ERR(gpio);
- if (gpio_is_valid(ddata->reset_gpio))
gpio_set_value(ddata->reset_gpio, 1);
ddata->reset_gpio = gpio;
if (ddata->reset_gpio)
gpiod_set_value(ddata->reset_gpio, 1);
/*
- After reset we have to wait 5 msec before the first
@@ -731,8 +717,8 @@ static int acx565akm_probe(struct spi_device *spi)
r = panel_detect(ddata);
- if (!ddata->enabled && gpio_is_valid(ddata->reset_gpio))
gpio_set_value(ddata->reset_gpio, 0);
if (!ddata->enabled && ddata->reset_gpio)
gpiod_set_value(ddata->reset_gpio, 0);
if (r) { dev_err(&spi->dev, "%s panel detect error\n", __func__);
-- Regards,
Laurent Pinchart
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
The driver doesn't use GPIOs and thus doesn't need to include the linux/gpio.h header.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c index 758e77b77920..d3b0d204b7c9 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c @@ -27,7 +27,6 @@ #include <linux/module.h> #include <linux/delay.h> #include <linux/spi/spi.h> -#include <linux/gpio.h>
#include "../dss/omapdss.h"
Hi,
On Wed, Jun 06, 2018 at 12:36:38PM +0300, Laurent Pinchart wrote:
The driver doesn't use GPIOs and thus doesn't need to include the linux/gpio.h header.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com
Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.co.uk
-- Sebastian
drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c index 758e77b77920..d3b0d204b7c9 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c @@ -27,7 +27,6 @@ #include <linux/module.h> #include <linux/delay.h> #include <linux/spi/spi.h> -#include <linux/gpio.h>
#include "../dss/omapdss.h"
-- Regards,
Laurent Pinchart
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
The GPIO descriptor API is favoured over the plain GPIO API for consumer drivers. Using it simplifies the driver code.
As the descriptor API handles the active-low flag internally we need to invert the polarity of all GPIO operations in the driver. Rename the nreset_gpio field to reset_gpio to reflect that.
The reset GPIO is mandatory, so drop conditional tests through the driver.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com --- .../drm/omapdrm/displays/panel-tpo-td043mtea1.c | 52 ++++++---------------- 1 file changed, 14 insertions(+), 38 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c index 34531169c166..1521812ab15b 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c @@ -10,14 +10,13 @@ * (at your option) any later version. */
-#include <linux/module.h> #include <linux/delay.h> -#include <linux/spi/spi.h> -#include <linux/regulator/consumer.h> -#include <linux/gpio/consumer.h> #include <linux/err.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/regulator/consumer.h> #include <linux/slab.h> -#include <linux/of_gpio.h> +#include <linux/spi/spi.h>
#include "../dss/omapdss.h"
@@ -59,7 +58,7 @@ struct panel_drv_data {
struct spi_device *spi; struct regulator *vcc_reg; - int nreset_gpio; + struct gpio_desc *reset_gpio; u16 gamma[12]; u32 mode; u32 vmirror:1; @@ -282,8 +281,7 @@ static int tpo_td043_power_on(struct panel_drv_data *ddata) /* wait for panel to stabilize */ msleep(160);
- if (gpio_is_valid(ddata->nreset_gpio)) - gpio_set_value(ddata->nreset_gpio, 1); + gpiod_set_value(ddata->reset_gpio, 0);
tpo_td043_write(ddata->spi, 2, TPO_R02_MODE(ddata->mode) | TPO_R02_NCLK_RISING); @@ -305,8 +303,7 @@ static void tpo_td043_power_off(struct panel_drv_data *ddata) tpo_td043_write(ddata->spi, 3, TPO_R03_VAL_STANDBY | TPO_R03_EN_PWM);
- if (gpio_is_valid(ddata->nreset_gpio)) - gpio_set_value(ddata->nreset_gpio, 0); + gpiod_set_value(ddata->reset_gpio, 1);
/* wait for at least 2 vsyncs before cutting off power */ msleep(50); @@ -419,26 +416,11 @@ static const struct omap_dss_driver tpo_td043_ops = { .check_timings = tpo_td043_check_timings, };
-static int tpo_td043_probe_of(struct spi_device *spi) -{ - struct device_node *node = spi->dev.of_node; - struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev); - int gpio; - - gpio = of_get_named_gpio(node, "reset-gpios", 0); - if (!gpio_is_valid(gpio)) { - dev_err(&spi->dev, "failed to parse enable gpio\n"); - return gpio; - } - ddata->nreset_gpio = gpio; - - return 0; -} - static int tpo_td043_probe(struct spi_device *spi) { struct panel_drv_data *ddata; struct omap_dss_device *dssdev; + struct gpio_desc *gpio; int r;
dev_dbg(&spi->dev, "%s\n", __func__); @@ -460,10 +442,6 @@ static int tpo_td043_probe(struct spi_device *spi)
ddata->spi = spi;
- r = tpo_td043_probe_of(spi); - if (r) - return r; - ddata->mode = TPO_R02_MODE_800x480; memcpy(ddata->gamma, tpo_td043_def_gamma, sizeof(ddata->gamma));
@@ -473,16 +451,14 @@ static int tpo_td043_probe(struct spi_device *spi) return PTR_ERR(ddata->vcc_reg); }
- if (gpio_is_valid(ddata->nreset_gpio)) { - r = devm_gpio_request_one(&spi->dev, - ddata->nreset_gpio, GPIOF_OUT_INIT_LOW, - "lcd reset"); - if (r < 0) { - dev_err(&spi->dev, "couldn't request reset GPIO\n"); - return r; - } + gpio = devm_gpiod_get(&spi->dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(gpio)) { + dev_err(&spi->dev, "failed to get reset gpio\n"); + return PTR_ERR(gpio); }
+ ddata->reset_gpio = gpio; + r = sysfs_create_group(&spi->dev.kobj, &tpo_td043_attr_group); if (r) { dev_err(&spi->dev, "failed to create sysfs files\n");
Hi,
On Wed, Jun 06, 2018 at 12:36:39PM +0300, Laurent Pinchart wrote:
The GPIO descriptor API is favoured over the plain GPIO API for consumer drivers. Using it simplifies the driver code.
As the descriptor API handles the active-low flag internally we need to invert the polarity of all GPIO operations in the driver. Rename the nreset_gpio field to reset_gpio to reflect that.
The reset GPIO is mandatory, so drop conditional tests through the driver.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com
Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.co.uk
-- Sebastian
.../drm/omapdrm/displays/panel-tpo-td043mtea1.c | 52 ++++++---------------- 1 file changed, 14 insertions(+), 38 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c index 34531169c166..1521812ab15b 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c @@ -10,14 +10,13 @@
- (at your option) any later version.
*/
-#include <linux/module.h> #include <linux/delay.h> -#include <linux/spi/spi.h> -#include <linux/regulator/consumer.h> -#include <linux/gpio/consumer.h> #include <linux/err.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/regulator/consumer.h> #include <linux/slab.h> -#include <linux/of_gpio.h> +#include <linux/spi/spi.h>
#include "../dss/omapdss.h"
@@ -59,7 +58,7 @@ struct panel_drv_data {
struct spi_device *spi; struct regulator *vcc_reg;
- int nreset_gpio;
- struct gpio_desc *reset_gpio; u16 gamma[12]; u32 mode; u32 vmirror:1;
@@ -282,8 +281,7 @@ static int tpo_td043_power_on(struct panel_drv_data *ddata) /* wait for panel to stabilize */ msleep(160);
- if (gpio_is_valid(ddata->nreset_gpio))
gpio_set_value(ddata->nreset_gpio, 1);
gpiod_set_value(ddata->reset_gpio, 0);
tpo_td043_write(ddata->spi, 2, TPO_R02_MODE(ddata->mode) | TPO_R02_NCLK_RISING);
@@ -305,8 +303,7 @@ static void tpo_td043_power_off(struct panel_drv_data *ddata) tpo_td043_write(ddata->spi, 3, TPO_R03_VAL_STANDBY | TPO_R03_EN_PWM);
- if (gpio_is_valid(ddata->nreset_gpio))
gpio_set_value(ddata->nreset_gpio, 0);
gpiod_set_value(ddata->reset_gpio, 1);
/* wait for at least 2 vsyncs before cutting off power */ msleep(50);
@@ -419,26 +416,11 @@ static const struct omap_dss_driver tpo_td043_ops = { .check_timings = tpo_td043_check_timings, };
-static int tpo_td043_probe_of(struct spi_device *spi) -{
- struct device_node *node = spi->dev.of_node;
- struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
- int gpio;
- gpio = of_get_named_gpio(node, "reset-gpios", 0);
- if (!gpio_is_valid(gpio)) {
dev_err(&spi->dev, "failed to parse enable gpio\n");
return gpio;
- }
- ddata->nreset_gpio = gpio;
- return 0;
-}
static int tpo_td043_probe(struct spi_device *spi) { struct panel_drv_data *ddata; struct omap_dss_device *dssdev;
struct gpio_desc *gpio; int r;
dev_dbg(&spi->dev, "%s\n", __func__);
@@ -460,10 +442,6 @@ static int tpo_td043_probe(struct spi_device *spi)
ddata->spi = spi;
- r = tpo_td043_probe_of(spi);
- if (r)
return r;
- ddata->mode = TPO_R02_MODE_800x480; memcpy(ddata->gamma, tpo_td043_def_gamma, sizeof(ddata->gamma));
@@ -473,16 +451,14 @@ static int tpo_td043_probe(struct spi_device *spi) return PTR_ERR(ddata->vcc_reg); }
- if (gpio_is_valid(ddata->nreset_gpio)) {
r = devm_gpio_request_one(&spi->dev,
ddata->nreset_gpio, GPIOF_OUT_INIT_LOW,
"lcd reset");
if (r < 0) {
dev_err(&spi->dev, "couldn't request reset GPIO\n");
return r;
}
gpio = devm_gpiod_get(&spi->dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(gpio)) {
dev_err(&spi->dev, "failed to get reset gpio\n");
return PTR_ERR(gpio);
}
ddata->reset_gpio = gpio;
r = sysfs_create_group(&spi->dev.kobj, &tpo_td043_attr_group); if (r) { dev_err(&spi->dev, "failed to create sysfs files\n");
-- Regards,
Laurent Pinchart
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
omap_dss_device instances have two ops structures, omap_dss_driver and omap_dss_device_ops. The former is used for devices at the end of the pipeline (a.k.a. display devices), and the latter for intermediate devices.
Having two sets of operations isn't convenient as code that iterates over omap_dss_device instances need to take them both into account. There's currently a reasonably small amount of such code, but more will be introduced to move the driver away from recursive operations. To simplify current and future code, move all operations that are not specific to the display device to the omap_dss_device_ops.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com --- .../gpu/drm/omapdrm/displays/connector-analog-tv.c | 4 +- drivers/gpu/drm/omapdrm/displays/connector-dvi.c | 4 +- drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 31 +++++++------ .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 14 +++--- drivers/gpu/drm/omapdrm/displays/panel-dpi.c | 4 +- drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c | 12 +++-- .../omapdrm/displays/panel-lgphilips-lb035q02.c | 4 +- .../drm/omapdrm/displays/panel-nec-nl8048hl11.c | 4 +- .../drm/omapdrm/displays/panel-sharp-ls037v7dw01.c | 4 +- .../drm/omapdrm/displays/panel-sony-acx565akm.c | 4 +- .../drm/omapdrm/displays/panel-tpo-td028ttec1.c | 4 +- .../drm/omapdrm/displays/panel-tpo-td043mtea1.c | 4 +- drivers/gpu/drm/omapdrm/dss/base.c | 12 +---- drivers/gpu/drm/omapdrm/dss/dss.c | 2 +- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 3 +- drivers/gpu/drm/omapdrm/dss/hdmi5.c | 3 +- drivers/gpu/drm/omapdrm/dss/omapdss.h | 54 ++++++---------------- drivers/gpu/drm/omapdrm/omap_connector.c | 37 +++++++-------- drivers/gpu/drm/omapdrm/omap_crtc.c | 2 +- drivers/gpu/drm/omapdrm/omap_drv.c | 12 ++--- drivers/gpu/drm/omapdrm/omap_encoder.c | 25 +++++----- 21 files changed, 106 insertions(+), 137 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c index d59b4f2e22dc..563fc7e618b3 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c @@ -119,7 +119,7 @@ static int tvc_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); }
-static const struct omap_dss_driver tvc_driver = { +static const struct omap_dss_device_ops tvc_ops = { .connect = tvc_connect, .disconnect = tvc_disconnect,
@@ -146,7 +146,7 @@ static int tvc_probe(struct platform_device *pdev) ddata->vm = tvc_pal_vm;
dssdev = &ddata->dssdev; - dssdev->driver = &tvc_driver; + dssdev->ops = &tvc_ops; dssdev->dev = &pdev->dev; dssdev->type = OMAP_DISPLAY_TYPE_VENC; dssdev->owner = THIS_MODULE; diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c index 39e7d0be887f..a639a86cd47b 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c @@ -265,7 +265,7 @@ static void dvic_disable_hpd(struct omap_dss_device *dssdev) mutex_unlock(&ddata->hpd_lock); }
-static const struct omap_dss_driver dvic_driver = { +static const struct omap_dss_device_ops dvic_ops = { .connect = dvic_connect, .disconnect = dvic_disconnect,
@@ -367,7 +367,7 @@ static int dvic_probe(struct platform_device *pdev) ddata->vm = dvic_default_vm;
dssdev = &ddata->dssdev; - dssdev->driver = &dvic_driver; + dssdev->ops = &dvic_ops; dssdev->dev = &pdev->dev; dssdev->type = OMAP_DISPLAY_TYPE_DVI; dssdev->owner = THIS_MODULE; diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index d39480b8cf6b..54bfd7156360 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c @@ -132,7 +132,7 @@ static int hdmic_read_edid(struct omap_dss_device *dssdev, { struct omap_dss_device *src = dssdev->src;
- return src->ops->hdmi.read_edid(src, edid, len); + return src->ops->read_edid(src, edid, len); }
static bool hdmic_detect(struct omap_dss_device *dssdev) @@ -144,7 +144,7 @@ static bool hdmic_detect(struct omap_dss_device *dssdev) if (ddata->hpd_gpio) connected = gpiod_get_value_cansleep(ddata->hpd_gpio); else - connected = src->ops->hdmi.detect(src); + connected = src->ops->detect(src); if (!connected && src->ops->hdmi.lost_hotplug) src->ops->hdmi.lost_hotplug(src); return connected; @@ -164,8 +164,8 @@ static int hdmic_register_hpd_cb(struct omap_dss_device *dssdev, ddata->hpd_cb_data = cb_data; mutex_unlock(&ddata->hpd_lock); return 0; - } else if (src->ops->hdmi.register_hpd_cb) { - return src->ops->hdmi.register_hpd_cb(src, cb, cb_data); + } else if (src->ops->register_hpd_cb) { + return src->ops->register_hpd_cb(src, cb, cb_data); }
return -ENOTSUPP; @@ -181,8 +181,8 @@ static void hdmic_unregister_hpd_cb(struct omap_dss_device *dssdev) ddata->hpd_cb = NULL; ddata->hpd_cb_data = NULL; mutex_unlock(&ddata->hpd_lock); - } else if (src->ops->hdmi.unregister_hpd_cb) { - src->ops->hdmi.unregister_hpd_cb(src); + } else if (src->ops->unregister_hpd_cb) { + src->ops->unregister_hpd_cb(src); } }
@@ -195,8 +195,8 @@ static void hdmic_enable_hpd(struct omap_dss_device *dssdev) mutex_lock(&ddata->hpd_lock); ddata->hpd_enabled = true; mutex_unlock(&ddata->hpd_lock); - } else if (src->ops->hdmi.enable_hpd) { - src->ops->hdmi.enable_hpd(src); + } else if (src->ops->enable_hpd) { + src->ops->enable_hpd(src); } }
@@ -209,8 +209,8 @@ static void hdmic_disable_hpd(struct omap_dss_device *dssdev) mutex_lock(&ddata->hpd_lock); ddata->hpd_enabled = false; mutex_unlock(&ddata->hpd_lock); - } else if (src->ops->hdmi.disable_hpd) { - src->ops->hdmi.disable_hpd(src); + } else if (src->ops->disable_hpd) { + src->ops->disable_hpd(src); } }
@@ -229,7 +229,7 @@ static int hdmic_set_infoframe(struct omap_dss_device *dssdev, return src->ops->hdmi.set_infoframe(src, avi); }
-static const struct omap_dss_driver hdmic_driver = { +static const struct omap_dss_device_ops hdmic_ops = { .connect = hdmic_connect, .disconnect = hdmic_disconnect,
@@ -246,8 +246,11 @@ static const struct omap_dss_driver hdmic_driver = { .unregister_hpd_cb = hdmic_unregister_hpd_cb, .enable_hpd = hdmic_enable_hpd, .disable_hpd = hdmic_disable_hpd, - .set_hdmi_mode = hdmic_set_hdmi_mode, - .set_hdmi_infoframe = hdmic_set_infoframe, + + .hdmi = { + .set_hdmi_mode = hdmic_set_hdmi_mode, + .set_infoframe = hdmic_set_infoframe, + }, };
static irqreturn_t hdmic_hpd_isr(int irq, void *data) @@ -309,7 +312,7 @@ static int hdmic_probe(struct platform_device *pdev) ddata->vm = hdmic_default_vm;
dssdev = &ddata->dssdev; - dssdev->driver = &hdmic_driver; + dssdev->ops = &hdmic_ops; dssdev->dev = &pdev->dev; dssdev->type = OMAP_DISPLAY_TYPE_HDMI; dssdev->owner = THIS_MODULE; diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c index 3bd6aeb7b3f4..545a06e6ca11 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c @@ -125,7 +125,7 @@ static int tpd_read_edid(struct omap_dss_device *dssdev, if (!gpiod_get_value_cansleep(ddata->hpd_gpio)) return -ENODEV;
- return src->ops->hdmi.read_edid(src, edid, len); + return src->ops->read_edid(src, edid, len); }
static bool tpd_detect(struct omap_dss_device *dssdev) @@ -205,14 +205,14 @@ static const struct omap_dss_device_ops tpd_ops = { .disable = tpd_disable, .check_timings = tpd_check_timings, .set_timings = tpd_set_timings, + .read_edid = tpd_read_edid, + .detect = tpd_detect, + .register_hpd_cb = tpd_register_hpd_cb, + .unregister_hpd_cb = tpd_unregister_hpd_cb, + .enable_hpd = tpd_enable_hpd, + .disable_hpd = tpd_disable_hpd,
.hdmi = { - .read_edid = tpd_read_edid, - .detect = tpd_detect, - .register_hpd_cb = tpd_register_hpd_cb, - .unregister_hpd_cb = tpd_unregister_hpd_cb, - .enable_hpd = tpd_enable_hpd, - .disable_hpd = tpd_disable_hpd, .set_infoframe = tpd_set_infoframe, .set_hdmi_mode = tpd_set_hdmi_mode, }, diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c index 91f99c95c4c4..c03877af9cdb 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c @@ -122,7 +122,7 @@ static int panel_dpi_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); }
-static const struct omap_dss_driver panel_dpi_ops = { +static const struct omap_dss_device_ops panel_dpi_ops = { .connect = panel_dpi_connect, .disconnect = panel_dpi_disconnect,
@@ -196,7 +196,7 @@ static int panel_dpi_probe(struct platform_device *pdev)
dssdev = &ddata->dssdev; dssdev->dev = &pdev->dev; - dssdev->driver = &panel_dpi_ops; + dssdev->ops = &panel_dpi_ops; dssdev->type = OMAP_DISPLAY_TYPE_DPI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0); diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c index be4f03aa7af3..e8a81c4fd066 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c @@ -1179,18 +1179,21 @@ static void dsicm_get_size(struct omap_dss_device *dssdev, *height = ddata->height_mm; }
-static const struct omap_dss_driver dsicm_ops = { +static const struct omap_dss_device_ops dsicm_ops = { .connect = dsicm_connect, .disconnect = dsicm_disconnect,
.enable = dsicm_enable, .disable = dsicm_disable,
+ .get_timings = dsicm_get_timings, + .check_timings = dsicm_check_timings, +}; + +static const struct omap_dss_driver dsicm_dss_driver = { .update = dsicm_update, .sync = dsicm_sync,
- .get_timings = dsicm_get_timings, - .check_timings = dsicm_check_timings, .get_size = dsicm_get_size,
.enable_te = dsicm_enable_te, @@ -1299,7 +1302,8 @@ static int dsicm_probe(struct platform_device *pdev)
dssdev = &ddata->dssdev; dssdev->dev = dev; - dssdev->driver = &dsicm_ops; + dssdev->ops = &dsicm_ops; + dssdev->driver = &dsicm_dss_driver; dssdev->type = OMAP_DISPLAY_TYPE_DSI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0); diff --git a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c index 66763a12fc3d..62576e4f89e3 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c @@ -199,7 +199,7 @@ static int lb035q02_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); }
-static const struct omap_dss_driver lb035q02_ops = { +static const struct omap_dss_device_ops lb035q02_ops = { .connect = lb035q02_connect, .disconnect = lb035q02_disconnect,
@@ -249,7 +249,7 @@ static int lb035q02_panel_spi_probe(struct spi_device *spi)
dssdev = &ddata->dssdev; dssdev->dev = &spi->dev; - dssdev->driver = &lb035q02_ops; + dssdev->ops = &lb035q02_ops; dssdev->type = OMAP_DISPLAY_TYPE_DPI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0); diff --git a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c index 767ffd2fa0f4..9f34cf02a114 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c @@ -187,7 +187,7 @@ static int nec_8048_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); }
-static const struct omap_dss_driver nec_8048_ops = { +static const struct omap_dss_device_ops nec_8048_ops = { .connect = nec_8048_connect, .disconnect = nec_8048_disconnect,
@@ -239,7 +239,7 @@ static int nec_8048_probe(struct spi_device *spi)
dssdev = &ddata->dssdev; dssdev->dev = &spi->dev; - dssdev->driver = &nec_8048_ops; + dssdev->ops = &nec_8048_ops; dssdev->type = OMAP_DISPLAY_TYPE_DPI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0); diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c index 7fbdf3ec0113..9ee6b8376916 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c @@ -161,7 +161,7 @@ static int sharp_ls_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); }
-static const struct omap_dss_driver sharp_ls_ops = { +static const struct omap_dss_device_ops sharp_ls_ops = { .connect = sharp_ls_connect, .disconnect = sharp_ls_disconnect,
@@ -247,7 +247,7 @@ static int sharp_ls_probe(struct platform_device *pdev)
dssdev = &ddata->dssdev; dssdev->dev = &pdev->dev; - dssdev->driver = &sharp_ls_ops; + dssdev->ops = &sharp_ls_ops; dssdev->type = OMAP_DISPLAY_TYPE_DPI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0); diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c index f5f3e5e5f3dc..8baa290f841b 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c @@ -660,7 +660,7 @@ static int acx565akm_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); }
-static const struct omap_dss_driver acx565akm_ops = { +static const struct omap_dss_device_ops acx565akm_ops = { .connect = acx565akm_connect, .disconnect = acx565akm_disconnect,
@@ -762,7 +762,7 @@ static int acx565akm_probe(struct spi_device *spi)
dssdev = &ddata->dssdev; dssdev->dev = &spi->dev; - dssdev->driver = &acx565akm_ops; + dssdev->ops = &acx565akm_ops; dssdev->type = OMAP_DISPLAY_TYPE_SDI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0); diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c index d3b0d204b7c9..4dfe200e8f70 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c @@ -330,7 +330,7 @@ static int td028ttec1_panel_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); }
-static const struct omap_dss_driver td028ttec1_ops = { +static const struct omap_dss_device_ops td028ttec1_ops = { .connect = td028ttec1_panel_connect, .disconnect = td028ttec1_panel_disconnect,
@@ -371,7 +371,7 @@ static int td028ttec1_panel_probe(struct spi_device *spi)
dssdev = &ddata->dssdev; dssdev->dev = &spi->dev; - dssdev->driver = &td028ttec1_ops; + dssdev->ops = &td028ttec1_ops; dssdev->type = OMAP_DISPLAY_TYPE_DPI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0); diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c index 1521812ab15b..b211a7809a26 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c @@ -404,7 +404,7 @@ static int tpo_td043_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); }
-static const struct omap_dss_driver tpo_td043_ops = { +static const struct omap_dss_device_ops tpo_td043_ops = { .connect = tpo_td043_connect, .disconnect = tpo_td043_disconnect,
@@ -469,7 +469,7 @@ static int tpo_td043_probe(struct spi_device *spi)
dssdev = &ddata->dssdev; dssdev->dev = &spi->dev; - dssdev->driver = &tpo_td043_ops; + dssdev->ops = &tpo_td043_ops; dssdev->type = OMAP_DISPLAY_TYPE_DPI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0); diff --git a/drivers/gpu/drm/omapdrm/dss/base.c b/drivers/gpu/drm/omapdrm/dss/base.c index 6a73d3559257..dcef0128818d 100644 --- a/drivers/gpu/drm/omapdrm/dss/base.c +++ b/drivers/gpu/drm/omapdrm/dss/base.c @@ -198,11 +198,7 @@ int omapdss_device_connect(struct dss_device *dss,
dst->dss = dss;
- if (dst->driver) - ret = dst->driver->connect(src, dst); - else - ret = dst->ops->connect(src, dst); - + ret = dst->ops->connect(src, dst); if (ret < 0) { dst->dss = NULL; return ret; @@ -238,11 +234,7 @@ void omapdss_device_disconnect(struct omap_dss_device *src,
WARN_ON(dst->state != OMAP_DSS_DISPLAY_DISABLED);
- if (dst->driver) - dst->driver->disconnect(src, dst); - else - dst->ops->disconnect(src, dst); - + dst->ops->disconnect(src, dst); dst->dss = NULL; } EXPORT_SYMBOL_GPL(omapdss_device_disconnect); diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index 6118159dd571..8d757e87bdda 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -1553,7 +1553,7 @@ static void dss_shutdown(struct platform_device *pdev)
for_each_dss_display(dssdev) { if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) - dssdev->driver->disable(dssdev); + dssdev->ops->disable(dssdev); } }
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index c4fcdc9ed62d..bebce93fed3e 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -511,8 +511,9 @@ static const struct omap_dss_device_ops hdmi_ops = { .check_timings = hdmi_display_check_timing, .set_timings = hdmi_display_set_timing,
+ .read_edid = hdmi_read_edid, + .hdmi = { - .read_edid = hdmi_read_edid, .lost_hotplug = hdmi_lost_hotplug, .set_infoframe = hdmi_set_infoframe, .set_hdmi_mode = hdmi_set_hdmi_mode, diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c index 889c31745492..7c07e0208107 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c @@ -505,8 +505,9 @@ static const struct omap_dss_device_ops hdmi_ops = { .check_timings = hdmi_display_check_timing, .set_timings = hdmi_display_set_timing,
+ .read_edid = hdmi_read_edid, + .hdmi = { - .read_edid = hdmi_read_edid, .set_infoframe = hdmi_set_infoframe, .set_hdmi_mode = hdmi_set_hdmi_mode, }, diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index ae30802f2151..3a5ee897baf0 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -297,18 +297,7 @@ struct omap_dss_writeback_info { };
struct omapdss_hdmi_ops { - int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len); void (*lost_hotplug)(struct omap_dss_device *dssdev); - bool (*detect)(struct omap_dss_device *dssdev); - - int (*register_hpd_cb)(struct omap_dss_device *dssdev, - void (*cb)(void *cb_data, - enum drm_connector_status status), - void *cb_data); - void (*unregister_hpd_cb)(struct omap_dss_device *dssdev); - void (*enable_hpd)(struct omap_dss_device *dssdev); - void (*disable_hpd)(struct omap_dss_device *dssdev); - int (*set_hdmi_mode)(struct omap_dss_device *dssdev, bool hdmi_mode); int (*set_infoframe)(struct omap_dss_device *dssdev, const struct hdmi_avi_infoframe *avi); @@ -376,9 +365,23 @@ struct omap_dss_device_ops {
int (*check_timings)(struct omap_dss_device *dssdev, struct videomode *vm); + void (*get_timings)(struct omap_dss_device *dssdev, + struct videomode *vm); void (*set_timings)(struct omap_dss_device *dssdev, struct videomode *vm);
+ bool (*detect)(struct omap_dss_device *dssdev); + + int (*register_hpd_cb)(struct omap_dss_device *dssdev, + void (*cb)(void *cb_data, + enum drm_connector_status status), + void *cb_data); + void (*unregister_hpd_cb)(struct omap_dss_device *dssdev); + void (*enable_hpd)(struct omap_dss_device *dssdev); + void (*disable_hpd)(struct omap_dss_device *dssdev); + + int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len); + union { const struct omapdss_hdmi_ops hdmi; const struct omapdss_dsi_ops dsi; @@ -435,14 +438,6 @@ struct omap_dss_device { };
struct omap_dss_driver { - int (*connect)(struct omap_dss_device *src, - struct omap_dss_device *dst); - void (*disconnect)(struct omap_dss_device *src, - struct omap_dss_device *dst); - - int (*enable)(struct omap_dss_device *display); - void (*disable)(struct omap_dss_device *display); - int (*update)(struct omap_dss_device *dssdev, u16 x, u16 y, u16 w, u16 h); int (*sync)(struct omap_dss_device *dssdev); @@ -454,29 +449,8 @@ struct omap_dss_driver { void *buf, size_t size, u16 x, u16 y, u16 w, u16 h);
- int (*check_timings)(struct omap_dss_device *dssdev, - struct videomode *vm); - void (*set_timings)(struct omap_dss_device *dssdev, - struct videomode *vm); - void (*get_timings)(struct omap_dss_device *dssdev, - struct videomode *vm); void (*get_size)(struct omap_dss_device *dssdev, unsigned int *width, unsigned int *height); - - int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len); - bool (*detect)(struct omap_dss_device *dssdev); - - int (*register_hpd_cb)(struct omap_dss_device *dssdev, - void (*cb)(void *cb_data, - enum drm_connector_status status), - void *cb_data); - void (*unregister_hpd_cb)(struct omap_dss_device *dssdev); - void (*enable_hpd)(struct omap_dss_device *dssdev); - void (*disable_hpd)(struct omap_dss_device *dssdev); - - int (*set_hdmi_mode)(struct omap_dss_device *dssdev, bool hdmi_mode); - int (*set_hdmi_infoframe)(struct omap_dss_device *dssdev, - const struct hdmi_avi_infoframe *avi); };
struct dss_device *omapdss_get_dss(void); diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c index bbcf40db8b28..a5e581c8c8d6 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.c +++ b/drivers/gpu/drm/omapdrm/omap_connector.c @@ -62,11 +62,10 @@ static enum drm_connector_status omap_connector_detect( { struct omap_connector *omap_connector = to_omap_connector(connector); struct omap_dss_device *dssdev = omap_connector->dssdev; - const struct omap_dss_driver *dssdrv = dssdev->driver; enum drm_connector_status ret;
- if (dssdrv->detect) { - if (dssdrv->detect(dssdev)) + if (dssdev->ops->detect) { + if (dssdev->ops->detect(dssdev)) ret = connector_status_connected; else ret = connector_status_disconnected; @@ -91,8 +90,8 @@ static void omap_connector_destroy(struct drm_connector *connector)
DBG("%s", omap_connector->dssdev->name); if (connector->polled == DRM_CONNECTOR_POLL_HPD && - dssdev->driver->unregister_hpd_cb) { - dssdev->driver->unregister_hpd_cb(dssdev); + dssdev->ops->unregister_hpd_cb) { + dssdev->ops->unregister_hpd_cb(dssdev); } drm_connector_unregister(connector); drm_connector_cleanup(connector); @@ -107,7 +106,6 @@ static int omap_connector_get_modes(struct drm_connector *connector) { struct omap_connector *omap_connector = to_omap_connector(connector); struct omap_dss_device *dssdev = omap_connector->dssdev; - const struct omap_dss_driver *dssdrv = dssdev->driver; struct drm_device *dev = connector->dev; int n = 0;
@@ -118,13 +116,13 @@ static int omap_connector_get_modes(struct drm_connector *connector) * LCD panels) we just return a single mode corresponding to the * currently configured timings: */ - if (dssdrv->read_edid) { + if (dssdev->ops->read_edid) { void *edid = kzalloc(MAX_EDID, GFP_KERNEL);
if (!edid) return 0;
- if ((dssdrv->read_edid(dssdev, edid, MAX_EDID) > 0) && + if ((dssdev->ops->read_edid(dssdev, edid, MAX_EDID) > 0) && drm_edid_is_valid(edid)) { drm_mode_connector_update_edid_property( connector, edid); @@ -145,7 +143,7 @@ static int omap_connector_get_modes(struct drm_connector *connector) if (!mode) return 0;
- dssdrv->get_timings(dssdev, &vm); + dssdev->ops->get_timings(dssdev, &vm);
drm_display_mode_from_videomode(&vm, mode);
@@ -153,8 +151,8 @@ static int omap_connector_get_modes(struct drm_connector *connector) drm_mode_set_name(mode); drm_mode_probed_add(connector, mode);
- if (dssdrv->get_size) { - dssdrv->get_size(dssdev, + if (dssdev->driver && dssdev->driver->get_size) { + dssdev->driver->get_size(dssdev, &connector->display_info.width_mm, &connector->display_info.height_mm); } @@ -170,7 +168,6 @@ static int omap_connector_mode_valid(struct drm_connector *connector, { struct omap_connector *omap_connector = to_omap_connector(connector); struct omap_dss_device *dssdev = omap_connector->dssdev; - const struct omap_dss_driver *dssdrv = dssdev->driver; struct videomode vm = {0}; struct drm_device *dev = connector->dev; struct drm_display_mode *new_mode; @@ -185,12 +182,12 @@ static int omap_connector_mode_valid(struct drm_connector *connector, * a fixed resolution panel, check if the timings match with the * panel's timings */ - if (dssdrv->check_timings) { - r = dssdrv->check_timings(dssdev, &vm); + if (dssdev->ops->check_timings) { + r = dssdev->ops->check_timings(dssdev, &vm); } else { struct videomode t = {0};
- dssdrv->get_timings(dssdev, &t); + dssdev->ops->get_timings(dssdev, &t);
/* * Ignore the flags, as we don't get them from @@ -269,10 +266,10 @@ struct drm_connector *omap_connector_init(struct drm_device *dev, connector_type); drm_connector_helper_add(connector, &omap_connector_helper_funcs);
- if (dssdev->driver->register_hpd_cb) { - int ret = dssdev->driver->register_hpd_cb(dssdev, - omap_connector_hpd_cb, - omap_connector); + if (dssdev->ops->register_hpd_cb) { + int ret = dssdev->ops->register_hpd_cb(dssdev, + omap_connector_hpd_cb, + omap_connector); if (!ret) hpd_supported = true; else if (ret != -ENOTSUPP) @@ -282,7 +279,7 @@ struct drm_connector *omap_connector_init(struct drm_device *dev,
if (hpd_supported) connector->polled = DRM_CONNECTOR_POLL_HPD; - else if (dssdev->driver->detect) + else if (dssdev->ops->detect) connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; else diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 80498dcde6d7..197d05312306 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -458,7 +458,7 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc) if (dssdev) { struct videomode vm = {0};
- dssdev->driver->get_timings(dssdev, &vm); + dssdev->ops->get_timings(dssdev, &vm);
omap_crtc->vm.flags |= vm.flags & flags_mask; } diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index e5b52fd4203e..49771475f792 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -378,8 +378,8 @@ static void omap_modeset_enable_external_hpd(struct drm_device *ddev) for (i = 0; i < priv->num_pipes; i++) { struct omap_dss_device *display = priv->pipes[i].display;
- if (display->driver->enable_hpd) - display->driver->enable_hpd(display); + if (display->ops->enable_hpd) + display->ops->enable_hpd(display); } }
@@ -394,8 +394,8 @@ static void omap_modeset_disable_external_hpd(struct drm_device *ddev) for (i = 0; i < priv->num_pipes; i++) { struct omap_dss_device *display = priv->pipes[i].display;
- if (display->driver->disable_hpd) - display->driver->disable_hpd(display); + if (display->ops->disable_hpd) + display->ops->disable_hpd(display); } }
@@ -724,7 +724,7 @@ static int omap_drm_suspend_all_displays(struct drm_device *ddev) struct omap_dss_device *display = priv->pipes[i].display;
if (display->state == OMAP_DSS_DISPLAY_ACTIVE) { - display->driver->disable(display); + display->ops->disable(display); display->activate_after_resume = true; } else { display->activate_after_resume = false; @@ -743,7 +743,7 @@ static int omap_drm_resume_all_displays(struct drm_device *ddev) struct omap_dss_device *display = priv->pipes[i].display;
if (display->activate_after_resume) { - display->driver->enable(display); + display->ops->enable(display); display->activate_after_resume = false; } } diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c index ec0f451e3b36..7bbf3700e393 100644 --- a/drivers/gpu/drm/omapdrm/omap_encoder.c +++ b/drivers/gpu/drm/omapdrm/omap_encoder.c @@ -77,16 +77,16 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder, } }
- if (dssdev->driver->set_hdmi_mode) - dssdev->driver->set_hdmi_mode(dssdev, hdmi_mode); + if (dssdev->ops->hdmi.set_hdmi_mode) + dssdev->ops->hdmi.set_hdmi_mode(dssdev, hdmi_mode);
- if (hdmi_mode && dssdev->driver->set_hdmi_infoframe) { + if (hdmi_mode && dssdev->ops->hdmi.set_infoframe) { struct hdmi_avi_infoframe avi;
r = drm_hdmi_avi_infoframe_from_display_mode(&avi, adjusted_mode, false); if (r == 0) - dssdev->driver->set_hdmi_infoframe(dssdev, &avi); + dssdev->ops->hdmi.set_infoframe(dssdev, &avi); } }
@@ -94,9 +94,8 @@ static void omap_encoder_disable(struct drm_encoder *encoder) { struct omap_encoder *omap_encoder = to_omap_encoder(encoder); struct omap_dss_device *dssdev = omap_encoder->dssdev; - const struct omap_dss_driver *dssdrv = dssdev->driver;
- dssdrv->disable(dssdev); + dssdev->ops->disable(dssdev); }
static int omap_encoder_update(struct drm_encoder *encoder, @@ -106,15 +105,14 @@ static int omap_encoder_update(struct drm_encoder *encoder, struct drm_device *dev = encoder->dev; struct omap_encoder *omap_encoder = to_omap_encoder(encoder); struct omap_dss_device *dssdev = omap_encoder->dssdev; - const struct omap_dss_driver *dssdrv = dssdev->driver; int ret;
- if (dssdrv->check_timings) { - ret = dssdrv->check_timings(dssdev, vm); + if (dssdev->ops->check_timings) { + ret = dssdev->ops->check_timings(dssdev, vm); } else { struct videomode t = {0};
- dssdrv->get_timings(dssdev, &t); + dssdev->ops->get_timings(dssdev, &t);
if (memcmp(vm, &t, sizeof(*vm))) ret = -EINVAL; @@ -127,8 +125,8 @@ static int omap_encoder_update(struct drm_encoder *encoder, return ret; }
- if (dssdrv->set_timings) - dssdrv->set_timings(dssdev, vm); + if (dssdev->ops->set_timings) + dssdev->ops->set_timings(dssdev, vm);
return 0; } @@ -137,13 +135,12 @@ static void omap_encoder_enable(struct drm_encoder *encoder) { struct omap_encoder *omap_encoder = to_omap_encoder(encoder); struct omap_dss_device *dssdev = omap_encoder->dssdev; - const struct omap_dss_driver *dssdrv = dssdev->driver; int r;
omap_encoder_update(encoder, omap_crtc_channel(encoder->crtc), omap_crtc_timings(encoder->crtc));
- r = dssdrv->enable(dssdev); + r = dssdev->ops->enable(dssdev); if (r) dev_err(encoder->dev->dev, "Failed to enable display '%s': %d\n",
Hi,
On Wed, Jun 06, 2018 at 12:36:40PM +0300, Laurent Pinchart wrote:
omap_dss_device instances have two ops structures, omap_dss_driver and omap_dss_device_ops. The former is used for devices at the end of the pipeline (a.k.a. display devices), and the latter for intermediate devices.
Having two sets of operations isn't convenient as code that iterates over omap_dss_device instances need to take them both into account. There's currently a reasonably small amount of such code, but more will be introduced to move the driver away from recursive operations. To simplify current and future code, move all operations that are not specific to the display device to the omap_dss_device_ops.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com
Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.co.uk
-- Sebastian
.../gpu/drm/omapdrm/displays/connector-analog-tv.c | 4 +- drivers/gpu/drm/omapdrm/displays/connector-dvi.c | 4 +- drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 31 +++++++------ .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 14 +++--- drivers/gpu/drm/omapdrm/displays/panel-dpi.c | 4 +- drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c | 12 +++-- .../omapdrm/displays/panel-lgphilips-lb035q02.c | 4 +- .../drm/omapdrm/displays/panel-nec-nl8048hl11.c | 4 +- .../drm/omapdrm/displays/panel-sharp-ls037v7dw01.c | 4 +- .../drm/omapdrm/displays/panel-sony-acx565akm.c | 4 +- .../drm/omapdrm/displays/panel-tpo-td028ttec1.c | 4 +- .../drm/omapdrm/displays/panel-tpo-td043mtea1.c | 4 +- drivers/gpu/drm/omapdrm/dss/base.c | 12 +---- drivers/gpu/drm/omapdrm/dss/dss.c | 2 +- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 3 +- drivers/gpu/drm/omapdrm/dss/hdmi5.c | 3 +- drivers/gpu/drm/omapdrm/dss/omapdss.h | 54 ++++++---------------- drivers/gpu/drm/omapdrm/omap_connector.c | 37 +++++++-------- drivers/gpu/drm/omapdrm/omap_crtc.c | 2 +- drivers/gpu/drm/omapdrm/omap_drv.c | 12 ++--- drivers/gpu/drm/omapdrm/omap_encoder.c | 25 +++++----- 21 files changed, 106 insertions(+), 137 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c index d59b4f2e22dc..563fc7e618b3 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c @@ -119,7 +119,7 @@ static int tvc_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); }
-static const struct omap_dss_driver tvc_driver = { +static const struct omap_dss_device_ops tvc_ops = { .connect = tvc_connect, .disconnect = tvc_disconnect,
@@ -146,7 +146,7 @@ static int tvc_probe(struct platform_device *pdev) ddata->vm = tvc_pal_vm;
dssdev = &ddata->dssdev;
- dssdev->driver = &tvc_driver;
- dssdev->ops = &tvc_ops; dssdev->dev = &pdev->dev; dssdev->type = OMAP_DISPLAY_TYPE_VENC; dssdev->owner = THIS_MODULE;
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c index 39e7d0be887f..a639a86cd47b 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c @@ -265,7 +265,7 @@ static void dvic_disable_hpd(struct omap_dss_device *dssdev) mutex_unlock(&ddata->hpd_lock); }
-static const struct omap_dss_driver dvic_driver = { +static const struct omap_dss_device_ops dvic_ops = { .connect = dvic_connect, .disconnect = dvic_disconnect,
@@ -367,7 +367,7 @@ static int dvic_probe(struct platform_device *pdev) ddata->vm = dvic_default_vm;
dssdev = &ddata->dssdev;
- dssdev->driver = &dvic_driver;
- dssdev->ops = &dvic_ops; dssdev->dev = &pdev->dev; dssdev->type = OMAP_DISPLAY_TYPE_DVI; dssdev->owner = THIS_MODULE;
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index d39480b8cf6b..54bfd7156360 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c @@ -132,7 +132,7 @@ static int hdmic_read_edid(struct omap_dss_device *dssdev, { struct omap_dss_device *src = dssdev->src;
- return src->ops->hdmi.read_edid(src, edid, len);
- return src->ops->read_edid(src, edid, len);
}
static bool hdmic_detect(struct omap_dss_device *dssdev) @@ -144,7 +144,7 @@ static bool hdmic_detect(struct omap_dss_device *dssdev) if (ddata->hpd_gpio) connected = gpiod_get_value_cansleep(ddata->hpd_gpio); else
connected = src->ops->hdmi.detect(src);
if (!connected && src->ops->hdmi.lost_hotplug) src->ops->hdmi.lost_hotplug(src); return connected;connected = src->ops->detect(src);
@@ -164,8 +164,8 @@ static int hdmic_register_hpd_cb(struct omap_dss_device *dssdev, ddata->hpd_cb_data = cb_data; mutex_unlock(&ddata->hpd_lock); return 0;
- } else if (src->ops->hdmi.register_hpd_cb) {
return src->ops->hdmi.register_hpd_cb(src, cb, cb_data);
} else if (src->ops->register_hpd_cb) {
return src->ops->register_hpd_cb(src, cb, cb_data);
}
return -ENOTSUPP;
@@ -181,8 +181,8 @@ static void hdmic_unregister_hpd_cb(struct omap_dss_device *dssdev) ddata->hpd_cb = NULL; ddata->hpd_cb_data = NULL; mutex_unlock(&ddata->hpd_lock);
- } else if (src->ops->hdmi.unregister_hpd_cb) {
src->ops->hdmi.unregister_hpd_cb(src);
- } else if (src->ops->unregister_hpd_cb) {
}src->ops->unregister_hpd_cb(src);
}
@@ -195,8 +195,8 @@ static void hdmic_enable_hpd(struct omap_dss_device *dssdev) mutex_lock(&ddata->hpd_lock); ddata->hpd_enabled = true; mutex_unlock(&ddata->hpd_lock);
- } else if (src->ops->hdmi.enable_hpd) {
src->ops->hdmi.enable_hpd(src);
- } else if (src->ops->enable_hpd) {
}src->ops->enable_hpd(src);
}
@@ -209,8 +209,8 @@ static void hdmic_disable_hpd(struct omap_dss_device *dssdev) mutex_lock(&ddata->hpd_lock); ddata->hpd_enabled = false; mutex_unlock(&ddata->hpd_lock);
- } else if (src->ops->hdmi.disable_hpd) {
src->ops->hdmi.disable_hpd(src);
- } else if (src->ops->disable_hpd) {
}src->ops->disable_hpd(src);
}
@@ -229,7 +229,7 @@ static int hdmic_set_infoframe(struct omap_dss_device *dssdev, return src->ops->hdmi.set_infoframe(src, avi); }
-static const struct omap_dss_driver hdmic_driver = { +static const struct omap_dss_device_ops hdmic_ops = { .connect = hdmic_connect, .disconnect = hdmic_disconnect,
@@ -246,8 +246,11 @@ static const struct omap_dss_driver hdmic_driver = { .unregister_hpd_cb = hdmic_unregister_hpd_cb, .enable_hpd = hdmic_enable_hpd, .disable_hpd = hdmic_disable_hpd,
- .set_hdmi_mode = hdmic_set_hdmi_mode,
- .set_hdmi_infoframe = hdmic_set_infoframe,
- .hdmi = {
.set_hdmi_mode = hdmic_set_hdmi_mode,
.set_infoframe = hdmic_set_infoframe,
- },
};
static irqreturn_t hdmic_hpd_isr(int irq, void *data) @@ -309,7 +312,7 @@ static int hdmic_probe(struct platform_device *pdev) ddata->vm = hdmic_default_vm;
dssdev = &ddata->dssdev;
- dssdev->driver = &hdmic_driver;
- dssdev->ops = &hdmic_ops; dssdev->dev = &pdev->dev; dssdev->type = OMAP_DISPLAY_TYPE_HDMI; dssdev->owner = THIS_MODULE;
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c index 3bd6aeb7b3f4..545a06e6ca11 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c @@ -125,7 +125,7 @@ static int tpd_read_edid(struct omap_dss_device *dssdev, if (!gpiod_get_value_cansleep(ddata->hpd_gpio)) return -ENODEV;
- return src->ops->hdmi.read_edid(src, edid, len);
- return src->ops->read_edid(src, edid, len);
}
static bool tpd_detect(struct omap_dss_device *dssdev) @@ -205,14 +205,14 @@ static const struct omap_dss_device_ops tpd_ops = { .disable = tpd_disable, .check_timings = tpd_check_timings, .set_timings = tpd_set_timings,
.read_edid = tpd_read_edid,
.detect = tpd_detect,
.register_hpd_cb = tpd_register_hpd_cb,
.unregister_hpd_cb = tpd_unregister_hpd_cb,
.enable_hpd = tpd_enable_hpd,
.disable_hpd = tpd_disable_hpd,
.hdmi = {
.read_edid = tpd_read_edid,
.detect = tpd_detect,
.register_hpd_cb = tpd_register_hpd_cb,
.unregister_hpd_cb = tpd_unregister_hpd_cb,
.enable_hpd = tpd_enable_hpd,
.set_infoframe = tpd_set_infoframe, .set_hdmi_mode = tpd_set_hdmi_mode, },.disable_hpd = tpd_disable_hpd,
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c index 91f99c95c4c4..c03877af9cdb 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c @@ -122,7 +122,7 @@ static int panel_dpi_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); }
-static const struct omap_dss_driver panel_dpi_ops = { +static const struct omap_dss_device_ops panel_dpi_ops = { .connect = panel_dpi_connect, .disconnect = panel_dpi_disconnect,
@@ -196,7 +196,7 @@ static int panel_dpi_probe(struct platform_device *pdev)
dssdev = &ddata->dssdev; dssdev->dev = &pdev->dev;
- dssdev->driver = &panel_dpi_ops;
- dssdev->ops = &panel_dpi_ops; dssdev->type = OMAP_DISPLAY_TYPE_DPI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0);
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c index be4f03aa7af3..e8a81c4fd066 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c @@ -1179,18 +1179,21 @@ static void dsicm_get_size(struct omap_dss_device *dssdev, *height = ddata->height_mm; }
-static const struct omap_dss_driver dsicm_ops = { +static const struct omap_dss_device_ops dsicm_ops = { .connect = dsicm_connect, .disconnect = dsicm_disconnect,
.enable = dsicm_enable, .disable = dsicm_disable,
- .get_timings = dsicm_get_timings,
- .check_timings = dsicm_check_timings,
+};
+static const struct omap_dss_driver dsicm_dss_driver = { .update = dsicm_update, .sync = dsicm_sync,
.get_timings = dsicm_get_timings,
.check_timings = dsicm_check_timings, .get_size = dsicm_get_size,
.enable_te = dsicm_enable_te,
@@ -1299,7 +1302,8 @@ static int dsicm_probe(struct platform_device *pdev)
dssdev = &ddata->dssdev; dssdev->dev = dev;
- dssdev->driver = &dsicm_ops;
- dssdev->ops = &dsicm_ops;
- dssdev->driver = &dsicm_dss_driver; dssdev->type = OMAP_DISPLAY_TYPE_DSI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0);
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c index 66763a12fc3d..62576e4f89e3 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c @@ -199,7 +199,7 @@ static int lb035q02_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); }
-static const struct omap_dss_driver lb035q02_ops = { +static const struct omap_dss_device_ops lb035q02_ops = { .connect = lb035q02_connect, .disconnect = lb035q02_disconnect,
@@ -249,7 +249,7 @@ static int lb035q02_panel_spi_probe(struct spi_device *spi)
dssdev = &ddata->dssdev; dssdev->dev = &spi->dev;
- dssdev->driver = &lb035q02_ops;
- dssdev->ops = &lb035q02_ops; dssdev->type = OMAP_DISPLAY_TYPE_DPI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0);
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c index 767ffd2fa0f4..9f34cf02a114 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c @@ -187,7 +187,7 @@ static int nec_8048_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); }
-static const struct omap_dss_driver nec_8048_ops = { +static const struct omap_dss_device_ops nec_8048_ops = { .connect = nec_8048_connect, .disconnect = nec_8048_disconnect,
@@ -239,7 +239,7 @@ static int nec_8048_probe(struct spi_device *spi)
dssdev = &ddata->dssdev; dssdev->dev = &spi->dev;
- dssdev->driver = &nec_8048_ops;
- dssdev->ops = &nec_8048_ops; dssdev->type = OMAP_DISPLAY_TYPE_DPI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0);
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c index 7fbdf3ec0113..9ee6b8376916 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c @@ -161,7 +161,7 @@ static int sharp_ls_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); }
-static const struct omap_dss_driver sharp_ls_ops = { +static const struct omap_dss_device_ops sharp_ls_ops = { .connect = sharp_ls_connect, .disconnect = sharp_ls_disconnect,
@@ -247,7 +247,7 @@ static int sharp_ls_probe(struct platform_device *pdev)
dssdev = &ddata->dssdev; dssdev->dev = &pdev->dev;
- dssdev->driver = &sharp_ls_ops;
- dssdev->ops = &sharp_ls_ops; dssdev->type = OMAP_DISPLAY_TYPE_DPI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0);
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c index f5f3e5e5f3dc..8baa290f841b 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c @@ -660,7 +660,7 @@ static int acx565akm_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); }
-static const struct omap_dss_driver acx565akm_ops = { +static const struct omap_dss_device_ops acx565akm_ops = { .connect = acx565akm_connect, .disconnect = acx565akm_disconnect,
@@ -762,7 +762,7 @@ static int acx565akm_probe(struct spi_device *spi)
dssdev = &ddata->dssdev; dssdev->dev = &spi->dev;
- dssdev->driver = &acx565akm_ops;
- dssdev->ops = &acx565akm_ops; dssdev->type = OMAP_DISPLAY_TYPE_SDI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0);
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c index d3b0d204b7c9..4dfe200e8f70 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c @@ -330,7 +330,7 @@ static int td028ttec1_panel_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); }
-static const struct omap_dss_driver td028ttec1_ops = { +static const struct omap_dss_device_ops td028ttec1_ops = { .connect = td028ttec1_panel_connect, .disconnect = td028ttec1_panel_disconnect,
@@ -371,7 +371,7 @@ static int td028ttec1_panel_probe(struct spi_device *spi)
dssdev = &ddata->dssdev; dssdev->dev = &spi->dev;
- dssdev->driver = &td028ttec1_ops;
- dssdev->ops = &td028ttec1_ops; dssdev->type = OMAP_DISPLAY_TYPE_DPI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0);
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c index 1521812ab15b..b211a7809a26 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c @@ -404,7 +404,7 @@ static int tpo_td043_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); }
-static const struct omap_dss_driver tpo_td043_ops = { +static const struct omap_dss_device_ops tpo_td043_ops = { .connect = tpo_td043_connect, .disconnect = tpo_td043_disconnect,
@@ -469,7 +469,7 @@ static int tpo_td043_probe(struct spi_device *spi)
dssdev = &ddata->dssdev; dssdev->dev = &spi->dev;
- dssdev->driver = &tpo_td043_ops;
- dssdev->ops = &tpo_td043_ops; dssdev->type = OMAP_DISPLAY_TYPE_DPI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0);
diff --git a/drivers/gpu/drm/omapdrm/dss/base.c b/drivers/gpu/drm/omapdrm/dss/base.c index 6a73d3559257..dcef0128818d 100644 --- a/drivers/gpu/drm/omapdrm/dss/base.c +++ b/drivers/gpu/drm/omapdrm/dss/base.c @@ -198,11 +198,7 @@ int omapdss_device_connect(struct dss_device *dss,
dst->dss = dss;
- if (dst->driver)
ret = dst->driver->connect(src, dst);
- else
ret = dst->ops->connect(src, dst);
- ret = dst->ops->connect(src, dst); if (ret < 0) { dst->dss = NULL; return ret;
@@ -238,11 +234,7 @@ void omapdss_device_disconnect(struct omap_dss_device *src,
WARN_ON(dst->state != OMAP_DSS_DISPLAY_DISABLED);
- if (dst->driver)
dst->driver->disconnect(src, dst);
- else
dst->ops->disconnect(src, dst);
- dst->ops->disconnect(src, dst); dst->dss = NULL;
} EXPORT_SYMBOL_GPL(omapdss_device_disconnect); diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index 6118159dd571..8d757e87bdda 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -1553,7 +1553,7 @@ static void dss_shutdown(struct platform_device *pdev)
for_each_dss_display(dssdev) { if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
dssdev->driver->disable(dssdev);
}dssdev->ops->disable(dssdev);
}
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index c4fcdc9ed62d..bebce93fed3e 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -511,8 +511,9 @@ static const struct omap_dss_device_ops hdmi_ops = { .check_timings = hdmi_display_check_timing, .set_timings = hdmi_display_set_timing,
- .read_edid = hdmi_read_edid,
- .hdmi = {
.lost_hotplug = hdmi_lost_hotplug, .set_infoframe = hdmi_set_infoframe, .set_hdmi_mode = hdmi_set_hdmi_mode,.read_edid = hdmi_read_edid,
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c index 889c31745492..7c07e0208107 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c @@ -505,8 +505,9 @@ static const struct omap_dss_device_ops hdmi_ops = { .check_timings = hdmi_display_check_timing, .set_timings = hdmi_display_set_timing,
- .read_edid = hdmi_read_edid,
- .hdmi = {
.set_infoframe = hdmi_set_infoframe, .set_hdmi_mode = hdmi_set_hdmi_mode, },.read_edid = hdmi_read_edid,
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index ae30802f2151..3a5ee897baf0 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -297,18 +297,7 @@ struct omap_dss_writeback_info { };
struct omapdss_hdmi_ops {
- int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len); void (*lost_hotplug)(struct omap_dss_device *dssdev);
- bool (*detect)(struct omap_dss_device *dssdev);
- int (*register_hpd_cb)(struct omap_dss_device *dssdev,
void (*cb)(void *cb_data,
enum drm_connector_status status),
void *cb_data);
- void (*unregister_hpd_cb)(struct omap_dss_device *dssdev);
- void (*enable_hpd)(struct omap_dss_device *dssdev);
- void (*disable_hpd)(struct omap_dss_device *dssdev);
- int (*set_hdmi_mode)(struct omap_dss_device *dssdev, bool hdmi_mode); int (*set_infoframe)(struct omap_dss_device *dssdev, const struct hdmi_avi_infoframe *avi);
@@ -376,9 +365,23 @@ struct omap_dss_device_ops {
int (*check_timings)(struct omap_dss_device *dssdev, struct videomode *vm);
void (*get_timings)(struct omap_dss_device *dssdev,
struct videomode *vm);
void (*set_timings)(struct omap_dss_device *dssdev, struct videomode *vm);
bool (*detect)(struct omap_dss_device *dssdev);
int (*register_hpd_cb)(struct omap_dss_device *dssdev,
void (*cb)(void *cb_data,
enum drm_connector_status status),
void *cb_data);
void (*unregister_hpd_cb)(struct omap_dss_device *dssdev);
void (*enable_hpd)(struct omap_dss_device *dssdev);
void (*disable_hpd)(struct omap_dss_device *dssdev);
int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len);
union { const struct omapdss_hdmi_ops hdmi; const struct omapdss_dsi_ops dsi;
@@ -435,14 +438,6 @@ struct omap_dss_device { };
struct omap_dss_driver {
- int (*connect)(struct omap_dss_device *src,
struct omap_dss_device *dst);
- void (*disconnect)(struct omap_dss_device *src,
struct omap_dss_device *dst);
- int (*enable)(struct omap_dss_device *display);
- void (*disable)(struct omap_dss_device *display);
- int (*update)(struct omap_dss_device *dssdev, u16 x, u16 y, u16 w, u16 h); int (*sync)(struct omap_dss_device *dssdev);
@@ -454,29 +449,8 @@ struct omap_dss_driver { void *buf, size_t size, u16 x, u16 y, u16 w, u16 h);
- int (*check_timings)(struct omap_dss_device *dssdev,
struct videomode *vm);
- void (*set_timings)(struct omap_dss_device *dssdev,
struct videomode *vm);
- void (*get_timings)(struct omap_dss_device *dssdev,
void (*get_size)(struct omap_dss_device *dssdev, unsigned int *width, unsigned int *height);struct videomode *vm);
- int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len);
- bool (*detect)(struct omap_dss_device *dssdev);
- int (*register_hpd_cb)(struct omap_dss_device *dssdev,
void (*cb)(void *cb_data,
enum drm_connector_status status),
void *cb_data);
- void (*unregister_hpd_cb)(struct omap_dss_device *dssdev);
- void (*enable_hpd)(struct omap_dss_device *dssdev);
- void (*disable_hpd)(struct omap_dss_device *dssdev);
- int (*set_hdmi_mode)(struct omap_dss_device *dssdev, bool hdmi_mode);
- int (*set_hdmi_infoframe)(struct omap_dss_device *dssdev,
const struct hdmi_avi_infoframe *avi);
};
struct dss_device *omapdss_get_dss(void); diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c index bbcf40db8b28..a5e581c8c8d6 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.c +++ b/drivers/gpu/drm/omapdrm/omap_connector.c @@ -62,11 +62,10 @@ static enum drm_connector_status omap_connector_detect( { struct omap_connector *omap_connector = to_omap_connector(connector); struct omap_dss_device *dssdev = omap_connector->dssdev;
const struct omap_dss_driver *dssdrv = dssdev->driver; enum drm_connector_status ret;
if (dssdrv->detect) {
if (dssdrv->detect(dssdev))
- if (dssdev->ops->detect) {
else ret = connector_status_disconnected;if (dssdev->ops->detect(dssdev)) ret = connector_status_connected;
@@ -91,8 +90,8 @@ static void omap_connector_destroy(struct drm_connector *connector)
DBG("%s", omap_connector->dssdev->name); if (connector->polled == DRM_CONNECTOR_POLL_HPD &&
dssdev->driver->unregister_hpd_cb) {
dssdev->driver->unregister_hpd_cb(dssdev);
dssdev->ops->unregister_hpd_cb) {
} drm_connector_unregister(connector); drm_connector_cleanup(connector);dssdev->ops->unregister_hpd_cb(dssdev);
@@ -107,7 +106,6 @@ static int omap_connector_get_modes(struct drm_connector *connector) { struct omap_connector *omap_connector = to_omap_connector(connector); struct omap_dss_device *dssdev = omap_connector->dssdev;
- const struct omap_dss_driver *dssdrv = dssdev->driver; struct drm_device *dev = connector->dev; int n = 0;
@@ -118,13 +116,13 @@ static int omap_connector_get_modes(struct drm_connector *connector) * LCD panels) we just return a single mode corresponding to the * currently configured timings: */
- if (dssdrv->read_edid) {
if (dssdev->ops->read_edid) { void *edid = kzalloc(MAX_EDID, GFP_KERNEL);
if (!edid) return 0;
if ((dssdrv->read_edid(dssdev, edid, MAX_EDID) > 0) &&
if ((dssdev->ops->read_edid(dssdev, edid, MAX_EDID) > 0) && drm_edid_is_valid(edid)) { drm_mode_connector_update_edid_property( connector, edid);
@@ -145,7 +143,7 @@ static int omap_connector_get_modes(struct drm_connector *connector) if (!mode) return 0;
dssdrv->get_timings(dssdev, &vm);
dssdev->ops->get_timings(dssdev, &vm);
drm_display_mode_from_videomode(&vm, mode);
@@ -153,8 +151,8 @@ static int omap_connector_get_modes(struct drm_connector *connector) drm_mode_set_name(mode); drm_mode_probed_add(connector, mode);
if (dssdrv->get_size) {
dssdrv->get_size(dssdev,
if (dssdev->driver && dssdev->driver->get_size) {
}dssdev->driver->get_size(dssdev, &connector->display_info.width_mm, &connector->display_info.height_mm);
@@ -170,7 +168,6 @@ static int omap_connector_mode_valid(struct drm_connector *connector, { struct omap_connector *omap_connector = to_omap_connector(connector); struct omap_dss_device *dssdev = omap_connector->dssdev;
- const struct omap_dss_driver *dssdrv = dssdev->driver; struct videomode vm = {0}; struct drm_device *dev = connector->dev; struct drm_display_mode *new_mode;
@@ -185,12 +182,12 @@ static int omap_connector_mode_valid(struct drm_connector *connector, * a fixed resolution panel, check if the timings match with the * panel's timings */
- if (dssdrv->check_timings) {
r = dssdrv->check_timings(dssdev, &vm);
- if (dssdev->ops->check_timings) {
} else { struct videomode t = {0};r = dssdev->ops->check_timings(dssdev, &vm);
dssdrv->get_timings(dssdev, &t);
dssdev->ops->get_timings(dssdev, &t);
/*
- Ignore the flags, as we don't get them from
@@ -269,10 +266,10 @@ struct drm_connector *omap_connector_init(struct drm_device *dev, connector_type); drm_connector_helper_add(connector, &omap_connector_helper_funcs);
- if (dssdev->driver->register_hpd_cb) {
int ret = dssdev->driver->register_hpd_cb(dssdev,
omap_connector_hpd_cb,
omap_connector);
- if (dssdev->ops->register_hpd_cb) {
int ret = dssdev->ops->register_hpd_cb(dssdev,
omap_connector_hpd_cb,
if (!ret) hpd_supported = true; else if (ret != -ENOTSUPP)omap_connector);
@@ -282,7 +279,7 @@ struct drm_connector *omap_connector_init(struct drm_device *dev,
if (hpd_supported) connector->polled = DRM_CONNECTOR_POLL_HPD;
- else if (dssdev->driver->detect)
- else if (dssdev->ops->detect) connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; else
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 80498dcde6d7..197d05312306 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -458,7 +458,7 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc) if (dssdev) { struct videomode vm = {0};
dssdev->driver->get_timings(dssdev, &vm);
dssdev->ops->get_timings(dssdev, &vm); omap_crtc->vm.flags |= vm.flags & flags_mask; }
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index e5b52fd4203e..49771475f792 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -378,8 +378,8 @@ static void omap_modeset_enable_external_hpd(struct drm_device *ddev) for (i = 0; i < priv->num_pipes; i++) { struct omap_dss_device *display = priv->pipes[i].display;
if (display->driver->enable_hpd)
display->driver->enable_hpd(display);
if (display->ops->enable_hpd)
}display->ops->enable_hpd(display);
}
@@ -394,8 +394,8 @@ static void omap_modeset_disable_external_hpd(struct drm_device *ddev) for (i = 0; i < priv->num_pipes; i++) { struct omap_dss_device *display = priv->pipes[i].display;
if (display->driver->disable_hpd)
display->driver->disable_hpd(display);
if (display->ops->disable_hpd)
}display->ops->disable_hpd(display);
}
@@ -724,7 +724,7 @@ static int omap_drm_suspend_all_displays(struct drm_device *ddev) struct omap_dss_device *display = priv->pipes[i].display;
if (display->state == OMAP_DSS_DISPLAY_ACTIVE) {
display->driver->disable(display);
} else { display->activate_after_resume = false;display->ops->disable(display); display->activate_after_resume = true;
@@ -743,7 +743,7 @@ static int omap_drm_resume_all_displays(struct drm_device *ddev) struct omap_dss_device *display = priv->pipes[i].display;
if (display->activate_after_resume) {
display->driver->enable(display);
} }display->ops->enable(display); display->activate_after_resume = false;
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c index ec0f451e3b36..7bbf3700e393 100644 --- a/drivers/gpu/drm/omapdrm/omap_encoder.c +++ b/drivers/gpu/drm/omapdrm/omap_encoder.c @@ -77,16 +77,16 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder, } }
- if (dssdev->driver->set_hdmi_mode)
dssdev->driver->set_hdmi_mode(dssdev, hdmi_mode);
- if (dssdev->ops->hdmi.set_hdmi_mode)
dssdev->ops->hdmi.set_hdmi_mode(dssdev, hdmi_mode);
- if (hdmi_mode && dssdev->driver->set_hdmi_infoframe) {
if (hdmi_mode && dssdev->ops->hdmi.set_infoframe) { struct hdmi_avi_infoframe avi;
r = drm_hdmi_avi_infoframe_from_display_mode(&avi, adjusted_mode, false); if (r == 0)
dssdev->driver->set_hdmi_infoframe(dssdev, &avi);
}dssdev->ops->hdmi.set_infoframe(dssdev, &avi);
}
@@ -94,9 +94,8 @@ static void omap_encoder_disable(struct drm_encoder *encoder) { struct omap_encoder *omap_encoder = to_omap_encoder(encoder); struct omap_dss_device *dssdev = omap_encoder->dssdev;
const struct omap_dss_driver *dssdrv = dssdev->driver;
dssdrv->disable(dssdev);
- dssdev->ops->disable(dssdev);
}
static int omap_encoder_update(struct drm_encoder *encoder, @@ -106,15 +105,14 @@ static int omap_encoder_update(struct drm_encoder *encoder, struct drm_device *dev = encoder->dev; struct omap_encoder *omap_encoder = to_omap_encoder(encoder); struct omap_dss_device *dssdev = omap_encoder->dssdev;
const struct omap_dss_driver *dssdrv = dssdev->driver; int ret;
if (dssdrv->check_timings) {
ret = dssdrv->check_timings(dssdev, vm);
- if (dssdev->ops->check_timings) {
} else { struct videomode t = {0};ret = dssdev->ops->check_timings(dssdev, vm);
dssdrv->get_timings(dssdev, &t);
dssdev->ops->get_timings(dssdev, &t);
if (memcmp(vm, &t, sizeof(*vm))) ret = -EINVAL;
@@ -127,8 +125,8 @@ static int omap_encoder_update(struct drm_encoder *encoder, return ret; }
- if (dssdrv->set_timings)
dssdrv->set_timings(dssdev, vm);
if (dssdev->ops->set_timings)
dssdev->ops->set_timings(dssdev, vm);
return 0;
} @@ -137,13 +135,12 @@ static void omap_encoder_enable(struct drm_encoder *encoder) { struct omap_encoder *omap_encoder = to_omap_encoder(encoder); struct omap_dss_device *dssdev = omap_encoder->dssdev;
const struct omap_dss_driver *dssdrv = dssdev->driver; int r;
omap_encoder_update(encoder, omap_crtc_channel(encoder->crtc), omap_crtc_timings(encoder->crtc));
r = dssdrv->enable(dssdev);
- r = dssdev->ops->enable(dssdev); if (r) dev_err(encoder->dev->dev, "Failed to enable display '%s': %d\n",
-- Regards,
Laurent Pinchart
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
When an omap_dss_device operation can be implemented in multiple places in a chain of devices, it is important to find out which device to address to perfom the operation. This is currently done by calling the operation on the display device at the end of the chain, and recursively delagating the operation to the previous device if it can't be performed locally. The drawback of this approach is an increased complexity in omap_dss_device drivers.
In order to simplify the drivers, we will switch from a recursive model to an interative model, centralizing the complexity in a single location. This requires knowing which operations an omap_dss_device supports at runtime. We can already test which operations are implemented by checking the operation pointer, but implemented operations can require resources whose availability varies between systems. For instance a hot-plug signal from a connector can be wired to a GPIO or to a bridge chip.
Add operation flags that can be set in the omap_dss_device structure by drivers to signal support for operations.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/omapdrm/dss/omapdss.h | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index 3a5ee897baf0..e9a47d8c0edc 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -388,6 +388,18 @@ struct omap_dss_device_ops { }; };
+/** + * enum omap_dss_device_ops_flag - Indicates which device ops are supported + * @OMAP_DSS_DEVICE_OP_DETECT: The device supports output connection detection + * @OMAP_DSS_DEVICE_OP_HPD: The device supports all hot-plug-related operations + * @OMAP_DSS_DEVICE_OP_EDID: The device supports readind EDID + */ +enum omap_dss_device_ops_flag { + OMAP_DSS_DEVICE_OP_DETECT = BIT(0), + OMAP_DSS_DEVICE_OP_HPD = BIT(1), + OMAP_DSS_DEVICE_OP_EDID = BIT(2), +}; + struct omap_dss_device { struct kobject kobj; struct device *dev; @@ -416,6 +428,7 @@ struct omap_dss_device {
const struct omap_dss_driver *driver; const struct omap_dss_device_ops *ops; + unsigned long ops_flags;
/* helper variable for driver suspend/resume */ bool activate_after_resume;
Hi,
On Wed, Jun 06, 2018 at 12:36:41PM +0300, Laurent Pinchart wrote:
When an omap_dss_device operation can be implemented in multiple places in a chain of devices, it is important to find out which device to address to perfom the operation. This is currently done by calling the operation on the display device at the end of the chain, and recursively delagating the operation to the previous device if it can't be performed locally. The drawback of this approach is an increased complexity in omap_dss_device drivers.
In order to simplify the drivers, we will switch from a recursive model to an interative model, centralizing the complexity in a single location. This requires knowing which operations an omap_dss_device supports at runtime. We can already test which operations are implemented by checking the operation pointer, but implemented operations can require resources whose availability varies between systems. For instance a hot-plug signal from a connector can be wired to a GPIO or to a bridge chip.
Add operation flags that can be set in the omap_dss_device structure by drivers to signal support for operations.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com
Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.co.uk
-- Sebastian
drivers/gpu/drm/omapdrm/dss/omapdss.h | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index 3a5ee897baf0..e9a47d8c0edc 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -388,6 +388,18 @@ struct omap_dss_device_ops { }; };
+/**
- enum omap_dss_device_ops_flag - Indicates which device ops are supported
- @OMAP_DSS_DEVICE_OP_DETECT: The device supports output connection detection
- @OMAP_DSS_DEVICE_OP_HPD: The device supports all hot-plug-related operations
- @OMAP_DSS_DEVICE_OP_EDID: The device supports readind EDID
- */
+enum omap_dss_device_ops_flag {
- OMAP_DSS_DEVICE_OP_DETECT = BIT(0),
- OMAP_DSS_DEVICE_OP_HPD = BIT(1),
- OMAP_DSS_DEVICE_OP_EDID = BIT(2),
+};
struct omap_dss_device { struct kobject kobj; struct device *dev; @@ -416,6 +428,7 @@ struct omap_dss_device {
const struct omap_dss_driver *driver; const struct omap_dss_device_ops *ops;
unsigned long ops_flags;
/* helper variable for driver suspend/resume */ bool activate_after_resume;
-- Regards,
Laurent Pinchart
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Instead of calling the .detect() operation recursively from the display device back to the first device that provides hot plug detection support, iterate over the devices manually in the DRM connector .detect() implementation. This moves the complexity to a single central location and simplifies the logic in omap_dss_device drivers.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/omapdrm/displays/connector-dvi.c | 2 ++ drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 6 ++-- .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 4 ++- drivers/gpu/drm/omapdrm/omap_connector.c | 36 ++++++++++++++-------- 4 files changed, 30 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c index a639a86cd47b..f1674b3eee50 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c @@ -372,6 +372,8 @@ static int dvic_probe(struct platform_device *pdev) dssdev->type = OMAP_DISPLAY_TYPE_DVI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0); + dssdev->ops_flags = ddata->hpd_gpio || ddata->i2c_adapter + ? OMAP_DSS_DEVICE_OP_DETECT : 0;
omapdss_display_init(dssdev); omapdss_device_register(dssdev); diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index 54bfd7156360..0d22d7004c98 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c @@ -141,10 +141,7 @@ static bool hdmic_detect(struct omap_dss_device *dssdev) struct omap_dss_device *src = dssdev->src; bool connected;
- if (ddata->hpd_gpio) - connected = gpiod_get_value_cansleep(ddata->hpd_gpio); - else - connected = src->ops->detect(src); + connected = gpiod_get_value_cansleep(ddata->hpd_gpio); if (!connected && src->ops->hdmi.lost_hotplug) src->ops->hdmi.lost_hotplug(src); return connected; @@ -317,6 +314,7 @@ static int hdmic_probe(struct platform_device *pdev) dssdev->type = OMAP_DISPLAY_TYPE_HDMI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0); + dssdev->ops_flags = ddata->hpd_gpio ? OMAP_DSS_DEVICE_OP_DETECT : 0;
omapdss_display_init(dssdev); omapdss_device_register(dssdev); diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c index 545a06e6ca11..f37878ca6077 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c @@ -132,8 +132,9 @@ static bool tpd_detect(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); struct omap_dss_device *src = dssdev->src; - bool connected = gpiod_get_value_cansleep(ddata->hpd_gpio); + bool connected;
+ connected = gpiod_get_value_cansleep(ddata->hpd_gpio); if (!connected && src->ops->hdmi.lost_hotplug) src->ops->hdmi.lost_hotplug(src); return connected; @@ -288,6 +289,7 @@ static int tpd_probe(struct platform_device *pdev) dssdev->output_type = OMAP_DISPLAY_TYPE_HDMI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(1) | BIT(0); + dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT;
dssdev->next = omapdss_of_find_connected_device(pdev->dev.of_node, 1); if (IS_ERR(dssdev->next)) { diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c index a5e581c8c8d6..6c02c2492d47 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.c +++ b/drivers/gpu/drm/omapdrm/omap_connector.c @@ -61,26 +61,36 @@ static enum drm_connector_status omap_connector_detect( struct drm_connector *connector, bool force) { struct omap_connector *omap_connector = to_omap_connector(connector); - struct omap_dss_device *dssdev = omap_connector->dssdev; - enum drm_connector_status ret; + struct omap_dss_device *dssdev; + enum drm_connector_status status; + + for (dssdev = omap_connector->dssdev; dssdev; dssdev = dssdev->src) { + if (dssdev->ops_flags & OMAP_DSS_DEVICE_OP_DETECT) + break; + }
- if (dssdev->ops->detect) { + if (dssdev) { if (dssdev->ops->detect(dssdev)) - ret = connector_status_connected; + status = connector_status_connected; else - ret = connector_status_disconnected; - } else if (dssdev->type == OMAP_DISPLAY_TYPE_DPI || - dssdev->type == OMAP_DISPLAY_TYPE_DBI || - dssdev->type == OMAP_DISPLAY_TYPE_SDI || - dssdev->type == OMAP_DISPLAY_TYPE_DSI) { - ret = connector_status_connected; + status = connector_status_disconnected; } else { - ret = connector_status_unknown; + switch (omap_connector->dssdev->type) { + case OMAP_DISPLAY_TYPE_DPI: + case OMAP_DISPLAY_TYPE_DBI: + case OMAP_DISPLAY_TYPE_SDI: + case OMAP_DISPLAY_TYPE_DSI: + status = connector_status_connected; + break; + default: + status = connector_status_unknown; + break; + } }
- VERB("%s: %d (force=%d)", omap_connector->dssdev->name, ret, force); + VERB("%s: %d (force=%d)", omap_connector->dssdev->name, status, force);
- return ret; + return status; }
static void omap_connector_destroy(struct drm_connector *connector)
Hi,
On Wed, Jun 06, 2018 at 12:36:42PM +0300, Laurent Pinchart wrote:
Instead of calling the .detect() operation recursively from the display device back to the first device that provides hot plug detection support, iterate over the devices manually in the DRM connector .detect() implementation. This moves the complexity to a single central location and simplifies the logic in omap_dss_device drivers.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com
Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.co.uk
-- Sebastian
drivers/gpu/drm/omapdrm/displays/connector-dvi.c | 2 ++ drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 6 ++-- .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 4 ++- drivers/gpu/drm/omapdrm/omap_connector.c | 36 ++++++++++++++-------- 4 files changed, 30 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c index a639a86cd47b..f1674b3eee50 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c @@ -372,6 +372,8 @@ static int dvic_probe(struct platform_device *pdev) dssdev->type = OMAP_DISPLAY_TYPE_DVI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0);
dssdev->ops_flags = ddata->hpd_gpio || ddata->i2c_adapter
? OMAP_DSS_DEVICE_OP_DETECT : 0;
omapdss_display_init(dssdev); omapdss_device_register(dssdev);
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index 54bfd7156360..0d22d7004c98 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c @@ -141,10 +141,7 @@ static bool hdmic_detect(struct omap_dss_device *dssdev) struct omap_dss_device *src = dssdev->src; bool connected;
- if (ddata->hpd_gpio)
connected = gpiod_get_value_cansleep(ddata->hpd_gpio);
- else
connected = src->ops->detect(src);
- connected = gpiod_get_value_cansleep(ddata->hpd_gpio); if (!connected && src->ops->hdmi.lost_hotplug) src->ops->hdmi.lost_hotplug(src); return connected;
@@ -317,6 +314,7 @@ static int hdmic_probe(struct platform_device *pdev) dssdev->type = OMAP_DISPLAY_TYPE_HDMI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0);
dssdev->ops_flags = ddata->hpd_gpio ? OMAP_DSS_DEVICE_OP_DETECT : 0;
omapdss_display_init(dssdev); omapdss_device_register(dssdev);
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c index 545a06e6ca11..f37878ca6077 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c @@ -132,8 +132,9 @@ static bool tpd_detect(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); struct omap_dss_device *src = dssdev->src;
- bool connected = gpiod_get_value_cansleep(ddata->hpd_gpio);
bool connected;
connected = gpiod_get_value_cansleep(ddata->hpd_gpio); if (!connected && src->ops->hdmi.lost_hotplug) src->ops->hdmi.lost_hotplug(src); return connected;
@@ -288,6 +289,7 @@ static int tpd_probe(struct platform_device *pdev) dssdev->output_type = OMAP_DISPLAY_TYPE_HDMI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(1) | BIT(0);
dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT;
dssdev->next = omapdss_of_find_connected_device(pdev->dev.of_node, 1); if (IS_ERR(dssdev->next)) {
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c index a5e581c8c8d6..6c02c2492d47 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.c +++ b/drivers/gpu/drm/omapdrm/omap_connector.c @@ -61,26 +61,36 @@ static enum drm_connector_status omap_connector_detect( struct drm_connector *connector, bool force) { struct omap_connector *omap_connector = to_omap_connector(connector);
- struct omap_dss_device *dssdev = omap_connector->dssdev;
- enum drm_connector_status ret;
- struct omap_dss_device *dssdev;
- enum drm_connector_status status;
- for (dssdev = omap_connector->dssdev; dssdev; dssdev = dssdev->src) {
if (dssdev->ops_flags & OMAP_DSS_DEVICE_OP_DETECT)
break;
- }
- if (dssdev->ops->detect) {
- if (dssdev) { if (dssdev->ops->detect(dssdev))
ret = connector_status_connected;
elsestatus = connector_status_connected;
ret = connector_status_disconnected;
- } else if (dssdev->type == OMAP_DISPLAY_TYPE_DPI ||
dssdev->type == OMAP_DISPLAY_TYPE_DBI ||
dssdev->type == OMAP_DISPLAY_TYPE_SDI ||
dssdev->type == OMAP_DISPLAY_TYPE_DSI) {
ret = connector_status_connected;
} else {status = connector_status_disconnected;
ret = connector_status_unknown;
switch (omap_connector->dssdev->type) {
case OMAP_DISPLAY_TYPE_DPI:
case OMAP_DISPLAY_TYPE_DBI:
case OMAP_DISPLAY_TYPE_SDI:
case OMAP_DISPLAY_TYPE_DSI:
status = connector_status_connected;
break;
default:
status = connector_status_unknown;
break;
}}
- VERB("%s: %d (force=%d)", omap_connector->dssdev->name, ret, force);
- VERB("%s: %d (force=%d)", omap_connector->dssdev->name, status, force);
- return ret;
- return status;
}
static void omap_connector_destroy(struct drm_connector *connector)
Regards,
Laurent Pinchart
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Instead of calling the hot-plug detection callback registration operations (.register_hpd_cb() and .unregister_hpd_cb()) recursively from the display device back to the first device that provides hot plug detection support, iterate over the devices manually in the DRM connector code. This moves the complexity to a single central location and simplifies the logic in omap_dss_device drivers.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/omapdrm/displays/connector-dvi.c | 8 ++- drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 67 ++++++++---------- .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 3 +- drivers/gpu/drm/omapdrm/omap_connector.c | 79 ++++++++++++++-------- 4 files changed, 88 insertions(+), 69 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c index f1674b3eee50..e9353e4cd297 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c @@ -372,8 +372,12 @@ static int dvic_probe(struct platform_device *pdev) dssdev->type = OMAP_DISPLAY_TYPE_DVI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0); - dssdev->ops_flags = ddata->hpd_gpio || ddata->i2c_adapter - ? OMAP_DSS_DEVICE_OP_DETECT : 0; + + if (ddata->hpd_gpio) + dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT + | OMAP_DSS_DEVICE_OP_HPD; + else if (ddata->i2c_adapter) + dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT;
omapdss_display_init(dssdev); omapdss_device_register(dssdev); diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index 0d22d7004c98..8eae973474dd 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c @@ -153,62 +153,53 @@ static int hdmic_register_hpd_cb(struct omap_dss_device *dssdev, void *cb_data) { struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *src = dssdev->src;
- if (ddata->hpd_gpio) { - mutex_lock(&ddata->hpd_lock); - ddata->hpd_cb = cb; - ddata->hpd_cb_data = cb_data; - mutex_unlock(&ddata->hpd_lock); - return 0; - } else if (src->ops->register_hpd_cb) { - return src->ops->register_hpd_cb(src, cb, cb_data); - } + if (!ddata->hpd_gpio) + return -ENOTSUPP;
- return -ENOTSUPP; + mutex_lock(&ddata->hpd_lock); + ddata->hpd_cb = cb; + ddata->hpd_cb_data = cb_data; + mutex_unlock(&ddata->hpd_lock); + + return 0; }
static void hdmic_unregister_hpd_cb(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *src = dssdev->src;
- if (ddata->hpd_gpio) { - mutex_lock(&ddata->hpd_lock); - ddata->hpd_cb = NULL; - ddata->hpd_cb_data = NULL; - mutex_unlock(&ddata->hpd_lock); - } else if (src->ops->unregister_hpd_cb) { - src->ops->unregister_hpd_cb(src); - } + if (!ddata->hpd_gpio) + return; + + mutex_lock(&ddata->hpd_lock); + ddata->hpd_cb = NULL; + ddata->hpd_cb_data = NULL; + mutex_unlock(&ddata->hpd_lock); }
static void hdmic_enable_hpd(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *src = dssdev->src;
- if (ddata->hpd_gpio) { - mutex_lock(&ddata->hpd_lock); - ddata->hpd_enabled = true; - mutex_unlock(&ddata->hpd_lock); - } else if (src->ops->enable_hpd) { - src->ops->enable_hpd(src); - } + if (!ddata->hpd_gpio) + return; + + mutex_lock(&ddata->hpd_lock); + ddata->hpd_enabled = true; + mutex_unlock(&ddata->hpd_lock); }
static void hdmic_disable_hpd(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *src = dssdev->src;
- if (ddata->hpd_gpio) { - mutex_lock(&ddata->hpd_lock); - ddata->hpd_enabled = false; - mutex_unlock(&ddata->hpd_lock); - } else if (src->ops->disable_hpd) { - src->ops->disable_hpd(src); - } + if (!ddata->hpd_gpio) + return; + + mutex_lock(&ddata->hpd_lock); + ddata->hpd_enabled = false; + mutex_unlock(&ddata->hpd_lock); }
static int hdmic_set_hdmi_mode(struct omap_dss_device *dssdev, bool hdmi_mode) @@ -314,7 +305,9 @@ static int hdmic_probe(struct platform_device *pdev) dssdev->type = OMAP_DISPLAY_TYPE_HDMI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0); - dssdev->ops_flags = ddata->hpd_gpio ? OMAP_DSS_DEVICE_OP_DETECT : 0; + dssdev->ops_flags = ddata->hpd_gpio + ? OMAP_DSS_DEVICE_OP_DETECT | OMAP_DSS_DEVICE_OP_HPD + : 0;
omapdss_display_init(dssdev); omapdss_device_register(dssdev); diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c index f37878ca6077..e5a25baa0364 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c @@ -289,7 +289,8 @@ static int tpd_probe(struct platform_device *pdev) dssdev->output_type = OMAP_DISPLAY_TYPE_HDMI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(1) | BIT(0); - dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT; + dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT + | OMAP_DSS_DEVICE_OP_HPD;
dssdev->next = omapdss_of_find_connected_device(pdev->dev.of_node, 1); if (IS_ERR(dssdev->next)) { diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c index 6c02c2492d47..578b0b105755 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.c +++ b/drivers/gpu/drm/omapdrm/omap_connector.c @@ -57,6 +57,21 @@ bool omap_connector_get_hdmi_mode(struct drm_connector *connector) return omap_connector->hdmi_mode; }
+static struct omap_dss_device * +omap_connector_find_device(struct drm_connector *connector, + enum omap_dss_device_ops_flag op) +{ + struct omap_connector *omap_connector = to_omap_connector(connector); + struct omap_dss_device *dssdev; + + for (dssdev = omap_connector->dssdev; dssdev; dssdev = dssdev->src) { + if (dssdev->ops_flags & op) + return dssdev; + } + + return NULL; +} + static enum drm_connector_status omap_connector_detect( struct drm_connector *connector, bool force) { @@ -64,10 +79,8 @@ static enum drm_connector_status omap_connector_detect( struct omap_dss_device *dssdev; enum drm_connector_status status;
- for (dssdev = omap_connector->dssdev; dssdev; dssdev = dssdev->src) { - if (dssdev->ops_flags & OMAP_DSS_DEVICE_OP_DETECT) - break; - } + dssdev = omap_connector_find_device(connector, + OMAP_DSS_DEVICE_OP_DETECT);
if (dssdev) { if (dssdev->ops->detect(dssdev)) @@ -96,18 +109,21 @@ static enum drm_connector_status omap_connector_detect( static void omap_connector_destroy(struct drm_connector *connector) { struct omap_connector *omap_connector = to_omap_connector(connector); - struct omap_dss_device *dssdev = omap_connector->dssdev; + struct omap_dss_device *dssdev;
DBG("%s", omap_connector->dssdev->name); - if (connector->polled == DRM_CONNECTOR_POLL_HPD && - dssdev->ops->unregister_hpd_cb) { + + if (connector->polled == DRM_CONNECTOR_POLL_HPD) { + dssdev = omap_connector_find_device(connector, + OMAP_DSS_DEVICE_OP_HPD); dssdev->ops->unregister_hpd_cb(dssdev); } + drm_connector_unregister(connector); drm_connector_cleanup(connector); kfree(omap_connector);
- omapdss_device_put(dssdev); + omapdss_device_put(omap_connector->dssdev); }
#define MAX_EDID 512 @@ -258,45 +274,50 @@ struct drm_connector *omap_connector_init(struct drm_device *dev, { struct drm_connector *connector = NULL; struct omap_connector *omap_connector; - bool hpd_supported = false;
DBG("%s", dssdev->name);
- omapdss_device_get(dssdev); - omap_connector = kzalloc(sizeof(*omap_connector), GFP_KERNEL); if (!omap_connector) goto fail;
- omap_connector->dssdev = dssdev; + omap_connector->dssdev = omapdss_device_get(dssdev);
connector = &omap_connector->base; + connector->interlace_allowed = 1; + connector->doublescan_allowed = 0;
drm_connector_init(dev, connector, &omap_connector_funcs, connector_type); drm_connector_helper_add(connector, &omap_connector_helper_funcs);
- if (dssdev->ops->register_hpd_cb) { - int ret = dssdev->ops->register_hpd_cb(dssdev, - omap_connector_hpd_cb, - omap_connector); - if (!ret) - hpd_supported = true; - else if (ret != -ENOTSUPP) + /* + * Initialize connector status handling. First try to find a device that + * supports hot-plug reporting. If it fails, fall back to a device that + * support polling. If that fails too, we don't support hot-plug + * detection at all. + */ + dssdev = omap_connector_find_device(connector, OMAP_DSS_DEVICE_OP_HPD); + if (dssdev) { + int ret; + + ret = dssdev->ops->register_hpd_cb(dssdev, + omap_connector_hpd_cb, + omap_connector); + if (ret < 0) DBG("%s: Failed to register HPD callback (%d).", dssdev->name, ret); + else + connector->polled = DRM_CONNECTOR_POLL_HPD; }
- if (hpd_supported) - connector->polled = DRM_CONNECTOR_POLL_HPD; - else if (dssdev->ops->detect) - connector->polled = DRM_CONNECTOR_POLL_CONNECT | - DRM_CONNECTOR_POLL_DISCONNECT; - else - connector->polled = 0; - - connector->interlace_allowed = 1; - connector->doublescan_allowed = 0; + if (!connector->polled) { + dssdev = omap_connector_find_device(connector, + OMAP_DSS_DEVICE_OP_DETECT); + if (dssdev) + connector->polled = DRM_CONNECTOR_POLL_CONNECT | + DRM_CONNECTOR_POLL_DISCONNECT; + }
return connector;
Hi,
On Wed, Jun 06, 2018 at 12:36:43PM +0300, Laurent Pinchart wrote:
Instead of calling the hot-plug detection callback registration operations (.register_hpd_cb() and .unregister_hpd_cb()) recursively from the display device back to the first device that provides hot plug detection support, iterate over the devices manually in the DRM connector code. This moves the complexity to a single central location and simplifies the logic in omap_dss_device drivers.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com
Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.co.uk
-- Sebastian
drivers/gpu/drm/omapdrm/displays/connector-dvi.c | 8 ++- drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 67 ++++++++---------- .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 3 +- drivers/gpu/drm/omapdrm/omap_connector.c | 79 ++++++++++++++-------- 4 files changed, 88 insertions(+), 69 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c index f1674b3eee50..e9353e4cd297 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c @@ -372,8 +372,12 @@ static int dvic_probe(struct platform_device *pdev) dssdev->type = OMAP_DISPLAY_TYPE_DVI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0);
- dssdev->ops_flags = ddata->hpd_gpio || ddata->i2c_adapter
? OMAP_DSS_DEVICE_OP_DETECT : 0;
if (ddata->hpd_gpio)
dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT
| OMAP_DSS_DEVICE_OP_HPD;
else if (ddata->i2c_adapter)
dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT;
omapdss_display_init(dssdev); omapdss_device_register(dssdev);
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index 0d22d7004c98..8eae973474dd 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c @@ -153,62 +153,53 @@ static int hdmic_register_hpd_cb(struct omap_dss_device *dssdev, void *cb_data) { struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
if (ddata->hpd_gpio) {
mutex_lock(&ddata->hpd_lock);
ddata->hpd_cb = cb;
ddata->hpd_cb_data = cb_data;
mutex_unlock(&ddata->hpd_lock);
return 0;
} else if (src->ops->register_hpd_cb) {
return src->ops->register_hpd_cb(src, cb, cb_data);
}
- if (!ddata->hpd_gpio)
return -ENOTSUPP;
- return -ENOTSUPP;
- mutex_lock(&ddata->hpd_lock);
- ddata->hpd_cb = cb;
- ddata->hpd_cb_data = cb_data;
- mutex_unlock(&ddata->hpd_lock);
- return 0;
}
static void hdmic_unregister_hpd_cb(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
if (ddata->hpd_gpio) {
mutex_lock(&ddata->hpd_lock);
ddata->hpd_cb = NULL;
ddata->hpd_cb_data = NULL;
mutex_unlock(&ddata->hpd_lock);
} else if (src->ops->unregister_hpd_cb) {
src->ops->unregister_hpd_cb(src);
}
- if (!ddata->hpd_gpio)
return;
- mutex_lock(&ddata->hpd_lock);
- ddata->hpd_cb = NULL;
- ddata->hpd_cb_data = NULL;
- mutex_unlock(&ddata->hpd_lock);
}
static void hdmic_enable_hpd(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
if (ddata->hpd_gpio) {
mutex_lock(&ddata->hpd_lock);
ddata->hpd_enabled = true;
mutex_unlock(&ddata->hpd_lock);
} else if (src->ops->enable_hpd) {
src->ops->enable_hpd(src);
}
- if (!ddata->hpd_gpio)
return;
- mutex_lock(&ddata->hpd_lock);
- ddata->hpd_enabled = true;
- mutex_unlock(&ddata->hpd_lock);
}
static void hdmic_disable_hpd(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
if (ddata->hpd_gpio) {
mutex_lock(&ddata->hpd_lock);
ddata->hpd_enabled = false;
mutex_unlock(&ddata->hpd_lock);
} else if (src->ops->disable_hpd) {
src->ops->disable_hpd(src);
}
- if (!ddata->hpd_gpio)
return;
- mutex_lock(&ddata->hpd_lock);
- ddata->hpd_enabled = false;
- mutex_unlock(&ddata->hpd_lock);
}
static int hdmic_set_hdmi_mode(struct omap_dss_device *dssdev, bool hdmi_mode) @@ -314,7 +305,9 @@ static int hdmic_probe(struct platform_device *pdev) dssdev->type = OMAP_DISPLAY_TYPE_HDMI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(0);
- dssdev->ops_flags = ddata->hpd_gpio ? OMAP_DSS_DEVICE_OP_DETECT : 0;
dssdev->ops_flags = ddata->hpd_gpio
? OMAP_DSS_DEVICE_OP_DETECT | OMAP_DSS_DEVICE_OP_HPD
: 0;
omapdss_display_init(dssdev); omapdss_device_register(dssdev);
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c index f37878ca6077..e5a25baa0364 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c @@ -289,7 +289,8 @@ static int tpd_probe(struct platform_device *pdev) dssdev->output_type = OMAP_DISPLAY_TYPE_HDMI; dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(1) | BIT(0);
- dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT;
dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT
| OMAP_DSS_DEVICE_OP_HPD;
dssdev->next = omapdss_of_find_connected_device(pdev->dev.of_node, 1); if (IS_ERR(dssdev->next)) {
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c index 6c02c2492d47..578b0b105755 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.c +++ b/drivers/gpu/drm/omapdrm/omap_connector.c @@ -57,6 +57,21 @@ bool omap_connector_get_hdmi_mode(struct drm_connector *connector) return omap_connector->hdmi_mode; }
+static struct omap_dss_device * +omap_connector_find_device(struct drm_connector *connector,
enum omap_dss_device_ops_flag op)
+{
- struct omap_connector *omap_connector = to_omap_connector(connector);
- struct omap_dss_device *dssdev;
- for (dssdev = omap_connector->dssdev; dssdev; dssdev = dssdev->src) {
if (dssdev->ops_flags & op)
return dssdev;
- }
- return NULL;
+}
static enum drm_connector_status omap_connector_detect( struct drm_connector *connector, bool force) { @@ -64,10 +79,8 @@ static enum drm_connector_status omap_connector_detect( struct omap_dss_device *dssdev; enum drm_connector_status status;
- for (dssdev = omap_connector->dssdev; dssdev; dssdev = dssdev->src) {
if (dssdev->ops_flags & OMAP_DSS_DEVICE_OP_DETECT)
break;
- }
dssdev = omap_connector_find_device(connector,
OMAP_DSS_DEVICE_OP_DETECT);
if (dssdev) { if (dssdev->ops->detect(dssdev))
@@ -96,18 +109,21 @@ static enum drm_connector_status omap_connector_detect( static void omap_connector_destroy(struct drm_connector *connector) { struct omap_connector *omap_connector = to_omap_connector(connector);
- struct omap_dss_device *dssdev = omap_connector->dssdev;
struct omap_dss_device *dssdev;
DBG("%s", omap_connector->dssdev->name);
- if (connector->polled == DRM_CONNECTOR_POLL_HPD &&
dssdev->ops->unregister_hpd_cb) {
- if (connector->polled == DRM_CONNECTOR_POLL_HPD) {
dssdev = omap_connector_find_device(connector,
dssdev->ops->unregister_hpd_cb(dssdev); }OMAP_DSS_DEVICE_OP_HPD);
- drm_connector_unregister(connector); drm_connector_cleanup(connector); kfree(omap_connector);
- omapdss_device_put(dssdev);
- omapdss_device_put(omap_connector->dssdev);
}
#define MAX_EDID 512 @@ -258,45 +274,50 @@ struct drm_connector *omap_connector_init(struct drm_device *dev, { struct drm_connector *connector = NULL; struct omap_connector *omap_connector;
bool hpd_supported = false;
DBG("%s", dssdev->name);
omapdss_device_get(dssdev);
omap_connector = kzalloc(sizeof(*omap_connector), GFP_KERNEL); if (!omap_connector) goto fail;
omap_connector->dssdev = dssdev;
omap_connector->dssdev = omapdss_device_get(dssdev);
connector = &omap_connector->base;
connector->interlace_allowed = 1;
connector->doublescan_allowed = 0;
drm_connector_init(dev, connector, &omap_connector_funcs, connector_type); drm_connector_helper_add(connector, &omap_connector_helper_funcs);
- if (dssdev->ops->register_hpd_cb) {
int ret = dssdev->ops->register_hpd_cb(dssdev,
omap_connector_hpd_cb,
omap_connector);
if (!ret)
hpd_supported = true;
else if (ret != -ENOTSUPP)
- /*
* Initialize connector status handling. First try to find a device that
* supports hot-plug reporting. If it fails, fall back to a device that
* support polling. If that fails too, we don't support hot-plug
* detection at all.
*/
- dssdev = omap_connector_find_device(connector, OMAP_DSS_DEVICE_OP_HPD);
- if (dssdev) {
int ret;
ret = dssdev->ops->register_hpd_cb(dssdev,
omap_connector_hpd_cb,
omap_connector);
if (ret < 0) DBG("%s: Failed to register HPD callback (%d).", dssdev->name, ret);
else
}connector->polled = DRM_CONNECTOR_POLL_HPD;
- if (hpd_supported)
connector->polled = DRM_CONNECTOR_POLL_HPD;
- else if (dssdev->ops->detect)
connector->polled = DRM_CONNECTOR_POLL_CONNECT |
DRM_CONNECTOR_POLL_DISCONNECT;
- else
connector->polled = 0;
- connector->interlace_allowed = 1;
- connector->doublescan_allowed = 0;
if (!connector->polled) {
dssdev = omap_connector_find_device(connector,
OMAP_DSS_DEVICE_OP_DETECT);
if (dssdev)
connector->polled = DRM_CONNECTOR_POLL_CONNECT |
DRM_CONNECTOR_POLL_DISCONNECT;
}
return connector;
-- Regards,
Laurent Pinchart
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
The HPD-related omap_dss_device operations are now only called when the device supports HPD. There's no need to duplicate that check in the omap_dss_device drivers. The .register_hpd_cb() operation can as a result be turned into a void operation.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/omapdrm/displays/connector-dvi.c | 9 +-------- drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 14 +++----------- drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 8 +++----- drivers/gpu/drm/omapdrm/dss/omapdss.h | 6 +++--- drivers/gpu/drm/omapdrm/omap_connector.c | 17 ++++------------- 5 files changed, 14 insertions(+), 40 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c index e9353e4cd297..a53d5967e5a9 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c @@ -211,30 +211,23 @@ static bool dvic_detect(struct omap_dss_device *dssdev) return r == 0; }
-static int dvic_register_hpd_cb(struct omap_dss_device *dssdev, +static void dvic_register_hpd_cb(struct omap_dss_device *dssdev, void (*cb)(void *cb_data, enum drm_connector_status status), void *cb_data) { struct panel_drv_data *ddata = to_panel_data(dssdev);
- if (!ddata->hpd_gpio) - return -ENOTSUPP; - mutex_lock(&ddata->hpd_lock); ddata->hpd_cb = cb; ddata->hpd_cb_data = cb_data; mutex_unlock(&ddata->hpd_lock); - return 0; }
static void dvic_unregister_hpd_cb(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev);
- if (!ddata->hpd_gpio) - return; - mutex_lock(&ddata->hpd_lock); ddata->hpd_cb = NULL; ddata->hpd_cb_data = NULL; diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index 8eae973474dd..c58bf64d1a9b 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c @@ -147,31 +147,23 @@ static bool hdmic_detect(struct omap_dss_device *dssdev) return connected; }
-static int hdmic_register_hpd_cb(struct omap_dss_device *dssdev, - void (*cb)(void *cb_data, +static void hdmic_register_hpd_cb(struct omap_dss_device *dssdev, + void (*cb)(void *cb_data, enum drm_connector_status status), - void *cb_data) + void *cb_data) { struct panel_drv_data *ddata = to_panel_data(dssdev);
- if (!ddata->hpd_gpio) - return -ENOTSUPP; - mutex_lock(&ddata->hpd_lock); ddata->hpd_cb = cb; ddata->hpd_cb_data = cb_data; mutex_unlock(&ddata->hpd_lock); - - return 0; }
static void hdmic_unregister_hpd_cb(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev);
- if (!ddata->hpd_gpio) - return; - mutex_lock(&ddata->hpd_lock); ddata->hpd_cb = NULL; ddata->hpd_cb_data = NULL; diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c index e5a25baa0364..7a6cac5b29e1 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c @@ -140,10 +140,10 @@ static bool tpd_detect(struct omap_dss_device *dssdev) return connected; }
-static int tpd_register_hpd_cb(struct omap_dss_device *dssdev, - void (*cb)(void *cb_data, +static void tpd_register_hpd_cb(struct omap_dss_device *dssdev, + void (*cb)(void *cb_data, enum drm_connector_status status), - void *cb_data) + void *cb_data) { struct panel_drv_data *ddata = to_panel_data(dssdev);
@@ -151,8 +151,6 @@ static int tpd_register_hpd_cb(struct omap_dss_device *dssdev, ddata->hpd_cb = cb; ddata->hpd_cb_data = cb_data; mutex_unlock(&ddata->hpd_lock); - - return 0; }
static void tpd_unregister_hpd_cb(struct omap_dss_device *dssdev) diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index e9a47d8c0edc..d7e06883f95c 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -372,10 +372,10 @@ struct omap_dss_device_ops {
bool (*detect)(struct omap_dss_device *dssdev);
- int (*register_hpd_cb)(struct omap_dss_device *dssdev, - void (*cb)(void *cb_data, + void (*register_hpd_cb)(struct omap_dss_device *dssdev, + void (*cb)(void *cb_data, enum drm_connector_status status), - void *cb_data); + void *cb_data); void (*unregister_hpd_cb)(struct omap_dss_device *dssdev); void (*enable_hpd)(struct omap_dss_device *dssdev); void (*disable_hpd)(struct omap_dss_device *dssdev); diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c index 578b0b105755..ba9a3dfec33e 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.c +++ b/drivers/gpu/drm/omapdrm/omap_connector.c @@ -299,19 +299,10 @@ struct drm_connector *omap_connector_init(struct drm_device *dev, */ dssdev = omap_connector_find_device(connector, OMAP_DSS_DEVICE_OP_HPD); if (dssdev) { - int ret; - - ret = dssdev->ops->register_hpd_cb(dssdev, - omap_connector_hpd_cb, - omap_connector); - if (ret < 0) - DBG("%s: Failed to register HPD callback (%d).", - dssdev->name, ret); - else - connector->polled = DRM_CONNECTOR_POLL_HPD; - } - - if (!connector->polled) { + dssdev->ops->register_hpd_cb(dssdev, omap_connector_hpd_cb, + omap_connector); + connector->polled = DRM_CONNECTOR_POLL_HPD; + } else { dssdev = omap_connector_find_device(connector, OMAP_DSS_DEVICE_OP_DETECT); if (dssdev)
Hi,
On Wed, Jun 06, 2018 at 12:36:44PM +0300, Laurent Pinchart wrote:
The HPD-related omap_dss_device operations are now only called when the device supports HPD. There's no need to duplicate that check in the omap_dss_device drivers. The .register_hpd_cb() operation can as a result be turned into a void operation.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com
Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.co.uk
-- Sebastian
drivers/gpu/drm/omapdrm/displays/connector-dvi.c | 9 +-------- drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 14 +++----------- drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 8 +++----- drivers/gpu/drm/omapdrm/dss/omapdss.h | 6 +++--- drivers/gpu/drm/omapdrm/omap_connector.c | 17 ++++------------- 5 files changed, 14 insertions(+), 40 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c index e9353e4cd297..a53d5967e5a9 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c @@ -211,30 +211,23 @@ static bool dvic_detect(struct omap_dss_device *dssdev) return r == 0; }
-static int dvic_register_hpd_cb(struct omap_dss_device *dssdev, +static void dvic_register_hpd_cb(struct omap_dss_device *dssdev, void (*cb)(void *cb_data, enum drm_connector_status status), void *cb_data) { struct panel_drv_data *ddata = to_panel_data(dssdev);
- if (!ddata->hpd_gpio)
return -ENOTSUPP;
- mutex_lock(&ddata->hpd_lock); ddata->hpd_cb = cb; ddata->hpd_cb_data = cb_data; mutex_unlock(&ddata->hpd_lock);
- return 0;
}
static void dvic_unregister_hpd_cb(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev);
- if (!ddata->hpd_gpio)
return;
- mutex_lock(&ddata->hpd_lock); ddata->hpd_cb = NULL; ddata->hpd_cb_data = NULL;
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index 8eae973474dd..c58bf64d1a9b 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c @@ -147,31 +147,23 @@ static bool hdmic_detect(struct omap_dss_device *dssdev) return connected; }
-static int hdmic_register_hpd_cb(struct omap_dss_device *dssdev,
void (*cb)(void *cb_data,
+static void hdmic_register_hpd_cb(struct omap_dss_device *dssdev,
void (*cb)(void *cb_data, enum drm_connector_status status),
void *cb_data)
void *cb_data)
{ struct panel_drv_data *ddata = to_panel_data(dssdev);
- if (!ddata->hpd_gpio)
return -ENOTSUPP;
- mutex_lock(&ddata->hpd_lock); ddata->hpd_cb = cb; ddata->hpd_cb_data = cb_data; mutex_unlock(&ddata->hpd_lock);
- return 0;
}
static void hdmic_unregister_hpd_cb(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev);
- if (!ddata->hpd_gpio)
return;
- mutex_lock(&ddata->hpd_lock); ddata->hpd_cb = NULL; ddata->hpd_cb_data = NULL;
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c index e5a25baa0364..7a6cac5b29e1 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c @@ -140,10 +140,10 @@ static bool tpd_detect(struct omap_dss_device *dssdev) return connected; }
-static int tpd_register_hpd_cb(struct omap_dss_device *dssdev,
void (*cb)(void *cb_data,
+static void tpd_register_hpd_cb(struct omap_dss_device *dssdev,
void (*cb)(void *cb_data, enum drm_connector_status status),
void *cb_data)
void *cb_data)
{ struct panel_drv_data *ddata = to_panel_data(dssdev);
@@ -151,8 +151,6 @@ static int tpd_register_hpd_cb(struct omap_dss_device *dssdev, ddata->hpd_cb = cb; ddata->hpd_cb_data = cb_data; mutex_unlock(&ddata->hpd_lock);
- return 0;
}
static void tpd_unregister_hpd_cb(struct omap_dss_device *dssdev) diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index e9a47d8c0edc..d7e06883f95c 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -372,10 +372,10 @@ struct omap_dss_device_ops {
bool (*detect)(struct omap_dss_device *dssdev);
- int (*register_hpd_cb)(struct omap_dss_device *dssdev,
void (*cb)(void *cb_data,
- void (*register_hpd_cb)(struct omap_dss_device *dssdev,
void (*cb)(void *cb_data, enum drm_connector_status status),
void *cb_data);
void (*unregister_hpd_cb)(struct omap_dss_device *dssdev); void (*enable_hpd)(struct omap_dss_device *dssdev); void (*disable_hpd)(struct omap_dss_device *dssdev);void *cb_data);
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c index 578b0b105755..ba9a3dfec33e 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.c +++ b/drivers/gpu/drm/omapdrm/omap_connector.c @@ -299,19 +299,10 @@ struct drm_connector *omap_connector_init(struct drm_device *dev, */ dssdev = omap_connector_find_device(connector, OMAP_DSS_DEVICE_OP_HPD); if (dssdev) {
int ret;
ret = dssdev->ops->register_hpd_cb(dssdev,
omap_connector_hpd_cb,
omap_connector);
if (ret < 0)
DBG("%s: Failed to register HPD callback (%d).",
dssdev->name, ret);
else
connector->polled = DRM_CONNECTOR_POLL_HPD;
- }
- if (!connector->polled) {
dssdev->ops->register_hpd_cb(dssdev, omap_connector_hpd_cb,
omap_connector);
connector->polled = DRM_CONNECTOR_POLL_HPD;
- } else { dssdev = omap_connector_find_device(connector, OMAP_DSS_DEVICE_OP_DETECT); if (dssdev)
-- Regards,
Laurent Pinchart
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
The omap_dss_device .enable_hpd() and .disable_hpd() are used to enable and disable hot-plug detection at omapdrm probe and remove time. This is required to avoid reporting hot-plug detection events before the DRM infrastructure is ready to accept them, as that could result in crashes or other malfunction.
Hot-plug event reporting is conditioned by both HPD being enabled through the .enable_hpd() operation and by the HPD callback being registered though the .register_hpd_cb() operation. We thus don't need a separate enable operation if we can guarantee that callbacks won't be registered too early.
HPD callbacks are registered at connector initialization time, which is too early to start reporting HPD events. There's however nothing blocking a move of callback registration to a later time when the omapdrm driver calls the HPD enable operations. Do so, and remove the HPD enable operation completely from omap_dss_device drivers.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/omapdrm/displays/connector-dvi.c | 26 ----------------- drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 29 +----------------- .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 23 +-------------- drivers/gpu/drm/omapdrm/dss/omapdss.h | 2 -- drivers/gpu/drm/omapdrm/omap_connector.c | 34 +++++++++++++++++----- drivers/gpu/drm/omapdrm/omap_connector.h | 2 ++ drivers/gpu/drm/omapdrm/omap_drv.c | 16 +++------- 7 files changed, 35 insertions(+), 97 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c index a53d5967e5a9..6be260ff6458 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c @@ -234,30 +234,6 @@ static void dvic_unregister_hpd_cb(struct omap_dss_device *dssdev) mutex_unlock(&ddata->hpd_lock); }
-static void dvic_enable_hpd(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - - if (!ddata->hpd_gpio) - return; - - mutex_lock(&ddata->hpd_lock); - ddata->hpd_enabled = true; - mutex_unlock(&ddata->hpd_lock); -} - -static void dvic_disable_hpd(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - - if (!ddata->hpd_gpio) - return; - - mutex_lock(&ddata->hpd_lock); - ddata->hpd_enabled = false; - mutex_unlock(&ddata->hpd_lock); -} - static const struct omap_dss_device_ops dvic_ops = { .connect = dvic_connect, .disconnect = dvic_disconnect, @@ -274,8 +250,6 @@ static const struct omap_dss_device_ops dvic_ops = {
.register_hpd_cb = dvic_register_hpd_cb, .unregister_hpd_cb = dvic_unregister_hpd_cb, - .enable_hpd = dvic_enable_hpd, - .disable_hpd = dvic_disable_hpd, };
static irqreturn_t dvic_hpd_isr(int irq, void *data) diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index c58bf64d1a9b..84cc68388940 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c @@ -37,7 +37,6 @@ struct panel_drv_data { struct omap_dss_device dssdev; void (*hpd_cb)(void *cb_data, enum drm_connector_status status); void *hpd_cb_data; - bool hpd_enabled; struct mutex hpd_lock;
struct device *dev; @@ -170,30 +169,6 @@ static void hdmic_unregister_hpd_cb(struct omap_dss_device *dssdev) mutex_unlock(&ddata->hpd_lock); }
-static void hdmic_enable_hpd(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - - if (!ddata->hpd_gpio) - return; - - mutex_lock(&ddata->hpd_lock); - ddata->hpd_enabled = true; - mutex_unlock(&ddata->hpd_lock); -} - -static void hdmic_disable_hpd(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - - if (!ddata->hpd_gpio) - return; - - mutex_lock(&ddata->hpd_lock); - ddata->hpd_enabled = false; - mutex_unlock(&ddata->hpd_lock); -} - static int hdmic_set_hdmi_mode(struct omap_dss_device *dssdev, bool hdmi_mode) { struct omap_dss_device *src = dssdev->src; @@ -224,8 +199,6 @@ static const struct omap_dss_device_ops hdmic_ops = { .detect = hdmic_detect, .register_hpd_cb = hdmic_register_hpd_cb, .unregister_hpd_cb = hdmic_unregister_hpd_cb, - .enable_hpd = hdmic_enable_hpd, - .disable_hpd = hdmic_disable_hpd,
.hdmi = { .set_hdmi_mode = hdmic_set_hdmi_mode, @@ -238,7 +211,7 @@ static irqreturn_t hdmic_hpd_isr(int irq, void *data) struct panel_drv_data *ddata = data;
mutex_lock(&ddata->hpd_lock); - if (ddata->hpd_enabled && ddata->hpd_cb) { + if (ddata->hpd_cb) { enum drm_connector_status status;
if (hdmic_detect(&ddata->dssdev)) diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c index 7a6cac5b29e1..1fa1d332dbc4 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c @@ -23,7 +23,6 @@ struct panel_drv_data { struct omap_dss_device dssdev; void (*hpd_cb)(void *cb_data, enum drm_connector_status status); void *hpd_cb_data; - bool hpd_enabled; struct mutex hpd_lock;
struct gpio_desc *ct_cp_hpd_gpio; @@ -163,24 +162,6 @@ static void tpd_unregister_hpd_cb(struct omap_dss_device *dssdev) mutex_unlock(&ddata->hpd_lock); }
-static void tpd_enable_hpd(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - - mutex_lock(&ddata->hpd_lock); - ddata->hpd_enabled = true; - mutex_unlock(&ddata->hpd_lock); -} - -static void tpd_disable_hpd(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - - mutex_lock(&ddata->hpd_lock); - ddata->hpd_enabled = false; - mutex_unlock(&ddata->hpd_lock); -} - static int tpd_set_infoframe(struct omap_dss_device *dssdev, const struct hdmi_avi_infoframe *avi) { @@ -208,8 +189,6 @@ static const struct omap_dss_device_ops tpd_ops = { .detect = tpd_detect, .register_hpd_cb = tpd_register_hpd_cb, .unregister_hpd_cb = tpd_unregister_hpd_cb, - .enable_hpd = tpd_enable_hpd, - .disable_hpd = tpd_disable_hpd,
.hdmi = { .set_infoframe = tpd_set_infoframe, @@ -222,7 +201,7 @@ static irqreturn_t tpd_hpd_isr(int irq, void *data) struct panel_drv_data *ddata = data;
mutex_lock(&ddata->hpd_lock); - if (ddata->hpd_enabled && ddata->hpd_cb) { + if (ddata->hpd_cb) { enum drm_connector_status status;
if (tpd_detect(&ddata->dssdev)) diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index d7e06883f95c..7605563aa666 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -377,8 +377,6 @@ struct omap_dss_device_ops { enum drm_connector_status status), void *cb_data); void (*unregister_hpd_cb)(struct omap_dss_device *dssdev); - void (*enable_hpd)(struct omap_dss_device *dssdev); - void (*disable_hpd)(struct omap_dss_device *dssdev);
int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len);
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c index ba9a3dfec33e..56985c191740 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.c +++ b/drivers/gpu/drm/omapdrm/omap_connector.c @@ -30,6 +30,7 @@ struct omap_connector { struct drm_connector base; struct omap_dss_device *dssdev; + struct omap_dss_device *hpd; bool hdmi_mode; };
@@ -50,6 +51,25 @@ static void omap_connector_hpd_cb(void *cb_data, drm_kms_helper_hotplug_event(dev); }
+void omap_connector_enable_hpd(struct drm_connector *connector) +{ + struct omap_connector *omap_connector = to_omap_connector(connector); + struct omap_dss_device *hpd = omap_connector->hpd; + + if (hpd) + hpd->ops->register_hpd_cb(hpd, omap_connector_hpd_cb, + omap_connector); +} + +void omap_connector_disable_hpd(struct drm_connector *connector) +{ + struct omap_connector *omap_connector = to_omap_connector(connector); + struct omap_dss_device *hpd = omap_connector->hpd; + + if (hpd) + hpd->ops->unregister_hpd_cb(hpd); +} + bool omap_connector_get_hdmi_mode(struct drm_connector *connector) { struct omap_connector *omap_connector = to_omap_connector(connector); @@ -109,14 +129,15 @@ static enum drm_connector_status omap_connector_detect( static void omap_connector_destroy(struct drm_connector *connector) { struct omap_connector *omap_connector = to_omap_connector(connector); - struct omap_dss_device *dssdev;
DBG("%s", omap_connector->dssdev->name);
- if (connector->polled == DRM_CONNECTOR_POLL_HPD) { - dssdev = omap_connector_find_device(connector, - OMAP_DSS_DEVICE_OP_HPD); - dssdev->ops->unregister_hpd_cb(dssdev); + if (omap_connector->hpd) { + struct omap_dss_device *hpd = omap_connector->hpd; + + hpd->ops->unregister_hpd_cb(hpd); + omapdss_device_put(hpd); + omap_connector->hpd = NULL; }
drm_connector_unregister(connector); @@ -299,8 +320,7 @@ struct drm_connector *omap_connector_init(struct drm_device *dev, */ dssdev = omap_connector_find_device(connector, OMAP_DSS_DEVICE_OP_HPD); if (dssdev) { - dssdev->ops->register_hpd_cb(dssdev, omap_connector_hpd_cb, - omap_connector); + omap_connector->hpd = omapdss_device_get(dssdev); connector->polled = DRM_CONNECTOR_POLL_HPD; } else { dssdev = omap_connector_find_device(connector, diff --git a/drivers/gpu/drm/omapdrm/omap_connector.h b/drivers/gpu/drm/omapdrm/omap_connector.h index 98bbc779b302..465b3c9499d5 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.h +++ b/drivers/gpu/drm/omapdrm/omap_connector.h @@ -33,5 +33,7 @@ struct drm_connector *omap_connector_init(struct drm_device *dev, struct drm_encoder *omap_connector_attached_encoder( struct drm_connector *connector); bool omap_connector_get_hdmi_mode(struct drm_connector *connector); +void omap_connector_enable_hpd(struct drm_connector *connector); +void omap_connector_disable_hpd(struct drm_connector *connector);
#endif /* __OMAPDRM_CONNECTOR_H__ */ diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index 49771475f792..bbcd467cd83f 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -375,12 +375,8 @@ static void omap_modeset_enable_external_hpd(struct drm_device *ddev) struct omap_drm_private *priv = ddev->dev_private; int i;
- for (i = 0; i < priv->num_pipes; i++) { - struct omap_dss_device *display = priv->pipes[i].display; - - if (display->ops->enable_hpd) - display->ops->enable_hpd(display); - } + for (i = 0; i < priv->num_pipes; i++) + omap_connector_enable_hpd(priv->pipes[i].connector); }
/* @@ -391,12 +387,8 @@ static void omap_modeset_disable_external_hpd(struct drm_device *ddev) struct omap_drm_private *priv = ddev->dev_private; int i;
- for (i = 0; i < priv->num_pipes; i++) { - struct omap_dss_device *display = priv->pipes[i].display; - - if (display->ops->disable_hpd) - display->ops->disable_hpd(display); - } + for (i = 0; i < priv->num_pipes; i++) + omap_connector_enable_hpd(priv->pipes[i].connector); }
/*
Hi,
On Wed, Jun 06, 2018 at 12:36:45PM +0300, Laurent Pinchart wrote:
The omap_dss_device .enable_hpd() and .disable_hpd() are used to enable and disable hot-plug detection at omapdrm probe and remove time. This is required to avoid reporting hot-plug detection events before the DRM infrastructure is ready to accept them, as that could result in crashes or other malfunction.
Hot-plug event reporting is conditioned by both HPD being enabled through the .enable_hpd() operation and by the HPD callback being registered though the .register_hpd_cb() operation. We thus don't need a separate enable operation if we can guarantee that callbacks won't be registered too early.
HPD callbacks are registered at connector initialization time, which is too early to start reporting HPD events. There's however nothing blocking a move of callback registration to a later time when the omapdrm driver calls the HPD enable operations. Do so, and remove the HPD enable operation completely from omap_dss_device drivers.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com
[...]
@@ -391,12 +387,8 @@ static void omap_modeset_disable_external_hpd(struct drm_device *ddev) struct omap_drm_private *priv = ddev->dev_private; int i;
- for (i = 0; i < priv->num_pipes; i++) {
struct omap_dss_device *display = priv->pipes[i].display;
if (display->ops->disable_hpd)
display->ops->disable_hpd(display);
- }
- for (i = 0; i < priv->num_pipes; i++)
omap_connector_enable_hpd(priv->pipes[i].connector);
}
/*
omap_connector_disable_hpd... Otherwise:
Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.co.uk
-- Sebastian
On HDMI outputs, CEC support requires notification of HPD signal deassertion. The HPD signal can be handled by various omap_dss_device instances in the pipeline, and all of them forward HPD events to the OMAP4 internal HDMI encoder.
Knowledge of the DSS internals need to be removed from the omap_dss_device instances in order to migrate to drm_bridge. To do so, move HPD handling for CEC to the omap_connector.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 7 +---- .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 7 +---- drivers/gpu/drm/omapdrm/omap_connector.c | 33 ++++++++++++++++++---- 3 files changed, 29 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index 84cc68388940..6f2364afb14a 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c @@ -137,13 +137,8 @@ static int hdmic_read_edid(struct omap_dss_device *dssdev, static bool hdmic_detect(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *src = dssdev->src; - bool connected;
- connected = gpiod_get_value_cansleep(ddata->hpd_gpio); - if (!connected && src->ops->hdmi.lost_hotplug) - src->ops->hdmi.lost_hotplug(src); - return connected; + return gpiod_get_value_cansleep(ddata->hpd_gpio); }
static void hdmic_register_hpd_cb(struct omap_dss_device *dssdev, diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c index 1fa1d332dbc4..2772af84531a 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c @@ -130,13 +130,8 @@ static int tpd_read_edid(struct omap_dss_device *dssdev, static bool tpd_detect(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *src = dssdev->src; - bool connected;
- connected = gpiod_get_value_cansleep(ddata->hpd_gpio); - if (!connected && src->ops->hdmi.lost_hotplug) - src->ops->hdmi.lost_hotplug(src); - return connected; + return gpiod_get_value_cansleep(ddata->hpd_gpio); }
static void tpd_register_hpd_cb(struct omap_dss_device *dssdev, diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c index 56985c191740..1b3f85a02c85 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.c +++ b/drivers/gpu/drm/omapdrm/omap_connector.c @@ -34,6 +34,22 @@ struct omap_connector { bool hdmi_mode; };
+static void omap_connector_hpd_notify(struct drm_connector *connector, + struct omap_dss_device *src, + enum drm_connector_status status) +{ + if (status == connector_status_disconnected) { + /* + * If the source is an HDMI encoder, notify it of disconnection. + * This is required to let the HDMI encoder reset any internal + * state related to connection status, such as the CEC address. + */ + if (src && src->type == OMAP_DISPLAY_TYPE_HDMI && + src->ops->hdmi.lost_hotplug) + src->ops->hdmi.lost_hotplug(src); + } +} + static void omap_connector_hpd_cb(void *cb_data, enum drm_connector_status status) { @@ -47,8 +63,12 @@ static void omap_connector_hpd_cb(void *cb_data, connector->status = status; mutex_unlock(&dev->mode_config.mutex);
- if (old_status != status) - drm_kms_helper_hotplug_event(dev); + if (old_status == status) + return; + + omap_connector_hpd_notify(connector, omap_connector->hpd, status); + + drm_kms_helper_hotplug_event(dev); }
void omap_connector_enable_hpd(struct drm_connector *connector) @@ -103,10 +123,11 @@ static enum drm_connector_status omap_connector_detect( OMAP_DSS_DEVICE_OP_DETECT);
if (dssdev) { - if (dssdev->ops->detect(dssdev)) - status = connector_status_connected; - else - status = connector_status_disconnected; + status = dssdev->ops->detect(dssdev) + ? connector_status_connected + : connector_status_disconnected; + + omap_connector_hpd_notify(connector, dssdev->src, status); } else { switch (omap_connector->dssdev->type) { case OMAP_DISPLAY_TYPE_DPI:
Hi,
On Wed, Jun 06, 2018 at 12:36:46PM +0300, Laurent Pinchart wrote:
On HDMI outputs, CEC support requires notification of HPD signal deassertion. The HPD signal can be handled by various omap_dss_device instances in the pipeline, and all of them forward HPD events to the OMAP4 internal HDMI encoder.
Knowledge of the DSS internals need to be removed from the omap_dss_device instances in order to migrate to drm_bridge. To do so, move HPD handling for CEC to the omap_connector.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com
Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.co.uk
-- Sebastian
drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 7 +---- .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 7 +---- drivers/gpu/drm/omapdrm/omap_connector.c | 33 ++++++++++++++++++---- 3 files changed, 29 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index 84cc68388940..6f2364afb14a 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c @@ -137,13 +137,8 @@ static int hdmic_read_edid(struct omap_dss_device *dssdev, static bool hdmic_detect(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
bool connected;
connected = gpiod_get_value_cansleep(ddata->hpd_gpio);
if (!connected && src->ops->hdmi.lost_hotplug)
src->ops->hdmi.lost_hotplug(src);
return connected;
- return gpiod_get_value_cansleep(ddata->hpd_gpio);
}
static void hdmic_register_hpd_cb(struct omap_dss_device *dssdev, diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c index 1fa1d332dbc4..2772af84531a 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c @@ -130,13 +130,8 @@ static int tpd_read_edid(struct omap_dss_device *dssdev, static bool tpd_detect(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
bool connected;
connected = gpiod_get_value_cansleep(ddata->hpd_gpio);
if (!connected && src->ops->hdmi.lost_hotplug)
src->ops->hdmi.lost_hotplug(src);
return connected;
- return gpiod_get_value_cansleep(ddata->hpd_gpio);
}
static void tpd_register_hpd_cb(struct omap_dss_device *dssdev, diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c index 56985c191740..1b3f85a02c85 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.c +++ b/drivers/gpu/drm/omapdrm/omap_connector.c @@ -34,6 +34,22 @@ struct omap_connector { bool hdmi_mode; };
+static void omap_connector_hpd_notify(struct drm_connector *connector,
struct omap_dss_device *src,
enum drm_connector_status status)
+{
- if (status == connector_status_disconnected) {
/*
* If the source is an HDMI encoder, notify it of disconnection.
* This is required to let the HDMI encoder reset any internal
* state related to connection status, such as the CEC address.
*/
if (src && src->type == OMAP_DISPLAY_TYPE_HDMI &&
src->ops->hdmi.lost_hotplug)
src->ops->hdmi.lost_hotplug(src);
- }
+}
static void omap_connector_hpd_cb(void *cb_data, enum drm_connector_status status) { @@ -47,8 +63,12 @@ static void omap_connector_hpd_cb(void *cb_data, connector->status = status; mutex_unlock(&dev->mode_config.mutex);
- if (old_status != status)
drm_kms_helper_hotplug_event(dev);
- if (old_status == status)
return;
- omap_connector_hpd_notify(connector, omap_connector->hpd, status);
- drm_kms_helper_hotplug_event(dev);
}
void omap_connector_enable_hpd(struct drm_connector *connector) @@ -103,10 +123,11 @@ static enum drm_connector_status omap_connector_detect( OMAP_DSS_DEVICE_OP_DETECT);
if (dssdev) {
if (dssdev->ops->detect(dssdev))
status = connector_status_connected;
else
status = connector_status_disconnected;
status = dssdev->ops->detect(dssdev)
? connector_status_connected
: connector_status_disconnected;
} else { switch (omap_connector->dssdev->type) { case OMAP_DISPLAY_TYPE_DPI:omap_connector_hpd_notify(connector, dssdev->src, status);
-- Regards,
Laurent Pinchart
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Instead of calling the EDID read operation (.read_edid()) recursively from the display device back to the first device that provides EDID read support, iterate over the devices manually in the DRM connector code. This moves the complexity to a single central location and simplifies the logic in omap_dss_device drivers.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/omapdrm/displays/connector-dvi.c | 15 +-- drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 11 --- .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 13 --- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 1 + drivers/gpu/drm/omapdrm/dss/hdmi5.c | 1 + drivers/gpu/drm/omapdrm/omap_connector.c | 101 ++++++++++++--------- 6 files changed, 65 insertions(+), 77 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c index 6be260ff6458..eae4108330f1 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c @@ -166,12 +166,6 @@ static int dvic_read_edid(struct omap_dss_device *dssdev, struct panel_drv_data *ddata = to_panel_data(dssdev); int r, l, bytes_read;
- if (ddata->hpd_gpio && !gpiod_get_value_cansleep(ddata->hpd_gpio)) - return -ENODEV; - - if (!ddata->i2c_adapter) - return -ENODEV; - l = min(EDID_LENGTH, len); r = dvic_ddc_read(ddata->i2c_adapter, edid, l, 0); if (r) @@ -341,10 +335,11 @@ static int dvic_probe(struct platform_device *pdev) dssdev->of_ports = BIT(0);
if (ddata->hpd_gpio) - dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT - | OMAP_DSS_DEVICE_OP_HPD; - else if (ddata->i2c_adapter) - dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT; + dssdev->ops_flags |= OMAP_DSS_DEVICE_OP_DETECT + | OMAP_DSS_DEVICE_OP_HPD; + if (ddata->i2c_adapter) + dssdev->ops_flags |= OMAP_DSS_DEVICE_OP_DETECT + | OMAP_DSS_DEVICE_OP_EDID;
omapdss_display_init(dssdev); omapdss_device_register(dssdev); diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index 6f2364afb14a..16dc22edcb8e 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c @@ -15,8 +15,6 @@ #include <linux/platform_device.h> #include <linux/slab.h>
-#include <drm/drm_edid.h> - #include "../dss/omapdss.h"
static const struct videomode hdmic_default_vm = { @@ -126,14 +124,6 @@ static int hdmic_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); }
-static int hdmic_read_edid(struct omap_dss_device *dssdev, - u8 *edid, int len) -{ - struct omap_dss_device *src = dssdev->src; - - return src->ops->read_edid(src, edid, len); -} - static bool hdmic_detect(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); @@ -190,7 +180,6 @@ static const struct omap_dss_device_ops hdmic_ops = { .get_timings = hdmic_get_timings, .check_timings = hdmic_check_timings,
- .read_edid = hdmic_read_edid, .detect = hdmic_detect, .register_hpd_cb = hdmic_register_hpd_cb, .unregister_hpd_cb = hdmic_unregister_hpd_cb, diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c index 2772af84531a..dbbf9683bd51 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c @@ -115,18 +115,6 @@ static int tpd_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); }
-static int tpd_read_edid(struct omap_dss_device *dssdev, - u8 *edid, int len) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *src = dssdev->src; - - if (!gpiod_get_value_cansleep(ddata->hpd_gpio)) - return -ENODEV; - - return src->ops->read_edid(src, edid, len); -} - static bool tpd_detect(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); @@ -180,7 +168,6 @@ static const struct omap_dss_device_ops tpd_ops = { .disable = tpd_disable, .check_timings = tpd_check_timings, .set_timings = tpd_set_timings, - .read_edid = tpd_read_edid, .detect = tpd_detect, .register_hpd_cb = tpd_register_hpd_cb, .unregister_hpd_cb = tpd_unregister_hpd_cb, diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index bebce93fed3e..c92564300446 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -711,6 +711,7 @@ static int hdmi4_init_output(struct omap_hdmi *hdmi) out->ops = &hdmi_ops; out->owner = THIS_MODULE; out->of_ports = BIT(0); + out->ops_flags = OMAP_DSS_DEVICE_OP_EDID;
out->next = omapdss_of_find_connected_device(out->dev->of_node, 0); if (IS_ERR(out->next)) { diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c index 7c07e0208107..2aaa8ee61662 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c @@ -703,6 +703,7 @@ static int hdmi5_init_output(struct omap_hdmi *hdmi) out->ops = &hdmi_ops; out->owner = THIS_MODULE; out->of_ports = BIT(0); + out->ops_flags = OMAP_DSS_DEVICE_OP_EDID;
out->next = omapdss_of_find_connected_device(out->dev->of_node, 0); if (IS_ERR(out->next)) { diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c index 1b3f85a02c85..a1d379816732 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.c +++ b/drivers/gpu/drm/omapdrm/omap_connector.c @@ -170,65 +170,80 @@ static void omap_connector_destroy(struct drm_connector *connector)
#define MAX_EDID 512
+static int omap_connector_get_modes_edid(struct drm_connector *connector, + struct omap_dss_device *dssdev) +{ + struct omap_connector *omap_connector = to_omap_connector(connector); + enum drm_connector_status status; + void *edid; + int n; + + status = omap_connector_detect(connector, false); + if (status != connector_status_connected) + goto no_edid; + + edid = kzalloc(MAX_EDID, GFP_KERNEL); + if (!edid) + goto no_edid; + + if (dssdev->ops->read_edid(dssdev, edid, MAX_EDID) <= 0 || + !drm_edid_is_valid(edid)) { + kfree(edid); + goto no_edid; + } + + drm_mode_connector_update_edid_property(connector, edid); + n = drm_add_edid_modes(connector, edid); + + omap_connector->hdmi_mode = drm_detect_hdmi_monitor(edid); + + kfree(edid); + return n; + +no_edid: + drm_mode_connector_update_edid_property(connector, NULL); + return 0; +} + static int omap_connector_get_modes(struct drm_connector *connector) { struct omap_connector *omap_connector = to_omap_connector(connector); - struct omap_dss_device *dssdev = omap_connector->dssdev; - struct drm_device *dev = connector->dev; - int n = 0; + struct omap_dss_device *dssdev; + struct drm_display_mode *mode; + struct videomode vm = {0};
DBG("%s", omap_connector->dssdev->name);
- /* if display exposes EDID, then we parse that in the normal way to - * build table of supported modes.. otherwise (ie. fixed resolution + /* + * If display exposes EDID, then we parse that in the normal way to + * build table of supported modes. Otherwise (ie. fixed resolution * LCD panels) we just return a single mode corresponding to the - * currently configured timings: + * currently configured timings. */ - if (dssdev->ops->read_edid) { - void *edid = kzalloc(MAX_EDID, GFP_KERNEL); - - if (!edid) - return 0; - - if ((dssdev->ops->read_edid(dssdev, edid, MAX_EDID) > 0) && - drm_edid_is_valid(edid)) { - drm_mode_connector_update_edid_property( - connector, edid); - n = drm_add_edid_modes(connector, edid); - - omap_connector->hdmi_mode = - drm_detect_hdmi_monitor(edid); - } else { - drm_mode_connector_update_edid_property( - connector, NULL); - } - - kfree(edid); - } else { - struct drm_display_mode *mode = drm_mode_create(dev); - struct videomode vm = {0}; + dssdev = omap_connector_find_device(connector, + OMAP_DSS_DEVICE_OP_EDID); + if (dssdev) + return omap_connector_get_modes_edid(connector, dssdev);
- if (!mode) - return 0; + mode = drm_mode_create(connector->dev); + if (!mode) + return 0;
- dssdev->ops->get_timings(dssdev, &vm); + dssdev = omap_connector->dssdev; + dssdev->ops->get_timings(dssdev, &vm);
- drm_display_mode_from_videomode(&vm, mode); + drm_display_mode_from_videomode(&vm, mode);
- mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; - drm_mode_set_name(mode); - drm_mode_probed_add(connector, mode); + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; + drm_mode_set_name(mode); + drm_mode_probed_add(connector, mode);
- if (dssdev->driver && dssdev->driver->get_size) { - dssdev->driver->get_size(dssdev, + if (dssdev->driver && dssdev->driver->get_size) + dssdev->driver->get_size(dssdev, &connector->display_info.width_mm, &connector->display_info.height_mm); - }
- n = 1; - } - - return n; + return 1; }
static int omap_connector_mode_valid(struct drm_connector *connector,
Hi,
On Wed, Jun 06, 2018 at 12:36:47PM +0300, Laurent Pinchart wrote:
Instead of calling the EDID read operation (.read_edid()) recursively from the display device back to the first device that provides EDID read support, iterate over the devices manually in the DRM connector code. This moves the complexity to a single central location and simplifies the logic in omap_dss_device drivers.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com
Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.co.uk
-- Sebastian
drivers/gpu/drm/omapdrm/displays/connector-dvi.c | 15 +-- drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 11 --- .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 13 --- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 1 + drivers/gpu/drm/omapdrm/dss/hdmi5.c | 1 + drivers/gpu/drm/omapdrm/omap_connector.c | 101 ++++++++++++--------- 6 files changed, 65 insertions(+), 77 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c index 6be260ff6458..eae4108330f1 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c @@ -166,12 +166,6 @@ static int dvic_read_edid(struct omap_dss_device *dssdev, struct panel_drv_data *ddata = to_panel_data(dssdev); int r, l, bytes_read;
- if (ddata->hpd_gpio && !gpiod_get_value_cansleep(ddata->hpd_gpio))
return -ENODEV;
- if (!ddata->i2c_adapter)
return -ENODEV;
- l = min(EDID_LENGTH, len); r = dvic_ddc_read(ddata->i2c_adapter, edid, l, 0); if (r)
@@ -341,10 +335,11 @@ static int dvic_probe(struct platform_device *pdev) dssdev->of_ports = BIT(0);
if (ddata->hpd_gpio)
dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT
| OMAP_DSS_DEVICE_OP_HPD;
- else if (ddata->i2c_adapter)
dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT;
dssdev->ops_flags |= OMAP_DSS_DEVICE_OP_DETECT
| OMAP_DSS_DEVICE_OP_HPD;
if (ddata->i2c_adapter)
dssdev->ops_flags |= OMAP_DSS_DEVICE_OP_DETECT
| OMAP_DSS_DEVICE_OP_EDID;
omapdss_display_init(dssdev); omapdss_device_register(dssdev);
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index 6f2364afb14a..16dc22edcb8e 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c @@ -15,8 +15,6 @@ #include <linux/platform_device.h> #include <linux/slab.h>
-#include <drm/drm_edid.h>
#include "../dss/omapdss.h"
static const struct videomode hdmic_default_vm = { @@ -126,14 +124,6 @@ static int hdmic_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); }
-static int hdmic_read_edid(struct omap_dss_device *dssdev,
u8 *edid, int len)
-{
- struct omap_dss_device *src = dssdev->src;
- return src->ops->read_edid(src, edid, len);
-}
static bool hdmic_detect(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); @@ -190,7 +180,6 @@ static const struct omap_dss_device_ops hdmic_ops = { .get_timings = hdmic_get_timings, .check_timings = hdmic_check_timings,
- .read_edid = hdmic_read_edid, .detect = hdmic_detect, .register_hpd_cb = hdmic_register_hpd_cb, .unregister_hpd_cb = hdmic_unregister_hpd_cb,
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c index 2772af84531a..dbbf9683bd51 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c @@ -115,18 +115,6 @@ static int tpd_check_timings(struct omap_dss_device *dssdev, return src->ops->check_timings(src, vm); }
-static int tpd_read_edid(struct omap_dss_device *dssdev,
u8 *edid, int len)
-{
- struct panel_drv_data *ddata = to_panel_data(dssdev);
- struct omap_dss_device *src = dssdev->src;
- if (!gpiod_get_value_cansleep(ddata->hpd_gpio))
return -ENODEV;
- return src->ops->read_edid(src, edid, len);
-}
static bool tpd_detect(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); @@ -180,7 +168,6 @@ static const struct omap_dss_device_ops tpd_ops = { .disable = tpd_disable, .check_timings = tpd_check_timings, .set_timings = tpd_set_timings,
- .read_edid = tpd_read_edid, .detect = tpd_detect, .register_hpd_cb = tpd_register_hpd_cb, .unregister_hpd_cb = tpd_unregister_hpd_cb,
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index bebce93fed3e..c92564300446 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -711,6 +711,7 @@ static int hdmi4_init_output(struct omap_hdmi *hdmi) out->ops = &hdmi_ops; out->owner = THIS_MODULE; out->of_ports = BIT(0);
out->ops_flags = OMAP_DSS_DEVICE_OP_EDID;
out->next = omapdss_of_find_connected_device(out->dev->of_node, 0); if (IS_ERR(out->next)) {
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c index 7c07e0208107..2aaa8ee61662 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c @@ -703,6 +703,7 @@ static int hdmi5_init_output(struct omap_hdmi *hdmi) out->ops = &hdmi_ops; out->owner = THIS_MODULE; out->of_ports = BIT(0);
out->ops_flags = OMAP_DSS_DEVICE_OP_EDID;
out->next = omapdss_of_find_connected_device(out->dev->of_node, 0); if (IS_ERR(out->next)) {
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c index 1b3f85a02c85..a1d379816732 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.c +++ b/drivers/gpu/drm/omapdrm/omap_connector.c @@ -170,65 +170,80 @@ static void omap_connector_destroy(struct drm_connector *connector)
#define MAX_EDID 512
+static int omap_connector_get_modes_edid(struct drm_connector *connector,
struct omap_dss_device *dssdev)
+{
- struct omap_connector *omap_connector = to_omap_connector(connector);
- enum drm_connector_status status;
- void *edid;
- int n;
- status = omap_connector_detect(connector, false);
- if (status != connector_status_connected)
goto no_edid;
- edid = kzalloc(MAX_EDID, GFP_KERNEL);
- if (!edid)
goto no_edid;
- if (dssdev->ops->read_edid(dssdev, edid, MAX_EDID) <= 0 ||
!drm_edid_is_valid(edid)) {
kfree(edid);
goto no_edid;
- }
- drm_mode_connector_update_edid_property(connector, edid);
- n = drm_add_edid_modes(connector, edid);
- omap_connector->hdmi_mode = drm_detect_hdmi_monitor(edid);
- kfree(edid);
- return n;
+no_edid:
- drm_mode_connector_update_edid_property(connector, NULL);
- return 0;
+}
static int omap_connector_get_modes(struct drm_connector *connector) { struct omap_connector *omap_connector = to_omap_connector(connector);
- struct omap_dss_device *dssdev = omap_connector->dssdev;
- struct drm_device *dev = connector->dev;
- int n = 0;
struct omap_dss_device *dssdev;
struct drm_display_mode *mode;
struct videomode vm = {0};
DBG("%s", omap_connector->dssdev->name);
- /* if display exposes EDID, then we parse that in the normal way to
* build table of supported modes.. otherwise (ie. fixed resolution
- /*
* If display exposes EDID, then we parse that in the normal way to
* build table of supported modes. Otherwise (ie. fixed resolution
- LCD panels) we just return a single mode corresponding to the
* currently configured timings:
*/* currently configured timings.
- if (dssdev->ops->read_edid) {
void *edid = kzalloc(MAX_EDID, GFP_KERNEL);
if (!edid)
return 0;
if ((dssdev->ops->read_edid(dssdev, edid, MAX_EDID) > 0) &&
drm_edid_is_valid(edid)) {
drm_mode_connector_update_edid_property(
connector, edid);
n = drm_add_edid_modes(connector, edid);
omap_connector->hdmi_mode =
drm_detect_hdmi_monitor(edid);
} else {
drm_mode_connector_update_edid_property(
connector, NULL);
}
kfree(edid);
- } else {
struct drm_display_mode *mode = drm_mode_create(dev);
struct videomode vm = {0};
- dssdev = omap_connector_find_device(connector,
OMAP_DSS_DEVICE_OP_EDID);
- if (dssdev)
return omap_connector_get_modes_edid(connector, dssdev);
if (!mode)
return 0;
- mode = drm_mode_create(connector->dev);
- if (!mode)
return 0;
dssdev->ops->get_timings(dssdev, &vm);
- dssdev = omap_connector->dssdev;
- dssdev->ops->get_timings(dssdev, &vm);
drm_display_mode_from_videomode(&vm, mode);
- drm_display_mode_from_videomode(&vm, mode);
mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
drm_mode_set_name(mode);
drm_mode_probed_add(connector, mode);
- mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
- drm_mode_set_name(mode);
- drm_mode_probed_add(connector, mode);
if (dssdev->driver && dssdev->driver->get_size) {
dssdev->driver->get_size(dssdev,
- if (dssdev->driver && dssdev->driver->get_size)
dssdev->driver->get_size(dssdev, &connector->display_info.width_mm, &connector->display_info.height_mm);
}
n = 1;
}
return n;
- return 1;
}
static int omap_connector_mode_valid(struct drm_connector *connector,
Regards,
Laurent Pinchart
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
The CRTC mode set implementation needs to access the omap_dss_device for the pipeline display. To do so, it iterates over all pipelines to find the one that contains an encoder corresponding to the CRTC, and request the display device from the encoder. That's a very complicated dance when the CRTC has a direct pipeline pointer already, and the pipeline contains a pointer to the display device.
Replace the convoluted code with direct access.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/omapdrm/omap_crtc.c | 25 ++++--------------------- drivers/gpu/drm/omapdrm/omap_encoder.c | 7 ------- drivers/gpu/drm/omapdrm/omap_encoder.h | 3 --- 3 files changed, 4 insertions(+), 31 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 197d05312306..6e7a777907f5 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -419,12 +419,12 @@ static enum drm_mode_status omap_crtc_mode_valid(struct drm_crtc *crtc, static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc) { struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + struct omap_dss_device *display = omap_crtc->pipe->display; struct drm_display_mode *mode = &crtc->state->adjusted_mode; - struct omap_drm_private *priv = crtc->dev->dev_private; const u32 flags_mask = DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_DE_LOW | DISPLAY_FLAGS_PIXDATA_POSEDGE | DISPLAY_FLAGS_PIXDATA_NEGEDGE | DISPLAY_FLAGS_SYNC_POSEDGE | DISPLAY_FLAGS_SYNC_NEGEDGE; - unsigned int i; + struct videomode vm = {0};
DBG("%s: set mode: %d:"%s" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", omap_crtc->name, mode->base.id, mode->name, @@ -447,25 +447,8 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc) * has been changed to the DRM model. */
- for (i = 0; i < priv->num_pipes; ++i) { - struct drm_encoder *encoder = priv->pipes[i].encoder; - - if (encoder->crtc == crtc) { - struct omap_dss_device *dssdev; - - dssdev = omap_encoder_get_dssdev(encoder); - - if (dssdev) { - struct videomode vm = {0}; - - dssdev->ops->get_timings(dssdev, &vm); - - omap_crtc->vm.flags |= vm.flags & flags_mask; - } - - break; - } - } + display->ops->get_timings(display, &vm); + omap_crtc->vm.flags |= vm.flags & flags_mask; }
static int omap_crtc_atomic_check(struct drm_crtc *crtc, diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c index 7bbf3700e393..87e2b3799a45 100644 --- a/drivers/gpu/drm/omapdrm/omap_encoder.c +++ b/drivers/gpu/drm/omapdrm/omap_encoder.c @@ -39,13 +39,6 @@ struct omap_encoder { struct omap_dss_device *dssdev; };
-struct omap_dss_device *omap_encoder_get_dssdev(struct drm_encoder *encoder) -{ - struct omap_encoder *omap_encoder = to_omap_encoder(encoder); - - return omap_encoder->dssdev; -} - static void omap_encoder_destroy(struct drm_encoder *encoder) { struct omap_encoder *omap_encoder = to_omap_encoder(encoder); diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.h b/drivers/gpu/drm/omapdrm/omap_encoder.h index d2f308bec494..e8f1a35dce2f 100644 --- a/drivers/gpu/drm/omapdrm/omap_encoder.h +++ b/drivers/gpu/drm/omapdrm/omap_encoder.h @@ -27,7 +27,4 @@ struct omap_dss_device; struct drm_encoder *omap_encoder_init(struct drm_device *dev, struct omap_dss_device *dssdev);
-/* map crtc to vblank mask */ -struct omap_dss_device *omap_encoder_get_dssdev(struct drm_encoder *encoder); - #endif /* __OMAPDRM_ENCODER_H__ */
Hi,
On Wed, Jun 06, 2018 at 12:36:48PM +0300, Laurent Pinchart wrote:
The CRTC mode set implementation needs to access the omap_dss_device for the pipeline display. To do so, it iterates over all pipelines to find the one that contains an encoder corresponding to the CRTC, and request the display device from the encoder. That's a very complicated dance when the CRTC has a direct pipeline pointer already, and the pipeline contains a pointer to the display device.
Replace the convoluted code with direct access.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com
Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.co.uk
-- Sebastian
drivers/gpu/drm/omapdrm/omap_crtc.c | 25 ++++--------------------- drivers/gpu/drm/omapdrm/omap_encoder.c | 7 ------- drivers/gpu/drm/omapdrm/omap_encoder.h | 3 --- 3 files changed, 4 insertions(+), 31 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 197d05312306..6e7a777907f5 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -419,12 +419,12 @@ static enum drm_mode_status omap_crtc_mode_valid(struct drm_crtc *crtc, static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc) { struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
- struct omap_dss_device *display = omap_crtc->pipe->display; struct drm_display_mode *mode = &crtc->state->adjusted_mode;
- struct omap_drm_private *priv = crtc->dev->dev_private; const u32 flags_mask = DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_DE_LOW | DISPLAY_FLAGS_PIXDATA_POSEDGE | DISPLAY_FLAGS_PIXDATA_NEGEDGE | DISPLAY_FLAGS_SYNC_POSEDGE | DISPLAY_FLAGS_SYNC_NEGEDGE;
- unsigned int i;
struct videomode vm = {0};
DBG("%s: set mode: %d:"%s" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", omap_crtc->name, mode->base.id, mode->name,
@@ -447,25 +447,8 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc) * has been changed to the DRM model. */
- for (i = 0; i < priv->num_pipes; ++i) {
struct drm_encoder *encoder = priv->pipes[i].encoder;
if (encoder->crtc == crtc) {
struct omap_dss_device *dssdev;
dssdev = omap_encoder_get_dssdev(encoder);
if (dssdev) {
struct videomode vm = {0};
dssdev->ops->get_timings(dssdev, &vm);
omap_crtc->vm.flags |= vm.flags & flags_mask;
}
break;
}
- }
- display->ops->get_timings(display, &vm);
- omap_crtc->vm.flags |= vm.flags & flags_mask;
}
static int omap_crtc_atomic_check(struct drm_crtc *crtc, diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c index 7bbf3700e393..87e2b3799a45 100644 --- a/drivers/gpu/drm/omapdrm/omap_encoder.c +++ b/drivers/gpu/drm/omapdrm/omap_encoder.c @@ -39,13 +39,6 @@ struct omap_encoder { struct omap_dss_device *dssdev; };
-struct omap_dss_device *omap_encoder_get_dssdev(struct drm_encoder *encoder) -{
- struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
- return omap_encoder->dssdev;
-}
static void omap_encoder_destroy(struct drm_encoder *encoder) { struct omap_encoder *omap_encoder = to_omap_encoder(encoder); diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.h b/drivers/gpu/drm/omapdrm/omap_encoder.h index d2f308bec494..e8f1a35dce2f 100644 --- a/drivers/gpu/drm/omapdrm/omap_encoder.h +++ b/drivers/gpu/drm/omapdrm/omap_encoder.h @@ -27,7 +27,4 @@ struct omap_dss_device; struct drm_encoder *omap_encoder_init(struct drm_device *dev, struct omap_dss_device *dssdev);
-/* map crtc to vblank mask */ -struct omap_dss_device *omap_encoder_get_dssdev(struct drm_encoder *encoder);
#endif /* __OMAPDRM_ENCODER_H__ */
Regards,
Laurent Pinchart
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
The drm_encoder implementation requires access to the omap_dss_device corresponding to the display, which is passed to its initialization function and stored internally. Clean up of the HDMI mode and infoframe handling will require access to the output omap_dss_device. To prepare for that, pass it to the encoder initialization function and store it internally as well.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/omapdrm/omap_drv.c | 2 +- drivers/gpu/drm/omapdrm/omap_encoder.c | 17 ++++++++++------- drivers/gpu/drm/omapdrm/omap_encoder.h | 3 ++- 3 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index bbcd467cd83f..49cd7609fa3b 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -318,7 +318,7 @@ static int omap_modeset_init(struct drm_device *dev) struct drm_encoder *encoder; struct drm_crtc *crtc;
- encoder = omap_encoder_init(dev, display); + encoder = omap_encoder_init(dev, pipe->output, display); if (!encoder) return -ENOMEM;
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c index 87e2b3799a45..2689ae74ea60 100644 --- a/drivers/gpu/drm/omapdrm/omap_encoder.c +++ b/drivers/gpu/drm/omapdrm/omap_encoder.c @@ -36,7 +36,8 @@ */ struct omap_encoder { struct drm_encoder base; - struct omap_dss_device *dssdev; + struct omap_dss_device *output; + struct omap_dss_device *display; };
static void omap_encoder_destroy(struct drm_encoder *encoder) @@ -57,7 +58,7 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder, { struct drm_device *dev = encoder->dev; struct omap_encoder *omap_encoder = to_omap_encoder(encoder); - struct omap_dss_device *dssdev = omap_encoder->dssdev; + struct omap_dss_device *dssdev = omap_encoder->display; struct drm_connector *connector; bool hdmi_mode; int r; @@ -86,7 +87,7 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder, static void omap_encoder_disable(struct drm_encoder *encoder) { struct omap_encoder *omap_encoder = to_omap_encoder(encoder); - struct omap_dss_device *dssdev = omap_encoder->dssdev; + struct omap_dss_device *dssdev = omap_encoder->display;
dssdev->ops->disable(dssdev); } @@ -97,7 +98,7 @@ static int omap_encoder_update(struct drm_encoder *encoder, { struct drm_device *dev = encoder->dev; struct omap_encoder *omap_encoder = to_omap_encoder(encoder); - struct omap_dss_device *dssdev = omap_encoder->dssdev; + struct omap_dss_device *dssdev = omap_encoder->display; int ret;
if (dssdev->ops->check_timings) { @@ -127,7 +128,7 @@ static int omap_encoder_update(struct drm_encoder *encoder, static void omap_encoder_enable(struct drm_encoder *encoder) { struct omap_encoder *omap_encoder = to_omap_encoder(encoder); - struct omap_dss_device *dssdev = omap_encoder->dssdev; + struct omap_dss_device *dssdev = omap_encoder->display; int r;
omap_encoder_update(encoder, omap_crtc_channel(encoder->crtc), @@ -156,7 +157,8 @@ static const struct drm_encoder_helper_funcs omap_encoder_helper_funcs = {
/* initialize encoder */ struct drm_encoder *omap_encoder_init(struct drm_device *dev, - struct omap_dss_device *dssdev) + struct omap_dss_device *output, + struct omap_dss_device *display) { struct drm_encoder *encoder = NULL; struct omap_encoder *omap_encoder; @@ -165,7 +167,8 @@ struct drm_encoder *omap_encoder_init(struct drm_device *dev, if (!omap_encoder) goto fail;
- omap_encoder->dssdev = dssdev; + omap_encoder->output = output; + omap_encoder->display = display;
encoder = &omap_encoder->base;
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.h b/drivers/gpu/drm/omapdrm/omap_encoder.h index e8f1a35dce2f..a7b5dde63ecb 100644 --- a/drivers/gpu/drm/omapdrm/omap_encoder.h +++ b/drivers/gpu/drm/omapdrm/omap_encoder.h @@ -25,6 +25,7 @@ struct drm_encoder; struct omap_dss_device;
struct drm_encoder *omap_encoder_init(struct drm_device *dev, - struct omap_dss_device *dssdev); + struct omap_dss_device *output, + struct omap_dss_device *display);
#endif /* __OMAPDRM_ENCODER_H__ */
Hi,
On Wed, Jun 06, 2018 at 12:36:49PM +0300, Laurent Pinchart wrote:
The drm_encoder implementation requires access to the omap_dss_device corresponding to the display, which is passed to its initialization function and stored internally. Clean up of the HDMI mode and infoframe handling will require access to the output omap_dss_device. To prepare for that, pass it to the encoder initialization function and store it internally as well.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com
Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.co.uk
-- Sebastian
drivers/gpu/drm/omapdrm/omap_drv.c | 2 +- drivers/gpu/drm/omapdrm/omap_encoder.c | 17 ++++++++++------- drivers/gpu/drm/omapdrm/omap_encoder.h | 3 ++- 3 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index bbcd467cd83f..49cd7609fa3b 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -318,7 +318,7 @@ static int omap_modeset_init(struct drm_device *dev) struct drm_encoder *encoder; struct drm_crtc *crtc;
encoder = omap_encoder_init(dev, display);
if (!encoder) return -ENOMEM;encoder = omap_encoder_init(dev, pipe->output, display);
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c index 87e2b3799a45..2689ae74ea60 100644 --- a/drivers/gpu/drm/omapdrm/omap_encoder.c +++ b/drivers/gpu/drm/omapdrm/omap_encoder.c @@ -36,7 +36,8 @@ */ struct omap_encoder { struct drm_encoder base;
- struct omap_dss_device *dssdev;
- struct omap_dss_device *output;
- struct omap_dss_device *display;
};
static void omap_encoder_destroy(struct drm_encoder *encoder) @@ -57,7 +58,7 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder, { struct drm_device *dev = encoder->dev; struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
- struct omap_dss_device *dssdev = omap_encoder->dssdev;
- struct omap_dss_device *dssdev = omap_encoder->display; struct drm_connector *connector; bool hdmi_mode; int r;
@@ -86,7 +87,7 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder, static void omap_encoder_disable(struct drm_encoder *encoder) { struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
- struct omap_dss_device *dssdev = omap_encoder->dssdev;
struct omap_dss_device *dssdev = omap_encoder->display;
dssdev->ops->disable(dssdev);
} @@ -97,7 +98,7 @@ static int omap_encoder_update(struct drm_encoder *encoder, { struct drm_device *dev = encoder->dev; struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
- struct omap_dss_device *dssdev = omap_encoder->dssdev;
struct omap_dss_device *dssdev = omap_encoder->display; int ret;
if (dssdev->ops->check_timings) {
@@ -127,7 +128,7 @@ static int omap_encoder_update(struct drm_encoder *encoder, static void omap_encoder_enable(struct drm_encoder *encoder) { struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
- struct omap_dss_device *dssdev = omap_encoder->dssdev;
struct omap_dss_device *dssdev = omap_encoder->display; int r;
omap_encoder_update(encoder, omap_crtc_channel(encoder->crtc),
@@ -156,7 +157,8 @@ static const struct drm_encoder_helper_funcs omap_encoder_helper_funcs = {
/* initialize encoder */ struct drm_encoder *omap_encoder_init(struct drm_device *dev,
struct omap_dss_device *dssdev)
struct omap_dss_device *output,
struct omap_dss_device *display)
{ struct drm_encoder *encoder = NULL; struct omap_encoder *omap_encoder; @@ -165,7 +167,8 @@ struct drm_encoder *omap_encoder_init(struct drm_device *dev, if (!omap_encoder) goto fail;
- omap_encoder->dssdev = dssdev;
omap_encoder->output = output;
omap_encoder->display = display;
encoder = &omap_encoder->base;
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.h b/drivers/gpu/drm/omapdrm/omap_encoder.h index e8f1a35dce2f..a7b5dde63ecb 100644 --- a/drivers/gpu/drm/omapdrm/omap_encoder.h +++ b/drivers/gpu/drm/omapdrm/omap_encoder.h @@ -25,6 +25,7 @@ struct drm_encoder; struct omap_dss_device;
struct drm_encoder *omap_encoder_init(struct drm_device *dev,
struct omap_dss_device *dssdev);
struct omap_dss_device *output,
struct omap_dss_device *display);
#endif /* __OMAPDRM_ENCODER_H__ */
Regards,
Laurent Pinchart
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
The HDMI mode (.set_hdmi_mode()) and infoframe (.set_infoframe()) operations are called recursively from the display device back to the HDMI encoder. This isn't required, as all components other than the HDMI encoder just forward the operation to the previous component in the chain. Call the operations directly on the HDMI encoder.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 20 -------------------- .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 21 --------------------- drivers/gpu/drm/omapdrm/omap_encoder.c | 2 +- 3 files changed, 1 insertion(+), 42 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index 16dc22edcb8e..fe6d2923ed81 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c @@ -154,21 +154,6 @@ static void hdmic_unregister_hpd_cb(struct omap_dss_device *dssdev) mutex_unlock(&ddata->hpd_lock); }
-static int hdmic_set_hdmi_mode(struct omap_dss_device *dssdev, bool hdmi_mode) -{ - struct omap_dss_device *src = dssdev->src; - - return src->ops->hdmi.set_hdmi_mode(src, hdmi_mode); -} - -static int hdmic_set_infoframe(struct omap_dss_device *dssdev, - const struct hdmi_avi_infoframe *avi) -{ - struct omap_dss_device *src = dssdev->src; - - return src->ops->hdmi.set_infoframe(src, avi); -} - static const struct omap_dss_device_ops hdmic_ops = { .connect = hdmic_connect, .disconnect = hdmic_disconnect, @@ -183,11 +168,6 @@ static const struct omap_dss_device_ops hdmic_ops = { .detect = hdmic_detect, .register_hpd_cb = hdmic_register_hpd_cb, .unregister_hpd_cb = hdmic_unregister_hpd_cb, - - .hdmi = { - .set_hdmi_mode = hdmic_set_hdmi_mode, - .set_infoframe = hdmic_set_infoframe, - }, };
static irqreturn_t hdmic_hpd_isr(int irq, void *data) diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c index dbbf9683bd51..3ad60f4b331e 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c @@ -145,22 +145,6 @@ static void tpd_unregister_hpd_cb(struct omap_dss_device *dssdev) mutex_unlock(&ddata->hpd_lock); }
-static int tpd_set_infoframe(struct omap_dss_device *dssdev, - const struct hdmi_avi_infoframe *avi) -{ - struct omap_dss_device *src = dssdev->src; - - return src->ops->hdmi.set_infoframe(src, avi); -} - -static int tpd_set_hdmi_mode(struct omap_dss_device *dssdev, - bool hdmi_mode) -{ - struct omap_dss_device *src = dssdev->src; - - return src->ops->hdmi.set_hdmi_mode(src, hdmi_mode); -} - static const struct omap_dss_device_ops tpd_ops = { .connect = tpd_connect, .disconnect = tpd_disconnect, @@ -171,11 +155,6 @@ static const struct omap_dss_device_ops tpd_ops = { .detect = tpd_detect, .register_hpd_cb = tpd_register_hpd_cb, .unregister_hpd_cb = tpd_unregister_hpd_cb, - - .hdmi = { - .set_infoframe = tpd_set_infoframe, - .set_hdmi_mode = tpd_set_hdmi_mode, - }, };
static irqreturn_t tpd_hpd_isr(int irq, void *data) diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c index 2689ae74ea60..94b75d018e71 100644 --- a/drivers/gpu/drm/omapdrm/omap_encoder.c +++ b/drivers/gpu/drm/omapdrm/omap_encoder.c @@ -58,7 +58,7 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder, { struct drm_device *dev = encoder->dev; struct omap_encoder *omap_encoder = to_omap_encoder(encoder); - struct omap_dss_device *dssdev = omap_encoder->display; + struct omap_dss_device *dssdev = omap_encoder->output; struct drm_connector *connector; bool hdmi_mode; int r;
Hi,
On Wed, Jun 06, 2018 at 12:36:50PM +0300, Laurent Pinchart wrote:
The HDMI mode (.set_hdmi_mode()) and infoframe (.set_infoframe()) operations are called recursively from the display device back to the HDMI encoder. This isn't required, as all components other than the HDMI encoder just forward the operation to the previous component in the chain. Call the operations directly on the HDMI encoder.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com
Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.co.uk
-- Sebastian
drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 20 -------------------- .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 21 --------------------- drivers/gpu/drm/omapdrm/omap_encoder.c | 2 +- 3 files changed, 1 insertion(+), 42 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index 16dc22edcb8e..fe6d2923ed81 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c @@ -154,21 +154,6 @@ static void hdmic_unregister_hpd_cb(struct omap_dss_device *dssdev) mutex_unlock(&ddata->hpd_lock); }
-static int hdmic_set_hdmi_mode(struct omap_dss_device *dssdev, bool hdmi_mode) -{
- struct omap_dss_device *src = dssdev->src;
- return src->ops->hdmi.set_hdmi_mode(src, hdmi_mode);
-}
-static int hdmic_set_infoframe(struct omap_dss_device *dssdev,
const struct hdmi_avi_infoframe *avi)
-{
- struct omap_dss_device *src = dssdev->src;
- return src->ops->hdmi.set_infoframe(src, avi);
-}
static const struct omap_dss_device_ops hdmic_ops = { .connect = hdmic_connect, .disconnect = hdmic_disconnect, @@ -183,11 +168,6 @@ static const struct omap_dss_device_ops hdmic_ops = { .detect = hdmic_detect, .register_hpd_cb = hdmic_register_hpd_cb, .unregister_hpd_cb = hdmic_unregister_hpd_cb,
- .hdmi = {
.set_hdmi_mode = hdmic_set_hdmi_mode,
.set_infoframe = hdmic_set_infoframe,
- },
};
static irqreturn_t hdmic_hpd_isr(int irq, void *data) diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c index dbbf9683bd51..3ad60f4b331e 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c @@ -145,22 +145,6 @@ static void tpd_unregister_hpd_cb(struct omap_dss_device *dssdev) mutex_unlock(&ddata->hpd_lock); }
-static int tpd_set_infoframe(struct omap_dss_device *dssdev,
const struct hdmi_avi_infoframe *avi)
-{
- struct omap_dss_device *src = dssdev->src;
- return src->ops->hdmi.set_infoframe(src, avi);
-}
-static int tpd_set_hdmi_mode(struct omap_dss_device *dssdev,
bool hdmi_mode)
-{
- struct omap_dss_device *src = dssdev->src;
- return src->ops->hdmi.set_hdmi_mode(src, hdmi_mode);
-}
static const struct omap_dss_device_ops tpd_ops = { .connect = tpd_connect, .disconnect = tpd_disconnect, @@ -171,11 +155,6 @@ static const struct omap_dss_device_ops tpd_ops = { .detect = tpd_detect, .register_hpd_cb = tpd_register_hpd_cb, .unregister_hpd_cb = tpd_unregister_hpd_cb,
- .hdmi = {
.set_infoframe = tpd_set_infoframe,
.set_hdmi_mode = tpd_set_hdmi_mode,
- },
};
static irqreturn_t tpd_hpd_isr(int irq, void *data) diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c index 2689ae74ea60..94b75d018e71 100644 --- a/drivers/gpu/drm/omapdrm/omap_encoder.c +++ b/drivers/gpu/drm/omapdrm/omap_encoder.c @@ -58,7 +58,7 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder, { struct drm_device *dev = encoder->dev; struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
- struct omap_dss_device *dssdev = omap_encoder->display;
- struct omap_dss_device *dssdev = omap_encoder->output; struct drm_connector *connector; bool hdmi_mode; int r;
-- Regards,
Laurent Pinchart
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
On 06/06/18 12:36, Laurent Pinchart wrote:
The HDMI mode (.set_hdmi_mode()) and infoframe (.set_infoframe()) operations are called recursively from the display device back to the HDMI encoder. This isn't required, as all components other than the HDMI encoder just forward the operation to the previous component in the chain. Call the operations directly on the HDMI encoder.
TI's kernel has omapdrm specific sii9022 DPI-to-HDMI encoder driver, which uses these. There's also a sii902x DRM bridge driver, which I think handles infoframe internally.
The aim is, of course, to move to the DRM bridge drivers asap, so this may not be an issue. So just fyi.
Tomi
dri-devel@lists.freedesktop.org