diff options
Diffstat (limited to 'board/freescale/p1010rdb/p1010rdb.c')
| -rw-r--r-- | board/freescale/p1010rdb/p1010rdb.c | 330 | 
1 files changed, 275 insertions, 55 deletions
| diff --git a/board/freescale/p1010rdb/p1010rdb.c b/board/freescale/p1010rdb/p1010rdb.c index 06aa8009b..e940d2275 100644 --- a/board/freescale/p1010rdb/p1010rdb.c +++ b/board/freescale/p1010rdb/p1010rdb.c @@ -21,10 +21,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; @@ -33,10 +31,30 @@ 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 + +enum { +	MUX_TYPE_IFC, +	MUX_TYPE_SDHC, +	MUX_TYPE_SPIFLASH, +	MUX_TYPE_TDM, +	MUX_TYPE_CAN, +	MUX_TYPE_CS0_NOR, +	MUX_TYPE_CS0_NAND, +}; + +enum { +	I2C_READ_BANK, +	I2C_READ_PCB_VER, +}; + +static uint sd_ifc_mux; -#ifndef CONFIG_SDCARD  struct cpld_data {  	u8 cpld_ver; /* cpld revision */ +#if defined(CONFIG_P1010RDB_PA)  	u8 pcba_ver; /* pcb revision number */  	u8 twindie_ddr3;  	u8 res1[6]; @@ -51,53 +69,18 @@ struct cpld_data {  	u8 por1; /* POR Options */  	u8 por2; /* POR Options */  	u8 por3; /* POR Options */ -}; - -void cpld_show(void) -{ -	struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); - -	printf("CPLD: V%x.%x PCBA: V%x.0\n", -		in_8(&cpld_data->cpld_ver) & 0xF0, -		in_8(&cpld_data->cpld_ver) & 0x0F, -		in_8(&cpld_data->pcba_ver) & 0x0F); - -#ifdef CONFIG_DEBUG -	printf("twindie_ddr =%x\n", -		in_8(&cpld_data->twindie_ddr3)); -	printf("bank_sel =%x\n", -		in_8(&cpld_data->bank_sel)); -	printf("usb2_sel =%x\n", -		in_8(&cpld_data->usb2_sel)); -	printf("porsw_sel =%x\n", -		in_8(&cpld_data->porsw_sel)); -	printf("tdm_can_sel =%x\n", -		in_8(&cpld_data->tdm_can_sel)); -	printf("tdm_can_sel =%x\n", -		in_8(&cpld_data->tdm_can_sel)); -	printf("spi_cs0_sel =%x\n", -		in_8(&cpld_data->spi_cs0_sel)); -	printf("bcsr0 =%x\n", -		in_8(&cpld_data->bcsr0)); -	printf("bcsr1 =%x\n", -		in_8(&cpld_data->bcsr1)); -	printf("bcsr2 =%x\n", -		in_8(&cpld_data->bcsr2)); -	printf("bcsr3 =%x\n", -		in_8(&cpld_data->bcsr3)); -#endif -} +#elif defined(CONFIG_P1010RDB_PB) +	u8 rom_loc;  #endif +};  int board_early_init_f(void)  {  	ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR); -#ifndef CONFIG_SDCARD  	struct fsl_ifc *ifc = (void *)CONFIG_SYS_IFC_ADDR;  	/* Clock configuration to access CPLD using IFC(GPCM) */  	setbits_be32(&ifc->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT); -#endif  	/*  	* Reset PCIe slots via GPIO4  	*/ @@ -109,7 +92,6 @@ int board_early_init_f(void)  int board_early_init_r(void)  { -#ifndef CONFIG_SDCARD  	const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;  	const u8 flash_esel = find_tlb_idx((void *)flashbase, 1); @@ -133,7 +115,6 @@ int board_early_init_r(void)  			CONFIG_SYS_FLASH_BASE_PHYS + 0x1000000,  			MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,  			0, flash_esel+1, BOOKE_PAGESZ_16M, 1); -#endif  	return 0;  } @@ -144,13 +125,199 @@ void pci_init_board(void)  }  #endif /* ifdef CONFIG_PCI */ +int config_board_mux(int ctrl_type) +{ +	ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); +	u8 tmp; + +#if defined(CONFIG_P1010RDB_PA) +	struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); + +	switch (ctrl_type) { +	case MUX_TYPE_IFC: +		i2c_set_bus_num(I2C_PCA9557_BUS_NUM); +		tmp = 0xf0; +		i2c_write(I2C_PCA9557_ADDR1, 3, 1, &tmp, 1); +		tmp = 0x01; +		i2c_write(I2C_PCA9557_ADDR1, 1, 1, &tmp, 1); +		sd_ifc_mux = MUX_TYPE_IFC; +		clrbits_be32(&gur->pmuxcr, PMUXCR1_IFC_MASK); +		break; +	case MUX_TYPE_SDHC: +		i2c_set_bus_num(I2C_PCA9557_BUS_NUM); +		tmp = 0xf0; +		i2c_write(I2C_PCA9557_ADDR1, 3, 1, &tmp, 1); +		tmp = 0x05; +		i2c_write(I2C_PCA9557_ADDR1, 1, 1, &tmp, 1); +		sd_ifc_mux = MUX_TYPE_SDHC; +		clrsetbits_be32(&gur->pmuxcr, PMUXCR1_SDHC_MASK, +				PMUXCR1_SDHC_ENABLE); +		break; +	case MUX_TYPE_SPIFLASH: +		out_8(&cpld_data->spi_cs0_sel, MUX_CPLD_SPICS0_FLASH); +		break; +	case MUX_TYPE_TDM: +		out_8(&cpld_data->tdm_can_sel, MUX_CPLD_TDM); +		out_8(&cpld_data->spi_cs0_sel, MUX_CPLD_SPICS0_SLIC); +		break; +	case MUX_TYPE_CAN: +		out_8(&cpld_data->tdm_can_sel, MUX_CPLD_CAN_UART); +		break; +	default: +		break; +	} +#elif defined(CONFIG_P1010RDB_PB) +	uint orig_bus = i2c_get_bus_num(); +	i2c_set_bus_num(I2C_PCA9557_BUS_NUM); + +	switch (ctrl_type) { +	case MUX_TYPE_IFC: +		i2c_read(I2C_PCA9557_ADDR2, 0, 1, &tmp, 1); +		clrbits_8(&tmp, 0x04); +		i2c_write(I2C_PCA9557_ADDR2, 1, 1, &tmp, 1); +		i2c_read(I2C_PCA9557_ADDR2, 3, 1, &tmp, 1); +		clrbits_8(&tmp, 0x04); +		i2c_write(I2C_PCA9557_ADDR2, 3, 1, &tmp, 1); +		sd_ifc_mux = MUX_TYPE_IFC; +		clrbits_be32(&gur->pmuxcr, PMUXCR1_IFC_MASK); +		break; +	case MUX_TYPE_SDHC: +		i2c_read(I2C_PCA9557_ADDR2, 0, 1, &tmp, 1); +		setbits_8(&tmp, 0x04); +		i2c_write(I2C_PCA9557_ADDR2, 1, 1, &tmp, 1); +		i2c_read(I2C_PCA9557_ADDR2, 3, 1, &tmp, 1); +		clrbits_8(&tmp, 0x04); +		i2c_write(I2C_PCA9557_ADDR2, 3, 1, &tmp, 1); +		sd_ifc_mux = MUX_TYPE_SDHC; +		clrsetbits_be32(&gur->pmuxcr, PMUXCR1_SDHC_MASK, +				PMUXCR1_SDHC_ENABLE); +		break; +	case MUX_TYPE_SPIFLASH: +		i2c_read(I2C_PCA9557_ADDR2, 0, 1, &tmp, 1); +		clrbits_8(&tmp, 0x80); +		i2c_write(I2C_PCA9557_ADDR2, 1, 1, &tmp, 1); +		i2c_read(I2C_PCA9557_ADDR2, 3, 1, &tmp, 1); +		clrbits_8(&tmp, 0x80); +		i2c_write(I2C_PCA9557_ADDR2, 3, 1, &tmp, 1); +		break; +	case MUX_TYPE_TDM: +		i2c_read(I2C_PCA9557_ADDR2, 0, 1, &tmp, 1); +		setbits_8(&tmp, 0x82); +		i2c_write(I2C_PCA9557_ADDR2, 1, 1, &tmp, 1); +		i2c_read(I2C_PCA9557_ADDR2, 3, 1, &tmp, 1); +		clrbits_8(&tmp, 0x82); +		i2c_write(I2C_PCA9557_ADDR2, 3, 1, &tmp, 1); +		break; +	case MUX_TYPE_CAN: +		i2c_read(I2C_PCA9557_ADDR2, 0, 1, &tmp, 1); +		clrbits_8(&tmp, 0x02); +		i2c_write(I2C_PCA9557_ADDR2, 1, 1, &tmp, 1); +		i2c_read(I2C_PCA9557_ADDR2, 3, 1, &tmp, 1); +		clrbits_8(&tmp, 0x02); +		i2c_write(I2C_PCA9557_ADDR2, 3, 1, &tmp, 1); +		break; +	case MUX_TYPE_CS0_NOR: +		i2c_read(I2C_PCA9557_ADDR2, 0, 1, &tmp, 1); +		clrbits_8(&tmp, 0x08); +		i2c_write(I2C_PCA9557_ADDR2, 1, 1, &tmp, 1); +		i2c_read(I2C_PCA9557_ADDR2, 3, 1, &tmp, 1); +		clrbits_8(&tmp, 0x08); +		i2c_write(I2C_PCA9557_ADDR2, 3, 1, &tmp, 1); +		break; +	case MUX_TYPE_CS0_NAND: +		i2c_read(I2C_PCA9557_ADDR2, 0, 1, &tmp, 1); +		setbits_8(&tmp, 0x08); +		i2c_write(I2C_PCA9557_ADDR2, 1, 1, &tmp, 1); +		i2c_read(I2C_PCA9557_ADDR2, 3, 1, &tmp, 1); +		clrbits_8(&tmp, 0x08); +		i2c_write(I2C_PCA9557_ADDR2, 3, 1, &tmp, 1); +		break; +	default: +		break; +	} +	i2c_set_bus_num(orig_bus); +#endif +	return 0; +} + +#ifdef CONFIG_P1010RDB_PB +int i2c_pca9557_read(int type) +{ +	u8 val; + +	i2c_set_bus_num(I2C_PCA9557_BUS_NUM); +	i2c_read(I2C_PCA9557_ADDR2, 0, 1, &val, 1); + +	switch (type) { +	case I2C_READ_BANK: +		val = (val & 0x10) >> 4; +		break; +	case I2C_READ_PCB_VER: +		val = ((val & 0x60) >> 5) + 1; +		break; +	default: +		break; +	} + +	return val; +} +#endif +  int checkboard(void)  {  	struct cpu_type *cpu; +	struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); +	u8 val;  	cpu = gd->arch.cpu; -	printf("Board: %sRDB\n", cpu->name); +#if defined(CONFIG_P1010RDB_PA) +	printf("Board: %sRDB-PA, ", cpu->name); +#elif defined(CONFIG_P1010RDB_PB) +	printf("Board: %sRDB-PB, ", cpu->name); +	i2c_set_bus_num(I2C_PCA9557_BUS_NUM); +	i2c_init(CONFIG_SYS_FSL_I2C_SPEED, CONFIG_SYS_FSL_I2C_SLAVE); +	val = 0x0;  /* no polarity inversion */ +	i2c_write(I2C_PCA9557_ADDR2, 2, 1, &val, 1); +#endif +#ifdef CONFIG_SDCARD +	/* switch to IFC to read info from CPLD */ +	config_board_mux(MUX_TYPE_IFC); +#endif + +#if defined(CONFIG_P1010RDB_PA) +	val = (in_8(&cpld_data->pcba_ver) & 0xf); +	printf("PCB: v%x.0\n", val); +#elif defined(CONFIG_P1010RDB_PB) +	val = in_8(&cpld_data->cpld_ver); +	printf("CPLD: v%x.%x, ", val >> 4, val & 0xf); +	printf("PCB: v%x.0, ", i2c_pca9557_read(I2C_READ_PCB_VER)); +	val = in_8(&cpld_data->rom_loc) & 0xf; +	puts("Boot from: "); +	switch (val) { +	case 0xf: +		config_board_mux(MUX_TYPE_CS0_NOR); +		printf("NOR vBank%d\n", i2c_pca9557_read(I2C_READ_BANK)); +		break; +	case 0xe: +		puts("SDHC\n"); +		val = 0x60; /* set pca9557 pin input/output */ +		i2c_write(I2C_PCA9557_ADDR2, 3, 1, &val, 1); +		break; +	case 0x5: +		config_board_mux(MUX_TYPE_IFC); +		config_board_mux(MUX_TYPE_CS0_NAND); +		puts("NAND\n"); +		break; +	case 0x6: +		config_board_mux(MUX_TYPE_IFC); +		puts("SPI\n"); +		break; +	default: +		puts("unknown\n"); +		break; +	} +#endif  	return 0;  } @@ -246,6 +413,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; @@ -289,9 +466,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 (sd_ifc_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); @@ -309,14 +490,27 @@ void ft_board_setup(void *blob, bd_t *bd)  		fdt_del_flexcan(blob);  		fdt_disable_uart1(blob);  	} +}  #endif + +#ifdef CONFIG_SDCARD +int board_mmc_init(bd_t *bis) +{ +	config_board_mux(MUX_TYPE_SDHC); +		return -1; +} +#else +void board_reset(void) +{ +	/* mux to IFC to enable CPLD for reset */ +	if (sd_ifc_mux != MUX_TYPE_IFC) +		config_board_mux(MUX_TYPE_IFC);  }  #endif -#ifndef CONFIG_SDCARD +  int misc_init_r(void)  { -	struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);  	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);  	if (hwconfig_subarg_cmp("fsl_p1010mux", "tdm_can", "can")) { @@ -324,7 +518,7 @@ int misc_init_r(void)  				MPC85xx_PMUXCR_CAN1_UART |  				MPC85xx_PMUXCR_CAN2_TDM |  				MPC85xx_PMUXCR_CAN2_UART); -		out_8(&cpld_data->tdm_can_sel, MUX_CPLD_CAN_UART); +		config_board_mux(MUX_TYPE_CAN);  	} else if (hwconfig_subarg_cmp("fsl_p1010mux", "tdm_can", "tdm")) {  		clrbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_CAN2_UART |  				MPC85xx_PMUXCR_CAN1_UART); @@ -332,13 +526,39 @@ int misc_init_r(void)  				MPC85xx_PMUXCR_CAN1_TDM);  		clrbits_be32(&gur->pmuxcr2, MPC85xx_PMUXCR2_UART_GPIO);  		setbits_be32(&gur->pmuxcr2, MPC85xx_PMUXCR2_UART_TDM); -		out_8(&cpld_data->tdm_can_sel, MUX_CPLD_TDM); -		out_8(&cpld_data->spi_cs0_sel, MUX_CPLD_SPICS0_SLIC); +		config_board_mux(MUX_TYPE_TDM);  	} else {  		/* defaultly spi_cs_sel to flash */ -		out_8(&cpld_data->spi_cs0_sel, MUX_CPLD_SPICS0_FLASH); +		config_board_mux(MUX_TYPE_SPIFLASH);  	} +	if (hwconfig("esdhc")) +		config_board_mux(MUX_TYPE_SDHC); +	else if (hwconfig("ifc")) +		config_board_mux(MUX_TYPE_IFC); + +#ifdef CONFIG_P1010RDB_PB +	setbits_be32(&gur->pmuxcr2, MPC85xx_PMUXCR2_GPIO01_DRVVBUS); +#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_board_mux(MUX_TYPE_IFC); +	else if (strcmp(argv[1], "sdhc") == 0) +		config_board_mux(MUX_TYPE_SDHC); +	else +		return CMD_RET_USAGE; +	return 0; +} + +U_BOOT_CMD( +	mux, 2, 0, pin_mux_cmd, +	"configure multiplexing pin for IFC/SDHC bus in runtime", +	"bus_type (e.g. mux sdhc)" +); |