drivers/scmi-msg: support for clock protocol

Adds SCMI clock protocol support in the SCMI message drivers as
defined in SCMI specification v2.0 [1] for clock protocol messages.

Platform can provide one of the plat_scmi_clock_*() handler for the
supported operations set/get state/rate and others.

scmi_msg_get_clock_handler() sanitizes the message_id value
against any speculative use of clock ID as a index since by
SCMI specification, IDs are indices.

This implementation is based on the OP-TEE project implementation [2]
itself based on the SCP-firmware implementation [3] of the SCMI
protocol server side.

Link: [1] http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/DEN0056A_System_Control_and_Management_Interface.pdf
Link: [2] https://github.com/OP-TEE/optee_os/commit/a7a9e3ba71dd908aafdc4c5ed9b29b15faa9692d
Link: [3] https://github.com/ARM-software/SCP-firmware.git

Change-Id: Ib56e096512042d4f7b9563d1e4181554eb8ed02c
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
diff --git a/include/drivers/st/scmi-msg.h b/include/drivers/st/scmi-msg.h
index af683e2..48fac16 100644
--- a/include/drivers/st/scmi-msg.h
+++ b/include/drivers/st/scmi-msg.h
@@ -62,4 +62,83 @@
 /* Get the name of the SCMI sub-vendor for the platform */
 const char *plat_scmi_sub_vendor_name(void);
 
+/* Handlers for SCMI Clock protocol services */
+
+/*
+ * Return number of clock controllers for an agent
+ * @agent_id: SCMI agent ID
+ * Return number of clock controllers
+ */
+size_t plat_scmi_clock_count(unsigned int agent_id);
+
+/*
+ * Get clock controller string ID (aka name)
+ * @agent_id: SCMI agent ID
+ * @scmi_id: SCMI clock ID
+ * Return pointer to name or NULL
+ */
+const char *plat_scmi_clock_get_name(unsigned int agent_id,
+				     unsigned int scmi_id);
+
+/*
+ * Get clock possible rate as an array of frequencies in Hertz.
+ *
+ * @agent_id: SCMI agent ID
+ * @scmi_id: SCMI clock ID
+ * @rates: If NULL, function returns, else output rates array
+ * @nb_elts: Array size of @rates.
+ * Return an SCMI compliant error code
+ */
+int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id,
+				    unsigned long *rates, size_t *nb_elts);
+
+/*
+ * Get clock possible rate as range with regular steps in Hertz
+ *
+ * @agent_id: SCMI agent ID
+ * @scmi_id: SCMI clock ID
+ * @min_max_step: 3 cell array for min, max and step rate data
+ * Return an SCMI compliant error code
+ */
+int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id,
+				      unsigned int scmi_id,
+				      unsigned long *min_max_step);
+
+/*
+ * Get clock rate in Hertz
+ * @agent_id: SCMI agent ID
+ * @scmi_id: SCMI clock ID
+ * Return clock rate or 0 if not supported
+ */
+unsigned long plat_scmi_clock_get_rate(unsigned int agent_id,
+				       unsigned int scmi_id);
+
+/*
+ * Set clock rate in Hertz
+ * @agent_id: SCMI agent ID
+ * @scmi_id: SCMI clock ID
+ * @rate: Target clock frequency in Hertz
+ * Return a compliant SCMI error code
+ */
+int32_t plat_scmi_clock_set_rate(unsigned int agent_id, unsigned int scmi_id,
+				 unsigned long rate);
+
+/*
+ * Get clock state (enabled or disabled)
+ * @agent_id: SCMI agent ID
+ * @scmi_id: SCMI clock ID
+ * Return 1 if clock is enabled, 0 if disables, or a negative SCMI error code
+ */
+int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id);
+
+/*
+ * Get clock state (enabled or disabled)
+ * @agent_id: SCMI agent ID
+ * @scmi_id: SCMI clock ID
+ * @enable_not_disable: Enable clock if true, disable clock otherwise
+ * Return a compliant SCMI error code
+ */
+int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id,
+				  bool enable_not_disable);
+
 #endif /* SCMI_MSG_H */