Thread (23 messages) 23 messages, 5 authors, 2012-10-22

Re: [PATCH 1/2 v6] of: add helper to parse display timings

From: Stephen Warren <hidden>
Date: 2012-10-04 18:47:16
Also in: dri-devel, linux-devicetree, linux-media

On 10/04/2012 11:59 AM, Steffen Trumtrar wrote:

A patch description would be useful for something like this.
quoted hunk ↗ jump to hunk
diff --git a/Documentation/devicetree/bindings/video/display-timings.txt b/Documentation/devicetree/bindings/video/display-timings.txt
new file mode 100644
...
+Usage in backend
+========
Everything before that point in the file looks fine to me.

Everything after this point in the file seems to be Linux-specific
implementation details. Does it really belong in the DT binding
documentation, rather than some Linux-specific documentation file?
+struct drm_display_mode
+===========> +
+  +----------+---------------------------------------------+----------+-------+
+  |          |                                             |          |       |  ↑
+  |          |                                             |          |       |  |
+  |          |                                             |          |       |  |
+  +----------###############################################----------+-------+  |
I suspect the entire horizontal box above (and the entire vertical box
all the way down the left-hand side) should be on the bottom/right
instead of top/left. The reason I think this is because all of
vsync_start, vsync_end, vdisplay have to be referenced to some known
point, which is usually zero or the start of the timing definition, /or/
there would be some value indicating the size of the top marging/porch
in order to say where those other values are referenced to.
+  |          #   ↑         ↑          ↑                    #          |       |  |
+  |          #   |         |          |                    #          |       |  |
+  |          #   |         |          |                    #          |       |  |
+  |          #   |         |          |                    #          |       |  |
+  |          #   |         |          |                    #          |       |  |
+  |          #   |         |          |       hdisplay     #          |       |  |
+  |          #<--+--------------------+------------------->#          |       |  |
+  |          #   |         |          |                    #          |       |  |
+  |          #   |vsync_start         |                    #          |       |  |
+  |          #   |         |          |                    #          |       |  |
+  |          #   |         |vsync_end |                    #          |       |  |
+  |          #   |         |          |vdisplay            #          |       |  |
+  |          #   |         |          |                    #          |       |  |
+  |          #   |         |          |                    #          |       |  |
+  |          #   |         |          |                    #          |       |  | vtotal
+  |          #   |         |          |                    #          |       |  |
+  |          #   |         |          |     hsync_start    #          |       |  |
+  |          #<--+---------+----------+------------------------------>|       |  |
+  |          #   |         |          |                    #          |       |  |
+  |          #   |         |          |     hsync_end      #          |       |  |
+  |          #<--+---------+----------+-------------------------------------->|  |
+  |          #   |         |          ↓                    #          |       |  |
+  +----------####|#########|################################----------+-------+  |
+  |          |   |         |                               |          |       |  |
+  |          |   |         |                               |          |       |  |
+  |          |   ↓         |                               |          |       |  |
+  +----------+-------------+-------------------------------+----------+-------+  |
+  |          |             |                               |          |       |  |
+  |          |             |                               |          |       |  |
+  |          |             ↓                               |          |       |  ↓
+  +----------+---------------------------------------------+----------+-------+
+                                   htotal
+   <------------------------------------------------------------------------->
quoted hunk ↗ jump to hunk
diff --git a/drivers/of/of_display_timings.c b/drivers/of/of_display_timings.c
+static int parse_property(struct device_node *np, char *name,
+				struct timing_entry *result)
+	if (cells = 1)
+		ret = of_property_read_u32_array(np, name, &result->typ, cells);
Should that branch not just set result->min/max to typ as well?
Presumably it'd prevent any code that interprets struct timing_entry
from having to check if those values were 0 or not?
+	else if (cells = 3)
+		ret = of_property_read_u32_array(np, name, &result->min, cells);
+struct display_timings *of_get_display_timing_list(struct device_node *np)
+	entry = of_parse_phandle(timings_np, "default-timing", 0);
+
+	if (!entry) {
+		pr_info("%s: no default-timing specified\n", __func__);
+		entry = of_find_node_by_name(np, "timing");
I don't think you want to require the node have an explicit name; I
don't recall the DT binding documentation making that a requirement.
Instead, can't you either just leave the default unset, or pick the
first DT child node, irrespective of name?
+	if (!entry) {
+		pr_info("%s: no timing specifications given\n", __func__);
+		return disp;
+	}
The DT bindings don't state that it's mandatory to have some timing
specified, although I agree that it makes sense in practice.
+	for_each_child_of_node(timings_np, entry) {
+		struct signal_timing *st;
+
+		st = of_get_display_timing(entry);
+
+		if (!st)
+			continue;
I wonder if that shouldn't be an error?
+		if (strcmp(default_timing, entry->full_name) = 0)
+			disp->default_timing = disp->num_timings;
Hmm. Why not compare the node pointers rather than the name? Also, if
the parsing failed, then this can lead to default_timing being
uninitialized anyway...
+		disp->timings[disp->num_timings] = st;
+		disp->num_timings++;
+	}
+	if (disp->num_timings >= 0)
+		pr_info("%s: got %d timings. Using timing #%d as default\n", __func__,
+			disp->num_timings , disp->default_timing + 1);
+	else
+		pr_info("%s: no timings specified\n", __func__);
The message in the else clause is not necessarily true; there may have
been some specified, but they just couldn't be parsed.
+int of_display_timings_exists(struct device_node *np)
+{
+	struct device_node *timings_np;
+	struct device_node *default_np;
+
+	if (!np)
+		return -EINVAL;
+
+	timings_np = of_parse_phandle(np, "display-timings", 0);
+
+	if (!timings_np)
+		return -EINVAL;
+
+	default_np = of_parse_phandle(np, "default-timing", 0);
+
+	if (default_np)
+		return 0;
If this function checks that a default-timing property exists, shouldn't
the function be named of_display_default_timing_exists()?
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help