firmware: scmi: sandbox test for SCMI clocks

Add tests for SCMI clocks. A test device driver sandbox-scmi_devices.c
is used to get clock resources, allowing further clock manipulation.

Change sandbox-smci_agent to emulate 3 clocks exposed through 2 agents.
Add DM test scmi_clocks to test these 3 clocks.
Update DM test sandbox_scmi_agent with load/remove test sequences
factorized by {load|remove}_sandbox_scmi_test_devices() helper functions.

Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
Cc: Simon Glass <sjg@chromium.org>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 4769ec0..5ed364f 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -371,6 +371,11 @@
 			compatible = "sandbox,scmi-agent";
 			#address-cells = <1>;
 			#size-cells = <0>;
+
+			clk_scmi0: protocol@14 {
+				reg = <0x14>;
+				#clock-cells = <1>;
+			};
 		};
 
 		sandbox-scmi-agent@1 {
@@ -378,6 +383,11 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 
+			clk_scmi1: protocol@14 {
+				reg = <0x14>;
+				#clock-cells = <1>;
+			};
+
 			protocol@10 {
 				reg = <0x10>;
 			};
@@ -1069,6 +1079,11 @@
 		compatible = "sandbox,virtio2";
 	};
 
+	sandbox_scmi {
+		compatible = "sandbox,scmi-devices";
+		clocks = <&clk_scmi0 7>, <&clk_scmi0 3>, <&clk_scmi1 1>;
+	};
+
 	pinctrl {
 		compatible = "sandbox,pinctrl";
 
diff --git a/arch/sandbox/include/asm/scmi_test.h b/arch/sandbox/include/asm/scmi_test.h
index a811fe1..63093fd 100644
--- a/arch/sandbox/include/asm/scmi_test.h
+++ b/arch/sandbox/include/asm/scmi_test.h
@@ -11,11 +11,27 @@
 struct sandbox_scmi_service;
 
 /**
+ * struct sandbox_scmi_clk - Simulated clock exposed by SCMI
+ * @id:		Identifier of the clock used in the SCMI protocol
+ * @enabled:	Clock state: true if enabled, false if disabled
+ * @rate:	Clock rate in Hertz
+ */
+struct sandbox_scmi_clk {
+	uint id;
+	bool enabled;
+	ulong rate;
+};
+
+/**
  * struct sandbox_scmi_agent - Simulated SCMI service seen by SCMI agent
  * @idx:	Identifier for the SCMI agent, its index
+ * @clk:	Simulated clocks
+ * @clk_count:	Simulated clocks array size
  */
 struct sandbox_scmi_agent {
 	uint idx;
+	struct sandbox_scmi_clk *clk;
+	size_t clk_count;
 };
 
 /**
@@ -28,16 +44,39 @@
 	size_t agent_count;
 };
 
+/**
+ * struct sandbox_scmi_devices - Reference to devices probed through SCMI
+ * @clk:		Array the clock devices
+ * @clk_count:		Number of clock devices probed
+ */
+struct sandbox_scmi_devices {
+	struct clk *clk;
+	size_t clk_count;
+};
+
 #ifdef CONFIG_SCMI_FIRMWARE
 /**
  * sandbox_scmi_service_context - Get the simulated SCMI services context
  * @return:	Reference to backend simulated resources state
  */
 struct sandbox_scmi_service *sandbox_scmi_service_ctx(void);
+
+/**
+ * sandbox_scmi_devices_get_ref - Get references to devices accessed through SCMI
+ * @dev:	Reference to the test device used get test resources
+ * @return:	Reference to the devices probed by the SCMI test
+ */
+struct sandbox_scmi_devices *sandbox_scmi_devices_ctx(struct udevice *dev);
 #else
 static inline struct sandbox_scmi_service *sandbox_scmi_service_ctx(void)
 {
 	return NULL;
 }
+
+static inline
+struct sandbox_scmi_devices *sandbox_scmi_devices_ctx(struct udevice *dev)
+{
+	return NULL;
+}
 #endif /* CONFIG_SCMI_FIRMWARE */
 #endif /* __SANDBOX_SCMI_TEST_H */