From mboxrd@z Thu Jan 1 00:00:00 1970 From: Chris LaRocque Date: Thu, 19 Sep 2019 12:10:50 -0400 Subject: [U-Boot] Driving GPIO in SPL Message-ID: List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hello I am trying to resolve an issue with a board based on the Beaglebone black. I am using U-Boot 2015.10, it is being built with Buildroot 2016.2 on OpenSuSE Leap 42.3 in a Virtualbox VM on a Windows 10 host. I want to set the pad registers for the mii interface to GPIO (mode 7), configure the pads as outputs, and drive the pins. I chose "enable_board_pin_mux" in "/board/ti/am335x/mux.c" as a the location to accomplish this task. However, I found that although I can change the state of a pin assigned to GPIO1 I could not change ones assigned to GPIO2 or GPIO3. I can read DATAOUT reg for all three GPIO modules and it reflects the requested setting but the pins do not reflect the reg state. I suspected that the pinmux was not being set by the call to "configure_module_pin_mux" so I used "__raw_write" to set the pad configuration registers. This did not change the situation. Here are some relevant code snippets. // CEL: Include necessary for timer #include // CEL: Create static pin mux configurations for // PHY configuration logic. static struct module_pin_mux phy_config_pin_mux[] = { {OFFSET(mii1_rxd3), MODE(7) | PULLUDDIS}, /* MII1_RXD3 */ {OFFSET(mii1_rxd2), MODE(7) | PULLUDDIS}, /* MII1_RXD2 */ {OFFSET(mii1_rxd1), MODE(7) | PULLUDDIS}, /* MII1_RXD1 */ {OFFSET(mii1_rxd0), MODE(7) | PULLUDDIS}, /* MII1_RXD0 */ {OFFSET(mii1_rxclk), MODE(7) | PULLUDDIS}, /* MII1_RXCLK */ {OFFSET(mii1_rxerr), MODE(7) | PULLUDDIS}, /* MII1_RXERR */ {OFFSET(mii1_col), MODE(7) | PULLUDDIS}, /* MII1_RXERR */ {OFFSET(gpmc_ad2), MODE(7) | PULLUDDIS}, /* GPIO 1_2 The PHY Reset Line */ {-1}, }; ------------------- unsigned long reg, en_gpio1, en_gpio2, en_gpio3; udelay(500000); // CEL: Write pinmux directly // instead of relying on inline functions //configure_module_pin_mux(phy_config_pin_mux); // OFFSET(mii1_rxd3), MODE(7) | PULLUDDIS __raw_writel((0x7 + (1 << 3)), (0x44E10800 + 0x134)); // OFFSET(mii1_rxd2), MODE(7) | PULLUDDIS __raw_writel((0x7 + (1 << 3)), (0x44E10800 + 0x139)); // OFFSET(mii1_rxd1), MODE(7) | PULLUDDIS __raw_writel((0x7 + (1 << 3)), (0x44E10800 + 0x13C)); // OFFSET(mii1_rxd0), MODE(7) | PULLUDDIS __raw_writel((0x7 + (1 << 3)), (0x44E10800 + 0x140)); // OFFSET(mii1_rxclk), MODE(7) | PULLUDDIS __raw_writel((0x7 + (1 << 3)), (0x44E10800 + 0x130)); // OFFSET(mii1_rxerr), MODE(7) | PULLUDDIS __raw_writel((0x7 + (1 << 3)), (0x44E10800 + 0x110)); // OFFSET(mii1_col), MODE(7) | PULLUDDIS __raw_writel((0x7 + (1 << 3)), (0x44E10800 + 0x108)); // OFFSET(gpmc_ad2), MODE(7) | PULLUDDIS __raw_writel((0x7 + (1 << 3)), (0x44E10800 + 0x08)); udelay(500000); //CM_PER_GPIO1_CLKCTRL __raw_writel(0x00000002, (0x44E00000 + 0xAC)); //CM_PER_GPIO2_CLKCTRL __raw_writel(0x00000002, (0x44E00000 + 0xB0)); //CM_PER_GPIO3_CLKCTRL __raw_writel(0x00000002, (0x44E00000 + 0xB4)); //udelay(100000); //puts("In measArmCard Pinmux Configure."); // CEL: Turn off clock gating and enable // GPIO Modules GPIO_CTRL en_gpio1 = __raw_readl((GPIO1_BASE + 0x130)); __raw_writel(0x0, (GPIO1_BASE + 0x130)); en_gpio2 = __raw_readl((GPIO2_BASE + 0x130)); __raw_writel(0x0, (GPIO2_BASE + 0x130)); en_gpio3 = __raw_readl((GPIO3_BASE + 0x130)); __raw_writel(0x0, (GPIO3_BASE + 0x130)); // CEL: Output Enable GPIO1, GPIO2, and GPIO3 // For the necessary GPIO Pins GPIO_OE reg = __raw_readl((GPIO1_BASE + 0x134)); __raw_writel((reg & 0xFFFFFFFB), (GPIO1_BASE + 0x134)); reg = __raw_readl((GPIO2_BASE + 0x134)); __raw_writel((reg & 0xFFC3FFFF), (GPIO2_BASE + 0x134)); reg = __raw_readl((GPIO3_BASE + 0x134)); __raw_writel((reg & 0xFFFFFBFA), (GPIO3_BASE + 0x134)); // CEL: Set Output State for // TPX2 = 0 GPIO_DATAOUT reg = __raw_readl((GPIO1_BASE + 0x13C)); // CEL: Mask off the bits I want to set reg = (reg & 0xFFFFFFFB); // CEL: Set the bits I want __raw_writel((reg | 0x00000000), (GPIO1_BASE + 0x13C)); // CEL: Set Output State for // RXD3 = 0, RXD2 = 0, RXD1 = 1, RXD0 = 1 // GPIO_DATAOUT reg = __raw_readl((GPIO2_BASE + 0x13C)); // CEL: Mask off the bits I want to set reg = (reg & 0xFFC3FFFF); // CEL: Set the bits I want __raw_writel((reg | 0x00300000), (GPIO2_BASE + 0x13C)); // CEL: Set Output State for // RXCLK = 0, RXERR = 0, COL = 1 // GPIO_DATAOUT reg = __raw_readl((GPIO3_BASE + 0x13C)); // CEL: Mask off the bits I want to set reg = (reg & 0xFFFFFBFA); // CEL: Set the bits I want __raw_writel((reg | 0x00000001), (GPIO3_BASE + 0x13C)); //puts("In pinmux configure: TPX2 = 0, RXD3 = 0, RXD2 = 0, RXD1 = 1, RXD0 = 1, RXCLK = 0, RXERR = 0, COL = 1.\n"); udelay(500000); // CEL: Set Output State for // TPX2 = 1 // GPIO_DATAOUT reg = __raw_readl((GPIO1_BASE + 0x13C)); // CEL: Mask off the bits I want to set reg = (reg & 0xFFFFFFFB); // CEL: Set the bits I want __raw_writel((reg | 0x00000004), (GPIO1_BASE + 0x13C)); //puts("In Pinmux Configure: TPX2 = 1, RXD3 = 0, RXD2 = 0, RXD1 = 1, RXD0 = 1, RXCLK = 0, RXERR = 0, COL = 1.\n"); udelay(500000); // CEL: Set Output State for // TPX2 = 0 // GPIO_DATAOUT reg = __raw_readl((GPIO1_BASE + 0x13C)); // CEL: Mask off the bits I want to set reg = (reg & 0xFFFFFFFB); // CEL: Set the bits I want __raw_writel((reg | 0x00000000), (GPIO1_BASE + 0x13C)); udelay(500000); // CEL: Set Output State for // TPX2 = 1 // GPIO_DATAOUT reg = __raw_readl((GPIO1_BASE + 0x13C)); // CEL: Mask off the bits I want to set reg = (reg & 0xFFFFFFFB); // CEL: Set the bits I want __raw_writel((reg | 0x00000004), (GPIO1_BASE + 0x13C)); //udelay(100000); puts("In Pinmux Configure. Releasing mii interface\n"); ------------------------------------------------- Questions: I believe that the SPL is a sequential application and that it does (can?) not lock access to the pinmux (pad configuration). Is this true. Shouldn't I be able to set the pad configurations for any pin? The pin designated "TPX2" is configured as GPIO1_2 and it is changing state as expected. The remaining pins GPIO2_18, GPIO2_19, GPIO2_20, GPIO2_21, GPIO3_0, GPIO3_2, and GPIO3_10 do not. The "puts " commands do not print to console. I see that the unmodified code in this function calls "puts" and expected console to be up. Is this an incorrect assumption? Adding all of this code caused u-boot to not come up and i had to remove some lines to get it to come back. Is it possible for the SPL to be too large and overwrite the available Static Ram in the AM3358 SOC? Your guidance and assistance is appreciated. Also, can someone suggest a good reference for the "legacy" build system for u-boot. At the moment the buildroot configuration for my board specifies the "legacy" build system and though it does allow selection of Kconfig that selection does not work in my case. Thank You in Advance Chris LaRocque