blob: 0a1e4b6872d9210f18b61797276f416ccddeab7e [file] [log] [blame]
Werner Zeh5fb66ad2022-08-26 13:40:47 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2
Jan Samek15606482022-11-11 15:59:05 +01003#include <acpi/acpi_device.h>
4#include <acpi/acpigen.h>
Werner Zeh5fb66ad2022-08-26 13:40:47 +02005#include <commonlib/bsd/bcd.h>
6#include <console/console.h>
7#include <delay.h>
8#include <device/device.h>
9#include <device/i2c.h>
10#include <device/i2c_bus.h>
11#include <timer.h>
12#include <types.h>
13#include <version.h>
14#include "chip.h"
15#include "rv3028c7.h"
16
17static enum cb_err rtc_eep_wait_ready(struct device *dev)
18{
19 struct stopwatch sw;
20 uint8_t status;
21
22 stopwatch_init_msecs_expire(&sw, EEP_SYNC_TIMEOUT_MS);
23 do {
24 status = (uint8_t)i2c_dev_readb_at(dev, STATUS_REG);
25 mdelay(1);
26 } while ((status & EE_BUSY_BIT) && !stopwatch_expired(&sw));
27
28 if (status & EE_BUSY_BIT) {
29 return CB_ERR;
30 } else {
31 return CB_SUCCESS;
32 }
33}
34
35static enum cb_err rtc_eep_auto_refresh(struct device *dev, uint8_t state)
36{
37 uint8_t reg;
38
39 reg = (uint8_t)i2c_dev_readb_at(dev, CTRL1_REG);
40 reg &= ~EERD_BIT;
41 if (state == EEP_REFRESH_DIS)
42 reg |= EERD_BIT;
43 i2c_dev_writeb_at(dev, CTRL1_REG, reg);
44 /* Wait until the EEPROM has finished a possible running operation. */
45 if (rtc_eep_wait_ready(dev) != CB_SUCCESS) {
46 printk(BIOS_ERR, "%s: EEPROM access timed out (%d ms)!\n",
47 dev->chip_ops->name, EEP_SYNC_TIMEOUT_MS);
48 return CB_ERR;
49 }
50 return CB_SUCCESS;
51}
52
53static enum cb_err rtc_eep_start_update(struct device *dev)
54{
55 /* Disable EEPROM auto refresh before writing RAM to EEPROM
56 to avoid race conditions. */
57 if (rtc_eep_auto_refresh(dev, EEP_REFRESH_DIS))
58 return CB_ERR;
59
60 /* Now start the update cycle.*/
61 i2c_dev_writeb_at(dev, EEP_CMD_REG, EEP_CMD_PREFIX);
62 i2c_dev_writeb_at(dev, EEP_CMD_REG, EEP_CMD_UPDATE);
63 return CB_SUCCESS;
64}
65
66static void rtc_set_time_date(struct device *dev)
67{
68 struct drivers_i2c_rv3028c7_config *config = dev->chip_info;
69 uint8_t buf[7];
70
71 /* The buffer contains the seconds through years of the new time and date.
72 Whenever a new date is set, the time is set to 00:00:00. */
73 buf[0] = 0; /* Entry for seconds. */
74 buf[1] = 0; /* Entry for minutes. */
75 buf[2] = 0; /* Entry for hours. */
76 if (config->set_user_date) {
77 buf[3] = config->user_weekday;
78 buf[4] = bin2bcd(config->user_day);
79 buf[5] = bin2bcd(config->user_month);
80 buf[6] = bin2bcd(config->user_year);
81 printk(BIOS_DEBUG, "%s: Set to user date\n", dev->chip_ops->name);
82 } else {
83 buf[3] = coreboot_build_date.weekday;
84 buf[4] = coreboot_build_date.day;
85 buf[5] = coreboot_build_date.month;
86 buf[6] = coreboot_build_date.year;
87 printk(BIOS_DEBUG, "%s: Set to coreboot build date\n", dev->chip_ops->name);
88 }
89 /* According to the datasheet, date and time should be transferred in "one go"
90 in order to avoid value corruption. */
91 if (i2c_dev_write_at(dev, buf, sizeof(buf), 0) != sizeof(buf)) {
92 printk(BIOS_ERR, "%s: Not able to set date and time!\n", dev->chip_ops->name);
93 }
94}
95
96static void rtc_final(struct device *dev)
97{
98 uint8_t buf[7];
99
100 /* Read back current RTC date and time and print it to the console.
101 Date and time are read in "one go", the buffer contains seconds (byte 0)
102 through years (byte 6) after this read. */
103 if (i2c_dev_read_at(dev, buf, sizeof(buf), 0) != sizeof(buf)) {
104 printk(BIOS_ERR, "%s: Not able to read current date and time!\n",
105 dev->chip_ops->name);
106 } else {
107 printk(BIOS_INFO, "%s: Current date %02d.%02d.%02d %02d:%02d:%02d\n",
108 dev->chip_ops->name, bcd2bin(buf[5]), bcd2bin(buf[4]),
109 bcd2bin(buf[6]), bcd2bin(buf[2]), bcd2bin(buf[1]),
110 bcd2bin(buf[0]));
111 }
112 /* Make sure the EEPROM automatic refresh is enabled. */
113 if (rtc_eep_auto_refresh(dev, EEP_REFRESH_EN) != CB_SUCCESS) {
114 printk(BIOS_ERR, "%s: Not able to enable EEPROM auto refresh!\n",
115 dev->chip_ops->name);
116 }
117}
118
119static void rtc_init(struct device *dev)
120{
121 struct drivers_i2c_rv3028c7_config *config = dev->chip_info;
122 uint8_t reg, backup_reg, eep_update_needed = 0;
123
124 /* On every startup, the RTC synchronizes the internal EEPROM with RAM.
125 * During this time no operation shall modify RAM registers. Ensure this
126 * sync is finished before starting the initialization. */
127 if (rtc_eep_wait_ready(dev) != CB_SUCCESS) {
128 printk(BIOS_WARNING, "%s: Timeout on EEPROM sync after power on!\n",
129 dev->chip_ops->name);
130 return;
131 }
132 reg = backup_reg = (uint8_t)i2c_dev_readb_at(dev, EEP_BACKUP_REG);
133 /* Configure the switch-over setting according to devicetree. */
134 if (config->bckup_sw_mode) {
135 reg &= ~BSM_MASK;
136 reg |= config->bckup_sw_mode << BSM_BIT;
137 }
138 /* Configure the VBACKUP charging mode. */
139 if (config->cap_charge) {
140 reg &= ~TCR_MASK;
141 reg |= ((config->cap_charge - 1) << TCR_BIT);
142 reg |= TCE_BIT;
143 } else {
144 reg &= ~TCE_BIT;
145 }
146 /* According to the datasheet the Fast Edge Detection Enable (FEDE) bit
147 should always be set. */
148 reg |= FEDE_BIT;
149 if (reg != backup_reg) {
150 /* Write new register value into shadow RAM and request an EEPROM update. */
151 i2c_dev_writeb_at(dev, EEP_BACKUP_REG, reg);
152 eep_update_needed = 1;
153 }
154 /* Make sure the hour register is in 24h format.*/
155 reg = (uint8_t)i2c_dev_readb_at(dev, CTRL2_REG);
156 if (reg & HOUR_12_24_BIT) {
157 reg &= ~HOUR_12_24_BIT;
158 i2c_dev_writeb_at(dev, CTRL2_REG, reg);
159 }
160 /* Check for a possible voltage drop event. */
161 reg = (uint8_t)i2c_dev_readb_at(dev, STATUS_REG);
162 if (reg & PORF_BIT) {
163 /* Voltage drop was detected, date and time needs to be set properly. */
164 rtc_set_time_date(dev);
165 /* Clear the PORF bit to mark that the event was handled. */
166 reg &= ~PORF_BIT;
167 i2c_dev_writeb_at(dev, STATUS_REG, reg);
168 }
169 /*
170 * Finally, trigger the EEPROM update procedure if needed.
171 * According to the datasheet, this update will consume ~63 ms.
172 * In order to not block the boot process here waiting for this update being finished,
173 * trigger the update now and check for readiness in the final hook.
174 */
175 if (eep_update_needed && rtc_eep_start_update(dev) != CB_SUCCESS) {
176 printk(BIOS_ERR, "%s: Not able to trigger EEPROM update!\n",
177 dev->chip_ops->name);
178 }
179}
180
Jan Samek15606482022-11-11 15:59:05 +0100181#if CONFIG(HAVE_ACPI_TABLES)
182static void rv3028c7_fill_ssdt(const struct device *dev)
183{
184 const char *scope = acpi_device_scope(dev);
185 struct drivers_i2c_rv3028c7_config *config = dev->chip_info;
186 enum i2c_speed bus_speed;
187
188 if (!scope)
189 return;
190
191 switch (config->bus_speed) {
192 case I2C_SPEED_STANDARD:
193 case I2C_SPEED_FAST:
194 bus_speed = config->bus_speed;
195 break;
196 default:
197 bus_speed = I2C_SPEED_STANDARD;
198 printk(BIOS_INFO, "%s: Bus speed unsupported, fall back to %d kHz!\n",
199 dev->chip_ops->name, bus_speed / 1000);
200 break;
201 }
202
203 struct acpi_i2c i2c = {
204 .address = dev->path.i2c.device,
205 .mode_10bit = dev->path.i2c.mode_10bit,
206 .speed = bus_speed,
207 .resource = scope,
208 };
209
210 /* Device */
211 acpigen_write_scope(scope);
212 acpigen_write_device(acpi_device_name(dev));
213 acpigen_write_name_string("_HID", RV3028C7_HID_NAME);
214 acpigen_write_name_string("_DDN", RV3028C7_HID_DESC);
215 acpigen_write_STA(acpi_device_status(dev));
216
217 /* Resources */
218 acpigen_write_name("_CRS");
219
220 acpigen_write_resourcetemplate_header();
221 acpi_device_write_i2c(&i2c);
222 acpigen_write_resourcetemplate_footer();
223
224 acpigen_pop_len(); /* Device */
225 acpigen_pop_len(); /* Scope */
226
227 printk(BIOS_INFO, "%s: %s at %s\n", acpi_device_path(dev), dev->chip_ops->name,
228 dev_path(dev));
229}
230
231static const char *rv3028c7_acpi_name(const struct device *dev)
232{
233 return RV3028C7_ACPI_NAME;
234}
235#endif
236
Werner Zeh5fb66ad2022-08-26 13:40:47 +0200237static struct device_operations rv3028c7_ops = {
238 .read_resources = noop_read_resources,
239 .set_resources = noop_set_resources,
240 .init = rtc_init,
241 .final = rtc_final,
Jan Samek15606482022-11-11 15:59:05 +0100242#if CONFIG(HAVE_ACPI_TABLES)
243 .acpi_name = rv3028c7_acpi_name,
244 .acpi_fill_ssdt = rv3028c7_fill_ssdt,
245#endif
Werner Zeh5fb66ad2022-08-26 13:40:47 +0200246};
247
248static void rtc_enable(struct device *dev)
249{
250 dev->ops = &rv3028c7_ops;
251}
252
253struct chip_operations drivers_i2c_rv3028c7_ops = {
Nicholas Sudsgaardbfb11be2024-01-30 09:53:46 +0900254 .name = "RV-3028-C7",
Werner Zeh5fb66ad2022-08-26 13:40:47 +0200255 .enable_dev = rtc_enable
256};