From 94110ce24f2260db96bd2d41b2466d1c6f833a3b Mon Sep 17 00:00:00 2001 From: "Ye.Li" Date: Thu, 17 Dec 2015 11:39:09 +0800 Subject: MLK-12034 imx: mx7dsabresd: Add RevB board support Since i.MX7D SDB revB board has some HW changes, we have modify the BSP file to support new pinmux. 1. OTG2 PWR pin is changed to GPIO1_IO07. 2. A enet2_en pin is added for isolating enet2 signals with EPDC, we also add support for enet2. 3. pin6 of 74LV output is changed for CSI PWDN. Set output to high to power down it. This patch also tries to get the board id and apply changes according with it. Since current RevB board does not burn GP1 fuse for board id, we have to check the TO rev instead even it is not very exact. Will update this if any new way implemented. Signed-off-by: Ye.Li --- board/freescale/mx7dsabresd/mx7dsabresd.c | 189 +++++++++++++++++++++++------- 1 file changed, 148 insertions(+), 41 deletions(-) (limited to 'board') diff --git a/board/freescale/mx7dsabresd/mx7dsabresd.c b/board/freescale/mx7dsabresd/mx7dsabresd.c index 59fb352..b6123b9 100644 --- a/board/freescale/mx7dsabresd/mx7dsabresd.c +++ b/board/freescale/mx7dsabresd/mx7dsabresd.c @@ -277,6 +277,49 @@ void iox74lv_set(int index) gpio_direction_output(IOX_STCP, 1); }; +#define BOARD_REV_B 0x200 +#define BOARD_REV_A 0x100 + +static int mx7sabre_rev(void) +{ + /* + * Get Board ID information from OCOTP_GP1[15:8] + * i.MX7D SDB RevA: 0x41 + * i.MX7D SDB RevB: 0x42 + */ + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; + struct fuse_bank *bank = &ocotp->bank[14]; + int reg = readl(&bank->fuse_regs[0]); + int ret; + + if (reg != 0) { + switch (reg >> 8 & 0x0F) { + case 0x02: + ret = BOARD_REV_B; + break; + case 0x01: + default: + ret = BOARD_REV_A; + break; + } + } else { + /* If the gp1 fuse is not burn, we have to use TO rev for the board rev */ + if (0 == is_soc_rev(CHIP_REV_1_0)) + ret = BOARD_REV_A; + else + ret = BOARD_REV_B; + } + + return ret; +} + +u32 get_board_rev(void) +{ + int rev = mx7sabre_rev(); + + return (get_cpu_rev() & ~(0xF << 8)) | rev; +} + #ifdef CONFIG_SYS_USE_NAND static iomux_v3_cfg_t const gpmi_pads[] = { @@ -436,30 +479,6 @@ int board_video_skip(void) } #endif -#ifdef CONFIG_FEC_MXC -static iomux_v3_cfg_t const fec1_pads[] = { - MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), - MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), - MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), - MX7D_PAD_ENET1_RGMII_RD2__ENET1_RGMII_RD2 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), - MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), - MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), - MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX7D_PAD_ENET1_RGMII_TD2__ENET1_RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX7D_PAD_GPIO1_IO10__ENET1_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL_MII), - MX7D_PAD_GPIO1_IO11__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL_MII), -}; - -static void setup_iomux_fec(void) -{ - imx_iomux_v3_setup_multiple_pads(fec1_pads, ARRAY_SIZE(fec1_pads)); -} -#endif - static void setup_iomux_uart(void) { imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); @@ -620,14 +639,69 @@ void board_late_mmc_init(void) #endif +iomux_v3_cfg_t const fec2_en_pads[] = { + MX7D_PAD_GPIO1_IO04__GPIO1_IO4 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + #ifdef CONFIG_FEC_MXC +static iomux_v3_cfg_t const fec1_pads[] = { + MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_RD2__ENET1_RGMII_RD2 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_TD2__ENET1_RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX7D_PAD_GPIO1_IO10__ENET1_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL_MII), + MX7D_PAD_GPIO1_IO11__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL_MII), +}; + +static iomux_v3_cfg_t const fec2_pads[] = { + MX7D_PAD_EPDC_SDCE0__ENET2_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_EPDC_SDCLK__ENET2_RGMII_RD0 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_EPDC_SDLE__ENET2_RGMII_RD1 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_EPDC_SDOE__ENET2_RGMII_RD2 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_EPDC_SDSHR__ENET2_RGMII_RD3 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_EPDC_SDCE1__ENET2_RGMII_RXC | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_EPDC_GDRL__ENET2_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX7D_PAD_EPDC_SDCE2__ENET2_RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX7D_PAD_EPDC_SDCE3__ENET2_RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX7D_PAD_EPDC_GDCLK__ENET2_RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX7D_PAD_EPDC_GDOE__ENET2_RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX7D_PAD_EPDC_GDSP__ENET2_RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX7D_PAD_GPIO1_IO10__ENET1_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL_MII), + MX7D_PAD_GPIO1_IO11__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL_MII), +}; + +static void setup_iomux_fec(void) +{ + if (0 == CONFIG_FEC_ENET_DEV) { + imx_iomux_v3_setup_multiple_pads(fec1_pads, ARRAY_SIZE(fec1_pads)); + } else { + if (mx7sabre_rev() == BOARD_REV_B) { + /* On RevB, GPIO1_IO04 is used for ENET2 EN, + * so set its output to low to enable ENET2 signals + */ + imx_iomux_v3_setup_multiple_pads(fec2_en_pads, + ARRAY_SIZE(fec2_en_pads)); + gpio_direction_output(IMX_GPIO_NR(1, 4), 0); + } + imx_iomux_v3_setup_multiple_pads(fec2_pads, ARRAY_SIZE(fec2_pads)); + } +} + int board_eth_init(bd_t *bis) { int ret; setup_iomux_fec(); - ret = fecmxc_initialize_multi(bis, 0, + ret = fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV, CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE); if (ret) printf("FEC1 MXC: %s:failed\n", __func__); @@ -635,16 +709,23 @@ int board_eth_init(bd_t *bis) return ret; } -static int setup_fec(void) +static int setup_fec(int fec_id) { struct iomuxc_gpr_base_regs *const iomuxc_gpr_regs = (struct iomuxc_gpr_base_regs *) IOMUXC_GPR_BASE_ADDR; int ret; - /* Use 125M anatop REF_CLK1 for ENET1, clear gpr1[13], gpr1[17]*/ - clrsetbits_le32(&iomuxc_gpr_regs->gpr[1], - (IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL_MASK | - IOMUXC_GPR_GPR1_GPR_ENET1_CLK_DIR_MASK), 0); + if (0 == fec_id) { + /* Use 125M anatop REF_CLK1 for ENET1, clear gpr1[13], gpr1[17]*/ + clrsetbits_le32(&iomuxc_gpr_regs->gpr[1], + (IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL_MASK | + IOMUXC_GPR_GPR1_GPR_ENET1_CLK_DIR_MASK), 0); + } else { + /* Use 125M anatop REF_CLK2 for ENET2, clear gpr1[14], gpr1[18]*/ + clrsetbits_le32(&iomuxc_gpr_regs->gpr[1], + (IOMUXC_GPR_GPR1_GPR_ENET2_TX_CLK_SEL_MASK | + IOMUXC_GPR_GPR1_GPR_ENET2_CLK_DIR_MASK), 0); + } ret = set_clk_enet(ENET_125MHz); if (ret) @@ -897,7 +978,7 @@ int board_init(void) iox74lv_init(); #ifdef CONFIG_FEC_MXC - setup_fec(); + setup_fec(CONFIG_FEC_ENET_DEV); #endif #ifdef CONFIG_SYS_USE_NAND @@ -909,8 +990,17 @@ int board_init(void) #endif #ifdef CONFIG_MXC_EPDC - qn_output[5] = qn_disable; - iox74lv_set(5); + if (mx7sabre_rev() == BOARD_REV_B) { + /* On RevB, GPIO1_IO04 is used for ENET2 EN, + * so set its output to high to isolate the ENET2 signals for EPDC + */ + imx_iomux_v3_setup_multiple_pads(fec2_en_pads, + ARRAY_SIZE(fec2_en_pads)); + gpio_direction_output(IMX_GPIO_NR(1, 4), 1); + } else { + qn_output[5] = qn_disable; + iox74lv_set(5); + } setup_epdc(); #endif @@ -991,14 +1081,22 @@ int board_late_init(void) return 0; } -u32 get_board_rev(void) -{ - return get_cpu_rev(); -} - int checkboard(void) { - puts("Board: i.MX7D SABRESD\n"); + int rev = mx7sabre_rev(); + char *revname; + + switch (rev) { + case BOARD_REV_B: + revname = "B"; + break; + case BOARD_REV_A: + default: + revname = "A"; + break; + } + + printf("Board: i.MX7D SABRESD Rev%s\n", revname); return 0; } @@ -1012,6 +1110,11 @@ iomux_v3_cfg_t const usb_otg2_pads[] = { MX7D_PAD_UART3_CTS_B__USB_OTG2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL), }; +/* On RevB board, the GPIO_IO07 is muxed for OTG2 PWR */ +iomux_v3_cfg_t const usb_otg2_revB_pads[] = { + MX7D_PAD_GPIO1_IO07__USB_OTG2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + int board_ehci_hcd_init(int port) { switch (port) { @@ -1020,8 +1123,12 @@ int board_ehci_hcd_init(int port) ARRAY_SIZE(usb_otg1_pads)); break; case 1: - imx_iomux_v3_setup_multiple_pads(usb_otg2_pads, - ARRAY_SIZE(usb_otg2_pads)); + if (mx7sabre_rev() == BOARD_REV_B) + imx_iomux_v3_setup_multiple_pads(usb_otg2_revB_pads, + ARRAY_SIZE(usb_otg2_revB_pads)); + else + imx_iomux_v3_setup_multiple_pads(usb_otg2_pads, + ARRAY_SIZE(usb_otg2_pads)); break; default: printf("MXC USB port %d not yet supported\n", port); -- cgit v1.1