[U-Boot] [PATCH 1/1] at91: Update MEESC board support

This patch implements several updates: -Write the ethernet address to the EMAC module -Disable CONFIG_ENV_OVERWRITE -Add new hardware style variants and set the arch numbers appropriate (autodetect) -Pass the serial# and hardware revision to the kernel
Signed-off-by: Daniel Gorsulowski Daniel.Gorsulowski@esd.eu --- board/esd/meesc/meesc.c | 97 +++++++++++++++++++++++++++++++++++++++++++++-- include/configs/meesc.h | 9 ++++- 2 files changed, 101 insertions(+), 5 deletions(-)
diff --git a/board/esd/meesc/meesc.c b/board/esd/meesc/meesc.c index 636d0ed..54a310a 100644 --- a/board/esd/meesc/meesc.c +++ b/board/esd/meesc/meesc.c @@ -38,6 +38,9 @@ #include <asm/arch/hardware.h> #include <asm/arch/io.h> #include <netdev.h> +#ifdef CONFIG_MACB +#include <net.h> +#endif
DECLARE_GLOBAL_DATA_PTR;
@@ -46,6 +49,7 @@ DECLARE_GLOBAL_DATA_PTR; */
static int hw_rev = -1; /* hardware revision */ +static u_char hw_type; /* hardware type */
int get_hw_rev(void) { @@ -63,6 +67,30 @@ int get_hw_rev(void) return hw_rev; }
+static void meesc_set_arch_number(void) +{ + /* read the "Type" register of the ET1100 controller */ + hw_type = readb(CONFIG_ET1100_BASE); + + switch (hw_type) { + case 0x11: + case 0x3F: + /* ET1100 present, + arch number of MEESC-Board */ + gd->bd->bi_arch_number = MACH_TYPE_MEESC; + break; + case 0xFF: + /* no ET1100 present, + arch number of EtherCAN/2-Board */ + gd->bd->bi_arch_number = MACH_TYPE_ETHERCAN2; + break; + default: + /* assume, no ET1100 present, + arch number of EtherCAN/2-Board */ + gd->bd->bi_arch_number = MACH_TYPE_ETHERCAN2; + break; + } +} #ifdef CONFIG_CMD_NAND static void meesc_nand_hw_init(void) { @@ -157,7 +185,19 @@ int checkboard(void) { char str[32];
- puts("Board: esd CAN-EtherCAT Gateway"); + switch (hw_type) { + case 0x11: + case 0x3F: + puts("Board: CAN-EtherCAT Gateway"); + break; + case 0xFF: + puts("Board: EtherCAN/2 Gateway"); + break; + default: + printf("FATAL! Read invalid hw_type: %02X\n", hw_type); + puts("Board: EtherCAN/2 Gateway"); + break; + } if (getenv_r("serial#", str, sizeof(str)) > 0) { puts(", serial# "); puts(str); @@ -167,6 +207,49 @@ int checkboard(void) return 0; }
+#ifdef CONFIG_SERIAL_TAG +void get_board_serial(struct tag_serialnr *serialnr) +{ + char *str; + + str = strchr(getenv("serial#"), '_'); + if (str) { + serialnr->high = (*(str + 1) << 8) | *(str + 2); + serialnr->low = simple_strtoul(str + 3, NULL, 16); + } else { + serialnr->high = 0; + serialnr->low = 0; + } +} +#endif + +#ifdef CONFIG_REVISION_TAG +u32 get_board_rev(void) +{ + return hw_rev | 0x100; +} +#endif + +int misc_init_r(void) +{ +#ifdef CONFIG_MACB + u32 hwaddr_btm; + u16 hwaddr_top; + u8 mac[6]; + + /* Set ethernet address */ + if (!eth_getenv_enetaddr("ethaddr", mac)) { + puts("Missing environment variable 'ethaddr'\n"); + } else { + hwaddr_btm = mac[0] | mac[1] << 8 | mac[2] << 16 | mac[3] << 24; + hwaddr_top = mac[4] | mac[5] << 8; + writel(hwaddr_btm, (void *)(AT91SAM9263_BASE_EMAC + MACB_SA1B)); + writel(hwaddr_top, (void *)(AT91SAM9263_BASE_EMAC + MACB_SA1T)); + } +#endif + return 0; +} + int board_init(void) { /* Peripheral Clock Enable Register */ @@ -174,8 +257,15 @@ int board_init(void) 1 << AT91SAM9263_ID_PIOB | 1 << AT91SAM9263_ID_PIOCDE);
- /* arch number of MEESC-Board */ - gd->bd->bi_arch_number = MACH_TYPE_MEESC; + /* initialize ET1100 Controller */ + meesc_ethercat_hw_init(); + + /* set arch number by hardware type */ + meesc_set_arch_number(); + + /* switch on LED1D, if running on EtherCAN/2 hardware */ + if (hw_type == 0xFF) + at91_set_gpio_output(AT91_PIN_PB12, 1);
/* adress of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; @@ -184,7 +274,6 @@ int board_init(void) #ifdef CONFIG_CMD_NAND meesc_nand_hw_init(); #endif - meesc_ethercat_hw_init(); #ifdef CONFIG_HAS_DATAFLASH at91_spi0_hw_init(1 << 0); #endif diff --git a/include/configs/meesc.h b/include/configs/meesc.h index 8253172..8495e3a 100644 --- a/include/configs/meesc.h +++ b/include/configs/meesc.h @@ -36,17 +36,19 @@ #define CONFIG_MEESC 1 /* Board is esd MEESC */ #define CONFIG_ARM926EJS 1 /* This is an ARM926EJS Core */ #define CONFIG_AT91SAM9263 1 /* It's an AT91SAM9263 SoC */ -#define CONFIG_ENV_OVERWRITE 1 /* necessary on prototypes */ #define CONFIG_DISPLAY_BOARDINFO 1 #define CONFIG_DISPLAY_CPUINFO 1 /* display cpu info and speed */ #define CONFIG_PREBOOT /* enable preboot variable */ #define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ #define CONFIG_SETUP_MEMORY_TAGS 1 #define CONFIG_INITRD_TAG 1 +#define CONFIG_SERIAL_TAG 1 +#define CONFIG_REVISION_TAG 1 #undef CONFIG_USE_IRQ /* don't need IRQ/FIQ stuff */
#define CONFIG_SKIP_LOWLEVEL_INIT #define CONFIG_SKIP_RELOCATE_UBOOT +#define CONFIG_MISC_INIT_R 1 /* Call misc_init_r */
#define CONFIG_ARCH_CPU_INIT
@@ -143,6 +145,11 @@ /* CAN */ #define CONFIG_AT91_CAN 1
+/* hw-controller addresses */ +#define MACB_SA1B 0x0098 +#define MACB_SA1T 0x009c +#define CONFIG_ET1100_BASE 0x70000000 + /* bootstrap + u-boot + env + linux in dataflash on CS0 */ #define CONFIG_ENV_IS_IN_DATAFLASH 1 #define CONFIG_SYS_MONITOR_BASE (CONFIG_SYS_DATAFLASH_LOGIC_ADDR_CS0 + \

