blob: 1380895c2ca12059c04a4193901ceac30b97605f [file] [log] [blame]
Rajan Vaja5529a012018-01-17 02:39:23 -08001/*
Ronak Jain325bad12021-12-21 01:39:59 -08002 * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
Rajan Vaja5529a012018-01-17 02:39:23 -08003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7/*
8 * ZynqMP system level PM-API functions for ioctl.
9 */
10
11#include <arch_helpers.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000012#include <drivers/delay_timer.h>
13#include <lib/mmio.h>
14#include <plat/common/platform.h>
Jolly Shah16fe5ab2019-01-08 11:16:16 -080015#include <zynqmp_def.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000016
Rajan Vaja35116132018-01-17 02:39:25 -080017#include "pm_api_clock.h"
Rajan Vaja5529a012018-01-17 02:39:23 -080018#include "pm_api_ioctl.h"
19#include "pm_api_sys.h"
20#include "pm_client.h"
21#include "pm_common.h"
22#include "pm_ipi.h"
Rajan Vaja5529a012018-01-17 02:39:23 -080023
24/**
25 * pm_ioctl_get_rpu_oper_mode () - Get current RPU operation mode
26 * @mode Buffer to store value of oper mode(Split/Lock-step)
27 *
28 * This function provides current configured RPU operational mode.
29 *
30 * @return Returns status, either success or error+reason
31 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +053032static enum pm_ret_status pm_ioctl_get_rpu_oper_mode(uint32_t *mode)
Rajan Vaja5529a012018-01-17 02:39:23 -080033{
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +053034 uint32_t val;
Rajan Vaja5529a012018-01-17 02:39:23 -080035
36 val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
37 val &= ZYNQMP_SLSPLIT_MASK;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +053038 if (val == 0) {
Rajan Vaja5529a012018-01-17 02:39:23 -080039 *mode = PM_RPU_MODE_LOCKSTEP;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +053040 } else {
Jolly Shah69fb5bf2018-02-07 16:25:41 -080041 *mode = PM_RPU_MODE_SPLIT;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +053042 }
Rajan Vaja5529a012018-01-17 02:39:23 -080043
44 return PM_RET_SUCCESS;
45}
46
47/**
48 * pm_ioctl_set_rpu_oper_mode () - Configure RPU operation mode
49 * @mode Value to set for oper mode(Split/Lock-step)
50 *
51 * This function configures RPU operational mode(Split/Lock-step).
52 * It also sets TCM combined mode in RPU lock-step and TCM non-combined
53 * mode for RPU split mode. In case of Lock step mode, RPU1's output is
54 * clamped.
55 *
56 * @return Returns status, either success or error+reason
57 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +053058static enum pm_ret_status pm_ioctl_set_rpu_oper_mode(uint32_t mode)
Rajan Vaja5529a012018-01-17 02:39:23 -080059{
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +053060 uint32_t val;
Rajan Vaja5529a012018-01-17 02:39:23 -080061
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +053062 if (mmio_read_32(CRL_APB_RST_LPD_TOP) & CRL_APB_RPU_AMBA_RESET) {
Rajan Vaja5529a012018-01-17 02:39:23 -080063 return PM_RET_ERROR_ACCESS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +053064 }
Rajan Vaja5529a012018-01-17 02:39:23 -080065
66 val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
67
68 if (mode == PM_RPU_MODE_SPLIT) {
69 val |= ZYNQMP_SLSPLIT_MASK;
70 val &= ~ZYNQMP_TCM_COMB_MASK;
71 val &= ~ZYNQMP_SLCLAMP_MASK;
72 } else if (mode == PM_RPU_MODE_LOCKSTEP) {
73 val &= ~ZYNQMP_SLSPLIT_MASK;
74 val |= ZYNQMP_TCM_COMB_MASK;
75 val |= ZYNQMP_SLCLAMP_MASK;
76 } else {
77 return PM_RET_ERROR_ARGS;
78 }
79
80 mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
81
82 return PM_RET_SUCCESS;
83}
84
85/**
86 * pm_ioctl_config_boot_addr() - Configure RPU boot address
87 * @nid Node ID of RPU
88 * @value Value to set for boot address (TCM/OCM)
89 *
90 * This function configures RPU boot address(memory).
91 *
92 * @return Returns status, either success or error+reason
93 */
94static enum pm_ret_status pm_ioctl_config_boot_addr(enum pm_node_id nid,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +053095 uint32_t value)
Rajan Vaja5529a012018-01-17 02:39:23 -080096{
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +053097 uint32_t rpu_cfg_addr, val;
Rajan Vaja5529a012018-01-17 02:39:23 -080098
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +053099 if (nid == NODE_RPU_0) {
Rajan Vaja5529a012018-01-17 02:39:23 -0800100 rpu_cfg_addr = ZYNQMP_RPU0_CFG;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530101 } else if (nid == NODE_RPU_1) {
Rajan Vaja5529a012018-01-17 02:39:23 -0800102 rpu_cfg_addr = ZYNQMP_RPU1_CFG;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530103 } else {
Rajan Vaja5529a012018-01-17 02:39:23 -0800104 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530105 }
Rajan Vaja5529a012018-01-17 02:39:23 -0800106
107 val = mmio_read_32(rpu_cfg_addr);
108
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530109 if (value == PM_RPU_BOOTMEM_LOVEC) {
Rajan Vaja5529a012018-01-17 02:39:23 -0800110 val &= ~ZYNQMP_VINITHI_MASK;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530111 } else if (value == PM_RPU_BOOTMEM_HIVEC) {
Rajan Vaja5529a012018-01-17 02:39:23 -0800112 val |= ZYNQMP_VINITHI_MASK;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530113 } else {
Rajan Vaja5529a012018-01-17 02:39:23 -0800114 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530115 }
Rajan Vaja5529a012018-01-17 02:39:23 -0800116
117 mmio_write_32(rpu_cfg_addr, val);
118
119 return PM_RET_SUCCESS;
120}
121
122/**
123 * pm_ioctl_config_tcm_comb() - Configure TCM combined mode
124 * @value Value to set (Split/Combined)
125 *
126 * This function configures TCM to be in split mode or combined
127 * mode.
128 *
129 * @return Returns status, either success or error+reason
130 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530131static enum pm_ret_status pm_ioctl_config_tcm_comb(uint32_t value)
Rajan Vaja5529a012018-01-17 02:39:23 -0800132{
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530133 uint32_t val;
Rajan Vaja5529a012018-01-17 02:39:23 -0800134
135 val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
136
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530137 if (value == PM_RPU_TCM_SPLIT) {
Rajan Vaja5529a012018-01-17 02:39:23 -0800138 val &= ~ZYNQMP_TCM_COMB_MASK;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530139 } else if (value == PM_RPU_TCM_COMB) {
Rajan Vaja5529a012018-01-17 02:39:23 -0800140 val |= ZYNQMP_TCM_COMB_MASK;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530141 } else {
Rajan Vaja5529a012018-01-17 02:39:23 -0800142 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530143 }
Rajan Vaja5529a012018-01-17 02:39:23 -0800144
145 mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
146
147 return PM_RET_SUCCESS;
148}
149
150/**
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800151 * pm_ioctl_set_tapdelay_bypass() - Enable/Disable tap delay bypass
152 * @type Type of tap delay to enable/disable (e.g. QSPI)
153 * @value Enable/Disable
154 *
155 * This function enable/disable tap delay bypass.
156 *
157 * @return Returns status, either success or error+reason
158 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530159static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(uint32_t type,
160 uint32_t value)
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800161{
162 if ((value != PM_TAPDELAY_BYPASS_ENABLE &&
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530163 value != PM_TAPDELAY_BYPASS_DISABLE) || type >= PM_TAPDELAY_MAX) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800164 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530165 }
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800166
167 return pm_mmio_write(IOU_TAPDLY_BYPASS, TAP_DELAY_MASK, value << type);
168}
169
170/**
171 * pm_ioctl_set_sgmii_mode() - Set SGMII mode for the GEM device
172 * @nid Node ID of the device
173 * @value Enable/Disable
174 *
175 * This function enable/disable SGMII mode for the GEM device.
176 * While enabling SGMII mode, it also ties the GEM PCS Signal
177 * Detect to 1 and selects EMIO for RX clock generation.
178 *
179 * @return Returns status, either success or error+reason
180 */
181static enum pm_ret_status pm_ioctl_set_sgmii_mode(enum pm_node_id nid,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530182 uint32_t value)
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800183{
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530184 uint32_t val, mask, shift;
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800185 enum pm_ret_status ret;
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800186
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530187 if (value != PM_SGMII_DISABLE && value != PM_SGMII_ENABLE) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800188 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530189 }
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800190
191 switch (nid) {
192 case NODE_ETH_0:
193 shift = 0;
194 break;
195 case NODE_ETH_1:
196 shift = 1;
197 break;
198 case NODE_ETH_2:
199 shift = 2;
200 break;
201 case NODE_ETH_3:
202 shift = 3;
203 break;
204 default:
205 return PM_RET_ERROR_ARGS;
206 }
207
208 if (value == PM_SGMII_DISABLE) {
209 mask = GEM_SGMII_MASK << GEM_CLK_CTRL_OFFSET * shift;
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800210 ret = pm_mmio_write(IOU_GEM_CLK_CTRL, mask, 0U);
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800211 } else {
212 /* Tie the GEM PCS Signal Detect to 1 */
213 mask = SGMII_SD_MASK << SGMII_SD_OFFSET * shift;
214 val = SGMII_PCS_SD_1 << SGMII_SD_OFFSET * shift;
215 ret = pm_mmio_write(IOU_GEM_CTRL, mask, val);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530216 if (ret != PM_RET_SUCCESS) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800217 return ret;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530218 }
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800219
220 /* Set the GEM to SGMII mode */
221 mask = GEM_CLK_CTRL_MASK << GEM_CLK_CTRL_OFFSET * shift;
222 val = GEM_RX_SRC_SEL_GTR | GEM_SGMII_MODE;
223 val <<= GEM_CLK_CTRL_OFFSET * shift;
224 ret = pm_mmio_write(IOU_GEM_CLK_CTRL, mask, val);
225 }
226
227 return ret;
228}
229
230/**
231 * pm_ioctl_sd_dll_reset() - Reset DLL logic
232 * @nid Node ID of the device
233 * @type Reset type
234 *
235 * This function resets DLL logic for the SD device.
236 *
237 * @return Returns status, either success or error+reason
238 */
239static enum pm_ret_status pm_ioctl_sd_dll_reset(enum pm_node_id nid,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530240 uint32_t type)
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800241{
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530242 uint32_t mask, val;
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800243 enum pm_ret_status ret;
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800244
245 if (nid == NODE_SD_0) {
246 mask = ZYNQMP_SD0_DLL_RST_MASK;
247 val = ZYNQMP_SD0_DLL_RST;
248 } else if (nid == NODE_SD_1) {
249 mask = ZYNQMP_SD1_DLL_RST_MASK;
250 val = ZYNQMP_SD1_DLL_RST;
251 } else {
252 return PM_RET_ERROR_ARGS;
253 }
254
255 switch (type) {
256 case PM_DLL_RESET_ASSERT:
257 case PM_DLL_RESET_PULSE:
258 ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, val);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530259 if (ret != PM_RET_SUCCESS) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800260 return ret;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530261 }
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800262
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530263 if (type == PM_DLL_RESET_ASSERT) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800264 break;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530265 }
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800266 mdelay(1);
Daniel Boulby8942a1b2018-06-22 14:16:03 +0100267 /* Fallthrough */
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800268 case PM_DLL_RESET_RELEASE:
269 ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, 0);
270 break;
271 default:
272 ret = PM_RET_ERROR_ARGS;
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800273 break;
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800274 }
275
276 return ret;
277}
278
279/**
280 * pm_ioctl_sd_set_tapdelay() - Set tap delay for the SD device
281 * @nid Node ID of the device
282 * @type Type of tap delay to set (input/output)
283 * @value Value to set fot the tap delay
284 *
285 * This function sets input/output tap delay for the SD device.
286 *
287 * @return Returns status, either success or error+reason
288 */
289static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid,
290 enum tap_delay_type type,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530291 uint32_t value)
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800292{
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530293 uint32_t shift;
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800294 enum pm_ret_status ret;
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530295 uint32_t val, mask;
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800296
Sai Krishna Potthuriad48c502020-10-20 07:00:06 -0600297 if (nid == NODE_SD_0) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800298 shift = 0;
Sai Krishna Potthuriad48c502020-10-20 07:00:06 -0600299 mask = ZYNQMP_SD0_DLL_RST_MASK;
300 } else if (nid == NODE_SD_1) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800301 shift = ZYNQMP_SD_TAP_OFFSET;
Sai Krishna Potthuriad48c502020-10-20 07:00:06 -0600302 mask = ZYNQMP_SD1_DLL_RST_MASK;
303 } else {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800304 return PM_RET_ERROR_ARGS;
Sai Krishna Potthuriad48c502020-10-20 07:00:06 -0600305 }
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800306
Sai Krishna Potthuriad48c502020-10-20 07:00:06 -0600307 ret = pm_mmio_read(ZYNQMP_SD_DLL_CTRL, &val);
308 if (ret != PM_RET_SUCCESS) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800309 return ret;
Sai Krishna Potthuriad48c502020-10-20 07:00:06 -0600310 }
311
312 if ((val & mask) == 0) {
313 ret = pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_ASSERT);
314 if (ret != PM_RET_SUCCESS) {
315 return ret;
316 }
317 }
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800318
319 if (type == PM_TAPDELAY_INPUT) {
320 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800321 (ZYNQMP_SD_ITAPCHGWIN_MASK << shift),
322 (ZYNQMP_SD_ITAPCHGWIN << shift));
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530323
324 if (ret != PM_RET_SUCCESS) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800325 goto reset_release;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530326 }
327
328 if (value == 0) {
Sai Krishna Potthuri15da5822020-10-30 00:09:43 -0600329 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
330 (ZYNQMP_SD_ITAPDLYENA_MASK <<
331 shift), 0);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530332 } else {
Sai Krishna Potthuri15da5822020-10-30 00:09:43 -0600333 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
334 (ZYNQMP_SD_ITAPDLYENA_MASK <<
335 shift), (ZYNQMP_SD_ITAPDLYENA <<
336 shift));
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530337 }
338
339 if (ret != PM_RET_SUCCESS) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800340 goto reset_release;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530341 }
342
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800343 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800344 (ZYNQMP_SD_ITAPDLYSEL_MASK << shift),
345 (value << shift));
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530346
347 if (ret != PM_RET_SUCCESS) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800348 goto reset_release;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530349 }
350
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800351 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800352 (ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0);
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800353 } else if (type == PM_TAPDELAY_OUTPUT) {
354 ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
Sai Krishna Potthuri15da5822020-10-30 00:09:43 -0600355 (ZYNQMP_SD_OTAPDLYENA_MASK << shift), 0);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530356
357 if (ret != PM_RET_SUCCESS) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800358 goto reset_release;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530359 }
360
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800361 ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800362 (ZYNQMP_SD_OTAPDLYSEL_MASK << shift),
363 (value << shift));
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800364 } else {
365 ret = PM_RET_ERROR_ARGS;
366 }
367
368reset_release:
Sai Krishna Potthuriad48c502020-10-20 07:00:06 -0600369 if ((val & mask) == 0) {
370 (void)pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_RELEASE);
371 }
372
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800373 return ret;
374}
375
376/**
Rajan Vaja35116132018-01-17 02:39:25 -0800377 * pm_ioctl_set_pll_frac_mode() - Ioctl function for
378 * setting pll mode
Jolly Shahcb5bc752019-01-02 12:46:46 -0800379 * @pll PLL clock id
Rajan Vaja35116132018-01-17 02:39:25 -0800380 * @mode Mode fraction/integar
381 *
382 * This function sets PLL mode
383 *
384 * @return Returns status, either success or error+reason
385 */
386static enum pm_ret_status pm_ioctl_set_pll_frac_mode
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530387 (uint32_t pll, uint32_t mode)
Rajan Vaja35116132018-01-17 02:39:25 -0800388{
Jolly Shahcb5bc752019-01-02 12:46:46 -0800389 return pm_clock_set_pll_mode(pll, mode);
Rajan Vaja35116132018-01-17 02:39:25 -0800390}
391
392/**
393 * pm_ioctl_get_pll_frac_mode() - Ioctl function for
394 * getting pll mode
Jolly Shah77eb52f2019-01-02 12:49:21 -0800395 * @pll PLL clock id
Rajan Vaja35116132018-01-17 02:39:25 -0800396 * @mode Mode fraction/integar
397 *
398 * This function return current PLL mode
399 *
400 * @return Returns status, either success or error+reason
401 */
402static enum pm_ret_status pm_ioctl_get_pll_frac_mode
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530403 (uint32_t pll, uint32_t *mode)
Rajan Vaja35116132018-01-17 02:39:25 -0800404{
Jolly Shah77eb52f2019-01-02 12:49:21 -0800405 return pm_clock_get_pll_mode(pll, mode);
Rajan Vaja35116132018-01-17 02:39:25 -0800406}
407
408/**
409 * pm_ioctl_set_pll_frac_data() - Ioctl function for
410 * setting pll fraction data
Jolly Shah68116ef2019-01-02 12:42:56 -0800411 * @pll PLL clock id
Rajan Vaja35116132018-01-17 02:39:25 -0800412 * @data fraction data
413 *
414 * This function sets fraction data.
415 * It is valid for fraction mode only.
416 *
417 * @return Returns status, either success or error+reason
418 */
419static enum pm_ret_status pm_ioctl_set_pll_frac_data
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530420 (uint32_t pll, uint32_t data)
Rajan Vaja35116132018-01-17 02:39:25 -0800421{
Jolly Shah68116ef2019-01-02 12:42:56 -0800422 enum pm_node_id pll_nid;
423 enum pm_ret_status status;
424
425 /* Get PLL node ID using PLL clock ID */
426 status = pm_clock_get_pll_node_id(pll, &pll_nid);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530427 if (status != PM_RET_SUCCESS) {
Jolly Shah68116ef2019-01-02 12:42:56 -0800428 return status;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530429 }
Jolly Shah68116ef2019-01-02 12:42:56 -0800430
431 return pm_pll_set_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
Rajan Vaja35116132018-01-17 02:39:25 -0800432}
433
434/**
435 * pm_ioctl_get_pll_frac_data() - Ioctl function for
436 * getting pll fraction data
Jolly Shahb4c99462019-01-02 12:40:17 -0800437 * @pll PLL clock id
Rajan Vaja35116132018-01-17 02:39:25 -0800438 * @data fraction data
439 *
440 * This function returns fraction data value.
441 *
442 * @return Returns status, either success or error+reason
443 */
444static enum pm_ret_status pm_ioctl_get_pll_frac_data
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530445 (uint32_t pll, uint32_t *data)
Rajan Vaja35116132018-01-17 02:39:25 -0800446{
Jolly Shahb4c99462019-01-02 12:40:17 -0800447 enum pm_node_id pll_nid;
448 enum pm_ret_status status;
449
450 /* Get PLL node ID using PLL clock ID */
451 status = pm_clock_get_pll_node_id(pll, &pll_nid);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530452 if (status != PM_RET_SUCCESS) {
Jolly Shahb4c99462019-01-02 12:40:17 -0800453 return status;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530454 }
Jolly Shahb4c99462019-01-02 12:40:17 -0800455
456 return pm_pll_get_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
Rajan Vaja35116132018-01-17 02:39:25 -0800457}
458
459/**
Rajan Vaja393c0a22018-01-17 02:39:27 -0800460 * pm_ioctl_write_ggs() - Ioctl function for writing
461 * global general storage (ggs)
462 * @index GGS register index
463 * @value Register value to be written
464 *
465 * This function writes value to GGS register.
466 *
467 * @return Returns status, either success or error+reason
468 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530469static enum pm_ret_status pm_ioctl_write_ggs(uint32_t index,
470 uint32_t value)
Rajan Vaja393c0a22018-01-17 02:39:27 -0800471{
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530472 if (index >= GGS_NUM_REGS) {
Rajan Vaja393c0a22018-01-17 02:39:27 -0800473 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530474 }
Rajan Vaja393c0a22018-01-17 02:39:27 -0800475
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800476 return pm_mmio_write(GGS_BASEADDR + (index << 2),
477 0xFFFFFFFFU, value);
Rajan Vaja393c0a22018-01-17 02:39:27 -0800478}
479
480/**
481 * pm_ioctl_read_ggs() - Ioctl function for reading
482 * global general storage (ggs)
483 * @index GGS register index
484 * @value Register value
485 *
486 * This function returns GGS register value.
487 *
488 * @return Returns status, either success or error+reason
489 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530490static enum pm_ret_status pm_ioctl_read_ggs(uint32_t index,
491 uint32_t *value)
Rajan Vaja393c0a22018-01-17 02:39:27 -0800492{
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530493 if (index >= GGS_NUM_REGS) {
Rajan Vaja393c0a22018-01-17 02:39:27 -0800494 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530495 }
Rajan Vaja393c0a22018-01-17 02:39:27 -0800496
497 return pm_mmio_read(GGS_BASEADDR + (index << 2), value);
498}
499
500/**
501 * pm_ioctl_write_pggs() - Ioctl function for writing persistent
502 * global general storage (pggs)
503 * @index PGGS register index
504 * @value Register value to be written
505 *
506 * This function writes value to PGGS register.
507 *
508 * @return Returns status, either success or error+reason
509 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530510static enum pm_ret_status pm_ioctl_write_pggs(uint32_t index,
511 uint32_t value)
Rajan Vaja393c0a22018-01-17 02:39:27 -0800512{
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530513 if (index >= PGGS_NUM_REGS) {
Rajan Vaja393c0a22018-01-17 02:39:27 -0800514 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530515 }
Rajan Vaja393c0a22018-01-17 02:39:27 -0800516
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800517 return pm_mmio_write(PGGS_BASEADDR + (index << 2),
518 0xFFFFFFFFU, value);
Rajan Vaja393c0a22018-01-17 02:39:27 -0800519}
520
521/**
Siva Durga Prasad Paladugua22b8852018-09-04 17:27:12 +0530522 * pm_ioctl_afi() - Ioctl function for writing afi values
523 *
524 * @index AFI register index
525 * @value Register value to be written
526 *
527 *
528 * @return Returns status, either success or error+reason
529 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530530static enum pm_ret_status pm_ioctl_afi(uint32_t index,
531 uint32_t value)
Siva Durga Prasad Paladugua22b8852018-09-04 17:27:12 +0530532{
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530533 uint32_t mask;
534 uint32_t regarr[] = {0xFD360000U,
Venkatesh Yadav Abbarapued4f1e82022-04-29 09:58:30 +0530535 0xFD360014U,
536 0xFD370000U,
537 0xFD370014U,
538 0xFD380000U,
539 0xFD380014U,
540 0xFD390000U,
541 0xFD390014U,
542 0xFD3a0000U,
543 0xFD3a0014U,
544 0xFD3b0000U,
545 0xFD3b0014U,
546 0xFF9b0000U,
547 0xFF9b0014U,
548 0xFD615000U,
549 0xFF419000U,
Siva Durga Prasad Paladugua22b8852018-09-04 17:27:12 +0530550 };
551
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530552 if (index >= ARRAY_SIZE(regarr)) {
Siva Durga Prasad Paladugua22b8852018-09-04 17:27:12 +0530553 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530554 }
Siva Durga Prasad Paladugua22b8852018-09-04 17:27:12 +0530555
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530556 if (index < AFIFM6_WRCTRL) {
Siva Durga Prasad Paladugua22b8852018-09-04 17:27:12 +0530557 mask = FABRIC_WIDTH;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530558 } else {
Siva Durga Prasad Paladugua22b8852018-09-04 17:27:12 +0530559 mask = 0xf00;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530560 }
Siva Durga Prasad Paladugua22b8852018-09-04 17:27:12 +0530561
562 return pm_mmio_write(regarr[index], mask, value);
563}
564
565/**
Rajan Vaja393c0a22018-01-17 02:39:27 -0800566 * pm_ioctl_read_pggs() - Ioctl function for reading persistent
567 * global general storage (pggs)
568 * @index PGGS register index
569 * @value Register value
570 *
571 * This function returns PGGS register value.
572 *
573 * @return Returns status, either success or error+reason
574 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530575static enum pm_ret_status pm_ioctl_read_pggs(uint32_t index,
576 uint32_t *value)
Rajan Vaja393c0a22018-01-17 02:39:27 -0800577{
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530578 if (index >= PGGS_NUM_REGS) {
Rajan Vaja393c0a22018-01-17 02:39:27 -0800579 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530580 }
Rajan Vaja393c0a22018-01-17 02:39:27 -0800581
582 return pm_mmio_read(PGGS_BASEADDR + (index << 2), value);
583}
584
585/**
Siva Durga Prasad Paladugued1d5cb2018-09-04 17:03:25 +0530586 * pm_ioctl_ulpi_reset() - Ioctl function for performing ULPI reset
587 *
588 * This function peerforms the ULPI reset sequence for resetting
589 * the ULPI transceiver.
590 *
591 * @return Returns status, either success or error+reason
592 */
593static enum pm_ret_status pm_ioctl_ulpi_reset(void)
594{
595 enum pm_ret_status ret;
596
597 ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
598 ZYNQMP_ULPI_RESET_VAL_HIGH);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530599 if (ret != PM_RET_SUCCESS) {
Siva Durga Prasad Paladugued1d5cb2018-09-04 17:03:25 +0530600 return ret;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530601 }
Siva Durga Prasad Paladugued1d5cb2018-09-04 17:03:25 +0530602
603 /* Drive ULPI assert for atleast 1ms */
604 mdelay(1);
605
606 ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
607 ZYNQMP_ULPI_RESET_VAL_LOW);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530608 if (ret != PM_RET_SUCCESS) {
Siva Durga Prasad Paladugued1d5cb2018-09-04 17:03:25 +0530609 return ret;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530610 }
Siva Durga Prasad Paladugued1d5cb2018-09-04 17:03:25 +0530611
612 /* Drive ULPI de-assert for atleast 1ms */
613 mdelay(1);
614
615 ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
616 ZYNQMP_ULPI_RESET_VAL_HIGH);
617
618 return ret;
619}
620
621/**
Siva Durga Prasad Paladuguac8526f2018-09-04 17:12:51 +0530622 * pm_ioctl_set_boot_health_status() - Ioctl for setting healthy boot status
623 *
624 * This function sets healthy bit value to indicate boot health status
625 * to firmware.
626 *
627 * @return Returns status, either success or error+reason
628 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530629static enum pm_ret_status pm_ioctl_set_boot_health_status(uint32_t value)
Siva Durga Prasad Paladuguac8526f2018-09-04 17:12:51 +0530630{
Tejas Patel6552a552020-11-22 23:37:55 -0800631 return pm_mmio_write(PMU_GLOBAL_GEN_STORAGE4,
Siva Durga Prasad Paladuguac8526f2018-09-04 17:12:51 +0530632 PM_BOOT_HEALTH_STATUS_MASK, value);
633}
634
635/**
Rajan Vaja5529a012018-01-17 02:39:23 -0800636 * pm_api_ioctl() - PM IOCTL API for device control and configs
637 * @node_id Node ID of the device
638 * @ioctl_id ID of the requested IOCTL
639 * @arg1 Argument 1 to requested IOCTL call
640 * @arg2 Argument 2 to requested IOCTL call
641 * @value Returned output value
642 *
643 * This function calls IOCTL to firmware for device control and configuration.
644 *
645 * @return Returns status, either success or error+reason
646 */
647enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530648 uint32_t ioctl_id,
649 uint32_t arg1,
650 uint32_t arg2,
651 uint32_t *value)
Rajan Vaja5529a012018-01-17 02:39:23 -0800652{
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800653 enum pm_ret_status ret;
Rajan Vaja0c0615a2021-10-12 03:30:09 -0700654 uint32_t payload[PAYLOAD_ARG_CNT];
Rajan Vaja5529a012018-01-17 02:39:23 -0800655
656 switch (ioctl_id) {
657 case IOCTL_GET_RPU_OPER_MODE:
658 ret = pm_ioctl_get_rpu_oper_mode(value);
659 break;
660 case IOCTL_SET_RPU_OPER_MODE:
661 ret = pm_ioctl_set_rpu_oper_mode(arg1);
662 break;
663 case IOCTL_RPU_BOOT_ADDR_CONFIG:
664 ret = pm_ioctl_config_boot_addr(nid, arg1);
665 break;
666 case IOCTL_TCM_COMB_CONFIG:
667 ret = pm_ioctl_config_tcm_comb(arg1);
668 break;
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800669 case IOCTL_SET_TAPDELAY_BYPASS:
670 ret = pm_ioctl_set_tapdelay_bypass(arg1, arg2);
671 break;
672 case IOCTL_SET_SGMII_MODE:
673 ret = pm_ioctl_set_sgmii_mode(nid, arg1);
674 break;
675 case IOCTL_SD_DLL_RESET:
676 ret = pm_ioctl_sd_dll_reset(nid, arg1);
677 break;
678 case IOCTL_SET_SD_TAPDELAY:
679 ret = pm_ioctl_sd_set_tapdelay(nid, arg1, arg2);
680 break;
Rajan Vaja35116132018-01-17 02:39:25 -0800681 case IOCTL_SET_PLL_FRAC_MODE:
682 ret = pm_ioctl_set_pll_frac_mode(arg1, arg2);
683 break;
684 case IOCTL_GET_PLL_FRAC_MODE:
685 ret = pm_ioctl_get_pll_frac_mode(arg1, value);
686 break;
687 case IOCTL_SET_PLL_FRAC_DATA:
688 ret = pm_ioctl_set_pll_frac_data(arg1, arg2);
689 break;
690 case IOCTL_GET_PLL_FRAC_DATA:
691 ret = pm_ioctl_get_pll_frac_data(arg1, value);
692 break;
Rajan Vaja393c0a22018-01-17 02:39:27 -0800693 case IOCTL_WRITE_GGS:
694 ret = pm_ioctl_write_ggs(arg1, arg2);
695 break;
696 case IOCTL_READ_GGS:
697 ret = pm_ioctl_read_ggs(arg1, value);
698 break;
699 case IOCTL_WRITE_PGGS:
700 ret = pm_ioctl_write_pggs(arg1, arg2);
701 break;
702 case IOCTL_READ_PGGS:
703 ret = pm_ioctl_read_pggs(arg1, value);
704 break;
Siva Durga Prasad Paladugued1d5cb2018-09-04 17:03:25 +0530705 case IOCTL_ULPI_RESET:
706 ret = pm_ioctl_ulpi_reset();
707 break;
Siva Durga Prasad Paladuguac8526f2018-09-04 17:12:51 +0530708 case IOCTL_SET_BOOT_HEALTH_STATUS:
709 ret = pm_ioctl_set_boot_health_status(arg1);
710 break;
Siva Durga Prasad Paladugua22b8852018-09-04 17:27:12 +0530711 case IOCTL_AFI:
712 ret = pm_ioctl_afi(arg1, arg2);
713 break;
Rajan Vaja5529a012018-01-17 02:39:23 -0800714 default:
Rajan Vaja0c0615a2021-10-12 03:30:09 -0700715 /* Send request to the PMU */
716 PM_PACK_PAYLOAD5(payload, PM_IOCTL, nid, ioctl_id, arg1, arg2);
717
718 ret = pm_ipi_send_sync(primary_proc, payload, value, 1);
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800719 break;
Rajan Vaja5529a012018-01-17 02:39:23 -0800720 }
721
722 return ret;
723}
Ronak Jain325bad12021-12-21 01:39:59 -0800724
725/**
726 * pm_update_ioctl_bitmask() - API to get supported IOCTL ID mask
727 * @bit_mask Returned bit mask of supported IOCTL IDs
728 */
729enum pm_ret_status atf_ioctl_bitmask(uint32_t *bit_mask)
730{
731 uint8_t supported_ids[] = {
732 IOCTL_GET_RPU_OPER_MODE,
733 IOCTL_SET_RPU_OPER_MODE,
734 IOCTL_RPU_BOOT_ADDR_CONFIG,
735 IOCTL_TCM_COMB_CONFIG,
736 IOCTL_SET_TAPDELAY_BYPASS,
737 IOCTL_SET_SGMII_MODE,
738 IOCTL_SD_DLL_RESET,
739 IOCTL_SET_SD_TAPDELAY,
740 IOCTL_SET_PLL_FRAC_MODE,
741 IOCTL_GET_PLL_FRAC_MODE,
742 IOCTL_SET_PLL_FRAC_DATA,
743 IOCTL_GET_PLL_FRAC_DATA,
744 IOCTL_WRITE_GGS,
745 IOCTL_READ_GGS,
746 IOCTL_WRITE_PGGS,
747 IOCTL_READ_PGGS,
748 IOCTL_ULPI_RESET,
749 IOCTL_SET_BOOT_HEALTH_STATUS,
750 IOCTL_AFI,
751 };
752 uint8_t i, ioctl_id;
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530753 int32_t ret;
Ronak Jain325bad12021-12-21 01:39:59 -0800754
755 for (i = 0U; i < ARRAY_SIZE(supported_ids); i++) {
756 ioctl_id = supported_ids[i];
757 if (ioctl_id >= 64U) {
758 return PM_RET_ERROR_NOTSUPPORTED;
759 }
760 ret = check_api_dependency(ioctl_id);
761 if (ret == PM_RET_SUCCESS) {
762 bit_mask[ioctl_id / 32] |= BIT(ioctl_id % 32);
763 }
764 }
765
766 return PM_RET_SUCCESS;
767}