1/*
2 * Copyright 2017, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(DATA61_BSD)
11 */
12
13#pragma once
14
15#include <assert.h>
16#include <platsupport/clock.h>
17
18#define _CLK_OPS(_id, _name, ops, data) \
19        .id       = _id,                \
20        .name     = _name,              \
21        .get_freq = _##ops##_get_freq,  \
22        .set_freq = _##ops##_set_freq,  \
23        .recal    = _##ops##_recal,     \
24        .init     = _##ops##_init,      \
25        .parent   = NULL,               \
26        .sibling  = NULL,               \
27        .child    = NULL,               \
28        .req_freq = 0,                  \
29        .priv     = (void*)data
30
31#define CLK_OPS(name, ops, data)        _CLK_OPS(CLK_##name, #name, ops, data)
32#define CLK_OPS_CUSTOM(name, ops, data) _CLK_OPS(CLK_CUSTOM, name, ops, data)
33#define CLK_OPS_DEFAULT(clk_id)         CLK_OPS(clk_id, default_clk, NULL)
34
35/* Array of default frequencies */
36extern freq_t ps_freq_default[];
37
38/* Array of clocks */
39extern clk_t* ps_clocks[];
40
41/** Helpers **/
42static inline clock_sys_t*
43clk_get_clock_sys(clk_t* clk)
44{
45    assert(clk);
46    return clk->clk_sys;
47}
48
49static inline clk_t*
50clk_init(clk_t* clk)
51{
52    assert(clk);
53    assert(clk->init);
54    return clk->init(clk);
55}
56
57static inline void
58clk_recal(clk_t* clk)
59{
60    assert(clk);
61    assert(clk->recal);
62    clk->recal(clk);
63}
64
65/**
66 * Prints a clock tree.
67 * The prefix should be based on the depth of the current root. When calling this
68 * funtion for the first time, pass "" for prefix. The prefix will be ammended
69 * for the current depth of traversal.
70 * @param[in] clk     The root of the tree
71 * @param[in] prefix  A string prefix to print before each line
72 */
73void clk_print_tree(clk_t* clk, const char* prefix);
74
75/* Default clocks - Frequency must be defined in freq_default */
76freq_t _default_clk_get_freq(clk_t* clk);
77freq_t _default_clk_set_freq(clk_t* clk, freq_t hz);
78void   _default_clk_recal(clk_t* clk);
79clk_t* _default_clk_init(clk_t* clk);
80
81/* Generic clock acquisition for all platforms */
82clk_t* ps_get_clock(clock_sys_t* sys, enum clk_id id);
83
84