1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "clock_devices.h"
9 #include "config_power_domain.h"
10 #include "sgm776_core.h"
11 
12 #include <mod_clock.h>
13 #include <mod_css_clock.h>
14 #include <mod_pik_clock.h>
15 #include <mod_power_domain.h>
16 #include <mod_system_pll.h>
17 
18 #include <fwk_element.h>
19 #include <fwk_id.h>
20 #include <fwk_module.h>
21 #include <fwk_module_idx.h>
22 
23 static const struct fwk_element clock_dev_desc_table[] = {
24     [CLOCK_DEV_IDX_BIG] = {
25         .name = "CPU_GROUP_BIG",
26         .data = &((struct mod_clock_dev_config) {
27             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CSS_CLOCK, 0),
28             .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_CSS_CLOCK,
29                                       MOD_CSS_CLOCK_API_TYPE_CLOCK),
30         }),
31     },
32     [CLOCK_DEV_IDX_LITTLE] = {
33         .name = "CPU_GROUP_LITTLE",
34         .data = &((struct mod_clock_dev_config) {
35             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CSS_CLOCK, 1),
36             .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_CSS_CLOCK,
37                                       MOD_CSS_CLOCK_API_TYPE_CLOCK),
38         }),
39     },
40     [CLOCK_DEV_IDX_GPU] = {
41         .name = "GPU",
42         .data = &((struct mod_clock_dev_config) {
43             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CSS_CLOCK, 2),
44             .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_CSS_CLOCK,
45                                       MOD_CSS_CLOCK_API_TYPE_CLOCK),
46         }),
47     },
48     [CLOCK_DEV_IDX_VPU] = {
49         .name = "VPU",
50         .data = &((struct mod_clock_dev_config) {
51             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CSS_CLOCK, 3),
52             .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_CSS_CLOCK,
53                                       MOD_CSS_CLOCK_API_TYPE_CLOCK),
54         }),
55     },
56     [CLOCK_DEV_IDX_DPU] = {
57         .name = "DPU",
58         .data = &((struct mod_clock_dev_config) {
59             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CSS_CLOCK, 4),
60             .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_CSS_CLOCK,
61                                       MOD_CSS_CLOCK_API_TYPE_CLOCK),
62         }),
63     },
64     [CLOCK_DEV_IDX_PIXEL_0] = {
65         .name = "PIXEL_0",
66         .data = &((struct mod_clock_dev_config) {
67             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SYSTEM_PLL, 5),
68             .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SYSTEM_PLL,
69                                       MOD_SYSTEM_PLL_API_TYPE_DEFAULT),
70         }),
71     },
72     [CLOCK_DEV_IDX_PIXEL_1] = {
73         .name = "PIXEL_1",
74         .data = &((struct mod_clock_dev_config) {
75             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SYSTEM_PLL, 6),
76             .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SYSTEM_PLL,
77                                       MOD_SYSTEM_PLL_API_TYPE_DEFAULT),
78         }),
79     },
80     [CLOCK_DEV_IDX_INTERCONNECT] = {
81         .name = "INTERCONNECT",
82         .data = &((struct mod_clock_dev_config) {
83             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 11),
84             .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PIK_CLOCK,
85                                       MOD_PIK_CLOCK_API_TYPE_CLOCK),
86         }),
87     },
88     [CLOCK_DEV_IDX_COUNT] = { 0 }, /* Termination description. */
89 };
90 
clock_get_dev_desc_table(fwk_id_t module_id)91 static const struct fwk_element *clock_get_dev_desc_table(fwk_id_t module_id)
92 {
93     unsigned int i;
94     unsigned int core_count, cluster_count;
95     struct mod_clock_dev_config *dev_config;
96 
97     core_count = sgm776_core_get_count();
98     cluster_count = sgm776_cluster_get_count();
99 
100     /* Configure all clocks to respond to changes in SYSTOP power state */
101     for (i = 0; i < CLOCK_DEV_IDX_COUNT; i++) {
102         dev_config =
103             (struct mod_clock_dev_config *)clock_dev_desc_table[i].data;
104         dev_config->pd_source_id = FWK_ID_ELEMENT(
105             FWK_MODULE_IDX_POWER_DOMAIN,
106             CONFIG_POWER_DOMAIN_SYSTOP_SYSTEM + core_count + cluster_count);
107     }
108 
109     return clock_dev_desc_table;
110 }
111 
112 struct fwk_module_config config_clock = {
113     .data =
114         &(struct mod_clock_config){
115             .pd_transition_notification_id = FWK_ID_NOTIFICATION_INIT(
116                 FWK_MODULE_IDX_POWER_DOMAIN,
117                 MOD_PD_NOTIFICATION_IDX_POWER_STATE_TRANSITION),
118             .pd_pre_transition_notification_id = FWK_ID_NOTIFICATION_INIT(
119                 FWK_MODULE_IDX_POWER_DOMAIN,
120                 MOD_PD_NOTIFICATION_IDX_POWER_STATE_PRE_TRANSITION),
121         },
122 
123     .elements = FWK_MODULE_DYNAMIC_ELEMENTS(clock_get_dev_desc_table),
124 };
125