@ -33,6 +33,7 @@
# ifdef CONFIG_FSL_ESDHC
# include <fsl_esdhc.h>
# endif
# include "../../../../drivers/qe/qe.h" /* For struct qe_firmware */
DECLARE_GLOBAL_DATA_PTR ;
@ -406,6 +407,126 @@ static void ft_fixup_qe_snum(void *blob)
}
# endif
/**
* fdt_fixup_fman_firmware - - insert the Fman firmware into the device tree
*
* The binding for an Fman firmware node is documented in
* Documentation / powerpc / dts - bindings / fsl / dpaa / fman . txt . This node contains
* the actual Fman firmware binary data . The operating system is expected to
* be able to parse the binary data to determine any attributes it needs .
*/
# ifdef CONFIG_SYS_DPAA_FMAN
void fdt_fixup_fman_firmware ( void * blob )
{
int rc , fmnode , fwnode = - 1 ;
uint32_t phandle ;
struct qe_firmware * fmanfw ;
const struct qe_header * hdr ;
unsigned int length ;
uint32_t crc ;
const char * p ;
/* The first Fman we find will contain the actual firmware. */
fmnode = fdt_node_offset_by_compatible ( blob , - 1 , " fsl,fman " ) ;
if ( fmnode < 0 )
/* Exit silently if there are no Fman devices */
return ;
/* If we already have a firmware node, then also exit silently. */
if ( fdt_node_offset_by_compatible ( blob , - 1 , " fsl,fman-firmware " ) > 0 )
return ;
/* If the environment variable is not set, then exit silently */
p = getenv ( " fman_ucode " ) ;
if ( ! p )
return ;
fmanfw = ( struct qe_firmware * ) simple_strtoul ( p , NULL , 0 ) ;
if ( ! fmanfw )
return ;
hdr = & fmanfw - > header ;
length = be32_to_cpu ( hdr - > length ) ;
/* Verify the firmware. */
if ( ( hdr - > magic [ 0 ] ! = ' Q ' ) | | ( hdr - > magic [ 1 ] ! = ' E ' ) | |
( hdr - > magic [ 2 ] ! = ' F ' ) ) {
printf ( " Data at %p is not an Fman firmware \n " , fmanfw ) ;
return ;
}
if ( length > CONFIG_SYS_FMAN_FW_LENGTH ) {
printf ( " Fman firmware at %p is too large (size=%u) \n " ,
fmanfw , length ) ;
return ;
}
length - = sizeof ( u32 ) ; /* Subtract the size of the CRC */
crc = be32_to_cpu ( * ( u32 * ) ( ( void * ) fmanfw + length ) ) ;
if ( crc ! = crc32_no_comp ( 0 , ( void * ) fmanfw , length ) ) {
printf ( " Fman firmware at %p has invalid CRC \n " , fmanfw ) ;
return ;
}
/* Increase the size of the fdt to make room for the node. */
rc = fdt_increase_size ( blob , fmanfw - > header . length ) ;
if ( rc < 0 ) {
printf ( " Unable to make room for Fman firmware: %s \n " ,
fdt_strerror ( rc ) ) ;
return ;
}
/* Create the firmware node. */
fwnode = fdt_add_subnode ( blob , fmnode , " fman-firmware " ) ;
if ( fwnode < 0 ) {
char s [ 64 ] ;
fdt_get_path ( blob , fmnode , s , sizeof ( s ) ) ;
printf ( " Could not add firmware node to %s: %s \n " , s ,
fdt_strerror ( fwnode ) ) ;
return ;
}
rc = fdt_setprop_string ( blob , fwnode , " compatible " , " fsl,fman-firmware " ) ;
if ( rc < 0 ) {
char s [ 64 ] ;
fdt_get_path ( blob , fwnode , s , sizeof ( s ) ) ;
printf ( " Could not add compatible property to node %s: %s \n " , s ,
fdt_strerror ( rc ) ) ;
return ;
}
phandle = fdt_alloc_phandle ( blob ) ;
rc = fdt_setprop_cell ( blob , fwnode , " linux,phandle " , phandle ) ;
if ( rc < 0 ) {
char s [ 64 ] ;
fdt_get_path ( blob , fwnode , s , sizeof ( s ) ) ;
printf ( " Could not add phandle property to node %s: %s \n " , s ,
fdt_strerror ( rc ) ) ;
return ;
}
rc = fdt_setprop ( blob , fwnode , " fsl,firmware " , fmanfw , fmanfw - > header . length ) ;
if ( rc < 0 ) {
char s [ 64 ] ;
fdt_get_path ( blob , fwnode , s , sizeof ( s ) ) ;
printf ( " Could not add firmware property to node %s: %s \n " , s ,
fdt_strerror ( rc ) ) ;
return ;
}
/* Find all other Fman nodes and point them to the firmware node. */
while ( ( fmnode = fdt_node_offset_by_compatible ( blob , fmnode , " fsl,fman " ) ) > 0 ) {
rc = fdt_setprop_cell ( blob , fmnode , " fsl,firmware-phandle " , phandle ) ;
if ( rc < 0 ) {
char s [ 64 ] ;
fdt_get_path ( blob , fmnode , s , sizeof ( s ) ) ;
printf ( " Could not add pointer property to node %s: %s \n " ,
s , fdt_strerror ( rc ) ) ;
return ;
}
}
}
# else
# define fdt_fixup_fman_firmware(x)
# endif
void ft_cpu_setup ( void * blob , bd_t * bd )
{
int off ;
@ -445,6 +566,8 @@ void ft_cpu_setup(void *blob, bd_t *bd)
ft_fixup_qe_snum ( blob ) ;
# endif
fdt_fixup_fman_firmware ( blob ) ;
# ifdef CONFIG_SYS_NS16550
do_fixup_by_compat_u32 ( blob , " ns16550 " ,
" clock-frequency " , CONFIG_SYS_NS16550_CLK , 1 ) ;