Add detection logic in hw21/26
(cherry picked from commit 0399dda8341c062a7a374152bfe255219c5db441)
This commit is contained in:
		
							parent
							
								
									d1c5c9c1e9
								
							
						
					
					
						commit
						f86ddfdff0
					
				|  | @ -37,6 +37,7 @@ | ||||||
| #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 "sja1105.h" | #include "sja1105.h" | ||||||
| #include "ui.h" | #include "ui.h" | ||||||
|  | @ -475,60 +476,142 @@ static void init_pmic_spl(void) | ||||||
| 	da9063_release_i2c_bus(bus); | 	da9063_release_i2c_bus(bus); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| struct reset_registers { | struct reset_registers { | ||||||
| 	uint32_t value; | 	/* Reboot Reasons, set by OS, expect watchdog set by bootloader */ | ||||||
| 	uint32_t value_crc; | 	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 */ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_NRSW_BUILD | /* Watchdog reboot reason event */ | ||||||
|  | #define RR_EXTERNAL_WATCHDOG_PATTERN	0x781f9ce2 | ||||||
| 
 | 
 | ||||||
| static uint32_t ether_crc(size_t len, uint8_t const *p) | /* 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 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | static void print_start_reason(uint32_t events) | ||||||
| { | { | ||||||
| 	uint32_t crc; | 	puts("Start Events: "); | ||||||
| 	unsigned i; |  | ||||||
| 
 | 
 | ||||||
| 	crc = ~0; | 	if (events == 0) { | ||||||
| 	while (len--) { | 		puts("-\n"); | ||||||
| 		crc ^= *p++; |  | ||||||
| 		for (i = 0; i < 8; i++) |  | ||||||
| 			crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0); |  | ||||||
| 	} | 	} | ||||||
|  | 	else { | ||||||
|  | 		static char buffer[10+11+11+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)); | ||||||
| 
 | 
 | ||||||
| 	/* an reverse the bits, cuz of way they arrive -- last-first */ | 		/* Trim last comma, no 0 len check required, at least one entry is present */ | ||||||
| 	crc = (crc >> 16) | (crc << 16); | 		buffer[strlen(buffer)-2] = 0;	 | ||||||
| 	crc = (crc >> 8 & 0x00ff00ff) | (crc << 8 & 0xff00ff00); | 		printf("%s\n", buffer); | ||||||
| 	crc = (crc >> 4 & 0x0f0f0f0f) | (crc << 4 & 0xf0f0f0f0); | 	} | ||||||
| 	crc = (crc >> 2 & 0x33333333) | (crc << 2 & 0xcccccccc); |  | ||||||
| 	crc = (crc >> 1 & 0x55555555) | (crc << 1 & 0xaaaaaaaa); |  | ||||||
| 	 |  | ||||||
| 	return crc; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void check_pmic_reset_reason(unsigned int reset_reason_shm_location) | 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; | ||||||
| 	uint8_t state = 0x00; | 	uint8_t state = 0x00; | ||||||
| 	int bus; | 	int bus; | ||||||
| 	int ret; | 	int ret; | ||||||
| 
 | 
 | ||||||
| 	bus = da9063_claim_i2c_bus(); | 	bus = da9063_claim_i2c_bus(); | ||||||
| 
 | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * Check/write boot marker to GP_ID_0 | ||||||
|  | 	 * If this marker is not present, we have a power on reset  | ||||||
|  | 	 */ | ||||||
|  | 	ret = da9063_get_reg(PMIC_GP_ID_0, &state); | ||||||
|  | 	if ((ret == 0) && (state != 0xC5)) { | ||||||
|  | 		start_event |= SE_POR; | ||||||
|  | 		(void)da9063_set_reg(PMIC_GP_ID_0, 0xC5); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * Check Fault Log register for | ||||||
|  | 	 * - Power On Reset: No Power, RTC Delivery -> requires removal of RTC battery | ||||||
|  | 	 * - Watchdog | ||||||
|  | 	 */ | ||||||
| 	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) { | 		if (state & PMIC_FAULT_TWD_ERROR_MASK) { | ||||||
| 			reset_regs->value = EXTERNAL_WATCHDOG_PATTERN; | 			start_event |= SE_WATCHDOG; | ||||||
| 			reset_regs->value_crc = ether_crc(sizeof(reset_regs->value),  | 
 | ||||||
| 							 (const uint8_t*)&(reset_regs->value)); | 			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 */ | ||||||
| 		da9063_set_reg(PMIC_REG_FAULT_LOG, state); | 		(void)da9063_set_reg(PMIC_REG_FAULT_LOG, state); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	da9063_release_i2c_bus(bus); | 	/*
 | ||||||
| } | 	 * Event Register A | ||||||
|  | 	 * - Event B Activity | ||||||
|  | 	 * - RTC Alarm | ||||||
|  | 	 */ | ||||||
|  | 	ret = da9063_get_reg(PMIC_REG_EVENT_A, &state); | ||||||
|  | 	if ((ret == 0) && (state != 0)) { | ||||||
|  | 		(void)da9063_set_reg(PMIC_REG_EVENT_A, state); | ||||||
| 
 | 
 | ||||||
| #endif | 		if (state & PMIC_REG_EVENT_RTC_ALARM_MASK) { | ||||||
|  | 			start_event |= SE_RTC_ALARM; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (state & PMIC_REG_EVENT_EVENTS_B_MASK) { | ||||||
|  | 			/*
 | ||||||
|  | 			 * 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) { | ||||||
|  | 					start_event |= SE_IGNITION; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Store start events in shared memory region for OS */ | ||||||
|  | 	reset_regs->se_magic = SE_MAGIC; | ||||||
|  | 	reset_regs->se_events = start_event; | ||||||
|  | 	reset_regs->se_checksum = 0; | ||||||
|  | 	reset_regs->se_checksum = ether_crc(sizeof(reset_regs->se_events),  | ||||||
|  | 					   (const uint8_t*)&(reset_regs->se_events)); | ||||||
|  | 
 | ||||||
|  | 	da9063_release_i2c_bus(bus); | ||||||
|  | 
 | ||||||
|  | 	print_start_reason(reset_regs->se_events); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| static void init_bd_spl(void) | static void init_bd_spl(void) | ||||||
| { | { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue