hw21/26: add support for hw v3.2

Support uart4 for added RS232/485 interface
Move led0.green to new pin
This commit is contained in:
Rene Straub 2022-04-14 10:38:41 +02:00 committed by Alexandre Bard
parent 7b4add1789
commit a9e615e7ae
3 changed files with 216 additions and 39 deletions

View File

@ -48,10 +48,11 @@ DECLARE_GLOBAL_DATA_PTR;
/*
* CPU GPIOs
*
* (C15) GPIO0_6: MB_LED_PWM
* (J18) GPIO0_16: ETH_SW_RST~ (V2.0)
* (K15) GPIO0_17: CTRL.INT~
* (T10) GPIO0_23: CAN_TERM1~ (V1.0)
* (T17) GPIO0_30: LED0.RD
* (T17) GPIO0_30: LED0.GN (<V3.2 only)
*
* (T12) GPIO1_12: SIM_SW
* (V13) GPIO1_14: GNSS_RST~
@ -59,11 +60,12 @@ DECLARE_GLOBAL_DATA_PTR;
* (R14) GPIO1_20: BT_EN
* (V15) GPIO1_21: GSM_PWR_EN
* (U15) GPIO1_22: LED1.RD
* (T15) GPIO1_23: LED0.GN (V3.2)
* (V16) GPIO1_24: LED1.GN
* (U16) GPIO1_25: RST_GSM
* (T16) GPIO1_26: WLAN_EN
* (V17) GPIO1_27: WLAN_IRQ
* (U18) GPIO1_28: LED0.GN
* (U18) GPIO1_28: LED0.RD
*
* (U3) GPIO2_16: TIMEPULSE~ (HW26)
* (R6) GPIO2_25: RST_ETH~
@ -77,7 +79,9 @@ DECLARE_GLOBAL_DATA_PTR;
#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))
#define GPIO_LED0_GREEN GPIO_TO_PIN(0, 30)
#define GPIO_LED_PWM_V32 GPIO_TO_PIN(0, 6) /* V3.2 LED brightness */
#define GPIO_LED0_GREEN GPIO_TO_PIN(0, 30) /* <V3.2 */
#define GPIO_LED0_GREEN_V32 GPIO_TO_PIN(1, 23) /* V3.2 */
#define GPIO_LED0_RED GPIO_TO_PIN(1, 28)
#define GPIO_LED1_GREEN GPIO_TO_PIN(1, 24)
#define GPIO_LED1_RED GPIO_TO_PIN(1, 22)
@ -160,6 +164,8 @@ static int hw_type = -1;
static char hw_variant_name[64];
#else
static int hw_type = -1;
static int hw_ver = -1;
static int hw_rev = -1;
static uint32_t sys_start_event = 0x0;
#endif
@ -220,10 +226,24 @@ err_free_gpio:
#define REQUEST_AND_CLEAR_GPIO(N) request_and_set_gpio(N, #N, 0);
static bool is_v32_or_newer(void)
{
int full_ver = hw_ver*256 + hw_rev;
bool res = full_ver >= 0x0302;
return res;
}
static void init_leds(void)
{
REQUEST_AND_SET_GPIO(GPIO_LED0_RED);
REQUEST_AND_SET_GPIO(GPIO_LED0_GREEN);
if (is_v32_or_newer()) {
REQUEST_AND_SET_GPIO(GPIO_LED_PWM_V32);
REQUEST_AND_SET_GPIO(GPIO_LED0_GREEN_V32);
}
else {
REQUEST_AND_SET_GPIO(GPIO_LED0_GREEN);
}
REQUEST_AND_SET_GPIO(GPIO_LED1_RED);
REQUEST_AND_SET_GPIO(GPIO_LED1_GREEN);
}
@ -231,7 +251,12 @@ static void init_leds(void)
static void set_status_led(int red, int green)
{
gpio_set_value(GPIO_LED0_RED, red);
gpio_set_value(GPIO_LED0_GREEN, green);
if (is_v32_or_newer()) {
gpio_set_value(GPIO_LED0_GREEN_V32, green);
}
else {
gpio_set_value(GPIO_LED0_GREEN, green);
}
}
static void set_indicator_led(int red, int green)
@ -734,6 +759,8 @@ static void init_bd_spl(void)
if (read_eeprom() >= 0) {
int hw_type_from_bd = -1;
bd_get_hw_version(&hw_ver, &hw_rev);
/* If entry is found returns value, otherwise 0 */
bd_get_hw_type(&hw_type_from_bd);
if (hw_type_from_bd != 0) {
@ -776,6 +803,14 @@ void am33xx_spl_board_init(void)
stop_if_ignition_is_off();
}
if (is_v32_or_newer()) {
enable_led_mux_v32();
enable_uart4_pin_mux();
}
else {
enable_led_mux();
}
init_leds();
set_status_led(1, 0); /* Red */
set_indicator_led(1, 0); /* Red */
@ -1155,16 +1190,6 @@ int board_init(void)
ui_init(CONFIG_UI_I2C_BUS);
#endif
/* Let user know we're starting */
init_leds();
set_status_led(1, 1); /* Orange */
set_indicator_led(0, 0); /* Off */
#ifndef CONFIG_NRSW_BUILD
ui_set_status_led(1, 1); /* Orange */
ui_set_indicator_led(0, 0); /* Off */
#endif
printf("OSC: %lu MHz\n", get_osclk()/1000000);
return 0;
@ -1808,6 +1833,16 @@ int board_late_init(void)
get_hw_version();
get_pmic_version();
/* Let user know we're starting */
init_leds();
set_status_led(1, 1); /* Orange */
set_indicator_led(0, 0); /* Off */
#ifndef CONFIG_NRSW_BUILD
ui_set_status_led(1, 1); /* Orange */
ui_set_indicator_led(0, 0); /* Off */
#endif
#ifdef CONFIG_NRSW_BUILD
set_root_partition();
set_devicetree_name();
@ -2054,6 +2089,74 @@ int board_fit_config_name_match(const char *name)
#if defined(CONFIG_OF_BOARD_SETUP) && !defined(CONFIG_SPL_BUILD)
static void ft_enable_node(void* blob, const char* name)
{
int node_ofs = -1;
node_ofs = fdt_path_offset(blob, name);
printf("ft_enable_node %s -> %d\n", name, node_ofs);
if (node_ofs >= 0) {
fdt_setprop_string(blob, node_ofs, "status", "okay");
}
}
/*
* Modify the name of a gpio in a gpio-line-names string list.
*/
static void ft_set_gpio_name(void *blob, const char* gpio, int pin, const char* name)
{
int node_ofs = fdt_path_offset(blob, gpio);
int gpios = -1;
const char* text;
int pos = 0;
int i;
char buffer[512];
if (node_ofs < 0) {
printf("Can't find node %s\n", gpio);
goto end;
}
/* get number of IOs in node */
gpios = fdt_getprop_u32_default_node(blob, node_ofs, 0, "ngpios", -1);
if (gpios == -1 || gpios > 64) {
printf("Illegal number of gpios %d\n", gpios);
goto end;
}
/* get string array with names */
const struct fdt_property* prop = fdt_get_property(blob, node_ofs, "gpio-line-names", NULL);
if (prop == NULL) {
goto end;
}
/* modify given name */
for (i=0; i<gpios; i++) {
if (i == pin) {
/* Take provided name if GPIO pin is matched */
text = name;
}
else {
/* Take existing name from string list */
(void)fdt_get_string_index(blob, node_ofs, "gpio-line-names", i, &text);
}
/* Add name to new string list */
if ((pos + strlen(text) + 1) < sizeof(buffer)) {
strncpy(buffer+pos, text, sizeof(buffer)-pos);
pos += strlen(text) + 1;
}
else {
printf("ft_set_gpio_name() Buffer too small\n");
goto end;
}
}
(void)fdt_setprop(blob, node_ofs, "gpio-line-names", buffer, pos);
end: ;
}
static void ft_bootloader_version(void *blob)
{
int node_offset;
@ -2220,6 +2323,37 @@ static void ft_eth(void *blob)
}
}
static void ft_uart4(void *blob)
{
/*
* V3.2 HW can feature uart4 as RS232/485 interface.
* TODO: Check product descriptor to see if interface is assembled?
*/
if (is_v32_or_newer()) {
ft_enable_node(blob, "serial4");
}
else {
/* If interface is not present, remove SEL_RS232_RS485n name from gpio0_8 */
ft_set_gpio_name(blob, "gpio0", 8, "");
}
}
static void ft_led(void *blob)
{
/*
* V3.2 HW has LED0 Green at GPIO1_23 instead of 0_30
* Link from SysState-LED Driver also needs to be adapted
*/
if (is_v32_or_newer()) {
ft_enable_node(blob, "status_led_v32");
ft_enable_node(blob, "/sysstate-led-v32");
}
else {
ft_enable_node(blob, "status_led");
ft_enable_node(blob, "/sysstate-led");
}
}
int ft_board_setup(void *blob, bd_t *bd)
{
ft_bootloader_version(blob);
@ -2229,6 +2363,8 @@ int ft_board_setup(void *blob, bd_t *bd)
ft_user_module(blob);
#endif
ft_eth(blob);
ft_uart4(blob);
ft_led(blob);
ft_start_event(blob, RESET_REASON_SHM_LOCATION);
return 0;

View File

@ -13,8 +13,10 @@
void enable_uart0_pin_mux(void);
void enable_uart2_pin_mux(void);
void enable_uart4_pin_mux(void);
void enable_spi1_mux(void);
void enable_led_mux(void);
void enable_led_mux_v32(void);
void enable_board_pin_mux(void);
#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))

View File

@ -26,19 +26,15 @@ static struct module_pin_mux gpio_pin_mux[] = {
* (J18) GPIO0_16: ETH_SW_RST~ (V2.0)
* (K15) GPIO0_17: CTRL.INT~
* (T10) GPIO0_23: CAN_TERM1~ (V1.0)
* (T17) GPIO0_30: LED0.GN
*
* (T12) GPIO1_12: SIM_SW
* (V13) GPIO1_14: GNSS_RST~
* (U13) GPIO1_15: CAN_TERM0~ (V1.0)
* (R14) GPIO1_20: BT_EN
* (V15) GPIO1_21: GSM_PWR_EN
* (U15) GPIO1_22: LED1.RD
* (V16) GPIO1_24: LED1.GN
* (U16) GPIO1_25: RST_GSM
* (T16) GPIO1_26: WLAN_EN
* (V17) GPIO1_27: WLAN_IRQ
* (U18) GPIO1_28: LED0.RD
*
* (U3) GPIO2_16: TIMEPULSE (HW26)
* (R6) GPIO2_25: RST_ETH~
@ -54,7 +50,6 @@ static struct module_pin_mux gpio_pin_mux[] = {
{OFFSET(mii1_txd3), (MODE(7) | PULLUDDIS)}, /* (J18) GPIO0_16: ETH_SW_RST~ (V2.0) */
{OFFSET(mii1_txd2), (MODE(7) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (K15) GPIO0_17: CTRL.INT~ */
{OFFSET(gpmc_ad9), (MODE(7) | PULLUDDIS)}, /* (T10) GPIO0_23: CAN_TERM1~ */
{OFFSET(gpmc_wait0), (MODE(7) | PULLUDDIS)}, /* (T17) GPIO0_30: LED0.GN */
/* Bank 1 */
{OFFSET(gpmc_ad12), (MODE(7) | PULLUDEN | PULLUP_EN)}, /* (T12) GPIO1_12: SIM_SW */
@ -63,32 +58,14 @@ static struct module_pin_mux gpio_pin_mux[] = {
{OFFSET(gpmc_a4), (MODE(7) | PULLUDDIS)}, /* (R14) gpio1_20: BT_EN */
{OFFSET(gpmc_a5), (MODE(7) | PULLUDDIS)}, /* (V15) gpio1_21: GSM_PWR_EN */
{OFFSET(gpmc_a6), (MODE(7) | PULLUDDIS)}, /* (U15) GPIO1_22: LED1.RD */
{OFFSET(gpmc_a8), (MODE(7) | PULLUDDIS)}, /* (V16) GPIO1_24: LED1.GN */
{OFFSET(gpmc_a9), (MODE(7) | PULLUDDIS)}, /* (U16) gpio1_25: RST_GSM */
{OFFSET(gpmc_a10), (MODE(7) | PULLUDDIS)}, /* (T16) gpio1_26: WLAN_EN */
{OFFSET(gpmc_a11), (MODE(7) | PULLUDDIS | RXACTIVE)}, /* (V17) gpio1_27: WLAN_IRQ */
{OFFSET(gpmc_be1n), (MODE(7) | PULLUDDIS)}, /* (U18) GPIO1_28: LED0.RD */
/* TODO: What about all the unused GPMC pins ? */
/* Bank 2 */
{OFFSET(lcd_data10), (MODE(7) | PULLUDEN | PULLDOWN_EN | RXACTIVE)}, /* (U3) GPIO2_16: TIMEPULSE input */
{OFFSET(lcd_ac_bias_en), (MODE(7) | PULLUDDIS)}, /* (R6) GPIO2_25: RST_ETH~ */
#if 0
/* TODO: What is this meant for? */
{OFFSET(lcd_data3), (MODE(7) | PULLUDEN | PULLUP_EN)}, /* (R4) gpio2[9] */ /* SYSBOOT_3 */
{OFFSET(lcd_data4), (MODE(7) | PULLUDEN | PULLUP_EN)}, /* (T1) gpio2[10] */ /* SYSBOOT_4 */
/* TODO: Check other unued pins from sysboot block */
/* Ensure PU/PD does not work against external signal */
/*
* SYSBOOT 0,1,5,12,13 = Low
* SYSBOOT 2 = High
*/
#endif
/* Bank 3 */
{OFFSET(mii1_rxdv), (MODE(7) | PULLUDDIS)}, /* (J17) GPIO3_4: GNSS_EXTINT */
{OFFSET(mii1_txclk), (MODE(7) | PULLUDDIS)}, /* (K18) GPIO3_9: CTRL.W_DIS */
@ -98,6 +75,39 @@ static struct module_pin_mux gpio_pin_mux[] = {
{-1}
};
static struct module_pin_mux led_pin_mux[] = {
/*
* (T17) GPIO0_30: LED0.GN
* (U15) GPIO1_22: LED1.RD
* (V16) GPIO1_24: LED1.GN
* (U18) GPIO1_28: LED0.RD
*/
{OFFSET(gpmc_wait0), (MODE(7) | PULLUDDIS)}, /* (T17) GPIO0_30: LED0.GN */
{OFFSET(gpmc_a6), (MODE(7) | PULLUDDIS)}, /* (U15) GPIO1_22: LED1.RD */
{OFFSET(gpmc_a8), (MODE(7) | PULLUDDIS)}, /* (V16) GPIO1_24: LED1.GN */
{OFFSET(gpmc_be1n), (MODE(7) | PULLUDDIS)}, /* (U18) GPIO1_28: LED0.RD */
{-1}
};
static struct module_pin_mux led_pin_mux_v32[] = {
/*
* (C15) GPIO0_6: MB_LED_PWM
* (U15) GPIO1_22: LED1.RD
* (T15) GPIO1_23: LED0.GN (formerly: (T17) GPIO0_30)
* (V16) GPIO1_24: LED1.GN
* (U18) GPIO1_28: LED0.RD
*/
{OFFSET(spi0_cs1), (MODE(7) | PULLUDDIS)}, /* (C15) GPIO0_6: MB_LED_PWM */
{OFFSET(gpmc_a6), (MODE(7) | PULLUDDIS)}, /* (U15) GPIO1_22: LED1.RD */
{OFFSET(gpmc_a7), (MODE(7) | PULLUDDIS)}, /* (T15) GPIO1_23: LED0.GN */
{OFFSET(gpmc_a8), (MODE(7) | PULLUDDIS)}, /* (V16) GPIO1_24: LED1.GN */
{OFFSET(gpmc_be1n), (MODE(7) | PULLUDDIS)}, /* (U18) GPIO1_28: LED0.RD */
{-1}
};
/* I2C0 PMIC */
static struct module_pin_mux i2c0_pin_mux[] = {
{OFFSET(i2c0_sda), (MODE(0) | RXACTIVE | PULLUDEN | PULLUP_EN | SLEWCTRL)}, /* (C17) I2C0_SDA */
@ -208,6 +218,20 @@ static struct module_pin_mux uart3_pin_mux[] = {
{-1}
};
/* UART4: User RS232/485 (V3.2 only) */
static struct module_pin_mux uart4_pin_mux[] = {
/*
* CTSn = SEL_RS232/RS485~: Default = High -> RS232 mode
* RTSn = RS485_DE: Default = Low -> RS485 transmitter disabled
* Configure as GPIO in U-Boot to keep disabled, Linux will change to RTSn
*/
{OFFSET(gpmc_wait0), (MODE(6) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (T17) UART4_RXD */
{OFFSET(gpmc_wpn), (MODE(6) | PULLUDEN | PULLUP_EN | SLEWCTRL)}, /* (U17) UART4_TXD */
{OFFSET(lcd_data12), (MODE(7) | PULLUDEN | PULLUP_EN)}, /* (V2) uart4_ctsn */
{OFFSET(lcd_data13), (MODE(7) | PULLUDEN | PULLDOWN_EN)}, /* (V3) uart4_rtsn */
{-1}
};
/* UART5: Highspeed UART for Bluetooth (no SLEWCTRL) */
static struct module_pin_mux uart5_pin_mux[] = {
{OFFSET(lcd_data9), (MODE(4) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (U2) UART5_RXD */
@ -268,7 +292,22 @@ void enable_uart2_pin_mux(void)
configure_module_pin_mux(uart2_pin_mux);
}
void enable_uart4_pin_mux(void)
{
configure_module_pin_mux(uart4_pin_mux);
}
void enable_spi1_mux(void)
{
configure_module_pin_mux(spi1_pin_mux);
}
void enable_led_mux(void)
{
configure_module_pin_mux(led_pin_mux);
}
void enable_led_mux_v32(void)
{
configure_module_pin_mux(led_pin_mux_v32);
}