Add flash to fpga intermediate driver
Subsystems (3)
v2 cover Add flash to fpga intermediate driver
From: Tien Fong Chee <[email protected]>
This patchset adding intermediate driver called cff driver to support all the FPGA program operations between FPGA manager and flash. This version mainly resolved comments from Marek in [v1]. This series is working on top of u-boot.git - http://git.denx.de/?p=u-boot.git;a=summary
[v1]: https://www.mail-archive.com/u-boot at lists.denx.de/msg258316.html
Tien Fong Chee (5):
arm: socfpga: Make spl_boot_device accessible to U-boot
arm: socfpga: Add checking function on FPGA setting in FDT
configs: Add FPGA loadfs config for Arria 10
arm: socfpga: Add intermediate driver between flash and FPGA manager
arm: socfpga: Enable cff driver build
arch/arm/mach-socfpga/Makefile | 1 + arch/arm/mach-socfpga/cff.c | 582 ++++++++++++++++++++++++++++++ arch/arm/mach-socfpga/include/mach/cff.h | 40 ++ arch/arm/mach-socfpga/include/mach/misc.h | 1 + arch/arm/mach-socfpga/misc.c | 30 ++ arch/arm/mach-socfpga/misc_arria10.c | 20 + arch/arm/mach-socfpga/spl.c | 29 -- configs/socfpga_arria10_defconfig | 1 + include/configs/socfpga_arria10_socdk.h | 6 + 9 files changed, 681 insertions(+), 29 deletions(-) create mode 100644 arch/arm/mach-socfpga/cff.c create mode 100644 arch/arm/mach-socfpga/include/mach/cff.h
Signature · 1 line
2.2.0
PATCH v2 1/5 arm: socfpga: Make spl_boot_device accessible to U-boot
From: Tien Fong Chee <[email protected]>
This function is required in both SPL and U-boot such as checking boot device type, which is required for locating flash where U-boot image, and FPGA design are stored.
--- arch/arm/mach-socfpga/misc.c | 30 ++++++++++++++++++++++++++++++ arch/arm/mach-socfpga/spl.c | 29 ----------------------------- 2 files changed, 30 insertions(+), 29 deletions(-)
arch/arm/mach-socfpga/misc.c +30 -0
@@ -12,6 +12,7 @@#include <altera.h> #include <miiphy.h> #include <netdev.h> +#include <spl.h> #include <watchdog.h> #include <asm/arch/misc.h> #include <asm/arch/reset_manager.h>
@@ -26,6 +27,9 @@ DECLARE_GLOBAL_DATA_PTR;static const struct pl310_regs *const pl310 = (struct pl310_regs *)CONFIG_SYS_PL310_BASE ; +static struct socfpga_system_manager *sysmgr_regs = + (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS ; +struct bsel bsel_str[] = { {"rsvd" ,"Reserved" , }, {"fpga" ,"FPGA (HPS2FPGA Bridge)" , },
@@ -37,6 +41,32 @@ struct bsel bsel_str[] = { { "qspi", "QSPI Flash (3.0V)", }, }; +u32 spl_boot_device (void ) +{ +const u32 bsel =readl (&sysmgr_regs->bootinfo); + +switch (SYSMGR_GET_BOOTINFO_BSEL (bsel)) { +case 0x1 :/* FPGA (HPS2FPGA Bridge) */ +return BOOT_DEVICE_RAM ; +case 0x2 :/* NAND Flash (1.8V) */ +case 0x3 :/* NAND Flash (3.0V) */ +socfpga_per_reset (SOCFPGA_RESET (NAND ),0 ); +return BOOT_DEVICE_NAND ; +case 0x4 :/* SD/MMC External Transceiver (1.8V) */ +case 0x5 :/* SD/MMC Internal Transceiver (3.0V) */ +socfpga_per_reset (SOCFPGA_RESET (SDMMC ),0 ); +socfpga_per_reset (SOCFPGA_RESET (DMA ),0 ); +return BOOT_DEVICE_MMC1 ; +case 0x6 :/* QSPI Flash (1.8V) */ +case 0x7 :/* QSPI Flash (3.0V) */ +socfpga_per_reset (SOCFPGA_RESET (QSPI ),0 ); +return BOOT_DEVICE_SPI ; +default : +printf ("Invalid boot device (bsel=%08x)!\n" , bsel); +hang (); + } +} +int dram_init (void ) { gd->ram_size =get_ram_size ((long *)PHYS_SDRAM_1 ,PHYS_SDRAM_1_SIZE );
arch/arm/mach-socfpga/spl.c +0 -29
@@ -37,35 +37,6 @@ static struct nic301_registers *nic301_regs = (struct nic301_registers *)SOCFPGA_L3REGS_ADDRESS ;#endif -static const struct socfpga_system_manager *sysmgr_regs = - (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS ; - -u32 spl_boot_device (void ) -{ -const u32 bsel =readl (&sysmgr_regs->bootinfo); - -switch (SYSMGR_GET_BOOTINFO_BSEL (bsel)) { -case 0x1 :/* FPGA (HPS2FPGA Bridge) */ -return BOOT_DEVICE_RAM ; -case 0x2 :/* NAND Flash (1.8V) */ -case 0x3 :/* NAND Flash (3.0V) */ -socfpga_per_reset (SOCFPGA_RESET (NAND ),0 ); -return BOOT_DEVICE_NAND ; -case 0x4 :/* SD/MMC External Transceiver (1.8V) */ -case 0x5 :/* SD/MMC Internal Transceiver (3.0V) */ -socfpga_per_reset (SOCFPGA_RESET (SDMMC ),0 ); -socfpga_per_reset (SOCFPGA_RESET (DMA ),0 ); -return BOOT_DEVICE_MMC1 ; -case 0x6 :/* QSPI Flash (1.8V) */ -case 0x7 :/* QSPI Flash (3.0V) */ -socfpga_per_reset (SOCFPGA_RESET (QSPI ),0 ); -return BOOT_DEVICE_SPI ; -default : -printf ("Invalid boot device (bsel=%08x)!\n" , bsel); -hang (); - } -} -#ifdef CONFIG_SPL_MMC_SUPPORT u32 spl_boot_mode (const u32 boot_device) {
Signature · 1 line
2.2.0
PATCH v2 2/5 arm: socfpga: Add checking function on FPGA setting in FDT
In reply to tien.fong.chee at intel.comFrom: Tien Fong Chee <[email protected]>
Function for checking FPGA early release setting which is defined by user in FDT chosen section. This function would be used by later driver in decision applying appropriate FPGA configuration in early release or full FPGA booting mode.
--- arch/arm/mach-socfpga/include/mach/misc.h | 1 + arch/arm/mach-socfpga/misc_arria10.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+)
arch/arm/mach-socfpga/include/mach/misc.h +1 -0
@@ -26,6 +26,7 @@ static inline void socfpga_fpga_add(void) {}unsigned int dedicated_uart_com_port (const void *blob);unsigned int shared_uart_com_port (const void *blob);unsigned int uart_com_port (const void *blob); +int is_early_release_fpga_config (const void *blob);#endif #endif /* _MISC_H_ */
arch/arm/mach-socfpga/misc_arria10.c +20 -0
@@ -235,6 +235,26 @@ unsigned int uart_com_port(const void *blob)return shared_uart_com_port (blob); } +int is_chosen_boolean_true (const void *blob,const char *name) +{ +int node; +int rval =0 ; + + node =fdt_subnode_offset (blob,0 ,"chosen" ); + +if (node >=0 ) + rval =fdtdec_get_bool (blob, node, name); + +return rval; +} + +int is_early_release_fpga_config (const void *blob) +{ +static const char *name ="early-release-fpga-config" ; + +return is_chosen_boolean_true (blob, name); +} +/* * Print CPU information */
Signature · 1 line
2.2.0
PATCH v2 2/5 arm: socfpga: Add checking function on FPGA setting in FDT
Quoted 6 lines · tien.fong.chee at intel.com
From: Tien Fong Chee <[email protected]>
Function for checking FPGA early release setting which is defined by user in FDT chosen section. This function would be used by later driver in decision applying appropriate FPGA configuration in early release or full FPGA booting mode.
Isn't this a property of the FPGA driver ?
Shouldn't this have altr, prefix ?
Did this go through DT binding review?
Quoted 50 lines
Signed-off-by Tien Fong Chee <[email protected]>--- arch/arm/mach-socfpga/include/mach/misc.h | 1 + arch/arm/mach-socfpga/misc_arria10.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+)arch/arm/mach-socfpga/include/mach/misc.h +1
-0@@ -26,6 +26,7 @@ static inline void socfpga_fpga_add(void) {}unsigned int dedicated_uart_com_port (const void *blob);unsigned int shared_uart_com_port (const void *blob);unsigned int uart_com_port (const void *blob); +int is_early_release_fpga_config (const void *blob);#endif #endif /* _MISC_H_ */ arch/arm/mach-socfpga/misc_arria10.c +20
-0@@ -235,6 +235,26 @@ unsigned int uart_com_port(const void *blob)return shared_uart_com_port (blob); } +int is_chosen_boolean_true (const void *blob,const char *name) +{ +int node; +int rval =0 ; + + node =fdt_subnode_offset (blob,0 ,"chosen" ); + +if (node >=0 ) + rval =fdtdec_get_bool (blob, node, name); + +return rval; +} + +int is_early_release_fpga_config (const void *blob) +{ +static const char *name ="early-release-fpga-config" ; + +return is_chosen_boolean_true (blob, name); +} +/* * Print CPU information */
Signature · 2 lines
Best regards, Marek Vasut
Chee
PATCH v2 2/5 arm: socfpga: Add checking function on FPGA setting in FDT
Quoted 4 lines · Marek Vasut
Quoted 3 lines · tien.fong.chee at intel.com
From: Tien Fong Chee <[email protected]>
Quoted 8 lines
Quoted 4 lines
Function for checking FPGA early release setting which is defined by user in FDT chosen section. This function would be used by later driver in decision applying appropriate FPGA configuration in early release or full FPGA booting mode.
Isn't this a property of the FPGA driver ?
Shouldn't this have altr, prefix ?
Did this go through DT binding review?
This is our own define under chosen section. This is flag to tell U- boot what kind of boot and what kind of fpga configuration we want during boot.
Quoted 55 lines
Quoted 54 lines
Signed-off-by Tien Fong Chee <[email protected]>---
arch/arm/mach-socfpga/include/mach/misc.h | 1 +
arch/arm/mach-socfpga/misc_arria10.c | 20
++++++++++++++++++++2 files changed, 21 insertions(+)arch/arm/mach-socfpga/include/mach/misc.h +1
-0@@ -26,6 +26,7 @@ static inline void socfpga_fpga_add(void) {} unsigned int dedicated_uart_com_port(const void *blob); unsigned int shared_uart_com_port(const void *blob); unsigned int uart_com_port(const void *blob); +int is_early_release_fpga_config (const void *blob); #endif
#endif /* _MISC_H_ */arch/arm/mach- renamed from arch/arm/mach-socfpga/misc_arria10.c +0
-0
socfpga/misc_arria10.c
index 9d751f6..2d6e977 100644arch/arm/mach-socfpga/misc_arria10.c +0
-0@@ -235,6 +235,26 @@ unsigned int uart_com_port(const void *blob) return shared_uart_com_port(blob); }arch/arm/mach-socfpga/misc_arria10.c +20
-0+int is_chosen_boolean_true (const void *blob,const char *name) +{ +int node; +int rval =0 ; + + node =fdt_subnode_offset (blob,0 ,"chosen" ); + +if (node >=0 ) + rval =fdtdec_get_bool (blob, node, name); + +return rval; +} + +int is_early_release_fpga_config (const void *blob) +{ +static const char *name ="early-release-fpga-config" ; + +return is_chosen_boolean_true (blob, name); +} +/*
* Print CPU information
*/
PATCH v2 2/5 arm: socfpga: Add checking function on FPGA setting in FDT
Quoted 9 lines · Tien Fong
Quoted 8 lines · Marek Vasut
Quoted 7 lines · tien.fong.chee at intel.com
From: Tien Fong Chee <[email protected]>
Function for checking FPGA early release setting which is defined by user in FDT chosen section. This function would be used by later driver in decision applying appropriate FPGA configuration in early release or full FPGA booting mode.
Quoted 7 lines
Quoted 4 lines
Isn't this a property of the FPGA driver ?
Shouldn't this have altr, prefix ?
Did this go through DT binding review?This is our own define under chosen section. This is flag to tell U- boot what kind of boot and what kind of fpga configuration we want during boot.
And you didn't answer any of the aforementioned questions :(
Quoted 54 lines
Quoted 54 lines
Quoted 54 lines
Signed-off-by Tien Fong Chee <[email protected]>--- arch/arm/mach-socfpga/include/mach/misc.h | 1 + arch/arm/mach-socfpga/misc_arria10.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+)arch/arm/mach-socfpga/include/mach/misc.h +1
-0@@ -26,6 +26,7 @@ static inline void socfpga_fpga_add(void) {}unsigned int dedicated_uart_com_port (const void *blob);unsigned int shared_uart_com_port (const void *blob);unsigned int uart_com_port (const void *blob); +int is_early_release_fpga_config (const void *blob);#endif #endif /* _MISC_H_ */ arch/arm/mach- renamed from arch/arm/mach-socfpga/misc_arria10.c +0
-0
socfpga/misc_arria10.c
index 9d751f6..2d6e977 100644arch/arm/mach-socfpga/misc_arria10.c +20
-0@@ -235,6 +235,26 @@ unsigned int uart_com_port(const void *blob)return shared_uart_com_port (blob); } +int is_chosen_boolean_true (const void *blob,const char *name) +{ +int node; +int rval =0 ; + + node =fdt_subnode_offset (blob,0 ,"chosen" ); + +if (node >=0 ) + rval =fdtdec_get_bool (blob, node, name); + +return rval; +} + +int is_early_release_fpga_config (const void *blob) +{ +static const char *name ="early-release-fpga-config" ; + +return is_chosen_boolean_true (blob, name); +} +/* * Print CPU information */
Signature · 2 lines
Best regards, Marek Vasut
Chee
PATCH v2 2/5 arm: socfpga: Add checking function on FPGA setting in FDT
Quoted 9 lines · Marek Vasut
Quoted 8 lines · Tien Fong
Quoted 6 lines · Marek Vasut
Quoted 4 lines · tien.fong.chee at intel.com
From: Tien Fong Chee <[email protected]>
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 6 lines
Function for checking FPGA early release setting which is defined
by user in FDT chosen section. This function would be used by later driver in decision applying appropriate FPGA configuration in
early release or full FPGA booting mode.Isn't this a property of the FPGA driver ?
This is not property of fpga driver. It acts like passing data flag to u-boot, so u-boot knows how to boot in the mode defined by user.
Quoted 1 line
Quoted 1 line
Quoted 1 line
Shouldn't this have altr, prefix ?
This node doesn't represet a real device, it acts like a place for passing data to U-boot. So, this flag name doesn't matter with prefix, right?
Quoted 1 line
Quoted 1 line
Quoted 1 line
Did this go through DT binding review?
No, refer my explanation above.
Quoted 7 lines
Quoted 5 lines
Quoted 1 line
This is our own define under chosen section. This is flag to tell U-
boot what kind of boot and what kind of fpga configuration we want during boot.And you didn't answer any of the aforementioned questions :(
Sorry, it could be i misunderstand your question. please refer my asnwer in above.
Quoted 60 lines
Quoted 59 lines
Quoted 59 lines
Quoted 59 lines
Signed-off-by Tien Fong Chee <[email protected]>---
arch/arm/mach-socfpga/include/mach/misc.h | 1 +
arch/arm/mach-socfpga/misc_arria10.c | 20
++++++++++++++++++++2 files changed, 21 insertions(+)arch/arm/mach-socfpga/include/mach/misc.h +1
-0@@ -26,6 +26,7 @@ static inline void socfpga_fpga_add(void) {} unsigned int dedicated_uart_com_port(const void *blob); unsigned int shared_uart_com_port(const void *blob); unsigned int uart_com_port(const void *blob); +int is_early_release_fpga_config (const void *blob); #endif
#endif /* _MISC_H_ */arch/arm/mach- renamed from arch/arm/mach-socfpga/misc_arria10.c +0
-0
socfpga/misc_arria10.c
index 9d751f6..2d6e977 100644arch/arm/mach-socfpga/misc_arria10.c +0
-0@@ -235,6 +235,26 @@ unsigned int uart_com_port(const void *blob) return shared_uart_com_port(blob); }arch/arm/mach-socfpga/misc_arria10.c +20
-0+int is_chosen_boolean_true (const void *blob,const char *name) +{ +int node; +int rval =0 ; + + node =fdt_subnode_offset (blob,0 ,"chosen" ); + +if (node >=0 ) + rval =fdtdec_get_bool (blob, node, name); + +return rval; +} + +int is_early_release_fpga_config (const void *blob) +{ +static const char *name ="early-release-fpga-config" ; + +return is_chosen_boolean_true (blob, name); +} +/*
* Print CPU information
*/
PATCH v2 2/5 arm: socfpga: Add checking function on FPGA setting in FDT
Quoted 16 lines · Tien Fong
Quoted 15 lines · Marek Vasut
Quoted 14 lines · Tien Fong
Quoted 12 lines · Marek Vasut
Quoted 10 lines · tien.fong.chee at intel.com
From: Tien Fong Chee <[email protected]>
Function for checking FPGA early release setting which is defined
by user in FDT chosen section. This function would be used by later driver in decision applying appropriate FPGA configuration in
early release or full FPGA booting mode.
Quoted 3 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
Isn't this a property of the FPGA driver ?
This is not property of fpga driver. It acts like passing data flag to u-boot, so u-boot knows how to boot in the mode defined by user.
So it's a configuration option ? Doing what ... since there's no binding document, it's not clear.
Quoted 4 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
Shouldn't this have altr, prefix ?
This node doesn't represet a real device, it acts like a place for passing data to U-boot. So, this flag name doesn't matter with prefix, right?
But it's altera-specific, so it should have one ?
Quoted 70 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
Did this go through DT binding review?
No, refer my explanation above.
Quoted 7 lines
Quoted 5 lines
Quoted 1 line
This is our own define under chosen section. This is flag to tell U-
boot what kind of boot and what kind of fpga configuration we want during boot.And you didn't answer any of the aforementioned questions :(
Sorry, it could be i misunderstand your question. please refer my asnwer in above.
Quoted 59 lines
Quoted 59 lines
Quoted 59 lines
Quoted 59 lines
Signed-off-by Tien Fong Chee <[email protected]>--- arch/arm/mach-socfpga/include/mach/misc.h | 1 + arch/arm/mach-socfpga/misc_arria10.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+)arch/arm/mach-socfpga/include/mach/misc.h +1
-0@@ -26,6 +26,7 @@ static inline void socfpga_fpga_add(void) {}unsigned int dedicated_uart_com_port (const void *blob);unsigned int shared_uart_com_port (const void *blob);unsigned int uart_com_port (const void *blob); +int is_early_release_fpga_config (const void *blob);#endif #endif /* _MISC_H_ */ arch/arm/mach- renamed from arch/arm/mach-socfpga/misc_arria10.c +0
-0
socfpga/misc_arria10.c
index 9d751f6..2d6e977 100644arch/arm/mach-socfpga/misc_arria10.c +20
-0@@ -235,6 +235,26 @@ unsigned int uart_com_port(const void *blob)return shared_uart_com_port (blob); } +int is_chosen_boolean_true (const void *blob,const char *name) +{ +int node; +int rval =0 ; + + node =fdt_subnode_offset (blob,0 ,"chosen" ); + +if (node >=0 ) + rval =fdtdec_get_bool (blob, node, name); + +return rval; +} + +int is_early_release_fpga_config (const void *blob) +{ +static const char *name ="early-release-fpga-config" ; + +return is_chosen_boolean_true (blob, name); +} +/* * Print CPU information */
Signature · 2 lines
Best regards, Marek Vasut
Chee
PATCH v2 2/5 arm: socfpga: Add checking function on FPGA setting in FDT
Quoted 23 lines · Marek Vasut
Quoted 22 lines · Tien Fong
Quoted 20 lines · Marek Vasut
Quoted 18 lines · Tien Fong
Quoted 15 lines · Marek Vasut
Quoted 12 lines · tien.fong.chee at intel.com
From: Tien Fong Chee <[email protected]>
Function for checking FPGA early release setting which is defined
by user in FDT chosen section. This function would be used by
later driver in decision applying appropriate FPGA configuration in
early release or full FPGA booting mode.
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
Isn't this a property of the FPGA driver ?
This is not property of fpga driver. It acts like passing data flag to
u-boot, so u-boot knows how to boot in the mode defined by user.So it's a configuration option ? Doing what ... since there's no binding
document, it's not clear.
Okay, i can add decription into / doc / device-tree-bindings / chosen.txt.
Quoted 11 lines
Quoted 9 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Shouldn't this have altr, prefix ?
This node doesn't represet a real device, it acts like a place for passing data to U-boot. So, this flag name doesn't matter with prefix,
right?But it's altera-specific, so it should have one ?
Yeah, i can add it.
Quoted 87 lines
Quoted 86 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Did this go through DT binding review?
No, refer my explanation above.
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 8 lines
Quoted 6 lines
This is our own define under chosen section. This is flag to tell
U-
boot what kind of boot and what kind of fpga configuration we want
during boot.And you didn't answer any of the aforementioned questions :(
Sorry, it could be i misunderstand your question. please refer my asnwer in above.
Quoted 66 lines
Quoted 66 lines
Quoted 66 lines
Quoted 66 lines
Signed-off-by Tien Fong Chee <[email protected]>---
arch/arm/mach-socfpga/include/mach/misc.h | 1 +
arch/arm/mach-socfpga/misc_arria10.c | 20
++++++++++++++++++++2 files changed, 21 insertions(+)arch/arm/mach-socfpga/include/mach/misc.h +1
-0@@ -26,6 +26,7 @@ static inline void socfpga_fpga_add(void) {} unsigned int dedicated_uart_com_port(const void *blob); unsigned int shared_uart_com_port(const void *blob); unsigned int uart_com_port(const void *blob); +int is_early_release_fpga_config (const void *blob); #endif
#endif /* _MISC_H_ */arch/arm/mach- renamed from arch/arm/mach-socfpga/misc_arria10.c +0
-0
socfpga/misc_arria10.c
index 9d751f6..2d6e977 100644arch/arm/mach-socfpga/misc_arria10.c +0
-0@@ -235,6 +235,26 @@ unsigned int uart_com_port(const void *blob) return shared_uart_com_port(blob); }
+intis_chosen_boolean_true(const void *blob, const char *name)arch/arm/mach-socfpga/misc_arria10.c +15
-0+{ +int node; +int rval =0 ; + + node =fdt_subnode_offset (blob,0 ,"chosen" ); + +if (node >=0 ) + rval =fdtdec_get_bool (blob, node, name); + +return rval; +} + +int is_early_release_fpga_config (const void *blob) +{ + static const char *name = "early-release-fpga-config";
arch/arm/mach-socfpga/misc_arria10.c +4
-0+ +return is_chosen_boolean_true (blob, name); +} +/*
* Print CPU information
*/
PATCH v2 2/5 arm: socfpga: Add checking function on FPGA setting in FDT
Quoted 38 lines · Tien Fong
Quoted 23 lines · Marek Vasut
Quoted 22 lines · Tien Fong
Quoted 20 lines · Marek Vasut
Quoted 18 lines · Tien Fong
Quoted 15 lines · Marek Vasut
Quoted 12 lines · tien.fong.chee at intel.com
From: Tien Fong Chee <[email protected]>
Function for checking FPGA early release setting which is defined
by user in FDT chosen section. This function would be used by
later driver in decision applying appropriate FPGA configuration in
early release or full FPGA booting mode.Quoted 8 lines
Quoted 4 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
Isn't this a property of the FPGA driver ?
This is not property of fpga driver. It acts like passing data flag to
u-boot, so u-boot knows how to boot in the mode defined by user.So it's a configuration option ? Doing what ... since there's no binding
document, it's not clear.Okay, i can add decription into / doc / device-tree-bindings / chosen.txt.
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 8 lines
Quoted 7 lines
Quoted 5 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
Shouldn't this have altr, prefix ?
This node doesn't represet a real device, it acts like a place for passing data to U-boot. So, this flag name doesn't matter with prefix,
right?But it's altera-specific, so it should have one ?
Yeah, i can add it.
OK
Signature · 2 lines
Best regards, Marek Vasut
PATCH v2 3/5 configs: Add FPGA loadfs config for Arria 10
In reply to tien.fong.chee at intel.comFrom: Tien Fong Chee <[email protected]>
This config allow FPGA design loaded from FAT fs to FPGA manager.
--- configs/socfpga_arria10_defconfig | 1 + 1 file changed, 1 insertion(+)
configs/socfpga_arria10_defconfig +1 -0
@@ -29,3 +29,4 @@ CONFIG_DWAPB_GPIO=y CONFIG_DM_MMC=y CONFIG_SYS_NS16550=y CONFIG_USE_TINY_PRINTF=y +CONFIG_CMD_FPGA_LOADFS=y
Signature · 1 line
2.2.0
PATCH v2 4/5 arm: socfpga: Add intermediate driver between flash and FPGA manager
In reply to tien.fong.chee at intel.comFrom: Tien Fong Chee <[email protected]>
Configuration flip-flop driver is mainly used for handling the FPGA program operation where the FPGA image loading from the flash into FPGA manager.
--- arch/arm/mach-socfpga/cff.c | 582 +++++++++++++++++++++++++++++++ arch/arm/mach-socfpga/include/mach/cff.h | 40 +++ include/configs/socfpga_arria10_socdk.h | 6 + 3 files changed, 628 insertions(+) create mode 100644 arch/arm/mach-socfpga/cff.c create mode 100644 arch/arm/mach-socfpga/include/mach/cff.h
arch/arm/mach-socfpga/cff.c new file +582 -0
@@ -0,0 +1,582 @@ +/* +* COPYRIGHT (C) 2017 Intel Corporation <www.intel.com> +* +* SPDX-License-Identifier: GPL-2.0 +*/ + +#include <altera.h> +#include <common.h> +#include <asm/io.h> +#include <asm/arch/cff.h> +#include <asm/arch/fpga_manager.h> +#include <asm/arch/misc.h> +#include <asm/arch/system_manager.h> +#include <asm/arch/reset_manager.h> +#include <errno.h> +#include <fat.h> +#include <fs.h> +#include <fdtdec.h> +#include <malloc.h> +#include <mmc.h> +#include <spi_flash.h> +#include <spl.h> +#include <watchdog.h> + +#define RBF_UNENCRYPTED 0xa65c +#define RBF_ENCRYPTED 0xa65d +#define ARRIA10RBF_PERIPH 0x0001 +#define ARRIA10RBF_CORE 0x8001 + +DECLARE_GLOBAL_DATA_PTR ; + +static int flash_type =-1 ; + +struct mmc *mmc; + +/* Local functions */ +static int cff_flash_read (struct cff_flash_info *cff_flashinfo,u32 *buffer, +u32 *buffer_sizebytes); +static int cff_flash_preinit (struct cff_flash_info *cff_flashinfo, +fpga_fs_info *fpga_fsinfo,u32 *buffer,u32 *buffer_sizebytes); +#ifdef CONFIG_CMD_FPGA_LOADFS +static const char *get_cff_filename (const void *fdt,int *len,u32 core); +#else +static int get_cff_offset (const void *fdt,u32 core); +#endif + +static struct mmc *init_mmc_device (int dev,bool force_init) +{ +struct mmc *mmc; + + mmc =find_mmc_device (dev); +if (!mmc) { +printf ("no mmc device at slot %x\n" , dev); +return NULL ; + } + +if (force_init) + mmc->has_init =0 ; +if (mmc_init (mmc)) +return NULL ; + +return mmc; +} + +static int cff_flash_probe (struct cff_flash_info *cff_flashinfo) +{ +int dev =0 ; + +if (BOOT_DEVICE_MMC1 == flash_type) + { + mmc =init_mmc_device (dev, true); + +if (!mmc) +return -ENOTBLK ; + +#ifdef CONFIG_CMD_FPGA_LOADFS +/* we are looking at the FAT partition */ +if (fat_register_device (mmc_get_blk_desc (mmc), + cff_flashinfo->sdmmc_flashinfo.dev_part)) { +printf ("Failed to set filesystem to FAT.\n" ); +return -EPERM ; + } +#endif + } + +return flash_type; +} + +static int flash_read (struct cff_flash_info *cff_flashinfo, +u32 size_read, +u32 *buffer_ptr) +{ +size_t ret =EEXIST ; +#ifdef CONFIG_CMD_FPGA_LOADFS +loff_t actread; +#endif + +if (BOOT_DEVICE_MMC1 == flash_type) { +#ifdef CONFIG_CMD_FPGA_LOADFS + ret =fat_read_file (cff_flashinfo->sdmmc_flashinfo.filename, + buffer_ptr, cff_flashinfo->flash_offset, + size_read, &actread); + +if (ret || actread != size_read) { +printf ("Failed to read %s from FAT %d " , + cff_flashinfo->sdmmc_flashinfo.filename, + ret); +printf ("!= %d.\n" , size_read); +return -EPERM ; + }else + ret = actread; +#else +u32 blk = cff_flashinfo->flash_offset/mmc->read_bl_len; +u32 cnt = size_read / mmc->read_bl_len; + +if (!cnt) + cnt =1 ; + +if ((size_read % mmc->read_bl_len) && + (size_read >= mmc->read_bl_len)) + cnt++; + + ret =blk_dread (mmc_get_blk_desc (mmc), blk, cnt, + buffer_ptr); + +if (cnt != ret) +return -EPERM ; +#endif + } + +return ret; +} + +#ifdef CONFIG_CMD_FPGA_LOADFS +const char *get_cff_filename (const void *fdt,int *len,u32 core) +{ +const char *cff_filename =NULL ; +const char *cell; +int nodeoffset; + nodeoffset =fdt_subnode_offset (fdt,0 ,"chosen" ); + +if (nodeoffset >=0 ) { +if (core) + cell =fdt_getprop (fdt, + nodeoffset, +"cffcore-file" , + len); +else + cell =fdt_getprop (fdt, nodeoffset,"cff-file" , len); + +if (cell) + cff_filename = cell; + } + +return cff_filename; +} +#else +static int get_cff_offset (const void *fdt,u32 core) +{ +int nodeoffset =0 ; + + nodeoffset =fdt_subnode_offset (fdt,0 ,"chosen" ); + +if (nodeoffset >=0 ) { +if (core) +return fdtdec_get_int (fdt, + nodeoffset, +"cffcore-offset" , + -ESPIPE ); +else +return fdtdec_get_int (fdt, + nodeoffset, +"cff-offset" , + -ESPIPE ); + } +return -ESPIPE ; +} +#endif + +int cff_from_sdmmc_env (u32 core) +{ +int rval = -ENOENT ; +fpga_fs_info fpga_fsinfo; + +#ifdef CONFIG_CMD_FPGA_LOADFS +int len =0 ; +const char *cff =NULL ; +#else +char addrToString[32 ] = {0 }; + +int sdmmc_rbf_rawaddr = -ENOENT ; +#endif + + flash_type =spl_boot_device (); + + fpga_fsinfo.interface ="sdmmc" ; + +#ifdef CONFIG_CMD_FPGA_LOADFS + cff =get_cff_filename (gd->fdt_blob, &len, core); + +/* FAT periph RBF file reading */ +if (cff && (len >0 )) { +mmc_initialize (gd->bd); + + fpga_fsinfo.filename = (char *)cff; + + fpga_fsinfo.dev_part =getenv ("cff_devsel_partition" ); + +if (NULL == fpga_fsinfo.dev_part) { +/* FAT partition */ + fpga_fsinfo.dev_part ="1" ; + +printf ("No SD/MMC partition found in environment. " ); +printf ("Assuming partition 1.\n" ); + } + + rval =cff_from_flash (&fpga_fsinfo); + } +#else + sdmmc_rbf_rawaddr =get_cff_offset (gd->fdt_blob, core); + +/* RAW periph RBF reading */ +if (sdmmc_rbf_rawaddr >=0 ) { +sprintf (addrToString,"%x" , sdmmc_rbf_rawaddr); + + fpga_fsinfo.filename = addrToString; + + rval =cff_from_flash (&fpga_fsinfo); + } +#endif +return rval; +} + +void get_rbf_image_info (struct rbf_info *rbf,u16 *buffer) +{ +/* +Magic ID starting at: +-> 1st dword in periph.rbf +-> 2nd dword in core.rbf +*/ +u32 word_reading_max =2 ; +u32 i; + +for (i =0 ; i < word_reading_max; i++) + { +if (RBF_UNENCRYPTED == *(buffer + i))/* PERIPH RBF */ + rbf->security = unencrypted; +else if (RBF_ENCRYPTED == *(buffer + i)) + rbf->security = encrypted; +else if (RBF_UNENCRYPTED == *(buffer + i +1 ))/* CORE RBF */ + rbf->security = unencrypted; +else if (RBF_ENCRYPTED == *(buffer + i +1 )) + rbf->security = encrypted; +else { + rbf->security = invalid; +continue ; + } + +/* PERIPH RBF */ +if (ARRIA10RBF_PERIPH == *(buffer + i +1 )) { + rbf->section = periph_section; +break ; + } +else if (ARRIA10RBF_CORE == *(buffer + i +1 )) { + rbf->section = core_section; +break ; + }/* CORE RBF */ +else if (ARRIA10RBF_PERIPH == *(buffer + i +2 )) { + rbf->section = periph_section; +break ; + } +else if (ARRIA10RBF_CORE == *(buffer + i +2 )) { + rbf->section = core_section; +break ; + } +else { + rbf->section = unknown; +break ; + } + } + +return ; +} + +static int cff_flash_preinit (struct cff_flash_info *cff_flashinfo, +fpga_fs_info *fpga_fsinfo,u32 *buffer,u32 *buffer_sizebytes) +{ +u32 *bufferptr_after_header =NULL ; +u32 buffersize_after_header =0 ; +u32 rbf_header_data_size =0 ; +int ret =0 ; +/* To avoid from keeping re-read the contents */ +struct image_header *header = &(cff_flashinfo->header); +size_t buffer_size = *buffer_sizebytes; +u32 *buffer_ptr = (u32 *)*buffer; + +#ifdef CONFIG_CMD_FPGA_LOADFS + cff_flashinfo->sdmmc_flashinfo.filename = fpga_fsinfo->filename; + cff_flashinfo->flash_offset =0 ; +#else + cff_flashinfo->flash_offset = +simple_strtoul (fpga_fsinfo->filename,NULL ,16 ); +#endif + +/* Load mkimage header into buffer */ + ret =flash_read (cff_flashinfo, +sizeof (struct image_header ), buffer_ptr); + +if (0 >= ret) { +printf (" Failed to read mkimage header from flash.\n" ); +return -ENOENT ; + } + +WATCHDOG_RESET (); + +memcpy (header, (u_char *)buffer_ptr,sizeof (*header)); + +if (!image_check_magic (header)) { +printf ("FPGA: Bad Magic Number.\n" ); +return -EBADF ; + } + +if (!image_check_hcrc (header)) { +printf ("FPGA: Bad Header Checksum.\n" ); +return -EPERM ; + } + +/* Getting rbf data size */ + cff_flashinfo->remaining = +image_get_data_size (header); + +/* Calculate total size of both rbf data with mkimage header */ + rbf_header_data_size = cff_flashinfo->remaining + +sizeof (struct image_header ); + +/* Loading to buffer chunk by chunk, normally for OCRAM buffer */ +if (rbf_header_data_size > buffer_size) { +/* Calculate size of rbf data in the buffer */ + buffersize_after_header = + buffer_size -sizeof (struct image_header ); + cff_flashinfo->remaining -= buffersize_after_header; + }else { +/* Loading whole rbf image into buffer, normally for DDR buffer */ + buffer_size = rbf_header_data_size; +/* Calculate size of rbf data in the buffer */ + buffersize_after_header = + buffer_size -sizeof (struct image_header ); + cff_flashinfo->remaining =0 ; + } + +/* Loading mkimage header and rbf data into buffer */ + ret =flash_read (cff_flashinfo, buffer_size, buffer_ptr); + +if (0 >= ret) { +printf (" Failed to read mkimage header and rbf data " ); +printf ("from flash.\n" ); +return -ENOENT ; + } + +/* Getting pointer of rbf data starting address where is it +right after mkimage header */ + bufferptr_after_header = + (u32 *)((u_char *)buffer_ptr +sizeof (struct image_header )); + +/* Update next reading rbf data flash offset */ + cff_flashinfo->flash_offset += buffer_size; + +/* Update the starting addr of rbf data to init FPGA & programming +into FPGA */ + *buffer = (u32 )bufferptr_after_header; + +get_rbf_image_info (&cff_flashinfo->rbfinfo, (u16 *)bufferptr_after_header); + +/* Update the size of rbf data to be programmed into FPGA */ + *buffer_sizebytes = buffersize_after_header; + +#ifdef CONFIG_CHECK_FPGA_DATA_CRC + cff_flashinfo->datacrc = +crc32 (cff_flashinfo->datacrc, + (u_char *)bufferptr_after_header, + buffersize_after_header); +#endif +if (0 == cff_flashinfo->remaining) { +#ifdef CONFIG_CHECK_FPGA_DATA_CRC +if (cff_flashinfo->datacrc != +image_get_dcrc (&(cff_flashinfo->header))) { +printf ("FPGA: Bad Data Checksum.\n" ); +return -EPERM ; + } +#endif +} +return 0 ; +} + + +static int cff_flash_read (struct cff_flash_info *cff_flashinfo,u32 *buffer, +u32 *buffer_sizebytes) +{ +int ret =0 ; +/* To avoid from keeping re-read the contents */ +size_t buffer_size = *buffer_sizebytes; +u32 *buffer_ptr = (u32 *)*buffer; +u32 flash_addr = cff_flashinfo->flash_offset; + +/* Buffer allocated in OCRAM */ +/* Read the data by small chunk by chunk. */ +if (cff_flashinfo->remaining > buffer_size) + cff_flashinfo->remaining -= buffer_size; +else { +/* Buffer allocated in DDR, larger than rbf data most +of the time */ + buffer_size = cff_flashinfo->remaining; + cff_flashinfo->remaining =0 ; + } + + ret =flash_read (cff_flashinfo, buffer_size, buffer_ptr); + +if (0 >= ret) { +printf (" Failed to read rbf data from flash.\n" ); +return -ENOENT ; + } + +#ifdef CONFIG_CHECK_FPGA_DATA_CRC + cff_flashinfo->datacrc = +crc32 (cff_flashinfo->datacrc, + (unsigned char *)buffer_ptr, buffer_size); +#endif + +if (0 == cff_flashinfo->remaining) { +#ifdef CONFIG_CHECK_FPGA_DATA_CRC +if (cff_flashinfo->datacrc != +image_get_dcrc (&(cff_flashinfo->header))) { +printf ("FPGA: Bad Data Checksum.\n" ); +return -EPERM ; + } +#endif +} +/* Update next reading rbf data flash offset */ + flash_addr += buffer_size; + + cff_flashinfo->flash_offset = flash_addr; + +/* Update the size of rbf data to be programmed into FPGA */ + *buffer_sizebytes = buffer_size; + +return 0 ; +} + +int cff_from_flash (fpga_fs_info *fpga_fsinfo) +{ +u32 buffer =0 ; +u32 buffer_ori =0 ; +u32 buffer_sizebytes =0 ; +u32 buffer_sizebytes_ori =0 ; +struct cff_flash_info cff_flashinfo; +u32 status; +int ret =0 ; + +memset (&cff_flashinfo,0 ,sizeof (cff_flashinfo)); + +if (fpga_fsinfo->filename ==NULL ) { +printf ("no [periph/core] rbf [filename/offset] specified.\n" ); +return -EINVAL ; + } + +WATCHDOG_RESET (); + +#ifdef CONFIG_CMD_FPGA_LOADFS + cff_flashinfo.sdmmc_flashinfo.dev_part = +simple_strtol (fpga_fsinfo->dev_part,NULL ,10 ); +#endif + + ret =cff_flash_probe (&cff_flashinfo); + +if (0 >= ret) { +puts ("Flash probe failed.\n" ); +return ret; + } + +#ifdef CONFIG_CMD_FPGA_LOADFS +/* Loading rbf data with DDR, faster than OCRAM, +only for core rbf */ +if (gd->ram_size !=0 ) { + ret =fat_size (fpga_fsinfo->filename, (loff_t *)&buffer_sizebytes); + +if (ret){ +puts ("Failed to read file size.\n" ); +return ret; + } + + buffer_ori = (u32 )memalign (ARCH_DMA_MINALIGN , buffer_sizebytes); + +if (!buffer_ori) { +error ("RBF calloc failed!\n" ); +return -ENOMEM ; + } + +/* Loading mkimage header and rbf data into +DDR instead of OCRAM */ + buffer = buffer_ori; + + buffer_sizebytes_ori = buffer_sizebytes; + }else { + buffer = buffer_ori = (u32 )cff_flashinfo.buffer; + + buffer_sizebytes = + buffer_sizebytes_ori = +sizeof (cff_flashinfo.buffer); + } +#else +/* Adjust to adjacent block */ + buffer_sizebytes = buffer_sizebytes_ori = + (sizeof (cff_flashinfo.buffer)/ mmc->read_bl_len) * + mmc->read_bl_len; +#endif + +/* Note: Both buffer and buffer_sizebytes values can be altered by +function below. */ + ret =cff_flash_preinit (&cff_flashinfo, fpga_fsinfo, &buffer, + &buffer_sizebytes); + +if (ret) +return ret; + +if (periph_section == cff_flashinfo.rbfinfo.section) { +/* initialize the FPGA Manager */ + status =fpgamgr_program_init ((u32 *)buffer, buffer_sizebytes); +if (status) { +printf ("FPGA: Init with periph rbf failed with error. " ); +printf ("code %d\n" , status); +return -EPERM ; + } + } + +WATCHDOG_RESET (); + +/* transfer data to FPGA Manager */ +fpgamgr_program_write ((void *)buffer, + buffer_sizebytes); + +WATCHDOG_RESET (); + +while (cff_flashinfo.remaining) { + ret =cff_flash_read (&cff_flashinfo, &buffer_ori, + &buffer_sizebytes_ori); + +if (ret) +return ret; + +/* transfer data to FPGA Manager */ +fpgamgr_program_write ((void *)buffer_ori, + buffer_sizebytes_ori); + +WATCHDOG_RESET (); + } + +if ((periph_section == cff_flashinfo.rbfinfo.section) && +is_early_release_fpga_config (gd->fdt_blob)) { +if (-ETIMEDOUT !=fpgamgr_wait_early_user_mode ()) +printf ("FPGA: Early Release Succeeded.\n" ); +else { +printf ("FPGA: Failed to see Early Release.\n" ); +return -EIO ; + } + }else if ((core_section == cff_flashinfo.rbfinfo.section) || + ((periph_section == cff_flashinfo.rbfinfo.section) && + !is_early_release_fpga_config (gd->fdt_blob))) { +/* Ensure the FPGA entering config done */ + status =fpgamgr_program_finish (); +if (status) +return status; +else +printf ("FPGA: Enter user mode.\n" ); + + }else { +printf ("Config Error: Unsupported FGPA raw binary type.\n" ); +return -ENOEXEC ; + } + +WATCHDOG_RESET (); +return 1 ; +}
arch/arm/mach-socfpga/include/mach/cff.h new file +40 -0
@@ -0,0 +1,40 @@ +/* +* Copyright (C) 2017 Intel Corporation <www.intel.com> +* +* SPDX-License-Identifier: GPL-2.0 +*/ + +#ifndef _SOCFPGA_CFF_H_ +#define _SOCFPGA_CFF_H_ + +#include <fpga.h> + +#ifndef __ASSEMBLY_ + +struct flash_info { +char *filename; +int dev_part; +}; + +enum rbf_type {unknown, periph_section, core_section}; +enum rbf_security {invalid, unencrypted, encrypted}; + +struct rbf_info { +enum rbf_type section ; +enum rbf_security security; +}; + +struct cff_flash_info { +struct flash_info sdmmc_flashinfo; +u32 buffer[4096 ]__aligned(ARCH_DMA_MINALIGN) ; +u32 remaining; +u32 flash_offset; +struct rbf_info rbfinfo; +struct image_header header; +}; + +int cff_from_sdmmc_env (unsigned int core); +int cff_from_flash (fpga_fs_info *fpga_fsinfo); +#endif /* __ASSEMBLY__ */ + +#endif /* _SOCFPGA_CFF_H_ */
include/configs/socfpga_arria10_socdk.h +6 -0
@@ -58,6 +58,12 @@* Flash configurations */ #define CONFIG_SYS_MAX_FLASH_BANKS 1 +/* Default SDMMC physical address for periph.rbf (sector alignment) */ +#define CONFIG_FS_FAT_MAX_CLUSTSIZE (32 * 1024) + +#if !defined(CONFIG_SPL_BUILD ) && !defined(CONFIG_CMD_FPGA_LOADFS ) +#define CONFIG_CMD_FPGA_LOADFS +#endif /* The rest of the configuration is shared */ #include <configs/socfpga_common.h>
Signature · 1 line
2.2.0
PATCH v2 4/5 arm: socfpga: Add intermediate driver between flash and FPGA manager
Quoted 4 lines · tien.fong.chee at intel.com
From: Tien Fong Chee <[email protected]>
Configuration flip-flop driver is mainly used for handling the FPGA program operation where the FPGA image loading from the flash into FPGA manager.
I don't understand what this driver is for , sorry.
Coding style issues are present (camel case, wrong comment style, use checkpatch).
If this is for some FPGA loading, can this functionality be scripted instead?
Quoted 661 lines
Signed-off-by Tien Fong Chee <[email protected]>--- arch/arm/mach-socfpga/cff.c | 582 +++++++++++++++++++++++++++++++ arch/arm/mach-socfpga/include/mach/cff.h | 40 +++ include/configs/socfpga_arria10_socdk.h | 6 + 3 files changed, 628 insertions(+) create mode 100644 arch/arm/mach-socfpga/cff.c create mode 100644 arch/arm/mach-socfpga/include/mach/cff.harch/arm/mach-socfpga/cff.c new file +582
-0@@ -0,0 +1,582 @@ +/* +* COPYRIGHT (C) 2017 Intel Corporation <www.intel.com> +* +* SPDX-License-Identifier: GPL-2.0 +*/ + +#include <altera.h> +#include <common.h> +#include <asm/io.h> +#include <asm/arch/cff.h> +#include <asm/arch/fpga_manager.h> +#include <asm/arch/misc.h> +#include <asm/arch/system_manager.h> +#include <asm/arch/reset_manager.h> +#include <errno.h> +#include <fat.h> +#include <fs.h> +#include <fdtdec.h> +#include <malloc.h> +#include <mmc.h> +#include <spi_flash.h> +#include <spl.h> +#include <watchdog.h> + +#define RBF_UNENCRYPTED 0xa65c +#define RBF_ENCRYPTED 0xa65d +#define ARRIA10RBF_PERIPH 0x0001 +#define ARRIA10RBF_CORE 0x8001 + +DECLARE_GLOBAL_DATA_PTR ; + +static int flash_type =-1 ; + +struct mmc *mmc; + +/* Local functions */ +static int cff_flash_read (struct cff_flash_info *cff_flashinfo,u32 *buffer, +u32 *buffer_sizebytes); +static int cff_flash_preinit (struct cff_flash_info *cff_flashinfo, +fpga_fs_info *fpga_fsinfo,u32 *buffer,u32 *buffer_sizebytes); +#ifdef CONFIG_CMD_FPGA_LOADFS +static const char *get_cff_filename (const void *fdt,int *len,u32 core); +#else +static int get_cff_offset (const void *fdt,u32 core); +#endif + +static struct mmc *init_mmc_device (int dev,bool force_init) +{ +struct mmc *mmc; + + mmc =find_mmc_device (dev); +if (!mmc) { +printf ("no mmc device at slot %x\n" , dev); +return NULL ; + } + +if (force_init) + mmc->has_init =0 ; +if (mmc_init (mmc)) +return NULL ; + +return mmc; +} + +static int cff_flash_probe (struct cff_flash_info *cff_flashinfo) +{ +int dev =0 ; + +if (BOOT_DEVICE_MMC1 == flash_type) + { + mmc =init_mmc_device (dev, true); + +if (!mmc) +return -ENOTBLK ; + +#ifdef CONFIG_CMD_FPGA_LOADFS +/* we are looking at the FAT partition */ +if (fat_register_device (mmc_get_blk_desc (mmc), + cff_flashinfo->sdmmc_flashinfo.dev_part)) { +printf ("Failed to set filesystem to FAT.\n" ); +return -EPERM ; + } +#endif + } + +return flash_type; +} + +static int flash_read (struct cff_flash_info *cff_flashinfo, +u32 size_read, +u32 *buffer_ptr) +{ +size_t ret =EEXIST ; +#ifdef CONFIG_CMD_FPGA_LOADFS +loff_t actread; +#endif + +if (BOOT_DEVICE_MMC1 == flash_type) { +#ifdef CONFIG_CMD_FPGA_LOADFS + ret =fat_read_file (cff_flashinfo->sdmmc_flashinfo.filename, + buffer_ptr, cff_flashinfo->flash_offset, + size_read, &actread); + +if (ret || actread != size_read) { +printf ("Failed to read %s from FAT %d " , + cff_flashinfo->sdmmc_flashinfo.filename, + ret); +printf ("!= %d.\n" , size_read); +return -EPERM ; + }else + ret = actread; +#else +u32 blk = cff_flashinfo->flash_offset/mmc->read_bl_len; +u32 cnt = size_read / mmc->read_bl_len; + +if (!cnt) + cnt =1 ; + +if ((size_read % mmc->read_bl_len) && + (size_read >= mmc->read_bl_len)) + cnt++; + + ret =blk_dread (mmc_get_blk_desc (mmc), blk, cnt, + buffer_ptr); + +if (cnt != ret) +return -EPERM ; +#endif + } + +return ret; +} + +#ifdef CONFIG_CMD_FPGA_LOADFS +const char *get_cff_filename (const void *fdt,int *len,u32 core) +{ +const char *cff_filename =NULL ; +const char *cell; +int nodeoffset; + nodeoffset =fdt_subnode_offset (fdt,0 ,"chosen" ); + +if (nodeoffset >=0 ) { +if (core) + cell =fdt_getprop (fdt, + nodeoffset, +"cffcore-file" , + len); +else + cell =fdt_getprop (fdt, nodeoffset,"cff-file" , len); + +if (cell) + cff_filename = cell; + } + +return cff_filename; +} +#else +static int get_cff_offset (const void *fdt,u32 core) +{ +int nodeoffset =0 ; + + nodeoffset =fdt_subnode_offset (fdt,0 ,"chosen" ); + +if (nodeoffset >=0 ) { +if (core) +return fdtdec_get_int (fdt, + nodeoffset, +"cffcore-offset" , + -ESPIPE ); +else +return fdtdec_get_int (fdt, + nodeoffset, +"cff-offset" , + -ESPIPE ); + } +return -ESPIPE ; +} +#endif + +int cff_from_sdmmc_env (u32 core) +{ +int rval = -ENOENT ; +fpga_fs_info fpga_fsinfo; + +#ifdef CONFIG_CMD_FPGA_LOADFS +int len =0 ; +const char *cff =NULL ; +#else +char addrToString[32 ] = {0 }; + +int sdmmc_rbf_rawaddr = -ENOENT ; +#endif + + flash_type =spl_boot_device (); + + fpga_fsinfo.interface ="sdmmc" ; + +#ifdef CONFIG_CMD_FPGA_LOADFS + cff =get_cff_filename (gd->fdt_blob, &len, core); + +/* FAT periph RBF file reading */ +if (cff && (len >0 )) { +mmc_initialize (gd->bd); + + fpga_fsinfo.filename = (char *)cff; + + fpga_fsinfo.dev_part =getenv ("cff_devsel_partition" ); + +if (NULL == fpga_fsinfo.dev_part) { +/* FAT partition */ + fpga_fsinfo.dev_part ="1" ; + +printf ("No SD/MMC partition found in environment. " ); +printf ("Assuming partition 1.\n" ); + } + + rval =cff_from_flash (&fpga_fsinfo); + } +#else + sdmmc_rbf_rawaddr =get_cff_offset (gd->fdt_blob, core); + +/* RAW periph RBF reading */ +if (sdmmc_rbf_rawaddr >=0 ) { +sprintf (addrToString,"%x" , sdmmc_rbf_rawaddr); + + fpga_fsinfo.filename = addrToString; + + rval =cff_from_flash (&fpga_fsinfo); + } +#endif +return rval; +} + +void get_rbf_image_info (struct rbf_info *rbf,u16 *buffer) +{ +/* +Magic ID starting at: +-> 1st dword in periph.rbf +-> 2nd dword in core.rbf +*/ +u32 word_reading_max =2 ; +u32 i; + +for (i =0 ; i < word_reading_max; i++) + { +if (RBF_UNENCRYPTED == *(buffer + i))/* PERIPH RBF */ + rbf->security = unencrypted; +else if (RBF_ENCRYPTED == *(buffer + i)) + rbf->security = encrypted; +else if (RBF_UNENCRYPTED == *(buffer + i +1 ))/* CORE RBF */ + rbf->security = unencrypted; +else if (RBF_ENCRYPTED == *(buffer + i +1 )) + rbf->security = encrypted; +else { + rbf->security = invalid; +continue ; + } + +/* PERIPH RBF */ +if (ARRIA10RBF_PERIPH == *(buffer + i +1 )) { + rbf->section = periph_section; +break ; + } +else if (ARRIA10RBF_CORE == *(buffer + i +1 )) { + rbf->section = core_section; +break ; + }/* CORE RBF */ +else if (ARRIA10RBF_PERIPH == *(buffer + i +2 )) { + rbf->section = periph_section; +break ; + } +else if (ARRIA10RBF_CORE == *(buffer + i +2 )) { + rbf->section = core_section; +break ; + } +else { + rbf->section = unknown; +break ; + } + } + +return ; +} + +static int cff_flash_preinit (struct cff_flash_info *cff_flashinfo, +fpga_fs_info *fpga_fsinfo,u32 *buffer,u32 *buffer_sizebytes) +{ +u32 *bufferptr_after_header =NULL ; +u32 buffersize_after_header =0 ; +u32 rbf_header_data_size =0 ; +int ret =0 ; +/* To avoid from keeping re-read the contents */ +struct image_header *header = &(cff_flashinfo->header); +size_t buffer_size = *buffer_sizebytes; +u32 *buffer_ptr = (u32 *)*buffer; + +#ifdef CONFIG_CMD_FPGA_LOADFS + cff_flashinfo->sdmmc_flashinfo.filename = fpga_fsinfo->filename; + cff_flashinfo->flash_offset =0 ; +#else + cff_flashinfo->flash_offset = +simple_strtoul (fpga_fsinfo->filename,NULL ,16 ); +#endif + +/* Load mkimage header into buffer */ + ret =flash_read (cff_flashinfo, +sizeof (struct image_header ), buffer_ptr); + +if (0 >= ret) { +printf (" Failed to read mkimage header from flash.\n" ); +return -ENOENT ; + } + +WATCHDOG_RESET (); + +memcpy (header, (u_char *)buffer_ptr,sizeof (*header)); + +if (!image_check_magic (header)) { +printf ("FPGA: Bad Magic Number.\n" ); +return -EBADF ; + } + +if (!image_check_hcrc (header)) { +printf ("FPGA: Bad Header Checksum.\n" ); +return -EPERM ; + } + +/* Getting rbf data size */ + cff_flashinfo->remaining = +image_get_data_size (header); + +/* Calculate total size of both rbf data with mkimage header */ + rbf_header_data_size = cff_flashinfo->remaining + +sizeof (struct image_header ); + +/* Loading to buffer chunk by chunk, normally for OCRAM buffer */ +if (rbf_header_data_size > buffer_size) { +/* Calculate size of rbf data in the buffer */ + buffersize_after_header = + buffer_size -sizeof (struct image_header ); + cff_flashinfo->remaining -= buffersize_after_header; + }else { +/* Loading whole rbf image into buffer, normally for DDR buffer */ + buffer_size = rbf_header_data_size; +/* Calculate size of rbf data in the buffer */ + buffersize_after_header = + buffer_size -sizeof (struct image_header ); + cff_flashinfo->remaining =0 ; + } + +/* Loading mkimage header and rbf data into buffer */ + ret =flash_read (cff_flashinfo, buffer_size, buffer_ptr); + +if (0 >= ret) { +printf (" Failed to read mkimage header and rbf data " ); +printf ("from flash.\n" ); +return -ENOENT ; + } + +/* Getting pointer of rbf data starting address where is it +right after mkimage header */ + bufferptr_after_header = + (u32 *)((u_char *)buffer_ptr +sizeof (struct image_header )); + +/* Update next reading rbf data flash offset */ + cff_flashinfo->flash_offset += buffer_size; + +/* Update the starting addr of rbf data to init FPGA & programming +into FPGA */ + *buffer = (u32 )bufferptr_after_header; + +get_rbf_image_info (&cff_flashinfo->rbfinfo, (u16 *)bufferptr_after_header); + +/* Update the size of rbf data to be programmed into FPGA */ + *buffer_sizebytes = buffersize_after_header; + +#ifdef CONFIG_CHECK_FPGA_DATA_CRC + cff_flashinfo->datacrc = +crc32 (cff_flashinfo->datacrc, + (u_char *)bufferptr_after_header, + buffersize_after_header); +#endif +if (0 == cff_flashinfo->remaining) { +#ifdef CONFIG_CHECK_FPGA_DATA_CRC +if (cff_flashinfo->datacrc != +image_get_dcrc (&(cff_flashinfo->header))) { +printf ("FPGA: Bad Data Checksum.\n" ); +return -EPERM ; + } +#endif +} +return 0 ; +} + + +static int cff_flash_read (struct cff_flash_info *cff_flashinfo,u32 *buffer, +u32 *buffer_sizebytes) +{ +int ret =0 ; +/* To avoid from keeping re-read the contents */ +size_t buffer_size = *buffer_sizebytes; +u32 *buffer_ptr = (u32 *)*buffer; +u32 flash_addr = cff_flashinfo->flash_offset; + +/* Buffer allocated in OCRAM */ +/* Read the data by small chunk by chunk. */ +if (cff_flashinfo->remaining > buffer_size) + cff_flashinfo->remaining -= buffer_size; +else { +/* Buffer allocated in DDR, larger than rbf data most +of the time */ + buffer_size = cff_flashinfo->remaining; + cff_flashinfo->remaining =0 ; + } + + ret =flash_read (cff_flashinfo, buffer_size, buffer_ptr); + +if (0 >= ret) { +printf (" Failed to read rbf data from flash.\n" ); +return -ENOENT ; + } + +#ifdef CONFIG_CHECK_FPGA_DATA_CRC + cff_flashinfo->datacrc = +crc32 (cff_flashinfo->datacrc, + (unsigned char *)buffer_ptr, buffer_size); +#endif + +if (0 == cff_flashinfo->remaining) { +#ifdef CONFIG_CHECK_FPGA_DATA_CRC +if (cff_flashinfo->datacrc != +image_get_dcrc (&(cff_flashinfo->header))) { +printf ("FPGA: Bad Data Checksum.\n" ); +return -EPERM ; + } +#endif +} +/* Update next reading rbf data flash offset */ + flash_addr += buffer_size; + + cff_flashinfo->flash_offset = flash_addr; + +/* Update the size of rbf data to be programmed into FPGA */ + *buffer_sizebytes = buffer_size; + +return 0 ; +} + +int cff_from_flash (fpga_fs_info *fpga_fsinfo) +{ +u32 buffer =0 ; +u32 buffer_ori =0 ; +u32 buffer_sizebytes =0 ; +u32 buffer_sizebytes_ori =0 ; +struct cff_flash_info cff_flashinfo; +u32 status; +int ret =0 ; + +memset (&cff_flashinfo,0 ,sizeof (cff_flashinfo)); + +if (fpga_fsinfo->filename ==NULL ) { +printf ("no [periph/core] rbf [filename/offset] specified.\n" ); +return -EINVAL ; + } + +WATCHDOG_RESET (); + +#ifdef CONFIG_CMD_FPGA_LOADFS + cff_flashinfo.sdmmc_flashinfo.dev_part = +simple_strtol (fpga_fsinfo->dev_part,NULL ,10 ); +#endif + + ret =cff_flash_probe (&cff_flashinfo); + +if (0 >= ret) { +puts ("Flash probe failed.\n" ); +return ret; + } + +#ifdef CONFIG_CMD_FPGA_LOADFS +/* Loading rbf data with DDR, faster than OCRAM, +only for core rbf */ +if (gd->ram_size !=0 ) { + ret =fat_size (fpga_fsinfo->filename, (loff_t *)&buffer_sizebytes); + +if (ret){ +puts ("Failed to read file size.\n" ); +return ret; + } + + buffer_ori = (u32 )memalign (ARCH_DMA_MINALIGN , buffer_sizebytes); + +if (!buffer_ori) { +error ("RBF calloc failed!\n" ); +return -ENOMEM ; + } + +/* Loading mkimage header and rbf data into +DDR instead of OCRAM */ + buffer = buffer_ori; + + buffer_sizebytes_ori = buffer_sizebytes; + }else { + buffer = buffer_ori = (u32 )cff_flashinfo.buffer; + + buffer_sizebytes = + buffer_sizebytes_ori = +sizeof (cff_flashinfo.buffer); + } +#else +/* Adjust to adjacent block */ + buffer_sizebytes = buffer_sizebytes_ori = + (sizeof (cff_flashinfo.buffer)/ mmc->read_bl_len) * + mmc->read_bl_len; +#endif + +/* Note: Both buffer and buffer_sizebytes values can be altered by +function below. */ + ret =cff_flash_preinit (&cff_flashinfo, fpga_fsinfo, &buffer, + &buffer_sizebytes); + +if (ret) +return ret; + +if (periph_section == cff_flashinfo.rbfinfo.section) { +/* initialize the FPGA Manager */ + status =fpgamgr_program_init ((u32 *)buffer, buffer_sizebytes); +if (status) { +printf ("FPGA: Init with periph rbf failed with error. " ); +printf ("code %d\n" , status); +return -EPERM ; + } + } + +WATCHDOG_RESET (); + +/* transfer data to FPGA Manager */ +fpgamgr_program_write ((void *)buffer, + buffer_sizebytes); + +WATCHDOG_RESET (); + +while (cff_flashinfo.remaining) { + ret =cff_flash_read (&cff_flashinfo, &buffer_ori, + &buffer_sizebytes_ori); + +if (ret) +return ret; + +/* transfer data to FPGA Manager */ +fpgamgr_program_write ((void *)buffer_ori, + buffer_sizebytes_ori); + +WATCHDOG_RESET (); + } + +if ((periph_section == cff_flashinfo.rbfinfo.section) && +is_early_release_fpga_config (gd->fdt_blob)) { +if (-ETIMEDOUT !=fpgamgr_wait_early_user_mode ()) +printf ("FPGA: Early Release Succeeded.\n" ); +else { +printf ("FPGA: Failed to see Early Release.\n" ); +return -EIO ; + } + }else if ((core_section == cff_flashinfo.rbfinfo.section) || + ((periph_section == cff_flashinfo.rbfinfo.section) && + !is_early_release_fpga_config (gd->fdt_blob))) { +/* Ensure the FPGA entering config done */ + status =fpgamgr_program_finish (); +if (status) +return status; +else +printf ("FPGA: Enter user mode.\n" ); + + }else { +printf ("Config Error: Unsupported FGPA raw binary type.\n" ); +return -ENOEXEC ; + } + +WATCHDOG_RESET (); +return 1 ; +}arch/arm/mach-socfpga/include/mach/cff.h new file +40
-0@@ -0,0 +1,40 @@ +/* +* Copyright (C) 2017 Intel Corporation <www.intel.com> +* +* SPDX-License-Identifier: GPL-2.0 +*/ + +#ifndef _SOCFPGA_CFF_H_ +#define _SOCFPGA_CFF_H_ + +#include <fpga.h> + +#ifndef __ASSEMBLY_ + +struct flash_info { +char *filename; +int dev_part; +}; + +enum rbf_type {unknown, periph_section, core_section}; +enum rbf_security {invalid, unencrypted, encrypted}; + +struct rbf_info { +enum rbf_type section ; +enum rbf_security security; +}; + +struct cff_flash_info { +struct flash_info sdmmc_flashinfo; +u32 buffer[4096 ]__aligned(ARCH_DMA_MINALIGN) ; +u32 remaining; +u32 flash_offset; +struct rbf_info rbfinfo; +struct image_header header; +}; + +int cff_from_sdmmc_env (unsigned int core); +int cff_from_flash (fpga_fs_info *fpga_fsinfo); +#endif /* __ASSEMBLY__ */ + +#endif /* _SOCFPGA_CFF_H_ */ include/configs/socfpga_arria10_socdk.h +6
-0@@ -58,6 +58,12 @@* Flash configurations */ #define CONFIG_SYS_MAX_FLASH_BANKS 1 +/* Default SDMMC physical address for periph.rbf (sector alignment) */ +#define CONFIG_FS_FAT_MAX_CLUSTSIZE (32 * 1024) + +#if !defined(CONFIG_SPL_BUILD ) && !defined(CONFIG_CMD_FPGA_LOADFS ) +#define CONFIG_CMD_FPGA_LOADFS +#endif /* The rest of the configuration is shared */ #include <configs/socfpga_common.h>
Signature · 2 lines
Best regards, Marek Vasut
Chee
PATCH v2 4/5 arm: socfpga: Add intermediate driver between flash and FPGA manager
Quoted 10 lines · Marek Vasut
Quoted 7 lines · tien.fong.chee at intel.com
From: Tien Fong Chee <[email protected]>
Configuration flip-flop driver is mainly used for handling the FPGA program
operation where the FPGA image loading from the flash into FPGA manager.I don't understand what this driver is for , sorry.
this is core driver for handling fpga program operation from flash to fpga manager. I can improve the message. Let me know if you have other comment need to add.
Quoted 3 lines
Coding style issues are present (camel case, wrong comment style, use checkpatch).
Okay, i will run checkpatch.
Quoted 3 lines
If this is for some FPGA loading, can this functionality be scripted instead?
Sorry, i'm not getting you. How functionality be scripted? Could you provide some example or details explanation?
Thanks.
Quoted 711 lines
Quoted 710 lines
Signed-off-by Tien Fong Chee <[email protected]>---
arch/arm/mach-socfpga/cff.c | 582
+++++++++++++++++++++++++++++++
arch/arm/mach-socfpga/include/mach/cff.h | 40 +++ include/configs/socfpga_arria10_socdk.h | 6 +3 files changed, 628 insertions(+)create mode 100644
arch/arm/mach-socfpga/cff.ccreate mode 100644arch/arm/mach-socfpga/include/mach/cff.harch/arm/mach- renamed from arch/arm/mach-socfpga/cff.c +0
-0
socfpga/cff.c
new file mode 100644
index 0000000..ccee5e9arch/arm/mach-socfpga/cff.c new file +37
-0@@ -0,0 +1,582 @@ +/* +* COPYRIGHT (C) 2017 Intel Corporation <www.intel.com> +* +* SPDX-License-Identifier: GPL-2.0 +*/ + +#include <altera.h> +#include <common.h> +#include <asm/io.h> +#include <asm/arch/cff.h> +#include <asm/arch/fpga_manager.h> +#include <asm/arch/misc.h> +#include <asm/arch/system_manager.h> +#include <asm/arch/reset_manager.h> +#include <errno.h> +#include <fat.h> +#include <fs.h> +#include <fdtdec.h> +#include <malloc.h> +#include <mmc.h> +#include <spi_flash.h> +#include <spl.h> +#include <watchdog.h> + +#define RBF_UNENCRYPTED 0xa65c +#define RBF_ENCRYPTED 0xa65d +#define ARRIA10RBF_PERIPH 0x0001 +#define ARRIA10RBF_CORE 0x8001 + +DECLARE_GLOBAL_DATA_PTR ; + +static int flash_type =-1 ; + +struct mmc *mmc; + +/* Local functions */ +static int cff_flash_read(struct cff_flash_info *cff_flashinfo,u32 *buffer,
arch/arm/mach-socfpga/cff.c new file +3
-0+ u32 *buffer_sizebytes); +static int cff_flash_preinit (struct cff_flash_info *cff_flashinfo, + fpga_fs_info *fpga_fsinfo, u32 *buffer, u32
*buffer_sizebytes);arch/arm/mach-socfpga/cff.c new file +2
-0+#ifdef CONFIG_CMD_FPGA_LOADFS +static const char *get_cff_filename(const void *fdt, int *len, u32core);
arch/arm/mach-socfpga/cff.c new file +37
-0+#else +static int get_cff_offset (const void *fdt,u32 core); +#endif + +static struct mmc *init_mmc_device (int dev,bool force_init) +{ +struct mmc *mmc; + + mmc =find_mmc_device (dev); +if (!mmc) { +printf ("no mmc device at slot %x\n" , dev); +return NULL ; + } + +if (force_init) + mmc->has_init =0 ; +if (mmc_init (mmc)) +return NULL ; + +return mmc; +} + +static int cff_flash_probe (struct cff_flash_info *cff_flashinfo) +{ +int dev =0 ; + +if (BOOT_DEVICE_MMC1 == flash_type) + { + mmc =init_mmc_device (dev, true); + +if (!mmc) +return -ENOTBLK ; + +#ifdef CONFIG_CMD_FPGA_LOADFS +/* we are looking at the FAT partition */ +if (fat_register_device (mmc_get_blk_desc (mmc), + cff_flashinfo->sdmmc_flashinfo.dev_part)){
arch/arm/mach-socfpga/cff.c new file +1
-0+ printf("Failed to set filesystem toFAT.\n");
arch/arm/mach-socfpga/cff.c new file +20
-0+return -EPERM ; + } +#endif + } + +return flash_type; +} + +static int flash_read (struct cff_flash_info *cff_flashinfo, +u32 size_read, +u32 *buffer_ptr) +{ +size_t ret =EEXIST ; +#ifdef CONFIG_CMD_FPGA_LOADFS +loff_t actread; +#endif + +if (BOOT_DEVICE_MMC1 == flash_type) { +#ifdef CONFIG_CMD_FPGA_LOADFS + ret = fat_read_file(cff_flashinfo-Quoted 1 line
sdmmc_flashinfo.filename,
arch/arm/mach-socfpga/cff.c new file +1
-0+ buffer_ptr, cff_flashinfo-Quoted 1 line
flash_offset,arch/arm/mach-socfpga/cff.c new file +5
-0+ size_read, &actread); + +if (ret || actread != size_read) { + printf("Failed to read %s from FAT %d ", + cff_flashinfo-Quoted 1 line
sdmmc_flashinfo.filename,
arch/arm/mach-socfpga/cff.c new file +7
-0+ ret); +printf ("!= %d.\n" , size_read); + return -EPERM; + }else + ret = actread; +#else + u32 blk = cff_flashinfo->flash_offset/mmc-Quoted 1 line
read_bl_len;arch/arm/mach-socfpga/cff.c new file +36
-0+u32 cnt = size_read / mmc->read_bl_len; + +if (!cnt) + cnt =1 ; + +if ((size_read % mmc->read_bl_len) && + (size_read >= mmc->read_bl_len)) + cnt++; + + ret =blk_dread (mmc_get_blk_desc (mmc), blk, cnt, + buffer_ptr); + +if (cnt != ret) +return -EPERM ; +#endif + } + +return ret; +} + +#ifdef CONFIG_CMD_FPGA_LOADFS +const char *get_cff_filename (const void *fdt,int *len,u32 core) +{ +const char *cff_filename =NULL ; +const char *cell; +int nodeoffset; + nodeoffset =fdt_subnode_offset (fdt,0 ,"chosen" ); + +if (nodeoffset >=0 ) { +if (core) + cell =fdt_getprop (fdt, + nodeoffset, +"cffcore-file" , + len); +else + cell = fdt_getprop(fdt, nodeoffset, "cff-file", len);
arch/arm/mach-socfpga/cff.c new file +58
-0+ +if (cell) + cff_filename = cell; + } + +return cff_filename; +} +#else +static int get_cff_offset (const void *fdt,u32 core) +{ +int nodeoffset =0 ; + + nodeoffset =fdt_subnode_offset (fdt,0 ,"chosen" ); + +if (nodeoffset >=0 ) { +if (core) +return fdtdec_get_int (fdt, + nodeoffset, +"cffcore-offset" , + -ESPIPE ); +else +return fdtdec_get_int (fdt, + nodeoffset, +"cff-offset" , + -ESPIPE ); + } +return -ESPIPE ; +} +#endif + +int cff_from_sdmmc_env (u32 core) +{ +int rval = -ENOENT ; +fpga_fs_info fpga_fsinfo; + +#ifdef CONFIG_CMD_FPGA_LOADFS +int len =0 ; +const char *cff =NULL ; +#else +char addrToString[32 ] = {0 }; + +int sdmmc_rbf_rawaddr = -ENOENT ; +#endif + + flash_type =spl_boot_device (); + + fpga_fsinfo.interface ="sdmmc" ; + +#ifdef CONFIG_CMD_FPGA_LOADFS + cff =get_cff_filename (gd->fdt_blob, &len, core); + +/* FAT periph RBF file reading */ +if (cff && (len >0 )) { +mmc_initialize (gd->bd); + + fpga_fsinfo.filename = (char *)cff; + + fpga_fsinfo.dev_part =
getenv("cff_devsel_partition");arch/arm/mach-socfpga/cff.c new file +6
-0+ +if (NULL == fpga_fsinfo.dev_part) { +/* FAT partition */ + fpga_fsinfo.dev_part ="1" ; + + printf("No SD/MMC partition found inenvironment. ");
arch/arm/mach-socfpga/cff.c new file +33
-0+ printf("Assuming partition 1.\n"); + } + + rval =cff_from_flash (&fpga_fsinfo); + } +#else + sdmmc_rbf_rawaddr =get_cff_offset (gd->fdt_blob, core); + + /* RAW periph RBF reading */ +if (sdmmc_rbf_rawaddr >=0 ) { +sprintf (addrToString,"%x" , sdmmc_rbf_rawaddr); + + fpga_fsinfo.filename = addrToString; + + rval =cff_from_flash (&fpga_fsinfo); + } +#endif +return rval; +} + +void get_rbf_image_info (struct rbf_info *rbf,u16 *buffer) +{ +/* +Magic ID starting at: +-> 1st dword in periph.rbf +-> 2nd dword in core.rbf +*/ +u32 word_reading_max =2 ; +u32 i; + +for (i =0 ; i < word_reading_max; i++) + { +if (RBF_UNENCRYPTED == *(buffer + i))/* PERIPH RBF */
arch/arm/mach-socfpga/cff.c new file +4
-0+ rbf->security = unencrypted; + else if (RBF_ENCRYPTED == *(buffer + i)) + rbf->security = encrypted; + else if (RBF_UNENCRYPTED == *(buffer + i + 1)) /*CORE RBF */
arch/arm/mach-socfpga/cff.c new file +1
-0+ rbf->security =unencrypted;
arch/arm/mach-socfpga/cff.c new file +35
-0+else if (RBF_ENCRYPTED == *(buffer + i +1 )) + rbf->security = encrypted; +else { + rbf->security = invalid; +continue ; + } + +/* PERIPH RBF */ +if (ARRIA10RBF_PERIPH == *(buffer + i +1 )) { + rbf->section = periph_section; +break ; + } +else if (ARRIA10RBF_CORE == *(buffer + i +1 )) { + rbf->section = core_section; +break ; + }/* CORE RBF */ +else if (ARRIA10RBF_PERIPH == *(buffer + i +2 )) { + rbf->section = periph_section; +break ; + } +else if (ARRIA10RBF_CORE == *(buffer + i +2 )) { + rbf->section = core_section; +break ; + } +else { + rbf->section = unknown; +break ; + } + } + +return ; +} + +static int cff_flash_preinit (struct cff_flash_info *cff_flashinfo, + fpga_fs_info *fpga_fsinfo, u32 *buffer, u32
*buffer_sizebytes)arch/arm/mach-socfpga/cff.c new file +12
-0+{ +u32 *bufferptr_after_header =NULL ; +u32 buffersize_after_header =0 ; +u32 rbf_header_data_size =0 ; +int ret =0 ; +/* To avoid from keeping re-read the contents */ +struct image_header *header = &(cff_flashinfo->header); +size_t buffer_size = *buffer_sizebytes; +u32 *buffer_ptr = (u32 *)*buffer; + +#ifdef CONFIG_CMD_FPGA_LOADFS + cff_flashinfo->sdmmc_flashinfo.filename = fpga_fsinfo-Quoted 1 line
filename;
arch/arm/mach-socfpga/cff.c new file +12
-0+ cff_flashinfo->flash_offset =0 ; +#else + cff_flashinfo->flash_offset = +simple_strtoul (fpga_fsinfo->filename,NULL ,16 ); +#endif + + /* Load mkimage header into buffer */ + ret =flash_read (cff_flashinfo, +sizeof (struct image_header ), buffer_ptr); + +if (0 >= ret) { + printf(" Failed to read mkimage header fromflash.\n");
arch/arm/mach-socfpga/cff.c new file +22
-0+return -ENOENT ; + } + +WATCHDOG_RESET (); + +memcpy (header, (u_char *)buffer_ptr,sizeof (*header)); + +if (!image_check_magic (header)) { +printf ("FPGA: Bad Magic Number.\n" ); +return -EBADF ; + } + +if (!image_check_hcrc (header)) { +printf ("FPGA: Bad Header Checksum.\n" ); +return -EPERM ; + } + +/* Getting rbf data size */ + cff_flashinfo->remaining = +image_get_data_size (header); + +/* Calculate total size of both rbf data with mkimage header */
arch/arm/mach-socfpga/cff.c new file +4
-0+ rbf_header_data_size = cff_flashinfo->remaining + +sizeof (struct image_header ); + +/* Loading to buffer chunk by chunk, normally for OCRAM buffer */
arch/arm/mach-socfpga/cff.c new file +5
-0+if (rbf_header_data_size > buffer_size) { +/* Calculate size of rbf data in the buffer */ + buffersize_after_header = + buffer_size -sizeof (struct image_header ); + cff_flashinfo->remaining -=
buffersize_after_header;arch/arm/mach-socfpga/cff.c new file +2
-0+ }else { +/* Loading whole rbf image into buffer, normally for DDR buffer */
arch/arm/mach-socfpga/cff.c new file +12
-0+ buffer_size = rbf_header_data_size; +/* Calculate size of rbf data in the buffer */ + buffersize_after_header = + buffer_size -sizeof (struct image_header ); + cff_flashinfo->remaining =0 ; + } + +/* Loading mkimage header and rbf data into buffer */ + ret =flash_read (cff_flashinfo, buffer_size, buffer_ptr); + +if (0 >= ret) { + printf(" Failed to read mkimage header and rbfdata ");
arch/arm/mach-socfpga/cff.c new file +5
-0+printf ("from flash.\n" ); +return -ENOENT ; + } + +/* Getting pointer of rbf data starting address where is it
arch/arm/mach-socfpga/cff.c new file +3
-0+right after mkimage header */ + bufferptr_after_header = + (u32 *)((u_char *)buffer_ptr + sizeof(struct
image_header));arch/arm/mach-socfpga/cff.c new file +5
-0+ +/* Update next reading rbf data flash offset */ + cff_flashinfo->flash_offset += buffer_size; + +/* Update the starting addr of rbf data to init FPGA & programming
arch/arm/mach-socfpga/cff.c new file +4
-0+into FPGA */ + *buffer = (u32 )bufferptr_after_header; + + get_rbf_image_info(&cff_flashinfo->rbfinfo, (u16*)bufferptr_after_header);
arch/arm/mach-socfpga/cff.c new file +2
-0+ +/* Update the size of rbf data to be programmed into FPGA */
arch/arm/mach-socfpga/cff.c new file +22
-0+ *buffer_sizebytes = buffersize_after_header; + +#ifdef CONFIG_CHECK_FPGA_DATA_CRC + cff_flashinfo->datacrc = +crc32 (cff_flashinfo->datacrc, + (u_char *)bufferptr_after_header, + buffersize_after_header); +#endif +if (0 == cff_flashinfo->remaining) { +#ifdef CONFIG_CHECK_FPGA_DATA_CRC +if (cff_flashinfo->datacrc != +image_get_dcrc (&(cff_flashinfo->header))) { +printf ("FPGA: Bad Data Checksum.\n" ); +return -EPERM ; + } +#endif +} +return 0 ; +} + + +static int cff_flash_read(struct cff_flash_info *cff_flashinfo,u32 *buffer,
arch/arm/mach-socfpga/cff.c new file +14
-0+ u32 *buffer_sizebytes) +{ +int ret =0 ; +/* To avoid from keeping re-read the contents */ +size_t buffer_size = *buffer_sizebytes; +u32 *buffer_ptr = (u32 *)*buffer; +u32 flash_addr = cff_flashinfo->flash_offset; + +/* Buffer allocated in OCRAM */ +/* Read the data by small chunk by chunk. */ +if (cff_flashinfo->remaining > buffer_size) + cff_flashinfo->remaining -= buffer_size; +else { +/* Buffer allocated in DDR, larger than rbf data most
arch/arm/mach-socfpga/cff.c new file +33
-0+of the time */ + buffer_size = cff_flashinfo->remaining; + cff_flashinfo->remaining =0 ; + } + + ret =flash_read (cff_flashinfo, buffer_size, buffer_ptr); + +if (0 >= ret) { +printf (" Failed to read rbf data from flash.\n" ); +return -ENOENT ; + } + +#ifdef CONFIG_CHECK_FPGA_DATA_CRC + cff_flashinfo->datacrc = +crc32 (cff_flashinfo->datacrc, + (unsigned char *)buffer_ptr, buffer_size); +#endif + +if (0 == cff_flashinfo->remaining) { +#ifdef CONFIG_CHECK_FPGA_DATA_CRC +if (cff_flashinfo->datacrc != +image_get_dcrc (&(cff_flashinfo->header))) { +printf ("FPGA: Bad Data Checksum.\n" ); +return -EPERM ; + } +#endif +} +/* Update next reading rbf data flash offset */ + flash_addr += buffer_size; + + cff_flashinfo->flash_offset = flash_addr; + +/* Update the size of rbf data to be programmed into FPGA */
arch/arm/mach-socfpga/cff.c new file +19
-0+ *buffer_sizebytes = buffer_size; + +return 0 ; +} + +int cff_from_flash (fpga_fs_info *fpga_fsinfo) +{ +u32 buffer =0 ; +u32 buffer_ori =0 ; +u32 buffer_sizebytes =0 ; +u32 buffer_sizebytes_ori =0 ; +struct cff_flash_info cff_flashinfo; +u32 status; +int ret =0 ; + +memset (&cff_flashinfo,0 ,sizeof (cff_flashinfo)); + +if (fpga_fsinfo->filename ==NULL ) { + printf("no [periph/core] rbf [filename/offset]specified.\n");
arch/arm/mach-socfpga/cff.c new file +22
-0+return -EINVAL ; + } + +WATCHDOG_RESET (); + +#ifdef CONFIG_CMD_FPGA_LOADFS + cff_flashinfo.sdmmc_flashinfo.dev_part = +simple_strtol (fpga_fsinfo->dev_part,NULL ,10 ); +#endif + + ret =cff_flash_probe (&cff_flashinfo); + +if (0 >= ret) { +puts ("Flash probe failed.\n" ); +return ret; + } + +#ifdef CONFIG_CMD_FPGA_LOADFS +/* Loading rbf data with DDR, faster than OCRAM, +only for core rbf */ +if (gd->ram_size !=0 ) { + ret = fat_size(fpga_fsinfo->filename, (loff_t*)&buffer_sizebytes);
arch/arm/mach-socfpga/cff.c new file +7
-0+ +if (ret){ +puts ("Failed to read file size.\n" ); +return ret; + } + + buffer_ori = (u32)memalign(ARCH_DMA_MINALIGN,
buffer_sizebytes);arch/arm/mach-socfpga/cff.c new file +22
-0+ +if (!buffer_ori) { +error ("RBF calloc failed!\n" ); +return -ENOMEM ; + } + +/* Loading mkimage header and rbf data into +DDR instead of OCRAM */ + buffer = buffer_ori; + + buffer_sizebytes_ori = buffer_sizebytes; + }else { + buffer = buffer_ori = (u32 )cff_flashinfo.buffer; + + buffer_sizebytes = + buffer_sizebytes_ori = +sizeof (cff_flashinfo.buffer); + } +#else +/* Adjust to adjacent block */ + buffer_sizebytes = buffer_sizebytes_ori = + (sizeof(cff_flashinfo.buffer)/
mmc->read_bl_len) *arch/arm/mach-socfpga/cff.c new file +4
-0+ mmc->read_bl_len; +#endif + +/* Note: Both buffer and buffer_sizebytes values can be altered by
arch/arm/mach-socfpga/cff.c new file +2
-0+function below. */ + ret = cff_flash_preinit(&cff_flashinfo, fpga_fsinfo,&buffer,
arch/arm/mach-socfpga/cff.c new file +8
-0+ &buffer_sizebytes); + +if (ret) +return ret; + +if (periph_section == cff_flashinfo.rbfinfo.section) { +/* initialize the FPGA Manager */ + status = fpgamgr_program_init((u32 *)buffer,
buffer_sizebytes);arch/arm/mach-socfpga/cff.c new file +2
-0+if (status) { + printf("FPGA: Init with periph rbf failedwith error. ");
arch/arm/mach-socfpga/cff.c new file +31
-0+printf ("code %d\n" , status); +return -EPERM ; + } + } + +WATCHDOG_RESET (); + +/* transfer data to FPGA Manager */ +fpgamgr_program_write ((void *)buffer, + buffer_sizebytes); + +WATCHDOG_RESET (); + +while (cff_flashinfo.remaining) { + ret =cff_flash_read (&cff_flashinfo, &buffer_ori, + &buffer_sizebytes_ori); + +if (ret) +return ret; + +/* transfer data to FPGA Manager */ +fpgamgr_program_write ((void *)buffer_ori, + buffer_sizebytes_ori); + +WATCHDOG_RESET (); + } + +if ((periph_section == cff_flashinfo.rbfinfo.section) && + is_early_release_fpga_config(gd->fdt_blob)) { +if (-ETIMEDOUT !=fpgamgr_wait_early_user_mode ()) + printf("FPGA: Early ReleaseSucceeded.\n");
arch/arm/mach-socfpga/cff.c new file +2
-0+else { + printf("FPGA: Failed to see EarlyRelease.\n");
arch/arm/mach-socfpga/cff.c new file +3
-0+return -EIO ; + } + } else if ((core_section == cff_flashinfo.rbfinfo.section)||
arch/arm/mach-socfpga/cff.c new file +11
-0+ ((periph_section == cff_flashinfo.rbfinfo.section) && + !is_early_release_fpga_config(gd->fdt_blob))) { +/* Ensure the FPGA entering config done */ + status =fpgamgr_program_finish (); +if (status) +return status; +else +printf ("FPGA: Enter user mode.\n" ); + + } else { + printf("Config Error: Unsupported FGPA raw binarytype.\n");
arch/arm/mach-socfpga/cff.c new file +6
-0+return -ENOEXEC ; + } + +WATCHDOG_RESET (); +return 1 ; +}arch/arm/mach-socfpga/include/mach/cff.h new file +40
-0@@ -0,0 +1,40 @@ +/* +* Copyright (C) 2017 Intel Corporation <www.intel.com> +* +* SPDX-License-Identifier: GPL-2.0 +*/ + +#ifndef _SOCFPGA_CFF_H_ +#define _SOCFPGA_CFF_H_ + +#include <fpga.h> + +#ifndef __ASSEMBLY_ + +struct flash_info { +char *filename; +int dev_part; +}; + +enum rbf_type {unknown, periph_section, core_section}; +enum rbf_security {invalid, unencrypted, encrypted}; + +struct rbf_info { +enum rbf_type section ; +enum rbf_security security; +}; + +struct cff_flash_info { +struct flash_info sdmmc_flashinfo; +u32 buffer[4096 ]__aligned(ARCH_DMA_MINALIGN) ; +u32 remaining; +u32 flash_offset; +struct rbf_info rbfinfo; +struct image_header header; +}; + +int cff_from_sdmmc_env (unsigned int core); +int cff_from_flash (fpga_fs_info *fpga_fsinfo); +#endif /* __ASSEMBLY__ */ + +#endif /* _SOCFPGA_CFF_H_ */ include/configs/socfpga_arria10_socdk.h +1
-0@@ -58,6 +58,12 @@* Flash configurations */ #define CONFIG_SYS_MAX_FLASH_BANKS 1 +/* Default SDMMC physical address for periph.rbf (sector alignment) */
include/configs/socfpga_arria10_socdk.h +5
-0+#define CONFIG_FS_FAT_MAX_CLUSTSIZE (32 * 1024) + +#if !defined(CONFIG_SPL_BUILD ) && !defined(CONFIG_CMD_FPGA_LOADFS ) +#define CONFIG_CMD_FPGA_LOADFS +#endif
/* The rest of the configuration is shared */
#include <configs/socfpga_common.h>
PATCH v2 4/5 arm: socfpga: Add intermediate driver between flash and FPGA manager
Quoted 9 lines · Tien Fong
Quoted 8 lines · Marek Vasut
Quoted 7 lines · tien.fong.chee at intel.com
From: Tien Fong Chee <[email protected]>
Configuration flip-flop driver is mainly used for handling the FPGA program
operation where the FPGA image loading from the flash into FPGA manager.
Quoted 5 lines
Quoted 2 lines
I don't understand what this driver is for , sorry.
this is core driver for handling fpga program operation from flash to fpga manager. I can improve the message. Let me know if you have other comment need to add.
Yes, it's not clear what this driver is for. It dabbles into multiple subsystems , but I don't understand how is this useful.
Quoted 4 lines
Quoted 3 lines
Coding style issues are present (camel case, wrong comment style, use checkpatch).
Okay, i will run checkpatch.
You should always run checkpatch before submitting patches.
Quoted 5 lines
Quoted 3 lines
If this is for some FPGA loading, can this functionality be scripted instead?
Sorry, i'm not getting you. How functionality be scripted? Could you provide some example or details explanation?
ie. "load" (from fs) + "fpga load" (program FPGA) commands ?
I think the fpga command already has some support for loading from FS too.
Quoted 711 lines
Thanks.
Quoted 710 lines
Quoted 710 lines
Signed-off-by Tien Fong Chee <[email protected]>--- arch/arm/mach-socfpga/cff.c | 582 +++++++++++++++++++++++++++++++ arch/arm/mach-socfpga/include/mach/cff.h | 40 +++ include/configs/socfpga_arria10_socdk.h | 6 + 3 files changed, 628 insertions(+) create mode 100644 arch/arm/mach-socfpga/cff.c create mode 100644 arch/arm/mach-socfpga/include/mach/cff.harch/arm/mach- renamed from arch/arm/mach-socfpga/cff.c +0
-0
socfpga/cff.c
new file mode 100644
index 0000000..ccee5e9arch/arm/mach-socfpga/cff.c new file +37
-0@@ -0,0 +1,582 @@ +/* +* COPYRIGHT (C) 2017 Intel Corporation <www.intel.com> +* +* SPDX-License-Identifier: GPL-2.0 +*/ + +#include <altera.h> +#include <common.h> +#include <asm/io.h> +#include <asm/arch/cff.h> +#include <asm/arch/fpga_manager.h> +#include <asm/arch/misc.h> +#include <asm/arch/system_manager.h> +#include <asm/arch/reset_manager.h> +#include <errno.h> +#include <fat.h> +#include <fs.h> +#include <fdtdec.h> +#include <malloc.h> +#include <mmc.h> +#include <spi_flash.h> +#include <spl.h> +#include <watchdog.h> + +#define RBF_UNENCRYPTED 0xa65c +#define RBF_ENCRYPTED 0xa65d +#define ARRIA10RBF_PERIPH 0x0001 +#define ARRIA10RBF_CORE 0x8001 + +DECLARE_GLOBAL_DATA_PTR ; + +static int flash_type =-1 ; + +struct mmc *mmc; + +/* Local functions */ +static int cff_flash_read(struct cff_flash_info *cff_flashinfo,u32 *buffer,
arch/arm/mach-socfpga/cff.c new file +3
-0+ u32 *buffer_sizebytes); +static int cff_flash_preinit (struct cff_flash_info *cff_flashinfo, + fpga_fs_info *fpga_fsinfo, u32 *buffer, u32
*buffer_sizebytes);arch/arm/mach-socfpga/cff.c new file +2
-0+#ifdef CONFIG_CMD_FPGA_LOADFS +static const char *get_cff_filename(const void *fdt, int *len, u32core);
arch/arm/mach-socfpga/cff.c new file +37
-0+#else +static int get_cff_offset (const void *fdt,u32 core); +#endif + +static struct mmc *init_mmc_device (int dev,bool force_init) +{ +struct mmc *mmc; + + mmc =find_mmc_device (dev); +if (!mmc) { +printf ("no mmc device at slot %x\n" , dev); +return NULL ; + } + +if (force_init) + mmc->has_init =0 ; +if (mmc_init (mmc)) +return NULL ; + +return mmc; +} + +static int cff_flash_probe (struct cff_flash_info *cff_flashinfo) +{ +int dev =0 ; + +if (BOOT_DEVICE_MMC1 == flash_type) + { + mmc =init_mmc_device (dev, true); + +if (!mmc) +return -ENOTBLK ; + +#ifdef CONFIG_CMD_FPGA_LOADFS +/* we are looking at the FAT partition */ +if (fat_register_device (mmc_get_blk_desc (mmc), + cff_flashinfo->sdmmc_flashinfo.dev_part)){
arch/arm/mach-socfpga/cff.c new file +1
-0+ printf("Failed to set filesystem toFAT.\n");
arch/arm/mach-socfpga/cff.c new file +20
-0+return -EPERM ; + } +#endif + } + +return flash_type; +} + +static int flash_read (struct cff_flash_info *cff_flashinfo, +u32 size_read, +u32 *buffer_ptr) +{ +size_t ret =EEXIST ; +#ifdef CONFIG_CMD_FPGA_LOADFS +loff_t actread; +#endif + +if (BOOT_DEVICE_MMC1 == flash_type) { +#ifdef CONFIG_CMD_FPGA_LOADFS + ret = fat_read_file(cff_flashinfo-Quoted 1 line
sdmmc_flashinfo.filename,
arch/arm/mach-socfpga/cff.c new file +1
-0+ buffer_ptr, cff_flashinfo-Quoted 1 line
flash_offset,arch/arm/mach-socfpga/cff.c new file +5
-0+ size_read, &actread); + +if (ret || actread != size_read) { + printf("Failed to read %s from FAT %d ", + cff_flashinfo-Quoted 1 line
sdmmc_flashinfo.filename,
arch/arm/mach-socfpga/cff.c new file +7
-0+ ret); +printf ("!= %d.\n" , size_read); + return -EPERM; + }else + ret = actread; +#else + u32 blk = cff_flashinfo->flash_offset/mmc-Quoted 1 line
read_bl_len;arch/arm/mach-socfpga/cff.c new file +36
-0+u32 cnt = size_read / mmc->read_bl_len; + +if (!cnt) + cnt =1 ; + +if ((size_read % mmc->read_bl_len) && + (size_read >= mmc->read_bl_len)) + cnt++; + + ret =blk_dread (mmc_get_blk_desc (mmc), blk, cnt, + buffer_ptr); + +if (cnt != ret) +return -EPERM ; +#endif + } + +return ret; +} + +#ifdef CONFIG_CMD_FPGA_LOADFS +const char *get_cff_filename (const void *fdt,int *len,u32 core) +{ +const char *cff_filename =NULL ; +const char *cell; +int nodeoffset; + nodeoffset =fdt_subnode_offset (fdt,0 ,"chosen" ); + +if (nodeoffset >=0 ) { +if (core) + cell =fdt_getprop (fdt, + nodeoffset, +"cffcore-file" , + len); +else + cell = fdt_getprop(fdt, nodeoffset, "cff-file", len);
arch/arm/mach-socfpga/cff.c new file +58
-0+ +if (cell) + cff_filename = cell; + } + +return cff_filename; +} +#else +static int get_cff_offset (const void *fdt,u32 core) +{ +int nodeoffset =0 ; + + nodeoffset =fdt_subnode_offset (fdt,0 ,"chosen" ); + +if (nodeoffset >=0 ) { +if (core) +return fdtdec_get_int (fdt, + nodeoffset, +"cffcore-offset" , + -ESPIPE ); +else +return fdtdec_get_int (fdt, + nodeoffset, +"cff-offset" , + -ESPIPE ); + } +return -ESPIPE ; +} +#endif + +int cff_from_sdmmc_env (u32 core) +{ +int rval = -ENOENT ; +fpga_fs_info fpga_fsinfo; + +#ifdef CONFIG_CMD_FPGA_LOADFS +int len =0 ; +const char *cff =NULL ; +#else +char addrToString[32 ] = {0 }; + +int sdmmc_rbf_rawaddr = -ENOENT ; +#endif + + flash_type =spl_boot_device (); + + fpga_fsinfo.interface ="sdmmc" ; + +#ifdef CONFIG_CMD_FPGA_LOADFS + cff =get_cff_filename (gd->fdt_blob, &len, core); + +/* FAT periph RBF file reading */ +if (cff && (len >0 )) { +mmc_initialize (gd->bd); + + fpga_fsinfo.filename = (char *)cff; + + fpga_fsinfo.dev_part =
getenv("cff_devsel_partition");arch/arm/mach-socfpga/cff.c new file +6
-0+ +if (NULL == fpga_fsinfo.dev_part) { +/* FAT partition */ + fpga_fsinfo.dev_part ="1" ; + + printf("No SD/MMC partition found inenvironment. ");
arch/arm/mach-socfpga/cff.c new file +33
-0+ printf("Assuming partition 1.\n"); + } + + rval =cff_from_flash (&fpga_fsinfo); + } +#else + sdmmc_rbf_rawaddr =get_cff_offset (gd->fdt_blob, core); + +/* RAW periph RBF reading */ +if (sdmmc_rbf_rawaddr >=0 ) { +sprintf (addrToString,"%x" , sdmmc_rbf_rawaddr); + + fpga_fsinfo.filename = addrToString; + + rval =cff_from_flash (&fpga_fsinfo); + } +#endif +return rval; +} + +void get_rbf_image_info (struct rbf_info *rbf,u16 *buffer) +{ +/* +Magic ID starting at: +-> 1st dword in periph.rbf +-> 2nd dword in core.rbf +*/ +u32 word_reading_max =2 ; +u32 i; + +for (i =0 ; i < word_reading_max; i++) + { +if (RBF_UNENCRYPTED == *(buffer + i))/* PERIPH RBF */
arch/arm/mach-socfpga/cff.c new file +4
-0+ rbf->security = unencrypted; + else if (RBF_ENCRYPTED == *(buffer + i)) + rbf->security = encrypted; + else if (RBF_UNENCRYPTED == *(buffer + i + 1)) /*CORE RBF */
arch/arm/mach-socfpga/cff.c new file +1
-0+ rbf->security =unencrypted;
arch/arm/mach-socfpga/cff.c new file +35
-0+else if (RBF_ENCRYPTED == *(buffer + i +1 )) + rbf->security = encrypted; +else { + rbf->security = invalid; +continue ; + } + +/* PERIPH RBF */ +if (ARRIA10RBF_PERIPH == *(buffer + i +1 )) { + rbf->section = periph_section; +break ; + } +else if (ARRIA10RBF_CORE == *(buffer + i +1 )) { + rbf->section = core_section; +break ; + }/* CORE RBF */ +else if (ARRIA10RBF_PERIPH == *(buffer + i +2 )) { + rbf->section = periph_section; +break ; + } +else if (ARRIA10RBF_CORE == *(buffer + i +2 )) { + rbf->section = core_section; +break ; + } +else { + rbf->section = unknown; +break ; + } + } + +return ; +} + +static int cff_flash_preinit (struct cff_flash_info *cff_flashinfo, + fpga_fs_info *fpga_fsinfo, u32 *buffer, u32
*buffer_sizebytes)arch/arm/mach-socfpga/cff.c new file +12
-0+{ +u32 *bufferptr_after_header =NULL ; +u32 buffersize_after_header =0 ; +u32 rbf_header_data_size =0 ; +int ret =0 ; +/* To avoid from keeping re-read the contents */ +struct image_header *header = &(cff_flashinfo->header); +size_t buffer_size = *buffer_sizebytes; +u32 *buffer_ptr = (u32 *)*buffer; + +#ifdef CONFIG_CMD_FPGA_LOADFS + cff_flashinfo->sdmmc_flashinfo.filename = fpga_fsinfo-Quoted 1 line
filename;
arch/arm/mach-socfpga/cff.c new file +12
-0+ cff_flashinfo->flash_offset =0 ; +#else + cff_flashinfo->flash_offset = +simple_strtoul (fpga_fsinfo->filename,NULL ,16 ); +#endif + +/* Load mkimage header into buffer */ + ret =flash_read (cff_flashinfo, +sizeof (struct image_header ), buffer_ptr); + +if (0 >= ret) { + printf(" Failed to read mkimage header fromflash.\n");
arch/arm/mach-socfpga/cff.c new file +22
-0+return -ENOENT ; + } + +WATCHDOG_RESET (); + +memcpy (header, (u_char *)buffer_ptr,sizeof (*header)); + +if (!image_check_magic (header)) { +printf ("FPGA: Bad Magic Number.\n" ); +return -EBADF ; + } + +if (!image_check_hcrc (header)) { +printf ("FPGA: Bad Header Checksum.\n" ); +return -EPERM ; + } + +/* Getting rbf data size */ + cff_flashinfo->remaining = +image_get_data_size (header); + +/* Calculate total size of both rbf data with mkimage header */
arch/arm/mach-socfpga/cff.c new file +4
-0+ rbf_header_data_size = cff_flashinfo->remaining + +sizeof (struct image_header ); + +/* Loading to buffer chunk by chunk, normally for OCRAM buffer */
arch/arm/mach-socfpga/cff.c new file +5
-0+if (rbf_header_data_size > buffer_size) { +/* Calculate size of rbf data in the buffer */ + buffersize_after_header = + buffer_size -sizeof (struct image_header ); + cff_flashinfo->remaining -=
buffersize_after_header;arch/arm/mach-socfpga/cff.c new file +2
-0+ }else { +/* Loading whole rbf image into buffer, normally for DDR buffer */
arch/arm/mach-socfpga/cff.c new file +12
-0+ buffer_size = rbf_header_data_size; +/* Calculate size of rbf data in the buffer */ + buffersize_after_header = + buffer_size -sizeof (struct image_header ); + cff_flashinfo->remaining =0 ; + } + +/* Loading mkimage header and rbf data into buffer */ + ret =flash_read (cff_flashinfo, buffer_size, buffer_ptr); + +if (0 >= ret) { + printf(" Failed to read mkimage header and rbfdata ");
arch/arm/mach-socfpga/cff.c new file +5
-0+printf ("from flash.\n" ); +return -ENOENT ; + } + +/* Getting pointer of rbf data starting address where is it
arch/arm/mach-socfpga/cff.c new file +3
-0+right after mkimage header */ + bufferptr_after_header = + (u32 *)((u_char *)buffer_ptr + sizeof(struct
image_header));arch/arm/mach-socfpga/cff.c new file +5
-0+ +/* Update next reading rbf data flash offset */ + cff_flashinfo->flash_offset += buffer_size; + +/* Update the starting addr of rbf data to init FPGA & programming
arch/arm/mach-socfpga/cff.c new file +4
-0+into FPGA */ + *buffer = (u32 )bufferptr_after_header; + + get_rbf_image_info(&cff_flashinfo->rbfinfo, (u16*)bufferptr_after_header);
arch/arm/mach-socfpga/cff.c new file +2
-0+ +/* Update the size of rbf data to be programmed into FPGA */
arch/arm/mach-socfpga/cff.c new file +22
-0+ *buffer_sizebytes = buffersize_after_header; + +#ifdef CONFIG_CHECK_FPGA_DATA_CRC + cff_flashinfo->datacrc = +crc32 (cff_flashinfo->datacrc, + (u_char *)bufferptr_after_header, + buffersize_after_header); +#endif +if (0 == cff_flashinfo->remaining) { +#ifdef CONFIG_CHECK_FPGA_DATA_CRC +if (cff_flashinfo->datacrc != +image_get_dcrc (&(cff_flashinfo->header))) { +printf ("FPGA: Bad Data Checksum.\n" ); +return -EPERM ; + } +#endif +} +return 0 ; +} + + +static int cff_flash_read(struct cff_flash_info *cff_flashinfo,u32 *buffer,
arch/arm/mach-socfpga/cff.c new file +14
-0+ u32 *buffer_sizebytes) +{ +int ret =0 ; +/* To avoid from keeping re-read the contents */ +size_t buffer_size = *buffer_sizebytes; +u32 *buffer_ptr = (u32 *)*buffer; +u32 flash_addr = cff_flashinfo->flash_offset; + +/* Buffer allocated in OCRAM */ +/* Read the data by small chunk by chunk. */ +if (cff_flashinfo->remaining > buffer_size) + cff_flashinfo->remaining -= buffer_size; +else { +/* Buffer allocated in DDR, larger than rbf data most
arch/arm/mach-socfpga/cff.c new file +33
-0+of the time */ + buffer_size = cff_flashinfo->remaining; + cff_flashinfo->remaining =0 ; + } + + ret =flash_read (cff_flashinfo, buffer_size, buffer_ptr); + +if (0 >= ret) { +printf (" Failed to read rbf data from flash.\n" ); +return -ENOENT ; + } + +#ifdef CONFIG_CHECK_FPGA_DATA_CRC + cff_flashinfo->datacrc = +crc32 (cff_flashinfo->datacrc, + (unsigned char *)buffer_ptr, buffer_size); +#endif + +if (0 == cff_flashinfo->remaining) { +#ifdef CONFIG_CHECK_FPGA_DATA_CRC +if (cff_flashinfo->datacrc != +image_get_dcrc (&(cff_flashinfo->header))) { +printf ("FPGA: Bad Data Checksum.\n" ); +return -EPERM ; + } +#endif +} +/* Update next reading rbf data flash offset */ + flash_addr += buffer_size; + + cff_flashinfo->flash_offset = flash_addr; + +/* Update the size of rbf data to be programmed into FPGA */
arch/arm/mach-socfpga/cff.c new file +19
-0+ *buffer_sizebytes = buffer_size; + +return 0 ; +} + +int cff_from_flash (fpga_fs_info *fpga_fsinfo) +{ +u32 buffer =0 ; +u32 buffer_ori =0 ; +u32 buffer_sizebytes =0 ; +u32 buffer_sizebytes_ori =0 ; +struct cff_flash_info cff_flashinfo; +u32 status; +int ret =0 ; + +memset (&cff_flashinfo,0 ,sizeof (cff_flashinfo)); + +if (fpga_fsinfo->filename ==NULL ) { + printf("no [periph/core] rbf [filename/offset]specified.\n");
arch/arm/mach-socfpga/cff.c new file +22
-0+return -EINVAL ; + } + +WATCHDOG_RESET (); + +#ifdef CONFIG_CMD_FPGA_LOADFS + cff_flashinfo.sdmmc_flashinfo.dev_part = +simple_strtol (fpga_fsinfo->dev_part,NULL ,10 ); +#endif + + ret =cff_flash_probe (&cff_flashinfo); + +if (0 >= ret) { +puts ("Flash probe failed.\n" ); +return ret; + } + +#ifdef CONFIG_CMD_FPGA_LOADFS +/* Loading rbf data with DDR, faster than OCRAM, +only for core rbf */ +if (gd->ram_size !=0 ) { + ret = fat_size(fpga_fsinfo->filename, (loff_t*)&buffer_sizebytes);
arch/arm/mach-socfpga/cff.c new file +7
-0+ +if (ret){ +puts ("Failed to read file size.\n" ); +return ret; + } + + buffer_ori = (u32)memalign(ARCH_DMA_MINALIGN,
buffer_sizebytes);arch/arm/mach-socfpga/cff.c new file +22
-0+ +if (!buffer_ori) { +error ("RBF calloc failed!\n" ); +return -ENOMEM ; + } + +/* Loading mkimage header and rbf data into +DDR instead of OCRAM */ + buffer = buffer_ori; + + buffer_sizebytes_ori = buffer_sizebytes; + }else { + buffer = buffer_ori = (u32 )cff_flashinfo.buffer; + + buffer_sizebytes = + buffer_sizebytes_ori = +sizeof (cff_flashinfo.buffer); + } +#else +/* Adjust to adjacent block */ + buffer_sizebytes = buffer_sizebytes_ori = + (sizeof(cff_flashinfo.buffer)/
mmc->read_bl_len) *arch/arm/mach-socfpga/cff.c new file +4
-0+ mmc->read_bl_len; +#endif + +/* Note: Both buffer and buffer_sizebytes values can be altered by
arch/arm/mach-socfpga/cff.c new file +2
-0+function below. */ + ret = cff_flash_preinit(&cff_flashinfo, fpga_fsinfo,&buffer,
arch/arm/mach-socfpga/cff.c new file +8
-0+ &buffer_sizebytes); + +if (ret) +return ret; + +if (periph_section == cff_flashinfo.rbfinfo.section) { +/* initialize the FPGA Manager */ + status = fpgamgr_program_init((u32 *)buffer,
buffer_sizebytes);arch/arm/mach-socfpga/cff.c new file +2
-0+if (status) { + printf("FPGA: Init with periph rbf failedwith error. ");
arch/arm/mach-socfpga/cff.c new file +31
-0+printf ("code %d\n" , status); +return -EPERM ; + } + } + +WATCHDOG_RESET (); + +/* transfer data to FPGA Manager */ +fpgamgr_program_write ((void *)buffer, + buffer_sizebytes); + +WATCHDOG_RESET (); + +while (cff_flashinfo.remaining) { + ret =cff_flash_read (&cff_flashinfo, &buffer_ori, + &buffer_sizebytes_ori); + +if (ret) +return ret; + +/* transfer data to FPGA Manager */ +fpgamgr_program_write ((void *)buffer_ori, + buffer_sizebytes_ori); + +WATCHDOG_RESET (); + } + +if ((periph_section == cff_flashinfo.rbfinfo.section) && +is_early_release_fpga_config (gd->fdt_blob)) { +if (-ETIMEDOUT !=fpgamgr_wait_early_user_mode ()) + printf("FPGA: Early ReleaseSucceeded.\n");
arch/arm/mach-socfpga/cff.c new file +2
-0+else { + printf("FPGA: Failed to see EarlyRelease.\n");
arch/arm/mach-socfpga/cff.c new file +3
-0+return -EIO ; + } + } else if ((core_section == cff_flashinfo.rbfinfo.section)||
arch/arm/mach-socfpga/cff.c new file +11
-0+ ((periph_section == cff_flashinfo.rbfinfo.section) && + !is_early_release_fpga_config(gd->fdt_blob))) { +/* Ensure the FPGA entering config done */ + status =fpgamgr_program_finish (); +if (status) +return status; +else +printf ("FPGA: Enter user mode.\n" ); + + } else { + printf("Config Error: Unsupported FGPA raw binarytype.\n");
arch/arm/mach-socfpga/cff.c new file +6
-0+return -ENOEXEC ; + } + +WATCHDOG_RESET (); +return 1 ; +}arch/arm/mach-socfpga/include/mach/cff.h new file +40
-0@@ -0,0 +1,40 @@ +/* +* Copyright (C) 2017 Intel Corporation <www.intel.com> +* +* SPDX-License-Identifier: GPL-2.0 +*/ + +#ifndef _SOCFPGA_CFF_H_ +#define _SOCFPGA_CFF_H_ + +#include <fpga.h> + +#ifndef __ASSEMBLY_ + +struct flash_info { +char *filename; +int dev_part; +}; + +enum rbf_type {unknown, periph_section, core_section}; +enum rbf_security {invalid, unencrypted, encrypted}; + +struct rbf_info { +enum rbf_type section ; +enum rbf_security security; +}; + +struct cff_flash_info { +struct flash_info sdmmc_flashinfo; +u32 buffer[4096 ]__aligned(ARCH_DMA_MINALIGN) ; +u32 remaining; +u32 flash_offset; +struct rbf_info rbfinfo; +struct image_header header; +}; + +int cff_from_sdmmc_env (unsigned int core); +int cff_from_flash (fpga_fs_info *fpga_fsinfo); +#endif /* __ASSEMBLY__ */ + +#endif /* _SOCFPGA_CFF_H_ */ include/configs/socfpga_arria10_socdk.h +1
-0@@ -58,6 +58,12 @@* Flash configurations */ #define CONFIG_SYS_MAX_FLASH_BANKS 1 +/* Default SDMMC physical address for periph.rbf (sector alignment) */
include/configs/socfpga_arria10_socdk.h +5
-0+#define CONFIG_FS_FAT_MAX_CLUSTSIZE (32 * 1024) + +#if !defined(CONFIG_SPL_BUILD ) && !defined(CONFIG_CMD_FPGA_LOADFS ) +#define CONFIG_CMD_FPGA_LOADFS +#endif /* The rest of the configuration is shared */ #include <configs/socfpga_common.h>
Signature · 2 lines
Best regards, Marek Vasut
Chee
PATCH v2 4/5 arm: socfpga: Add intermediate driver between flash and FPGA manager
Quoted 39 lines · Marek Vasut
Quoted 13 lines · Tien Fong
Quoted 11 lines · Marek Vasut
Quoted 9 lines · tien.fong.chee at intel.com
From: Tien Fong Chee <[email protected]>
Configuration flip-flop driver is mainly used for handling the FPGA
program
operation where the FPGA image loading from the flash into FPGA manager.Quoted 7 lines
Quoted 2 lines
I don't understand what this driver is for , sorry.
this is core driver for handling fpga program operation from flash to
fpga manager. I can improve the message. Let me know if you have other
comment need to add.Yes, it's not clear what this driver is for. It dabbles into multiple subsystems , but I don't understand how is this useful.
Quoted 7 lines
Quoted 6 lines
Coding style issues are present (camel case, wrong comment style, use
checkpatch).Okay, i will run checkpatch.
You should always run checkpatch before submitting patches.
Quoted 6 lines
Quoted 6 lines
If this is for some FPGA loading, can this functionality be scripted
instead?
Quoted 7 lines
Quoted 3 lines
Sorry, i'm not getting you. How functionality be scripted? Could you
provide some example or details explanation?ie. "load" (from fs) + "fpga load" (program FPGA) commands ? I think the fpga command already has some support for loading from FS too.
Currently, we already have fpga load commands in fpga driver, fpga rbf is loaded to memory, and programmed to fpga from memory, where memory location would be decided by user, it could be OCRAM or SDRAM.
for fpga loadfs command, i plan to implement it after having complete boot to U-boot console, since this is quite complex and involving some hardware workaround issue, and some use case scenarios need to be considerd. For example reconfiguring fpga with periperal rbf can corrupt the sdram since sdram IOs is part of the fpga periph rbf. I need console to run a lot different scenarios testing.
We still need cff.c, because most functionality in cff.c are required by fpga loadfs command.
Quoted 767 lines
Quoted 766 lines
Thanks.
Quoted 764 lines
Quoted 764 lines
Signed-off-by Tien Fong Chee <[email protected]>---
arch/arm/mach-socfpga/cff.c | 582
+++++++++++++++++++++++++++++++
arch/arm/mach-socfpga/include/mach/cff.h | 40 +++ include/configs/socfpga_arria10_socdk.h | 6 +3 files changed, 628 insertions(+)create mode 100644
arch/arm/mach-socfpga/cff.ccreate mode 100644arch/arm/mach-socfpga/include/mach/cff.harch/arm/mach- renamed from arch/arm/mach-socfpga/cff.c +0
-0
socfpga/cff.c
new file mode 100644
index 0000000..ccee5e9arch/arm/mach-socfpga/cff.c new file +37
-0@@ -0,0 +1,582 @@ +/* +* COPYRIGHT (C) 2017 Intel Corporation <www.intel.com> +* +* SPDX-License-Identifier: GPL-2.0 +*/ + +#include <altera.h> +#include <common.h> +#include <asm/io.h> +#include <asm/arch/cff.h> +#include <asm/arch/fpga_manager.h> +#include <asm/arch/misc.h> +#include <asm/arch/system_manager.h> +#include <asm/arch/reset_manager.h> +#include <errno.h> +#include <fat.h> +#include <fs.h> +#include <fdtdec.h> +#include <malloc.h> +#include <mmc.h> +#include <spi_flash.h> +#include <spl.h> +#include <watchdog.h> + +#define RBF_UNENCRYPTED 0xa65c +#define RBF_ENCRYPTED 0xa65d +#define ARRIA10RBF_PERIPH 0x0001 +#define ARRIA10RBF_CORE 0x8001 + +DECLARE_GLOBAL_DATA_PTR ; + +static int flash_type =-1 ; + +struct mmc *mmc; + +/* Local functions */ +static int cff_flash_read(struct cff_flash_info
*cff_flashinfo,
u32 *buffer,arch/arm/mach-socfpga/cff.c new file +2
-0+ u32 *buffer_sizebytes); +static int cff_flash_preinit(struct cff_flash_info
*cff_flashinfo,arch/arm/mach-socfpga/cff.c new file +1
-0+ fpga_fs_info *fpga_fsinfo, u32 *buffer, u32
*buffer_sizebytes);arch/arm/mach-socfpga/cff.c new file +2
-0+#ifdef CONFIG_CMD_FPGA_LOADFS +static const char *get_cff_filename(const void *fdt, int *len,u32
core);arch/arm/mach-socfpga/cff.c new file +23
-0+#else +static int get_cff_offset (const void *fdt,u32 core); +#endif + +static struct mmc *init_mmc_device (int dev,bool force_init) +{ +struct mmc *mmc; + + mmc =find_mmc_device (dev); +if (!mmc) { +printf ("no mmc device at slot %x\n" , dev); +return NULL ; + } + +if (force_init) + mmc->has_init =0 ; +if (mmc_init (mmc)) +return NULL ; + +return mmc; +} + +static int cff_flash_probe(struct cff_flash_info
*cff_flashinfo)arch/arm/mach-socfpga/cff.c new file +14
-0+{ +int dev =0 ; + +if (BOOT_DEVICE_MMC1 == flash_type) + { + mmc =init_mmc_device (dev, true); + +if (!mmc) +return -ENOTBLK ; + +#ifdef CONFIG_CMD_FPGA_LOADFS +/* we are looking at the FAT partition */ + if (fat_register_device(mmc_get_blk_desc(mmc), + cff_flashinfo-Quoted 1 line
sdmmc_flashinfo.dev_part))
{
arch/arm/mach-socfpga/cff.c new file +1
-0+ printf("Failed to set filesystem toFAT.\n");
arch/arm/mach-socfpga/cff.c new file +20
-0+return -EPERM ; + } +#endif + } + +return flash_type; +} + +static int flash_read (struct cff_flash_info *cff_flashinfo, +u32 size_read, +u32 *buffer_ptr) +{ +size_t ret =EEXIST ; +#ifdef CONFIG_CMD_FPGA_LOADFS +loff_t actread; +#endif + +if (BOOT_DEVICE_MMC1 == flash_type) { +#ifdef CONFIG_CMD_FPGA_LOADFS + ret = fat_read_file(cff_flashinfo-Quoted 2 lines
sdmmc_flashinfo.filename,
arch/arm/mach-socfpga/cff.c new file +1
-0+ buffer_ptr, cff_flashinfo-Quoted 2 lines
flash_offset,arch/arm/mach-socfpga/cff.c new file +4
-0+ size_read, &actread); + +if (ret || actread != size_read) { + printf("Failed to read %s from FAT %d",
arch/arm/mach-socfpga/cff.c new file +1
-0+ cff_flashinfo-Quoted 2 lines
sdmmc_flashinfo.filename,
arch/arm/mach-socfpga/cff.c new file +7
-0+ ret); +printf ("!= %d.\n" , size_read); + return -EPERM; + }else + ret = actread; +#else + u32 blk = cff_flashinfo->flash_offset/mmc-Quoted 2 lines
read_bl_len;arch/arm/mach-socfpga/cff.c new file +7
-0+u32 cnt = size_read / mmc->read_bl_len; + +if (!cnt) + cnt =1 ; + + if((size_read % mmc->read_bl_len) && + (size_read >= mmc-Quoted 1 line
read_bl_len))arch/arm/mach-socfpga/cff.c new file +3
-0+ cnt++; + + ret = blk_dread(mmc_get_blk_desc(mmc), blk,cnt,
arch/arm/mach-socfpga/cff.c new file +12
-0+ buffer_ptr); + +if (cnt != ret) +return -EPERM ; +#endif + } + +return ret; +} + +#ifdef CONFIG_CMD_FPGA_LOADFS +const char *get_cff_filename(const void *fdt, int *len, u32core)
arch/arm/mach-socfpga/cff.c new file +14
-0+{ +const char *cff_filename =NULL ; +const char *cell; +int nodeoffset; + nodeoffset =fdt_subnode_offset (fdt,0 ,"chosen" ); + +if (nodeoffset >=0 ) { +if (core) + cell =fdt_getprop (fdt, + nodeoffset, +"cffcore-file" , + len); +else + cell = fdt_getprop(fdt, nodeoffset,"cff-
file", len);arch/arm/mach-socfpga/cff.c new file +58
-0+ +if (cell) + cff_filename = cell; + } + +return cff_filename; +} +#else +static int get_cff_offset (const void *fdt,u32 core) +{ +int nodeoffset =0 ; + + nodeoffset =fdt_subnode_offset (fdt,0 ,"chosen" ); + +if (nodeoffset >=0 ) { +if (core) +return fdtdec_get_int (fdt, + nodeoffset, +"cffcore-offset" , + -ESPIPE ); +else +return fdtdec_get_int (fdt, + nodeoffset, +"cff-offset" , + -ESPIPE ); + } +return -ESPIPE ; +} +#endif + +int cff_from_sdmmc_env (u32 core) +{ +int rval = -ENOENT ; +fpga_fs_info fpga_fsinfo; + +#ifdef CONFIG_CMD_FPGA_LOADFS +int len =0 ; +const char *cff =NULL ; +#else +char addrToString[32 ] = {0 }; + +int sdmmc_rbf_rawaddr = -ENOENT ; +#endif + + flash_type =spl_boot_device (); + + fpga_fsinfo.interface ="sdmmc" ; + +#ifdef CONFIG_CMD_FPGA_LOADFS + cff =get_cff_filename (gd->fdt_blob, &len, core); + +/* FAT periph RBF file reading */ +if (cff && (len >0 )) { +mmc_initialize (gd->bd); + + fpga_fsinfo.filename = (char *)cff; + + fpga_fsinfo.dev_part =
getenv("cff_devsel_partition");arch/arm/mach-socfpga/cff.c new file +6
-0+ +if (NULL == fpga_fsinfo.dev_part) { +/* FAT partition */ + fpga_fsinfo.dev_part ="1" ; + + printf("No SD/MMC partition found inenvironment. ");
arch/arm/mach-socfpga/cff.c new file +7
-0+ printf("Assuming partition 1.\n"); + } + + rval =cff_from_flash (&fpga_fsinfo); + } +#else + sdmmc_rbf_rawaddr = get_cff_offset(gd->fdt_blob,core);
arch/arm/mach-socfpga/cff.c new file +4
-0+ + /* RAW periph RBF reading */ +if (sdmmc_rbf_rawaddr >=0 ) { + sprintf(addrToString, "%x",
sdmmc_rbf_rawaddr);arch/arm/mach-socfpga/cff.c new file +22
-0+ + fpga_fsinfo.filename = addrToString; + + rval = cff_from_flash(&fpga_fsinfo); + } +#endif +return rval; +} + +void get_rbf_image_info (struct rbf_info *rbf,u16 *buffer) +{ +/* +Magic ID starting at: +-> 1st dword in periph.rbf +-> 2nd dword in core.rbf +*/ +u32 word_reading_max =2 ; +u32 i; + +for (i =0 ; i < word_reading_max; i++) + { +if (RBF_UNENCRYPTED == *(buffer + i))/* PERIPH RBF
*/arch/arm/mach-socfpga/cff.c new file +4
-0+ rbf->security = unencrypted; + else if (RBF_ENCRYPTED == *(buffer + i)) + rbf->security = encrypted; + else if (RBF_UNENCRYPTED == *(buffer + i + 1))/*
CORE RBF */arch/arm/mach-socfpga/cff.c new file +1
-0+ rbf->security =unencrypted;
arch/arm/mach-socfpga/cff.c new file +2
-0+else if (RBF_ENCRYPTED == *(buffer + i +1 )) + rbf->security =encrypted;
arch/arm/mach-socfpga/cff.c new file +11
-0+else { + rbf->security = invalid; +continue ; + } + +/* PERIPH RBF */ +if (ARRIA10RBF_PERIPH == *(buffer + i +1 )) { + rbf->section = periph_section; +break ; + } +else if (ARRIA10RBF_CORE == *(buffer + i +1 )){
arch/arm/mach-socfpga/cff.c new file +4
-0+ rbf->section = core_section; +break ; + }/* CORE RBF */ + else if (ARRIA10RBF_PERIPH == *(buffer + i +2)) {
arch/arm/mach-socfpga/cff.c new file +4
-0+ rbf->section = periph_section; +break ; + } +else if (ARRIA10RBF_CORE == *(buffer + i +2 )){
arch/arm/mach-socfpga/cff.c new file +13
-0+ rbf->section = core_section; +break ; + } +else { + rbf->section = unknown; +break ; + } + } + +return ; +} + +static int cff_flash_preinit(struct cff_flash_info
*cff_flashinfo,arch/arm/mach-socfpga/cff.c new file +1
-0+ fpga_fs_info *fpga_fsinfo, u32 *buffer, u32
*buffer_sizebytes)arch/arm/mach-socfpga/cff.c new file +7
-0+{ +u32 *bufferptr_after_header =NULL ; +u32 buffersize_after_header =0 ; +u32 rbf_header_data_size =0 ; +int ret =0 ; +/* To avoid from keeping re-read the contents */ + struct image_header *header = &(cff_flashinfo-Quoted 1 line
header);
arch/arm/mach-socfpga/cff.c new file +5
-0+size_t buffer_size = *buffer_sizebytes; +u32 *buffer_ptr = (u32 *)*buffer; + +#ifdef CONFIG_CMD_FPGA_LOADFS + cff_flashinfo->sdmmc_flashinfo.filename = fpga_fsinfo-Quoted 2 lines
filename;
arch/arm/mach-socfpga/cff.c new file +4
-0+ cff_flashinfo->flash_offset =0 ; +#else + cff_flashinfo->flash_offset = + simple_strtoul(fpga_fsinfo->filename, NULL,16);
arch/arm/mach-socfpga/cff.c new file +5
-0+#endif + + /* Load mkimage header into buffer */ + ret = flash_read(cff_flashinfo, + sizeof(struct image_header),
buffer_ptr);arch/arm/mach-socfpga/cff.c new file +3
-0+ +if (0 >= ret) { + printf(" Failed to read mkimage header fromflash.\n");
arch/arm/mach-socfpga/cff.c new file +22
-0+return -ENOENT ; + } + +WATCHDOG_RESET (); + +memcpy (header, (u_char *)buffer_ptr,sizeof (*header)); + +if (!image_check_magic (header)) { +printf ("FPGA: Bad Magic Number.\n" ); +return -EBADF ; + } + +if (!image_check_hcrc (header)) { +printf ("FPGA: Bad Header Checksum.\n" ); +return -EPERM ; + } + +/* Getting rbf data size */ + cff_flashinfo->remaining = +image_get_data_size (header); + +/* Calculate total size of both rbf data with mkimage header */
arch/arm/mach-socfpga/cff.c new file +4
-0+ rbf_header_data_size = cff_flashinfo->remaining + +sizeof (struct image_header ); + +/* Loading to buffer chunk by chunk, normally for OCRAM
buffer */arch/arm/mach-socfpga/cff.c new file +4
-0+if (rbf_header_data_size > buffer_size) { +/* Calculate size of rbf data in the buffer */ + buffersize_after_header = + buffer_size - sizeof(struct
image_header);arch/arm/mach-socfpga/cff.c new file +1
-0+ cff_flashinfo->remaining -=
buffersize_after_header;arch/arm/mach-socfpga/cff.c new file +2
-0+ }else { +/* Loading whole rbf image into buffer, normally for DDR
buffer */arch/arm/mach-socfpga/cff.c new file +4
-0+ buffer_size = rbf_header_data_size; +/* Calculate size of rbf data in the buffer */ + buffersize_after_header = + buffer_size - sizeof(struct
image_header);arch/arm/mach-socfpga/cff.c new file +5
-0+ cff_flashinfo->remaining =0 ; + } + +/* Loading mkimage header and rbf data into buffer */ + ret = flash_read(cff_flashinfo, buffer_size,
buffer_ptr);arch/arm/mach-socfpga/cff.c new file +3
-0+ +if (0 >= ret) { + printf(" Failed to read mkimage header and rbfdata ");
arch/arm/mach-socfpga/cff.c new file +5
-0+printf ("from flash.\n" ); +return -ENOENT ; + } + +/* Getting pointer of rbf data starting address where is
itarch/arm/mach-socfpga/cff.c new file +3
-0+right after mkimage header */ + bufferptr_after_header = + (u32 *)((u_char *)buffer_ptr + sizeof(struct
image_header));arch/arm/mach-socfpga/cff.c new file +5
-0+ +/* Update next reading rbf data flash offset */ + cff_flashinfo->flash_offset += buffer_size; + +/* Update the starting addr of rbf data to init FPGA & programming
arch/arm/mach-socfpga/cff.c new file +4
-0+into FPGA */ + *buffer = (u32 )bufferptr_after_header; + + get_rbf_image_info(&cff_flashinfo->rbfinfo, (u16*)bufferptr_after_header);
arch/arm/mach-socfpga/cff.c new file +2
-0+ +/* Update the size of rbf data to be programmed into FPGA
*/arch/arm/mach-socfpga/cff.c new file +22
-0+ *buffer_sizebytes = buffersize_after_header; + +#ifdef CONFIG_CHECK_FPGA_DATA_CRC + cff_flashinfo->datacrc = +crc32 (cff_flashinfo->datacrc, + (u_char *)bufferptr_after_header, + buffersize_after_header); +#endif +if (0 == cff_flashinfo->remaining) { +#ifdef CONFIG_CHECK_FPGA_DATA_CRC +if (cff_flashinfo->datacrc != +image_get_dcrc (&(cff_flashinfo->header))) { +printf ("FPGA: Bad Data Checksum.\n" ); +return -EPERM ; + } +#endif +} +return 0 ; +} + + +static int cff_flash_read(struct cff_flash_info
*cff_flashinfo,
u32 *buffer,arch/arm/mach-socfpga/cff.c new file +14
-0+ u32 *buffer_sizebytes) +{ +int ret =0 ; +/* To avoid from keeping re-read the contents */ +size_t buffer_size = *buffer_sizebytes; +u32 *buffer_ptr = (u32 *)*buffer; +u32 flash_addr = cff_flashinfo->flash_offset; + +/* Buffer allocated in OCRAM */ +/* Read the data by small chunk by chunk. */ +if (cff_flashinfo->remaining > buffer_size) + cff_flashinfo->remaining -= buffer_size; +else { +/* Buffer allocated in DDR, larger than rbf data
mostarch/arm/mach-socfpga/cff.c new file +6
-0+of the time */ + buffer_size = cff_flashinfo->remaining; + cff_flashinfo->remaining =0 ; + } + + ret = flash_read(cff_flashinfo, buffer_size,
buffer_ptr);arch/arm/mach-socfpga/cff.c new file +3
-0+ +if (0 >= ret) { + printf(" Failed to read rbf data fromflash.\n");
arch/arm/mach-socfpga/cff.c new file +7
-0+return -ENOENT ; + } + +#ifdef CONFIG_CHECK_FPGA_DATA_CRC + cff_flashinfo->datacrc = + crc32(cff_flashinfo->datacrc, + (unsigned char *)buffer_ptr,
buffer_size);arch/arm/mach-socfpga/cff.c new file +17
-0+#endif + +if (0 == cff_flashinfo->remaining) { +#ifdef CONFIG_CHECK_FPGA_DATA_CRC +if (cff_flashinfo->datacrc != +image_get_dcrc (&(cff_flashinfo->header))) { +printf ("FPGA: Bad Data Checksum.\n" ); +return -EPERM ; + } +#endif +} +/* Update next reading rbf data flash offset */ + flash_addr += buffer_size; + + cff_flashinfo->flash_offset = flash_addr; + +/* Update the size of rbf data to be programmed into FPGA
*/arch/arm/mach-socfpga/cff.c new file +19
-0+ *buffer_sizebytes = buffer_size; + +return 0 ; +} + +int cff_from_flash (fpga_fs_info *fpga_fsinfo) +{ +u32 buffer =0 ; +u32 buffer_ori =0 ; +u32 buffer_sizebytes =0 ; +u32 buffer_sizebytes_ori =0 ; +struct cff_flash_info cff_flashinfo; +u32 status; +int ret =0 ; + +memset (&cff_flashinfo,0 ,sizeof (cff_flashinfo)); + +if (fpga_fsinfo->filename ==NULL ) { + printf("no [periph/core] rbf [filename/offset]specified.\n");
arch/arm/mach-socfpga/cff.c new file +8
-0+return -EINVAL ; + } + +WATCHDOG_RESET (); + +#ifdef CONFIG_CMD_FPGA_LOADFS + cff_flashinfo.sdmmc_flashinfo.dev_part = + simple_strtol(fpga_fsinfo->dev_part, NULL,10);
arch/arm/mach-socfpga/cff.c new file +14
-0+#endif + + ret =cff_flash_probe (&cff_flashinfo); + +if (0 >= ret) { +puts ("Flash probe failed.\n" ); +return ret; + } + +#ifdef CONFIG_CMD_FPGA_LOADFS +/* Loading rbf data with DDR, faster than OCRAM, +only for core rbf */ +if (gd->ram_size !=0 ) { + ret = fat_size(fpga_fsinfo->filename, (loff_t*)&buffer_sizebytes);
arch/arm/mach-socfpga/cff.c new file +7
-0+ +if (ret){ +puts ("Failed to read file size.\n" ); +return ret; + } + + buffer_ori = (u32)memalign(ARCH_DMA_MINALIGN,
buffer_sizebytes);arch/arm/mach-socfpga/cff.c new file +13
-0+ +if (!buffer_ori) { +error ("RBF calloc failed!\n" ); +return -ENOMEM ; + } + +/* Loading mkimage header and rbf data into +DDR instead of OCRAM */ + buffer = buffer_ori; + + buffer_sizebytes_ori = buffer_sizebytes; + }else { + buffer = buffer_ori =(u32)cff_flashinfo.buffer;
arch/arm/mach-socfpga/cff.c new file +9
-0+ + buffer_sizebytes = + buffer_sizebytes_ori = +sizeof (cff_flashinfo.buffer); + } +#else +/* Adjust to adjacent block */ + buffer_sizebytes = buffer_sizebytes_ori = + (sizeof(cff_flashinfo.buffer)/
mmc->read_bl_len) *arch/arm/mach-socfpga/cff.c new file +4
-0+ mmc->read_bl_len; +#endif + +/* Note: Both buffer and buffer_sizebytes values can be
altered byarch/arm/mach-socfpga/cff.c new file +2
-0+function below. */ + ret = cff_flash_preinit(&cff_flashinfo, fpga_fsinfo,&buffer,
arch/arm/mach-socfpga/cff.c new file +8
-0+ &buffer_sizebytes); + +if (ret) +return ret; + +if (periph_section == cff_flashinfo.rbfinfo.section) { +/* initialize the FPGA Manager */ + status = fpgamgr_program_init((u32 *)buffer,
buffer_sizebytes);arch/arm/mach-socfpga/cff.c new file +2
-0+if (status) { + printf("FPGA: Init with periph rbffailed
with error. ");arch/arm/mach-socfpga/cff.c new file +15
-0+printf ("code %d\n" , status); +return -EPERM ; + } + } + +WATCHDOG_RESET (); + +/* transfer data to FPGA Manager */ +fpgamgr_program_write ((void *)buffer, + buffer_sizebytes); + +WATCHDOG_RESET (); + +while (cff_flashinfo.remaining) { + ret = cff_flash_read(&cff_flashinfo,
&buffer_ori,arch/arm/mach-socfpga/cff.c new file +13
-0+ &buffer_sizebytes_ori); + +if (ret) +return ret; + +/* transfer data to FPGA Manager */ +fpgamgr_program_write ((void *)buffer_ori, + buffer_sizebytes_ori); + +WATCHDOG_RESET (); + } + + if ((periph_section == cff_flashinfo.rbfinfo.section)&&
arch/arm/mach-socfpga/cff.c new file +2
-0+ is_early_release_fpga_config(gd->fdt_blob)) { + if (-ETIMEDOUT !=
fpgamgr_wait_early_user_mode())arch/arm/mach-socfpga/cff.c new file +1
-0+ printf("FPGA: Early ReleaseSucceeded.\n");
arch/arm/mach-socfpga/cff.c new file +2
-0+else { + printf("FPGA: Failed to see EarlyRelease.\n");
arch/arm/mach-socfpga/cff.c new file +3
-0+return -EIO ; + } + } else if ((core_section ==cff_flashinfo.rbfinfo.section)
Quoted 3 lines
Quoted 3 lines
arch/arm/mach-socfpga/cff.c new file +11
-0+ ((periph_section == cff_flashinfo.rbfinfo.section) && + !is_early_release_fpga_config(gd->fdt_blob))) { +/* Ensure the FPGA entering config done */ + status =fpgamgr_program_finish (); +if (status) +return status; +else +printf ("FPGA: Enter user mode.\n" ); + + } else { + printf("Config Error: Unsupported FGPA rawbinary
type.\n");arch/arm/mach-socfpga/cff.c new file +6
-0+return -ENOEXEC ; + } + +WATCHDOG_RESET (); +return 1 ; +}arch/arm/mach-socfpga/include/mach/cff.h new file +40
-0@@ -0,0 +1,40 @@ +/* +* Copyright (C) 2017 Intel Corporation <www.intel.com> +* +* SPDX-License-Identifier: GPL-2.0 +*/ + +#ifndef _SOCFPGA_CFF_H_ +#define _SOCFPGA_CFF_H_ + +#include <fpga.h> + +#ifndef __ASSEMBLY_ + +struct flash_info { +char *filename; +int dev_part; +}; + +enum rbf_type {unknown, periph_section, core_section}; +enum rbf_security {invalid, unencrypted, encrypted}; + +struct rbf_info { +enum rbf_type section ; +enum rbf_security security; +}; + +struct cff_flash_info { +struct flash_info sdmmc_flashinfo; +u32 buffer[4096 ]__aligned(ARCH_DMA_MINALIGN) ; +u32 remaining; +u32 flash_offset; +struct rbf_info rbfinfo; +struct image_header header; +}; + +int cff_from_sdmmc_env (unsigned int core); +int cff_from_flash (fpga_fs_info *fpga_fsinfo); +#endif /* __ASSEMBLY__ */ + +#endif /* _SOCFPGA_CFF_H_ */ include/configs/socfpga_arria10_socdk.h +1
-0@@ -58,6 +58,12 @@* Flash configurations */ #define CONFIG_SYS_MAX_FLASH_BANKS 1 +/* Default SDMMC physical address for periph.rbf (sector alignment) */
include/configs/socfpga_arria10_socdk.h +3
-0+#define CONFIG_FS_FAT_MAX_CLUSTSIZE (32 * 1024) + +#if !defined(CONFIG_SPL_BUILD) &&!defined(CONFIG_CMD_FPGA_LOADFS)
include/configs/socfpga_arria10_socdk.h +2
-0+#define CONFIG_CMD_FPGA_LOADFS +#endif
/* The rest of the configuration is shared */
#include <configs/socfpga_common.h>
PATCH v2 4/5 arm: socfpga: Add intermediate driver between flash and FPGA manager
On 08/09/2017 06:50 AM, Chee, Tien Fong wrote:
[...]
Quoted 11 lines
Quoted 11 lines
Quoted 7 lines
Quoted 4 lines
If this is for some FPGA loading, can this functionality be scripted
instead?Sorry, i'm not getting you. How functionality be scripted? Could you
provide some example or details explanation?ie. "load" (from fs) + "fpga load" (program FPGA) commands ? I think the fpga command already has some support for loading from FS too.
Quoted 8 lines
Currently, we already have fpga load commands in fpga driver, fpga rbf is loaded to memory, and programmed to fpga from memory, where memory location would be decided by user, it could be OCRAM or SDRAM.
for fpga loadfs command, i plan to implement it after having complete boot to U-boot console, since this is quite complex and involving some hardware workaround issue, and some use case scenarios need to be considerd.
So the arria10 u-boot port is still unable to boot to console ?
Quoted 3 lines
For example reconfiguring fpga with periperal rbf can corrupt the sdram since sdram IOs is part of the fpga periph rbf. I need console to run a lot different scenarios testing.
OK
Quoted 2 lines
We still need
cff.c, because most functionality incff.care required by fpga loadfs command.
It seems a lot of stuff from this is common code, so why does it have to be in this driver again ? Also, the ifdeffery is awful and the explicit depedence on VFAT when loading from FS is real bad.
[...]
Signature · 2 lines
Best regards, Marek Vasut
Chee
PATCH v2 4/5 arm: socfpga: Add intermediate driver between flash and FPGA manager
Quoted 26 lines · Marek Vasut
On 08/09/2017 06:50 AM, Chee, Tien Fong wrote:
[...]Quoted 23 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
If this is for some FPGA loading, can this functionality be scripted
instead?Quoted 9 lines
Quoted 4 lines
Sorry, i'm not getting you. How functionality be scripted? Could
you
provide some example or details explanation?ie. "load" (from fs) + "fpga load" (program FPGA) commands ? I think the fpga command already has some support for loading from FS
too.Currently, we already have fpga load commands in fpga driver, fpga rbf
is loaded to memory, and programmed to fpga from memory, where memory
location would be decided by user, it could be OCRAM or SDRAM.
Quoted 8 lines
Quoted 6 lines
for fpga loadfs command, i plan to implement it after having complete
boot to U-boot console, since this is quite complex and involving some
hardware workaround issue, and some use case scenarios need to be considerd.So the arria10 u-boot port is still unable to boot to console ?
Still need 2 to 3 more patchsets to get it boot to console.
Quoted 7 lines
Quoted 4 lines
For example reconfiguring fpga with periperal rbf can corrupt the sdram since sdram IOs is part of the fpga periph rbf. I need console to run a lot different scenarios testing.
OK
Quoted 1 line
Quoted 6 lines
Quoted 3 lines
We still need
cff.c, because most functionality incff.care required
by fpga loadfs command.It seems a lot of stuff from this is common code, so why does it have to
be in this driver again ?
This driver contains a lot "smart" functionality such as:
1: It having ability to the right memory(OCRAM or SDRAM) to achieve the best FPGA programing performance.
2: It can determine the right size buffer for the fpga rbf without info of buffer size defined by user.
3: It has ability to know what kind of fpga rbf type, and security type, such as peripheral, core, combined rbf, encryption and unencryption based on any fpga file user pass in .
4: It supports the checksum.
5: support raw flash without fs.
6: support the file name defined in DTS and U-boot environment variable.
Quoted 3 lines
Also, the ifdeffery is awful and the explicit
depedence on VFAT when loading from FS is real bad.
It is because a lot functions is common to sdmmc, nand and qspi in different fs such as vfat, ubi and raw. It is unavoidable to have some ifdeffery if we want to keep the function common to all flashes and fs.
Quoted 1 line
[...]
PATCH v2 4/5 arm: socfpga: Add intermediate driver between flash and FPGA manager
Quoted 43 lines · Tien Fong
Quoted 26 lines · Marek Vasut
On 08/09/2017 06:50 AM, Chee, Tien Fong wrote:
[...]Quoted 23 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
If this is for some FPGA loading, can this functionality be scripted
instead?Quoted 9 lines
Quoted 4 lines
Sorry, i'm not getting you. How functionality be scripted? Could
you
provide some example or details explanation?ie. "load" (from fs) + "fpga load" (program FPGA) commands ? I think the fpga command already has some support for loading from FS
too.Currently, we already have fpga load commands in fpga driver, fpga rbf
is loaded to memory, and programmed to fpga from memory, where memory
location would be decided by user, it could be OCRAM or SDRAM.Quoted 8 lines
Quoted 6 lines
for fpga loadfs command, i plan to implement it after having complete
boot to U-boot console, since this is quite complex and involving some
hardware workaround issue, and some use case scenarios need to be considerd.So the arria10 u-boot port is still unable to boot to console ?
Still need 2 to 3 more patchsets to get it boot to console.
Quoted 7 lines
Quoted 4 lines
For example reconfiguring fpga with periperal rbf can corrupt the sdram since sdram IOs is part of the fpga periph rbf. I need console to run a lot different scenarios testing.
OK
Quoted 1 line
Quoted 7 lines
Quoted 6 lines
Quoted 3 lines
We still need
cff.c, because most functionality incff.care required
by fpga loadfs command.It seems a lot of stuff from this is common code, so why does it have to
be in this driver again ?This driver contains a lot "smart" functionality such as:
I start to cringe when I read "smart functionality".
Quoted 2 lines
1: It having ability to the right memory(OCRAM or SDRAM) to achieve the best FPGA programing performance.
Did you find significant throughput difference ?
Quoted 2 lines
2: It can determine the right size buffer for the fpga rbf without info of buffer size defined by user.
You mean like $filesize variable in the command prompt ?
Quoted 3 lines
3: It has ability to know what kind of fpga rbf type, and security type, such as peripheral, core, combined rbf, encryption and unencryption based on any fpga file user pass in .
Is this information used for anything ? I was under the impression that the user just needs to load in the correct RBF file into the FPGA.
Quoted 1 line
4: It supports the checksum.
What checksum ? Can we have a generic hook into the FPGA framework ?
Quoted 1 line
5: support raw flash without fs.
This should go into common code.
Quoted 2 lines
6: support the file name defined in DTS and U-boot environment variable.
I think you should extend the FPGA LOADFS here instead.
Quoted 7 lines
Quoted 3 lines
Also, the ifdeffery is awful and the explicit
depedence on VFAT when loading from FS is real bad.It is because a lot functions is common to sdmmc, nand and qspi in different fs such as vfat, ubi and raw. It is unavoidable to have some ifdeffery if we want to keep the function common to all flashes and fs.
Can the FPGA LOADFS be extended generically ?
Quoted 1 line
Quoted 1 line
[...]
Signature · 2 lines
Best regards, Marek Vasut
Chee
PATCH v2 4/5 arm: socfpga: Add intermediate driver between flash and FPGA manager
Quoted 65 lines · Marek Vasut
Quoted 64 lines · Tien Fong
Quoted 41 lines · Marek Vasut
On 08/09/2017 06:50 AM, Chee, Tien Fong wrote:
[...]Quoted 29 lines
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
If this is for some FPGA loading, can this functionality be
scripted
instead?Quoted 9 lines
Quoted 4 lines
Sorry, i'm not getting you. How functionality be scripted? Could
you
provide some example or details explanation?ie. "load" (from fs) + "fpga load" (program FPGA) commands ? I think the fpga command already has some support for loading from FS
too.Currently, we already have fpga load commands in fpga driver, fpga
rbf
is loaded to memory, and programmed to fpga from memory, where memory
location would be decided by user, it could be OCRAM or SDRAM.Quoted 8 lines
for fpga loadfs command, i plan to implement it after having complete
boot to U-boot console, since this is quite complex and involving
some
hardware workaround issue, and some use case scenarios need to be
considerd.Quoted 2 lines
So the arria10 u-boot port is still unable to boot to console ?
Still need 2 to 3 more patchsets to get it boot to console.
Quoted 18 lines
Quoted 7 lines
For example reconfiguring fpga with periperal rbf can corrupt the sdram since sdram IOs is part of the fpga periph rbf. I
need console to run a lot different scenarios testing.OK
Quoted 5 lines
We still need
cff.c, because most functionality incff.care required
by fpga loadfs command.It seems a lot of stuff from this is common code, so why does it have
to
be in this driver again ?
Quoted 9 lines
Quoted 1 line
This driver contains a lot "smart" functionality such as:
I start to cringe when I read "smart functionality".
Quoted 4 lines
1: It having ability to the right memory(OCRAM or SDRAM) to achieve the
best FPGA programing performance.Did you find significant throughput difference ?
80% performance improvement with SDRAM.
Quoted 6 lines
Quoted 4 lines
2: It can determine the right size buffer for the fpga rbf without info
of buffer size defined by user.You mean like $filesize variable in the command prompt ?
Yeah. No filesize is required.
Quoted 8 lines
Quoted 4 lines
3: It has ability to know what kind of fpga rbf type, and security type, such as peripheral, core, combined rbf, encryption and unencryption based on any fpga file user pass in .
Is this information used for anything ? I was under the impression that
the user just needs to load in the correct RBF file into the FPGA.
Yeah, the driver would decode the RBF image to know what type of RBF user loading, and applying correct method(buffer allocation, which memory to use and configuration on FPGA manager) to program FPGA.
Quoted 4 lines
Quoted 2 lines
4: It supports the checksum.
What checksum ? Can we have a generic hook into the FPGA framework ?
This checksum is to ensure integrity of RBF file after loading from flash into SDRAM. This can help to prevent possibility system instability caused by programming corrupt rbf into FPGA. So, this should be implemented in cff.c .
Quoted 4 lines
Quoted 2 lines
5: support raw flash without fs.
This should go into common code.
raw flash is part of common codes in cff.c because it is part of mechanism like fs to determine how loading rbf from flash and program into fpga.
Quoted 5 lines
Quoted 3 lines
6: support the file name defined in DTS and U-boot environment variable.
I think you should extend the FPGA LOADFS here instead.
The peripheral rbf filename and DTS are generated from our bsp tool. But user can run fpga loadfs to reconfigure FPGA in U-boot console after i have supported it.
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Also, the ifdeffery is awful and the explicit depedence on VFAT when loading from FS is real bad.
Quoted 7 lines
Quoted 5 lines
It is because a lot functions is common to sdmmc, nand and qspi in different fs such as vfat, ubi and raw. It is unavoidable to have some
ifdeffery if we want to keep the function common to all flashes and fs.Can the FPGA LOADFS be extended generically ?
Yeah, FPGA loadfs is considered when design cff.c. But, i plan to to support FPGA loadfs after having complete boot to U-boot console.
Quoted 4 lines
Quoted 3 lines
Quoted 3 lines
[...]
PATCH v2 4/5 arm: socfpga: Add intermediate driver between flash and FPGA manager
On 08/12/2017 10:03 AM, Chee, Tien Fong wrote:
[...]
Quoted 6 lines
Quoted 5 lines
Quoted 3 lines
1: It having ability to the right memory(OCRAM or SDRAM) to achieve the
best FPGA programing performance.Did you find significant throughput difference ?
80% performance improvement with SDRAM.
This looks more like caches are not enabled ... sort of problem ?
Quoted 6 lines
Quoted 5 lines
Quoted 3 lines
2: It can determine the right size buffer for the fpga rbf without info
of buffer size defined by user.You mean like $filesize variable in the command prompt ?
Yeah. No filesize is required.
You can use $filesize instead of reimplementing this functionality yourself though ?
Quoted 10 lines
Quoted 7 lines
Quoted 3 lines
3: It has ability to know what kind of fpga rbf type, and security type, such as peripheral, core, combined rbf, encryption and unencryption based on any fpga file user pass in .
Is this information used for anything ? I was under the impression that
the user just needs to load in the correct RBF file into the FPGA.Yeah, the driver would decode the RBF image to know what type of RBF user loading, and applying correct
method(buffer allocation, which memory to use and configuration on FPGA manager)to program FPGA.
If the code needs to extract some information from the RBF to correctly configure something in the FPGA manager, then that's where this should go then.
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
4: It supports the checksum.
What checksum ? Can we have a generic hook into the FPGA framework ?
This checksum is to ensure integrity of RBF file after loading from flash into SDRAM. This can help to prevent possibility system instability caused by programming corrupt rbf into FPGA. So, this should be implemented in
cff.c.
Or the FPGA manager driver .
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
5: support raw flash without fs.
This should go into common code.
raw flash is part of common codes in
cff.cbecause it is part of mechanism like fs to determine how loading rbf from flash and program into fpga.
By common code I mean the stuff around FPGA LOADFS , so other FPGAs can also benefit from that.
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
6: support the file name defined in DTS and U-boot environment variable.
I think you should extend the FPGA LOADFS here instead.
The peripheral rbf filename and DTS are generated from our bsp tool. But user can run fpga loadfs to reconfigure FPGA in U-boot console after i have supported it.
And why don't you rather apply some FPGA LOADFS if this property is detected in the DT instead of reimplementing it ?
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 5 lines
Also, the ifdeffery is awful and the explicit
depedence on VFAT when loading from FS is real bad.It is because a lot functions is common to sdmmc, nand and qspi in different fs such as vfat, ubi and raw. It is unavoidable to have some
ifdeffery if we want to keep the function common to all flashes and fs.
Quoted 4 lines
Quoted 2 lines
Can the FPGA LOADFS be extended generically ?
Yeah, FPGA loadfs is considered when design
cff.c. But, i plan to to support FPGA loadfs after having complete boot to U-boot console.
Does that mean the Arria10 is still not even capable of booting into U-Boot console ?
cff.c is unlikely to hit mainline unless there's compelling argument that it is needed . Thus far, I see most of the functionality should be added elsewhere or is already there (fpga loadfs).
Signature · 2 lines
Best regards, Marek Vasut
Chee
PATCH v2 4/5 arm: socfpga: Add intermediate driver between flash and FPGA manager
Quoted 5 lines · Marek Vasut
On 08/12/2017 10:03 AM, Chee, Tien Fong wrote:
[...]Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 9 lines
Quoted 7 lines
Quoted 6 lines
Quoted 4 lines
1: It having ability to the right memory(OCRAM or SDRAM) to achieve
the
best FPGA programing performance.Did you find significant throughput difference ?
80% performance improvement with SDRAM.
This looks more like caches are not enabled ... sort of problem ?
It is because SDRAM size large enough to store whole rbf file and reduce significantly of the repetitive block transfer. It requires one time block transfer from SDRAM to FPGA compare to OCRAM which require more than that.
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
2: It can determine the right size buffer for the fpga rbf without
info
of buffer size defined by user.
Quoted 6 lines
Quoted 3 lines
Quoted 2 lines
You mean like $filesize variable in the command prompt ?
Yeah. No filesize is required.
You can use $filesize instead of reimplementing this functionality yourself though ?
I'am sorry to have confused you. What i trying to say is user no longer require to specify the file size and location when calling fpga loadfs. So, this would keep the thing simple. The driver in cff.c would handle all these troublesome things and deciding the best route for good performance.
Quoted 17 lines
Quoted 13 lines
Quoted 7 lines
Quoted 7 lines
3: It has ability to know what kind of fpga rbf type, and security
type, such as peripheral, core, combined rbf, encryption and unencryption based on any fpga file user pass in .Quoted 6 lines
Is this information used for anything ? I was under the impression
that
the user just needs to load in the correct RBF file into the FPGA.Quoted 4 lines
Yeah, the driver would decode the RBF image to know what type of RBF
user loading, and applying correctmethod(buffer allocation, which memory to use and configuration on FPGA manager)to program FPGA.
Quoted 6 lines
If the code needs to extract some information from the RBF to correctly
configure something in the FPGA manager, then that's where this should
go then.
Those functions for extracting info from RBF and configuring the FPGA are actually come from fpga driver which i have submited as in previous patchset. The actualy implementation is in cff.c, as i try to explain cff.c drivers are mainly to handle all activities of loading rbf from flashes to program FPGA.
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
4: It supports the checksum.
Quoted 9 lines
Quoted 7 lines
Quoted 3 lines
What checksum ? Can we have a generic hook into the FPGA framework ?
This checksum is to ensure integrity of RBF file after loading from flash into SDRAM. This can help to prevent possibility system instability caused by programming corrupt rbf into FPGA. So, this should be implemented in
cff.c.Or the FPGA manager driver .
This integrity checking is implemented during RBF loading from flash to SDRAM before calling the functions from fpga driver to program FPGA. So cff.c which is designed for handling these operation and it should be appropriate place for checksum.
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 4 lines
5: support raw flash without fs.
This should go into common code.
Quoted 8 lines
Quoted 4 lines
raw flash is part of common codes in
cff.cbecause it is part of mechanism like fs to determine how loading rbf from flash and program
into fpga.By common code I mean the stuff around FPGA LOADFS , so other FPGAs can
also benefit from that.
But the raw flash to FPGA implementation is designed fully tied to common codes in cff.c. FPGA loadfs would be acted like a wrapper to it, so i am not sure it can be shared by other FPGA.
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
6: support the file name defined in DTS and U-boot environment variable.
Quoted 9 lines
Quoted 6 lines
Quoted 2 lines
I think you should extend the FPGA LOADFS here instead.
The peripheral rbf filename and DTS are generated from our bsp tool.
But user can run fpga loadfs to reconfigure FPGA in U-boot console after i have supported it.And why don't you rather apply some FPGA LOADFS if this property is detected in the DT instead of reimplementing it ?
We need to program the FPGA IO ring buffer from very early phase in SPL before SDRAM can be initialized. So we need the peripheral rbf file name from DTS, which is defined by user in our BSP tool. I don't think FPGA loadfs would be available in SPL by that time. So, i think FPGA loadfs is suitable for reprogramming FPGA in U-boot console, and filename is passed as parameter to fpga loadfs command.
Quoted 22 lines
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
Quoted 9 lines
Also, the ifdeffery is awful and the explicit depedence on VFAT when loading from FS is real bad.
It is because a lot functions is common to sdmmc, nand and qspi in
different fs such as vfat, ubi and raw. It is unavoidable to have
some
ifdeffery if we want to keep the function common to all flashes and
fs.Quoted 5 lines
Quoted 2 lines
Can the FPGA LOADFS be extended generically ?
Yeah, FPGA loadfs is considered when design
cff.c. But, i plan to to
support FPGA loadfs after having complete boot to U-boot console.
Quoted 8 lines
Does that mean the Arria10 is still not even capable of booting into U-Boot console ?
cff.cis unlikely to hit mainline unless there's compelling argument that it is needed . Thus far, I see most of the functionality should be
added elsewhere or is already there (fpga loadfs).
Please consider it, as i think that implementation of loading rbf from any flashes to memory before programming PFGA should not be part of FPGA driver. FPGA driver should contains only functionality of init fpga and programming FPGA. cff.c is designed so the fpga loadfs can be acted wrapper on it.
PATCH v2 4/5 arm: socfpga: Add intermediate driver between flash and FPGA manager
Quoted 12 lines · Tien Fong
Quoted 11 lines · Marek Vasut
On 08/12/2017 10:03 AM, Chee, Tien Fong wrote:
[...]Quoted 9 lines
Quoted 9 lines
Quoted 7 lines
1: It having ability to the right memory(OCRAM or SDRAM) to achieve
the
best FPGA programing performance.Did you find significant throughput difference ?
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
80% performance improvement with SDRAM.
This looks more like caches are not enabled ... sort of problem ?
It is because SDRAM size large enough to store whole rbf file and reduce significantly of the repetitive block transfer. It requires one time block transfer from SDRAM to FPGA compare to OCRAM which require more than that.
OK, do that as a subsequent optimization.
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 9 lines
Quoted 7 lines
2: It can determine the right size buffer for the fpga rbf without
info
of buffer size defined by user.You mean like $filesize variable in the command prompt ?
Yeah. No filesize is required.
Quoted 8 lines
Quoted 3 lines
You can use $filesize instead of reimplementing this functionality yourself though ?
I'am sorry to have confused you. What i trying to say is user no longer require to specify the file size and location when calling fpga loadfs. So, this would keep the thing simple. The driver in
cff.cwould handle all these troublesome things and deciding the best route for good performance.
OK, separate patch
Quoted 23 lines
Quoted 17 lines
Quoted 13 lines
Quoted 7 lines
Quoted 7 lines
3: It has ability to know what kind of fpga rbf type, and security
type, such as peripheral, core, combined rbf, encryption and unencryption based on any fpga file user pass in .Quoted 6 lines
Is this information used for anything ? I was under the impression
that
the user just needs to load in the correct RBF file into the FPGA.Quoted 4 lines
Yeah, the driver would decode the RBF image to know what type of RBF
user loading, and applying correctmethod(buffer allocation, which memory to use and configuration on FPGA manager)to program FPGA.Quoted 6 lines
If the code needs to extract some information from the RBF to correctly
configure something in the FPGA manager, then that's where this should
go then.
Quoted 5 lines
Those functions for extracting info from RBF and configuring the FPGA are actually come from fpga driver which i have submited as in previous patchset. The actualy implementation is in
cff.c, as i try to explaincff.cdrivers are mainly to handle all activities of loading rbf from flashes to program FPGA.
Such functionality should be generic and split between fpga loadfs and the driver.
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 7 lines
Quoted 4 lines
4: It supports the checksum.
What checksum ? Can we have a generic hook into the FPGA framework ?
This checksum is to ensure integrity of RBF file after loading from flash into SDRAM. This can help to prevent possibility system instability caused by programming corrupt rbf into FPGA. So, this should be implemented in
cff.c.
Quoted 6 lines
Quoted 2 lines
Or the FPGA manager driver .
This integrity checking is implemented during RBF loading from flash to SDRAM before calling the functions from fpga driver to program FPGA. So
cff.cwhich is designed for handling these operation and it should be appropriate place for checksum.
Add a checksum hook into the FPGA framework ?
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 6 lines
Quoted 4 lines
5: support raw flash without fs.
This should go into common code.
raw flash is part of common codes in
cff.cbecause it is part of mechanism like fs to determine how loading rbf from flash and program
into fpga.
Quoted 7 lines
Quoted 4 lines
By common code I mean the stuff around FPGA LOADFS , so other FPGAs can
also benefit from that.But the raw flash to FPGA implementation is designed fully tied to common codes in
cff.c. FPGA loadfs would be acted like a wrapper to it, so i am not sure it can be shared by other FPGA.
I do not want any ad-hoc wrapper, implement it properly be extending fpga loadfs or the fpga framework.
Quoted 14 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
6: support the file name defined in DTS and U-boot environment variable.
Quoted 9 lines
Quoted 6 lines
Quoted 2 lines
I think you should extend the FPGA LOADFS here instead.
The peripheral rbf filename and DTS are generated from our bsp tool.
But user can run fpga loadfs to reconfigure FPGA in U-boot console after i have supported it.And why don't you rather apply some FPGA LOADFS if this property is detected in the DT instead of reimplementing it ?
Quoted 6 lines
We need to program the FPGA IO ring buffer from very early phase in SPL before SDRAM can be initialized. So we need the peripheral rbf file name from DTS, which is defined by user in our BSP tool. I don't think FPGA loadfs would be available in SPL by that time. So, i think FPGA loadfs is suitable for reprogramming FPGA in U-boot console, and filename is passed as parameter to fpga loadfs command.
Then just call the required bits from fpga loadfs during SPL . Extract them into some fpga-loadfs-common and make both fpga loadfs and your SPL code call those functions.
Quoted 25 lines
Quoted 25 lines
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
Quoted 9 lines
Also, the ifdeffery is awful and the explicit
depedence on VFAT when loading from FS is real bad.It is because a lot functions is common to sdmmc, nand and qspi in
different fs such as vfat, ubi and raw. It is unavoidable to have
some
ifdeffery if we want to keep the function common to all flashes and
fs.Quoted 5 lines
Quoted 2 lines
Can the FPGA LOADFS be extended generically ?
Yeah, FPGA loadfs is considered when design
cff.c. But, i plan to to
support FPGA loadfs after having complete boot to U-boot console.Does that mean the Arria10 is still not even capable of booting into U-Boot console ?
Quoted 8 lines
Quoted 5 lines
cff.cis unlikely to hit mainline unless there's compelling argument that it is needed . Thus far, I see most of the functionality should be
added elsewhere or is already there (fpga loadfs).Please consider it, as i think that implementation of loading rbf from any flashes to memory before programming PFGA should not be part of FPGA driver.
That's correct.
Quoted 3 lines
FPGA driver should contains only functionality of init
fpga and programming FPGA.cff.cis designed so the fpga loadfs can be acted wrapper on it.
And that is the part I have real problem with. Extend the common code and then use it to load whatever stuff into the FPGA instead of making common code a wrapper around ad-hoc stuff.
Signature · 2 lines
Best regards, Marek Vasut
PATCH v2 5/5 arm: socfpga: Enable cff driver build
In reply to tien.fong.chee at intel.comFrom: Tien Fong Chee <[email protected]>
Enable cff driver build which is needed as intermediate driver for handling operation of FPGA program between feeding FPGA design from flash into FPGA manager.
--- arch/arm/mach-socfpga/Makefile | 1 + 1 file changed, 1 insertion(+)
arch/arm/mach-socfpga/Makefile +1 -0
@@ -28,6 +28,7 @@ obj-y += clock_manager_arria10.o obj-y += misc_arria10.o obj-y += pinmux_arria10.o obj-y += reset_manager_arria10.o +obj-y += cff.o endif ifdef CONFIG_SPL_BUILD
Signature · 1 line
2.2.0
PATCH v2 5/5 arm: socfpga: Enable cff driver build
Quoted 16 lines · tien.fong.chee at intel.com
From: Tien Fong Chee <[email protected]>
Enable cff driver build which is needed as intermediate driver for handling operation of FPGA program between feeding FPGA design from flash into FPGA manager.
Signed-off-by Tien Fong Chee <[email protected]>--- arch/arm/mach-socfpga/Makefile | 1 + 1 file changed, 1 insertion(+)arch/arm/mach-socfpga/Makefile +0
-0
arch/arm/mach-socfpga/Makefile obj-y += clock_manager_arria10.o · line 31
Quoted 4 lines
arch/arm/mach-socfpga/Makefile +1
-0@@ -28,6 +28,7 @@ obj-y += clock_manager_arria10.o obj-y += misc_arria10.o obj-y += pinmux_arria10.o obj-y += reset_manager_arria10.o +obj-y += cff.o
Keep the list sorted ...
Quoted 4 lines
arch/arm/mach-socfpga/Makefile +0
-0endif ifdef CONFIG_SPL_BUILD
Signature · 2 lines
Best regards, Marek Vasut
Chee
PATCH v2 5/5 arm: socfpga: Enable cff driver build
Quoted 15 lines · Marek Vasut
Quoted 14 lines · tien.fong.chee at intel.com
From: Tien Fong Chee <[email protected]>
Enable cff driver build which is needed as intermediate driver for handling
operation of FPGA program between feeding FPGA design from flash into FPGA
manager.Signed-off-by Tien Fong Chee <[email protected]>---
arch/arm/mach-socfpga/Makefile | 1 +1 file changed, 1 insertion(+)
Quoted 12 lines
Quoted 10 lines
arch/arm/mach- renamed from arch/arm/mach-socfpga/Makefile +0
-0socfpga/Makefile
index 286bfef..23fb322 100644arch/arm/mach-socfpga/Makefile +0
-0@@ -28,6 +28,7 @@ obj-y += clock_manager_arria10.oobj-y += misc_arria10.o
obj-y += pinmux_arria10.o
obj-y += reset_manager_arria10.o
+obj-y += cff.oKeep the list sorted ...
Okay.
Quoted 6 lines
Quoted 5 lines
endif
ifdefCONFIG_SPL_BUILD