Other Parts Discussed in Thread: AM4372
On our target board we have three am4376 targets. Each is using GPIO Bank 0 inputs 1 and 2 (Not 0 and 1) to identify which CPU instance any executable code environment may be running. Each is pulled either high or low using a 1K pull up/down resisters. (We have checked the specs and this is a strong enough resister to overcome the internal pullup if used.)
At present I can test this functionality on 2 of the three targets using SPL and U-boot. Using U-boot it appears that I am not getting the expected input values on the GPIO0 inputs.
This is the expected result:
CPU A = 0x00000002 // input 1 is low and input 2 is high
CPU C = 0x00000003 // input 1 is high and input 2 is high
This the code snippet, mux and DTS that I am using in SPL/U-Boot ( I have attached the source files as well.)
in board/ti/am43xx/board.c
#define CPUTYPE_MASK 0x0000006
#define CPUTYPE_MSB 2
#define CPUTYPE_LSB 1
#define GPIO0_DATAIN (AM33XX_GPIO0_BASE + OMAP_GPIO_DATAIN)
#define GPIO0_OE (AM33XX_GPIO0_BASE + OMAP_GPIO_OE)
static void set_bank0_direction(int gpio,int is_input)
{
void *reg = GPIO0_OE;
u32 l;
l = __raw_readl(reg);
if (is_input)
l |= 1 << gpio;
else
l &= ~(1 << gpio);
__raw_writel(l, reg);
}
static int get_bank0_value(int gpio)
{
void *reg = GPIO0_DATAIN;
return (__raw_readl(reg) & (1 << gpio)) != 0;
}
unsigned int get_bank0val(void)
{
u32 Bank0Val = 0;
enable_cpu_gpio_pin_mux();
set_bank0_direction(CPUTYPE_LSB,1);
set_bank0_direction(CPUTYPE_MSB,1);
if( get_bank0_value(CPUTYPE_LSB) > 0)
{
Bank0Val += 1;
}
if( get_bank0_value(CPUTYPE_MSB) > 0)
{
Bank0Val += 2;
}
return Bank0Val;
}
unsigned int get_cputype(void)
{
u32 Bank0Val = 0;
unsigned int RetVal;
enable_cpu_gpio_pin_mux();
Bank0Val = get_bank0val();
switch(Bank0Val)
{
case CPU_A:
{
RetVal = CPU_A;
break;
}
case CPU_B:
{
RetVal = CPU_B;
break;
}
case CPU_C:
{
RetVal = CPU_C;
break;
}
default:
RetVal = CPU_A;
}
return RetVal;
}
void sentenv_cputype(void)
{
int cpu_type = get_cputype();
printf("get_bank0val() : 0x%08X\n",get_bank0val());
// Set env varible cputype
switch(cpu_type)
{
case CPU_A:
env_set("cputype","A");
break;
case CPU_B:
env_set("cputype","B");
break;
case CPU_C:
env_set("cputype","C");
break;
default:
// Unknown
env_set("cputype","1");
}
}
in board/ti/am43xx/mux.c
static struct module_pin_mux gpio0_pin_mux[] = {
{OFFSET(mii1_rxdv), (MODE(9) | PULLUP_EN)}, /* GPIO0_1 */
{OFFSET(mcasp0_axr1), (MODE(9) | PULLUP_EN)},/* GPIO0_2 */
{-1},
};
void enable_cpu_gpio_pin_mux(void)
{
configure_module_pin_mux(gpio0_pin_mux);
}
Devicetree for u-boot: /arch/arm/dts/am437x-idk-evm.dts
gpio0_pins_default: gpio0_pins_default {
pinctrl-single,pins = <
AM4372_IOPAD(0x118, PIN_INPUT | MUX_MODE9) /* (A15) mii1_rx_dv.gpio0[1] */
AM4372_IOPAD(0x1a8, PIN_INPUT | MUX_MODE9) /* (M25) mcasp0_axr1.gpio0[2] */
>;
};
This is the result when setenv_cputype() is called from board_eth_init() in board.c
(I have confirmed, using a meter, that the inputs on 1 and 2 are being driven to the expected levels)
From CPU A:
get_bank0val() : 0x00000002
<ethaddr> set to CoreACE CPU C
From CPU C:
get_bank0val() : 0x00000002
<ethaddr> set to CoreACE CPU C
We have also used an emulator to break on the get_bank0val() function and read the GPIO Bank 0 register and identified that it contains the data we are seeing.
Also, If I stop u-boot and use the gpio command on the command line I get the same result on CPU A and CPU C.
Have I configured the pins and bank registers correctly? If so, isre more needed to read the input data.
Thanks in advance,
Rob