From c9ab6352f6ec9bc3947f03481fb8f3aa77ffcf62 Mon Sep 17 00:00:00 2001 From: CTCaer Date: Mon, 19 Dec 2022 05:30:23 +0200 Subject: [PATCH] bdk: rtc: add T210B01 R2P --- bdk/rtc/max77620-rtc.c | 42 ++++++++++++++++++++++++++++++++++++++++++ bdk/rtc/max77620-rtc.h | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/bdk/rtc/max77620-rtc.c b/bdk/rtc/max77620-rtc.c index 785ab4b..87cc8c4 100644 --- a/bdk/rtc/max77620-rtc.c +++ b/bdk/rtc/max77620-rtc.c @@ -153,3 +153,45 @@ u32 max77620_rtc_date_to_epoch(const rtc_time_t *time) return epoch; } + +void max77620_rtc_set_reboot_reason(rtc_reboot_reason_t *rr) +{ + max77620_rtc_stop_alarm(); + + // Set reboot reason. + i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_YEAR_REG, rr->enc.val1); + i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_YEAR_REG, rr->enc.val2); + + // Set reboot reason magic. + i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_WEEKDAY_REG, RTC_REBOOT_REASON_MAGIC); + i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_WEEKDAY_REG, RTC_REBOOT_REASON_MAGIC); + + // Update RTC clock from RTC regs. + i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_WRITE_UPDATE); + msleep(16); +} + +bool max77620_rtc_get_reboot_reason(rtc_reboot_reason_t *rr) +{ + u8 magic[2]; + + // Get reboot reason magic. + magic[0] = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_WEEKDAY_REG); + magic[1] = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_WEEKDAY_REG); + + // Magic must be correct and match on both registers. + if (magic[0] != RTC_REBOOT_REASON_MAGIC || magic[0] != magic[1]) + return false; + + // Reboot reason setter is expected to have updated the actual regs already. + rr->enc.val1 = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_YEAR_REG); + rr->enc.val2 = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_YEAR_REG); + + // Clear magic and update actual regs. + i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_WEEKDAY_REG, 0); + i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_WEEKDAY_REG, 0); + i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_WRITE_UPDATE); + + // Return reboot reason. False if [config] was selected. + return true; +} diff --git a/bdk/rtc/max77620-rtc.h b/bdk/rtc/max77620-rtc.h index 48d1b9b..b0d616d 100644 --- a/bdk/rtc/max77620-rtc.h +++ b/bdk/rtc/max77620-rtc.h @@ -74,10 +74,45 @@ typedef struct _rtc_time_t { u16 year; } rtc_time_t; +#define RTC_REBOOT_REASON_MAGIC 0x77 // 7-bit reg. + +enum { + REBOOT_REASON_NOP = 0, // Use [config]. + REBOOT_REASON_SELF = 1, // Use autoboot_idx/autoboot_list. + REBOOT_REASON_MENU = 2, // Force menu. + REBOOT_REASON_UMS = 3, // Force selected UMS partition. + REBOOT_REASON_REC = 4, // Set PMC_SCRATCH0_MODE_RECOVERY and reboot to self. + REBOOT_REASON_PANIC = 5 // Inform bootloader that panic occured if T210B01. +}; + +typedef struct _rtc_rr_decoded_t +{ + u16 reason:4; + u16 autoboot_idx:4; + u16 autoboot_list:1; + u16 ums_idx:3; +} rtc_rr_decoded_t; + +typedef struct _rtc_rr_encoded_t +{ + u16 val1:6; // 6-bit reg. + u16 val2:6; // 6-bit reg. +} rtc_rr_encoded_t; + +typedef struct _rtc_reboot_reason_t +{ + union { + rtc_rr_decoded_t dec; + rtc_rr_encoded_t enc; + }; +} rtc_reboot_reason_t; + void max77620_rtc_prep_read(); void max77620_rtc_get_time(rtc_time_t *time); void max77620_rtc_stop_alarm(); void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time); u32 max77620_rtc_date_to_epoch(const rtc_time_t *time); +void max77620_rtc_set_reboot_reason(rtc_reboot_reason_t *rr); +bool max77620_rtc_get_reboot_reason(rtc_reboot_reason_t *rr); #endif /* _MFD_MAX77620_RTC_H_ */