| /* |
| * (C) Copyright 2008-2009 |
| * Stefan Roese, DENX Software Engineering, sr@denx.de. |
| * |
| * (C) Copyright 2009 |
| * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de |
| * |
| * SPDX-License-Identifier: GPL-2.0+ |
| */ |
| |
| #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_chip_config(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
| { |
| int i; |
| int ret; |
| int cur_config_nr = -1; |
| u8 cur_config[CONFIG_4xx_CONFIG_BLOCKSIZE]; |
| |
| /* |
| * First switch to correct I2C bus. This is I2C bus 0 |
| * for all currently available 4xx derivats. |
| */ |
| i2c_set_bus_num(0); |
| |
| #ifdef CONFIG_CMD_EEPROM |
| ret = eeprom_read(CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR, |
| CONFIG_4xx_CONFIG_I2C_EEPROM_OFFSET, |
| cur_config, CONFIG_4xx_CONFIG_BLOCKSIZE); |
| #else |
| ret = i2c_read(CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR, |
| CONFIG_4xx_CONFIG_I2C_EEPROM_OFFSET, |
| 1, cur_config, CONFIG_4xx_CONFIG_BLOCKSIZE); |
| #endif |
| 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); |
| |
| #ifdef CONFIG_CMD_EEPROM |
| ret = eeprom_write(CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR, |
| CONFIG_4xx_CONFIG_I2C_EEPROM_OFFSET, |
| ppc4xx_config_val[i].val, |
| CONFIG_4xx_CONFIG_BLOCKSIZE); |
| #else |
| ret = i2c_write(CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR, |
| CONFIG_4xx_CONFIG_I2C_EEPROM_OFFSET, |
| 1, ppc4xx_config_val[i].val, |
| CONFIG_4xx_CONFIG_BLOCKSIZE); |
| #endif |
| udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000); |
| if (ret) { |
| printf("Error updating EEPROM at addr 0x%x\n", |
| CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR); |
| return -1; |
| } |
| |
| printf("done (dump via 'i2c md %x 0.1 %x')\n", |
| CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR, |
| CONFIG_4xx_CONFIG_BLOCKSIZE); |
| printf("Reset the board for the changes to" |
| " take effect\n"); |
| return 0; |
| } |
| } |
| |
| printf("Configuration %s not found!\n", argv[1]); |
| print_configs(cur_config_nr); |
| return -1; |
| } |
| |
| U_BOOT_CMD( |
| chip_config, 2, 0, do_chip_config, |
| "program the I2C bootstrap EEPROM", |
| "[config-label]" |
| ); |