All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] Driving GPIO in SPL
@ 2019-09-19 16:10 Chris LaRocque
  2019-09-20 14:53 ` Chris LaRocque
  0 siblings, 1 reply; 2+ messages in thread
From: Chris LaRocque @ 2019-09-19 16:10 UTC (permalink / raw)
  To: u-boot

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 <common.h>

// 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

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [U-Boot] Driving GPIO in SPL
  2019-09-19 16:10 [U-Boot] Driving GPIO in SPL Chris LaRocque
@ 2019-09-20 14:53 ` Chris LaRocque
  0 siblings, 0 replies; 2+ messages in thread
From: Chris LaRocque @ 2019-09-20 14:53 UTC (permalink / raw)
  To: u-boot

On Thu, Sep 19, 2019 at 12:10 PM Chris LaRocque <clarocq@gmail.com> 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 <common.h>
>
> // 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

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-09-20 14:53 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-19 16:10 [U-Boot] Driving GPIO in SPL Chris LaRocque
2019-09-20 14:53 ` Chris LaRocque

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.