diff mbox

[v2,2/2] drm/tegra: Obtain head number from DT

Message ID 1389710758-29444-3-git-send-email-treding@nvidia.com (mailing list archive)
State New, archived
Headers show

Commit Message

Thierry Reding Jan. 14, 2014, 2:45 p.m. UTC
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.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
Changes in v2:
- if the nvidia,head property isn't present, find the position of the
  display controller within the DT and derive the head number from it

 .../bindings/gpu/nvidia,tegra20-host1x.txt         |  3 ++
 drivers/gpu/drm/tegra/dc.c                         | 41 ++++++++++++++++++++--
 2 files changed, 42 insertions(+), 2 deletions(-)

Comments

Stephen Warren Jan. 14, 2014, 5:53 p.m. UTC | #1
On 01/14/2014 07:45 AM, Thierry Reding wrote:
> 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.

The series,
Tested-by: Stephen Warren <swarren@nvidia.com>

This patch should really have been sent to the DT maintainers and list
since it changes a DT binding...

> diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c

> +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 of_property_read_u32() returns an error, does it guarantee that value
is left unchanged? I suspect it'd be safer to add ...

> +	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.
> +		 */

... "value = 0;" here?

> +		for_each_matching_node(np, tegra_dc_of_match) {
> +			if (np == dc->dev->of_node)
> +				break;
> +
> +			value++;
> +		}
> +	}
> +
> +	dc->pipe = value;
Thierry Reding Jan. 15, 2014, 9:06 a.m. UTC | #2
On Tue, Jan 14, 2014 at 10:53:19AM -0700, Stephen Warren wrote:
> On 01/14/2014 07:45 AM, Thierry Reding wrote:
> > 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.
> 
> The series,
> Tested-by: Stephen Warren <swarren@nvidia.com>
> 
> This patch should really have been sent to the DT maintainers and list
> since it changes a DT binding...

Indeed. I'll resend this to the appropriate people and lists. Sorry
about that.

> > diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
> 
> > +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 of_property_read_u32() returns an error, does it guarantee that value
> is left unchanged? I suspect it'd be safer to add ...

That's the way it's always been at least. of_property_read_u32() ends up
calling of_property_read_u32_array(), which looking at the code only
modifies the out_values parameter when it knows that it will succeed.

Furthermore the function's kernel-doc explicitly says that "out_values
is modified only if a valid u32 value can be decoded" (i.e. on success).

Thierry
Stephen Warren Jan. 15, 2014, 5:25 p.m. UTC | #3
On 01/15/2014 02:06 AM, Thierry Reding wrote:
> On Tue, Jan 14, 2014 at 10:53:19AM -0700, Stephen Warren wrote:
>> On 01/14/2014 07:45 AM, Thierry Reding wrote:
>>> 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.

>>> diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
>>
>>> +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 of_property_read_u32() returns an error, does it guarantee that value
>> is left unchanged? I suspect it'd be safer to add ...
> 
> That's the way it's always been at least. of_property_read_u32() ends up
> calling of_property_read_u32_array(), which looking at the code only
> modifies the out_values parameter when it knows that it will succeed.
> 
> Furthermore the function's kernel-doc explicitly says that "out_values
> is modified only if a valid u32 value can be decoded" (i.e. on success).

OK, that last bit is the important part. So, this is fine.
diff mbox

Patch

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");