[PATCH 1/2 v6] of: add helper to parse display timings
Stephen Warren
swarren at wwwdotorg.org
Fri Oct 5 04:47:16 EST 2012
On 10/04/2012 11:59 AM, Steffen Trumtrar wrote:
A patch description would be useful for something like this.
> 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
> + <------------------------------------------------------------------------->
> 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()?
More information about the devicetree-discuss
mailing list