Hi
We would like to access the TI814x GPIO with U-boot (read the state of GPIO pins set up as inputs in this case).
Is this possible?.
thanks
steve
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi Steve,
Yes, you can read the GPIO pin status from u-boot.
Steps for reading the GPIO pins:-
1. Enable clock for GPIO bank which you are using.
2. Put the GPIO pins in Input mode
3. Read the register values to know the status
Regards
AnilKumar
hello:
How to configure gpio in the U-boot?
eg:I want to enbale the ninth pin in the bank 3,and set the pin as output,and output value 1.
But the U-boot will stop when I use the followings operation:(if I use only the __raw_writel,and the uboot will stop here,eg: __raw_writel(l,0x481AE134))
u32 l;
l = __raw_readl(0x481AE13C);
l |= 1 << 9;
/*
0x481AE13C: The GPIO_DATAOUT register is used for setting the value of the GPIO output pins. Data is written to the
GPIO_DATAOUT register synchronously with the interface clock. This register can be accessed with
direct read/write operations or using the alternate ‘Set/Clear’ feature. This feature enables to set or clear
specific bits of this register with a single write access to the set data output register
(GPIO_SETDATAOUT) or to the clear data output register (GPIO_CLEARDATAOUT) address.
*/
__raw_writel(l,0x481AE134);//Enable output*/
__raw_writel(l,0x481AE13C);//Set the out put value 1
/*
0x481AE194:Writing a 1 to a bit in the GPIO_SETDATAOUT register sets to 1 the corresponding bit in the
GPIO_DATAOUT register; writing a 0 has no effect. A read of the GPIO_SETDATAOUT register returns
the value of the data output register (GPIO_DATAOUT).
*/
__raw_writel(l,0x481AE194);
So,I want to know why I can't use the _raw_writel fun ,and if there is some problem about my register addr?
as you say,. Enable clock for GPIO bank which you are using.wheather you point the GPIO_CTRL Register ?
Thanks very much.
Hi!
I'm suffering the same problem... In our custom am3874 boards I'm trying to set the GP3[10] as an output pin in u-boot in order to generate a pulse to reset our ethernet phy controller, with no luck.
I have not found any example in the ti boards code to access the gpios... Any code example is welcome!
Thanks!
Jorge
Jorge,
Jorge Fernandez said:I have not found any example in the ti boards code to access the gpios... Any code example is welcome!
Refer to the voltage_scale_init(void) function in file:
{EZSDK}/board-support/u-boot-2010.06-psp04.04.00.01/board/ti/ti8168/evm.c
/*
* The routine reads the efuse register and programs the GPIO
* to adjust the TPS40041 core voltage.
* Assumptions:
* 1. The efuse data is programmed into TI816X_SMRT_SCALE_ADDR
* 2. The efuse and gpio clocks are already enabled
*/
static void voltage_scale_init(void)
{
u32 sr_efuse_data;
u8 gpio_val;
u32 gpio_reg_val;
sr_efuse_data = __raw_readl(TI816X_SMRT_SCALE_ADDR);
gpio_val = voltage_scale_lookup(sr_efuse_data);
if (gpio_val != 0) {
gpio_val &= 0xF;
/* Enable Output on GPIO0[0:3] */
gpio_reg_val = __raw_readl(TI816X_GPIO0_BASE + 0x134);
gpio_reg_val &= 0xF;
__raw_writel(gpio_reg_val, TI816X_GPIO0_BASE + 0x134);
/* Clear any existing output data */
gpio_reg_val = __raw_readl(TI816X_GPIO0_BASE + 0x190);
gpio_reg_val &= 0xF;
__raw_writel(gpio_reg_val, TI816X_GPIO0_BASE + 0x190);
/* Program the GPIO to change the TPS40041 Voltage */
gpio_reg_val = __raw_readl(TI816X_GPIO0_BASE + 0x194);
gpio_reg_val &= gpio_val;
__raw_writel(gpio_reg_val, TI816X_GPIO0_BASE + 0x194);
}
}
Note that GPIO0 is used, GPIO0 is enabled in peripheral_enable(void) function:
/* GPIO0 */
__raw_writel(0x2, CM_ALWON_GPIO_0_CLKCTRL);
while(__raw_readl(CM_ALWON_GPIO_0_CLKCTRL) != 0x2);
__raw_writel((BIT(8)), CM_ALWON_GPIO_0_OPTFCLKEN_DBCLK);
And GPIO0 base address is defined at:
{EZSDK}/board-support/u-boot-2010.06-psp04.04.00.01/include/asm/arch-ti81xx/hardware.h
/* GPIO Base address */
#define GPIO0_BASE 0x48032000
#define GPIO1_BASE 0x4804C000
You need to define the GPIO3_BASE address : 0x481AE000. You also need to enable the GPIO3 in the peripheral_enable(void) function using the CM_ALWON_GPIO_1_CLKCTRL register.
Regards,
Pavel
And what about calculating TI816X_GPIO0_BASE + 0x134 from GPIO0[0:3] ??
Regards,
Jorge
Jorge,
Jorge Fernandez said:And what about calculating TI816X_GPIO0_BASE + 0x134 from GPIO0[0:3] ??
This is equal to 0x48032134, which is the DM816x GPIO0.GPIO_OE register.
Regards,
Pavel
No luck doing the pulse! This is my code:
hardware.h
#define GPIO3_BASE 0x481AE000
my board.c
/* GPIO3 */
__raw_writel(0x2, CM_ALWON_GPIO_1_CLKCTRL);
while(__raw_readl(CM_ALWON_GPIO_1_CLKCTRL) != 0x2);
__raw_writel((BIT(8)), CM_ALWON_GPIO_1_OPTFCLKEN_DBCLK);
...
#define GPIO_ETHERNET_NRESET (1 << 10)
static void micrel_reset(void)
{
u8 gpio_val;
u32 gpio_reg_val;
/* Enable Output on GPIO3[10] */
gpio_reg_val = __raw_readl(GPIO3_BASE + 0x134); // base + 0x134 = GPIO_OE
gpio_reg_val &= ~GPIO_ETHERNET_NRESET;
__raw_writel(gpio_reg_val, GPIO3_BASE + 0x134);
/* Clear the GPIO */
gpio_reg_val = __raw_readl(GPIO3_BASE + 0x190);
gpio_reg_val &= GPIO_ETHERNET_NRESET;
__raw_writel(gpio_reg_val, GPIO3_BASE + 0x190);
udelay(500000);
/* Set the GPIO */
gpio_reg_val = __raw_readl(GPIO3_BASE + 0x194);
gpio_reg_val &= GPIO_ETHERNET_NRESET;
__raw_writel(gpio_reg_val, GPIO3_BASE + 0x194);
}
This code is executed when I do 'dhcp' from uboot command line because is the first thing I do on 'phy_init()' method. The scope don't get any pulse on the GPIO3[10] pin and the uboot is frozen when I run the reset...
It's a mess managing gpio pins with this cpu...
Regards,
Jorge,
Jorge Fernandez said:/* GPIO3 */
__raw_writel(0x2, CM_ALWON_GPIO_1_CLKCTRL);
while(__raw_readl(CM_ALWON_GPIO_1_CLKCTRL) != 0x2);
__raw_writel((BIT(8)), CM_ALWON_GPIO_1_OPTFCLKEN_DBCLK);
The CM_ALWON_GPIO_1_OPTFCLKEN_DBCLK is not defined by default in the u-boot source. Do you define it yourself? Do you have as result of the above operations the value of 0x00000102 inside the CM_ALWON_GPIO_1_CLKCTRL register?
Jorge Fernandez said:/* Enable Output on GPIO3[10] */
gpio_reg_val = __raw_readl(GPIO3_BASE + 0x134); // base + 0x134 = GPIO_OE
gpio_reg_val &= ~GPIO_ETHERNET_NRESET;
__raw_writel(gpio_reg_val, GPIO3_BASE + 0x134);
Do you have as result the value of 0 into the GPIO3.GPIO_OE[10] bit?
Do you measure the GP3[10] signal on the AH27 physical pin? Do you program the value of 0x80 into the PINCNTL218(0x48140B64) [7:0] MUXMODE bits?
Regards,
Pavel
Hi!
Pavel Botev said:The CM_ALWON_GPIO_1_OPTFCLKEN_DBCLK is not defined by default in the u-boot source. Do you define it yourself? Do you have as result of the above operations the value of 0x00000102 inside the CM_ALWON_GPIO_1_CLKCTRL register?
/* Enable Output on GPIO3[10] */
gpio_reg_val = __raw_readl(GPIO3_BASE + 0x134); // base + 0x134 = GPIO_OE
gpio_reg_val &= ~GPIO_ETHERNET_NRESET;
__raw_writel(gpio_reg_val, GPIO3_BASE + 0x134);Do you have as result the value of 0 into the GPIO3.GPIO_OE[10] bit?
Do you measure the GP3[10] signal on the AH27 physical pin? Do you program the value of 0x80 into the PINCNTL218(0x48140B64) [7:0] MUXMODE bits?
[/quote]
Yes, I have edited cpu.h this way:
#define CM_ALWON_GPIO_0_CLKCTRL (PRCM_BASE + 0x155c)
#define CM_ALWON_GPIO_0_OPTFCLKEN_DBCLK (PRCM_BASE + 0x155c)
#define CM_ALWON_GPIO_1_CLKCTRL (PRCM_BASE + 0x1560)
#define CM_ALWON_GPIO_1_OPTFCLKEN_DBCLK (PRCM_BASE + 0x1560)But if I print the 'CM_ALWON_GPIO_1_CLKCTRL' register in the 'phy_init()' I get 0x30100 !! In the 'per_clocks_enable()' I can put a printf.
I have discovered where the code hangs... If I try to do
gpio_reg_val = __raw_readl(GPIO3_BASE + 0x134);
the call never returns!
Any hint?
Regards,
Jorge
Jorge,
Jorge Fernandez said:But if I print the 'CM_ALWON_GPIO_1_CLKCTRL' register in the 'phy_init()' I get 0x30100 !! In the 'per_clocks_enable()' I can put a printf.
I suspect that __raw_writel((BIT(8)), CM_ALWON_GPIO_1_OPTFCLKEN_DBCLK); is setting bit [8] to 0x1, but at the same time is clearing bits [1:0] from 0x2 to 0x0. Which is not good, thus the GPIO3 module is disabled.
Jorge Fernandez said:I have discovered where the code hangs... If I try to do
gpio_reg_val = __raw_readl(GPIO3_BASE + 0x134);
the call never returns!
This is normal, as GPIO3 module is disabled, reading from the GPIO3 registers makes the flow to hang!
Jorge Fernandez said:Any hint?
You can modify your code as;
/* GPIO3 */
__raw_writel(0x102, CM_ALWON_GPIO_1_CLKCTRL);
while(__raw_readl(CM_ALWON_GPIO_1_CLKCTRL) != 0x102);
// __raw_writel((BIT(8)), CM_ALWON_GPIO_1_OPTFCLKEN_DBCLK);
This should work.
Regards,
Pavel
Pavel Botev said:You can modify your code as;
/* GPIO3 */
__raw_writel(0x102, CM_ALWON_GPIO_1_CLKCTRL);
while(__raw_readl(CM_ALWON_GPIO_1_CLKCTRL) != 0x102);
// __raw_writel((BIT(8)), CM_ALWON_GPIO_1_OPTFCLKEN_DBCLK);This should work.
Yes!! you're right, now it works!
Thanks!