[PATCH] drm: omap: fix: Defer probe if an omapdss device requests for it at connect

Archit Taneja archit at ti.com
Wed Sep 18 04:15:05 PDT 2013


On Wednesday 18 September 2013 04:38 PM, Archit Taneja wrote:
> Some omapdss panels are connected to outputs/encoders(HDMI/DSI/DPI) that require
> regulators. The output's connect op tries to get a regulator which may not exist
> yet because it might get registered later in the kernel boot.
>
> omapdrm currently ignores those panels which return a non zero value when
> connected. A better approach would be for omapdrm to request for probe
> deferral if a panel's connect op returns -EPROBE_DEFER.
>
> The connecting of panels is moved very early in the the drm device's probe
> before anything else is initialized. When we enter omap_modeset_init(), we have
> a set of panels that have been connected. We now proceed with registering only
> those panels which are already connected.
>
> Checking whether the panel has a driver or whether it has get_timing/read_edid
> ops in omap_modeset_init() are redundant with the new display model. These can
> be removed since a dssdev device will always have a driver associated with it,
> and all dssdev drivers have a get_timings op.
>
> This fixes boot with omapdrm on an omap4 panda ES board. The regulators used by
> HDMI aren't initialized because I2c isn't initialized, I2C isn't initialized
> as it's pins are not configured because pinctrl is yet to probe.

Copying dri-devel list.

>
> Signed-off-by: Archit Taneja <archit at ti.com>
> ---
>   drivers/gpu/drm/omapdrm/omap_crtc.c |  5 ++++
>   drivers/gpu/drm/omapdrm/omap_drv.c  | 51 +++++++++++++++++++++----------------
>   drivers/gpu/drm/omapdrm/omap_drv.h  |  1 +
>   3 files changed, 35 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
> index 0fd2eb1..9c01311 100644
> --- a/drivers/gpu/drm/omapdrm/omap_crtc.c
> +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
> @@ -623,6 +623,11 @@ void omap_crtc_pre_init(void)
>   	dss_install_mgr_ops(&mgr_ops);
>   }
>
> +void omap_crtc_pre_uninit(void)
> +{
> +	dss_uninstall_mgr_ops();
> +}
> +
>   /* initialize crtc */
>   struct drm_crtc *omap_crtc_init(struct drm_device *dev,
>   		struct drm_plane *plane, enum omap_channel channel, int id)
> diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
> index 2603d90..cbe5d8e 100644
> --- a/drivers/gpu/drm/omapdrm/omap_drv.c
> +++ b/drivers/gpu/drm/omapdrm/omap_drv.c
> @@ -87,6 +87,24 @@ static bool channel_used(struct drm_device *dev, enum omap_channel channel)
>   	return false;
>   }
>
> +static int omap_connect_dssdevs(void)
> +{
> +	int r;
> +	struct omap_dss_device *dssdev = NULL;
> +
> +	for_each_dss_dev(dssdev) {
> +		r = dssdev->driver->connect(dssdev);
> +		if (r == -EPROBE_DEFER) {
> +			return r;
> +		} else if (r) {
> +			dev_warn(dssdev->dev, "could not connect display: %s\n",
> +				dssdev->name);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>   static int omap_modeset_init(struct drm_device *dev)
>   {
>   	struct omap_drm_private *priv = dev->dev_private;
> @@ -95,9 +113,6 @@ static int omap_modeset_init(struct drm_device *dev)
>   	int num_mgrs = dss_feat_get_num_mgrs();
>   	int num_crtcs;
>   	int i, id = 0;
> -	int r;
> -
> -	omap_crtc_pre_init();
>
>   	drm_mode_config_init(dev);
>
> @@ -119,26 +134,8 @@ static int omap_modeset_init(struct drm_device *dev)
>   		enum omap_channel channel;
>   		struct omap_overlay_manager *mgr;
>
> -		if (!dssdev->driver) {
> -			dev_warn(dev->dev, "%s has no driver.. skipping it\n",
> -					dssdev->name);
> +		if (!omapdss_device_is_connected(dssdev))
>   			continue;
> -		}
> -
> -		if (!(dssdev->driver->get_timings ||
> -					dssdev->driver->read_edid)) {
> -			dev_warn(dev->dev, "%s driver does not support "
> -				"get_timings or read_edid.. skipping it!\n",
> -				dssdev->name);
> -			continue;
> -		}
> -
> -		r = dssdev->driver->connect(dssdev);
> -		if (r) {
> -			dev_err(dev->dev, "could not connect display: %s\n",
> -					dssdev->name);
> -			continue;
> -		}
>
>   		encoder = omap_encoder_init(dev, dssdev);
>
> @@ -656,9 +653,19 @@ static void pdev_shutdown(struct platform_device *device)
>
>   static int pdev_probe(struct platform_device *device)
>   {
> +	int r;
> +
>   	if (omapdss_is_initialized() == false)
>   		return -EPROBE_DEFER;
>
> +	omap_crtc_pre_init();
> +
> +	r = omap_connect_dssdevs();
> +	if (r) {
> +		omap_crtc_pre_uninit();
> +		return r;
> +	}
> +
>   	DBG("%s", device->name);
>   	return drm_platform_init(&omap_drm_driver, device);
>   }
> diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
> index 30b95b7..cb86cb3 100644
> --- a/drivers/gpu/drm/omapdrm/omap_drv.h
> +++ b/drivers/gpu/drm/omapdrm/omap_drv.h
> @@ -158,6 +158,7 @@ enum omap_channel omap_crtc_channel(struct drm_crtc *crtc);
>   int omap_crtc_apply(struct drm_crtc *crtc,
>   		struct omap_drm_apply *apply);
>   void omap_crtc_pre_init(void);
> +void omap_crtc_pre_uninit(void);
>   struct drm_crtc *omap_crtc_init(struct drm_device *dev,
>   		struct drm_plane *plane, enum omap_channel channel, int id);
>
>



More information about the dri-devel mailing list