[U-Boot] [PATCH v1 08/16] arm: socfpga: stratix10: Add mailbox support for Stratix10 SoC

Ley Foon Tan lftan.linux at gmail.com
Tue May 8 06:49:26 UTC 2018


On Thu, Apr 19, 2018 at 10:53 AM, Marek Vasut <marex at denx.de> wrote:
> On 04/19/2018 11:50 AM, Ley Foon Tan wrote:
>> Add mailbox support for Stratix SoC
>>
>> Signed-off-by: Ley Foon Tan <ley.foon.tan at intel.com>
>> Signed-off-by: Chin Liang See <chin.liang.see at intel.com>
>> ---
>>  arch/arm/mach-socfpga/Makefile                   |    1 +
>>  arch/arm/mach-socfpga/include/mach/mailbox_s10.h |  155 +++++++++
>>  arch/arm/mach-socfpga/mailbox_s10.c              |  378 ++++++++++++++++++++++
>>  3 files changed, 534 insertions(+), 0 deletions(-)
>>  create mode 100644 arch/arm/mach-socfpga/include/mach/mailbox_s10.h
>>  create mode 100644 arch/arm/mach-socfpga/mailbox_s10.c
>>
>> diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
>> index b253914..43e18d2 100644
>> --- a/arch/arm/mach-socfpga/Makefile
>> +++ b/arch/arm/mach-socfpga/Makefile
>> @@ -32,6 +32,7 @@ endif
>>
>>  ifdef CONFIG_TARGET_SOCFPGA_STRATIX10
>>  obj-y        += clock_manager_s10.o
>> +obj-y        += mailbox_s10.o
>>  obj-y        += misc_s10.o
>>  obj-y        += reset_manager_s10.o
>>  obj-y        += system_manager_s10.o
>> diff --git a/arch/arm/mach-socfpga/include/mach/mailbox_s10.h b/arch/arm/mach-socfpga/include/mach/mailbox_s10.h
>> new file mode 100644
>> index 0000000..85e7f84
>> --- /dev/null
>> +++ b/arch/arm/mach-socfpga/include/mach/mailbox_s10.h
>> @@ -0,0 +1,155 @@
>> +/* SPDX-License-Identifier: GPL-2.0
>> + *
>> + * Copyright (C) 2017-2018 Intel Corporation <www.intel.com>
>> + *
>> + */
>> +
>> +#ifndef _MAILBOX_S10_H_
>> +#define _MAILBOX_S10_H_
>> +
>> +/* user define Uboot ID */
>> +#define MBOX_CLIENT_ID_UBOOT 0xB
>> +#define MBOX_ID_UBOOT                0x1
>> +
>> +#define MBOX_CMD_DIRECT      0
>> +#define MBOX_CMD_INDIRECT    1
>> +
>> +#define MBOX_MAX_CMD_INDEX   2047
>> +#define MBOX_CMD_BUFFER_SIZE 32
>> +#define MBOX_RESP_BUFFER_SIZE        16
>> +
>> +#define MBOX_HDR_CMD_LSB     0
>> +#define MBOX_HDR_CMD_MSK     (BIT(11) - 1)
>> +#define MBOX_HDR_I_LSB               11
>> +#define MBOX_HDR_I_MSK               BIT(11)
>> +#define MBOX_HDR_LEN_LSB     12
>> +#define MBOX_HDR_LEN_MSK     0x007FF000
>> +#define MBOX_HDR_ID_LSB              24
>> +#define MBOX_HDR_ID_MSK              0x0F000000
>> +#define MBOX_HDR_CLIENT_LSB  28
>> +#define MBOX_HDR_CLIENT_MSK  0xF0000000
>> +
>> +/* Interrupt flags */
>> +#define MBOX_FLAGS_INT_COE   BIT(0)  /* COUT update interrupt enable */
>> +#define MBOX_FLAGS_INT_RIE   BIT(1)  /* RIN update interrupt enable */
>> +#define MBOX_FLAGS_INT_UAE   BIT(8)  /* Urgent ACK interrupt enable */
>> +#define MBOX_ALL_INTRS               (MBOX_FLAGS_INT_COE | \
>> +                              MBOX_FLAGS_INT_RIE | \
>> +                              MBOX_FLAGS_INT_UAE)
>> +
>> +/* Status */
>> +#define MBOX_STATUS_UA_MSK   BIT(8)
>> +
>> +#define MBOX_CMD_HEADER(client, id, len, indirect, cmd)     \
>> +     ((((cmd) << MBOX_HDR_CMD_LSB) & MBOX_HDR_CMD_MSK) | \
>> +     (((indirect) << MBOX_HDR_I_LSB) & MBOX_HDR_I_MSK) | \
>> +     (((len) << MBOX_HDR_LEN_LSB) & MBOX_HDR_LEN_MSK)  | \
>> +     (((id) << MBOX_HDR_ID_LSB) & MBOX_HDR_ID_MSK)     | \
>> +     (((client) << MBOX_HDR_CLIENT_LSB) & MBOX_HDR_CLIENT_MSK))
>> +
>> +#define MBOX_RESP_ERR_GET(resp)                              \
>> +     (((resp) & MBOX_HDR_CMD_MSK) >> MBOX_HDR_CMD_LSB)
>> +#define MBOX_RESP_LEN_GET(resp)                      \
>> +     (((resp) & MBOX_HDR_LEN_MSK) >> MBOX_HDR_LEN_LSB)
>> +#define MBOX_RESP_ID_GET(resp)                               \
>> +     (((resp) & MBOX_HDR_ID_MSK) >> MBOX_HDR_ID_LSB)
>> +#define MBOX_RESP_CLIENT_GET(resp)                   \
>> +     (((resp) & MBOX_HDR_CLIENT_MSK) >> MBOX_HDR_CLIENT_LSB)
>> +
>> +/* Response error list */
>> +enum ALT_SDM_MBOX_RESP_CODE {
>> +     /* CMD completed successfully, but check resp ARGS for any errors */
>> +     MBOX_RESP_STATOK = 0,
>> +     /* CMD is incorrectly formatted in some way */
>> +     MBOX_RESP_INVALID_COMMAND = 1,
>> +     /* BootROM Command code not undesrtood */
>> +     MBOX_RESP_UNKNOWN_BR = 2,
>> +     /* CMD code not recognized by firmware */
>> +     MBOX_RESP_UNKNOWN = 3,
>> +     /* Indicates that the device is not configured */
>> +     MBOX_RESP_NOT_CONFIGURED = 256,
>> +     /* Indicates that the device is busy */
>> +     MBOX_RESP_DEVICE_BUSY = 0x1FF,
>> +     /* Indicates that there is no valid response available */
>> +     MBOX_RESP_NO_VALID_RESP_AVAILABLE = 0x2FF,
>> +     /* General Error */
>> +     MBOX_RESP_ERROR = 0x3FF,
>> +};
>> +
>> +/* Mailbox command list */
>> +#define MBOX_RESTART         2
>> +#define MBOX_CONFIG_STATUS   4
>> +#define MBOX_RECONFIG                6
>> +#define MBOX_RECONFIG_MSEL   7
>> +#define MBOX_RECONFIG_DATA   8
>> +#define MBOX_RECONFIG_STATUS 9
>> +#define MBOX_QSPI_OPEN               50
>> +#define MBOX_QSPI_CLOSE              51
>> +#define MBOX_QSPI_DIRECT     59
>> +#define MBOX_REBOOT_HPS              71
>> +
>> +struct socfpga_mailbox {
>
> We should probably just use register offset macros in new code, this
> struct {} stuff often doesn't work too well and the limitations are showing.
Okay, will change this.
>
>> +     u32 cin;                /* command valid offset */
>> +     u32 rout;               /* response output offset */
>> +     u32 urg;                /* urgent command */
>> +     u32 flags;              /* interrupt enables */
>> +     u32 pad_0x10_0x1f[4];   /* 0x10 - 0x1F reserved */
>> +     u32 cout;               /* command free offset */
>> +     u32 rin;                /* respond valid offset */
>> +     u32 pad_0x28;           /* 0x28 reserved */
>> +     u32 status;             /* mailbox status */
>> +     u32 pad_0x30_0x3f[4];   /* 0x30 - 0x3F reserved */
>> +     u32 cmd_buf[MBOX_CMD_BUFFER_SIZE];      /* 0x40 - 0xBC circular command
>> +                                              * buffer to SDM
>> +                                              */
>> +     u32 resp_buf[MBOX_RESP_BUFFER_SIZE];    /* 0xC0 - 0xFF circular
>> +                                              * response buffer
>> +                                              */
>> +};
>> +
>> +/* Use define other than put into struct socfpga_mailbox to save spaces */
>> +#define MBOX_DOORBELL_TO_SDM_REG     (SOCFPGA_MAILBOX_ADDRESS + 0x400)
>> +#define MBOX_DOORBELL_FROM_SDM_REG   (SOCFPGA_MAILBOX_ADDRESS + 0x480)
>> +
>> +/******** Status and bit information returned by RECONFIG_STATUS ********/
>> +#define RECONFIG_STATUS_RESPONSE_LEN                 6
>> +#define RECONFIG_STATUS_STATE                                0
>> +#define RECONFIG_STATUS_PIN_STATUS                   2
>> +#define RECONFIG_STATUS_SOFTFUNC_STATUS                      3
>> +
>> +#define MBOX_CFGSTAT_STATE_IDLE                              0x00000000
>> +#define MBOX_CFGSTAT_STATE_CONFIG                    0x10000000
>> +#define MBOX_CFGSTAT_STATE_FAILACK                   0x08000000
>> +#define MBOX_CFGSTAT_STATE_ERROR_INVALID             0xf0000001
>> +#define MBOX_CFGSTAT_STATE_ERROR_CORRUPT             0xf0000002
>> +#define MBOX_CFGSTAT_STATE_ERROR_AUTH                        0xf0000003
>> +#define MBOX_CFGSTAT_STATE_ERROR_CORE_IO             0xf0000004
>> +#define MBOX_CFGSTAT_STATE_ERROR_HARDWARE            0xf0000005
>> +#define MBOX_CFGSTAT_STATE_ERROR_FAKE                        0xf0000006
>> +#define MBOX_CFGSTAT_STATE_ERROR_BOOT_INFO           0xf0000007
>> +#define MBOX_CFGSTAT_STATE_ERROR_QSPI_ERROR          0xf0000008
>> +
>> +#define RCF_SOFTFUNC_STATUS_CONF_DONE                        BIT(0)
>> +#define RCF_SOFTFUNC_STATUS_INIT_DONE                        BIT(1)
>> +#define RCF_SOFTFUNC_STATUS_SEU_ERROR                        BIT(3)
>> +#define RCF_PIN_STATUS_NSTATUS                               BIT(31)
>> +/************************************************************************/
>> +
>> +int mbox_send_cmd(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg, u8 urgent,
>> +               u32 *resp_buf_len, u32 *resp_buf);
>> +int mbox_send_cmd_psci(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg,
>> +                    u8 urgent, u32 *resp_buf_len, u32 *resp_buf);
>> +int mbox_send_cmd_only(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg);
>> +int mbox_send_cmd_only_psci(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg);
>> +int mbox_rcv_resp(u32 *resp_buf, u32 resp_buf_max_len);
>> +int mbox_rcv_resp_psci(u32 *resp_buf, u32 resp_buf_max_len);
>> +int mbox_init(void);
>> +
>> +#ifdef CONFIG_CADENCE_QSPI
>> +int mbox_qspi_close(void);
>> +int mbox_qspi_open(void);
>> +#endif
>> +
>> +int mbox_reset_cold(void);
>> +
>> +#endif /* _MAILBOX_S10_H_ */
>> diff --git a/arch/arm/mach-socfpga/mailbox_s10.c b/arch/arm/mach-socfpga/mailbox_s10.c
>> new file mode 100644
>> index 0000000..ed713a9
>> --- /dev/null
>> +++ b/arch/arm/mach-socfpga/mailbox_s10.c
>> @@ -0,0 +1,378 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (C) 2017-2018 Intel Corporation <www.intel.com>
>> + *
>> + */
>> +
>> +#include <common.h>
>> +#include <wait_bit.h>
>> +#include <asm/io.h>
>> +#include <asm/arch/mailbox_s10.h>
>> +#include <asm/arch/system_manager.h>
>> +#include <asm/secure.h>
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +static __always_inline int mbox_polling_resp(u32 rout)
>> +{
>> +     static const struct socfpga_mailbox *mbox_base =
>> +                                     (void *)SOCFPGA_MAILBOX_ADDRESS;
>> +     u32 rin;
>> +     unsigned long i = ~0;
>> +
>> +     while (i) {
>> +             rin = readl(&mbox_base->rin);
>> +             if (rout != rin)
>> +                     return 0;
>
> This looks like include/wait_bit.h reimplementation
The reason we use this method instead of using wait_bit because this
function will use in Secure Monitor Call (SMC) call as well.
When run in secure section, timer is not available.  So, we can't use
wait_for_bit.

>
>> +             i--;
>> +     }
>> +
>> +     return -ETIMEDOUT;
>> +}
>> +
>> +/* Check for available slot and write to circular buffer.
>> + * It also update command valid offset (cin) register.
>> + */
>> +static __always_inline int mbox_fill_cmd_circular_buff(u32 header, u32 len,
>> +                                                    u32 *arg)
>> +{
>> +     static const struct socfpga_mailbox *mbox_base =
>> +                                     (void *)SOCFPGA_MAILBOX_ADDRESS;
>> +     u32 cin;
>> +     u32 cout;
>> +     u32 i;
>> +
>> +     cin = readl(&mbox_base->cin) % MBOX_CMD_BUFFER_SIZE;
>> +     cout = readl(&mbox_base->cout) % MBOX_CMD_BUFFER_SIZE;
>> +
>> +     /* if command buffer is full or not enough free space
>> +      * to fit the data
>> +      */
>> +     if (((cin + 1) % MBOX_CMD_BUFFER_SIZE) == cout ||
>> +         ((MBOX_CMD_BUFFER_SIZE - cin + cout - 1) %
>> +          MBOX_CMD_BUFFER_SIZE) < len)
>> +             return -ENOMEM;
>> +
>> +     /* write header to circular buffer */
>> +     writel(header, &mbox_base->cmd_buf[cin++]);
>> +     /* wrapping around when it reach the buffer size */
>> +     cin %= MBOX_CMD_BUFFER_SIZE;
>> +
>> +     /* write arguments */
>> +     for (i = 0; i < len; i++) {
>> +             writel(arg[i], &mbox_base->cmd_buf[cin++]);
>> +             /* wrapping around when it reach the buffer size */
>> +             cin %= MBOX_CMD_BUFFER_SIZE;
>> +     }
>> +
>> +     /* write command valid offset */
>> +     writel(cin, &mbox_base->cin);
>> +
>> +     return 0;
>> +}
>> +
>> +/* Check the command and fill it into circular buffer */
>> +static __always_inline int mbox_prepare_cmd_only(u8 id, u32 cmd,
>> +                                              u8 is_indirect, u32 len,
>> +                                              u32 *arg)
>> +{
>> +     u32 header;
>> +     int ret;
>> +
>> +     /* Total length is command + argument length */
>> +     if ((len + 1) > MBOX_CMD_BUFFER_SIZE)
>> +             return -EINVAL;
>> +
>> +     if (cmd > MBOX_MAX_CMD_INDEX)
>> +             return -EINVAL;
>> +
>> +     header = MBOX_CMD_HEADER(MBOX_CLIENT_ID_UBOOT, id, len,
>> +                              (is_indirect) ? 1 : 0, cmd);
>> +
>> +     ret = mbox_fill_cmd_circular_buff(header, len, arg);
>> +
>> +     return ret;
>> +}
>> +
>> +/* Send command only without waiting for responses from SDM */
>> +static __always_inline int __mbox_send_cmd_only(u8 id, u32 cmd,
>> +                                             u8 is_indirect, u32 len,
>> +                                             u32 *arg)
>> +{
>> +     int ret = mbox_prepare_cmd_only(id, cmd, is_indirect, len, arg);
>> +     /* write doorbell */
>> +     writel(1, MBOX_DOORBELL_TO_SDM_REG);
>> +
>> +     return ret;
>> +}
>> +
>> +/* Return number of responses received in buffer */
>> +static __always_inline int __mbox_rcv_resp(u32 *resp_buf, u32 resp_buf_max_len)
>
> __always_inline is nonsense, drop it. Let the compiler do it's thing.
This function used in SMC call as well, so it needs to be inline when
in secure section.

