From 90c08fa038451d6d7b7d8711bfd829b61d64c490 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Mon, 11 Jun 2018 13:07:09 -0600 Subject: fdt: Add device tree memory bindings Support a default memory bank, specified in reg, as well as board-specific memory banks in subtree board-id nodes. This allows memory information to be provided in the device tree, rather than hard-coded in, which will make it simpler to handle similar devices with different memory banks, as the board-id values or masks can be used to match devices. Signed-off-by: Michael Pratt Signed-off-by: Simon Glass Reviewed-by: Vadim Bendebury --- include/asm-generic/global_data.h | 1 + include/fdt_support.h | 10 ++++++++++ include/fdtdec.h | 38 +++++++++++++++++++++++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 2d451f8..0fd4900 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -52,6 +52,7 @@ typedef struct global_data { unsigned long env_has_init; /* Bitmask of boolean of struct env_location offsets */ int env_load_location; + unsigned long ram_base; /* Base address of RAM used by U-Boot */ unsigned long ram_top; /* Top address of RAM used by U-Boot */ unsigned long relocaddr; /* Start address of U-Boot in RAM */ phys_size_t ram_size; /* RAM size */ diff --git a/include/fdt_support.h b/include/fdt_support.h index e6c43ea..a9a0078 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -283,6 +283,16 @@ int fdt_setup_simplefb_node(void *fdt, int node, u64 base_address, u32 width, int fdt_overlay_apply_verbose(void *fdt, void *fdto); +/** + * fdt_get_cells_len() - Get the length of a type of cell in top-level nodes + * + * Returns the length of the cell type in bytes (4 or 8). + * + * @blob: Pointer to device tree blob + * @nr_cells_name: Name to lookup, e.g. "#address-cells" + */ +int fdt_get_cells_len(const void *blob, char *nr_cells_name); + #endif /* ifdef CONFIG_OF_LIBFDT */ #ifdef USE_HOSTCC diff --git a/include/fdtdec.h b/include/fdtdec.h index c15b2a0..3321055 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -41,6 +41,8 @@ struct fdt_memory { fdt_addr_t end; }; +struct bd_info; + #ifdef CONFIG_SPL_BUILD #define SPL_BUILD 1 #else @@ -993,6 +995,40 @@ int fdtdec_setup(void); * Called when CONFIG_OF_BOARD is defined, or if CONFIG_OF_SEPARATE is defined * and the board implements it. */ -void *board_fdt_blob_setup(void); + +/* + * Decode the size of memory + * + * RAM size is normally set in a /memory node and consists of a list of + * (base, size) cells in the 'reg' property. This information is used to + * determine the total available memory as well as the address and size + * of each bank. + * + * Optionally the memory configuration can vary depending on a board id, + * typically read from strapping resistors or an EEPROM on the board. + * + * Finally, memory size can be detected (within certain limits) by probing + * the available memory. It is safe to do so within the limits provides by + * the board's device tree information. This makes it possible to produce + * boards with different memory sizes, where the device tree specifies the + * maximum memory configuration, and the smaller memory configuration is + * probed. + * + * This function decodes that information, returning the memory base address, + * size and bank information. See the memory.txt binding for full + * documentation. + * + * @param blob Device tree blob + * @param area Name of node to check (NULL means "/memory") + * @param board_id Board ID to look up + * @param basep Returns base address of first memory bank (NULL to + * ignore) + * @param sizep Returns total memory size (NULL to ignore) + * @param bd Updated with the memory bank information (NULL to skip) + * @return 0 if OK, -ve on error + */ +int fdtdec_decode_ram_size(const void *blob, const char *area, int board_id, + phys_addr_t *basep, phys_size_t *sizep, + struct bd_info *bd); #endif -- cgit v1.1 From 7e5196c409f17091f2aeca144c6d76750df81cc4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 11 Jun 2018 13:07:10 -0600 Subject: dm: core: Add ofnode function to read a 64-bit int We have a 32-bit version of this function. Add a 64-bit version as well so we can easily read 64-bit ints from the device tree. Signed-off-by: Simon Glass --- include/dm/of_access.h | 16 ++++++++++++++++ include/dm/ofnode.h | 10 ++++++++++ 2 files changed, 26 insertions(+) (limited to 'include') diff --git a/include/dm/of_access.h b/include/dm/of_access.h index 74f0606..dd1abb8 100644 --- a/include/dm/of_access.h +++ b/include/dm/of_access.h @@ -219,6 +219,22 @@ struct device_node *of_find_node_by_phandle(phandle handle); int of_read_u32(const struct device_node *np, const char *propname, u32 *outp); /** + * of_read_u64() - Find and read a 64-bit integer from a property + * + * Search for a property in a device node and read a 64-bit value from + * it. + * + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * @outp: pointer to return value, modified only if return value is 0. + * + * @return 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough. + */ +int of_read_u64(const struct device_node *np, const char *propname, u64 *outp); + +/** * of_read_u32_array() - Find and read an array of 32 bit integers * * Search for a property in a device node and read 32-bit value(s) from diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 5af6b7e..dbb4273 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -237,6 +237,16 @@ int ofnode_read_u32_default(ofnode ref, const char *propname, u32 def); int ofnode_read_s32_default(ofnode node, const char *propname, s32 def); /** + * ofnode_read_u64_default() - Read a 64-bit integer from a property + * + * @ref: valid node reference to read property from + * @propname: name of the property to read from + * @def: default value to return if the property has no value + * @return property value, or @def if not found + */ +int ofnode_read_u64_default(ofnode node, const char *propname, u64 def); + +/** * ofnode_read_string() - Read a string from a property * * @ref: valid node reference to read property from -- cgit v1.1 From fbe8d033fcc64eef90d3e9642545804a0ab9b74f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 11 Jun 2018 13:07:11 -0600 Subject: dm: core: Fix a few ofnode function comments Tidy up three return-value errors. Signed-off-by: Simon Glass --- include/dm/ofnode.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index dbb4273..85cb87b 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -262,6 +262,7 @@ const char *ofnode_read_string(ofnode node, const char *propname); * @propname: name of the property to read * @out_values: pointer to return value, modified only if return value is 0 * @sz: number of array elements to read + * @return 0 if OK, -ve on error * * Search for a property in a device node and read 32-bit value(s) from * it. Returns 0 on success, -EINVAL if the property does not exist, @@ -490,6 +491,7 @@ ofnode ofnode_path(const char *path); * This looks for a property within the /chosen node and returns its value * * @propname: Property name to look for + * @return property value if found, else NULL */ const char *ofnode_get_chosen_prop(const char *propname); @@ -645,7 +647,7 @@ int ofnode_read_simple_size_cells(ofnode node); * new platforms. * * @node: node to check - * @eturns true if node is needed in SPL/TL, false otherwise + * @return true if node is needed in SPL/TL, false otherwise */ bool ofnode_pre_reloc(ofnode node); -- cgit v1.1 From c98ad4434c1a680915d10e5696e6bee9c81044d5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 11 Jun 2018 13:07:12 -0600 Subject: dm: core: Add comments to ofnode_read_resource() functoins These functions are missing comments. Add some. Signed-off-by: Simon Glass --- include/dm/ofnode.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'include') diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 85cb87b..61c4231 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -651,7 +651,30 @@ int ofnode_read_simple_size_cells(ofnode node); */ bool ofnode_pre_reloc(ofnode node); +/** + * ofnode_read_resource() - Read a resource from a node + * + * Read resource information from a node at the given index + * + * @node: Node to read from + * @index: Index of resource to read (0 = first) + * @res: Returns resource that was read, on success + * @return 0 if OK, -ve on error + */ int ofnode_read_resource(ofnode node, uint index, struct resource *res); + +/** + * ofnode_read_resource_byname() - Read a resource from a node by name + * + * Read resource information from a node matching the given name. This uses a + * 'reg-names' string list property with the names matching the associated + * 'reg' property list. + * + * @node: Node to read from + * @name: Name of resource to read + * @res: Returns resource that was read, on success + * @return 0 if OK, -ve on error + */ int ofnode_read_resource_byname(ofnode node, const char *name, struct resource *res); -- cgit v1.1 From c60f671b65a8b336c3533fcf0f0ee45dff287ff7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 11 Jun 2018 13:07:13 -0600 Subject: dm: core: Add a way to find an ofnode by compatible string Add an ofnode_by_compatible() to allow iterating through ofnodes with a given compatible string. Signed-off-by: Simon Glass --- include/dm/ofnode.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include') diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 61c4231..cd08a7e 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -679,6 +679,17 @@ int ofnode_read_resource_byname(ofnode node, const char *name, struct resource *res); /** + * ofnode_by_compatible() - Find the next compatible node + * + * Find the next node after @from that is compatible with @compat + * + * @from: ofnode to start from (use ofnode_null() to start at the beginning) + * @compat: Compatible string to match + * @return ofnode found, or ofnode_null() if none + */ +ofnode ofnode_by_compatible(ofnode from, const char *compat); + +/** * ofnode_for_each_subnode() - iterate over all subnodes of a parent * * @node: child node (ofnode, lvalue) -- cgit v1.1 From b616cef97aa8562a8c08558505675e255b5347cc Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 11 Jun 2018 13:07:14 -0600 Subject: log: Add a way to log a return value with a message It is sometimes useful to show a message when logging an error return value, perhaps to add a few details about the problem. Add a function to support this. Signed-off-by: Simon Glass --- include/log.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/log.h b/include/log.h index 3e99d6e..653fb8d 100644 --- a/include/log.h +++ b/include/log.h @@ -166,8 +166,16 @@ void __assert_fail(const char *assertion, const char *file, unsigned int line, log(LOG_CATEGORY, LOGL_ERR, "returning err=%d\n", __ret); \ __ret; \ }) +#define log_msg_ret(_msg, _ret) ({ \ + int __ret = (_ret); \ + if (__ret < 0) \ + log(LOG_CATEGORY, LOGL_ERR, "%s: returning err=%d\n", _msg, \ + __ret); \ + __ret; \ + }) #else #define log_ret(_ret) (_ret) +#define log_msg_ret(_ret) (_ret) #endif /** -- cgit v1.1 From d677b00cb62a4cf4d4a24468f218581b4f57c2fe Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 11 Jun 2018 13:07:15 -0600 Subject: dm: core: Add a way to bind a device by ofnode Add a new device_bind_ofnode() function which can bind a device given its ofnode. This allows binding devices more easily with livetree nodes. Signed-off-by: Simon Glass --- include/dm/device-internal.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h index 5a4d50c..f4af154 100644 --- a/include/dm/device-internal.h +++ b/include/dm/device-internal.h @@ -40,6 +40,10 @@ int device_bind(struct udevice *parent, const struct driver *drv, const char *name, void *platdata, int of_offset, struct udevice **devp); +int device_bind_ofnode(struct udevice *parent, const struct driver *drv, + const char *name, void *platdata, ofnode node, + struct udevice **devp); + /** * device_bind_with_driver_data() - Create a device and bind it to a driver * -- cgit v1.1 From 008dcddf9937bd2576f98b48eb5bf0f60ad36014 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 11 Jun 2018 13:07:16 -0600 Subject: dm: spi: Update sandbox SPI emulation driver to use ofnode Update the parameters sandbox_sf_bind_emul to support livetree. Signed-off-by: Simon Glass --- include/spi_flash.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/spi_flash.h b/include/spi_flash.h index 2253331..0ec98fb 100644 --- a/include/spi_flash.h +++ b/include/spi_flash.h @@ -185,7 +185,7 @@ static inline int spi_flash_erase(struct spi_flash *flash, u32 offset, struct sandbox_state; int sandbox_sf_bind_emul(struct sandbox_state *state, int busnum, int cs, - struct udevice *bus, int of_offset, const char *spec); + struct udevice *bus, ofnode node, const char *spec); void sandbox_sf_unbind_emul(struct sandbox_state *state, int busnum, int cs); -- cgit v1.1 From 5e0a7341cdda182f310624d5c336fb48be04a703 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 11 Jun 2018 13:07:17 -0600 Subject: dm: core: Update of_read_fmap_entry() for livetree Update this function to take an ofnode so that it can work with livetree. Signed-off-by: Simon Glass --- include/dm/of_extra.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/dm/of_extra.h b/include/dm/of_extra.h index 6f15296..e1540c1 100644 --- a/include/dm/of_extra.h +++ b/include/dm/of_extra.h @@ -34,12 +34,10 @@ struct fmap_entry { /** * Read a flash entry from the fdt * - * @param node Reference to node to read - * @param name Name of node being read + * @param node Reference to node to read * @param entry Place to put offset and size of this node * @return 0 if ok, -ve on error */ -int of_read_fmap_entry(ofnode node, const char *name, - struct fmap_entry *entry); +int ofnode_read_fmap_entry(ofnode node, struct fmap_entry *entry); #endif -- cgit v1.1 From 964cadc445f1437e63f1d2b4fffd233ac053c6e6 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 11 Jun 2018 13:07:18 -0600 Subject: dm: core: Add a function to decode a memory region Add a way to decode a memory region, including the memory type (sram or sdram) and its start address and size. Signed-off-by: Simon Glass --- include/dm/of_extra.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'include') diff --git a/include/dm/of_extra.h b/include/dm/of_extra.h index e1540c1..97988b6 100644 --- a/include/dm/of_extra.h +++ b/include/dm/of_extra.h @@ -40,4 +40,49 @@ struct fmap_entry { */ int ofnode_read_fmap_entry(ofnode node, struct fmap_entry *entry); +/** + * ofnode_decode_region() - Decode a memory region from a node + * + * Look up a property in a node which contains a memory region address and + * size. Then return a pointer to this address. + * + * The property must hold one address with a length. This is only tested on + * 32-bit machines. + * + * @param node ofnode to examine + * @param prop_name name of property to find + * @param basep Returns base address of region + * @param size Returns size of region + * @return 0 if ok, -1 on error (property not found) + */ +int ofnode_decode_region(ofnode node, const char *prop_name, fdt_addr_t *basep, + fdt_size_t *sizep); + +/** + * ofnode_decode_memory_region()- Decode a named region within a memory bank + * + * This function handles selection of a memory region. The region is + * specified as an offset/size within a particular type of memory. + * + * The properties used are: + * + * -memory for the name of the memory bank + * -offset for the offset in that bank + * + * The property value must have an offset and a size. The function checks + * that the region is entirely within the memory bank.5 + * + * @param node ofnode containing the properties (-1 for /config) + * @param mem_type Type of memory to use, which is a name, such as + * "u-boot" or "kernel". + * @param suffix String to append to the memory/offset + * property names + * @param basep Returns base of region + * @param sizep Returns size of region + * @return 0 if OK, -ive on error + */ +int ofnode_decode_memory_region(ofnode config_node, const char *mem_type, + const char *suffix, fdt_addr_t *basep, + fdt_size_t *sizep); + #endif -- cgit v1.1