summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-k3/am62ax/am62a7_init.c4
-rw-r--r--arch/arm/mach-k3/am62px/am62p5_init.c4
-rw-r--r--arch/arm/mach-k3/common.c29
-rw-r--r--arch/arm/mach-k3/common.h1
-rw-r--r--arch/arm/mach-k3/j721e/j721e_init.c4
-rw-r--r--arch/arm/mach-k3/j721s2/j721s2_init.c4
-rw-r--r--arch/arm/mach-k3/j722s/j722s_init.c4
-rw-r--r--arch/arm/mach-k3/j784s4/j784s4_init.c4
-rw-r--r--drivers/firmware/ti_sci.c99
-rw-r--r--drivers/firmware/ti_sci.h42
-rw-r--r--include/linux/soc/ti/ti_sci_protocol.h39
11 files changed, 234 insertions, 0 deletions
diff --git a/arch/arm/mach-k3/am62ax/am62a7_init.c b/arch/arm/mach-k3/am62ax/am62a7_init.c
index edd43a1d78d..ac4d30052f3 100644
--- a/arch/arm/mach-k3/am62ax/am62a7_init.c
+++ b/arch/arm/mach-k3/am62ax/am62a7_init.c
@@ -172,6 +172,10 @@ void board_init_f(ulong dummy)
/* Output System Firmware version info */
k3_sysfw_print_ver();
+ /* Output DM Firmware version info */
+ if (IS_ENABLED(CONFIG_ARM64))
+ k3_dm_print_ver();
+
if (IS_ENABLED(CONFIG_ESM_K3)) {
/* Probe/configure ESM0 */
ret = uclass_get_device_by_name(UCLASS_MISC, "esm@420000", &dev);
diff --git a/arch/arm/mach-k3/am62px/am62p5_init.c b/arch/arm/mach-k3/am62px/am62p5_init.c
index 6e3c66e5107..44a2d445d24 100644
--- a/arch/arm/mach-k3/am62px/am62p5_init.c
+++ b/arch/arm/mach-k3/am62px/am62p5_init.c
@@ -224,6 +224,10 @@ void board_init_f(ulong dummy)
/* Output System Firmware version info */
k3_sysfw_print_ver();
+ /* Output DM Firmware version info */
+ if (IS_ENABLED(CONFIG_ARM64))
+ k3_dm_print_ver();
+
if (IS_ENABLED(CONFIG_K3_AM62A_DDRSS)) {
ret = uclass_get_device(UCLASS_RAM, 0, &dev);
if (ret)
diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c
index 9f1f99b19ab..f8c53b286eb 100644
--- a/arch/arm/mach-k3/common.c
+++ b/arch/arm/mach-k3/common.c
@@ -73,6 +73,35 @@ void k3_sysfw_print_ver(void)
ti_sci->version.firmware_revision, fw_desc);
}
+void __maybe_unused k3_dm_print_ver(void)
+{
+ struct ti_sci_handle *ti_sci = get_ti_sci_handle();
+ struct ti_sci_firmware_ops *fw_ops = &ti_sci->ops.fw_ops;
+ struct ti_sci_dm_version_info dm_info = {0};
+ u64 fw_caps;
+ int ret;
+
+ ret = fw_ops->query_dm_cap(ti_sci, &fw_caps);
+ if (ret) {
+ printf("Failed to query DM firmware capability %d\n", ret);
+ return;
+ }
+
+ if (!(fw_caps & TI_SCI_MSG_FLAG_FW_CAP_DM))
+ return;
+
+ ret = fw_ops->get_dm_version(ti_sci, &dm_info);
+ if (ret) {
+ printf("Failed to fetch DM firmware version %d\n", ret);
+ return;
+ }
+
+ printf("DM ABI: %d.%d (firmware ver 0x%04x '%s--%s' "
+ "patch_ver: %d)\n", dm_info.abi_major, dm_info.abi_minor,
+ dm_info.dm_ver, dm_info.sci_server_version,
+ dm_info.rm_pm_hal_version, dm_info.patch_ver);
+}
+
void mmr_unlock(uintptr_t base, u32 partition)
{
/* Translate the base address */
diff --git a/arch/arm/mach-k3/common.h b/arch/arm/mach-k3/common.h
index 6e33f578151..52d3faaab5c 100644
--- a/arch/arm/mach-k3/common.h
+++ b/arch/arm/mach-k3/common.h
@@ -42,6 +42,7 @@ int remove_fwl_region(struct fwl_data *fwl);
void remove_fwl_configs(struct fwl_data *fwl_data, size_t fwl_data_size);
int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr);
void k3_sysfw_print_ver(void);
+void k3_dm_print_ver(void);
void spl_enable_cache(void);
void mmr_unlock(uintptr_t base, u32 partition);
bool is_rom_loaded_sysfw(struct rom_extended_boot_data *data);
diff --git a/arch/arm/mach-k3/j721e/j721e_init.c b/arch/arm/mach-k3/j721e/j721e_init.c
index edca2634fb9..f9af0288cf6 100644
--- a/arch/arm/mach-k3/j721e/j721e_init.c
+++ b/arch/arm/mach-k3/j721e/j721e_init.c
@@ -381,6 +381,10 @@ void board_init_f(ulong dummy)
/* Output System Firmware version info */
k3_sysfw_print_ver();
+ /* Output DM Firmware version info */
+ if (IS_ENABLED(CONFIG_ARM64))
+ k3_dm_print_ver();
+
/* Perform board detection */
do_board_detect();
diff --git a/arch/arm/mach-k3/j721s2/j721s2_init.c b/arch/arm/mach-k3/j721s2/j721s2_init.c
index 6342161f830..eee3d0440ac 100644
--- a/arch/arm/mach-k3/j721s2/j721s2_init.c
+++ b/arch/arm/mach-k3/j721s2/j721s2_init.c
@@ -239,6 +239,10 @@ void k3_spl_init(void)
/* Output System Firmware version info */
k3_sysfw_print_ver();
+
+ /* Output DM Firmware version info */
+ if (IS_ENABLED(CONFIG_ARM64))
+ k3_dm_print_ver();
}
bool check_rom_loaded_sysfw(void)
diff --git a/arch/arm/mach-k3/j722s/j722s_init.c b/arch/arm/mach-k3/j722s/j722s_init.c
index af211377e7c..d8123f282ee 100644
--- a/arch/arm/mach-k3/j722s/j722s_init.c
+++ b/arch/arm/mach-k3/j722s/j722s_init.c
@@ -150,6 +150,10 @@ static void k3_spl_init(void)
/* Output System Firmware version info */
k3_sysfw_print_ver();
+
+ /* Output DM Firmware version info */
+ if (IS_ENABLED(CONFIG_ARM64))
+ k3_dm_print_ver();
}
static void k3_mem_init(void)
diff --git a/arch/arm/mach-k3/j784s4/j784s4_init.c b/arch/arm/mach-k3/j784s4/j784s4_init.c
index 5c06632a5ca..0f11511bda0 100644
--- a/arch/arm/mach-k3/j784s4/j784s4_init.c
+++ b/arch/arm/mach-k3/j784s4/j784s4_init.c
@@ -215,6 +215,10 @@ void k3_spl_init(void)
/* Output System Firmware version info */
k3_sysfw_print_ver();
+
+ /* Output DM Firmware version info */
+ if (IS_ENABLED(CONFIG_ARM64))
+ k3_dm_print_ver();
}
void k3_mem_init(void)
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index 344df9454b3..8013afef304 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -279,6 +279,101 @@ static int ti_sci_do_xfer(struct ti_sci_info *info,
}
/**
+ * ti_sci_cmd_query_dm_cap() - Command to query DM firmware's capabilities
+ * @handle: Pointer to TI SCI handle
+ * @fw_caps: Pointer to firmware capabilities
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_cmd_query_dm_cap(struct ti_sci_handle *handle, u64 *fw_caps)
+{
+ struct ti_sci_query_fw_caps_resp *cap_info;
+ struct ti_sci_msg_hdr hdr;
+ struct ti_sci_info *info;
+ struct ti_sci_xfer *xfer;
+ int ret;
+
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ if (!handle)
+ return -EINVAL;
+
+ info = handle_to_ti_sci_info(handle);
+
+ xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_QUERY_FW_CAPS,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ (u32 *)&hdr, sizeof(struct ti_sci_msg_hdr),
+ sizeof(*cap_info));
+ if (IS_ERR(xfer)) {
+ ret = PTR_ERR(xfer);
+ return ret;
+ }
+
+ ret = ti_sci_do_xfer(info, xfer);
+ if (ret)
+ return ret;
+
+ cap_info = (struct ti_sci_query_fw_caps_resp *)xfer->tx_message.buf;
+
+ *fw_caps = cap_info->fw_caps;
+
+ return 0;
+}
+
+/**
+ * ti_sci_cmd_get_dm_version() - command to get the DM version of the SCI
+ * entity
+ * @handle: Pointer to TI SCI handle
+ * @dm_info: Pointer to DM version information structure
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+
+static int ti_sci_cmd_get_dm_version(struct ti_sci_handle *handle,
+ struct ti_sci_dm_version_info *dm_info)
+{
+ struct ti_sci_msg_dm_resp_version *ver_info;
+ struct ti_sci_msg_hdr hdr;
+ struct ti_sci_info *info;
+ struct ti_sci_xfer *xfer;
+ int ret;
+
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ if (!handle || !dm_info)
+ return -EINVAL;
+
+ info = handle_to_ti_sci_info(handle);
+
+ xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_DM_VERSION,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ (u32 *)&hdr, sizeof(struct ti_sci_msg_hdr),
+ sizeof(*ver_info));
+ if (IS_ERR(xfer)) {
+ ret = PTR_ERR(xfer);
+ return ret;
+ }
+
+ ret = ti_sci_do_xfer(info, xfer);
+ if (ret)
+ return ret;
+
+ ver_info = (struct ti_sci_msg_dm_resp_version *)xfer->tx_message.buf;
+
+ dm_info->abi_major = ver_info->abi_major;
+ dm_info->abi_minor = ver_info->abi_minor;
+ dm_info->dm_ver = ver_info->version;
+ dm_info->patch_ver = ver_info->patch_version;
+ dm_info->sub_ver = ver_info->sub_version;
+ strlcpy(dm_info->sci_server_version, ver_info->sci_server_version,
+ sizeof(ver_info->sci_server_version));
+ strlcpy(dm_info->rm_pm_hal_version, ver_info->rm_pm_hal_version,
+ sizeof(ver_info->rm_pm_hal_version));
+
+ return 0;
+}
+
+/**
* ti_sci_cmd_get_revision() - command to get the revision of the SCI entity
* @handle: pointer to TI SCI handle
*
@@ -2624,6 +2719,7 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
struct ti_sci_dev_ops *dops = &ops->dev_ops;
struct ti_sci_clk_ops *cops = &ops->clk_ops;
struct ti_sci_core_ops *core_ops = &ops->core_ops;
+ struct ti_sci_firmware_ops *fw_ops = &ops->fw_ops;
struct ti_sci_rm_core_ops *rm_core_ops = &ops->rm_core_ops;
struct ti_sci_proc_ops *pops = &ops->proc_ops;
struct ti_sci_rm_ringacc_ops *rops = &ops->rm_ring_ops;
@@ -2694,6 +2790,9 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
fwl_ops->set_fwl_region = ti_sci_cmd_set_fwl_region;
fwl_ops->get_fwl_region = ti_sci_cmd_get_fwl_region;
fwl_ops->change_fwl_owner = ti_sci_cmd_change_fwl_owner;
+
+ fw_ops->get_dm_version = ti_sci_cmd_get_dm_version;
+ fw_ops->query_dm_cap = ti_sci_cmd_query_dm_cap;
}
/**
diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h
index bb8bc7beead..ce50bf6800e 100644
--- a/drivers/firmware/ti_sci.h
+++ b/drivers/firmware/ti_sci.h
@@ -26,7 +26,9 @@
#define TI_SCI_MSG_BOARD_CONFIG_RM 0x000c
#define TI_SCI_MSG_BOARD_CONFIG_SECURITY 0x000d
#define TI_SCI_MSG_BOARD_CONFIG_PM 0x000e
+#define TI_SCI_MSG_DM_VERSION 0x000f
#define TISCI_MSG_QUERY_MSMC 0x0020
+#define TI_SCI_MSG_QUERY_FW_CAPS 0x0022
/* Device requests */
#define TI_SCI_MSG_SET_DEVICE_STATE 0x0200
@@ -135,6 +137,46 @@ struct ti_sci_msg_resp_version {
} __packed;
/**
+ * struct ti_sci_msg_dm_resp_version - Response for a message
+ * @hdr: Generic header
+ * @version: Version number of the firmware
+ * @sub_version: Sub-version number of the firmware
+ * @patch_version: Patch version number of the firmware
+ * @abi_major: Major version of the ABI that firmware supports
+ * @abi_minor: Minor version of the ABI that firmware supports
+ * @sci_server_version: String describing the SCI server version
+ * @rm_pm_hal_version: String describing the RM PM HAL version
+ *
+ * In general, ABI version changes follow the rule that minor version increments
+ * are backward compatible. Major revision changes in ABI may not be
+ * backward compatible.
+ *
+ * Response to a message with message type TI_SCI_MSG_DM_VERSION
+ */
+struct ti_sci_msg_dm_resp_version {
+ struct ti_sci_msg_hdr hdr;
+ u16 version;
+ u8 sub_version;
+ u8 patch_version;
+ u8 abi_major;
+ u8 abi_minor;
+ char rm_pm_hal_version[12];
+ char sci_server_version[26];
+} __packed;
+
+/**
+ * struct ti_sci_query_fw_caps_resp - Response for a message
+ * @hdr: Generic header
+ * @fw_caps: 64-bit value representing the FW/SOC capabilities.
+ *
+ * Response to a message with message type TI_SCI_MSG_QUERY_FW_CAPS
+ */
+struct ti_sci_query_fw_caps_resp {
+ struct ti_sci_msg_hdr hdr;
+ u64 fw_caps;
+} __packed;
+
+/**
* struct ti_sci_msg_req_reboot - Reboot the SoC
* @hdr: Generic Header
* @domain: Domain to be reset, 0 for full SoC reboot.
diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h
index aa4d105ee98..52696763ecf 100644
--- a/include/linux/soc/ti/ti_sci_protocol.h
+++ b/include/linux/soc/ti/ti_sci_protocol.h
@@ -30,6 +30,28 @@ struct ti_sci_version_info {
char firmware_description[32];
};
+/**
+ * struct ti_sci_dm_version_info - version information structure
+ * @abi_major: Major ABI version. Change here implies risk of backward
+ * compatibility break.
+ * @abi_minor: Minor ABI version. Change here implies new feature addition,
+ * or compatible change in ABI.
+ * @patch_ver: Patch version of the firmware.
+ * @sub_ver: Sub-version of the firmware.
+ * @dm_ver: DM version.
+ * @sci_server_version: Version string of the SCI server.
+ * @rm_pm_hal_version: Version string of the RM PM HAL.
+ */
+struct ti_sci_dm_version_info {
+ u8 abi_major;
+ u8 abi_minor;
+ u8 patch_ver;
+ u8 sub_ver;
+ u16 dm_ver;
+ char rm_pm_hal_version[12];
+ char sci_server_version[26];
+};
+
struct ti_sci_handle;
/**
@@ -262,6 +284,22 @@ struct ti_sci_core_ops {
};
/**
+ * struct ti_sci_firmware_ops - DM firmware operations
+ * @query_dm_cap: Query the DM capabilities
+ * Return 0 for successful query else appropriate error value.
+ * @get_dm_version: Get the DM version.
+ * Return 0 for successful request else appropriate error value.
+ */
+struct ti_sci_firmware_ops {
+ int (*query_dm_cap)(struct ti_sci_handle *handle,
+ u64 *dm_cap);
+ int (*get_dm_version)(struct ti_sci_handle *handle,
+ struct ti_sci_dm_version_info *get_dm_version);
+};
+
+#define TI_SCI_MSG_FLAG_FW_CAP_DM 0x100
+
+/**
* struct ti_sci_proc_ops - Processor specific operations.
*
* @proc_request: Request for controlling a physical processor.
@@ -609,6 +647,7 @@ struct ti_sci_ops {
struct ti_sci_dev_ops dev_ops;
struct ti_sci_clk_ops clk_ops;
struct ti_sci_core_ops core_ops;
+ struct ti_sci_firmware_ops fw_ops;
struct ti_sci_proc_ops proc_ops;
struct ti_sci_rm_core_ops rm_core_ops;
struct ti_sci_rm_ringacc_ops rm_ring_ops;