55 */
66
77#include <zephyr/cache.h>
8+ #include <zephyr/device.h>
9+ #include <zephyr/init.h>
10+ #include <zephyr/kernel.h>
11+ #include <zephyr/drivers/firmware/scmi/clk.h>
12+ #include <zephyr/drivers/firmware/scmi/power.h>
13+ #include <zephyr/dt-bindings/clock/imx95_clock.h>
14+ #include <zephyr/dt-bindings/power/imx95_power.h>
15+ #include <soc.h>
16+
17+ /* SCMI power domain states */
18+ #define POWER_DOMAIN_STATE_ON 0x00000000
19+ #define POWER_DOMAIN_STATE_OFF 0x40000000
820
921void soc_late_init_hook (void )
1022{
@@ -13,3 +25,56 @@ void soc_late_init_hook(void)
1325 sys_cache_instr_enable ();
1426#endif /* CONFIG_CACHE_MANAGEMENT */
1527}
28+
29+ static int soc_init (void )
30+ {
31+ #if defined(CONFIG_ETH_NXP_IMX_NETC ) && (DT_CHILD_NUM_STATUS_OKAY (DT_NODELABEL (netc )) != 0 )
32+ const struct device * clk_dev = DEVICE_DT_GET (DT_NODELABEL (scmi_clk ));
33+ struct scmi_protocol * proto = clk_dev -> data ;
34+ struct scmi_clock_rate_config clk_cfg = {0 };
35+ struct scmi_power_state_config pwr_cfg = {0 };
36+ uint32_t power_state = POWER_DOMAIN_STATE_OFF ;
37+ uint64_t enetref_clk = 250000000 ; /* 250 MHz*/
38+ int ret ;
39+
40+ /* Power up NETCMIX */
41+ pwr_cfg .domain_id = IMX95_PD_NETC ;
42+ pwr_cfg .power_state = POWER_DOMAIN_STATE_ON ;
43+
44+ ret = scmi_power_state_set (& pwr_cfg );
45+ if (ret ) {
46+ return ret ;
47+ }
48+
49+ while (power_state != POWER_DOMAIN_STATE_ON ) {
50+ ret = scmi_power_state_get (IMX95_PD_NETC , & power_state );
51+ if (ret ) {
52+ return ret ;
53+ }
54+ }
55+
56+ /* ENETREF clock init */
57+ ret = scmi_clock_parent_set (proto , IMX95_CLK_ENETREF , IMX95_CLK_SYSPLL1_PFD0 );
58+ if (ret ) {
59+ return ret ;
60+ }
61+
62+ clk_cfg .flags = SCMI_CLK_RATE_SET_FLAGS_ROUNDS_AUTO ;
63+ clk_cfg .clk_id = IMX95_CLK_ENETREF ;
64+ clk_cfg .rate [0 ] = enetref_clk & 0xffffffff ;
65+ clk_cfg .rate [1 ] = (enetref_clk >> 32 ) & 0xffffffff ;
66+
67+ ret = scmi_clock_rate_set (proto , & clk_cfg );
68+ if (ret ) {
69+ return ret ;
70+ }
71+ #endif
72+ return 0 ;
73+ }
74+
75+ /*
76+ * Because platform is using ARM SCMI, drivers like scmi, mbox etc. are
77+ * initialized during PRE_KERNEL_1. Common init hooks is not able to use.
78+ * SoC early init and board early init could be run during PRE_KERNEL_2 instead.
79+ */
80+ SYS_INIT (soc_init , PRE_KERNEL_2 , 0 );
0 commit comments