From patchwork Fri Aug 8 05:35:45 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tim Harvey X-Patchwork-Id: 378061 X-Patchwork-Delegate: sbabic@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 58BE514011B for ; Fri, 8 Aug 2014 15:42:39 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 06D73A770B; Fri, 8 Aug 2014 07:42:37 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id vUm1qEqchSqK; Fri, 8 Aug 2014 07:42:36 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id C7924A756A; Fri, 8 Aug 2014 07:42:34 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 168A1A7534 for ; Fri, 8 Aug 2014 07:42:32 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 1dJfoMmwmZGr for ; Fri, 8 Aug 2014 07:42:28 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-pa0-f45.google.com (mail-pa0-f45.google.com [209.85.220.45]) by theia.denx.de (Postfix) with ESMTPS id A018DA770A for ; Fri, 8 Aug 2014 07:42:14 +0200 (CEST) Received: by mail-pa0-f45.google.com with SMTP id eu11so6697692pac.32 for ; Thu, 07 Aug 2014 22:42:13 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=GgA3AVbbW/qaj/o2YLqe0Ph71qfWGMy/+QzxQo4oRGg=; b=DhYPh6lAf4fFRMKdOjDUaJZDPeCiFA2zoLiIXC/rv/kWyHEjH8gmgVPlUxtiul8HOh o9AR+beRrciynA/fLPms7PdaMlpTWzBtX+PQ/cKhGrr+tOlTqgH4hfCslWYnbkjjZ2rS ns8qkP8VkMcVeFyHtEOl4RX7zM0oGw6zq50wE7en3zyMwYRJLTFOpVTMKKhWPfS2qHg1 WofiUGHYTkdCh91dUPjoFHI8YO9tTrI7aVVZ6VEJj/CUsoI3ySS0mkhNjp/Jo4hbfws2 fvETU8R/ABmps5dhc7g2ZbjQ2V1pcnmRrUupF194+HrrG/8JAzg95FQM2cWtK5DYa6vq YdiA== X-Gm-Message-State: ALoCoQkZG7WR/QbpNK9b8ZCSF8QjqdDSTl6ZQENI5rZpCUAoQd+YdVJUT5U40Km0yC0xvFrtSP9r X-Received: by 10.70.33.161 with SMTP id s1mr22190603pdi.10.1407476164953; Thu, 07 Aug 2014 22:36:04 -0700 (PDT) Received: from tharvey-gw.gw (68-189-91-139.static.snlo.ca.charter.com. [68.189.91.139]) by mx.google.com with ESMTPSA id m5sm733251pde.17.2014.08.07.22.36.04 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 07 Aug 2014 22:36:04 -0700 (PDT) From: Tim Harvey To: Stefano Babic Date: Thu, 7 Aug 2014 22:35:45 -0700 Message-Id: <1407476151-5603-6-git-send-email-tharvey@gateworks.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1407476151-5603-1-git-send-email-tharvey@gateworks.com> References: <1407476151-5603-1-git-send-email-tharvey@gateworks.com> Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH 05/11] imx: ventana: add econfig command X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de The Gateworks Ventana EEPROM contains a set of configuration bits that affect the removal of device-tree nodes that support peripherals that do not exist on sub-loaded boards. This patch adds: - a structure to define a config bit name, dt node alias, bit position - an array of supported configuration items - an econfig command to get/set/list configuration bits - use of the array when adjusting the FDT prior to boot Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/eeprom.c | 168 +++++++++++++++++++++++++++- board/gateworks/gw_ventana/gw_ventana.c | 100 +++-------------- board/gateworks/gw_ventana/ventana_eeprom.h | 11 ++ include/configs/gw_ventana.h | 5 +- 4 files changed, 198 insertions(+), 86 deletions(-) diff --git a/board/gateworks/gw_ventana/eeprom.c b/board/gateworks/gw_ventana/eeprom.c index e90186e..3edc915 100644 --- a/board/gateworks/gw_ventana/eeprom.c +++ b/board/gateworks/gw_ventana/eeprom.c @@ -6,7 +6,10 @@ */ #include +#include #include +#include +#include #include "gsc.h" #include "ventana_eeprom.h" @@ -38,14 +41,12 @@ read_eeprom(int bus, struct ventana_board_info *info) /* read eeprom config section */ if (gsc_i2c_read(GSC_EEPROM_ADDR, 0x00, 1, buf, sizeof(*info))) { puts("EEPROM: Failed to read EEPROM\n"); - info->model[0] = 0; return GW_UNKNOWN; } /* sanity checks */ if (info->model[0] != 'G' || info->model[1] != 'W') { puts("EEPROM: Invalid Model in EEPROM\n"); - info->model[0] = 0; return GW_UNKNOWN; } @@ -55,7 +56,6 @@ read_eeprom(int bus, struct ventana_board_info *info) if ((info->chksum[0] != chksum>>8) || (info->chksum[1] != (chksum&0xff))) { puts("EEPROM: Failed EEPROM checksum\n"); - info->model[0] = 0; return GW_UNKNOWN; } @@ -87,3 +87,165 @@ read_eeprom(int bus, struct ventana_board_info *info) } return type; } + +/* list of config bits that the bootloader will remove from dtb if not set */ +struct ventana_eeprom_config econfig[] = { + { "eth0", "ethernet0", EECONFIG_ETH0 }, + { "eth1", "ethernet1", EECONFIG_ETH1 }, + { "sata", "ahci0", EECONFIG_SATA }, + { "pcie", NULL, EECONFIG_PCIE}, + { "lvds0", NULL, EECONFIG_LVDS0 }, + { "lvds1", NULL, EECONFIG_LVDS1 }, + { "usb0", NULL, EECONFIG_USB0 }, + { "usb1", NULL, EECONFIG_USB1 }, + { "mmc0", NULL, EECONFIG_SD0 }, + { "mmc1", NULL, EECONFIG_SD1 }, + { "mmc2", NULL, EECONFIG_SD2 }, + { "mmc3", NULL, EECONFIG_SD3 }, + { "uart0", NULL, EECONFIG_UART0 }, + { "uart1", NULL, EECONFIG_UART1 }, + { "uart2", NULL, EECONFIG_UART2 }, + { "uart3", NULL, EECONFIG_UART3 }, + { "uart4", NULL, EECONFIG_UART4 }, + { "ipu0", NULL, EECONFIG_IPU0 }, + { "ipu1", NULL, EECONFIG_IPU1 }, + { "can0", NULL, EECONFIG_FLEXCAN }, + { "i2c0", NULL, EECONFIG_I2C0 }, + { "i2c1", NULL, EECONFIG_I2C1 }, + { "i2c2", NULL, EECONFIG_I2C2 }, + { "vpu", NULL, EECONFIG_VPU }, + { "csi0", NULL, EECONFIG_CSI0 }, + { "csi1", NULL, EECONFIG_CSI1 }, + { "spi0", NULL, EECONFIG_ESPCI0 }, + { "spi1", NULL, EECONFIG_ESPCI1 }, + { "spi2", NULL, EECONFIG_ESPCI2 }, + { "spi3", NULL, EECONFIG_ESPCI3 }, + { "spi4", NULL, EECONFIG_ESPCI4 }, + { "spi5", NULL, EECONFIG_ESPCI5 }, + { "gps", "pps", EECONFIG_GPS }, + { "hdmi_in", NULL, EECONFIG_HDMI_IN }, + { "hdmi_out", NULL, EECONFIG_HDMI_OUT }, + { "cvbs_in", NULL, EECONFIG_VID_IN }, + { "cvbs_out", NULL, EECONFIG_VID_OUT }, + { "nand", NULL, EECONFIG_NAND }, + { /* Sentinel */ } +}; + +#ifdef CONFIG_CMD_EECONFIG +static struct ventana_eeprom_config *get_config(const char *name) +{ + struct ventana_eeprom_config *cfg = econfig; + + while (cfg->name) { + if (0 == strcmp(name, cfg->name)) + return cfg; + cfg++; + } + return NULL; +} + +static u8 econfig_bytes[sizeof(ventana_info.config)]; +static int econfig_init = -1; + +int do_econfig(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + struct ventana_eeprom_config *cfg; + struct ventana_board_info *info = &ventana_info; + int i; + + if (argc < 2) + return CMD_RET_USAGE; + + /* initialize */ + if (econfig_init != 1) { + memcpy(econfig_bytes, info->config, sizeof(econfig_bytes)); + econfig_init = 1; + } + + /* list configs */ + if ((strncmp(argv[1], "list", 4) == 0)) { + cfg = econfig; + while (cfg->name) { + printf("%s: %d\n", cfg->name, + test_bit(cfg->bit, econfig_bytes) ? 1 : 0); + cfg++; + } + } + + /* save */ + else if ((strncmp(argv[1], "save", 4) == 0)) { + unsigned char *buf = (unsigned char *)info; + int chksum; + + /* calculate new checksum */ + memcpy(info->config, econfig_bytes, sizeof(econfig_bytes)); + for (chksum = 0, i = 0; i < sizeof(*info)-2; i++) + chksum += buf[i]; + debug("old chksum:0x%04x\n", + (info->chksum[0] << 8) | info->chksum[1]); + debug("new chksum:0x%04x\n", chksum); + info->chksum[0] = chksum >> 8; + info->chksum[1] = chksum & 0xff; + + /* write new config data */ + if (gsc_i2c_write(GSC_EEPROM_ADDR, info->config - (u8 *)info, + 1, econfig_bytes, sizeof(econfig_bytes))) { + printf("EEPROM: Failed updating config\n"); + return CMD_RET_FAILURE; + } + + /* write new config data */ + if (gsc_i2c_write(GSC_EEPROM_ADDR, info->chksum - (u8 *)info, + 1, info->chksum, 2)) { + printf("EEPROM: Failed updating checksum\n"); + return CMD_RET_FAILURE; + } + + printf("Config saved to EEPROM\n"); + } + + /* get config */ + else if (argc == 2) { + cfg = get_config(argv[1]); + if (cfg) { + printf("%s: %d\n", cfg->name, + test_bit(cfg->bit, econfig_bytes) ? 1 : 0); + } else { + printf("invalid config: %s\n", argv[1]); + return CMD_RET_FAILURE; + } + } + + /* set config */ + else if (argc == 3) { + cfg = get_config(argv[1]); + if (cfg) { + if (simple_strtol(argv[2], NULL, 10)) { + test_and_set_bit(cfg->bit, econfig_bytes); + printf("Enabled %s\n", cfg->name); + } else { + test_and_clear_bit(cfg->bit, econfig_bytes); + printf("Disabled %s\n", cfg->name); + } + } else { + printf("invalid config: %s\n", argv[1]); + return CMD_RET_FAILURE; + } + } + + else + return CMD_RET_USAGE; + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD( + econfig, 3, 0, do_econfig, + "EEPROM configuration", + "list - list config\n" + "save - save config to EEPROM\n" + " - get config 'name'\n" + " [0|1] - set config 'name' to value\n" +); + +#endif /* CONFIG_CMD_EECONFIG */ diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c index b35fe5a..9857a05 100644 --- a/board/gateworks/gw_ventana/gw_ventana.c +++ b/board/gateworks/gw_ventana/gw_ventana.c @@ -50,10 +50,6 @@ DECLARE_GLOBAL_DATA_PTR; #define GP_RS232_EN IMX_GPIO_NR(2, 11) #define GP_MSATA_SEL IMX_GPIO_NR(2, 8) -/* I2C bus numbers */ -#define I2C_GSC 0 -#define I2C_PMIC 1 - #define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) @@ -82,7 +78,7 @@ DECLARE_GLOBAL_DATA_PTR; * EEPROM board info struct populated by read_eeprom so that we only have to * read it once. */ -static struct ventana_board_info ventana_info; +struct ventana_board_info ventana_info; int board_type; @@ -902,7 +898,7 @@ int power_init_board(void) /* configure PFUZE100 PMIC */ if (board_type == GW54xx || board_type == GW54proto) { - power_pfuze100_init(I2C_PMIC); + power_pfuze100_init(CONFIG_I2C_PMIC); p = pmic_get("PFUZE100_PMIC"); if (p && !pmic_probe(p)) { pmic_reg_read(p, PFUZE100_DEVICEID, ®); @@ -924,7 +920,7 @@ int power_init_board(void) /* configure LTC3676 PMIC */ else { - power_ltc3676_init(I2C_PMIC); + power_ltc3676_init(CONFIG_I2C_PMIC); p = pmic_get("LTC3676_PMIC"); if (p && !pmic_probe(p)) { puts("PMIC: LTC3676\n"); @@ -1152,7 +1148,7 @@ int board_init(void) setup_sata(); #endif /* read Gateworks EEPROM into global struct (used later) */ - board_type = read_eeprom(I2C_GSC, &ventana_info); + board_type = read_eeprom(CONFIG_I2C_GSC, &ventana_info); /* board-specifc GPIO iomux */ SETUP_IOMUX_PADS(gw_gpio_pads); @@ -1200,7 +1196,7 @@ int checkboard(void) return 0; /* Display GSC firmware revision/CRC/status */ - i2c_set_bus_num(I2C_GSC); + i2c_set_bus_num(CONFIG_I2C_GSC); if (!gsc_i2c_read(GSC_SC_ADDR, GSC_SC_FWVER, 1, buf, 1)) { printf("GSC: v%d", buf[0]); if (!gsc_i2c_read(GSC_SC_ADDR, GSC_SC_STATUS, 1, buf, 4)) { @@ -1331,7 +1327,7 @@ int misc_init_r(void) * * Disable the boot watchdog and display/clear the timeout flag if set */ - i2c_set_bus_num(I2C_GSC); + i2c_set_bus_num(CONFIG_I2C_GSC); if (!gsc_i2c_read(GSC_SC_ADDR, GSC_SC_CTRL1, 1, ®, 1)) { reg |= (1 << GSC_SC_CTRL1_WDDIS); if (gsc_i2c_write(GSC_SC_ADDR, GSC_SC_CTRL1, 1, ®, 1)) @@ -1352,74 +1348,6 @@ int misc_init_r(void) #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) -/* FDT aliases associated with EEPROM config bits */ -const char *fdt_aliases[] = { - "ethernet0", - "ethernet1", - "hdmi_out", - "ahci0", - "pcie", - "ssi0", - "ssi1", - "lcd0", - "lvds0", - "lvds1", - "usb0", - "usb1", - "mmc0", - "mmc1", - "mmc2", - "mmc3", - "uart0", - "uart1", - "uart2", - "uart3", - "uart4", - "ipu0", - "ipu1", - "can0", - "mipi_dsi", - "mipi_csi", - "tzasc0", - "tzasc1", - "i2c0", - "i2c1", - "i2c2", - "vpu", - "csi0", - "csi1", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "spi0", - "spi1", - "spi2", - "spi3", - "spi4", - "spi5", - NULL, - NULL, - "pps", - NULL, - NULL, - NULL, - "hdmi_in", - "cvbs_out", - "cvbs_in", - "nand", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -}; - /* * called prior to booting kernel or by 'fdt boardsetup' command * @@ -1431,8 +1359,8 @@ const char *fdt_aliases[] = { */ void ft_board_setup(void *blob, bd_t *bd) { - int bit; struct ventana_board_info *info = &ventana_info; + struct ventana_eeprom_config *cfg; struct node_info nodes[] = { { "sst,w25q256", MTD_DEV_TYPE_NOR, }, /* SPI flash */ { "fsl,imx6q-gpmi-nand", MTD_DEV_TYPE_NAND, }, /* NAND flash */ @@ -1467,9 +1395,17 @@ void ft_board_setup(void *blob, bd_t *bd) * remove nodes by alias path if EEPROM config tells us the * peripheral is not loaded on the board. */ - for (bit = 0; bit < 64; bit++) { - if (!test_bit(bit, info->config)) - fdt_del_node_and_alias(blob, fdt_aliases[bit]); + if (getenv("fdt_noconfig")) { + puts(" Skiping periperhal config (fdt_noconfig defined)\n"); + return; + } + cfg = econfig; + while (cfg->name) { + if (!test_bit(cfg->bit, info->config)) { + fdt_del_node_and_alias(blob, cfg->dtalias ? + cfg->dtalias : cfg->name); + } + cfg++; } } #endif /* defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) */ diff --git a/board/gateworks/gw_ventana/ventana_eeprom.h b/board/gateworks/gw_ventana/ventana_eeprom.h index 5b065be..d64b910 100644 --- a/board/gateworks/gw_ventana/ventana_eeprom.h +++ b/board/gateworks/gw_ventana/ventana_eeprom.h @@ -110,8 +110,19 @@ enum { GW53xx, GW54xx, GW_UNKNOWN, + GW_BADCRC, }; +/* config items */ +struct ventana_eeprom_config { + const char *name; /* name of item */ + const char *dtalias; /* name of dt node to remove if not set */ + int bit; /* bit within config */ +}; + +extern struct ventana_eeprom_config econfig[]; +extern struct ventana_board_info ventana_info; + int read_eeprom(int bus, struct ventana_board_info *); #endif diff --git a/include/configs/gw_ventana.h b/include/configs/gw_ventana.h index 8197a72..b991b09 100644 --- a/include/configs/gw_ventana.h +++ b/include/configs/gw_ventana.h @@ -95,7 +95,9 @@ #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC -#define CONFIG_SYS_I2C_SPEED 100000 +#define CONFIG_SYS_I2C_SPEED 100000 +#define CONFIG_I2C_GSC 0 +#define CONFIG_I2C_PMIC 1 /* MMC Configs */ #define CONFIG_FSL_ESDHC @@ -164,6 +166,7 @@ #define CONFIG_CMD_SETEXPR #define CONFIG_CMD_BOOTZ #define CONFIG_CMD_GSC +#define CONFIG_CMD_EECONFIG /* Gateworks EEPROM config cmd */ #define CONFIG_CMD_UBI #define CONFIG_RBTREE #define CONFIG_LZO