fdt: Add binding decode function for display-timings
This is useful for display parameters. Add a simple decode function to read from this device tree node. Signed-off-by: Simon Glass <sjg@chromium.org> Signed-off-by: Tom Warren <twarren@nvidia.com>
This commit is contained in:
92
lib/fdtdec.c
92
lib/fdtdec.c
@@ -1037,6 +1037,98 @@ int fdtdec_decode_memory_region(const void *blob, int config_node,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_timing_property(const void *blob, int node, const char *name,
|
||||
struct timing_entry *result)
|
||||
{
|
||||
int length, ret = 0;
|
||||
const u32 *prop;
|
||||
|
||||
prop = fdt_getprop(blob, node, name, &length);
|
||||
if (!prop) {
|
||||
debug("%s: could not find property %s\n",
|
||||
fdt_get_name(blob, node, NULL), name);
|
||||
return length;
|
||||
}
|
||||
|
||||
if (length == sizeof(u32)) {
|
||||
result->typ = fdtdec_get_int(blob, node, name, 0);
|
||||
result->min = result->typ;
|
||||
result->max = result->typ;
|
||||
} else {
|
||||
ret = fdtdec_get_int_array(blob, node, name, &result->min, 3);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fdtdec_decode_display_timing(const void *blob, int parent, int index,
|
||||
struct display_timing *dt)
|
||||
{
|
||||
int i, node, timings_node;
|
||||
u32 val = 0;
|
||||
int ret = 0;
|
||||
|
||||
timings_node = fdt_subnode_offset(blob, parent, "display-timings");
|
||||
if (timings_node < 0)
|
||||
return timings_node;
|
||||
|
||||
for (i = 0, node = fdt_first_subnode(blob, timings_node);
|
||||
node > 0 && i != index;
|
||||
node = fdt_next_subnode(blob, node))
|
||||
i++;
|
||||
|
||||
if (node < 0)
|
||||
return node;
|
||||
|
||||
memset(dt, 0, sizeof(*dt));
|
||||
|
||||
ret |= decode_timing_property(blob, node, "hback-porch",
|
||||
&dt->hback_porch);
|
||||
ret |= decode_timing_property(blob, node, "hfront-porch",
|
||||
&dt->hfront_porch);
|
||||
ret |= decode_timing_property(blob, node, "hactive", &dt->hactive);
|
||||
ret |= decode_timing_property(blob, node, "hsync-len", &dt->hsync_len);
|
||||
ret |= decode_timing_property(blob, node, "vback-porch",
|
||||
&dt->vback_porch);
|
||||
ret |= decode_timing_property(blob, node, "vfront-porch",
|
||||
&dt->vfront_porch);
|
||||
ret |= decode_timing_property(blob, node, "vactive", &dt->vactive);
|
||||
ret |= decode_timing_property(blob, node, "vsync-len", &dt->vsync_len);
|
||||
ret |= decode_timing_property(blob, node, "clock-frequency",
|
||||
&dt->pixelclock);
|
||||
|
||||
dt->flags = 0;
|
||||
val = fdtdec_get_int(blob, node, "vsync-active", -1);
|
||||
if (val != -1) {
|
||||
dt->flags |= val ? DISPLAY_FLAGS_VSYNC_HIGH :
|
||||
DISPLAY_FLAGS_VSYNC_LOW;
|
||||
}
|
||||
val = fdtdec_get_int(blob, node, "hsync-active", -1);
|
||||
if (val != -1) {
|
||||
dt->flags |= val ? DISPLAY_FLAGS_HSYNC_HIGH :
|
||||
DISPLAY_FLAGS_HSYNC_LOW;
|
||||
}
|
||||
val = fdtdec_get_int(blob, node, "de-active", -1);
|
||||
if (val != -1) {
|
||||
dt->flags |= val ? DISPLAY_FLAGS_DE_HIGH :
|
||||
DISPLAY_FLAGS_DE_LOW;
|
||||
}
|
||||
val = fdtdec_get_int(blob, node, "pixelclk-active", -1);
|
||||
if (val != -1) {
|
||||
dt->flags |= val ? DISPLAY_FLAGS_PIXDATA_POSEDGE :
|
||||
DISPLAY_FLAGS_PIXDATA_NEGEDGE;
|
||||
}
|
||||
|
||||
if (fdtdec_get_bool(blob, node, "interlaced"))
|
||||
dt->flags |= DISPLAY_FLAGS_INTERLACED;
|
||||
if (fdtdec_get_bool(blob, node, "doublescan"))
|
||||
dt->flags |= DISPLAY_FLAGS_DOUBLESCAN;
|
||||
if (fdtdec_get_bool(blob, node, "doubleclk"))
|
||||
dt->flags |= DISPLAY_FLAGS_DOUBLECLK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdtdec_setup(void)
|
||||
{
|
||||
#ifdef CONFIG_OF_CONTROL
|
||||
|
||||
Reference in New Issue
Block a user