[PATCH v3 1/2] board: phytec: common: Add product information to FTD

ft_board_setup inside the board code allows to alter device-tree during the boot process.
Introduce a new function for the PHYTEC SOM detection to read the product name and part number from the EEPROM content and include both into the device-tree as * phytec,som-part-number * phytec,som-product-name
This function can be called from the board code when those values should be exposed to Linux.
This patch also updates the phytec_print_som_info function and changes the output.
Signed-off-by: Daniel Schultz d.schultz@phytec.de ---
Changes in v2: * Removed 'struct bd_info' as argument in function phytec_ft_board_fixup
Changes in v3: * Removed not required check if variable data is valid in new functions. * Moved '+1' from string length definitions to snprintf calls. * Define more string lenghts to check snprintf result. * Return -EINVAL instead of -1.
board/phytec/common/phytec_som_detection.c | 198 ++++++++++++++++----- board/phytec/common/phytec_som_detection.h | 12 ++ 2 files changed, 167 insertions(+), 43 deletions(-)
diff --git a/board/phytec/common/phytec_som_detection.c b/board/phytec/common/phytec_som_detection.c index 166c3eae565..1f2213902ed 100644 --- a/board/phytec/common/phytec_som_detection.c +++ b/board/phytec/common/phytec_som_detection.c @@ -271,11 +271,122 @@ err: return ret; }
+static int phytec_get_product_name(struct phytec_eeprom_data *data, + char *product) +{ + struct phytec_api2_data *api2; + unsigned int ksp_no, som_type; + int len; + + if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2) + return -EINVAL; + + api2 = &data->payload.data.data_api2; + + if (api2->som_type > 1 && api2->som_type <= 3) { + ksp_no = (api2->ksp_no << 8) | api2->som_no; + len = snprintf(product, PHYTEC_PRODUCT_NAME_MAX_LEN + 1, + "%s-%04u", phytec_som_type_str[api2->som_type], + ksp_no); + if (len != PHYTEC_PRODUCT_NAME_KSP_LEN) + return -EINVAL; + return 0; + } + + switch (api2->som_type) { + case 0: + som_type = api2->som_type; + break; + case 4: + som_type = 0; + break; + case 5: + som_type = 0; + break; + case 6: + som_type = 1; + break; + case 7: + som_type = 1; + break; + default: + pr_err("%s: Invalid SOM type: %i", __func__, api2->som_type); + return -EINVAL; + }; + + len = snprintf(product, PHYTEC_PRODUCT_NAME_MAX_LEN + 1, "%s-%03u", + phytec_som_type_str[som_type], api2->som_no); + if (len != PHYTEC_PRODUCT_NAME_STD_LEN) + return -EINVAL; + return 0; +} + +static int phytec_get_part_number(struct phytec_eeprom_data *data, + char *part) +{ + char product_name[PHYTEC_PRODUCT_NAME_MAX_LEN + 1] = {'\0'}; + struct phytec_api2_data *api2; + unsigned int ksp_type; + int res, len; + + if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2) + return -EINVAL; + + api2 = &data->payload.data.data_api2; + + res = phytec_get_product_name(data, product_name); + if (res) + return res; + + if (api2->som_type <= 1) { + len = snprintf(part, PHYTEC_PART_NUMBER_MAX_LEN + 1, + "%s-%s.%s", product_name, api2->opt, + api2->bom_rev); + if (len < PHYTEC_PART_NUMBER_STD_LEN) + return -EINVAL; + return 0; + } + if (api2->som_type <= 3) { + snprintf(part, PHYTEC_PART_NUMBER_MAX_LEN + 1, "%s.%s", + product_name, api2->bom_rev); + if (len != PHYTEC_PART_NUMBER_KSP_LEN) + return -EINVAL; + return 0; + } + + switch (api2->som_type) { + case 4: + ksp_type = 3; + break; + case 5: + ksp_type = 2; + break; + case 6: + ksp_type = 3; + break; + case 7: + ksp_type = 2; + break; + default: + pr_err("%s: Invalid SOM type: %i", __func__, api2->som_type); + return -EINVAL; + }; + + len = snprintf(part, PHYTEC_PART_NUMBER_MAX_LEN + 1, "%s-%s%02u.%s", + product_name, phytec_som_type_str[ksp_type], + api2->ksp_no, api2->bom_rev); + if (len < PHYTEC_PART_NUMBER_STD_KSP_LEN) + return -EINVAL; + + return 0; +} + void __maybe_unused phytec_print_som_info(struct phytec_eeprom_data *data) { + char part_number[PHYTEC_PART_NUMBER_MAX_LEN + 1] = {'\0'}; struct phytec_api2_data *api2; char pcb_sub_rev; - unsigned int ksp_no, sub_som_type1, sub_som_type2; + int res;
if (!data) data = &eeprom_data; @@ -289,50 +400,14 @@ void __maybe_unused phytec_print_som_info(struct phytec_eeprom_data *data) pcb_sub_rev = api2->pcb_sub_opt_rev & 0x0f; pcb_sub_rev = pcb_sub_rev ? ((pcb_sub_rev - 1) + 'a') : ' ';
- /* print standard product string */ - if (api2->som_type <= 1) { - printf("SoM: %s-%03u-%s.%s PCB rev: %u%c\n", - phytec_som_type_str[api2->som_type], api2->som_no, - api2->opt, api2->bom_rev, api2->pcb_rev, pcb_sub_rev); + res = phytec_get_part_number(data, part_number); + if (res) return; - } - /* print KSP/KSM string */ - if (api2->som_type <= 3) { - ksp_no = (api2->ksp_no << 8) | api2->som_no; - printf("SoM: %s-%u ", - phytec_som_type_str[api2->som_type], ksp_no); - /* print standard product based KSP/KSM strings */ - } else { - switch (api2->som_type) { - case 4: - sub_som_type1 = 0; - sub_som_type2 = 3; - break; - case 5: - sub_som_type1 = 0; - sub_som_type2 = 2; - break; - case 6: - sub_som_type1 = 1; - sub_som_type2 = 3; - break; - case 7: - sub_som_type1 = 1; - sub_som_type2 = 2; - break; - default: - pr_err("%s: Invalid SoM type: %i", __func__, api2->som_type); - return; - }; - - printf("SoM: %s-%03u-%s-%03u ", - phytec_som_type_str[sub_som_type1], - api2->som_no, phytec_som_type_str[sub_som_type2], - api2->ksp_no); - }
- printf("Option: %s BOM rev: %s PCB rev: %u%c\n", api2->opt, - api2->bom_rev, api2->pcb_rev, pcb_sub_rev); + printf("SOM: %s\n", part_number); + printf("PCB Rev.: %u%c\n", api2->pcb_rev, pcb_sub_rev); + if (api2->som_type > 1) + printf("Options: %s\n", api2->opt); }
char * __maybe_unused phytec_get_opt(struct phytec_eeprom_data *data) @@ -379,6 +454,37 @@ u8 __maybe_unused phytec_get_som_type(struct phytec_eeprom_data *data) return data->payload.data.data_api2.som_type; }
+#if IS_ENABLED(CONFIG_OF_LIBFDT) +int phytec_ft_board_fixup(struct phytec_eeprom_data *data, void *blob) +{ + char product_name[PHYTEC_PRODUCT_NAME_MAX_LEN + 1] = {'\0'}; + char part_number[PHYTEC_PART_NUMBER_MAX_LEN + 1] = {'\0'}; + int res; + + if (!data) + data = &eeprom_data; + + if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2) + return -EINVAL; + + res = phytec_get_product_name(data, product_name); + if (res) + return res; + + fdt_setprop(blob, 0, "phytec,som-product-name", product_name, + strlen(product_name) + 1); + + res = phytec_get_part_number(data, part_number); + if (res) + return res; + + fdt_setprop(blob, 0, "phytec,som-part-number", part_number, + strlen(part_number) + 1); + + return 0; +} +#endif /* IS_ENABLED(CONFIG_OF_LIBFDT) */ + #if IS_ENABLED(CONFIG_CMD_EXTENSION) struct extension *phytec_add_extension(const char *name, const char *overlay, const char *other) @@ -458,6 +564,12 @@ inline struct phytec_api3_element * __maybe_unused return NULL; }
+#if IS_ENABLED(CONFIG_OF_LIBFDT) +inline int phytec_ft_board_fixup(struct phytec_eeprom_data *data, void *blob) +{ + return 0; +} +#endif /* IS_ENABLED(CONFIG_OF_LIBFDT) */ #if IS_ENABLED(CONFIG_CMD_EXTENSION) inline struct extension *phytec_add_extension(const char *name, const char *overlay, diff --git a/board/phytec/common/phytec_som_detection.h b/board/phytec/common/phytec_som_detection.h index 5e35a13cb21..187424a2b44 100644 --- a/board/phytec/common/phytec_som_detection.h +++ b/board/phytec/common/phytec_som_detection.h @@ -8,6 +8,7 @@ #define _PHYTEC_SOM_DETECTION_H
#include "phytec_som_detection_blocks.h" +#include <fdtdec.h>
#define PHYTEC_MAX_OPTIONS 17 #define PHYTEC_EEPROM_INVAL 0xff @@ -17,6 +18,14 @@ #define PHYTEC_GET_OPTION(option) \ (((option) > '9') ? (option) - 'A' + 10 : (option) - '0')
+#define PHYTEC_PRODUCT_NAME_STD_LEN 7 // PCx-000 +#define PHYTEC_PRODUCT_NAME_KSP_LEN 8 // KSP-0000 +#define PHYTEC_PRODUCT_NAME_MAX_LEN PHYTEC_PRODUCT_NAME_KSP_LEN +#define PHYTEC_PART_NUMBER_STD_LEN 11 // PCx-000-\w{1,17}.Ax +#define PHYTEC_PART_NUMBER_KSP_LEN 11 // KSP-0000.Ax +#define PHYTEC_PART_NUMBER_STD_KSP_LEN 16 // PCx-000-KSx00.Ax +#define PHYTEC_PART_NUMBER_MAX_LEN PHYTEC_PRODUCT_NAME_MAX_LEN + 21 + enum { PHYTEC_API_REV0 = 0, PHYTEC_API_REV1, @@ -86,6 +95,9 @@ void __maybe_unused phytec_print_som_info(struct phytec_eeprom_data *data); char * __maybe_unused phytec_get_opt(struct phytec_eeprom_data *data); u8 __maybe_unused phytec_get_rev(struct phytec_eeprom_data *data); u8 __maybe_unused phytec_get_som_type(struct phytec_eeprom_data *data); +#if IS_ENABLED(CONFIG_OF_LIBFDT) +int phytec_ft_board_fixup(struct phytec_eeprom_data *data, void *blob); +#endif /* IS_ENABLED(CONFIG_OF_LIBFDT) */
#if IS_ENABLED(CONFIG_CMD_EXTENSION) struct extension *phytec_add_extension(const char *name, const char *overlay,

