[U-Boot] [PATCH v3] Add "cpu_config" command for PPC4xx bootstrap configuration

Matthias Fuchs
2009-07-17T19:57:11Z

Please see one comment below

On Friday 17 July 2009 15:53:56 Stefan Roese wrote:
> This patch adds a generic command for programming I2C bootstrap
> eeproms on PPC4xx. An implementation for Canyonlands board is
> included.
>
> The command name is intentionally chosen not to be PPC4xx specific.
> This way other CPU's/SoC's can implement a similar command under
> the same name, perhaps with a different syntax.
>
> Usage on Canyonlands:
>
> => cpu_config
> Available configurations (I2C address 0x52):
> 600-nor - NOR CPU: 600 PLB: 200 OPB: 100 EBC: 100
> 600-nand - NAND CPU: 600 PLB: 200 OPB: 100 EBC: 100
> 800-nor - NOR CPU: 800 PLB: 200 OPB: 100 EBC: 100
> 800-nand - NAND CPU: 800 PLB: 200 OPB: 100 EBC: 100
> 1000-nor - NOR CPU:1000 PLB: 200 OPB: 100 EBC: 100
> 1000-nand - NAND CPU:1000 PLB: 200 OPB: 100 EBC: 100
> 1066-nor - NOR CPU:1066 PLB: 266 OPB: 88 EBC: 88 ***
> 1066-nand - NAND CPU:1066 PLB: 266 OPB: 88 EBC: 88
> => cpu_config 600-nor
> Using configuration:
> 600-nor - NOR CPU: 600 PLB: 200 OPB: 100 EBC: 100
> done (dump via 'i2c md 52 0.1 10')
> Reset the board for the changes to take effect
>
> Other 4xx boards will be migrated to use this command soon
> as well.
>
> Signed-off-by: Stefan Roese <sr@denx.de>
> Signed-off-by: Dirk Eibach <eibach@gdsys.de>
> Cc: Matthias Fuchs <matthias.fuchs@esd.eu>
> ---
> v3:
> - Line length of one printf reduced
>
> v2:
> - Patch authorship changes to Stefan
> - s-o-b from Dirk added
> - Added current configuration detection
> - Minor coding style cleanup
>
> board/amcc/canyonlands/Makefile | 5 +-
> board/amcc/canyonlands/bootstrap.c | 195
> ----------------------------------- board/amcc/canyonlands/cpu_config.c |
> 55 ++++++++++
> cpu/ppc4xx/Makefile | 3 +
> cpu/ppc4xx/cmd_cpu_config.c | 127 +++++++++++++++++++++++
> include/asm-ppc/ppc4xx_config.h | 42 ++++++++
> include/configs/canyonlands.h | 4 +
> 7 files changed, 234 insertions(+), 197 deletions(-)
> delete mode 100644 board/amcc/canyonlands/bootstrap.c
> create mode 100644 board/amcc/canyonlands/cpu_config.c
> create mode 100644 cpu/ppc4xx/cmd_cpu_config.c
> create mode 100644 include/asm-ppc/ppc4xx_config.h
>
> diff --git a/board/amcc/canyonlands/Makefile
> b/board/amcc/canyonlands/Makefile index 2aeead6..b1dfb0b 100644
> --- a/board/amcc/canyonlands/Makefile
> +++ b/board/amcc/canyonlands/Makefile
> @@ -25,10 +25,11 @@ include $(TOPDIR)/config.mk
>
> LIB = $(obj)lib$(BOARD).a
>
> -COBJS := $(BOARD).o
> -COBJS += bootstrap.o
> +COBJS-y := $(BOARD).o
> +COBJS-$(CONFIG_CMD_CPU_CONFIG) += cpu_config.o
> SOBJS := init.o
>
> +COBJS := $(COBJS-y)
> SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
> OBJS := $(addprefix $(obj),$(COBJS))
> SOBJS := $(addprefix $(obj),$(SOBJS))
> diff --git a/board/amcc/canyonlands/bootstrap.c
> b/board/amcc/canyonlands/bootstrap.c deleted file mode 100644
> index 6dc2cca..0000000
> --- a/board/amcc/canyonlands/bootstrap.c
> +++ /dev/null
> @@ -1,195 +0,0 @@
> -/*
> - * (C) Copyright 2008
> - * Stefan Roese, DENX Software Engineering, sr at denx.de.
> - *
> - * See file CREDITS for list of people who contributed to this
> - * project.
> - *
> - * This program is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU General Public License as
> - * published by the Free Software Foundation; either version 2 of
> - * the License, or (at your option) any later version.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> - * GNU General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License
> - * along with this program; if not, write to the Free Software
> - * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> - * MA 02111-1307 USA
> - *
> - */
> -
> -#include <common.h>
> -#include <command.h>
> -#include <i2c.h>
> -#include <asm/io.h>
> -
> -/*
> - * NOR and NAND boot options change bytes 5, 6, 8, 9, 11. The
> - * values are independent of the rest of the clock settings.
> - */
> -
> -#define NAND_COMPATIBLE 0x01
> -#define NOR_COMPATIBLE 0x02
> -
> -#define I2C_EEPROM_ADDR 0x52
> -
> -static char *config_labels[] = {
> - "CPU: 600 PLB: 200 OPB: 100 EBC: 100",
> - "CPU: 800 PLB: 200 OPB: 100 EBC: 100",
> - "CPU:1000 PLB: 200 OPB: 100 EBC: 100",
> - "CPU:1066 PLB: 266 OPB: 88 EBC: 88",
> - NULL
> -};
> -
> -static u8 boot_configs[][17] = {
> - {
> - (NAND_COMPATIBLE | NOR_COMPATIBLE),
> - 0x86, 0x80, 0xce, 0x1f, 0x79, 0x80, 0x00, 0xa0, 0x40, 0x08,
> - 0x23, 0x50, 0x0d, 0x05, 0x00, 0x00
> - },
> - {
> - (NAND_COMPATIBLE | NOR_COMPATIBLE),
> - 0x86, 0x80, 0xba, 0x14, 0x99, 0x80, 0x00, 0xa0, 0x40, 0x08,
> - 0x23, 0x50, 0x0d, 0x05, 0x00, 0x00
> - },
> - {
> - (NAND_COMPATIBLE | NOR_COMPATIBLE),
> - 0x86, 0x82, 0x96, 0x19, 0xb9, 0x80, 0x00, 0xa0, 0x40, 0x08,
> - 0x23, 0x50, 0x0d, 0x05, 0x00, 0x00
> - },
> - {
> - (NAND_COMPATIBLE | NOR_COMPATIBLE),
> - 0x86, 0x80, 0xb3, 0x01, 0x9d, 0x80, 0x00, 0xa0, 0x40, 0x08,
> - 0x23, 0x50, 0x0d, 0x05, 0x00, 0x00
> - },
> - {
> - 0,
> - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
> - }
> -};
> -
> -/*
> - * Bytes 5,6,8,9,11 change for NAND boot
> - */
> -#if 0
> -/*
> - * Values for 512 page size NAND chips, not used anymore, just
> - * keep them here for reference
> - */
> -static u8 nand_boot[] = {
> - 0x90, 0x01, 0xa0, 0x68, 0x58
> -};
> -#else
> -/*
> - * Values for 2k page size NAND chips
> - */
> -static u8 nand_boot[] = {
> - 0x90, 0x01, 0xa0, 0xe8, 0x58
> -};
> -#endif
> -
> -static int do_bootstrap(cmd_tbl_t *cmdtp, int flag, int argc, char
> *argv[]) -{
> - u8 *buf, b_nand;
> - int x, y, nbytes, selcfg;
> - extern char console_buffer[];
> -
> - if (argc < 2) {
> - cmd_usage(cmdtp);
> - return 1;
> - }
> -
> - if ((strcmp(argv[1], "nor") != 0) &&
> - (strcmp(argv[1], "nand") != 0)) {
> - printf("Unsupported boot-device - only nor|nand support\n");
> - return 1;
> - }
> -
> - /* set the nand flag based on provided input */
> - if ((strcmp(argv[1], "nand") == 0))
> - b_nand = 1;
> - else
> - b_nand = 0;
> -
> - printf("Available configurations: \n\n");
> -
> - if (b_nand) {
> - for(x = 0, y = 0; boot_configs[x][0] != 0; x++) {
> - /* filter on nand compatible */
> - if (boot_configs[x][0] & NAND_COMPATIBLE) {
> - printf(" %d - %s\n", (y+1), config_labels[x]);
> - y++;
> - }
> - }
> - } else {
> - for(x = 0, y = 0; boot_configs[x][0] != 0; x++) {
> - /* filter on nor compatible */
> - if (boot_configs[x][0] & NOR_COMPATIBLE) {
> - printf(" %d - %s\n", (y+1), config_labels[x]);
> - y++;
> - }
> - }
> - }
> -
> - do {
> - nbytes = readline(" Selection [1-x / quit]: ");
> -
> - if (nbytes) {
> - if (strcmp(console_buffer, "quit") == 0)
> - return 0;
> - selcfg = simple_strtol(console_buffer, NULL, 10);
> - if ((selcfg < 1) || (selcfg > y))
> - nbytes = 0;
> - }
> - } while (nbytes == 0);
> -
> -
> - y = (selcfg - 1);
> -
> - for (x = 0; boot_configs[x][0] != 0; x++) {
> - if (b_nand) {
> - if (boot_configs[x][0] & NAND_COMPATIBLE) {
> - if (y > 0)
> - y--;
> - else if (y < 1)
> - break;
> - }
> - } else {
> - if (boot_configs[x][0] & NOR_COMPATIBLE) {
> - if (y > 0)
> - y--;
> - else if (y < 1)
> - break;
> - }
> - }
> - }
> -
> - buf = &boot_configs[x][1];
> -
> - if (b_nand) {
> - buf[5] = nand_boot[0];
> - buf[6] = nand_boot[1];
> - buf[8] = nand_boot[2];
> - buf[9] = nand_boot[3];
> - buf[11] = nand_boot[4];
> - }
> -
> - if (i2c_write(I2C_EEPROM_ADDR, 0, 1, buf, 16) != 0)
> - printf("Error writing to EEPROM at address 0x%x\n", I2C_EEPROM_ADDR);
> - udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
> -
> - printf("Done\n");
> - printf("Please power-cycle the board for the changes to take effect\n");
> -
> - return 0;
> -}
> -
> -U_BOOT_CMD(
> - bootstrap, 2, 0, do_bootstrap,
> - "program the I2C bootstrap EEPROM",
> - "<nand|nor> - strap to boot from NAND or NOR flash"
> -);
> diff --git a/board/amcc/canyonlands/cpu_config.c
> b/board/amcc/canyonlands/cpu_config.c new file mode 100644
> index 0000000..8504171
> --- /dev/null
> +++ b/board/amcc/canyonlands/cpu_config.c
> @@ -0,0 +1,55 @@
> +/*
> + * (C) Copyright 2008-2009
> + * Stefan Roese, DENX Software Engineering, sr at denx.de.
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + *
> + */
> +
> +#include <common.h>
> +#include <asm/ppc4xx_config.h>
> +
> +struct ppc4xx_config ppc4xx_config_val[] = {
> + { "600-nor", "NOR CPU: 600 PLB: 200 OPB: 100 EBC: 100",
> + { 0x86, 0x80, 0xce, 0x1f, 0x79, 0x80, 0x00, 0xa0,
> + 0x40, 0x08, 0x23, 0x50, 0x0d, 0x05, 0x00, 0x00 } },
> + { "600-nand", "NAND CPU: 600 PLB: 200 OPB: 100 EBC: 100",
> + { 0x86, 0x80, 0xce, 0x1f, 0x79, 0x90, 0x01, 0xa0,
> + 0xa0, 0xe8, 0x23, 0x58, 0x0d, 0x05, 0x00, 0x00 } },
> + { "800-nor", "NOR CPU: 800 PLB: 200 OPB: 100 EBC: 100",
> + { 0x86, 0x80, 0xba, 0x14, 0x99, 0x80, 0x00, 0xa0,
> + 0x40, 0x08, 0x23, 0x50, 0x0d, 0x05, 0x00, 0x00 } },
> + { "800-nand", "NAND CPU: 800 PLB: 200 OPB: 100 EBC: 100",
> + { 0x86, 0x80, 0xba, 0x14, 0x99, 0x90, 0x01, 0xa0,
> + 0xa0, 0xe8, 0x23, 0x58, 0x0d, 0x05, 0x00, 0x00 } },
> + { "1000-nor", "NOR CPU:1000 PLB: 200 OPB: 100 EBC: 100",
> + { 0x86, 0x82, 0x96, 0x19, 0xb9, 0x80, 0x00, 0xa0,
> + 0x40, 0x08, 0x23, 0x50, 0x0d, 0x05, 0x00, 0x00 } },
> + { "1000-nand", "NAND CPU:1000 PLB: 200 OPB: 100 EBC: 100",
> + { 0x86, 0x82, 0x96, 0x19, 0xb9, 0x90, 0x01, 0xa0,
> + 0xa0, 0xe8, 0x23, 0x58, 0x0d, 0x05, 0x00, 0x00 } },
> + { "1066-nor", "NOR CPU:1066 PLB: 266 OPB: 88 EBC: 88",
> + { 0x86, 0x80, 0xb3, 0x01, 0x9d, 0x80, 0x00, 0xa0,
> + 0x40, 0x08, 0x23, 0x50, 0x0d, 0x05, 0x00, 0x00 } },
> + { "1066-nand", "NAND CPU:1066 PLB: 266 OPB: 88 EBC: 88",
> + { 0x86, 0x80, 0xb3, 0x01, 0x9d, 0x90, 0x01, 0xa0,
> + 0xa0, 0xe8, 0x23, 0x58, 0x0d, 0x05, 0x00, 0x00 } },
> +};
> +
> +int ppc4xx_config_count = ARRAY_SIZE(ppc4xx_config_val);
> diff --git a/cpu/ppc4xx/Makefile b/cpu/ppc4xx/Makefile
> index 96ab5c6..c5f22f1 100644
> --- a/cpu/ppc4xx/Makefile
> +++ b/cpu/ppc4xx/Makefile
> @@ -41,6 +41,9 @@ endif
> COBJS += 4xx_pci.o
> COBJS += 4xx_pcie.o
> COBJS += bedbug_405.o
> +ifdef CONFIG_CMD_CPU_CONFIG
> +COBJS += cmd_cpu_config.o
> +endif
> COBJS += commproc.o
> COBJS += cpu.o
> COBJS += cpu_init.o
> diff --git a/cpu/ppc4xx/cmd_cpu_config.c b/cpu/ppc4xx/cmd_cpu_config.c
> new file mode 100644
> index 0000000..0d203f7
> --- /dev/null
> +++ b/cpu/ppc4xx/cmd_cpu_config.c
> @@ -0,0 +1,127 @@
> +/*
> + * (C) Copyright 2008-2009
> + * Stefan Roese, DENX Software Engineering, sr at denx.de.
> + *
> + * (C) Copyright 2009
> + * Dirk Eibach, Guntermann & Drunck GmbH, eibach at gdsys.de
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + *
> + */
> +
> +#include <common.h>
> +#include <command.h>
> +#include <i2c.h>
> +#include <asm/ppc4xx_config.h>
> +#include <asm/io.h>
> +
> +static void print_configs(int cur_config_nr)
> +{
> + int i;
> +
> + for (i = 0; i < ppc4xx_config_count; i++) {
> + printf("%-16s - %s", ppc4xx_config_val[i].label,
> + ppc4xx_config_val[i].description);
> + if (i == cur_config_nr)
> + printf(" ***");
> + printf("\n");
> + }
> +
> +}
> +
> +static int do_cpu_config(cmd_tbl_t *cmdtp, int flag, int argc, char
> *argv[]) +{
> + int i;
> + int ret;
> + int cur_config_nr = -1;
> + u8 cur_config[CONFIG_4xx_CONFIG_BLOCKSIZE];
> +
> + ret = i2c_read(CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR, 0, 1,
> + cur_config, CONFIG_4xx_CONFIG_BLOCKSIZE);
> + if (ret) {
> + printf("Error reading EEPROM at addr 0x%x\n",
> + CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR);
> + return -1;
> + }
> +
> + /*
> + * Search the current configuration
> + */
> + for (i = 0; i < ppc4xx_config_count; i++) {
> + if (memcmp(cur_config, ppc4xx_config_val[i].val,
> + CONFIG_4xx_CONFIG_BLOCKSIZE) == 0)
> + cur_config_nr = i;
> + }
> +
> + if (cur_config_nr == -1) {
> + printf("Warning: The I2C bootstrap values don't match any"
> + " of the available options!\n");
> + printf("I2C bootstrap EEPROM values are (I2C address 0x%02x):\n",
> + CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR);
> + for (i = 0; i < CONFIG_4xx_CONFIG_BLOCKSIZE; i++) {
> + printf("%02x ", cur_config[i]);
> + }
> + printf("\n");
> + }
> +
> + if (argc < 2) {
> + printf("Available configurations (I2C address 0x%02x):\n",
> + CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR);
> + print_configs(cur_config_nr);
> + return 0;
> + }
> +
> + for (i = 0; i < ppc4xx_config_count; i++) {
> + /*
> + * Search for configuration name/label
> + */
> + if (strcmp(argv[1], ppc4xx_config_val[i].label) == 0) {
> + printf("Using configuration:\n%-16s - %s\n",
> + ppc4xx_config_val[i].label,
> + ppc4xx_config_val[i].description);
> +
> + ret = i2c_write(CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR, 0, 1,
> + ppc4xx_config_val[i].val,
> + CONFIG_4xx_CONFIG_BLOCKSIZE);
I would like to see eeprom_write() here. On 405EP the strapping data is 0x20
bytes but the/our EEPROM has a page size of 16 bytes so i2c_write makes
problems with the 2nd half of data. Also eeprom_write handles the write
protection stuff. See some esd boards or the recent sbe command implementation
in my last PMC405DE patch.

For the rest you got my ack.

Matthias