drm/tegra: Obtain head number from DT
authorThierry Reding <treding@nvidia.com>
Thu, 9 Jan 2014 16:08:36 +0000 (17:08 +0100)
committerThierry Reding <treding@nvidia.com>
Thu, 23 Jan 2014 14:51:32 +0000 (15:51 +0100)
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 <swarren@nvidia.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt
drivers/gpu/drm/tegra/dc.c

index 9e9008f8fa3231905428d8e1b62cf2a864008b31..efaeec8961b64bddba0df9d48af9af65e630f659 100644 (file)
@@ -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
index 386f3b4b00940660f72c889e91b8068ad34e9af4..9336006b475d70b7494f1694d8661c07c2cd882a 100644 (file)
@@ -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");