mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2025-12-10 07:44:53 +01:00
Merge "ipq: fdt_fixup: add support to add / edit array of values"
This commit is contained in:
commit
9648ab1374
1 changed files with 106 additions and 17 deletions
|
|
@ -16,6 +16,7 @@
|
||||||
#include <asm/arch-qca-common/scm.h>
|
#include <asm/arch-qca-common/scm.h>
|
||||||
#include <jffs2/load_kernel.h>
|
#include <jffs2/load_kernel.h>
|
||||||
#include <fdtdec.h>
|
#include <fdtdec.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
|
@ -647,60 +648,148 @@ static int ipq40xx_patch_eth_params(void *blob, unsigned long gmac_no)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_IPQ_FDT_FIXUP
|
#ifdef CONFIG_IPQ_FDT_FIXUP
|
||||||
|
/* setenv fdteditnum <num> - here <num> represents number of envs to parse
|
||||||
|
* Note: without setting 'fdteditnum' fdtedit envs will not parsed
|
||||||
|
*
|
||||||
|
* fdtedit<num> <node>%<property>%<node_value> - dts patching env format
|
||||||
|
* here '%' is separator; <num> can be between 1 to 99;
|
||||||
|
*
|
||||||
|
* 1. To change add/change a particular property of a node:
|
||||||
|
* setenv fdtedit0 <node_path>%<property>%<value>
|
||||||
|
*
|
||||||
|
* This can be used to add properties which doesn't have any value associated
|
||||||
|
* eg: qca,secure; property of q6v5_wcss@CD00000 node can be added as:
|
||||||
|
* setenv fdtedit0 /soc/q6v5_wcss@CD00000/%qca,secure%1
|
||||||
|
* other eg:
|
||||||
|
* fdtedit0=/soc/q6v5_wcss@CD00000%qca,sec-reset-cmd%0x19
|
||||||
|
* fdtedit1=/soc/usb3@8A00000/dwc3@8A00000%dr_mode%?peripheral
|
||||||
|
* fdtedit2=/soc/qcom,gadget_diag@0/%status%?ok
|
||||||
|
*
|
||||||
|
* 2. To delete a property of a node:
|
||||||
|
* setenv fdtedit0 <node_path>%delete%<property>
|
||||||
|
* example:
|
||||||
|
* fdtedit0=/soc/q6v5_wcss@CD00000%delete%?qca,secure
|
||||||
|
*
|
||||||
|
* The last param in both add or delete case, if it is a string, it should
|
||||||
|
* start with '?' else if it is a number, it can be put directly.
|
||||||
|
* check above examples for reference.
|
||||||
|
*
|
||||||
|
* 3. To add 32bit or 64bit array values:
|
||||||
|
* setenv fdtedit0 <node_path>%<bit_value>?<num_values>?<property_name>%<value1>?<value2>?<value3>?..
|
||||||
|
* <bit_value> can be 32 / 64; <num_values> is number of array elements
|
||||||
|
* to be patched; <property_name> is the actual name of the property to
|
||||||
|
* be patched; each array value has to be separated by '?'
|
||||||
|
* for reg = <addr> <size>; <num_values> is 2 in this case
|
||||||
|
* example:
|
||||||
|
* setenv fdtedit0 /soc/dbm@0x8AF8000/%32?2?reg%0x8AF8000?0x500
|
||||||
|
* setenv fdtedit1 /soc/pci@20000000/%32?2?bus-range%0xee?0xee
|
||||||
|
* setenv fdtedit2 /soc/usb3@8A00000/%32?4?reg%0x8AF8600?0x200?0x8A00000?0xcb00
|
||||||
|
* setenv fdtedit3 /reserved-memory/tzapp@49B00000/%64?2?reg%0x49A00000?0x500000
|
||||||
|
*/
|
||||||
void parse_fdt_fixup(char* buf, void *blob)
|
void parse_fdt_fixup(char* buf, void *blob)
|
||||||
{
|
{
|
||||||
int nodeoff, value, ret;
|
int nodeoff, value, ret, num_values, i;
|
||||||
char *node, *property, *node_value;
|
char *node, *property, *node_value, *sliced_string;
|
||||||
bool str = true;
|
bool if_string = true, bit32 = true;
|
||||||
|
u32 *values32;
|
||||||
|
u64 *values64;
|
||||||
|
|
||||||
|
/* env is split into <node>%<property>%<node_value>. '%' is separator */
|
||||||
node = strsep(&buf, "%");
|
node = strsep(&buf, "%");
|
||||||
property = strsep(&buf, "%");
|
property = strsep(&buf, "%");
|
||||||
node_value = strsep(&buf, "%");
|
node_value = strsep(&buf, "%");
|
||||||
|
|
||||||
debug("node: %s, property: %s, node_value: %s\n",
|
debug("node: %s property: %s node_value: %s\n", node, property, node_value);
|
||||||
node, property, node_value);
|
|
||||||
|
|
||||||
|
/* if '?' is present then node_value is string;
|
||||||
|
* else, node_value is 32bit value
|
||||||
|
*/
|
||||||
if (node_value && node_value[0] != '?') {
|
if (node_value && node_value[0] != '?') {
|
||||||
str = false;
|
if_string = false;
|
||||||
value = simple_strtoul(node_value, NULL, 10);
|
value = simple_strtoul(node_value, NULL, 10);
|
||||||
} else {
|
} else {
|
||||||
|
/* skip '?' */
|
||||||
node_value++;
|
node_value++;
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeoff = fdt_path_offset(blob, node);
|
nodeoff = fdt_path_offset(blob, node);
|
||||||
if (nodeoff < 0) {
|
if (nodeoff < 0) {
|
||||||
printf("%s: unable to find node '%s'\n",
|
printf("%s: unable to find node '%s'\n", __func__, node);
|
||||||
__func__, node);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strncmp(property, "delete", strlen("delete"))) {
|
if (!strncmp(property, "delete", strlen("delete"))) {
|
||||||
|
/* handle property deletes */
|
||||||
ret = fdt_delprop(blob, nodeoff, node_value);
|
ret = fdt_delprop(blob, nodeoff, node_value);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("%s: unable to delete %s\n",
|
printf("%s: unable to delete %s\n", __func__, node_value);
|
||||||
__func__, node_value);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (!str) {
|
} else if (!strncmp(property, "32", strlen("32")) || !strncmp(property, "64", strlen("64"))) {
|
||||||
ret = fdt_setprop_u32(blob, nodeoff, property,
|
/* if property name starts with '32' or '64', then it is used
|
||||||
value);
|
* for patching array of 32bit / 64bit values correspondingly.
|
||||||
|
* 32bit patching is usually used to patch reg = <addr> <size>;
|
||||||
|
* but could also be used to patch multiple addresses & sizes
|
||||||
|
* <property> = <addr1> <size1> <addr2> <size2> ..
|
||||||
|
* 64bit patching is usually used to patch reserved memory nodes
|
||||||
|
*/
|
||||||
|
sliced_string = strsep(&property, "?");
|
||||||
|
if (simple_strtoul(sliced_string, NULL, 10) == 64)
|
||||||
|
bit32 = false;
|
||||||
|
|
||||||
|
/* get the number of array values */
|
||||||
|
sliced_string = strsep(&property, "?");
|
||||||
|
num_values = simple_strtoul(sliced_string, NULL, 10);
|
||||||
|
|
||||||
|
if (bit32 == true) {
|
||||||
|
values32 = malloc(num_values * sizeof(u32));
|
||||||
|
|
||||||
|
for (i = 0; i < num_values; i++) {
|
||||||
|
sliced_string = strsep(&node_value, "?");
|
||||||
|
values32[i] = cpu_to_fdt32(simple_strtoul(sliced_string, NULL, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = fdt_setprop(blob, nodeoff, property, values32, num_values * sizeof(u32));
|
||||||
|
if (ret) {
|
||||||
|
printf("%s: failed to set prop %s\n", __func__, property);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
values64 = malloc(num_values * sizeof(u64));
|
||||||
|
|
||||||
|
for (i = 0; i < num_values; i++) {
|
||||||
|
sliced_string = strsep(&node_value, "?");
|
||||||
|
values64[i] = cpu_to_fdt64(simple_strtoul(sliced_string, NULL, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = fdt_setprop(blob, nodeoff, property, values64, num_values * sizeof(u64));
|
||||||
|
if (ret) {
|
||||||
|
printf("%s: failed to set prop %s\n", __func__, property);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!if_string) {
|
||||||
|
/* handle 32bit integer value patching */
|
||||||
|
ret = fdt_setprop_u32(blob, nodeoff, property, value);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("%s: failed to set prop %s\n",
|
printf("%s: failed to set prop %s\n", __func__, property);
|
||||||
__func__, property);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
/* handle string value patching
|
||||||
|
* usually used to patch status = "ok"; status = "disabled";
|
||||||
|
*/
|
||||||
ret = fdt_setprop(blob, nodeoff, property,
|
ret = fdt_setprop(blob, nodeoff, property,
|
||||||
node_value,
|
node_value,
|
||||||
(strlen(node_value) + 1));
|
(strlen(node_value) + 1));
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("%s: failed to set prop %s\n",
|
printf("%s: failed to set prop %s\n", __func__, property);
|
||||||
__func__, property);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check parse_fdt_fixup for detailed explanation */
|
||||||
void ipq_fdt_fixup(void *blob)
|
void ipq_fdt_fixup(void *blob)
|
||||||
{
|
{
|
||||||
int i, fdteditnum;
|
int i, fdteditnum;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue