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