Compare commits
15 Commits
hw21-ui-v3
...
2016.05-am
| Author | SHA1 | Date |
|---|---|---|
|
|
cd55d2932a | |
|
|
f47237771c | |
|
|
69e9c386dd | |
|
|
4e67fc3997 | |
|
|
4bbdb87d6b | |
|
|
e1069f6d23 | |
|
|
a9e615e7ae | |
|
|
7b4add1789 | |
|
|
4832ca022a | |
|
|
2fa18965e6 | |
|
|
a6b26419bc | |
|
|
6cc285809d | |
|
|
3a9ef955c2 | |
|
|
a39cba028a | |
|
|
2997b916c1 |
|
|
@ -23,6 +23,7 @@
|
||||||
#define PMIC_FAULT_POR_MASK 0x02 /* Startup from No-Power/RTC/Delivery mode */
|
#define PMIC_FAULT_POR_MASK 0x02 /* Startup from No-Power/RTC/Delivery mode */
|
||||||
|
|
||||||
#define PMIC_REG_EVENT_A 0x06
|
#define PMIC_REG_EVENT_A 0x06
|
||||||
|
#define PMIC_REG_EVENT_ONKEY_MASK 0x01
|
||||||
#define PMIC_REG_EVENT_RTC_ALARM_MASK 0x02
|
#define PMIC_REG_EVENT_RTC_ALARM_MASK 0x02
|
||||||
#define PMIC_REG_EVENT_RTC_TICK_MASK 0x04
|
#define PMIC_REG_EVENT_RTC_TICK_MASK 0x04
|
||||||
#define PMIC_REG_EVENT_EVENTS_B_MASK 0x20
|
#define PMIC_REG_EVENT_EVENTS_B_MASK 0x20
|
||||||
|
|
@ -30,6 +31,11 @@
|
||||||
#define PMIC_REG_EVENT_B 0x07
|
#define PMIC_REG_EVENT_B 0x07
|
||||||
#define PMIC_REG_EVENT_COMP1V2_MASK 0x04
|
#define PMIC_REG_EVENT_COMP1V2_MASK 0x04
|
||||||
|
|
||||||
|
#define PMIC_REG_IRQ_MASK_A 0x0A
|
||||||
|
#define PMIC_REG_IRQ_MASK_B 0x0B
|
||||||
|
#define PMIC_REG_IRQ_MASK_C 0x0C
|
||||||
|
#define PMIC_REG_IRQ_MASK_D 0x0D
|
||||||
|
|
||||||
#define PMIC_REG_CONTROL_A 0x0E /* Control register for power states */
|
#define PMIC_REG_CONTROL_A 0x0E /* Control register for power states */
|
||||||
#define PMIC_REG_CONTROL_D 0x11 /* Control register for blink/watchdog */
|
#define PMIC_REG_CONTROL_D 0x11 /* Control register for blink/watchdog */
|
||||||
#define PMIC_REG_GPIO14_15 0x1C /* Configuration of GPIO14/15 (mode, wake) */
|
#define PMIC_REG_GPIO14_15 0x1C /* Configuration of GPIO14/15 (mode, wake) */
|
||||||
|
|
@ -51,6 +57,7 @@
|
||||||
#define PMIC_LDOx_CONF_MASK 0x80
|
#define PMIC_LDOx_CONF_MASK 0x80
|
||||||
|
|
||||||
#define PMIC_REG_ID_4_3 0x84
|
#define PMIC_REG_ID_4_3 0x84
|
||||||
|
#define PMIC_REG_ID_6_5 0x85
|
||||||
|
|
||||||
#define PMIC_REG_BUCK_ILIM_A 0x9A
|
#define PMIC_REG_BUCK_ILIM_A 0x9A
|
||||||
#define PMIC_REG_BUCK_ILIM_B 0x9B
|
#define PMIC_REG_BUCK_ILIM_B 0x9B
|
||||||
|
|
@ -77,6 +84,7 @@
|
||||||
#define PMIC_REG_TRIM_CLDR 0x120 /* Calendar Trim register, 2's complement, 1.9ppm per bit */
|
#define PMIC_REG_TRIM_CLDR 0x120 /* Calendar Trim register, 2's complement, 1.9ppm per bit */
|
||||||
|
|
||||||
#define PMIC_GP_ID_0 0x121 /* General purpose ID 0 (R/W) */
|
#define PMIC_GP_ID_0 0x121 /* General purpose ID 0 (R/W) */
|
||||||
|
#define PMIC_GP_ID_1 0x122 /* General purpose ID 1 (R/W) */
|
||||||
|
|
||||||
#define PMIC_REG_CONFIG_ID 0x184 /* OTP Config ID <ver.rev> */
|
#define PMIC_REG_CONFIG_ID 0x184 /* OTP Config ID <ver.rev> */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1304,13 +1304,13 @@ static void ft_dio(void *blob)
|
||||||
ft_enable_node(blob, "/netbox_dio_2in_1out");
|
ft_enable_node(blob, "/netbox_dio_2in_1out");
|
||||||
|
|
||||||
/* OEM Linux gpios -> remove IOs not present */
|
/* OEM Linux gpios -> remove IOs not present */
|
||||||
ft_set_gpio_name(blob, "/ocp/gpio@44e07000", 27, ""); /* gpio0_27: IO_OUT1n */
|
ft_set_gpio_name(blob, "gpio0", 27, ""); /* gpio0_27: IO_OUT1n */
|
||||||
ft_set_gpio_name(blob, "/ocp/gpio@4804c000", 14, ""); /* gpio1_14: IO_IN2 */
|
ft_set_gpio_name(blob, "gpio1", 14, ""); /* gpio1_14: IO_IN2 */
|
||||||
ft_set_gpio_name(blob, "/ocp/gpio@4804c000", 15, ""); /* gpio1_15: IO_IN3 */
|
ft_set_gpio_name(blob, "gpio1", 15, ""); /* gpio1_15: IO_IN3 */
|
||||||
|
|
||||||
/* pmic_gpios: 5: IO_IN2_WAKE3n, 6: IO_IN2_WAKE3n */
|
/* pmic_gpios: 5: IO_IN2_WAKE3n, 6: IO_IN2_WAKE3n */
|
||||||
ft_set_gpio_name(blob, "/ocp/i2c@44e0b000/da9063@58/gpio", 5, "");
|
ft_set_gpio_name(blob, "pmic_gpios", 5, "");
|
||||||
ft_set_gpio_name(blob, "/ocp/i2c@44e0b000/da9063@58/gpio", 6, "");
|
ft_set_gpio_name(blob, "pmic_gpios", 6, "");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -1321,13 +1321,12 @@ static void ft_dio(void *blob)
|
||||||
static void ft_tty(void *blob)
|
static void ft_tty(void *blob)
|
||||||
{
|
{
|
||||||
if (hw_has_tty) {
|
if (hw_has_tty) {
|
||||||
/* TODO: Should use alias uart5 */
|
ft_enable_node(blob, "serial5");
|
||||||
ft_enable_node(blob, "/ocp/serial@481aa000");
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* OEM Linux gpios -> remove IOs not present */
|
/* OEM Linux gpios -> remove IOs not present */
|
||||||
ft_set_gpio_name(blob, "/ocp/gpio@44e07000", 22, ""); /* gpio0_22: SEL_RS232_RS485n */
|
ft_set_gpio_name(blob, "gpio0", 22, ""); /* gpio0_22: SEL_RS232_RS485n */
|
||||||
ft_set_gpio_name(blob, "/ocp/gpio@44e07000", 23, ""); /* gpio0_23: RS485_TERM_ENn */
|
ft_set_gpio_name(blob, "gpio0", 23, ""); /* gpio0_23: RS485_TERM_ENn */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,4 +10,4 @@ ifeq ($(CONFIG_SKIP_LOWLEVEL_INIT),)
|
||||||
obj-y := mux.o
|
obj-y := mux.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
obj-y += board.o ../common/bdparser.o ../common/board_descriptor.o ../common/da9063.o ../common/ether_crc.o fileaccess.o sja1105.o ui.o um.o
|
obj-y += board.o ../common/bdparser.o ../common/board_descriptor.o ../common/da9063.o ../common/ether_crc.o fileaccess.o sja1105.o ui.o um.o reset_reason.o
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,8 @@
|
||||||
#include "../common/bdparser.h"
|
#include "../common/bdparser.h"
|
||||||
#include "../common/board_descriptor.h"
|
#include "../common/board_descriptor.h"
|
||||||
#include "../common/da9063.h"
|
#include "../common/da9063.h"
|
||||||
#include "../common/ether_crc.h"
|
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
|
#include "reset_reason.h"
|
||||||
#include "sja1105.h"
|
#include "sja1105.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "um.h"
|
#include "um.h"
|
||||||
|
|
@ -48,10 +48,13 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||||
/*
|
/*
|
||||||
* CPU GPIOs
|
* CPU GPIOs
|
||||||
*
|
*
|
||||||
|
* (C15) GPIO0_6: MB_LED_PWM
|
||||||
|
* (V2) GPIO0_8: RS232_485n_SEL (V3.2)
|
||||||
|
* (V3) GPIO0_9: RS485_DE (V3.2)
|
||||||
* (J18) GPIO0_16: ETH_SW_RST~ (V2.0)
|
* (J18) GPIO0_16: ETH_SW_RST~ (V2.0)
|
||||||
* (K15) GPIO0_17: CTRL.INT~
|
* (K15) GPIO0_17: CTRL.INT~
|
||||||
* (T10) GPIO0_23: CAN_TERM1~ (V1.0)
|
* (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
|
* (T12) GPIO1_12: SIM_SW
|
||||||
* (V13) GPIO1_14: GNSS_RST~
|
* (V13) GPIO1_14: GNSS_RST~
|
||||||
|
|
@ -59,11 +62,12 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||||
* (R14) GPIO1_20: BT_EN
|
* (R14) GPIO1_20: BT_EN
|
||||||
* (V15) GPIO1_21: GSM_PWR_EN
|
* (V15) GPIO1_21: GSM_PWR_EN
|
||||||
* (U15) GPIO1_22: LED1.RD
|
* (U15) GPIO1_22: LED1.RD
|
||||||
|
* (T15) GPIO1_23: LED0.GN (V3.2)
|
||||||
* (V16) GPIO1_24: LED1.GN
|
* (V16) GPIO1_24: LED1.GN
|
||||||
* (U16) GPIO1_25: RST_GSM
|
* (U16) GPIO1_25: RST_GSM
|
||||||
* (T16) GPIO1_26: WLAN_EN
|
* (T16) GPIO1_26: WLAN_EN
|
||||||
* (V17) GPIO1_27: WLAN_IRQ
|
* (V17) GPIO1_27: WLAN_IRQ
|
||||||
* (U18) GPIO1_28: LED0.GN
|
* (U18) GPIO1_28: LED0.RD
|
||||||
*
|
*
|
||||||
* (U3) GPIO2_16: TIMEPULSE~ (HW26)
|
* (U3) GPIO2_16: TIMEPULSE~ (HW26)
|
||||||
* (R6) GPIO2_25: RST_ETH~
|
* (R6) GPIO2_25: RST_ETH~
|
||||||
|
|
@ -77,7 +81,9 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))
|
#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_LED0_RED GPIO_TO_PIN(1, 28)
|
||||||
#define GPIO_LED1_GREEN GPIO_TO_PIN(1, 24)
|
#define GPIO_LED1_GREEN GPIO_TO_PIN(1, 24)
|
||||||
#define GPIO_LED1_RED GPIO_TO_PIN(1, 22)
|
#define GPIO_LED1_RED GPIO_TO_PIN(1, 22)
|
||||||
|
|
@ -107,6 +113,8 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
#define GPIO_UART2_RX GPIO_TO_PIN(0, 2) /* UART Rx Pin as GPIO */
|
#define GPIO_UART2_RX GPIO_TO_PIN(0, 2) /* UART Rx Pin as GPIO */
|
||||||
|
|
||||||
|
#define GPIO_RS232_RS485n_SEL GPIO_TO_PIN(0, 8)
|
||||||
|
#define GPIO_RS485_DE GPIO_TO_PIN(0, 9)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PMIC GPIOs
|
* PMIC GPIOs
|
||||||
|
|
@ -142,6 +150,13 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||||
#error Recovery boot time must be larger than factory reset + 1 second
|
#error Recovery boot time must be larger than factory reset + 1 second
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CPU Reset Reason
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CPU_GLOBAL_COLD_RST 0x01
|
||||||
|
#define CPU_GLOBAL_WARM_SW_RST 0x02
|
||||||
|
#define CPU_WDT1_RESET 0x10
|
||||||
|
|
||||||
|
|
||||||
#if !defined(CONFIG_SPL_BUILD)
|
#if !defined(CONFIG_SPL_BUILD)
|
||||||
|
|
@ -153,6 +168,8 @@ static int hw_type = -1;
|
||||||
static char hw_variant_name[64];
|
static char hw_variant_name[64];
|
||||||
#else
|
#else
|
||||||
static int hw_type = -1;
|
static int hw_type = -1;
|
||||||
|
static int hw_ver = -1;
|
||||||
|
static int hw_rev = -1;
|
||||||
static uint32_t sys_start_event = 0x0;
|
static uint32_t sys_start_event = 0x0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -213,10 +230,24 @@ err_free_gpio:
|
||||||
#define REQUEST_AND_CLEAR_GPIO(N) request_and_set_gpio(N, #N, 0);
|
#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)
|
static void init_leds(void)
|
||||||
{
|
{
|
||||||
REQUEST_AND_SET_GPIO(GPIO_LED0_RED);
|
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_RED);
|
||||||
REQUEST_AND_SET_GPIO(GPIO_LED1_GREEN);
|
REQUEST_AND_SET_GPIO(GPIO_LED1_GREEN);
|
||||||
}
|
}
|
||||||
|
|
@ -224,7 +255,12 @@ static void init_leds(void)
|
||||||
static void set_status_led(int red, int green)
|
static void set_status_led(int red, int green)
|
||||||
{
|
{
|
||||||
gpio_set_value(GPIO_LED0_RED, red);
|
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)
|
static void set_indicator_led(int red, int green)
|
||||||
|
|
@ -418,6 +454,26 @@ static void pmic_disable_auto_mode(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pmic_gnss_pwr_sequence(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
uint8_t val;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GNSS 3.3V needs to start at same time as board 3.3V.
|
||||||
|
* Modify LDO6 configuration accordingly if not already done.
|
||||||
|
*/
|
||||||
|
rc = da9063_get_reg(PMIC_REG_ID_6_5, &val);
|
||||||
|
if (!rc && (val != 0x20)) {
|
||||||
|
(void)da9063_set_reg(PMIC_REG_ID_6_5, 0x20); /* Add LDO6 to sequencer, slot 2 */
|
||||||
|
(void)da9063_set_reg(PMIC_REG_CONFIG_G, 0x64); /* LDO6 automatic enable control by sequencer */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable +3V3_GNSS (LDO6) */
|
||||||
|
(void)da9063_set_reg(PMIC_REG_LDO6_CONT, PMIC_LDOx_EN_MASK);
|
||||||
|
mdelay(2);
|
||||||
|
}
|
||||||
|
|
||||||
static void init_pmic_spl(void)
|
static void init_pmic_spl(void)
|
||||||
{
|
{
|
||||||
int bus;
|
int bus;
|
||||||
|
|
@ -435,9 +491,7 @@ static void init_pmic_spl(void)
|
||||||
pmic_disable_auto_mode();
|
pmic_disable_auto_mode();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable +3V3_GNSS (LDO6) */
|
pmic_gnss_pwr_sequence();
|
||||||
(void)da9063_set_reg(PMIC_REG_LDO6_CONT, PMIC_LDOx_EN_MASK);
|
|
||||||
mdelay(2);
|
|
||||||
|
|
||||||
/* Enable +5V_CAN (LDO11 Switch) */
|
/* Enable +5V_CAN (LDO11 Switch) */
|
||||||
(void)da9063_set_reg(PMIC_REG_LDO11_CONT, PMIC_LDOx_EN_MASK);
|
(void)da9063_set_reg(PMIC_REG_LDO11_CONT, PMIC_LDOx_EN_MASK);
|
||||||
|
|
@ -452,81 +506,39 @@ static void init_pmic_spl(void)
|
||||||
(void)da9063_set_reg(PMIC_REG_TRIM_CLDR, 0);
|
(void)da9063_set_reg(PMIC_REG_TRIM_CLDR, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mask unwanted IRQs to avoid accidental wakeup */
|
||||||
|
const uint8_t mask_a = PMIC_REG_EVENT_ONKEY_MASK |
|
||||||
|
PMIC_REG_EVENT_RTC_ALARM_MASK |
|
||||||
|
PMIC_REG_EVENT_RTC_TICK_MASK;
|
||||||
|
(void)da9063_set_reg(PMIC_REG_IRQ_MASK_A, ~(mask_a) & 0x1F);
|
||||||
|
(void)da9063_set_reg(PMIC_REG_IRQ_MASK_B, ~PMIC_REG_EVENT_COMP1V2_MASK);
|
||||||
|
(void)da9063_set_reg(PMIC_REG_IRQ_MASK_C, ~0x00);
|
||||||
|
(void)da9063_set_reg(PMIC_REG_IRQ_MASK_D, ~0x00);
|
||||||
|
|
||||||
da9063_release_i2c_bus(bus);
|
da9063_release_i2c_bus(bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void check_reset_reason(unsigned int reset_reason_shm_location)
|
||||||
struct reset_registers {
|
|
||||||
/* Reboot Reasons, set by OS, expect watchdog set by bootloader */
|
|
||||||
uint32_t rr_value;
|
|
||||||
uint32_t rr_value_crc;
|
|
||||||
|
|
||||||
/* Start Events */
|
|
||||||
uint32_t se_magic; /* Token to check presence of following fields */
|
|
||||||
uint32_t se_events; /* Events bitmask, see SE_... defines */
|
|
||||||
uint32_t se_checksum; /* Checksum over se_events */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Watchdog reboot reason event */
|
|
||||||
#define RR_EXTERNAL_WATCHDOG_PATTERN 0x781f9ce2
|
|
||||||
|
|
||||||
/* Start event token 'SRTE' */
|
|
||||||
#define SE_MAGIC 0x53525445
|
|
||||||
|
|
||||||
/* Possible start events (see se_events) */
|
|
||||||
#define SE_POR 0x00000001
|
|
||||||
#define SE_WATCHDOG 0x00000010
|
|
||||||
#define SE_IGNITION 0x00000100
|
|
||||||
#define SE_RTC_ALARM 0x00000200
|
|
||||||
#define SE_RTC_TICK 0x00000400
|
|
||||||
|
|
||||||
|
|
||||||
static void print_start_reason(uint32_t events)
|
|
||||||
{
|
|
||||||
puts("\nStart Events: ");
|
|
||||||
|
|
||||||
if (events == 0) {
|
|
||||||
puts("-\n");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
static char buffer[10+11+11+6+6+1];
|
|
||||||
|
|
||||||
buffer[0] = 0;
|
|
||||||
if (events & SE_POR)
|
|
||||||
strncat(buffer, "PowerOn, ", sizeof(buffer));
|
|
||||||
if (events & SE_WATCHDOG)
|
|
||||||
strncat(buffer, "Watchdog, ", sizeof(buffer));
|
|
||||||
if (events & SE_IGNITION)
|
|
||||||
strncat(buffer, "Ignition, ", sizeof(buffer));
|
|
||||||
if (events & SE_RTC_ALARM)
|
|
||||||
strncat(buffer, "RTC, ", sizeof(buffer));
|
|
||||||
if (events & SE_RTC_TICK)
|
|
||||||
strncat(buffer, "Tick, ", sizeof(buffer));
|
|
||||||
|
|
||||||
/* Trim last comma, no 0 len check required, at least one entry is present */
|
|
||||||
buffer[strlen(buffer)-2] = 0;
|
|
||||||
printf("%s\n", buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void check_pmic_reset_reason(unsigned int reset_reason_shm_location)
|
|
||||||
{
|
{
|
||||||
volatile struct reset_registers* reset_regs = (struct reset_registers*)reset_reason_shm_location;
|
volatile struct reset_registers* reset_regs = (struct reset_registers*)reset_reason_shm_location;
|
||||||
uint32_t start_event = 0;
|
uint32_t start_reason = 0;
|
||||||
|
uint32_t reset_reason = 0;
|
||||||
|
uint32_t cpu_reset_reason = 0;
|
||||||
uint8_t state = 0x00;
|
uint8_t state = 0x00;
|
||||||
int bus;
|
int bus;
|
||||||
int ret;
|
int ret;
|
||||||
|
char strbuf[256];
|
||||||
|
|
||||||
bus = da9063_claim_i2c_bus();
|
bus = da9063_claim_i2c_bus();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check/write boot marker to GP_ID_0
|
* Check/write boot marker to PMIC register GP_ID_1
|
||||||
* If this marker is not present, we have a power on reset
|
* If this marker is not present, we have a power on reset
|
||||||
*/
|
*/
|
||||||
ret = da9063_get_reg(PMIC_GP_ID_0, &state);
|
ret = da9063_get_reg(PMIC_GP_ID_1, &state);
|
||||||
if ((ret == 0) && (state != 0xC5)) {
|
if ((ret == 0) && (state != 0xC5)) {
|
||||||
start_event |= SE_POR;
|
(void)da9063_set_reg(PMIC_GP_ID_1, 0xC5);
|
||||||
(void)da9063_set_reg(PMIC_GP_ID_0, 0xC5);
|
start_reason |= SR_POR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -536,72 +548,131 @@ static void check_pmic_reset_reason(unsigned int reset_reason_shm_location)
|
||||||
*/
|
*/
|
||||||
ret = da9063_get_reg(PMIC_REG_FAULT_LOG, &state);
|
ret = da9063_get_reg(PMIC_REG_FAULT_LOG, &state);
|
||||||
if ((ret == 0) && (state != 0)) {
|
if ((ret == 0) && (state != 0)) {
|
||||||
// PMIC Watchdog
|
|
||||||
if (state & PMIC_FAULT_TWD_ERROR_MASK) {
|
|
||||||
start_event |= SE_WATCHDOG;
|
|
||||||
|
|
||||||
reset_regs->rr_value = RR_EXTERNAL_WATCHDOG_PATTERN;
|
|
||||||
reset_regs->rr_value_crc = ether_crc(sizeof(reset_regs->rr_value),
|
|
||||||
(const uint8_t*)&(reset_regs->rr_value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// PMIC Power On Reset (only when RTC battery is removed)
|
|
||||||
if (state & PMIC_FAULT_POR_MASK) {
|
|
||||||
start_event |= SE_POR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clear pmic fault log by writing back all bits currently set */
|
/* clear pmic fault log by writing back all bits currently set */
|
||||||
(void)da9063_set_reg(PMIC_REG_FAULT_LOG, state);
|
(void)da9063_set_reg(PMIC_REG_FAULT_LOG, state);
|
||||||
|
|
||||||
|
/* PMIC Power On Reset (only when RTC battery is removed) */
|
||||||
|
if (state & PMIC_FAULT_POR_MASK) {
|
||||||
|
start_reason |= SR_POR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PMIC Watchdog */
|
||||||
|
if (state & PMIC_FAULT_TWD_ERROR_MASK) {
|
||||||
|
start_reason |= SR_WATCHDOG;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Event Register A
|
* Check CPU reset reason register as the device can be reset
|
||||||
* - Event B Activity
|
* by a CPU watchdog
|
||||||
|
*/
|
||||||
|
cpu_reset_reason = readl(PRM_RSTST);
|
||||||
|
if (cpu_reset_reason & CPU_WDT1_RESET) {
|
||||||
|
start_reason |= SR_WATCHDOG;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clear the CPU reset reason register */
|
||||||
|
writel((CPU_WDT1_RESET | CPU_GLOBAL_COLD_RST | CPU_GLOBAL_WARM_SW_RST), PRM_RSTST);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check Wakeup Events
|
||||||
|
* Event Register A holds:
|
||||||
|
* - Event B, C Activity
|
||||||
|
* - nONKEY: Button
|
||||||
* - RTC Alarm
|
* - RTC Alarm
|
||||||
* - RTC Tick
|
* - RTC Tick
|
||||||
|
* Event Register B
|
||||||
|
* - COMP 1V2: Ignition
|
||||||
*/
|
*/
|
||||||
ret = da9063_get_reg(PMIC_REG_EVENT_A, &state);
|
ret = da9063_get_reg(PMIC_REG_EVENT_A, &state);
|
||||||
if ((ret == 0) && (state != 0)) {
|
if ((ret == 0) && (state != 0)) {
|
||||||
(void)da9063_set_reg(PMIC_REG_EVENT_A, state);
|
(void)da9063_set_reg(PMIC_REG_EVENT_A, state);
|
||||||
|
|
||||||
|
if (state & PMIC_REG_EVENT_ONKEY_MASK) {
|
||||||
|
start_reason |= (SR_WAKEUP | SR_EVT_BUTTON);
|
||||||
|
}
|
||||||
|
|
||||||
if (state & PMIC_REG_EVENT_RTC_ALARM_MASK) {
|
if (state & PMIC_REG_EVENT_RTC_ALARM_MASK) {
|
||||||
start_event |= SE_RTC_ALARM;
|
start_reason |= (SR_WAKEUP | SR_EVT_RTC_ALARM);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state & PMIC_REG_EVENT_RTC_TICK_MASK) {
|
if (state & PMIC_REG_EVENT_RTC_TICK_MASK) {
|
||||||
start_event |= SE_RTC_TICK;
|
start_reason |= (SR_WAKEUP | SR_EVT_RTC_TICK);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state & PMIC_REG_EVENT_EVENTS_B_MASK) {
|
if (state & PMIC_REG_EVENT_EVENTS_B_MASK) {
|
||||||
/*
|
uint8_t state_b;
|
||||||
* Event Register B
|
|
||||||
* - COMP 1V2: Ignition
|
|
||||||
*/
|
|
||||||
ret = da9063_get_reg(PMIC_REG_EVENT_B, &state);
|
|
||||||
if ((ret == 0) && (state != 0)) {
|
|
||||||
(void)da9063_set_reg(PMIC_REG_EVENT_B, state);
|
|
||||||
|
|
||||||
if (state & PMIC_REG_EVENT_COMP1V2_MASK) {
|
ret = da9063_get_reg(PMIC_REG_EVENT_B, &state_b);
|
||||||
start_event |= SE_IGNITION;
|
if ((ret == 0) && (state_b != 0)) {
|
||||||
|
(void)da9063_set_reg(PMIC_REG_EVENT_B, state_b);
|
||||||
|
|
||||||
|
if (state_b & PMIC_REG_EVENT_COMP1V2_MASK) {
|
||||||
|
start_reason |= (SR_WAKEUP | SR_EVT_IGNITION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Should we clear events here or leave them for Linux driver? */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sys_start_event = start_event;
|
/*
|
||||||
|
* Check for software reboot indicated by OS via shared memory
|
||||||
|
* - checksum valid?
|
||||||
|
* - Reason == 'REBO' or 'OOPS'
|
||||||
|
*/
|
||||||
|
if (rr_is_reset_reason_valid(reset_regs))
|
||||||
|
{
|
||||||
|
if (reset_regs->rr_value == RR_REBOOT_PATTERN) {
|
||||||
|
start_reason |= SR_REBOOT;
|
||||||
|
}
|
||||||
|
else if (reset_regs->rr_value == RR_OOPS_PATTERN) {
|
||||||
|
/* Treat kernel oops as reboot */
|
||||||
|
start_reason |= SR_REBOOT;
|
||||||
|
}
|
||||||
|
else if (reset_regs->rr_value == RR_WAKE_PATTERN) {
|
||||||
|
start_reason |= SR_WAKEUP;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Unknown reset reason */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Store start events in shared memory region for OS */
|
/*
|
||||||
reset_regs->se_magic = SE_MAGIC;
|
* Priority decoder for start and reset reason
|
||||||
reset_regs->se_events = start_event;
|
*/
|
||||||
reset_regs->se_checksum = 0;
|
if (start_reason & SR_WATCHDOG) {
|
||||||
reset_regs->se_checksum = ether_crc(sizeof(reset_regs->se_events),
|
/* Watchdog has highest priority as it also sets POR and other events */
|
||||||
(const uint8_t*)&(reset_regs->se_events));
|
start_reason = SR_WATCHDOG;
|
||||||
|
reset_reason = RR_EXTERNAL_WATCHDOG_PATTERN;
|
||||||
|
}
|
||||||
|
else if (start_reason & SR_POR) {
|
||||||
|
start_reason = SR_POR;
|
||||||
|
reset_reason = RR_POWEROFF_PATTERN;
|
||||||
|
}
|
||||||
|
else if (start_reason & SR_WAKEUP) {
|
||||||
|
/* Include start events when wakeup is detected */
|
||||||
|
start_reason = SR_WAKEUP | (start_reason & SR_EVT_WAKE_MASK);
|
||||||
|
reset_reason = RR_WAKE_PATTERN;
|
||||||
|
}
|
||||||
|
else if (start_reason & SR_REBOOT) {
|
||||||
|
start_reason = SR_REBOOT;
|
||||||
|
reset_reason = reset_regs->rr_value;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Unknown start reason, assume reboot */
|
||||||
|
start_reason = SR_REBOOT;
|
||||||
|
reset_reason = reset_regs->rr_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
sys_start_event = start_reason;
|
||||||
|
|
||||||
|
rr_set_reset_reason(reset_regs, reset_reason);
|
||||||
|
rr_set_start_reason(reset_regs, start_reason);
|
||||||
|
|
||||||
da9063_release_i2c_bus(bus);
|
da9063_release_i2c_bus(bus);
|
||||||
|
|
||||||
print_start_reason(reset_regs->se_events);
|
rr_start_reason_to_str(reset_regs->sr_events, strbuf, sizeof(strbuf));
|
||||||
|
printf("\nStart Events: %s\n", strbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pmic_ignition_gate_on(void)
|
static void pmic_ignition_gate_on(void)
|
||||||
|
|
@ -619,9 +690,7 @@ static void pmic_ignition_gate_on(void)
|
||||||
val |= 0xC0;
|
val |= 0xC0;
|
||||||
(void)da9063_set_reg(PMIC_REG_CONFIG_L, val);
|
(void)da9063_set_reg(PMIC_REG_CONFIG_L, val);
|
||||||
|
|
||||||
(void)da9063_get_reg(PMIC_REG_CONTROL_D, &val); /* No blinking, state selected by GPIOxx_MODE */
|
(void)da9063_set_reg(PMIC_REG_CONTROL_D, 0x00); /* No blinking, state selected by GPIOxx_MODE */
|
||||||
val &= ~0xF8;
|
|
||||||
(void)da9063_set_reg(PMIC_REG_CONTROL_D, val);
|
|
||||||
|
|
||||||
(void)da9063_get_reg(PMIC_REG_GPIO_MODE8_15, &val); /* Set to GPIO14,15 to high */
|
(void)da9063_get_reg(PMIC_REG_GPIO_MODE8_15, &val); /* Set to GPIO14,15 to high */
|
||||||
val |= 0xC0;
|
val |= 0xC0;
|
||||||
|
|
@ -643,7 +712,7 @@ static void powerdown(void)
|
||||||
bus = da9063_claim_i2c_bus();
|
bus = da9063_claim_i2c_bus();
|
||||||
|
|
||||||
/* Final call, will not return */
|
/* Final call, will not return */
|
||||||
da9063_set_reg(PMIC_REG_CONTROL_A, 0x00);
|
(void)da9063_set_reg(PMIC_REG_CONTROL_A, 0x00);
|
||||||
|
|
||||||
da9063_release_i2c_bus(bus);
|
da9063_release_i2c_bus(bus);
|
||||||
|
|
||||||
|
|
@ -712,6 +781,8 @@ static void init_bd_spl(void)
|
||||||
if (read_eeprom() >= 0) {
|
if (read_eeprom() >= 0) {
|
||||||
int hw_type_from_bd = -1;
|
int hw_type_from_bd = -1;
|
||||||
|
|
||||||
|
bd_get_hw_version(&hw_ver, &hw_rev);
|
||||||
|
|
||||||
/* If entry is found returns value, otherwise 0 */
|
/* If entry is found returns value, otherwise 0 */
|
||||||
bd_get_hw_type(&hw_type_from_bd);
|
bd_get_hw_type(&hw_type_from_bd);
|
||||||
if (hw_type_from_bd != 0) {
|
if (hw_type_from_bd != 0) {
|
||||||
|
|
@ -723,6 +794,29 @@ static void init_bd_spl(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void power_um(void)
|
||||||
|
{
|
||||||
|
int bus;
|
||||||
|
|
||||||
|
da9063_init(CONFIG_PMIC_I2C_BUS);
|
||||||
|
|
||||||
|
bus = da9063_claim_i2c_bus();
|
||||||
|
|
||||||
|
REQUEST_AND_CLEAR_GPIO(GPIO_RST_UM_N); /* Assert reset (active low) */
|
||||||
|
REQUEST_AND_CLEAR_GPIO(GPIO_CTRL_WDIS_N);
|
||||||
|
|
||||||
|
da9063_set_gpio(PMIC_UM_SUPPLY_EN_IO, 0); /* Switch Supply off */
|
||||||
|
mdelay(30); /* Give time to discharge output */
|
||||||
|
|
||||||
|
da9063_set_gpio(PMIC_UM_SUPPLY_VSEL_IO, 0); /* Set voltage to 3.3V */
|
||||||
|
mdelay(1);
|
||||||
|
|
||||||
|
da9063_set_gpio(PMIC_UM_SUPPLY_EN_IO, 1); /* Enable Supply */
|
||||||
|
mdelay(10);
|
||||||
|
|
||||||
|
da9063_release_i2c_bus(bus);
|
||||||
|
}
|
||||||
|
|
||||||
void am33xx_spl_board_init(void)
|
void am33xx_spl_board_init(void)
|
||||||
{
|
{
|
||||||
/* Set CPU speed to 600 MHz (fix) */
|
/* Set CPU speed to 600 MHz (fix) */
|
||||||
|
|
@ -734,25 +828,39 @@ void am33xx_spl_board_init(void)
|
||||||
/* Configure both I2C buses used */
|
/* Configure both I2C buses used */
|
||||||
init_i2c();
|
init_i2c();
|
||||||
|
|
||||||
|
/* Power on Extension/User module, so it doesn't block I2C bus */
|
||||||
|
power_um();
|
||||||
|
|
||||||
/* Get board descriptor */
|
/* Get board descriptor */
|
||||||
init_bd_spl();
|
init_bd_spl();
|
||||||
|
|
||||||
/* Detect reset/Wakeup reason */
|
/* Detect reset/Wakeup reason */
|
||||||
check_pmic_reset_reason(RESET_REASON_SHM_LOCATION);
|
check_reset_reason(RESET_REASON_SHM_LOCATION);
|
||||||
|
|
||||||
/* Switch on ignition gate so we can read state later */
|
/* Switch on ignition gate so we can read state later */
|
||||||
pmic_ignition_gate_on();
|
pmic_ignition_gate_on();
|
||||||
|
|
||||||
|
/* Setup PMIC */
|
||||||
|
init_pmic_spl();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this is a power-on start, see if ignition is active.
|
* If this is a power-on start, see if ignition is active.
|
||||||
* If not, power down as this is considered an unwanted system start.
|
* If not, power down as this is considered an unwanted system start.
|
||||||
*/
|
*/
|
||||||
if (sys_start_event & SE_POR) {
|
if (sys_start_event & SR_POR) {
|
||||||
stop_if_ignition_is_off();
|
stop_if_ignition_is_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup PMIC */
|
if (is_v32_or_newer()) {
|
||||||
init_pmic_spl();
|
enable_led_mux_v32();
|
||||||
|
enable_uart4_pin_mux();
|
||||||
|
|
||||||
|
REQUEST_AND_CLEAR_GPIO(GPIO_RS485_DE);
|
||||||
|
REQUEST_AND_CLEAR_GPIO(GPIO_RS232_RS485n_SEL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
enable_led_mux();
|
||||||
|
}
|
||||||
|
|
||||||
init_leds();
|
init_leds();
|
||||||
set_status_led(1, 0); /* Red */
|
set_status_led(1, 0); /* Red */
|
||||||
|
|
@ -963,30 +1071,14 @@ static void init_usb_hub(void)
|
||||||
|
|
||||||
static void init_user_module(void)
|
static void init_user_module(void)
|
||||||
{
|
{
|
||||||
int bus;
|
|
||||||
|
|
||||||
bus = da9063_claim_i2c_bus();
|
|
||||||
|
|
||||||
puts("UM: ");
|
puts("UM: ");
|
||||||
|
|
||||||
REQUEST_AND_CLEAR_GPIO(GPIO_RST_UM_N); /* Assert reset (active low) */
|
REQUEST_AND_CLEAR_GPIO(GPIO_RST_UM_N); /* Assert reset (active low) */
|
||||||
REQUEST_AND_CLEAR_GPIO(GPIO_CTRL_WDIS_N) /* TODO: CHECK */
|
REQUEST_AND_CLEAR_GPIO(GPIO_CTRL_WDIS_N);
|
||||||
|
|
||||||
/* TODO: Should this be done at first power up as well? */
|
|
||||||
da9063_set_gpio(PMIC_UM_SUPPLY_EN_IO, 0); /* Switch Supply off */
|
|
||||||
mdelay(30); /* Give time to discharge output */
|
|
||||||
|
|
||||||
da9063_set_gpio(PMIC_UM_SUPPLY_VSEL_IO, 0); /* Set voltage to 3.3V */
|
|
||||||
mdelay(1);
|
|
||||||
|
|
||||||
da9063_set_gpio(PMIC_UM_SUPPLY_EN_IO, 1); /* Enable Supply */
|
|
||||||
mdelay(10);
|
|
||||||
|
|
||||||
gpio_direction_input(GPIO_RST_UM_N); /* Release reset (open drain) */
|
gpio_direction_input(GPIO_RST_UM_N); /* Release reset (open drain) */
|
||||||
mdelay(10);
|
mdelay(10);
|
||||||
|
|
||||||
da9063_release_i2c_bus(bus);
|
|
||||||
|
|
||||||
mdelay(200); /* Give module some time to boot */
|
mdelay(200); /* Give module some time to boot */
|
||||||
um_init(CONFIG_UM_I2C_BUS); /* Try to detect user module */
|
um_init(CONFIG_UM_I2C_BUS); /* Try to detect user module */
|
||||||
|
|
||||||
|
|
@ -1084,12 +1176,33 @@ static void init_gsm(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_gnss(void)
|
static void init_gnss(uint32_t reset_reason_shm_location)
|
||||||
{
|
{
|
||||||
|
volatile struct reset_registers* reset_regs = (struct reset_registers*)reset_reason_shm_location;
|
||||||
|
bool do_reset = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Release GNSS reset line, so that module starts up early
|
* Release GNSS reset line, so that module starts up early.
|
||||||
|
* Excpetion: If this is an initial power up, we reset the module to ensure defined operation.
|
||||||
|
* Reasoning: Some NEO-M9 modems start in Safe Boot mode, due to power sequencing.
|
||||||
*/
|
*/
|
||||||
REQUEST_AND_SET_GPIO(GPIO_RST_GNSS);
|
puts("GNSS: ");
|
||||||
|
|
||||||
|
if (rr_is_start_reason_valid(reset_regs)) {
|
||||||
|
if ((reset_regs->sr_events & SR_POR) == SR_POR) {
|
||||||
|
do_reset = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (do_reset) {
|
||||||
|
puts("reset\n");
|
||||||
|
REQUEST_AND_CLEAR_GPIO(GPIO_RST_GNSS);
|
||||||
|
mdelay(110);
|
||||||
|
gpio_set_value(GPIO_RST_GNSS, 1);
|
||||||
|
} else {
|
||||||
|
puts("init\n");
|
||||||
|
REQUEST_AND_SET_GPIO(GPIO_RST_GNSS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_timepulse(void)
|
static void init_timepulse(void)
|
||||||
|
|
@ -1133,16 +1246,6 @@ int board_init(void)
|
||||||
ui_init(CONFIG_UI_I2C_BUS);
|
ui_init(CONFIG_UI_I2C_BUS);
|
||||||
#endif
|
#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);
|
printf("OSC: %lu MHz\n", get_osclk()/1000000);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1786,6 +1889,16 @@ int board_late_init(void)
|
||||||
get_hw_version();
|
get_hw_version();
|
||||||
get_pmic_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
|
#ifdef CONFIG_NRSW_BUILD
|
||||||
set_root_partition();
|
set_root_partition();
|
||||||
set_devicetree_name();
|
set_devicetree_name();
|
||||||
|
|
@ -1845,7 +1958,7 @@ int board_late_init(void)
|
||||||
#endif
|
#endif
|
||||||
init_sim_mux();
|
init_sim_mux();
|
||||||
init_gsm();
|
init_gsm();
|
||||||
init_gnss();
|
init_gnss(RESET_REASON_SHM_LOCATION);
|
||||||
init_timepulse();
|
init_timepulse();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -2032,6 +2145,85 @@ int board_fit_config_name_match(const char *name)
|
||||||
|
|
||||||
#if defined(CONFIG_OF_BOARD_SETUP) && !defined(CONFIG_SPL_BUILD)
|
#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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ft_disable_node(void* blob, const char* name)
|
||||||
|
{
|
||||||
|
int node_ofs = -1;
|
||||||
|
|
||||||
|
node_ofs = fdt_path_offset(blob, name);
|
||||||
|
// printf("ft_disable_node %s -> %d\n", name, node_ofs);
|
||||||
|
if (node_ofs >= 0) {
|
||||||
|
fdt_setprop_string(blob, node_ofs, "status", "disabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
static void ft_bootloader_version(void *blob)
|
||||||
{
|
{
|
||||||
int node_offset;
|
int node_offset;
|
||||||
|
|
@ -2101,7 +2293,7 @@ static void ft_user_interface(void *blob)
|
||||||
if (ui_hw_version == 1) {
|
if (ui_hw_version == 1) {
|
||||||
int node_offset;
|
int node_offset;
|
||||||
|
|
||||||
node_offset = fdt_path_offset(blob, "/ocp/i2c@4802a000/pca9539@74/");
|
node_offset = fdt_path_offset(blob, "ui_v1");
|
||||||
if (node_offset != -1) {
|
if (node_offset != -1) {
|
||||||
fdt_setprop_string(blob, node_offset, "status", "okay");
|
fdt_setprop_string(blob, node_offset, "status", "okay");
|
||||||
}
|
}
|
||||||
|
|
@ -2126,7 +2318,7 @@ static void ft_user_interface(void *blob)
|
||||||
else if (ui_hw_version == 2) {
|
else if (ui_hw_version == 2) {
|
||||||
int node_offset;
|
int node_offset;
|
||||||
|
|
||||||
node_offset = fdt_path_offset(blob, "/ocp/i2c@4802a000/pca9538@70/");
|
node_offset = fdt_path_offset(blob, "ui_v2");
|
||||||
if (node_offset != -1) {
|
if (node_offset != -1) {
|
||||||
fdt_setprop_string(blob, node_offset, "status", "okay");
|
fdt_setprop_string(blob, node_offset, "status", "okay");
|
||||||
}
|
}
|
||||||
|
|
@ -2153,6 +2345,21 @@ static void ft_user_interface(void *blob)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ft_start_event(void *blob, uint32_t reset_reason_shm_location)
|
||||||
|
{
|
||||||
|
volatile struct reset_registers* reset_regs = (struct reset_registers*)reset_reason_shm_location;
|
||||||
|
|
||||||
|
if (rr_is_start_reason_valid(reset_regs)) {
|
||||||
|
int node_offset;
|
||||||
|
|
||||||
|
node_offset = fdt_path_offset(blob, "/sysstate-start/");
|
||||||
|
if (node_offset != -1) {
|
||||||
|
|
||||||
|
fdt_setprop_u32(blob, node_offset, "start-reason", reset_regs->sr_events);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void ft_eth(void *blob)
|
static void ft_eth(void *blob)
|
||||||
|
|
@ -2169,13 +2376,13 @@ static void ft_eth(void *blob)
|
||||||
if (hw_ver == 1) {
|
if (hw_ver == 1) {
|
||||||
int node_offset;
|
int node_offset;
|
||||||
|
|
||||||
node_offset = fdt_path_offset(blob, "/ocp/ethernet@4a100000/mdio@4a101000/ethernet-phy@2/");
|
node_offset = fdt_path_offset(blob, "broadr1");
|
||||||
if (node_offset != -1) {
|
if (node_offset != -1) {
|
||||||
fdt_setprop_u32(blob, node_offset, "<reg>", 7);
|
fdt_setprop_u32(blob, node_offset, "<reg>", 7);
|
||||||
fdt_setprop_u32(blob, node_offset, "reg", 7);
|
fdt_setprop_u32(blob, node_offset, "reg", 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
node_offset = fdt_path_offset(blob, "/ocp/ethernet@4a100000/mdio@4a101000/ethernet-phy@3/");
|
node_offset = fdt_path_offset(blob, "broadr0");
|
||||||
if (node_offset != -1) {
|
if (node_offset != -1) {
|
||||||
fdt_setprop_u32(blob, node_offset, "<reg>", 6);
|
fdt_setprop_u32(blob, node_offset, "<reg>", 6);
|
||||||
fdt_setprop_u32(blob, node_offset, "reg", 6);
|
fdt_setprop_u32(blob, node_offset, "reg", 6);
|
||||||
|
|
@ -2183,6 +2390,35 @@ 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_disable_node(blob, "status_led");
|
||||||
|
ft_disable_node(blob, "/sysstate-led");
|
||||||
|
ft_enable_node(blob, "status_led_v32");
|
||||||
|
ft_enable_node(blob, "/sysstate-led-v32");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int ft_board_setup(void *blob, bd_t *bd)
|
int ft_board_setup(void *blob, bd_t *bd)
|
||||||
{
|
{
|
||||||
ft_bootloader_version(blob);
|
ft_bootloader_version(blob);
|
||||||
|
|
@ -2192,6 +2428,9 @@ int ft_board_setup(void *blob, bd_t *bd)
|
||||||
ft_user_module(blob);
|
ft_user_module(blob);
|
||||||
#endif
|
#endif
|
||||||
ft_eth(blob);
|
ft_eth(blob);
|
||||||
|
ft_uart4(blob);
|
||||||
|
ft_led(blob);
|
||||||
|
ft_start_event(blob, RESET_REASON_SHM_LOCATION);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,10 @@
|
||||||
|
|
||||||
void enable_uart0_pin_mux(void);
|
void enable_uart0_pin_mux(void);
|
||||||
void enable_uart2_pin_mux(void);
|
void enable_uart2_pin_mux(void);
|
||||||
|
void enable_uart4_pin_mux(void);
|
||||||
void enable_spi1_mux(void);
|
void enable_spi1_mux(void);
|
||||||
|
void enable_led_mux(void);
|
||||||
|
void enable_led_mux_v32(void);
|
||||||
void enable_board_pin_mux(void);
|
void enable_board_pin_mux(void);
|
||||||
|
|
||||||
#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))
|
#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))
|
||||||
|
|
|
||||||
|
|
@ -23,24 +23,22 @@
|
||||||
|
|
||||||
static struct module_pin_mux gpio_pin_mux[] = {
|
static struct module_pin_mux gpio_pin_mux[] = {
|
||||||
/*
|
/*
|
||||||
|
* (V2) GPIO0_8: RS232_485n_SEL (V3.2)
|
||||||
|
* (V3) GPIO0_9: RS485_DE (V3.2)
|
||||||
* (J18) GPIO0_16: ETH_SW_RST~ (V2.0)
|
* (J18) GPIO0_16: ETH_SW_RST~ (V2.0)
|
||||||
* (K15) GPIO0_17: CTRL.INT~
|
* (K15) GPIO0_17: CTRL.INT~
|
||||||
* (T10) GPIO0_23: CAN_TERM1~ (V1.0)
|
* (T10) GPIO0_23: CAN_TERM1~ (V1.0)
|
||||||
* (T17) GPIO0_30: LED0.GN
|
|
||||||
*
|
*
|
||||||
* (T12) GPIO1_12: SIM_SW
|
* (T12) GPIO1_12: SIM_SW
|
||||||
* (V13) GPIO1_14: GNSS_RST~
|
* (V13) GPIO1_14: GNSS_RST~
|
||||||
* (U13) GPIO1_15: CAN_TERM0~ (V1.0)
|
* (U13) GPIO1_15: CAN_TERM0~ (V1.0)
|
||||||
* (R14) GPIO1_20: BT_EN
|
* (R14) GPIO1_20: BT_EN
|
||||||
* (V15) GPIO1_21: GSM_PWR_EN
|
* (V15) GPIO1_21: GSM_PWR_EN
|
||||||
* (U15) GPIO1_22: LED1.RD
|
|
||||||
* (V16) GPIO1_24: LED1.GN
|
|
||||||
* (U16) GPIO1_25: RST_GSM
|
* (U16) GPIO1_25: RST_GSM
|
||||||
* (T16) GPIO1_26: WLAN_EN
|
* (T16) GPIO1_26: WLAN_EN
|
||||||
* (V17) GPIO1_27: WLAN_IRQ
|
* (V17) GPIO1_27: WLAN_IRQ
|
||||||
* (U18) GPIO1_28: LED0.RD
|
|
||||||
*
|
*
|
||||||
* (U3) GPIO2_16: TIMEPULSE (HW26)
|
* (U3) GPIO2_16: TIMEPULSE (HW26), see note [1]
|
||||||
* (R6) GPIO2_25: RST_ETH~
|
* (R6) GPIO2_25: RST_ETH~
|
||||||
*
|
*
|
||||||
* (J17) GPIO3_4: GNSS_EXTINT
|
* (J17) GPIO3_4: GNSS_EXTINT
|
||||||
|
|
@ -48,47 +46,31 @@ static struct module_pin_mux gpio_pin_mux[] = {
|
||||||
* (L18) GPIO3_10: CTRL.RST
|
* (L18) GPIO3_10: CTRL.RST
|
||||||
* (C12) GPIO3_17: UI_RST~
|
* (C12) GPIO3_17: UI_RST~
|
||||||
* (A14) GPIO3_21: RST_HUB~ (USB)
|
* (A14) GPIO3_21: RST_HUB~ (USB)
|
||||||
|
*
|
||||||
|
* [1] No PU/PD allowed as TIMEPULSE is internally connected with SAFEBOOT_N.
|
||||||
|
* SAFEBOOT_N must be left open/floating.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Bank 0 */
|
/* Bank 0 */
|
||||||
{OFFSET(mii1_txd3), (MODE(7) | PULLUDDIS)}, /* (J18) GPIO0_16: ETH_SW_RST~ (V2.0) */
|
{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(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_ad9), (MODE(7) | PULLUDDIS)}, /* (T10) GPIO0_23: CAN_TERM1~ */
|
||||||
{OFFSET(gpmc_wait0), (MODE(7) | PULLUDDIS)}, /* (T17) GPIO0_30: LED0.GN */
|
|
||||||
|
|
||||||
/* Bank 1 */
|
/* Bank 1 */
|
||||||
{OFFSET(gpmc_ad12), (MODE(7) | PULLUDDIS)}, /* (T12) GPIO1_12: SIM_SW */
|
{OFFSET(gpmc_ad12), (MODE(7) | PULLUDEN | PULLUP_EN)}, /* (T12) GPIO1_12: SIM_SW */
|
||||||
{OFFSET(gpmc_ad14), (MODE(7) | PULLUDDIS)}, /* (V13) GPIO1_14: GNSS_RST~ */
|
{OFFSET(gpmc_ad14), (MODE(7) | PULLUDDIS)}, /* (V13) GPIO1_14: GNSS_RST~ */
|
||||||
{OFFSET(gpmc_ad15), (MODE(7) | PULLUDDIS)}, /* (U13) GPIO1_15: CAN_TERM0~ */
|
{OFFSET(gpmc_ad15), (MODE(7) | PULLUDDIS)}, /* (U13) GPIO1_15: CAN_TERM0~ */
|
||||||
|
|
||||||
{OFFSET(gpmc_a4), (MODE(7) | PULLUDDIS)}, /* (R14) gpio1_20: BT_EN */
|
{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_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_a9), (MODE(7) | PULLUDDIS)}, /* (U16) gpio1_25: RST_GSM */
|
||||||
{OFFSET(gpmc_a10), (MODE(7) | PULLUDDIS)}, /* (T16) gpio1_26: WLAN_EN */
|
{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_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 */
|
/* Bank 2 */
|
||||||
{OFFSET(lcd_data10), (MODE(7) | PULLUDEN | PULLDOWN_EN | RXACTIVE)}, /* (U3) GPIO2_16: TIMEPULSE input */
|
{OFFSET(lcd_data10), (MODE(7) | PULLUDDIS | RXACTIVE)}, /* (U3) GPIO2_16: TIMEPULSE */
|
||||||
{OFFSET(lcd_ac_bias_en), (MODE(7) | PULLUDDIS)}, /* (R6) GPIO2_25: RST_ETH~ */
|
{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 */
|
/* Bank 3 */
|
||||||
{OFFSET(mii1_rxdv), (MODE(7) | PULLUDDIS)}, /* (J17) GPIO3_4: GNSS_EXTINT */
|
{OFFSET(mii1_rxdv), (MODE(7) | PULLUDDIS)}, /* (J17) GPIO3_4: GNSS_EXTINT */
|
||||||
{OFFSET(mii1_txclk), (MODE(7) | PULLUDDIS)}, /* (K18) GPIO3_9: CTRL.W_DIS */
|
{OFFSET(mii1_txclk), (MODE(7) | PULLUDDIS)}, /* (K18) GPIO3_9: CTRL.W_DIS */
|
||||||
|
|
@ -98,6 +80,39 @@ static struct module_pin_mux gpio_pin_mux[] = {
|
||||||
{-1}
|
{-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 */
|
/* I2C0 PMIC */
|
||||||
static struct module_pin_mux i2c0_pin_mux[] = {
|
static struct module_pin_mux i2c0_pin_mux[] = {
|
||||||
{OFFSET(i2c0_sda), (MODE(0) | RXACTIVE | PULLUDEN | PULLUP_EN | SLEWCTRL)}, /* (C17) I2C0_SDA */
|
{OFFSET(i2c0_sda), (MODE(0) | RXACTIVE | PULLUDEN | PULLUP_EN | SLEWCTRL)}, /* (C17) I2C0_SDA */
|
||||||
|
|
@ -203,8 +218,22 @@ static struct module_pin_mux uart2_pin_mux[] = {
|
||||||
|
|
||||||
/* UART3: GNSS */
|
/* UART3: GNSS */
|
||||||
static struct module_pin_mux uart3_pin_mux[] = {
|
static struct module_pin_mux uart3_pin_mux[] = {
|
||||||
{OFFSET(mii1_rxd3), (MODE(1) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (L17) UART3_RXD */
|
{OFFSET(mii1_rxd3), (MODE(1) | PULLUDDIS | RXACTIVE)}, /* (L17) UART3_RXD */
|
||||||
{OFFSET(mii1_rxd2), (MODE(1) | PULLUDEN | PULLUP_EN | SLEWCTRL)}, /* (L16) UART3_TXD */
|
{OFFSET(mii1_rxd2), (MODE(1) | PULLUDDIS | SLEWCTRL)}, /* (L16) UART3_TXD */
|
||||||
|
{-1}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* UART4: User RS232/485 (V3.2 only) */
|
||||||
|
static struct module_pin_mux uart4_pin_mux[] = {
|
||||||
|
/*
|
||||||
|
* CTSn = SEL_RS232/RS485~: Default = Low -> RS485 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 | PULLDOWN_EN)}, /* (V2) uart4_ctsn */
|
||||||
|
{OFFSET(lcd_data13), (MODE(7) | PULLUDEN | PULLDOWN_EN)}, /* (V3) uart4_rtsn */
|
||||||
{-1}
|
{-1}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -268,7 +297,22 @@ void enable_uart2_pin_mux(void)
|
||||||
configure_module_pin_mux(uart2_pin_mux);
|
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)
|
void enable_spi1_mux(void)
|
||||||
{
|
{
|
||||||
configure_module_pin_mux(spi1_pin_mux);
|
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);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* reset_reason.c
|
||||||
|
*
|
||||||
|
* Reset/start reason handling
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 NetModule AG - https://www.netmodule.com/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
|
*/
|
||||||
|
#include <common.h>
|
||||||
|
#include "../common/ether_crc.h"
|
||||||
|
#include "reset_reason.h"
|
||||||
|
|
||||||
|
|
||||||
|
void rr_set_reset_reason(volatile struct reset_registers* reset_regs, uint32_t reason)
|
||||||
|
{
|
||||||
|
reset_regs->rr_value = reason;
|
||||||
|
reset_regs->rr_value_crc = ether_crc(sizeof(reset_regs->rr_value),
|
||||||
|
(const uint8_t*)&(reset_regs->rr_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rr_is_reset_reason_valid(volatile const struct reset_registers* reset_regs)
|
||||||
|
{
|
||||||
|
const uint32_t crc = ether_crc(sizeof(reset_regs->rr_value),
|
||||||
|
(const uint8_t*)&(reset_regs->rr_value));
|
||||||
|
return crc == reset_regs->rr_value_crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rr_set_start_reason(volatile struct reset_registers* reset_regs, uint32_t event)
|
||||||
|
{
|
||||||
|
/* Store start events in shared memory region for OS */
|
||||||
|
reset_regs->sr_magic = SR_MAGIC;
|
||||||
|
reset_regs->sr_events = event;
|
||||||
|
reset_regs->sr_checksum = ether_crc(sizeof(reset_regs->sr_events),
|
||||||
|
(const uint8_t*)&(reset_regs->sr_events));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rr_is_start_reason_valid(volatile const struct reset_registers* reset_regs)
|
||||||
|
{
|
||||||
|
if (reset_regs->sr_magic == SR_MAGIC) {
|
||||||
|
const uint32_t crc = ether_crc(sizeof(reset_regs->sr_events),
|
||||||
|
(const uint8_t*)&(reset_regs->sr_events));
|
||||||
|
if (crc == reset_regs->sr_checksum) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rr_start_reason_to_str(uint32_t events, char* buffer, size_t bufsize)
|
||||||
|
{
|
||||||
|
if (events == 0) {
|
||||||
|
strncpy(buffer, "-\n", bufsize);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
buffer[0] = 0;
|
||||||
|
if (events & SR_POR)
|
||||||
|
strncat(buffer, "PowerOn, ", bufsize);
|
||||||
|
if (events & SR_WATCHDOG)
|
||||||
|
strncat(buffer, "Watchdog, ", bufsize);
|
||||||
|
if (events & SR_REBOOT)
|
||||||
|
strncat(buffer, "Reboot, ", bufsize);
|
||||||
|
if (events & SR_WAKEUP)
|
||||||
|
strncat(buffer, "Wakeup, ", bufsize);
|
||||||
|
|
||||||
|
if (events & SR_EVT_IGNITION)
|
||||||
|
strncat(buffer, "Ignition, ", bufsize);
|
||||||
|
if (events & SR_EVT_RTC_ALARM)
|
||||||
|
strncat(buffer, "RTC, ", bufsize);
|
||||||
|
if (events & SR_EVT_RTC_TICK)
|
||||||
|
strncat(buffer, "Tick, ", bufsize);
|
||||||
|
if (events & SR_EVT_GPI)
|
||||||
|
strncat(buffer, "GPI, ", bufsize);
|
||||||
|
if (events & SR_EVT_BUTTON)
|
||||||
|
strncat(buffer, "Button, ", bufsize);
|
||||||
|
|
||||||
|
/* Trim last comma, no 0 len check required, at least one entry is present */
|
||||||
|
buffer[strlen(buffer)-2] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* reset_reason.h
|
||||||
|
*
|
||||||
|
* Reset/start reason handling
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 NetModule AG - https://www.netmodule.com/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RESET_REASON_H
|
||||||
|
#define RESET_REASON_H
|
||||||
|
|
||||||
|
struct reset_registers {
|
||||||
|
/* Reboot Reasons, set by OS, expect watchdog set by bootloader */
|
||||||
|
uint32_t rr_value;
|
||||||
|
uint32_t rr_value_crc;
|
||||||
|
|
||||||
|
/* Start Reasons as determined by hardware */
|
||||||
|
uint32_t sr_magic; /* Token to check presence of following fields */
|
||||||
|
uint32_t sr_events; /* Events bitmask, see SE_... defines */
|
||||||
|
uint32_t sr_checksum; /* Checksum over se_events */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Watchdog reboot reason event */
|
||||||
|
#define RR_POWEROFF_PATTERN 0x00000000
|
||||||
|
#define RR_EXTERNAL_WATCHDOG_PATTERN 0x781f9ce2
|
||||||
|
#define RR_BOOT_PATTERN 0x424f4f54 /* ‘BOOT’, 0xb9808470 */
|
||||||
|
#define RR_REBOOT_PATTERN 0x5245424f /* ‘REBO’, 0x7d5d9d66 */
|
||||||
|
#define RR_OOPS_PATTERN 0x4F4F5053 /* ‘OOPS’, 0x2b85bc5f */
|
||||||
|
#define RR_WAKE_PATTERN 0x57414B45 /* 'WAKE', 0x7b0acb48 */
|
||||||
|
|
||||||
|
/* Start reason token 'SRTE' */
|
||||||
|
#define SR_MAGIC 0x53525445
|
||||||
|
|
||||||
|
/* Possible start events (see sr_events) */
|
||||||
|
#define SR_POR 0x00000001
|
||||||
|
#define SR_WATCHDOG 0x00000010
|
||||||
|
#define SR_REBOOT 0x00000020
|
||||||
|
#define SR_WAKEUP 0x00000080 /* See SR_EVT_xx bits */
|
||||||
|
|
||||||
|
/* In case of wake-up, these are the events that caused the start */
|
||||||
|
#define SR_EVT_IGNITION 0x00000100
|
||||||
|
#define SR_EVT_RTC_ALARM 0x00000200 /* RTC date/time alarm */
|
||||||
|
#define SR_EVT_RTC_TICK 0x00000400 /* RTC tick based alarm */
|
||||||
|
#define SR_EVT_GPI 0x00000800 /* General purpose input(s) */
|
||||||
|
#define SR_EVT_BUTTON 0x00001000
|
||||||
|
#define SR_EVT_WAKE_MASK 0x00001F00
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern void rr_set_reset_reason(volatile struct reset_registers* reset_regs, uint32_t reason);
|
||||||
|
extern bool rr_is_reset_reason_valid(volatile const struct reset_registers* reset_regs);
|
||||||
|
|
||||||
|
extern void rr_set_start_reason(volatile struct reset_registers* reset_regs, uint32_t event);
|
||||||
|
extern bool rr_is_start_reason_valid(volatile const struct reset_registers* reset_regs);
|
||||||
|
extern void rr_start_reason_to_str(uint32_t events, char* buffer, size_t bufsize);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* RESET_REASON_H */
|
||||||
|
|
@ -1330,10 +1330,10 @@ end: ;
|
||||||
static void ft_comio_gpios(void *blob)
|
static void ft_comio_gpios(void *blob)
|
||||||
{
|
{
|
||||||
/* gpio0_7: COM/IO relay output */
|
/* gpio0_7: COM/IO relay output */
|
||||||
ft_set_gpio_name(blob, "/ocp/gpio@44e07000", 7, "COMIO_OUT0");
|
ft_set_gpio_name(blob, "gpio0", 7, "COMIO_OUT0");
|
||||||
|
|
||||||
/* gpio1_8: COM/IO digital input */
|
/* gpio1_8: COM/IO digital input */
|
||||||
ft_set_gpio_name(blob, "/ocp/gpio@4804c000", 8, "COMIO_IN0");
|
ft_set_gpio_name(blob, "gpio1", 8, "COMIO_IN0");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ft_shields(void* blob)
|
static void ft_shields(void* blob)
|
||||||
|
|
@ -1345,15 +1345,13 @@ static void ft_shields(void* blob)
|
||||||
case SHIELD_COM_IO:
|
case SHIELD_COM_IO:
|
||||||
ft_comio_gpios(blob);
|
ft_comio_gpios(blob);
|
||||||
ft_enable_node(blob, "/netbox_dio_comio");
|
ft_enable_node(blob, "/netbox_dio_comio");
|
||||||
/* TODO: Should use alias serial0 */
|
ft_enable_node(blob, "serial0");
|
||||||
ft_enable_node(blob, "/ocp/serial@44e09000");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHIELD_DUALCAN:
|
case SHIELD_DUALCAN:
|
||||||
case SHIELD_DUALCAN_PASSIVE:
|
case SHIELD_DUALCAN_PASSIVE:
|
||||||
/* TODO: Should use alias d_can0, d_can1 */
|
ft_enable_node(blob, "d-can0");
|
||||||
ft_enable_node(blob, "/ocp/can@481cc000");
|
ft_enable_node(blob, "d-can1");
|
||||||
ft_enable_node(blob, "/ocp/can@481d0000");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -1242,10 +1242,10 @@ end: ;
|
||||||
static void ft_comio_gpios(void *blob)
|
static void ft_comio_gpios(void *blob)
|
||||||
{
|
{
|
||||||
/* gpio0_7: COM/IO relay output */
|
/* gpio0_7: COM/IO relay output */
|
||||||
ft_set_gpio_name(blob, "/ocp/gpio@44e07000", 7, "COMIO_OUT0");
|
ft_set_gpio_name(blob, "gpio0", 7, "COMIO_OUT0");
|
||||||
|
|
||||||
/* gpio1_8: COM/IO digital input */
|
/* gpio1_8: COM/IO digital input */
|
||||||
ft_set_gpio_name(blob, "/ocp/gpio@4804c000", 8, "COMIO_IN0");
|
ft_set_gpio_name(blob, "gpio1", 8, "COMIO_IN0");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ft_shields(void* blob)
|
static void ft_shields(void* blob)
|
||||||
|
|
@ -1257,15 +1257,13 @@ static void ft_shields(void* blob)
|
||||||
case SHIELD_COM_IO:
|
case SHIELD_COM_IO:
|
||||||
ft_comio_gpios(blob);
|
ft_comio_gpios(blob);
|
||||||
ft_enable_node(blob, "/netbox_dio_comio");
|
ft_enable_node(blob, "/netbox_dio_comio");
|
||||||
/* TODO: Should use alias serial0 */
|
ft_enable_node(blob, "serial0");
|
||||||
ft_enable_node(blob, "/ocp/serial@44e09000");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHIELD_DUALCAN:
|
case SHIELD_DUALCAN:
|
||||||
case SHIELD_DUALCAN_PASSIVE:
|
case SHIELD_DUALCAN_PASSIVE:
|
||||||
/* TODO: Should use alias d_can0, d_can1 */
|
ft_enable_node(blob, "d-can0");
|
||||||
ft_enable_node(blob, "/ocp/can@481cc000");
|
ft_enable_node(blob, "d-can1");
|
||||||
ft_enable_node(blob, "/ocp/can@481d0000");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -1273,7 +1271,7 @@ static void ft_shields(void* blob)
|
||||||
* Enable uart1 (ttyS0) always as kernel needs it as fallback console,
|
* Enable uart1 (ttyS0) always as kernel needs it as fallback console,
|
||||||
* if (ttyS1) is not available as console.
|
* if (ttyS1) is not available as console.
|
||||||
*/
|
*/
|
||||||
ft_enable_node(blob, "/ocp/serial@44e09000");
|
ft_enable_node(blob, "serial0");
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue