feat(intel): add SMC support for HWMON voltage and temp sensor

Add support to read temperature and voltage using SMC command

Signed-off-by: Kris Chaplin <kris.chaplin@linux.intel.com>
Signed-off-by: Jit Loon Lim <jit.loon.lim@intel.com>
Change-Id: I806611610043906b720b5096728a5deb5d652b1d
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index 09dd117..b260a62 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -51,6 +51,11 @@
 #define MBOX_RECONFIG_DATA		0x08
 #define MBOX_RECONFIG_STATUS		0x09
 
+/* HWMON Commands */
+#define MBOX_HWMON_READVOLT		0x18
+#define MBOX_HWMON_READTEMP		0x19
+
+
 /* QSPI Commands */
 #define MBOX_CMD_QSPI_OPEN		0x32
 #define MBOX_CMD_QSPI_CLOSE		0x33
@@ -178,5 +183,7 @@
 int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len);
 int mailbox_rsu_update(uint32_t *flash_offset);
 int mailbox_hps_stage_notify(uint32_t execution_stage);
+int mailbox_hwmon_readtemp(uint32_t chan, uint32_t *resp_buf);
+int mailbox_hwmon_readvolt(uint32_t chan, uint32_t *resp_buf);
 
 #endif /* SOCFPGA_MBOX_H */
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
index 0f3cc09..43f3dc4 100644
--- a/plat/intel/soc/common/include/socfpga_sip_svc.h
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -50,6 +50,11 @@
 #define INTEL_SIP_SMC_RSU_DCMF_STATUS			0xC2000014
 #define INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS		0xC2000015
 
+/* Hardware monitor */
+#define INTEL_SIP_SMC_HWMON_READTEMP			0xC2000020
+#define INTEL_SIP_SMC_HWMON_READVOLT			0xC2000021
+#define TEMP_CHANNEL_MAX				(1 << 15)
+#define VOLT_CHANNEL_MAX				(1 << 15)
 
 /* ECC */
 #define INTEL_SIP_SMC_ECC_DBE				0xC200000D
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index fbb6b46..8ecd6db 100644
--- a/plat/intel/soc/common/soc/socfpga_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -529,3 +529,22 @@
 
 	return ret;
 }
+
+int mailbox_hwmon_readtemp(uint32_t chan, uint32_t *resp_buf)
+{
+	unsigned int resp_len = sizeof(resp_buf);
+
+	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HWMON_READTEMP, &chan, 1U,
+				CMD_CASUAL, resp_buf,
+				&resp_len);
+
+}
+
+int mailbox_hwmon_readvolt(uint32_t chan, uint32_t *resp_buf)
+{
+	unsigned int resp_len = sizeof(resp_buf);
+
+	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HWMON_READVOLT, &chan, 1U,
+				CMD_CASUAL, resp_buf,
+				&resp_len);
+}
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index ece2352..f22c2ee 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -90,16 +90,18 @@
 {
 	uint32_t ret;
 
-	if (query_type == 1)
+	if (query_type == 1U) {
 		ret = intel_mailbox_get_config_status(MBOX_CONFIG_STATUS, false);
-	else
+	} else {
 		ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS, true);
+	}
 
 	if (ret != 0U) {
-		if (ret == MBOX_CFGSTAT_STATE_CONFIG)
+		if (ret == MBOX_CFGSTAT_STATE_CONFIG) {
 			return INTEL_SIP_SMC_STATUS_BUSY;
-		else
+		} else {
 			return INTEL_SIP_SMC_STATUS_ERROR;
+		}
 	}
 
 	if (bridge_disable) {
@@ -434,6 +436,33 @@
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
+/* Intel HWMON services */
+static uint32_t intel_hwmon_readtemp(uint32_t chan, uint32_t *retval)
+{
+	if (chan > TEMP_CHANNEL_MAX) {
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	if (mailbox_hwmon_readtemp(chan, retval) < 0) {
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
+static uint32_t intel_hwmon_readvolt(uint32_t chan, uint32_t *retval)
+{
+	if (chan > VOLT_CHANNEL_MAX) {
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	if (mailbox_hwmon_readvolt(chan, retval) < 0) {
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
 /* Mailbox services */
 static uint32_t intel_smc_fw_version(uint32_t *fw_version)
 {
@@ -682,6 +711,14 @@
 		status = intel_hps_set_bridges(x1);
 		SMC_RET1(handle, status);
 
+	case INTEL_SIP_SMC_HWMON_READTEMP:
+		status = intel_hwmon_readtemp(x1, &retval);
+		SMC_RET2(handle, status, retval);
+
+	case INTEL_SIP_SMC_HWMON_READVOLT:
+		status = intel_hwmon_readvolt(x1, &retval);
+		SMC_RET2(handle, status, retval);
+
 	default:
 		return socfpga_sip_handler(smc_fid, x1, x2, x3, x4,
 			cookie, handle, flags);