[U-Boot] [PATCH v2] board/p1010rdb: add pin mux and sdhc support in any boot

SDHC pins are multiplexed with IFC and ULPI interfaces. This patch intends to enable SDHC function in case of NOR/NAND/SPI boot aside from SD boot.
If "esdhc" is configured in hwconfig, u-boot will configure multiplexing pins from default IFC to SDHC at runtime to enable SD function. And add minimal necessary mux command for ifc/sdhc/ulpi to conveniently configure multiplexing pins without reboot or updating u-boot.
Signed-off-by: Shengzhou Liu Shengzhou.Liu@freescale.com --- v2: updated description.
board/freescale/p1010rdb/p1010rdb.c | 128 +++++++++++++++++++++++++++++++++--- include/configs/P1010RDB.h | 11 ++-- 2 files changed, 125 insertions(+), 14 deletions(-)
diff --git a/board/freescale/p1010rdb/p1010rdb.c b/board/freescale/p1010rdb/p1010rdb.c index 0c30d76..5a2f1f0 100644 --- a/board/freescale/p1010rdb/p1010rdb.c +++ b/board/freescale/p1010rdb/p1010rdb.c @@ -37,10 +37,8 @@ #include <asm/fsl_serdes.h> #include <asm/fsl_ifc.h> #include <asm/fsl_pci.h> - -#ifndef CONFIG_SDCARD #include <hwconfig.h> -#endif +#include <i2c.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -49,6 +47,19 @@ DECLARE_GLOBAL_DATA_PTR; #define MUX_CPLD_TDM 0x01 #define MUX_CPLD_SPICS0_FLASH 0x00 #define MUX_CPLD_SPICS0_SLIC 0x02 +#define PMUXCR1_IFC_MASK 0x00ffff00 +#define PMUXCR1_SDHC_MASK 0x00fff000 +#define PMUXCR1_SDHC_ENABLE 0x00555000 +#define PMUXCR1_ULPI_MASK 0x00ffffc0 +#define PMUXCR1_ULPI_ENABLE 0x00aaaa80 + +enum { + MUX_TYPE_IFC, + MUX_TYPE_SDHC, + MUX_TYPE_ULPI, +}; + +uint pin_mux;
#ifndef CONFIG_SDCARD struct cpld_data { @@ -262,6 +273,16 @@ void fdt_del_sdhc(void *blob) } }
+void fdt_del_ifc(void *blob) +{ + int nodeoff = 0; + + while ((nodeoff = fdt_node_offset_by_compatible(blob, 0, + "fsl,ifc")) >= 0) { + fdt_del_node(blob, nodeoff); + } +} + void fdt_disable_uart1(void *blob) { int nodeoff; @@ -305,9 +326,13 @@ void ft_board_setup(void *blob, bd_t *bd) fdt_del_flexcan(blob); fdt_del_node_and_alias(blob, "ethernet2"); } -#ifndef CONFIG_SDCARD - /* disable sdhc due to sdhc bug */ - fdt_del_sdhc(blob); + + /* Delete IFC node as IFC pins are multiplexing with SDHC */ + if (pin_mux != MUX_TYPE_IFC) + fdt_del_ifc(blob); + else + fdt_del_sdhc(blob); + if (hwconfig_subarg_cmp("fsl_p1010mux", "tdm_can", "can")) { fdt_del_tdm(blob); fdt_del_spi_slic(blob); @@ -325,13 +350,72 @@ void ft_board_setup(void *blob, bd_t *bd) fdt_del_flexcan(blob); fdt_disable_uart1(blob); } -#endif } #endif
+int config_pin_mux(int if_type) +{ + ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + u8 tmp; + uint orig_bus = i2c_get_bus_num(); + + i2c_set_bus_num(CONFIG_SYS_PCA9557_BUS_NUM); + tmp = 0xf0; + if (i2c_write(CONFIG_SYS_I2C_PCA9557_ADDR, 3, 1, &tmp, 1) < 0) + goto wr_err; + + switch (if_type) { + case MUX_TYPE_IFC: + tmp = 0x01; + if (i2c_write(CONFIG_SYS_I2C_PCA9557_ADDR, 1, 1, &tmp, 1) < 0) + goto wr_err; + pin_mux = MUX_TYPE_IFC; + clrbits_be32(&gur->pmuxcr, PMUXCR1_IFC_MASK); + debug("pin mux is configured for IFC, SDHC disabled\n"); + break; + case MUX_TYPE_SDHC: + tmp = 0x05; + if (i2c_write(CONFIG_SYS_I2C_PCA9557_ADDR, 1, 1, &tmp, 1) < 0) + goto wr_err; + pin_mux = MUX_TYPE_SDHC; + clrsetbits_be32(&gur->pmuxcr, PMUXCR1_SDHC_MASK, + PMUXCR1_SDHC_ENABLE); + debug("pin mux is configured for SDHC, IFC disabled\n"); + break; + case MUX_TYPE_ULPI: + tmp = 0x06; + if (i2c_write(CONFIG_SYS_I2C_PCA9557_ADDR, 1, 1, &tmp, 1) < 0) + goto wr_err; + pin_mux = MUX_TYPE_ULPI; + clrsetbits_be32(&gur->pmuxcr, PMUXCR1_ULPI_MASK, + PMUXCR1_ULPI_ENABLE); + debug("pin mux is configured for ULPI, IFC & SDHC disabled\n"); + break; + default: + printf("wrong mux interface type\n"); + i2c_set_bus_num(orig_bus); + return -1; + } + i2c_set_bus_num(orig_bus); + return 0; +wr_err: + printf("pca9557: i2c write failed\n"); + i2c_set_bus_num(orig_bus); + return -1; +} + #ifndef CONFIG_SDCARD +void board_reset(void) +{ + /* mux to IFC to enable CPLD for reset */ + if (pin_mux != MUX_TYPE_IFC) + config_pin_mux(MUX_TYPE_IFC); +} +#endif + int misc_init_r(void) { +#ifndef CONFIG_SDCARD struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
@@ -355,6 +439,34 @@ int misc_init_r(void) out_8(&cpld_data->spi_cs0_sel, MUX_CPLD_SPICS0_FLASH); }
+ if (hwconfig("esdhc")) { + pin_mux = MUX_TYPE_SDHC; + config_pin_mux(MUX_TYPE_SDHC); + } +#else + pin_mux = MUX_TYPE_SDHC; +#endif return 0; } -#endif + +static int pin_mux_cmd(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + if (argc < 2) + return CMD_RET_USAGE; + if (strcmp(argv[1], "ifc") == 0) + config_pin_mux(MUX_TYPE_IFC); + else if (strcmp(argv[1], "sdhc") == 0) + config_pin_mux(MUX_TYPE_SDHC); + else if (strcmp(argv[1], "ulpi") == 0) + config_pin_mux(MUX_TYPE_ULPI); + else + return CMD_RET_USAGE; + return 0; +} + +U_BOOT_CMD( + mux, 2, 0, pin_mux_cmd, + "configure multiplexing pin for IFC/SDHC/ULPI buses", + "bus_type[ifc/sdhc/ulpi] (e.g. mux sdhc)" +); diff --git a/include/configs/P1010RDB.h b/include/configs/P1010RDB.h index 5185597..259bb6a 100644 --- a/include/configs/P1010RDB.h +++ b/include/configs/P1010RDB.h @@ -156,11 +156,9 @@ #define CONFIG_DDR_CLK_FREQ 66666666 /* DDRCLK on P1010 RDB */ #define CONFIG_SYS_CLK_FREQ 66666666 /* SYSCLK for P1010 RDB */
-#ifndef CONFIG_SDCARD #define CONFIG_MISC_INIT_R -#endif - #define CONFIG_HWCONFIG + /* * These can be toggled for performance analysis, otherwise use default. */ @@ -485,6 +483,8 @@ extern unsigned long get_sdram_size(void); #define CONFIG_SYS_I2C_SLAVE 0x7F #define CONFIG_SYS_I2C_OFFSET 0x3000 #define CONFIG_SYS_I2C2_OFFSET 0x3100 +#define CONFIG_SYS_I2C_PCA9557_ADDR 0x18 +#define CONFIG_SYS_PCA9557_BUS_NUM 0
/* I2C EEPROM */ #undef CONFIG_ID_EEPROM @@ -570,11 +570,10 @@ extern unsigned long get_sdram_size(void); #define CONFIG_LBA48 #endif /* #ifdef CONFIG_FSL_SATA */
-/* SD interface will only be available in case of SD boot */ #ifdef CONFIG_SDCARD -#define CONFIG_MMC -#define CONFIG_DEF_HWCONFIG esdhc +#define CONFIG_DEF_HWCONFIG esdhc #endif +#define CONFIG_MMC
#ifdef CONFIG_MMC #define CONFIG_CMD_MMC