Call 'phytec_ft_board_fixup' in the common K3 board code to expose the product name and part number to Linux.
Signed-off-by: Daniel Schultz d.schultz@phytec.de Reviewed-by: Wadim Egorov w.egorov@phytec.de ---
Changes in v2: * Removed 'return 0' right before leaving with the same return code anyways. * Added Wadim's Reviewed-by.
No changes in v3
board/phytec/common/k3/board.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/board/phytec/common/k3/board.c b/board/phytec/common/k3/board.c index 9ff861cd3f4..3f70dcddf45 100644 --- a/board/phytec/common/k3/board.c +++ b/board/phytec/common/k3/board.c @@ -252,9 +252,21 @@ fixup_error:
int ft_board_setup(void *blob, struct bd_info *bd) { + struct phytec_eeprom_data data; + int ret; + fdt_apply_som_overlays(blob); fdt_copy_fixed_partitions(blob);
+ ret = phytec_eeprom_data_setup(&data, 0, EEPROM_ADDR); + if (ret || !data.valid) + return 0; + + ret = phytec_ft_board_fixup(&data, blob); + if (ret) + pr_err("%s: Failed to add PHYTEC information to fdt.\n", + __func__); + return 0; } #endif

Am 23.01.25 um 21:43 schrieb Daniel Schultz:
ft_board_setup inside the board code allows to alter device-tree during the boot process.
Introduce a new function for the PHYTEC SOM detection to read the product name and part number from the EEPROM content and include both into the device-tree as
- phytec,som-part-number
- phytec,som-product-name
This function can be called from the board code when those values should be exposed to Linux.
This patch also updates the phytec_print_som_info function and changes the output.
Signed-off-by: Daniel Schultz d.schultz@phytec.de
Changes in v2:
- Removed 'struct bd_info' as argument in function phytec_ft_board_fixup
Changes in v3:
- Removed not required check if variable data is valid in new functions.
- Moved '+1' from string length definitions to snprintf calls.
- Define more string lenghts to check snprintf result.
- Return -EINVAL instead of -1.
Reviewed-by: Wadim Egorov w.egorov@phytec.de Tested-by: Wadim Egorov w.egorov@phytec.de
participants (2)
-
Daniel Schultz
-
Wadim Egorov