1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include <config_clock.h>
9 #include <morello_mcp_pik.h>
10 #include <morello_pik_mcp.h>
11 #include <morello_system_clock.h>
12 
13 #include <mod_pik_clock.h>
14 
15 #include <fwk_element.h>
16 #include <fwk_id.h>
17 #include <fwk_module.h>
18 
19 #include <stdbool.h>
20 
21 /*
22  * Rate lookup tables
23  */
24 
25 static const struct mod_pik_clock_rate rate_table_mcp_coreclk[1] = {
26     {
27         .rate = PIK_CLK_RATE_MCP_CORECLK,
28         .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK,
29         .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS,
30         .divider = CLOCK_RATE_SYSPLLCLK / PIK_CLK_RATE_MCP_CORECLK,
31     },
32 };
33 
34 static const struct mod_pik_clock_rate rate_table_mcp_axiclk[1] = {
35     {
36         .rate = PIK_CLK_RATE_MCP_AXICLK,
37         .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK,
38         .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS,
39         .divider = CLOCK_RATE_SYSPLLCLK / PIK_CLK_RATE_MCP_AXICLK,
40     },
41 };
42 
43 static const struct fwk_element
44     pik_clock_element_table[CLOCK_PIK_IDX_COUNT + 1] = {
45         [CLOCK_PIK_IDX_MCP_CORECLK] = {
46             .name = "MCP CORECLK",
47             .data = &((struct mod_pik_clock_dev_config) {
48                 .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE,
49                 .is_group_member = false,
50                 .control_reg = &PIK_MCP->CORECLK_CTRL,
51                 .divsys_reg = &PIK_MCP->CORECLK_DIV1,
52                 .rate_table = rate_table_mcp_coreclk,
53                 .rate_count = FWK_ARRAY_SIZE(rate_table_mcp_coreclk),
54                 .initial_rate = PIK_CLK_RATE_MCP_CORECLK,
55                 .defer_initialization = true,
56             }),
57         },
58         [CLOCK_PIK_IDX_MCP_AXICLK] = {
59             .name = "MCP AXICLK",
60             .data = &((struct mod_pik_clock_dev_config) {
61                 .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE,
62                 .is_group_member = false,
63                 .control_reg = &PIK_MCP->CORECLK_CTRL,
64                 .divsys_reg = &PIK_MCP->CORECLK_DIV1,
65                 .rate_table = rate_table_mcp_axiclk,
66                 .rate_count = FWK_ARRAY_SIZE(rate_table_mcp_axiclk),
67                 .initial_rate = PIK_CLK_RATE_MCP_AXICLK,
68                 .defer_initialization = true,
69             }),
70         },
71         [CLOCK_PIK_IDX_COUNT] = { 0 }, /* Termination description. */
72 };
73 
pik_clock_get_element_table(fwk_id_t module_id)74 static const struct fwk_element *pik_clock_get_element_table(fwk_id_t module_id)
75 {
76     return pik_clock_element_table;
77 }
78 
79 const struct fwk_module_config config_pik_clock = {
80     .elements = FWK_MODULE_DYNAMIC_ELEMENTS(pik_clock_get_element_table),
81 };
82