On Sun, Jun 16, 2013 at 9:32 PM, Shengzhou Liu Shengzhou.Liu@freescale.comwrote:
SDHC pins are multiplexed with IFC and ULPI interfaces. This patch intends to enable SDHC function in case of NOR/NAND/SPI boot aside from SD boot.
If "esdhc" is configured in hwconfig, u-boot will configure multiplexing pins from default IFC to SDHC at runtime to enable SD function. And add minimal necessary mux command for ifc/sdhc/ulpi to conveniently configure multiplexing pins without reboot or updating u-boot.
Signed-off-by: Shengzhou Liu Shengzhou.Liu@freescale.com
v2: updated description.
board/freescale/p1010rdb/p1010rdb.c | 128 +++++++++++++++++++++++++++++++++--- include/configs/P1010RDB.h | 11 ++-- 2 files changed, 125 insertions(+), 14 deletions(-)
diff --git a/board/freescale/p1010rdb/p1010rdb.c b/board/freescale/p1010rdb/p1010rdb.c index 0c30d76..5a2f1f0 100644 --- a/board/freescale/p1010rdb/p1010rdb.c +++ b/board/freescale/p1010rdb/p1010rdb.c
+static int pin_mux_cmd(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
+{
if (argc < 2)
return CMD_RET_USAGE;
if (strcmp(argv[1], "ifc") == 0)
config_pin_mux(MUX_TYPE_IFC);
else if (strcmp(argv[1], "sdhc") == 0)
config_pin_mux(MUX_TYPE_SDHC);
else if (strcmp(argv[1], "ulpi") == 0)
config_pin_mux(MUX_TYPE_ULPI);
else
return CMD_RET_USAGE;
return 0;
+}
+U_BOOT_CMD(
mux, 2, 0, pin_mux_cmd,
"configure multiplexing pin for IFC/SDHC/ULPI buses",
"bus_type[ifc/sdhc/ulpi] (e.g. mux sdhc)"
This command name is very generic, but the command is highly-specific to this board. Ideally, you'd come up with code that could be reused by other boards that have similar issues. It should be fairly straightforward to implement a version of this code which allowed arbitrary pin muxing code to register with a name. It would require some discussion on the list. If you're not willing to do that, at least rename the command so it's clear it is just for this board.
Andy
participants (2)
-
Andy Fleming
-
Shengzhou Liu