imx-drm: imx-drm-core: provide helper function to parse possible crtcs
authorRussell King <rmk+kernel@arm.linux.org.uk>
Sun, 3 Nov 2013 14:04:47 +0000 (14:04 +0000)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Mon, 24 Feb 2014 12:07:43 +0000 (12:07 +0000)
Provide a helper function to parse possible crtcs before the encoder
is registered.  The crtc mask is derived from the position of the
CRTCs registered in the drm_device.

Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
Acked-by: Shawn Guo <shawn.guo@linaro.org>
Reviewed-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
drivers/staging/imx-drm/imx-drm-core.c
drivers/staging/imx-drm/imx-drm.h

index 3d1c6b6..5cac6ee 100644 (file)
@@ -658,6 +658,72 @@ err_busy:
 }
 EXPORT_SYMBOL_GPL(imx_drm_add_encoder);
 
+/*
+ * Find the DRM CRTC possible mask for the device node cookie/id.
+ *
+ * The encoder possible masks are defined by their position in the
+ * mode_config crtc_list.  This means that CRTCs must not be added
+ * or removed once the DRM device has been fully initialised.
+ */
+static uint32_t imx_drm_find_crtc_mask(struct imx_drm_device *imxdrm,
+       void *cookie, int id)
+{
+       unsigned i;
+
+       for (i = 0; i < MAX_CRTC; i++) {
+               struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[i];
+               if (imx_drm_crtc && imx_drm_crtc->cookie.id == id &&
+                   imx_drm_crtc->cookie.cookie == cookie)
+                       return drm_crtc_mask(imx_drm_crtc->crtc);
+       }
+
+       return 0;
+}
+
+int imx_drm_encoder_parse_of(struct drm_device *drm,
+       struct drm_encoder *encoder, struct device_node *np)
+{
+       struct imx_drm_device *imxdrm = drm->dev_private;
+       uint32_t crtc_mask = 0;
+       int i, ret = 0;
+
+       for (i = 0; !ret; i++) {
+               struct of_phandle_args args;
+               uint32_t mask;
+               int id;
+
+               ret = of_parse_phandle_with_args(np, "crtcs", "#crtc-cells", i,
+                                                &args);
+               if (ret == -ENOENT)
+                       break;
+               if (ret < 0)
+                       return ret;
+
+               id = args.args_count > 0 ? args.args[0] : 0;
+               mask = imx_drm_find_crtc_mask(imxdrm, args.np, id);
+               of_node_put(args.np);
+
+               /*
+                * If we failed to find the CRTC(s) which this encoder is
+                * supposed to be connected to, it's because the CRTC has
+                * not been registered yet.  Defer probing, and hope that
+                * the required CRTC is added later.
+                */
+               if (mask == 0)
+                       return -EPROBE_DEFER;
+
+               crtc_mask |= mask;
+       }
+
+       encoder->possible_crtcs = crtc_mask;
+
+       /* FIXME: this is the mask of outputs which can clone this output. */
+       encoder->possible_clones = ~0;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(imx_drm_encoder_parse_of);
+
 int imx_drm_encoder_add_possible_crtcs(
                struct imx_drm_encoder *imx_drm_encoder,
                struct device_node *np)
index 7846523..49d4aaf 100644 (file)
@@ -64,6 +64,8 @@ struct device_node;
 int imx_drm_encoder_get_mux_id(struct drm_encoder *encoder);
 int imx_drm_encoder_add_possible_crtcs(struct imx_drm_encoder *imx_drm_encoder,
                struct device_node *np);
+int imx_drm_encoder_parse_of(struct drm_device *drm,
+       struct drm_encoder *encoder, struct device_node *np);
 
 int imx_drm_connector_mode_valid(struct drm_connector *connector,
        struct drm_display_mode *mode);