+#ifdef CONFIG_REVISION_TAG +u32 get_board_rev(void) +{
- return hw_rev | 0x100;
+} +#endif
+int misc_init_r(void) +{ +#ifdef CONFIG_MACB
- u32 hwaddr_btm;
- u16 hwaddr_top;
- u8 mac[6];
- /* Set ethernet address */
- if (!eth_getenv_enetaddr("ethaddr", mac)) {
puts("Missing environment variable 'ethaddr'\n");
} else {
hwaddr_btm = mac[0] | mac[1] << 8 | mac[2] << 16 | mac[3] << 24;
hwaddr_top = mac[4] | mac[5] << 8;
writel(hwaddr_btm, (void *)(AT91SAM9263_BASE_EMAC + MACB_SA1B));
writel(hwaddr_top, (void *)(AT91SAM9263_BASE_EMAC + MACB_SA1T));
nack this will be done when u-boot will need to use the macb
Best Regards, J.

Dear Daniel,
In message 20090904211358.GR30118@game.jcrosoft.org Jean-Christophe wrote:
+#ifdef CONFIG_REVISION_TAG +u32 get_board_rev(void) +{
- return hw_rev | 0x100;
+} +#endif
+int misc_init_r(void) +{ +#ifdef CONFIG_MACB
- u32 hwaddr_btm;
- u16 hwaddr_top;
- u8 mac[6];
- /* Set ethernet address */
- if (!eth_getenv_enetaddr("ethaddr", mac)) {
puts("Missing environment variable 'ethaddr'\n");
} else {
hwaddr_btm = mac[0] | mac[1] << 8 | mac[2] << 16 | mac[3] << 24;
hwaddr_top = mac[4] | mac[5] << 8;
writel(hwaddr_btm, (void *)(AT91SAM9263_BASE_EMAC + MACB_SA1B));
writel(hwaddr_top, (void *)(AT91SAM9263_BASE_EMAC + MACB_SA1T));
nack this will be done when u-boot will need to use the macb
Jean-Christophe means: The Etherent interface must not be always initialized, but only when it is needed and used within U-Boot itself, i. e. if U-boot is performing anetwork command. See also item 2 at http://www.denx.de/wiki/U-Boot/DesignPrinciples and http://www.denx.de/wiki/view/DULG/EthernetDoesNotWorkInLinux
Best regards,
Wolfgang Denk

Hello Wolfgang, Jean-Christophe,
Wolfgang Denk wrote:
Dear Daniel,
In message 20090904211358.GR30118@game.jcrosoft.org Jean-Christophe wrote:
+#ifdef CONFIG_REVISION_TAG +u32 get_board_rev(void) +{
- return hw_rev | 0x100;
+} +#endif
+int misc_init_r(void) +{ +#ifdef CONFIG_MACB
- u32 hwaddr_btm;
- u16 hwaddr_top;
- u8 mac[6];
- /* Set ethernet address */
- if (!eth_getenv_enetaddr("ethaddr", mac)) {
puts("Missing environment variable 'ethaddr'\n");
} else {
hwaddr_btm = mac[0] | mac[1] << 8 | mac[2] << 16 | mac[3] << 24;
hwaddr_top = mac[4] | mac[5] << 8;
writel(hwaddr_btm, (void *)(AT91SAM9263_BASE_EMAC + MACB_SA1B));
writel(hwaddr_top, (void *)(AT91SAM9263_BASE_EMAC + MACB_SA1T));
nack this will be done when u-boot will need to use the macb#
Just imagine: U-boot boots a Linux kernel from NAND flash. It does NOT need the ethernet interface, so it does NOT initialize ethernet, so the ethernet address will NOT be written to the EMAC module! As a result, Linux will assign a random address, that is not acceptable!
Jean-Christophe means: The Etherent interface must not be always initialized, but only when it is needed and used within U-Boot itself, i. e. if U-boot is performing anetwork command. See also item 2 at http://www.denx.de/wiki/U-Boot/DesignPrinciples and http://www.denx.de/wiki/view/DULG/EthernetDoesNotWorkInLinux
Best regards,
Wolfgang Denk
I know about it.
But this patch does NOT initialize the Ethernet Interface. It JUST write the ethernet address to the EMAC module!
So please ACK this patch.
Regards, Daniel Gorsulowski

On Mon, 07 Sep 2009 09:26:17 +0200 Daniel Gorsulowski Daniel.Gorsulowski@esd.eu wrote:
nack this will be done when u-boot will need to use the macb#
Just imagine: U-boot boots a Linux kernel from NAND flash. It does NOT need the ethernet interface, so it does NOT initialize ethernet, so the ethernet address will NOT be written to the EMAC module! As a result, Linux will assign a random address, that is not acceptable!
Unfortunately, you'll have to communicate this in some other way to Linux. I also had this problem and submitted a patch for it. In the replies there were some suggestions on how to handle this:
http://lists.denx.de/pipermail/u-boot/2009-July/055725.html
Unfortunately, there is no standard way of doing this on ARM. Some people want to introduce PowerPC-style device trees on ARM as well, where this is handled in a generic way, but that hasn't been done yet and requires changes on both the Linux-side and U-boot.
So I believe this kind of patches will not be accepted, unfortunately. If you depend on the behavior, you can obviously keep the patch in your own tree.
// Simon

Hello,
Daniel Gorsulowski wrote:
Hello Wolfgang, Jean-Christophe,
Wolfgang Denk wrote:
Dear Daniel,
In message 20090904211358.GR30118@game.jcrosoft.org Jean-Christophe wrote:
+#ifdef CONFIG_REVISION_TAG +u32 get_board_rev(void) +{
- return hw_rev | 0x100;
+} +#endif
+int misc_init_r(void) +{ +#ifdef CONFIG_MACB
- u32 hwaddr_btm;
- u16 hwaddr_top;
- u8 mac[6];
- /* Set ethernet address */
- if (!eth_getenv_enetaddr("ethaddr", mac)) {
puts("Missing environment variable 'ethaddr'\n");
} else {
hwaddr_btm = mac[0] | mac[1] << 8 | mac[2] << 16 | mac[3] << 24;
hwaddr_top = mac[4] | mac[5] << 8;
writel(hwaddr_btm, (void *)(AT91SAM9263_BASE_EMAC + MACB_SA1B));
writel(hwaddr_top, (void *)(AT91SAM9263_BASE_EMAC + MACB_SA1T));
nack this will be done when u-boot will need to use the macb#
Just imagine: U-boot boots a Linux kernel from NAND flash. It does NOT need the ethernet interface, so it does NOT initialize ethernet, so the ethernet address will NOT be written to the EMAC module! As a result, Linux will assign a random address, that is not acceptable!
Jean-Christophe means: The Etherent interface must not be always initialized, but only when it is needed and used within U-Boot itself, i. e. if U-boot is performing anetwork command. See also item 2 at http://www.denx.de/wiki/U-Boot/DesignPrinciples and http://www.denx.de/wiki/view/DULG/EthernetDoesNotWorkInLinux
Best regards,
Wolfgang Denk
I know about it.
But this patch does NOT initialize the Ethernet Interface. It JUST write the ethernet address to the EMAC module!
So please ACK this patch.
Regards, Daniel Gorsulowski
it was worth an attempt... I made a new patch without the MACB stuff, see separate mail.
Now I parse the ethaddr through the kernel commandline. The kernel patch is temporary available at http://paste.debian.net/46114/ (maybe someone is interested in it)
Regards, Daniel Gorsulowski
participants (4)
-
Daniel Gorsulowski
-
Jean-Christophe PLAGNIOL-VILLARD
-
Simon Kagstrom
-
Wolfgang Denk