diff options
Diffstat (limited to 'driver/sb_rmi.c')
-rw-r--r-- | driver/sb_rmi.c | 192 |
1 files changed, 0 insertions, 192 deletions
diff --git a/driver/sb_rmi.c b/driver/sb_rmi.c deleted file mode 100644 index fbcbd990ff..0000000000 --- a/driver/sb_rmi.c +++ /dev/null @@ -1,192 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* AMD SB-RMI (Side-band Remote Management Interface) Driver */ - -#include "common.h" -#include "chipset.h" -#include "i2c.h" -#include "sb_rmi.h" -#include "stdbool.h" -#include "time.h" -#include "util.h" - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_SYSTEM, outstr) -#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) - -#define SB_RMI_MAILBOX_TIMEOUT_MS 10 -#define SB_RMI_MAILBOX_RETRY_DELAY_US 200 - -/** - * Write an SB-RMI register - */ -static int sb_rmi_write(const int reg, int data) -{ - return i2c_write8(I2C_PORT_THERMAL_AP, SB_RMI_I2C_ADDR_FLAGS0, reg, - data); -} - -/** - * Read an SB-RMI register - */ -static int sb_rmi_read(const int reg, int *data) -{ - return i2c_read8(I2C_PORT_THERMAL_AP, SB_RMI_I2C_ADDR_FLAGS0, reg, - data); -} - -/** - * Set SB-RMI software interrupt - */ -static int sb_rmi_assert_interrupt(bool assert) -{ - return sb_rmi_write(SB_RMI_SW_INTR_REG, assert ? 0x1 : 0x0); -} - - -/** - * Execute a SB-RMI mailbox transaction - * - * cmd: - * See "SB-RMI Soft Mailbox Message" table in PPR for command id - * msg_in: - * Message In buffer - * msg_out: - * Message Out buffer - */ -int sb_rmi_mailbox_xfer(int cmd, uint32_t msg_in, uint32_t *msg_out_ptr) -{ - /** - * The sequence is as follows: - * 1. The initiator (BMC) indicates that command is to be serviced by - * firmware by writing 0x80 to SBRMI::InBndMsg_inst7 (SBRMI_x3F). This - * register must be set to 0x80 after reset. - * 2. The initiator (BMC) writes the command to SBRMI::InBndMsg_inst0 - * (SBRMI_x38). - * 3. For write operations or read operations which require additional - * addressing information as shown in the table above, the initiator - * (BMC) writes Command Data In[31:0] to SBRMI::InBndMsg_inst[4:1] - * {SBRMI_x3C(MSB):SBRMI_x39(LSB)}. - * 4. The initiator (BMC) writes 0x01 to SBRMI::SoftwareInterrupt to - * notify firmware to perform the requested read or write command. - * 5. Firmware reads the message and performs the defined action. - * 6. Firmware writes the original command to outbound message register - * SBRMI::OutBndMsg_inst0 (SBRMI_x30). - * 7. Firmware will write SBRMI::Status[SwAlertSts]=1 to generate an - * ALERT (if enabled) to initiator (BMC) to indicate completion of the - * requested command. Firmware must (if applicable) put the message - * data into the message registers SBRMI::OutBndMsg_inst[4:1] - * {SBRMI_x34(MSB):SBRMI_x31(LSB)}. - * 8. For a read operation, the initiator (BMC) reads the firmware - * response Command Data Out[31:0] from SBRMI::OutBndMsg_inst[4:1] - * {SBRMI_x34(MSB):SBRMI_x31(LSB)}. - * 9. Firmware clears the interrupt on SBRMI::SoftwareInterrupt. - * 10. BMC must write 1'b1 to SBRMI::Status[SwAlertSts] to clear the - * ALERT to initiator (BMC). It is recommended to clear the ALERT - * upon completion of the current mailbox command. - */ - int val; - bool alerted; - timestamp_t start; - - if (!chipset_in_state(CHIPSET_STATE_ON)) - return EC_ERROR_NOT_POWERED; - - /** - * Step 1: writing 0x80 to SBRMI::InBndMsg_inst7 (SBRMI_x3F) to - * indicate that command is to be serviced and to make sure - * SBRMIx40[Software Interrupt] is cleared - */ - RETURN_ERROR(sb_rmi_write(SB_RMI_IN_BND_MSG7_REG, 0x80)); - RETURN_ERROR(sb_rmi_assert_interrupt(0)); - - /* Step 2: writes the command to SBRMI::InBndMsg_inst0 (SBRMI_x38) */ - RETURN_ERROR(sb_rmi_write(SB_RMI_IN_BND_MSG0_REG, cmd)); - /* Step 3: msgIn to {SBRMI_x3C(MSB):SBRMI_x39(LSB)} */ - RETURN_ERROR(sb_rmi_write(SB_RMI_IN_BND_MSG1_REG, msg_in & 0xFF)); - RETURN_ERROR( - sb_rmi_write(SB_RMI_IN_BND_MSG2_REG, (msg_in >> 8) & 0xFF)); - RETURN_ERROR( - sb_rmi_write(SB_RMI_IN_BND_MSG3_REG, (msg_in >> 16) & 0xFF)); - RETURN_ERROR( - sb_rmi_write(SB_RMI_IN_BND_MSG4_REG, (msg_in >> 24) & 0xFF)); - - /** - * Step 4: writes 0x01 to SBRMIx40[Software Interrupt] to notify - * firmware to start service. - */ - RETURN_ERROR(sb_rmi_assert_interrupt(1)); - - /** - * Step 5: SoC do the service - * Step 6: The original command will be copied to SBRMI::OutBndMsg_inst0 - * (SBRMI_x30) - * Step 7: wait SBRMIx02[SwAlertSts] to 1 which indicate the completion - * of a mailbox operation - */ - alerted = false; - start = get_time(); - do { - if (sb_rmi_read(SB_RMI_STATUS_REG, &val)) - break; - if (val & 0x02) { - alerted = true; - break; - } - msleep(1); - } while (time_since32(start) < SB_RMI_MAILBOX_TIMEOUT_MS * MSEC); - - if (!alerted) { - CPRINTS("SB-SMI: Mailbox transfer timeout"); - /* Clear interrupt */ - sb_rmi_assert_interrupt(0); - return EC_ERROR_TIMEOUT; - } - - RETURN_ERROR(sb_rmi_read(SB_RMI_OUT_BND_MSG0_REG, &val)); - if (val != cmd) { - CPRINTS("RMI: Unexpected command value in out bound message"); - sb_rmi_assert_interrupt(0); - return EC_ERROR_UNKNOWN; - } - - /* Step 8: read msgOut from {SBRMI_x34(MSB):SBRMI_x31(LSB)} */ - *msg_out_ptr = 0; - RETURN_ERROR(sb_rmi_read(SB_RMI_OUT_BND_MSG1_REG, &val)); - *msg_out_ptr |= val; - RETURN_ERROR(sb_rmi_read(SB_RMI_OUT_BND_MSG2_REG, &val)); - *msg_out_ptr |= val << 8; - RETURN_ERROR(sb_rmi_read(SB_RMI_OUT_BND_MSG3_REG, &val)); - *msg_out_ptr |= val << 16; - RETURN_ERROR(sb_rmi_read(SB_RMI_OUT_BND_MSG4_REG, &val)); - *msg_out_ptr |= val << 24; - - /* Step 9: clear SBRMIx40[Software Interrupt] */ - RETURN_ERROR(sb_rmi_assert_interrupt(0)); - - /** - * Step 10: BMC must write 1'b1 to SBRMI::Status[SwAlertSts] to clear - * the ALERT to initiator (BMC). It is recommended to clear the - * ALERT upon completion of the current mailbox command. - */ - RETURN_ERROR(sb_rmi_write(SB_RMI_STATUS_REG, 0x2)); - - /* Step 11: read the return code from OutBndMsg_inst7 (SBRMI_x37) */ - RETURN_ERROR(sb_rmi_read(SB_RMI_OUT_BND_MSG7_REG, &val)); - - switch (val) { - case SB_RMI_MAILBOX_SUCCESS: - return EC_SUCCESS; - case SB_RMI_MAILBOX_ERROR_ABORTED: - return EC_ERROR_UNKNOWN; - case SB_RMI_MAILBOX_ERROR_UNKNOWN_CMD: - return EC_ERROR_INVAL; - case SB_RMI_MAILBOX_ERROR_INVALID_CORE: - return EC_ERROR_PARAM1; - default: - return EC_ERROR_UNKNOWN; - } -} |