>
>> +{
>> +     static const struct socfpga_mailbox *mbox_base =
>> +                                     (void *)SOCFPGA_MAILBOX_ADDRESS;
>> +     u32 rin;
>> +     u32 rout;
>> +     u32 resp_len = 0;
>> +
>> +     /* clear doorbell from SDM if it was SET */
>> +     if (readl((const u32 *)MBOX_DOORBELL_FROM_SDM_REG) & 1)
>> +             writel(0, MBOX_DOORBELL_FROM_SDM_REG);
>> +
>> +     /* read current response offset */
>> +     rout = readl(&mbox_base->rout);
>> +     /* read response valid offset */
>> +     rin = readl(&mbox_base->rin);
>> +
>> +     while (rin != rout && (resp_len < resp_buf_max_len)) {
>> +             /* Response received */
>> +             if (resp_buf)
>> +                     resp_buf[resp_len++] =
>> +                             readl(&mbox_base->resp_buf[rout]);
>> +             rout++;
>> +             /* wrapping around when it reach the buffer size */
>> +             rout %= MBOX_RESP_BUFFER_SIZE;
>> +             /* update next ROUT */
>> +             writel(rout, &mbox_base->rout);
>> +     }
>> +
>> +     return resp_len;
>> +}
>> +
>> +/* Support one command and up to 31 words argument length only */
>> +static __always_inline int __mbox_send_cmd(u8 id, u32 cmd, u8 is_indirect,
>> +                                        u32 len, u32 *arg, u8 urgent,
>> +                                        u32 *resp_buf_len, u32 *resp_buf)
>> +{
>> +     static const struct socfpga_mailbox *mbox_base =
>> +                                     (void *)SOCFPGA_MAILBOX_ADDRESS;
>> +
>> +     u32 rin;
>> +     u32 resp;
>> +     u32 rout;
>> +     u32 status;
>> +     u32 resp_len;
>> +     u32 buf_len;
>> +     int ret;
>> +
>> +     ret = mbox_prepare_cmd_only(id, cmd, is_indirect, len, arg);
>> +     if (ret)
>> +             return ret;
>> +
>> +     if (urgent) {
>> +             /* Read status because it is toggled */
>> +             status = readl(&mbox_base->status) & MBOX_STATUS_UA_MSK;
>> +             /* Send command as urgent command */
>> +             writel(1, &mbox_base->urg);
>> +     }
>> +
>> +     /* write doorbell */
>> +     writel(1, MBOX_DOORBELL_TO_SDM_REG);
>> +
>> +     while (1) {
>> +             ret = ~0;
>> +
>> +             /* Wait for doorbell from SDM */
>> +             while (!readl(MBOX_DOORBELL_FROM_SDM_REG) && ret--)
>> +                     ;
>> +             if (!ret)
>> +                     return -ETIMEDOUT;
>
> wait_for_bit...
Same reason as above.
>
>> +             /* clear interrupt */
>> +             writel(0, MBOX_DOORBELL_FROM_SDM_REG);
>> +
>> +             if (urgent) {
>> +                     u32 new_status = readl(&mbox_base->status);
>> +                     /* urgent command doesn't have response */
>> +                     writel(0, &mbox_base->urg);
>> +                     /* Urgent ACK is toggled */
>> +                     if ((new_status & MBOX_STATUS_UA_MSK) ^ status)
>> +                             return 0;
>> +
>> +                     return -ECOMM;
>> +             }
>> +
>> +             /* read current response offset */
>> +             rout = readl(&mbox_base->rout);
>> +
>> +             /* read response valid offset */
>> +             rin = readl(&mbox_base->rin);
>> +
>> +             if (rout != rin) {
>> +                     /* Response received */
>> +                     resp = readl(&mbox_base->resp_buf[rout]);
>> +                     rout++;
>> +                     /* wrapping around when it reach the buffer size */
>> +                     rout %= MBOX_RESP_BUFFER_SIZE;
>> +                     /* update next ROUT */
>> +                     writel(rout, &mbox_base->rout);
>> +
>> +                     /* check client ID and ID */
>> +                     if ((MBOX_RESP_CLIENT_GET(resp) == MBOX_CLIENT_ID_UBOOT) &&
>> +                         (MBOX_RESP_ID_GET(resp) == id)) {
>> +                             ret = MBOX_RESP_ERR_GET(resp);
>> +                             if (ret)
>> +                                     return ret;
>> +
>> +                             if (resp_buf_len) {
>> +                                     buf_len = *resp_buf_len;
>> +                                     *resp_buf_len = 0;
>> +                             } else {
>> +                                     buf_len = 0;
>> +                             }
>> +
>> +                             resp_len = MBOX_RESP_LEN_GET(resp);
>> +                             while (resp_len) {
>> +                                     ret = mbox_polling_resp(rout);
>> +                                     if (ret)
>> +                                             return ret;
>> +                                     /* we need to process response buffer
>> +                                      * even caller doesn't need it
>> +                                      */
>> +                                     resp = readl(&mbox_base->resp_buf[rout]);
>> +                                     rout++;
>> +                                     resp_len--;
>> +                                     rout %= MBOX_RESP_BUFFER_SIZE;
>> +                                     writel(rout, &mbox_base->rout);
>> +                                     if (buf_len) {
>> +                                             /* copy response to buffer */
>> +                                             resp_buf[*resp_buf_len] = resp;
>> +                                             (*resp_buf_len)++;
>> +                                             buf_len--;
>> +                                     }
>> +                             }
>> +                             return ret;
>> +                     }
>> +             }
>> +     };
>> +
>> +     return -EIO;
>> +}
>> +
>> +int mbox_init(void)
>> +{
>> +     static const struct socfpga_mailbox *mbox_base =
>> +                                     (void *)SOCFPGA_MAILBOX_ADDRESS;
>> +     int ret;
>> +
>> +     /* enable mailbox interrupts */
>> +     writel(MBOX_ALL_INTRS, &mbox_base->flags);
>> +
>> +     /* Ensure urgent request is cleared */
>> +     writel(0, &mbox_base->urg);
>> +
>> +     /* Ensure the Doorbell Interrupt is cleared */
>> +     writel(0, MBOX_DOORBELL_FROM_SDM_REG);
>> +
>> +     ret = mbox_send_cmd(MBOX_ID_UBOOT, MBOX_RESTART, MBOX_CMD_DIRECT, 0,
>> +                         NULL, 1, 0, NULL);
>> +     if (ret)
>> +             return ret;
>> +
>> +     /* Renable mailbox interrupts after MBOX_RESTART */
>> +     writel(MBOX_ALL_INTRS, &mbox_base->flags);
>> +
>> +     return 0;
>> +}
>> +
>> +#ifdef CONFIG_CADENCE_QSPI
>> +int mbox_qspi_close(void)
>> +{
>> +     return mbox_send_cmd(MBOX_ID_UBOOT, MBOX_QSPI_CLOSE, MBOX_CMD_DIRECT,
>> +                          0, NULL, 0, 0, NULL);
>> +}
>> +
>> +int mbox_qspi_open(void)
>> +{
>> +     static const struct socfpga_system_manager *sysmgr_regs =
>> +             (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;
>> +
>> +     int ret;
>> +     u32 resp_buf[1];
>> +     u32 resp_buf_len;
>> +
>> +     ret = mbox_send_cmd(MBOX_ID_UBOOT, MBOX_QSPI_OPEN, MBOX_CMD_DIRECT,
>> +                         0, NULL, 0, 0, NULL);
>> +     if (ret) {
>> +             /* retry again by closing and reopen the QSPI again */
>> +             ret = mbox_qspi_close();
>> +             if (ret)
>> +                     return ret;
>> +
>> +             ret = mbox_send_cmd(MBOX_ID_UBOOT, MBOX_QSPI_OPEN,
>> +                                 MBOX_CMD_DIRECT, 0, NULL, 0, 0, NULL);
>> +             if (ret)
>> +                     return ret;
>> +     }
>> +
>> +     /* HPS will directly control the QSPI controller, no longer mailbox */
>> +     resp_buf_len = 1;
>> +     ret = mbox_send_cmd(MBOX_ID_UBOOT, MBOX_QSPI_DIRECT, MBOX_CMD_DIRECT,
>> +                         0, NULL, 0, (u32 *)&resp_buf_len,
>> +                         (u32 *)&resp_buf);
>> +     if (ret)
>> +             goto error;
>> +
>> +     /* We are getting QSPI ref clock and set into sysmgr boot register */
>> +     printf("QSPI: Reference clock at %d Hz\n", resp_buf[0]);
>
> Certainly something I can get out of clock or clk command, drop the print.
In Stratix 10, QSPI IP is not in HPS, but in the SDM side. So, SW
needs send mailbox command to get QSPI clock.
Will change printf to debug().

>
>> +     writel(resp_buf[0], &sysmgr_regs->boot_scratch_cold0);
>> +
>> +     return 0;
>> +
>> +error:
>> +     mbox_qspi_close();
>> +
>> +     return ret;
>> +}
>> +#endif /* CONFIG_CADENCE_QSPI */
>> +
>> +int mbox_reset_cold(void)
>> +{
>> +     int ret;
>> +
>> +     ret = mbox_send_cmd(MBOX_ID_UBOOT, MBOX_REBOOT_HPS, MBOX_CMD_DIRECT,
>> +                         0, NULL, 0, 0, NULL);
>> +     if (ret) {
>> +             /* mailbox sent failure, wait for watchdog to kick in */
>> +             while (1)
>> +                     ;
>
> Is this supposed to be hang() ?
Okay, will change this.

>
>> +     }
>> +     return 0;
>> +}
>> +
>> +int mbox_send_cmd(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg,
>> +               u8 urgent, u32 *resp_buf_len, u32 *resp_buf)
>> +{
>> +     return __mbox_send_cmd(id, cmd, is_indirect, len, arg, urgent,
>> +                            resp_buf_len, resp_buf);
>> +}
>
> __anything is reserved for compiler, drop the leading underscores
Okay, will change to other name.

>>
>
>
> --
> Best regards,
> Marek Vasut


More information about the U-Boot mailing list