diff options
author | Russell King | 2013-11-03 15:04:47 +0100 |
---|---|---|
committer | Russell King | 2014-02-24 13:07:43 +0100 |
commit | 9e2d410d18bf93c620877a4ea0cab213362a2dda (patch) | |
tree | 7fd6bc71c2eddef87b00d3e42848f37fb05fc4ca | |
parent | imx-drm: use supplied drm_device where possible (diff) | |
download | kernel-qcow2-linux-9e2d410d18bf93c620877a4ea0cab213362a2dda.tar.gz kernel-qcow2-linux-9e2d410d18bf93c620877a4ea0cab213362a2dda.tar.xz kernel-qcow2-linux-9e2d410d18bf93c620877a4ea0cab213362a2dda.zip |
imx-drm: imx-drm-core: provide helper function to parse possible crtcs
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>
-rw-r--r-- | drivers/staging/imx-drm/imx-drm-core.c | 66 | ||||
-rw-r--r-- | drivers/staging/imx-drm/imx-drm.h | 2 |
2 files changed, 68 insertions, 0 deletions
diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 3d1c6b6c4388..5cac6ee24472 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -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) diff --git a/drivers/staging/imx-drm/imx-drm.h b/drivers/staging/imx-drm/imx-drm.h index 78465239ed4c..49d4aaf33f97 100644 --- a/drivers/staging/imx-drm/imx-drm.h +++ b/drivers/staging/imx-drm/imx-drm.h @@ -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); |