From 6d54e3d275de861c0290c85fec8c0ed6deaf6ad5 Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Sat, 21 Dec 2013 21:38:12 +0100 Subject: [PATCH 01/12] drm/panel: Add support for Samsung LTN101NT05 panel The Samsung LNT101NT05 10.1" WXVGA panel can be supported by the simple panel driver. Cc: linux-fbdev@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: David Airlie Signed-off-by: Marc Dietrich Signed-off-by: Thierry Reding --- .../bindings/panel/samsung,ltn101nt05.txt | 7 ++++++ drivers/gpu/drm/panel/panel-simple.c | 25 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 Documentation/devicetree/bindings/panel/samsung,ltn101nt05.txt diff --git a/Documentation/devicetree/bindings/panel/samsung,ltn101nt05.txt b/Documentation/devicetree/bindings/panel/samsung,ltn101nt05.txt new file mode 100644 index 000000000000..ef522c6bb85f --- /dev/null +++ b/Documentation/devicetree/bindings/panel/samsung,ltn101nt05.txt @@ -0,0 +1,7 @@ +Samsung Electronics 10.1" WSVGA TFT LCD panel + +Required properties: +- compatible: should be "samsung,ltn101nt05" + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 3e611afc93f4..a2d5e3f1205e 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -338,6 +338,28 @@ static const struct panel_desc chunghwa_claa101wb01 = { }, }; +static const struct drm_display_mode samsung_ltn101nt05_mode = { + .clock = 54030, + .hdisplay = 1024, + .hsync_start = 1024 + 24, + .hsync_end = 1024 + 24 + 136, + .htotal = 1024 + 24 + 136 + 160, + .vdisplay = 600, + .vsync_start = 600 + 3, + .vsync_end = 600 + 3 + 6, + .vtotal = 600 + 3 + 6 + 61, + .vrefresh = 60, +}; + +static const struct panel_desc samsung_ltn101nt05 = { + .modes = &samsung_ltn101nt05_mode, + .num_modes = 1, + .size = { + .width = 1024, + .height = 600, + }, +}; + static const struct of_device_id platform_of_match[] = { { .compatible = "auo,b101aw03", @@ -345,6 +367,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "chunghwa,claa101wb01", .data = &chunghwa_claa101wb01 + }, { + .compatible = "samsung,ltn101nt05", + .data = &samsung_ltn101nt05, }, { .compatible = "simple-panel", }, { From 4c9307577ef686e041d1525047ffdebfc465e329 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 7 Jan 2014 16:46:26 -0700 Subject: [PATCH 02/12] drm/panel: Add support for Chunghwa CLAA101WA01A panel The Chunghwa CLAA101WA01A is a 10.1" 1366x768 panel, which can be supported by the simple panel driver. Signed-off-by: Stephen Warren Signed-off-by: Thierry Reding --- .../bindings/panel/chunghwa,claa101wa01a.txt | 7 ++++++ drivers/gpu/drm/panel/panel-simple.c | 25 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 Documentation/devicetree/bindings/panel/chunghwa,claa101wa01a.txt diff --git a/Documentation/devicetree/bindings/panel/chunghwa,claa101wa01a.txt b/Documentation/devicetree/bindings/panel/chunghwa,claa101wa01a.txt new file mode 100644 index 000000000000..f24614e4d5ec --- /dev/null +++ b/Documentation/devicetree/bindings/panel/chunghwa,claa101wa01a.txt @@ -0,0 +1,7 @@ +Chunghwa Picture Tubes Ltd. 10.1" WXGA TFT LCD panel + +Required properties: +- compatible: should be "chunghwa,claa101wa01a" + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index a2d5e3f1205e..520b569ae3c8 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -316,6 +316,28 @@ static const struct panel_desc auo_b101aw03 = { }, }; +static const struct drm_display_mode chunghwa_claa101wa01a_mode = { + .clock = 72070, + .hdisplay = 1366, + .hsync_start = 1366 + 58, + .hsync_end = 1366 + 58 + 58, + .htotal = 1366 + 58 + 58 + 58, + .vdisplay = 768, + .vsync_start = 768 + 4, + .vsync_end = 768 + 4 + 4, + .vtotal = 768 + 4 + 4 + 4, + .vrefresh = 60, +}; + +static const struct panel_desc chunghwa_claa101wa01a = { + .modes = &chunghwa_claa101wa01a_mode, + .num_modes = 1, + .size = { + .width = 220, + .height = 120, + }, +}; + static const struct drm_display_mode chunghwa_claa101wb01_mode = { .clock = 69300, .hdisplay = 1366, @@ -364,6 +386,9 @@ static const struct of_device_id platform_of_match[] = { { .compatible = "auo,b101aw03", .data = &auo_b101aw03, + }, { + .compatible = "chunghwa,claa101wa01a", + .data = &chunghwa_claa101wa01a }, { .compatible = "chunghwa,claa101wb01", .data = &chunghwa_claa101wb01 From ff5009ef8df87908a956412619e4f1bf1078ef5d Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 14 Jan 2014 12:58:54 +0100 Subject: [PATCH 03/12] drm/tegra: Don't check resource with devm_ioremap_resource() devm_ioremap_resource() does sanity checks on the given resource. No need to duplicate this in the driver. Signed-off-by: Wolfram Sang Reviewed-by: Terje Bergstrom Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/hdmi.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c index bc9cb1ac709b..6928015d11a4 100644 --- a/drivers/gpu/drm/tegra/hdmi.c +++ b/drivers/gpu/drm/tegra/hdmi.c @@ -1418,9 +1418,6 @@ static int tegra_hdmi_probe(struct platform_device *pdev) return err; regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!regs) - return -ENXIO; - hdmi->regs = devm_ioremap_resource(&pdev->dev, regs); if (IS_ERR(hdmi->regs)) return PTR_ERR(hdmi->regs); From db5f7a6e78303fd96dc87487d6976145f70ab84a Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 2 Jan 2014 21:27:33 +0000 Subject: [PATCH 04/12] drm: provide a helper for the encoder possible_crtcs mask The encoder possible_crtcs mask identifies which CRTCs can be bound to a particular encoder. Each bit from bit 0 defines an index in the list of CRTCs held in the DRM mode_config crtc_list. Rather than having drivers trying to track the position of their CRTCs in the list, expose the code which already exists for calculating the appropriate mask bit for a CRTC. Signed-off-by: Russell King Reviewed-by: David Herrmann Reviewed-by: Jani Nikula [treding@nvidia.com: add drm_crtc_index(), move to core] Signed-off-by: Thierry Reding --- drivers/gpu/drm/drm_crtc.c | 23 +++++++++++++++++++++++ drivers/gpu/drm/drm_crtc_helper.c | 18 +----------------- include/drm/drm_crtc.h | 13 +++++++++++++ 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index d6cf77c472e7..452bcbd0eab9 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -674,6 +674,29 @@ void drm_crtc_cleanup(struct drm_crtc *crtc) } EXPORT_SYMBOL(drm_crtc_cleanup); +/** + * drm_crtc_index - find the index of a registered CRTC + * @crtc: CRTC to find index for + * + * Given a registered CRTC, return the index of that CRTC within a DRM + * device's list of CRTCs. + */ +unsigned int drm_crtc_index(struct drm_crtc *crtc) +{ + unsigned int index = 0; + struct drm_crtc *tmp; + + list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) { + if (tmp == crtc) + return index; + + index++; + } + + BUG(); +} +EXPORT_SYMBOL(drm_crtc_index); + /** * drm_mode_probed_add - add a mode to a connector's probed mode list * @connector: connector the new mode diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 01361aba033b..940c678cf012 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -334,23 +334,7 @@ EXPORT_SYMBOL(drm_helper_disable_unused_functions); static bool drm_encoder_crtc_ok(struct drm_encoder *encoder, struct drm_crtc *crtc) { - struct drm_device *dev; - struct drm_crtc *tmp; - int crtc_mask = 1; - - WARN(!crtc, "checking null crtc?\n"); - - dev = crtc->dev; - - list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) { - if (tmp == crtc) - break; - crtc_mask <<= 1; - } - - if (encoder->possible_crtcs & crtc_mask) - return true; - return false; + return !!(encoder->possible_crtcs & drm_crtc_mask(crtc)); } /* diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index f32c5cd51f41..4f2e3e82f014 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -929,6 +929,19 @@ extern int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, const struct drm_crtc_funcs *funcs); extern void drm_crtc_cleanup(struct drm_crtc *crtc); +extern unsigned int drm_crtc_index(struct drm_crtc *crtc); + +/** + * drm_crtc_mask - find the mask of a registered CRTC + * @crtc: CRTC to find mask for + * + * Given a registered CRTC, return the mask bit of that CRTC for an + * encoder's possible_crtcs field. + */ +static inline uint32_t drm_crtc_mask(struct drm_crtc *crtc) +{ + return 1 << drm_crtc_index(crtc); +} extern void drm_connector_ida_init(void); extern void drm_connector_ida_destroy(void); From 3d887368701ef78fe17fc998fe5a74ac8f7c6d4c Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 13 Jan 2014 14:33:20 +0100 Subject: [PATCH 05/12] drm: Move drm_encoder_crtc_ok() to core Using the new drm_crtc_mask() function, drm_encoder_crtc_ok() can now be written in a significantly shorter way, so it can be moved to a header file and be made static inline. Signed-off-by: Thierry Reding --- drivers/gpu/drm/drm_crtc_helper.c | 13 ------------- include/drm/drm_crtc.h | 13 +++++++++++++ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 940c678cf012..48c90cbceb06 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -324,19 +324,6 @@ void drm_helper_disable_unused_functions(struct drm_device *dev) } EXPORT_SYMBOL(drm_helper_disable_unused_functions); -/** - * drm_encoder_crtc_ok - can a given crtc drive a given encoder? - * @encoder: encoder to test - * @crtc: crtc to test - * - * Return false if @encoder can't be driven by @crtc, true otherwise. - */ -static bool drm_encoder_crtc_ok(struct drm_encoder *encoder, - struct drm_crtc *crtc) -{ - return !!(encoder->possible_crtcs & drm_crtc_mask(crtc)); -} - /* * Check the CRTC we're going to map each output to vs. its current * CRTC. If they don't match, we have to disable the output and the CRTC diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 4f2e3e82f014..b3865a0e39f4 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -963,6 +963,19 @@ extern int drm_encoder_init(struct drm_device *dev, const struct drm_encoder_funcs *funcs, int encoder_type); +/** + * drm_encoder_crtc_ok - can a given crtc drive a given encoder? + * @encoder: encoder to test + * @crtc: crtc to test + * + * Return false if @encoder can't be driven by @crtc, true otherwise. + */ +static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder, + struct drm_crtc *crtc) +{ + return !!(encoder->possible_crtcs & drm_crtc_mask(crtc)); +} + extern int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, unsigned long possible_crtcs, From 14509916c35225d00e294cb161bdfd1108dda38c Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 13 Jan 2014 12:00:22 +0100 Subject: [PATCH 06/12] drm/i915: Use drm_encoder_crtc_ok() The intel_encoder_crtc_ok() is a duplicate of the drm_encoder_crtc_ok() function that used to be only available in the DRM CRTC helpers. It has recently been moved to the core, so the duplicate can now be dropped. Acked-by: Daniel Vetter Reviewed-by: Jani Nikula Signed-off-by: Thierry Reding --- drivers/gpu/drm/i915/intel_display.c | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 080f6fd4e839..1b20b4644979 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8493,28 +8493,6 @@ static struct drm_crtc_helper_funcs intel_helper_funcs = { .load_lut = intel_crtc_load_lut, }; -static bool intel_encoder_crtc_ok(struct drm_encoder *encoder, - struct drm_crtc *crtc) -{ - struct drm_device *dev; - struct drm_crtc *tmp; - int crtc_mask = 1; - - WARN(!crtc, "checking null crtc?\n"); - - dev = crtc->dev; - - list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) { - if (tmp == crtc) - break; - crtc_mask <<= 1; - } - - if (encoder->possible_crtcs & crtc_mask) - return true; - return false; -} - /** * intel_modeset_update_staged_output_state * @@ -9679,8 +9657,8 @@ intel_modeset_stage_output_state(struct drm_device *dev, } /* Make sure the new CRTC will work with the encoder */ - if (!intel_encoder_crtc_ok(&connector->new_encoder->base, - new_crtc)) { + if (!drm_encoder_crtc_ok(&connector->new_encoder->base, + new_crtc)) { return -EINVAL; } connector->encoder->new_crtc = to_intel_crtc(new_crtc); From 456ac56b7d9f49b519b436b36a708cf46e5aeefb Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 10 Jan 2014 16:56:06 +0100 Subject: [PATCH 07/12] drm/tegra: Fix possible CRTC mask for RGB outputs The mask of possible CRTCs that an output (DRM encoder) can be attached to is relative to the position within the DRM device's list of CRTCs. Deferred probing can cause this to not match the pipe number associated with a CRTC. Use the newly introduced drm_crtc_mask() to compute the mask by looking up the proper index of the given CRTC in the list. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/rgb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c index 03885bb8dcc0..338f7f6561d7 100644 --- a/drivers/gpu/drm/tegra/rgb.c +++ b/drivers/gpu/drm/tegra/rgb.c @@ -258,7 +258,7 @@ int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc) * RGB outputs are an exception, so we make sure they can be attached * to only their parent display controller. */ - rgb->output.encoder.possible_crtcs = 1 << dc->pipe; + rgb->output.encoder.possible_crtcs = drm_crtc_mask(&dc->base); return 0; } From acde541324dcfe443791da2f3926614d35429222 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 13 Jan 2014 12:56:19 +0100 Subject: [PATCH 08/12] drm/tegra: Clarify how panel modes override others When a panel advertises one or more modes, they are used exclusively. Other methods for obtaining the mode, such as DDC as used for HDMI or binary EDID blobs embedded in the DT, are ignored. The panel drivers should be providing this functionality if they want to expose it as well. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/output.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c index f1b5030f55e3..921e4001a090 100644 --- a/drivers/gpu/drm/tegra/output.c +++ b/drivers/gpu/drm/tegra/output.c @@ -18,6 +18,10 @@ static int tegra_connector_get_modes(struct drm_connector *connector) struct edid *edid = NULL; int err = 0; + /* + * If the panel provides one or more modes, use them exclusively and + * ignore any other means of obtaining a mode. + */ if (output->panel) { err = output->panel->funcs->get_modes(output->panel); if (err > 0) From 7236aa03ff6e65e8678886a4d5ce12d780e1fd94 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 13 Jan 2014 13:58:17 +0100 Subject: [PATCH 09/12] drm/tegra: Use proper data type The last argument to of_get_property() is a pointer to an int, rather than size_t. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/output.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c index 921e4001a090..57cecbd18ca8 100644 --- a/drivers/gpu/drm/tegra/output.c +++ b/drivers/gpu/drm/tegra/output.c @@ -191,8 +191,7 @@ int tegra_output_probe(struct tegra_output *output) { struct device_node *ddc, *panel; enum of_gpio_flags flags; - size_t size; - int err; + int err, size; if (!output->of_node) output->of_node = output->dev->of_node; From be2cd59b80dad88094d558432dfc01b8c703b595 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 13 Jan 2014 14:00:19 +0100 Subject: [PATCH 10/12] gpu: host1x: Remove unnecessary include Nothing from the asm/mach/irq.h header is needed in this file, so there is no need to include it. Signed-off-by: Thierry Reding --- drivers/gpu/host1x/hw/intr_hw.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/host1x/hw/intr_hw.c b/drivers/gpu/host1x/hw/intr_hw.c index b26dcc83bc1b..db9017adfe2b 100644 --- a/drivers/gpu/host1x/hw/intr_hw.c +++ b/drivers/gpu/host1x/hw/intr_hw.c @@ -20,7 +20,6 @@ #include #include #include -#include #include "../intr.h" #include "../dev.h" From 70bf6878a874523e4b62992d07b5739298f8c1eb Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 9 Jan 2014 11:37:34 -0700 Subject: [PATCH 11/12] drm/panel: update EDID BLOB in panel_simple_get_modes() This stashes away the EDID data so that the sysfs per-connector file "edid" can display it. Without this change, the "edid" file is always empty. Signed-off-by: Stephen Warren Signed-off-by: Thierry Reding --- drivers/gpu/drm/panel/panel-simple.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 520b569ae3c8..59d52ca2c67f 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -162,6 +162,7 @@ static int panel_simple_get_modes(struct drm_panel *panel) /* probe EDID if a DDC bus is available */ if (p->ddc) { struct edid *edid = drm_get_edid(panel->connector, p->ddc); + drm_mode_connector_update_edid_property(panel->connector, edid); if (edid) { num += drm_add_edid_modes(panel->connector, edid); kfree(edid); From 13411ddd319057ae334a4084ebcf2c741b317f34 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 9 Jan 2014 17:08:36 +0100 Subject: [PATCH 12/12] drm/tegra: Obtain head number from DT The head number of a given display controller is fixed in hardware and required to program outputs appropriately. Relying on the driver probe order to determine this number will not work, since that could yield a situation where the second head was probed first and would be assigned head number 0 instead of 1. By explicitly specifying the head number in the device tree, it is no longer necessary to rely on these assumptions. As a fallback, if the property isn't available, derive the head number from the display controller node's position in the device tree. That's somewhat more reliable than the previous default but not a proper solution. Tested-by: Stephen Warren Signed-off-by: Thierry Reding --- .../bindings/gpu/nvidia,tegra20-host1x.txt | 3 ++ drivers/gpu/drm/tegra/dc.c | 41 ++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt b/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt index 9e9008f8fa32..efaeec8961b6 100644 --- a/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt +++ b/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt @@ -118,6 +118,9 @@ of the following host1x client modules: See ../reset/reset.txt for details. - reset-names: Must include the following entries: - dc + - nvidia,head: The number of the display controller head. This is used to + setup the various types of output to receive video data from the given + head. Each display controller node has a child node, named "rgb", that represents the RGB output associated with the controller. It can take the following diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 386f3b4b0094..9336006b475d 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -1100,8 +1100,6 @@ static int tegra_dc_init(struct host1x_client *client) struct tegra_dc *dc = host1x_client_to_dc(client); int err; - dc->pipe = tegra->drm->mode_config.num_crtc; - drm_crtc_init(tegra->drm, &dc->base, &tegra_crtc_funcs); drm_mode_crtc_set_gamma_size(&dc->base, 256); drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs); @@ -1187,6 +1185,41 @@ static const struct of_device_id tegra_dc_of_match[] = { } }; +static int tegra_dc_parse_dt(struct tegra_dc *dc) +{ + struct device_node *np; + u32 value = 0; + int err; + + err = of_property_read_u32(dc->dev->of_node, "nvidia,head", &value); + if (err < 0) { + dev_err(dc->dev, "missing \"nvidia,head\" property\n"); + + /* + * If the nvidia,head property isn't present, try to find the + * correct head number by looking up the position of this + * display controller's node within the device tree. Assuming + * that the nodes are ordered properly in the DTS file and + * that the translation into a flattened device tree blob + * preserves that ordering this will actually yield the right + * head number. + * + * If those assumptions don't hold, this will still work for + * cases where only a single display controller is used. + */ + for_each_matching_node(np, tegra_dc_of_match) { + if (np == dc->dev->of_node) + break; + + value++; + } + } + + dc->pipe = value; + + return 0; +} + static int tegra_dc_probe(struct platform_device *pdev) { const struct of_device_id *id; @@ -1207,6 +1240,10 @@ static int tegra_dc_probe(struct platform_device *pdev) dc->dev = &pdev->dev; dc->soc = id->data; + err = tegra_dc_parse_dt(dc); + if (err < 0) + return err; + dc->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(dc->clk)) { dev_err(&pdev->dev, "failed to get clock\n");