mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-09-27 23:20:26 +09:00
fdtdec: Implement carveout support functions
The fdtdec_get_carveout() and fdtdec_set_carveout() function can be used to read a carveout from a given node or add a carveout to a given node using the standard device tree bindings (involving reserved-memory nodes and the memory-region property). Reviewed-by: Simon Glass <sjg@chromium.org> Signed-off-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
parent
c9222a08b3
commit
16523ac790
@ -1069,6 +1069,8 @@ int fdtdec_set_phandle(void *blob, int node, uint32_t phandle);
|
|||||||
* The phandle returned from the function call can be used to reference this
|
* The phandle returned from the function call can be used to reference this
|
||||||
* reserved memory region from other nodes.
|
* reserved memory region from other nodes.
|
||||||
*
|
*
|
||||||
|
* See fdtdec_set_carveout() for a more elaborate example.
|
||||||
|
*
|
||||||
* @param blob FDT blob
|
* @param blob FDT blob
|
||||||
* @param basename base name of the node to create
|
* @param basename base name of the node to create
|
||||||
* @param carveout information about the carveout region
|
* @param carveout information about the carveout region
|
||||||
@ -1079,6 +1081,85 @@ int fdtdec_add_reserved_memory(void *blob, const char *basename,
|
|||||||
const struct fdt_memory *carveout,
|
const struct fdt_memory *carveout,
|
||||||
uint32_t *phandlep);
|
uint32_t *phandlep);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fdtdec_get_carveout() - reads a carveout from an FDT
|
||||||
|
*
|
||||||
|
* Reads information about a carveout region from an FDT. The carveout is a
|
||||||
|
* referenced by its phandle that is read from a given property in a given
|
||||||
|
* node.
|
||||||
|
*
|
||||||
|
* @param blob FDT blob
|
||||||
|
* @param node name of a node
|
||||||
|
* @param name name of the property in the given node that contains
|
||||||
|
* the phandle for the carveout
|
||||||
|
* @param index index of the phandle for which to read the carveout
|
||||||
|
* @param carveout return location for the carveout information
|
||||||
|
* @return 0 on success or a negative error code on failure
|
||||||
|
*/
|
||||||
|
int fdtdec_get_carveout(const void *blob, const char *node, const char *name,
|
||||||
|
unsigned int index, struct fdt_memory *carveout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fdtdec_set_carveout() - sets a carveout region for a given node
|
||||||
|
*
|
||||||
|
* Sets a carveout region for a given node. If a reserved-memory node already
|
||||||
|
* exists for the carveout, the phandle for that node will be reused. If no
|
||||||
|
* such node exists, a new one will be created and a phandle to it stored in
|
||||||
|
* a specified property of the given node.
|
||||||
|
*
|
||||||
|
* As an example, consider the following code snippet:
|
||||||
|
*
|
||||||
|
* const char *node = "/host1x@50000000/dc@54240000";
|
||||||
|
* struct fdt_memory fb = {
|
||||||
|
* .start = 0x92cb3000,
|
||||||
|
* .end = 0x934b2fff,
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* fdtdec_set_carveout(fdt, node, "memory-region", 0, "framebuffer", &fb);
|
||||||
|
*
|
||||||
|
* dc@54200000 is a display controller and was set up by the bootloader to
|
||||||
|
* scan out the framebuffer specified by "fb". This would cause the following
|
||||||
|
* reserved memory region to be added:
|
||||||
|
*
|
||||||
|
* reserved-memory {
|
||||||
|
* #address-cells = <0x00000002>;
|
||||||
|
* #size-cells = <0x00000002>;
|
||||||
|
* ranges;
|
||||||
|
*
|
||||||
|
* framebuffer@92cb3000 {
|
||||||
|
* reg = <0x00000000 0x92cb3000 0x00000000 0x00800000>;
|
||||||
|
* phandle = <0x0000004d>;
|
||||||
|
* };
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* A "memory-region" property will also be added to the node referenced by the
|
||||||
|
* offset parameter.
|
||||||
|
*
|
||||||
|
* host1x@50000000 {
|
||||||
|
* ...
|
||||||
|
*
|
||||||
|
* dc@54240000 {
|
||||||
|
* ...
|
||||||
|
* memory-region = <0x0000004d>;
|
||||||
|
* ...
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* ...
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* @param blob FDT blob
|
||||||
|
* @param node name of the node to add the carveout to
|
||||||
|
* @param prop_name name of the property in which to store the phandle of
|
||||||
|
* the carveout
|
||||||
|
* @param index index of the phandle to store
|
||||||
|
* @param name base name of the reserved-memory node to create
|
||||||
|
* @param carveout information about the carveout to add
|
||||||
|
* @return 0 on success or a negative error code on failure
|
||||||
|
*/
|
||||||
|
int fdtdec_set_carveout(void *blob, const char *node, const char *prop_name,
|
||||||
|
unsigned int index, const char *name,
|
||||||
|
const struct fdt_memory *carveout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up the device tree ready for use
|
* Set up the device tree ready for use
|
||||||
*/
|
*/
|
||||||
|
87
lib/fdtdec.c
87
lib/fdtdec.c
@ -1399,6 +1399,93 @@ int fdtdec_add_reserved_memory(void *blob, const char *basename,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fdtdec_get_carveout(const void *blob, const char *node, const char *name,
|
||||||
|
unsigned int index, struct fdt_memory *carveout)
|
||||||
|
{
|
||||||
|
const fdt32_t *prop;
|
||||||
|
uint32_t phandle;
|
||||||
|
int offset, len;
|
||||||
|
fdt_size_t size;
|
||||||
|
|
||||||
|
offset = fdt_path_offset(blob, node);
|
||||||
|
if (offset < 0)
|
||||||
|
return offset;
|
||||||
|
|
||||||
|
prop = fdt_getprop(blob, offset, name, &len);
|
||||||
|
if (!prop) {
|
||||||
|
debug("failed to get %s for %s\n", name, node);
|
||||||
|
return -FDT_ERR_NOTFOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((len % sizeof(phandle)) != 0) {
|
||||||
|
debug("invalid phandle property\n");
|
||||||
|
return -FDT_ERR_BADPHANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len < (sizeof(phandle) * (index + 1))) {
|
||||||
|
debug("invalid phandle index\n");
|
||||||
|
return -FDT_ERR_BADPHANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
phandle = fdt32_to_cpu(prop[index]);
|
||||||
|
|
||||||
|
offset = fdt_node_offset_by_phandle(blob, phandle);
|
||||||
|
if (offset < 0) {
|
||||||
|
debug("failed to find node for phandle %u\n", phandle);
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
carveout->start = fdtdec_get_addr_size_auto_noparent(blob, offset,
|
||||||
|
"reg", 0, &size,
|
||||||
|
true);
|
||||||
|
if (carveout->start == FDT_ADDR_T_NONE) {
|
||||||
|
debug("failed to read address/size from \"reg\" property\n");
|
||||||
|
return -FDT_ERR_NOTFOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
carveout->end = carveout->start + size - 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fdtdec_set_carveout(void *blob, const char *node, const char *prop_name,
|
||||||
|
unsigned int index, const char *name,
|
||||||
|
const struct fdt_memory *carveout)
|
||||||
|
{
|
||||||
|
uint32_t phandle;
|
||||||
|
int err, offset;
|
||||||
|
fdt32_t value;
|
||||||
|
|
||||||
|
/* XXX implement support for multiple phandles */
|
||||||
|
if (index > 0) {
|
||||||
|
debug("invalid index %u\n", index);
|
||||||
|
return -FDT_ERR_BADOFFSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = fdtdec_add_reserved_memory(blob, name, carveout, &phandle);
|
||||||
|
if (err < 0) {
|
||||||
|
debug("failed to add reserved memory: %d\n", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = fdt_path_offset(blob, node);
|
||||||
|
if (offset < 0) {
|
||||||
|
debug("failed to find offset for node %s: %d\n", node, offset);
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = cpu_to_fdt32(phandle);
|
||||||
|
|
||||||
|
err = fdt_setprop(blob, offset, prop_name, &value, sizeof(value));
|
||||||
|
if (err < 0) {
|
||||||
|
debug("failed to set %s property for node %s: %d\n", prop_name,
|
||||||
|
node, err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int fdtdec_setup(void)
|
int fdtdec_setup(void)
|
||||||
{
|
{
|
||||||
#if CONFIG_IS_ENABLED(OF_CONTROL)
|
#if CONFIG_IS_ENABLED(OF_CONTROL)
|
||||||
|
Loading…
Reference in New Issue
Block a user