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/board_descriptor.h" | ||||
| #include "../common/da9063.h" | ||||
| #include "../common/ether_crc.h" | ||||
| #include "board.h" | ||||
| #include "sja1105.h" | ||||
| #include "ui.h" | ||||
|  | @ -475,60 +476,142 @@ static void init_pmic_spl(void) | |||
| 	da9063_release_i2c_bus(bus); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| struct reset_registers { | ||||
| 	uint32_t value; | ||||
| 	uint32_t value_crc; | ||||
| 	/* 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 */ | ||||
| }; | ||||
| 
 | ||||
| #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; | ||||
| 	unsigned i; | ||||
| 	puts("Start Events: "); | ||||
| 
 | ||||
| 	crc = ~0; | ||||
| 	while (len--) { | ||||
| 		crc ^= *p++; | ||||
| 		for (i = 0; i < 8; i++) | ||||
| 			crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0); | ||||
| 	if (events == 0) { | ||||
| 		puts("-\n"); | ||||
| 	} | ||||
| 	else { | ||||
| 		static char buffer[10+11+11+6+1]; | ||||
| 		 | ||||
| 	/* an reverse the bits, cuz of way they arrive -- last-first */ | ||||
| 	crc = (crc >> 16) | (crc << 16); | ||||
| 	crc = (crc >> 8 & 0x00ff00ff) | (crc << 8 & 0xff00ff00); | ||||
| 	crc = (crc >> 4 & 0x0f0f0f0f) | (crc << 4 & 0xf0f0f0f0); | ||||
| 	crc = (crc >> 2 & 0x33333333) | (crc << 2 & 0xcccccccc); | ||||
| 	crc = (crc >> 1 & 0x55555555) | (crc << 1 & 0xaaaaaaaa); | ||||
| 		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)); | ||||
| 
 | ||||
| 	return crc; | ||||
| 		/* Trim last comma, no 0 len check required, at least one entry is present */ | ||||
| 		buffer[strlen(buffer)-2] = 0;	 | ||||
| 		printf("%s\n", buffer); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 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; | ||||
| 	uint32_t start_event = 0; | ||||
| 	uint8_t state = 0x00; | ||||
| 	int bus; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	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); | ||||
| 	if ((ret == 0) && (state != 0)) { | ||||
| 		// PMIC Watchdog
 | ||||
| 		if (state & PMIC_FAULT_TWD_ERROR_MASK) { | ||||
| 			reset_regs->value = EXTERNAL_WATCHDOG_PATTERN; | ||||
| 			reset_regs->value_crc = ether_crc(sizeof(reset_regs->value),  | ||||
| 							 (const uint8_t*)&(reset_regs->value)); | ||||
| 			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 */ | ||||
| 		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) | ||||
| { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue