From 04cec1a2bc5c70e719c1da8eaca2842da4cd77fb Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 16 Oct 2013 10:19:00 +0100 Subject: imx-drm: add imx6 DT configuration for HDMI Extracted from another patch by Fabio Estevam, this adds the DT configuration for HDMI output on the IMX6 SoCs Acked-by: Philipp Zabel Acked-by: Shawn Guo Reviewed-by: Fabio Estevam Signed-off-by: Russell King --- arch/arm/boot/dts/imx6dl.dtsi | 4 ++++ arch/arm/boot/dts/imx6q.dtsi | 4 ++++ arch/arm/boot/dts/imx6qdl.dtsi | 10 ++++++++++ 3 files changed, 18 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/imx6dl.dtsi b/arch/arm/boot/dts/imx6dl.dtsi index 9e8ae118fdd4..65e54b4529c5 100644 --- a/arch/arm/boot/dts/imx6dl.dtsi +++ b/arch/arm/boot/dts/imx6dl.dtsi @@ -88,3 +88,7 @@ crtcs = <&ipu1 0>, <&ipu1 1>; }; }; + +&hdmi { + crtcs = <&ipu1 0>, <&ipu1 1>; +} diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index f024ef28b34b..d2467f532de6 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -159,3 +159,7 @@ crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>; }; }; + +&hdmi { + crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>; +}; diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index fb28b2ecb1db..400bbc624f25 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -1368,6 +1368,16 @@ }; }; + hdmi: hdmi@0120000 { + compatible = "fsl,imx6q-hdmi"; + reg = <0x00120000 0x9000>; + interrupts = <0 115 0x04>; + gpr = <&gpr>; + clocks = <&clks 123>, <&clks 124>; + clock-names = "iahb", "isfr"; + status = "disabled"; + }; + dcic1: dcic@020e4000 { reg = <0x020e4000 0x4000>; interrupts = <0 124 0x04>; -- cgit v1.2.3 From cf83eb24d22f3a9580fb86ee64e2830c65df062a Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 30 Oct 2013 20:10:31 +0000 Subject: imx-drm: update and fix imx6 DT descriptions for v3 HDMI driver Acked-by: Philipp Zabel Acked-by: Shawn Guo Reviewed-by: Fabio Estevam Signed-off-by: Russell King --- arch/arm/boot/dts/imx6dl.dtsi | 3 ++- arch/arm/boot/dts/imx6q.dtsi | 1 + arch/arm/boot/dts/imx6qdl.dtsi | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/imx6dl.dtsi b/arch/arm/boot/dts/imx6dl.dtsi index 65e54b4529c5..6dc397022214 100644 --- a/arch/arm/boot/dts/imx6dl.dtsi +++ b/arch/arm/boot/dts/imx6dl.dtsi @@ -90,5 +90,6 @@ }; &hdmi { + compatible = "fsl,imx6dl-hdmi"; crtcs = <&ipu1 0>, <&ipu1 1>; -} +}; diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index d2467f532de6..187fe33ba515 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -161,5 +161,6 @@ }; &hdmi { + compatible = "fsl,imx6q-hdmi"; crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>; }; diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 400bbc624f25..930ebe0c2937 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -1369,7 +1369,6 @@ }; hdmi: hdmi@0120000 { - compatible = "fsl,imx6q-hdmi"; reg = <0x00120000 0x9000>; interrupts = <0 115 0x04>; gpr = <&gpr>; -- cgit v1.2.3 From 17b5001b5143e3b7fce1c584bdcffd726dd8667c Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 3 Nov 2013 11:23:34 +0000 Subject: imx-drm: convert to componentised device support Use the componentised device support for imx-drm. This requires all the sub-components and the master device to register with the component device support. Acked-by: Philipp Zabel Acked-by: Shawn Guo Reviewed-by: Fabio Estevam Signed-off-by: Russell King --- arch/arm/boot/dts/imx51-babbage.dts | 10 ++- arch/arm/boot/dts/imx53-m53evk.dts | 8 ++- arch/arm/boot/dts/imx53-mba53.dts | 6 ++ arch/arm/boot/dts/imx53-qsb.dts | 8 ++- arch/arm/boot/dts/imx6q-sabresd.dts | 4 ++ arch/arm/boot/dts/imx6qdl-sabresd.dtsi | 6 ++ drivers/staging/imx-drm/imx-drm-core.c | 105 +++++++++++++++++++++++------ drivers/staging/imx-drm/imx-hdmi.c | 41 +++++++---- drivers/staging/imx-drm/imx-ldb.c | 40 +++++++---- drivers/staging/imx-drm/imx-tve.c | 63 ++++++++++------- drivers/staging/imx-drm/ipuv3-crtc.c | 46 +++++++++---- drivers/staging/imx-drm/parallel-display.c | 30 +++++++-- 12 files changed, 275 insertions(+), 92 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts index be1407cf5abd..6ff15a0eacb3 100644 --- a/arch/arm/boot/dts/imx51-babbage.dts +++ b/arch/arm/boot/dts/imx51-babbage.dts @@ -21,7 +21,7 @@ reg = <0x90000000 0x20000000>; }; - display@di0 { + display0: display@di0 { compatible = "fsl,imx-parallel-display"; crtcs = <&ipu 0>; interface-pix-fmt = "rgb24"; @@ -43,7 +43,7 @@ }; }; - display@di1 { + display1: display@di1 { compatible = "fsl,imx-parallel-display"; crtcs = <&ipu 1>; interface-pix-fmt = "rgb565"; @@ -81,6 +81,12 @@ }; }; + imx-drm { + compatible = "fsl,imx-drm"; + crtcs = <&ipu 0>, <&ipu 1>; + connectors = <&display0>, <&display1>; + }; + sound { compatible = "fsl,imx51-babbage-sgtl5000", "fsl,imx-audio-sgtl5000"; diff --git a/arch/arm/boot/dts/imx53-m53evk.dts b/arch/arm/boot/dts/imx53-m53evk.dts index 7d304d02ed38..ee6107b6484c 100644 --- a/arch/arm/boot/dts/imx53-m53evk.dts +++ b/arch/arm/boot/dts/imx53-m53evk.dts @@ -21,7 +21,7 @@ }; soc { - display@di1 { + display1: display@di1 { compatible = "fsl,imx-parallel-display"; crtcs = <&ipu 1>; interface-pix-fmt = "bgr666"; @@ -53,6 +53,12 @@ default-brightness-level = <6>; }; + imx-drm { + compatible = "fsl,imx-drm"; + crtcs = <&ipu 1>; + connectors = <&display1>; + }; + leds { compatible = "gpio-leds"; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/imx53-mba53.dts b/arch/arm/boot/dts/imx53-mba53.dts index a63090267941..9b6e76980a74 100644 --- a/arch/arm/boot/dts/imx53-mba53.dts +++ b/arch/arm/boot/dts/imx53-mba53.dts @@ -43,6 +43,12 @@ status = "disabled"; }; + imx-drm { + compatible = "fsl,imx-drm"; + crtcs = <&ipu 1>; + connectors = <&disp1>, <&tve>; + }; + reg_3p2v: 3p2v { compatible = "regulator-fixed"; regulator-name = "3P2V"; diff --git a/arch/arm/boot/dts/imx53-qsb.dts b/arch/arm/boot/dts/imx53-qsb.dts index 91a5935a4aac..3cb4f7791a91 100644 --- a/arch/arm/boot/dts/imx53-qsb.dts +++ b/arch/arm/boot/dts/imx53-qsb.dts @@ -21,7 +21,7 @@ reg = <0x70000000 0x40000000>; }; - display@di0 { + display0: display@di0 { compatible = "fsl,imx-parallel-display"; crtcs = <&ipu 0>; interface-pix-fmt = "rgb565"; @@ -72,6 +72,12 @@ }; }; + imx-drm { + compatible = "fsl,imx-drm"; + crtcs = <&ipu 0>; + connectors = <&display0>; + }; + leds { compatible = "gpio-leds"; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/imx6q-sabresd.dts b/arch/arm/boot/dts/imx6q-sabresd.dts index 9cbdfe7a0931..66f220a82e45 100644 --- a/arch/arm/boot/dts/imx6q-sabresd.dts +++ b/arch/arm/boot/dts/imx6q-sabresd.dts @@ -20,6 +20,10 @@ compatible = "fsl,imx6q-sabresd", "fsl,imx6q"; }; +&imx_drm { + crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>; +}; + &sata { status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi index e75e11b36dff..dfca3e001398 100644 --- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi @@ -62,6 +62,12 @@ }; }; + imx_drm: imx-drm { + compatible = "fsl,imx-drm"; + crtcs = <&ipu1 0>, <&ipu1 1>; + connectors = <&ldb>; + }; + sound { compatible = "fsl,imx6q-sabresd-wm8962", "fsl,imx-audio-wm8962"; diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index d9786eca3a36..82b0337096b0 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -13,7 +13,7 @@ * GNU General Public License for more details. * */ - +#include #include #include #include @@ -90,6 +90,8 @@ static int imx_drm_driver_unload(struct drm_device *drm) { struct imx_drm_device *imxdrm = drm->dev_private; + component_unbind_all(drm->dev, drm); + imx_drm_device_put(); drm_vblank_cleanup(drm); @@ -371,11 +373,8 @@ static void imx_drm_connector_unregister( } /* - * Called by the CRTC driver when all CRTCs are registered. This - * puts all the pieces together and initializes the driver. - * Once this is called no more CRTCs can be registered since - * the drm core has hardcoded the number of crtcs in several - * places. + * Main DRM initialisation. This binds, initialises and registers + * with DRM the subcomponents of the driver. */ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) { @@ -428,8 +427,15 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) platform_set_drvdata(drm->platformdev, drm); mutex_unlock(&imxdrm->mutex); + + /* Now try and bind all our sub-components */ + ret = component_bind_all(drm->dev, drm); + if (ret) + goto err_relock; return 0; +err_relock: + mutex_lock(&imxdrm->mutex); err_vblank: drm_vblank_cleanup(drm); err_kms: @@ -809,6 +815,70 @@ static struct drm_driver imx_drm_driver = { .patchlevel = 0, }; +static int compare_parent_of(struct device *dev, void *data) +{ + struct of_phandle_args *args = data; + return dev->parent && dev->parent->of_node == args->np; +} + +static int compare_of(struct device *dev, void *data) +{ + return dev->of_node == data; +} + +static int imx_drm_add_components(struct device *master, struct master *m) +{ + struct device_node *np = master->of_node; + unsigned i; + int ret; + + for (i = 0; ; i++) { + struct of_phandle_args args; + + ret = of_parse_phandle_with_fixed_args(np, "crtcs", 1, + i, &args); + if (ret) + break; + + ret = component_master_add_child(m, compare_parent_of, &args); + of_node_put(args.np); + + if (ret) + return ret; + } + + for (i = 0; ; i++) { + struct device_node *node; + + node = of_parse_phandle(np, "connectors", i); + if (!node) + break; + + ret = component_master_add_child(m, compare_of, node); + of_node_put(node); + + if (ret) + return ret; + } + return 0; +} + +static int imx_drm_bind(struct device *dev) +{ + return drm_platform_init(&imx_drm_driver, to_platform_device(dev)); +} + +static void imx_drm_unbind(struct device *dev) +{ + drm_put_dev(dev_get_drvdata(dev)); +} + +static const struct component_master_ops imx_drm_ops = { + .add_components = imx_drm_add_components, + .bind = imx_drm_bind, + .unbind = imx_drm_unbind, +}; + static int imx_drm_platform_probe(struct platform_device *pdev) { int ret; @@ -819,27 +889,31 @@ static int imx_drm_platform_probe(struct platform_device *pdev) imx_drm_device->dev = &pdev->dev; - return drm_platform_init(&imx_drm_driver, pdev); + return component_master_add(&pdev->dev, &imx_drm_ops); } static int imx_drm_platform_remove(struct platform_device *pdev) { - drm_put_dev(platform_get_drvdata(pdev)); - + component_master_del(&pdev->dev, &imx_drm_ops); return 0; } +static const struct of_device_id imx_drm_dt_ids[] = { + { .compatible = "fsl,imx-drm", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, imx_drm_dt_ids); + static struct platform_driver imx_drm_pdrv = { .probe = imx_drm_platform_probe, .remove = imx_drm_platform_remove, .driver = { .owner = THIS_MODULE, .name = "imx-drm", + .of_match_table = imx_drm_dt_ids, }, }; -static struct platform_device *imx_drm_pdev; - static int __init imx_drm_init(void) { int ret; @@ -852,12 +926,6 @@ static int __init imx_drm_init(void) INIT_LIST_HEAD(&imx_drm_device->connector_list); INIT_LIST_HEAD(&imx_drm_device->encoder_list); - imx_drm_pdev = platform_device_register_simple("imx-drm", -1, NULL, 0); - if (IS_ERR(imx_drm_pdev)) { - ret = PTR_ERR(imx_drm_pdev); - goto err_pdev; - } - ret = platform_driver_register(&imx_drm_pdrv); if (ret) goto err_pdrv; @@ -865,8 +933,6 @@ static int __init imx_drm_init(void) return 0; err_pdrv: - platform_device_unregister(imx_drm_pdev); -err_pdev: kfree(imx_drm_device); return ret; @@ -874,7 +940,6 @@ err_pdev: static void __exit imx_drm_exit(void) { - platform_device_unregister(imx_drm_pdev); platform_driver_unregister(&imx_drm_pdrv); kfree(imx_drm_device); diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index 50475e606849..14b4a4b976b9 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -12,6 +12,7 @@ * Copyright (C) 2010, Guennadi Liakhovetski */ +#include #include #include #include @@ -1582,21 +1583,22 @@ static const struct of_device_id imx_hdmi_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids); -static int imx_hdmi_platform_probe(struct platform_device *pdev) +static int imx_hdmi_bind(struct device *dev, struct device *master, void *data) { + struct platform_device *pdev = to_platform_device(dev); const struct of_device_id *of_id = - of_match_device(imx_hdmi_dt_ids, &pdev->dev); - struct device_node *np = pdev->dev.of_node; + of_match_device(imx_hdmi_dt_ids, dev); + struct device_node *np = dev->of_node; struct device_node *ddc_node; struct imx_hdmi *hdmi; struct resource *iores; int ret, irq; - hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); + hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); if (!hdmi) return -ENOMEM; - hdmi->dev = &pdev->dev; + hdmi->dev = dev; hdmi->sample_rate = 48000; hdmi->ratio = 100; @@ -1620,13 +1622,13 @@ static int imx_hdmi_platform_probe(struct platform_device *pdev) if (irq < 0) return -EINVAL; - ret = devm_request_irq(&pdev->dev, irq, imx_hdmi_irq, 0, - dev_name(&pdev->dev), hdmi); + ret = devm_request_irq(dev, irq, imx_hdmi_irq, 0, + dev_name(dev), hdmi); if (ret) return ret; iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); - hdmi->regs = devm_ioremap_resource(&pdev->dev, iores); + hdmi->regs = devm_ioremap_resource(dev, iores); if (IS_ERR(hdmi->regs)) return PTR_ERR(hdmi->regs); @@ -1665,7 +1667,7 @@ static int imx_hdmi_platform_probe(struct platform_device *pdev) } /* Product and revision IDs */ - dev_info(&pdev->dev, + dev_info(dev, "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n", hdmi_readb(hdmi, HDMI_DESIGN_ID), hdmi_readb(hdmi, HDMI_REVISION_ID), @@ -1699,7 +1701,7 @@ static int imx_hdmi_platform_probe(struct platform_device *pdev) imx_drm_encoder_add_possible_crtcs(hdmi->imx_drm_encoder, np); - platform_set_drvdata(pdev, hdmi); + dev_set_drvdata(dev, hdmi); return 0; @@ -1711,9 +1713,10 @@ err_isfr: return ret; } -static int imx_hdmi_platform_remove(struct platform_device *pdev) +static void imx_hdmi_unbind(struct device *dev, struct device *master, + void *data) { - struct imx_hdmi *hdmi = platform_get_drvdata(pdev); + struct imx_hdmi *hdmi = dev_get_drvdata(dev); struct drm_connector *connector = &hdmi->connector; struct drm_encoder *encoder = &hdmi->encoder; @@ -1724,7 +1727,21 @@ static int imx_hdmi_platform_remove(struct platform_device *pdev) clk_disable_unprepare(hdmi->iahb_clk); clk_disable_unprepare(hdmi->isfr_clk); i2c_put_adapter(hdmi->ddc); +} +static const struct component_ops hdmi_ops = { + .bind = imx_hdmi_bind, + .unbind = imx_hdmi_unbind, +}; + +static int imx_hdmi_platform_probe(struct platform_device *pdev) +{ + return component_add(&pdev->dev, &hdmi_ops); +} + +static int imx_hdmi_platform_remove(struct platform_device *pdev) +{ + component_del(&pdev->dev, &hdmi_ops); return 0; } diff --git a/drivers/staging/imx-drm/imx-ldb.c b/drivers/staging/imx-drm/imx-ldb.c index dd29a4aad376..d00f93f3440d 100644 --- a/drivers/staging/imx-drm/imx-ldb.c +++ b/drivers/staging/imx-drm/imx-ldb.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -450,11 +451,11 @@ static const struct of_device_id imx_ldb_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, imx_ldb_dt_ids); -static int imx_ldb_probe(struct platform_device *pdev) +static int imx_ldb_bind(struct device *dev, struct device *master, void *data) { - struct device_node *np = pdev->dev.of_node; + struct device_node *np = dev->of_node; const struct of_device_id *of_id = - of_match_device(imx_ldb_dt_ids, &pdev->dev); + of_match_device(imx_ldb_dt_ids, dev); struct device_node *child; const u8 *edidp; struct imx_ldb *imx_ldb; @@ -464,17 +465,17 @@ static int imx_ldb_probe(struct platform_device *pdev) int ret; int i; - imx_ldb = devm_kzalloc(&pdev->dev, sizeof(*imx_ldb), GFP_KERNEL); + imx_ldb = devm_kzalloc(dev, sizeof(*imx_ldb), GFP_KERNEL); if (!imx_ldb) return -ENOMEM; imx_ldb->regmap = syscon_regmap_lookup_by_phandle(np, "gpr"); if (IS_ERR(imx_ldb->regmap)) { - dev_err(&pdev->dev, "failed to get parent regmap\n"); + dev_err(dev, "failed to get parent regmap\n"); return PTR_ERR(imx_ldb->regmap); } - imx_ldb->dev = &pdev->dev; + imx_ldb->dev = dev; if (of_id) imx_ldb->lvds_mux = of_id->data; @@ -512,7 +513,7 @@ static int imx_ldb_probe(struct platform_device *pdev) return -EINVAL; if (dual && i > 0) { - dev_warn(&pdev->dev, "dual-channel mode, ignoring second output\n"); + dev_warn(dev, "dual-channel mode, ignoring second output\n"); continue; } @@ -551,7 +552,7 @@ static int imx_ldb_probe(struct platform_device *pdev) break; case LVDS_BIT_MAP_JEIDA: if (datawidth == 18) { - dev_err(&pdev->dev, "JEIDA standard only supported in 24 bit\n"); + dev_err(dev, "JEIDA standard only supported in 24 bit\n"); return -EINVAL; } if (i == 0 || dual) @@ -560,7 +561,7 @@ static int imx_ldb_probe(struct platform_device *pdev) imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 | LDB_BIT_MAP_CH1_JEIDA; break; default: - dev_err(&pdev->dev, "data mapping not specified or invalid\n"); + dev_err(dev, "data mapping not specified or invalid\n"); return -EINVAL; } @@ -571,14 +572,15 @@ static int imx_ldb_probe(struct platform_device *pdev) imx_drm_encoder_add_possible_crtcs(channel->imx_drm_encoder, child); } - platform_set_drvdata(pdev, imx_ldb); + dev_set_drvdata(dev, imx_ldb); return 0; } -static int imx_ldb_remove(struct platform_device *pdev) +static void imx_ldb_unbind(struct device *dev, struct device *master, + void *data) { - struct imx_ldb *imx_ldb = platform_get_drvdata(pdev); + struct imx_ldb *imx_ldb = dev_get_drvdata(dev); int i; for (i = 0; i < 2; i++) { @@ -591,7 +593,21 @@ static int imx_ldb_remove(struct platform_device *pdev) imx_drm_remove_connector(channel->imx_drm_connector); imx_drm_remove_encoder(channel->imx_drm_encoder); } +} +static const struct component_ops imx_ldb_ops = { + .bind = imx_ldb_bind, + .unbind = imx_ldb_unbind, +}; + +static int imx_ldb_probe(struct platform_device *pdev) +{ + return component_add(&pdev->dev, &imx_ldb_ops); +} + +static int imx_ldb_remove(struct platform_device *pdev) +{ + component_del(&pdev->dev, &imx_ldb_ops); return 0; } diff --git a/drivers/staging/imx-drm/imx-tve.c b/drivers/staging/imx-drm/imx-tve.c index 77131e5770f3..ad840d78a09a 100644 --- a/drivers/staging/imx-drm/imx-tve.c +++ b/drivers/staging/imx-drm/imx-tve.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -583,9 +584,10 @@ static const int of_get_tve_mode(struct device_node *np) return -EINVAL; } -static int imx_tve_probe(struct platform_device *pdev) +static int imx_tve_bind(struct device *dev, struct device *master, void *data) { - struct device_node *np = pdev->dev.of_node; + struct platform_device *pdev = to_platform_device(dev); + struct device_node *np = dev->of_node; struct device_node *ddc_node; struct imx_tve *tve; struct resource *res; @@ -594,11 +596,11 @@ static int imx_tve_probe(struct platform_device *pdev) int irq; int ret; - tve = devm_kzalloc(&pdev->dev, sizeof(*tve), GFP_KERNEL); + tve = devm_kzalloc(dev, sizeof(*tve), GFP_KERNEL); if (!tve) return -ENOMEM; - tve->dev = &pdev->dev; + tve->dev = dev; spin_lock_init(&tve->lock); ddc_node = of_parse_phandle(np, "ddc", 0); @@ -609,7 +611,7 @@ static int imx_tve_probe(struct platform_device *pdev) tve->mode = of_get_tve_mode(np); if (tve->mode != TVE_MODE_VGA) { - dev_err(&pdev->dev, "only VGA mode supported, currently\n"); + dev_err(dev, "only VGA mode supported, currently\n"); return -EINVAL; } @@ -618,7 +620,7 @@ static int imx_tve_probe(struct platform_device *pdev) &tve->hsync_pin); if (ret < 0) { - dev_err(&pdev->dev, "failed to get vsync pin\n"); + dev_err(dev, "failed to get vsync pin\n"); return ret; } @@ -626,40 +628,40 @@ static int imx_tve_probe(struct platform_device *pdev) &tve->vsync_pin); if (ret < 0) { - dev_err(&pdev->dev, "failed to get vsync pin\n"); + dev_err(dev, "failed to get vsync pin\n"); return ret; } } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_ioremap_resource(dev, res); if (IS_ERR(base)) return PTR_ERR(base); tve_regmap_config.lock_arg = tve; - tve->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "tve", base, + tve->regmap = devm_regmap_init_mmio_clk(dev, "tve", base, &tve_regmap_config); if (IS_ERR(tve->regmap)) { - dev_err(&pdev->dev, "failed to init regmap: %ld\n", + dev_err(dev, "failed to init regmap: %ld\n", PTR_ERR(tve->regmap)); return PTR_ERR(tve->regmap); } irq = platform_get_irq(pdev, 0); if (irq < 0) { - dev_err(&pdev->dev, "failed to get irq\n"); + dev_err(dev, "failed to get irq\n"); return irq; } - ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, + ret = devm_request_threaded_irq(dev, irq, NULL, imx_tve_irq_handler, IRQF_ONESHOT, "imx-tve", tve); if (ret < 0) { - dev_err(&pdev->dev, "failed to request irq: %d\n", ret); + dev_err(dev, "failed to request irq: %d\n", ret); return ret; } - tve->dac_reg = devm_regulator_get(&pdev->dev, "dac"); + tve->dac_reg = devm_regulator_get(dev, "dac"); if (!IS_ERR(tve->dac_reg)) { regulator_set_voltage(tve->dac_reg, 2750000, 2750000); ret = regulator_enable(tve->dac_reg); @@ -667,17 +669,17 @@ static int imx_tve_probe(struct platform_device *pdev) return ret; } - tve->clk = devm_clk_get(&pdev->dev, "tve"); + tve->clk = devm_clk_get(dev, "tve"); if (IS_ERR(tve->clk)) { - dev_err(&pdev->dev, "failed to get high speed tve clock: %ld\n", + dev_err(dev, "failed to get high speed tve clock: %ld\n", PTR_ERR(tve->clk)); return PTR_ERR(tve->clk); } /* this is the IPU DI clock input selector, can be parented to tve_di */ - tve->di_sel_clk = devm_clk_get(&pdev->dev, "di_sel"); + tve->di_sel_clk = devm_clk_get(dev, "di_sel"); if (IS_ERR(tve->di_sel_clk)) { - dev_err(&pdev->dev, "failed to get ipu di mux clock: %ld\n", + dev_err(dev, "failed to get ipu di mux clock: %ld\n", PTR_ERR(tve->di_sel_clk)); return PTR_ERR(tve->di_sel_clk); } @@ -688,11 +690,11 @@ static int imx_tve_probe(struct platform_device *pdev) ret = regmap_read(tve->regmap, TVE_COM_CONF_REG, &val); if (ret < 0) { - dev_err(&pdev->dev, "failed to read configuration register: %d\n", ret); + dev_err(dev, "failed to read configuration register: %d\n", ret); return ret; } if (val != 0x00100000) { - dev_err(&pdev->dev, "configuration register default value indicates this is not a TVEv2\n"); + dev_err(dev, "configuration register default value indicates this is not a TVEv2\n"); return -ENODEV; } @@ -705,14 +707,15 @@ static int imx_tve_probe(struct platform_device *pdev) ret = imx_drm_encoder_add_possible_crtcs(tve->imx_drm_encoder, np); - platform_set_drvdata(pdev, tve); + dev_set_drvdata(dev, tve); return 0; } -static int imx_tve_remove(struct platform_device *pdev) +static void imx_tve_unbind(struct device *dev, struct device *master, + void *data) { - struct imx_tve *tve = platform_get_drvdata(pdev); + struct imx_tve *tve = dev_get_drvdata(dev); struct drm_connector *connector = &tve->connector; struct drm_encoder *encoder = &tve->encoder; @@ -723,7 +726,21 @@ static int imx_tve_remove(struct platform_device *pdev) if (!IS_ERR(tve->dac_reg)) regulator_disable(tve->dac_reg); +} +static const struct component_ops imx_tve_ops = { + .bind = imx_tve_bind, + .unbind = imx_tve_unbind, +}; + +static int imx_tve_probe(struct platform_device *pdev) +{ + return component_add(&pdev->dev, &imx_tve_ops); +} + +static int imx_tve_remove(struct platform_device *pdev) +{ + component_del(&pdev->dev, &imx_tve_ops); return 0; } diff --git a/drivers/staging/imx-drm/ipuv3-crtc.c b/drivers/staging/imx-drm/ipuv3-crtc.c index 08e0a3b29174..d779ad2d1f4e 100644 --- a/drivers/staging/imx-drm/ipuv3-crtc.c +++ b/drivers/staging/imx-drm/ipuv3-crtc.c @@ -17,6 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ +#include #include #include #include @@ -400,43 +401,60 @@ err_put_resources: return ret; } -static int ipu_drm_probe(struct platform_device *pdev) +static int ipu_drm_bind(struct device *dev, struct device *master, void *data) { - struct ipu_client_platformdata *pdata = pdev->dev.platform_data; + struct ipu_client_platformdata *pdata = dev->platform_data; struct ipu_crtc *ipu_crtc; int ret; - if (!pdata) - return -EINVAL; - - ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); - if (ret) - return ret; - - ipu_crtc = devm_kzalloc(&pdev->dev, sizeof(*ipu_crtc), GFP_KERNEL); + ipu_crtc = devm_kzalloc(dev, sizeof(*ipu_crtc), GFP_KERNEL); if (!ipu_crtc) return -ENOMEM; - ipu_crtc->dev = &pdev->dev; + ipu_crtc->dev = dev; ret = ipu_crtc_init(ipu_crtc, pdata); if (ret) return ret; - platform_set_drvdata(pdev, ipu_crtc); + dev_set_drvdata(dev, ipu_crtc); return 0; } -static int ipu_drm_remove(struct platform_device *pdev) +static void ipu_drm_unbind(struct device *dev, struct device *master, + void *data) { - struct ipu_crtc *ipu_crtc = platform_get_drvdata(pdev); + struct ipu_crtc *ipu_crtc = dev_get_drvdata(dev); imx_drm_remove_crtc(ipu_crtc->imx_crtc); ipu_plane_put_resources(ipu_crtc->plane[0]); ipu_put_resources(ipu_crtc); +} + +static const struct component_ops ipu_crtc_ops = { + .bind = ipu_drm_bind, + .unbind = ipu_drm_unbind, +}; +static int ipu_drm_probe(struct platform_device *pdev) +{ + int ret; + + if (!pdev->dev.platform_data) + return -EINVAL; + + ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); + if (ret) + return ret; + + return component_add(&pdev->dev, &ipu_crtc_ops); +} + +static int ipu_drm_remove(struct platform_device *pdev) +{ + component_del(&pdev->dev, &ipu_crtc_ops); return 0; } diff --git a/drivers/staging/imx-drm/parallel-display.c b/drivers/staging/imx-drm/parallel-display.c index 12bcf4f58bdf..4019cae35ff9 100644 --- a/drivers/staging/imx-drm/parallel-display.c +++ b/drivers/staging/imx-drm/parallel-display.c @@ -18,6 +18,7 @@ * MA 02110-1301, USA. */ +#include #include #include #include @@ -192,15 +193,15 @@ static int imx_pd_register(struct imx_parallel_display *imxpd) return 0; } -static int imx_pd_probe(struct platform_device *pdev) +static int imx_pd_bind(struct device *dev, struct device *master, void *data) { - struct device_node *np = pdev->dev.of_node; + struct device_node *np = dev->of_node; const u8 *edidp; struct imx_parallel_display *imxpd; int ret; const char *fmt; - imxpd = devm_kzalloc(&pdev->dev, sizeof(*imxpd), GFP_KERNEL); + imxpd = devm_kzalloc(dev, sizeof(*imxpd), GFP_KERNEL); if (!imxpd) return -ENOMEM; @@ -218,7 +219,7 @@ static int imx_pd_probe(struct platform_device *pdev) imxpd->interface_pix_fmt = V4L2_PIX_FMT_BGR666; } - imxpd->dev = &pdev->dev; + imxpd->dev = dev; ret = imx_pd_register(imxpd); if (ret) @@ -226,14 +227,15 @@ static int imx_pd_probe(struct platform_device *pdev) ret = imx_drm_encoder_add_possible_crtcs(imxpd->imx_drm_encoder, np); - platform_set_drvdata(pdev, imxpd); + dev_set_drvdata(dev, imxpd); return 0; } -static int imx_pd_remove(struct platform_device *pdev) +static void imx_pd_unbind(struct device *dev, struct device *master, + void *data) { - struct imx_parallel_display *imxpd = platform_get_drvdata(pdev); + struct imx_parallel_display *imxpd = dev_get_drvdata(dev); struct drm_connector *connector = &imxpd->connector; struct drm_encoder *encoder = &imxpd->encoder; @@ -241,7 +243,21 @@ static int imx_pd_remove(struct platform_device *pdev) imx_drm_remove_connector(imxpd->imx_drm_connector); imx_drm_remove_encoder(imxpd->imx_drm_encoder); +} +static const struct component_ops imx_pd_ops = { + .bind = imx_pd_bind, + .unbind = imx_pd_unbind, +}; + +static int imx_pd_probe(struct platform_device *pdev) +{ + return component_add(&pdev->dev, &imx_pd_ops); +} + +static int imx_pd_remove(struct platform_device *pdev) +{ + component_del(&pdev->dev, &imx_pd_ops); return 0; } -- cgit v1.2.3 From 49ba179086740743f035daacf60a18f9cb0c8f6b Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 5 Mar 2014 10:20:58 +0100 Subject: ARM: dts: imx53-mba53: Fix TVE DDC I2C bus property This patch fixes the Television Encoder node's DDC I2C bus property to use the common property name of 'ddc-i2c-bus' instead of just 'ddc'. Signed-off-by: Philipp Zabel Signed-off-by: Russell King --- arch/arm/boot/dts/imx53-mba53.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/imx53-mba53.dts b/arch/arm/boot/dts/imx53-mba53.dts index 9b6e76980a74..f2affb0cb959 100644 --- a/arch/arm/boot/dts/imx53-mba53.dts +++ b/arch/arm/boot/dts/imx53-mba53.dts @@ -234,7 +234,7 @@ &tve { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_vga_sync_1>; - ddc = <&i2c3>; + i2c-ddc-bus = <&i2c3>; fsl,tve-mode = "vga"; fsl,hsync-pin = <4>; fsl,vsync-pin = <6>; -- cgit v1.2.3 From de10e04e8cc60e1e273c83e356184f9200a8deb8 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 5 Mar 2014 10:20:59 +0100 Subject: ARM: dts: imx51: Add IPU ports and endpoints, move imx-drm node to dtsi This patch connects IPU and and parallel display device tree nodes using the OF graph bindings described in Documentation/devicetree/bindings/media/video-interfaces.txt The IPU ports correspond to the two display interfaces. The order of endpoints in the ports is arbitrary. Since the imx-drm node now only needs to contain links to the display interfaces, it can be moved to the SoC dtsi level. At the board level, only connections between the display interface ports and panels have to be added. Signed-off-by: Philipp Zabel Signed-off-by: Russell King --- arch/arm/boot/dts/imx51-apf51dev.dts | 11 ++++++++++- arch/arm/boot/dts/imx51-babbage.dts | 28 ++++++++++++++++++++-------- arch/arm/boot/dts/imx51.dtsi | 22 +++++++++++++++++++++- 3 files changed, 51 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/imx51-apf51dev.dts b/arch/arm/boot/dts/imx51-apf51dev.dts index 5a7f552786a1..d3f98141462c 100644 --- a/arch/arm/boot/dts/imx51-apf51dev.dts +++ b/arch/arm/boot/dts/imx51-apf51dev.dts @@ -18,7 +18,6 @@ display@di1 { compatible = "fsl,imx-parallel-display"; - crtcs = <&ipu 0>; interface-pix-fmt = "bgr666"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ipu_disp1_1>; @@ -41,6 +40,12 @@ pixelclk-active = <0>; }; }; + + port { + display_in: endpoint { + remote-endpoint = <&ipu_di0_disp0>; + }; + }; }; gpio-keys { @@ -122,3 +127,7 @@ }; }; }; + +&ipu_di0_disp0 { + remote-endpoint = <&display_in>; +}; diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts index 6ff15a0eacb3..671927145632 100644 --- a/arch/arm/boot/dts/imx51-babbage.dts +++ b/arch/arm/boot/dts/imx51-babbage.dts @@ -23,7 +23,6 @@ display0: display@di0 { compatible = "fsl,imx-parallel-display"; - crtcs = <&ipu 0>; interface-pix-fmt = "rgb24"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ipu_disp1_1>; @@ -41,11 +40,16 @@ vsync-len = <10>; }; }; + + port { + display0_in: endpoint { + remote-endpoint = <&ipu_di0_disp0>; + }; + }; }; display1: display@di1 { compatible = "fsl,imx-parallel-display"; - crtcs = <&ipu 1>; interface-pix-fmt = "rgb565"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ipu_disp2_1>; @@ -68,6 +72,12 @@ pixelclk-active = <0>; }; }; + + port { + display1_in: endpoint { + remote-endpoint = <&ipu_di1_disp1>; + }; + }; }; gpio-keys { @@ -81,12 +91,6 @@ }; }; - imx-drm { - compatible = "fsl,imx-drm"; - crtcs = <&ipu 0>, <&ipu 1>; - connectors = <&display0>, <&display1>; - }; - sound { compatible = "fsl,imx51-babbage-sgtl5000", "fsl,imx-audio-sgtl5000"; @@ -264,6 +268,14 @@ }; }; +&ipu_di0_disp0 { + remote-endpoint = <&display0_in>; +}; + +&ipu_di1_disp1 { + remote-endpoint = <&display1_in>; +}; + &ssi2 { fsl,mode = "i2s-slave"; status = "okay"; diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi index 4bcdd3ad15e5..28c96aada80b 100644 --- a/arch/arm/boot/dts/imx51.dtsi +++ b/arch/arm/boot/dts/imx51.dtsi @@ -79,6 +79,11 @@ }; }; + display-subsystem { + compatible = "fsl,imx-display-subsystem"; + ports = <&ipu_di0>, <&ipu_di1>; + }; + soc { #address-cells = <1>; #size-cells = <1>; @@ -92,13 +97,28 @@ }; ipu: ipu@40000000 { - #crtc-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; compatible = "fsl,imx51-ipu"; reg = <0x40000000 0x20000000>; interrupts = <11 10>; clocks = <&clks 59>, <&clks 110>, <&clks 61>; clock-names = "bus", "di0", "di1"; resets = <&src 2>; + + ipu_di0: port@2 { + reg = <2>; + + ipu_di0_disp0: endpoint { + }; + }; + + ipu_di1: port@3 { + reg = <3>; + + ipu_di1_disp1: endpoint { + }; + }; }; aips@70000000 { /* AIPS1 */ -- cgit v1.2.3 From e05c8c9a790a0670bc166144e6dfbe7db148bd34 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 5 Mar 2014 10:21:00 +0100 Subject: ARM: dts: imx53: Add IPU DI ports and endpoints, move imx-drm node to dtsi This patch connects IPU and display encoder (VGA, LVDS) device tree nodes, as well as parallel displays on the DISP0 and DISP1 outputs, using the OF graph bindings described in Documentation/devicetree/bindings/media/video-interfaces.txt The IPU ports correspond to the two display interfaces. The order of endpoints in the ports is arbitrary. Since the imx-drm node now only needs to contain links to the display interfaces, it can be moved to the SoC dtsi level. At the board level, only connections between the display interface ports and encoders or panels have to be added. Signed-off-by: Philipp Zabel Signed-off-by: Russell King --- arch/arm/boot/dts/imx53-m53evk.dts | 17 +++++----- arch/arm/boot/dts/imx53-mba53.dts | 15 +++++---- arch/arm/boot/dts/imx53-qsb.dts | 17 +++++----- arch/arm/boot/dts/imx53.dtsi | 64 +++++++++++++++++++++++++++++++++++--- 4 files changed, 89 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/imx53-m53evk.dts b/arch/arm/boot/dts/imx53-m53evk.dts index ee6107b6484c..0298adc73bb7 100644 --- a/arch/arm/boot/dts/imx53-m53evk.dts +++ b/arch/arm/boot/dts/imx53-m53evk.dts @@ -23,7 +23,6 @@ soc { display1: display@di1 { compatible = "fsl,imx-parallel-display"; - crtcs = <&ipu 1>; interface-pix-fmt = "bgr666"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ipu_disp2_1>; @@ -44,6 +43,12 @@ }; }; }; + + port { + display1_in: endpoint { + remote-endpoint = <&ipu_di1_disp1>; + }; + }; }; backlight { @@ -53,12 +58,6 @@ default-brightness-level = <6>; }; - imx-drm { - compatible = "fsl,imx-drm"; - crtcs = <&ipu 1>; - connectors = <&display1>; - }; - leds { compatible = "gpio-leds"; pinctrl-names = "default"; @@ -227,6 +226,10 @@ }; }; +&ipu_di1_disp1 { + remote-endpoint = <&display1_in>; +}; + &nfc { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_nand_1>; diff --git a/arch/arm/boot/dts/imx53-mba53.dts b/arch/arm/boot/dts/imx53-mba53.dts index f2affb0cb959..a5b55c603591 100644 --- a/arch/arm/boot/dts/imx53-mba53.dts +++ b/arch/arm/boot/dts/imx53-mba53.dts @@ -38,15 +38,14 @@ compatible = "fsl,imx-parallel-display"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_disp1_1>; - crtcs = <&ipu 1>; interface-pix-fmt = "rgb24"; status = "disabled"; - }; - imx-drm { - compatible = "fsl,imx-drm"; - crtcs = <&ipu 1>; - connectors = <&disp1>, <&tve>; + port { + display1_in: endpoint { + remote-endpoint = <&ipu_di1_disp1>; + }; + }; }; reg_3p2v: 3p2v { @@ -147,6 +146,10 @@ }; }; +&ipu_di1_disp1 { + remote-endpoint = <&display1_in>; +}; + &cspi { status = "okay"; }; diff --git a/arch/arm/boot/dts/imx53-qsb.dts b/arch/arm/boot/dts/imx53-qsb.dts index 3cb4f7791a91..8b254289344f 100644 --- a/arch/arm/boot/dts/imx53-qsb.dts +++ b/arch/arm/boot/dts/imx53-qsb.dts @@ -23,7 +23,6 @@ display0: display@di0 { compatible = "fsl,imx-parallel-display"; - crtcs = <&ipu 0>; interface-pix-fmt = "rgb565"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ipu_disp0_1>; @@ -46,6 +45,12 @@ pixelclk-active = <0>; }; }; + + port { + display0_in: endpoint { + remote-endpoint = <&ipu_di0_disp0>; + }; + }; }; gpio-keys { @@ -72,12 +77,6 @@ }; }; - imx-drm { - compatible = "fsl,imx-drm"; - crtcs = <&ipu 0>; - connectors = <&display0>; - }; - leds { compatible = "gpio-leds"; pinctrl-names = "default"; @@ -132,6 +131,10 @@ status = "okay"; }; +&ipu_di0_disp0 { + remote-endpoint = <&display0_in>; +}; + &ssi2 { fsl,mode = "i2s-slave"; status = "okay"; diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index 4307e80b2d2e..04d3127edfe1 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi @@ -45,6 +45,11 @@ }; }; + display-subsystem { + compatible = "fsl,imx-display-subsystem"; + ports = <&ipu_di0>, <&ipu_di1>; + }; + tzic: tz-interrupt-controller@0fffc000 { compatible = "fsl,imx53-tzic", "fsl,tzic"; interrupt-controller; @@ -85,13 +90,49 @@ ranges; ipu: ipu@18000000 { - #crtc-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; compatible = "fsl,imx53-ipu"; reg = <0x18000000 0x080000000>; interrupts = <11 10>; clocks = <&clks 59>, <&clks 110>, <&clks 61>; clock-names = "bus", "di0", "di1"; resets = <&src 2>; + + ipu_di0: port@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + + ipu_di0_disp0: endpoint@0 { + reg = <0>; + }; + + ipu_di0_lvds0: endpoint@1 { + reg = <1>; + remote-endpoint = <&lvds0_in>; + }; + }; + + ipu_di1: port@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + + ipu_di1_disp1: endpoint@0 { + reg = <0>; + }; + + ipu_di1_lvds1: endpoint@1 { + reg = <1>; + remote-endpoint = <&lvds1_in>; + }; + + ipu_di1_tve: endpoint@2 { + reg = <2>; + remote-endpoint = <&tve_in>; + }; + }; }; aips@50000000 { /* AIPS1 */ @@ -838,14 +879,24 @@ lvds-channel@0 { reg = <0>; - crtcs = <&ipu 0>; status = "disabled"; + + port { + lvds0_in: endpoint { + remote-endpoint = <&ipu_di0_lvds0>; + }; + }; }; lvds-channel@1 { reg = <1>; - crtcs = <&ipu 1>; status = "disabled"; + + port { + lvds1_in: endpoint { + remote-endpoint = <&ipu_di0_lvds0>; + }; + }; }; }; @@ -1103,8 +1154,13 @@ interrupts = <92>; clocks = <&clks 69>, <&clks 116>; clock-names = "tve", "di_sel"; - crtcs = <&ipu 1>; status = "disabled"; + + port { + tve_in: endpoint { + remote-endpoint = <&ipu_di1_tve>; + }; + }; }; vpu: vpu@63ff4000 { -- cgit v1.2.3 From 4520e69238b3d55094561432b969d82658055f88 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 5 Mar 2014 10:21:01 +0100 Subject: ARM: dts: imx6qdl: Add IPU DI ports and endpoints, move imx-drm node to dtsi This patch connects IPU and display encoder (HDMI, LVDS, MIPI) device tree nodes, as well as parallel displays on the DISP0 and DISP1 outputs, using the OF graph bindings described in Documentation/devicetree/bindings/media/video-interfaces.txt The IPU ports correspond to the two display interfaces. The order of endpoints in the ports is arbitrary. Each encoder with an associated input multiplexer has multiple input ports in the device tree. The order and reg property of the ports must correspond to the multiplexer input order. Since the imx-drm node now only needs to contain links to the display interfaces, it can be moved to the SoC dtsi level. At the board level, only connections between the display interface ports and encoders or panels have to be added. Signed-off-by: Philipp Zabel Signed-off-by: Russell King --- arch/arm/boot/dts/imx6dl.dtsi | 22 +++--- arch/arm/boot/dts/imx6q-sabresd.dts | 4 -- arch/arm/boot/dts/imx6q.dtsi | 124 ++++++++++++++++++++++++++++++-- arch/arm/boot/dts/imx6qdl-sabresd.dtsi | 6 -- arch/arm/boot/dts/imx6qdl.dtsi | 128 ++++++++++++++++++++++++++++++++- 5 files changed, 253 insertions(+), 31 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/imx6dl.dtsi b/arch/arm/boot/dts/imx6dl.dtsi index 6dc397022214..25bbdd6f214b 100644 --- a/arch/arm/boot/dts/imx6dl.dtsi +++ b/arch/arm/boot/dts/imx6dl.dtsi @@ -70,6 +70,15 @@ }; }; }; + + display-subsystem { + compatible = "fsl,imx-display-subsystem"; + ports = <&ipu1_di0>, <&ipu1_di1>; + }; +}; + +&hdmi { + compatible = "fsl,imx6dl-hdmi"; }; &ldb { @@ -79,17 +88,4 @@ clock-names = "di0_pll", "di1_pll", "di0_sel", "di1_sel", "di0", "di1"; - - lvds-channel@0 { - crtcs = <&ipu1 0>, <&ipu1 1>; - }; - - lvds-channel@1 { - crtcs = <&ipu1 0>, <&ipu1 1>; - }; -}; - -&hdmi { - compatible = "fsl,imx6dl-hdmi"; - crtcs = <&ipu1 0>, <&ipu1 1>; }; diff --git a/arch/arm/boot/dts/imx6q-sabresd.dts b/arch/arm/boot/dts/imx6q-sabresd.dts index 66f220a82e45..9cbdfe7a0931 100644 --- a/arch/arm/boot/dts/imx6q-sabresd.dts +++ b/arch/arm/boot/dts/imx6q-sabresd.dts @@ -20,10 +20,6 @@ compatible = "fsl,imx6q-sabresd", "fsl,imx6q"; }; -&imx_drm { - crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>; -}; - &sata { status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index 187fe33ba515..2a8d9de666c9 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -132,13 +132,84 @@ }; ipu2: ipu@02800000 { - #crtc-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; compatible = "fsl,imx6q-ipu"; reg = <0x02800000 0x400000>; interrupts = <0 8 0x4 0 7 0x4>; clocks = <&clks 133>, <&clks 134>, <&clks 137>; clock-names = "bus", "di0", "di1"; resets = <&src 4>; + + ipu2_di0: port@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + + ipu2_di0_disp0: endpoint@0 { + }; + + ipu2_di0_hdmi: endpoint@1 { + remote-endpoint = <&hdmi_mux_2>; + }; + + ipu2_di0_mipi: endpoint@2 { + }; + + ipu2_di0_lvds0: endpoint@3 { + remote-endpoint = <&lvds0_mux_2>; + }; + + ipu2_di0_lvds1: endpoint@4 { + remote-endpoint = <&lvds1_mux_2>; + }; + }; + + ipu2_di1: port@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + + ipu2_di1_hdmi: endpoint@1 { + remote-endpoint = <&hdmi_mux_3>; + }; + + ipu2_di1_mipi: endpoint@2 { + }; + + ipu2_di1_lvds0: endpoint@3 { + remote-endpoint = <&lvds0_mux_3>; + }; + + ipu2_di1_lvds1: endpoint@4 { + remote-endpoint = <&lvds1_mux_3>; + }; + }; + }; + }; + + display-subsystem { + compatible = "fsl,imx-display-subsystem"; + ports = <&ipu1_di0>, <&ipu1_di1>, <&ipu2_di0>, <&ipu2_di1>; + }; +}; + +&hdmi { + compatible = "fsl,imx6q-hdmi"; + + port@2 { + reg = <2>; + + hdmi_mux_2: endpoint { + remote-endpoint = <&ipu2_di0_hdmi>; + }; + }; + + port@3 { + reg = <3>; + + hdmi_mux_3: endpoint { + remote-endpoint = <&ipu2_di1_hdmi>; }; }; }; @@ -152,15 +223,56 @@ "di0", "di1"; lvds-channel@0 { - crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>; + port@2 { + reg = <2>; + + lvds0_mux_2: endpoint { + remote-endpoint = <&ipu2_di0_lvds0>; + }; + }; + + port@3 { + reg = <3>; + + lvds0_mux_3: endpoint { + remote-endpoint = <&ipu2_di1_lvds0>; + }; + }; }; lvds-channel@1 { - crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>; + port@2 { + reg = <2>; + + lvds1_mux_2: endpoint { + remote-endpoint = <&ipu2_di0_lvds1>; + }; + }; + + port@3 { + reg = <3>; + + lvds1_mux_3: endpoint { + remote-endpoint = <&ipu2_di1_lvds1>; + }; + }; }; }; -&hdmi { - compatible = "fsl,imx6q-hdmi"; - crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>; +&mipi_dsi { + port@2 { + reg = <2>; + + mipi_mux_2: endpoint { + remote-endpoint = <&ipu2_di0_mipi>; + }; + }; + + port@3 { + reg = <3>; + + mipi_mux_3: endpoint { + remote-endpoint = <&ipu2_di1_mipi>; + }; + }; }; diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi index dfca3e001398..e75e11b36dff 100644 --- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi @@ -62,12 +62,6 @@ }; }; - imx_drm: imx-drm { - compatible = "fsl,imx-drm"; - crtcs = <&ipu1 0>, <&ipu1 1>; - connectors = <&ldb>; - }; - sound { compatible = "fsl,imx6q-sabresd-wm8962", "fsl,imx-audio-wm8962"; diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 930ebe0c2937..64a8cbe9480f 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -1358,23 +1358,77 @@ status = "disabled"; lvds-channel@0 { + #address-cells = <1>; + #size-cells = <0>; reg = <0>; status = "disabled"; + + port@0 { + reg = <0>; + + lvds0_mux_0: endpoint { + remote-endpoint = <&ipu1_di0_lvds0>; + }; + }; + + port@1 { + reg = <1>; + + lvds0_mux_1: endpoint { + remote-endpoint = <&ipu1_di1_lvds0>; + }; + }; }; lvds-channel@1 { + #address-cells = <1>; + #size-cells = <0>; reg = <1>; status = "disabled"; + + port@0 { + reg = <0>; + + lvds1_mux_0: endpoint { + remote-endpoint = <&ipu1_di0_lvds1>; + }; + }; + + port@1 { + reg = <1>; + + lvds1_mux_1: endpoint { + remote-endpoint = <&ipu1_di1_lvds1>; + }; + }; }; }; hdmi: hdmi@0120000 { + #address-cells = <1>; + #size-cells = <0>; reg = <0x00120000 0x9000>; interrupts = <0 115 0x04>; gpr = <&gpr>; clocks = <&clks 123>, <&clks 124>; clock-names = "iahb", "isfr"; status = "disabled"; + + port@0 { + reg = <0>; + + hdmi_mux_0: endpoint { + remote-endpoint = <&ipu1_di0_hdmi>; + }; + }; + + port@1 { + reg = <1>; + + hdmi_mux_1: endpoint { + remote-endpoint = <&ipu1_di1_hdmi>; + }; + }; }; dcic1: dcic@020e4000 { @@ -1588,8 +1642,27 @@ reg = <0x021dc000 0x4000>; }; - mipi@021e0000 { /* MIPI-DSI */ + mipi_dsi: mipi@021e0000 { + #address-cells = <1>; + #size-cells = <0>; reg = <0x021e0000 0x4000>; + status = "disabled"; + + port@0 { + reg = <0>; + + mipi_mux_0: endpoint { + remote-endpoint = <&ipu1_di0_mipi>; + }; + }; + + port@1 { + reg = <1>; + + mipi_mux_1: endpoint { + remote-endpoint = <&ipu1_di1_mipi>; + }; + }; }; vdoa@021e4000 { @@ -1643,13 +1716,64 @@ }; ipu1: ipu@02400000 { - #crtc-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; compatible = "fsl,imx6q-ipu"; reg = <0x02400000 0x400000>; interrupts = <0 6 0x4 0 5 0x4>; clocks = <&clks 130>, <&clks 131>, <&clks 132>; clock-names = "bus", "di0", "di1"; resets = <&src 2>; + + ipu1_di0: port@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + + ipu1_di0_disp0: endpoint@0 { + }; + + ipu1_di0_hdmi: endpoint@1 { + remote-endpoint = <&hdmi_mux_0>; + }; + + ipu1_di0_mipi: endpoint@2 { + remote-endpoint = <&mipi_mux_0>; + }; + + ipu1_di0_lvds0: endpoint@3 { + remote-endpoint = <&lvds0_mux_0>; + }; + + ipu1_di0_lvds1: endpoint@4 { + remote-endpoint = <&lvds1_mux_0>; + }; + }; + + ipu1_di1: port@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + + ipu1_di0_disp1: endpoint@0 { + }; + + ipu1_di1_hdmi: endpoint@1 { + remote-endpoint = <&hdmi_mux_1>; + }; + + ipu1_di1_mipi: endpoint@2 { + remote-endpoint = <&mipi_mux_1>; + }; + + ipu1_di1_lvds0: endpoint@3 { + remote-endpoint = <&lvds0_mux_1>; + }; + + ipu1_di1_lvds1: endpoint@4 { + remote-endpoint = <&lvds1_mux_1>; + }; + }; }; }; }; -- cgit v1.2.3