]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - k3conf/k3conf.git/blob - common/tisci/tisci_clock.c
tisci: Add support for handling clocks
[k3conf/k3conf.git] / common / tisci / tisci_clock.c
1 /*
2  * TISCI clock ops library
3  *
4  * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
5  *      Lokesh Vutla <lokeshvutla@ti.com>
6  *
7  *  Redistribution and use in source and binary forms, with or without
8  *  modification, are permitted provided that the following conditions
9  *  are met:
10  *
11  *    Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
14  *    Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the
17  *    distribution.
18  *
19  *    Neither the name of Texas Instruments Incorporated nor the names of
20  *    its contributors may be used to endorse or promote products derived
21  *    from this software without specific prior written permission.
22  *
23  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
36 #include <string.h>
37 #include <sec_proxy.h>
38 #include <tisci_protocol.h>
39 #include <tisci.h>
41 static const char clock_state[MAX_CLOCK_HW_STATES + 1][MAX_CLOCK_STATE_LENGTH] = {
42         [MSG_CLOCK_HW_STATE_NOT_READY] = "CLK_STATE_NOT_READY",
43         [MSG_CLOCK_HW_STATE_READY] = "CLK_STATE_READY",
44         [MAX_CLOCK_HW_STATES] = "CLK_STATE_UNKNOWN"
45 };
47 static int ti_sci_set_clock_state(uint32_t dev_id, uint32_t clk_id,
48                                   uint32_t flags, uint8_t state)
49 {
50         struct ti_sci_msg_req_set_clock_state *req;
51         uint8_t buf[SEC_PROXY_MAX_MSG_SIZE];
52         struct k3_sec_proxy_msg msg;
54         memset(buf, 0, sizeof(buf));
55         ti_sci_setup_header((struct ti_sci_msg_hdr *)buf,
56                             TI_SCI_MSG_SET_CLOCK_STATE, flags);
57         req = (struct ti_sci_msg_req_set_clock_state *)buf;
58         req->dev_id = dev_id;
59         if (clk_id < 255) {
60                 req->clk_id = clk_id;
61         } else {
62                 req->clk_id = 255;
63                 req->clk_id_32 = clk_id;
64         }
65         req->request_state = state;
67         msg.len = sizeof(*req);
68         msg.buf = buf;
69         return ti_sci_xfer_msg(&msg);
70 }
72 int ti_sci_cmd_get_clk(uint32_t dev_id, uint32_t clk_id)
73 {
74         return ti_sci_set_clock_state(dev_id, clk_id,
75                                       MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE,
76                                       MSG_CLOCK_SW_STATE_REQ);
77 }
79 int ti_sci_cmd_put_clk(uint32_t dev_id, uint32_t clk_id)
80 {
81         return ti_sci_set_clock_state(dev_id, clk_id,
82                                       MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE,
83                                       MSG_CLOCK_SW_STATE_UNREQ);
84 }
86 const char *ti_sci_cmd_get_clk_state(uint32_t dev_id, uint32_t clk_id)
87 {
88         struct ti_sci_msg_resp_get_clock_state *resp;
89         struct ti_sci_msg_req_get_clock_state *req;
90         uint8_t buf[SEC_PROXY_MAX_MSG_SIZE];
91         struct k3_sec_proxy_msg msg;
92         int ret;
94         memset(buf, 0, sizeof(buf));
95         ti_sci_setup_header((struct ti_sci_msg_hdr *)buf,
96                             TI_SCI_MSG_GET_CLOCK_STATE, 0);
97         req = (struct ti_sci_msg_req_get_clock_state *)buf;
98         req->dev_id = dev_id;
99         if (clk_id < 255) {
100                 req->clk_id = clk_id;
101         } else {
102                 req->clk_id = 255;
103                 req->clk_id_32 = clk_id;
104         }
106         msg.len = sizeof(*req);
107         msg.buf = buf;
108         ret = ti_sci_xfer_msg(&msg);
109         if (ret)
110                 return NULL;
112         resp = (struct ti_sci_msg_resp_get_clock_state *)buf;
114         return clock_state[resp->current_state];
117 int ti_sci_cmd_set_clk_freq(uint32_t dev_id, uint32_t clk_id, uint64_t freq)
119         struct ti_sci_msg_req_set_clock_freq *req;
120         uint8_t buf[SEC_PROXY_MAX_MSG_SIZE];
121         struct k3_sec_proxy_msg msg;
123         memset(buf, 0, sizeof(buf));
124         ti_sci_setup_header((struct ti_sci_msg_hdr *)buf,
125                             TI_SCI_MSG_SET_CLOCK_FREQ, 0);
126         req = (struct ti_sci_msg_req_set_clock_freq *)buf;
127         req->dev_id = dev_id;
128         if (clk_id < 255) {
129                 req->clk_id = clk_id;
130         } else {
131                 req->clk_id = 255;
132                 req->clk_id_32 = clk_id;
133         }
134         /* ToDo: Get best match freq and set that freq */
135         req->min_freq_hz = freq;
136         req->target_freq_hz = freq;
137         req->max_freq_hz = freq;
139         msg.len = sizeof(*req);
140         msg.buf = buf;
141         return ti_sci_xfer_msg(&msg);
144 int ti_sci_cmd_get_clk_freq(uint32_t dev_id, uint32_t clk_id, uint64_t *freq)
146         struct ti_sci_msg_resp_get_clock_freq *resp;
147         struct ti_sci_msg_req_get_clock_freq *req;
148         uint8_t buf[SEC_PROXY_MAX_MSG_SIZE];
149         struct k3_sec_proxy_msg msg;
150         int ret;
152         memset(buf, 0, sizeof(buf));
153         ti_sci_setup_header((struct ti_sci_msg_hdr *)buf,
154                             TI_SCI_MSG_GET_CLOCK_FREQ, 0);
155         req = (struct ti_sci_msg_req_get_clock_freq *)buf;
156         req->dev_id = dev_id;
157         if (clk_id < 255) {
158                 req->clk_id = clk_id;
159         } else {
160                 req->clk_id = 255;
161                 req->clk_id_32 = clk_id;
162         }
164         msg.len = sizeof(*req);
165         msg.buf = buf;
166         ret = ti_sci_xfer_msg(&msg);
167         if (ret)
168                 return ret;
170         resp = (struct ti_sci_msg_resp_get_clock_freq *)buf;
171         *freq = resp->freq_hz;
173         return 0;