From mboxrd@z Thu Jan 1 00:00:00 1970 From: Chris LaRocque Date: Fri, 20 Sep 2019 10:53:18 -0400 Subject: [U-Boot] Driving GPIO in SPL In-Reply-To: References: 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 On Thu, Sep 19, 2019 at 12:10 PM Chris LaRocque wrote: > 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 > > Update, I found that the PHY chip I was trying to configure was contending with the GPIO pins. When I asserted the reset line I was able to set the configuration lines for the PHY without issue. So the note about the GPIO not changing state can be ignored. I would still appreciate comments about the Console and the limit of the code size for the SPL. Thank You Chris LaRocque