blob: 45038b063fd8ed167fe87320c7554ebeba0979df [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.
Jay Buddhabhatti26e138a2022-12-21 23:03:35 -08003 * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
Rajan Vaja5529a012018-01-17 02:39:23 -08004 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8/*
9 * ZynqMP system level PM-API functions for ioctl.
10 */
11
12#include <arch_helpers.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000013#include <drivers/delay_timer.h>
14#include <lib/mmio.h>
15#include <plat/common/platform.h>
Jolly Shah16fe5ab2019-01-08 11:16:16 -080016#include <zynqmp_def.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000017
Rajan Vaja35116132018-01-17 02:39:25 -080018#include "pm_api_clock.h"
Rajan Vaja5529a012018-01-17 02:39:23 -080019#include "pm_api_ioctl.h"
Rajan Vaja5529a012018-01-17 02:39:23 -080020#include "pm_client.h"
21#include "pm_common.h"
22#include "pm_ipi.h"
Jay Buddhabhatti26e138a2022-12-21 23:03:35 -080023#include "zynqmp_pm_api_sys.h"
Rajan Vaja5529a012018-01-17 02:39:23 -080024
25/**
26 * pm_ioctl_get_rpu_oper_mode () - Get current RPU operation mode
27 * @mode Buffer to store value of oper mode(Split/Lock-step)
28 *
29 * This function provides current configured RPU operational mode.
30 *
31 * @return Returns status, either success or error+reason
32 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +053033static enum pm_ret_status pm_ioctl_get_rpu_oper_mode(uint32_t *mode)
Rajan Vaja5529a012018-01-17 02:39:23 -080034{
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +053035 uint32_t val;
Rajan Vaja5529a012018-01-17 02:39:23 -080036
37 val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
38 val &= ZYNQMP_SLSPLIT_MASK;
Venkatesh Yadav Abbarapua2ca35d2022-07-04 11:40:27 +053039 if (val == 0U) {
Rajan Vaja5529a012018-01-17 02:39:23 -080040 *mode = PM_RPU_MODE_LOCKSTEP;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +053041 } else {
Jolly Shah69fb5bf2018-02-07 16:25:41 -080042 *mode = PM_RPU_MODE_SPLIT;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +053043 }
Rajan Vaja5529a012018-01-17 02:39:23 -080044
45 return PM_RET_SUCCESS;
46}
47
48/**
49 * pm_ioctl_set_rpu_oper_mode () - Configure RPU operation mode
50 * @mode Value to set for oper mode(Split/Lock-step)
51 *
52 * This function configures RPU operational mode(Split/Lock-step).
53 * It also sets TCM combined mode in RPU lock-step and TCM non-combined
54 * mode for RPU split mode. In case of Lock step mode, RPU1's output is
55 * clamped.
56 *
57 * @return Returns status, either success or error+reason
58 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +053059static enum pm_ret_status pm_ioctl_set_rpu_oper_mode(uint32_t mode)
Rajan Vaja5529a012018-01-17 02:39:23 -080060{
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +053061 uint32_t val;
Rajan Vaja5529a012018-01-17 02:39:23 -080062
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +053063 if (mmio_read_32(CRL_APB_RST_LPD_TOP) & CRL_APB_RPU_AMBA_RESET) {
Rajan Vaja5529a012018-01-17 02:39:23 -080064 return PM_RET_ERROR_ACCESS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +053065 }
Rajan Vaja5529a012018-01-17 02:39:23 -080066
67 val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
68
69 if (mode == PM_RPU_MODE_SPLIT) {
70 val |= ZYNQMP_SLSPLIT_MASK;
71 val &= ~ZYNQMP_TCM_COMB_MASK;
72 val &= ~ZYNQMP_SLCLAMP_MASK;
73 } else if (mode == PM_RPU_MODE_LOCKSTEP) {
74 val &= ~ZYNQMP_SLSPLIT_MASK;
75 val |= ZYNQMP_TCM_COMB_MASK;
76 val |= ZYNQMP_SLCLAMP_MASK;
77 } else {
78 return PM_RET_ERROR_ARGS;
79 }
80
81 mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
82
83 return PM_RET_SUCCESS;
84}
85
86/**
87 * pm_ioctl_config_boot_addr() - Configure RPU boot address
88 * @nid Node ID of RPU
89 * @value Value to set for boot address (TCM/OCM)
90 *
91 * This function configures RPU boot address(memory).
92 *
93 * @return Returns status, either success or error+reason
94 */
95static enum pm_ret_status pm_ioctl_config_boot_addr(enum pm_node_id nid,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +053096 uint32_t value)
Rajan Vaja5529a012018-01-17 02:39:23 -080097{
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +053098 uint32_t rpu_cfg_addr, val;
Rajan Vaja5529a012018-01-17 02:39:23 -080099
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530100 if (nid == NODE_RPU_0) {
Rajan Vaja5529a012018-01-17 02:39:23 -0800101 rpu_cfg_addr = ZYNQMP_RPU0_CFG;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530102 } else if (nid == NODE_RPU_1) {
Rajan Vaja5529a012018-01-17 02:39:23 -0800103 rpu_cfg_addr = ZYNQMP_RPU1_CFG;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530104 } else {
Rajan Vaja5529a012018-01-17 02:39:23 -0800105 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530106 }
Rajan Vaja5529a012018-01-17 02:39:23 -0800107
108 val = mmio_read_32(rpu_cfg_addr);
109
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530110 if (value == PM_RPU_BOOTMEM_LOVEC) {
Rajan Vaja5529a012018-01-17 02:39:23 -0800111 val &= ~ZYNQMP_VINITHI_MASK;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530112 } else if (value == PM_RPU_BOOTMEM_HIVEC) {
Rajan Vaja5529a012018-01-17 02:39:23 -0800113 val |= ZYNQMP_VINITHI_MASK;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530114 } else {
Rajan Vaja5529a012018-01-17 02:39:23 -0800115 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530116 }
Rajan Vaja5529a012018-01-17 02:39:23 -0800117
118 mmio_write_32(rpu_cfg_addr, val);
119
120 return PM_RET_SUCCESS;
121}
122
123/**
124 * pm_ioctl_config_tcm_comb() - Configure TCM combined mode
125 * @value Value to set (Split/Combined)
126 *
127 * This function configures TCM to be in split mode or combined
128 * mode.
129 *
130 * @return Returns status, either success or error+reason
131 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530132static enum pm_ret_status pm_ioctl_config_tcm_comb(uint32_t value)
Rajan Vaja5529a012018-01-17 02:39:23 -0800133{
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530134 uint32_t val;
Rajan Vaja5529a012018-01-17 02:39:23 -0800135
136 val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
137
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530138 if (value == PM_RPU_TCM_SPLIT) {
Rajan Vaja5529a012018-01-17 02:39:23 -0800139 val &= ~ZYNQMP_TCM_COMB_MASK;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530140 } else if (value == PM_RPU_TCM_COMB) {
Rajan Vaja5529a012018-01-17 02:39:23 -0800141 val |= ZYNQMP_TCM_COMB_MASK;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530142 } else {
Rajan Vaja5529a012018-01-17 02:39:23 -0800143 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530144 }
Rajan Vaja5529a012018-01-17 02:39:23 -0800145
146 mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
147
148 return PM_RET_SUCCESS;
149}
150
151/**
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800152 * pm_ioctl_set_tapdelay_bypass() - Enable/Disable tap delay bypass
153 * @type Type of tap delay to enable/disable (e.g. QSPI)
154 * @value Enable/Disable
155 *
156 * This function enable/disable tap delay bypass.
157 *
158 * @return Returns status, either success or error+reason
159 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530160static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(uint32_t type,
161 uint32_t value)
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800162{
163 if ((value != PM_TAPDELAY_BYPASS_ENABLE &&
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530164 value != PM_TAPDELAY_BYPASS_DISABLE) || type >= PM_TAPDELAY_MAX) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800165 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530166 }
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800167
168 return pm_mmio_write(IOU_TAPDLY_BYPASS, TAP_DELAY_MASK, value << type);
169}
170
171/**
172 * pm_ioctl_set_sgmii_mode() - Set SGMII mode for the GEM device
173 * @nid Node ID of the device
174 * @value Enable/Disable
175 *
176 * This function enable/disable SGMII mode for the GEM device.
177 * While enabling SGMII mode, it also ties the GEM PCS Signal
178 * Detect to 1 and selects EMIO for RX clock generation.
179 *
180 * @return Returns status, either success or error+reason
181 */
182static enum pm_ret_status pm_ioctl_set_sgmii_mode(enum pm_node_id nid,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530183 uint32_t value)
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800184{
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530185 uint32_t val, mask, shift;
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800186 enum pm_ret_status ret;
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800187
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530188 if (value != PM_SGMII_DISABLE && value != PM_SGMII_ENABLE) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800189 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530190 }
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800191
192 switch (nid) {
193 case NODE_ETH_0:
194 shift = 0;
195 break;
196 case NODE_ETH_1:
197 shift = 1;
198 break;
199 case NODE_ETH_2:
200 shift = 2;
201 break;
202 case NODE_ETH_3:
203 shift = 3;
204 break;
205 default:
206 return PM_RET_ERROR_ARGS;
207 }
208
209 if (value == PM_SGMII_DISABLE) {
210 mask = GEM_SGMII_MASK << GEM_CLK_CTRL_OFFSET * shift;
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800211 ret = pm_mmio_write(IOU_GEM_CLK_CTRL, mask, 0U);
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800212 } else {
213 /* Tie the GEM PCS Signal Detect to 1 */
214 mask = SGMII_SD_MASK << SGMII_SD_OFFSET * shift;
215 val = SGMII_PCS_SD_1 << SGMII_SD_OFFSET * shift;
216 ret = pm_mmio_write(IOU_GEM_CTRL, mask, val);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530217 if (ret != PM_RET_SUCCESS) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800218 return ret;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530219 }
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800220
221 /* Set the GEM to SGMII mode */
222 mask = GEM_CLK_CTRL_MASK << GEM_CLK_CTRL_OFFSET * shift;
223 val = GEM_RX_SRC_SEL_GTR | GEM_SGMII_MODE;
224 val <<= GEM_CLK_CTRL_OFFSET * shift;
225 ret = pm_mmio_write(IOU_GEM_CLK_CTRL, mask, val);
226 }
227
228 return ret;
229}
230
231/**
232 * pm_ioctl_sd_dll_reset() - Reset DLL logic
233 * @nid Node ID of the device
234 * @type Reset type
235 *
236 * This function resets DLL logic for the SD device.
237 *
238 * @return Returns status, either success or error+reason
239 */
240static enum pm_ret_status pm_ioctl_sd_dll_reset(enum pm_node_id nid,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530241 uint32_t type)
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800242{
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530243 uint32_t mask, val;
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800244 enum pm_ret_status ret;
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800245
246 if (nid == NODE_SD_0) {
247 mask = ZYNQMP_SD0_DLL_RST_MASK;
248 val = ZYNQMP_SD0_DLL_RST;
249 } else if (nid == NODE_SD_1) {
250 mask = ZYNQMP_SD1_DLL_RST_MASK;
251 val = ZYNQMP_SD1_DLL_RST;
252 } else {
253 return PM_RET_ERROR_ARGS;
254 }
255
256 switch (type) {
257 case PM_DLL_RESET_ASSERT:
258 case PM_DLL_RESET_PULSE:
259 ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, val);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530260 if (ret != PM_RET_SUCCESS) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800261 return ret;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530262 }
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800263
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530264 if (type == PM_DLL_RESET_ASSERT) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800265 break;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530266 }
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800267 mdelay(1);
Daniel Boulby8942a1b2018-06-22 14:16:03 +0100268 /* Fallthrough */
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800269 case PM_DLL_RESET_RELEASE:
270 ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, 0);
271 break;
272 default:
273 ret = PM_RET_ERROR_ARGS;
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800274 break;
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800275 }
276
277 return ret;
278}
279
280/**
281 * pm_ioctl_sd_set_tapdelay() - Set tap delay for the SD device
282 * @nid Node ID of the device
283 * @type Type of tap delay to set (input/output)
284 * @value Value to set fot the tap delay
285 *
286 * This function sets input/output tap delay for the SD device.
287 *
288 * @return Returns status, either success or error+reason
289 */
290static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid,
291 enum tap_delay_type type,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530292 uint32_t value)
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800293{
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530294 uint32_t shift;
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800295 enum pm_ret_status ret;
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530296 uint32_t val, mask;
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800297
Sai Krishna Potthuriad48c502020-10-20 07:00:06 -0600298 if (nid == NODE_SD_0) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800299 shift = 0;
Sai Krishna Potthuriad48c502020-10-20 07:00:06 -0600300 mask = ZYNQMP_SD0_DLL_RST_MASK;
301 } else if (nid == NODE_SD_1) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800302 shift = ZYNQMP_SD_TAP_OFFSET;
Sai Krishna Potthuriad48c502020-10-20 07:00:06 -0600303 mask = ZYNQMP_SD1_DLL_RST_MASK;
304 } else {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800305 return PM_RET_ERROR_ARGS;
Sai Krishna Potthuriad48c502020-10-20 07:00:06 -0600306 }
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800307
Sai Krishna Potthuriad48c502020-10-20 07:00:06 -0600308 ret = pm_mmio_read(ZYNQMP_SD_DLL_CTRL, &val);
309 if (ret != PM_RET_SUCCESS) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800310 return ret;
Sai Krishna Potthuriad48c502020-10-20 07:00:06 -0600311 }
312
Venkatesh Yadav Abbarapua2ca35d2022-07-04 11:40:27 +0530313 if ((val & mask) == 0U) {
Sai Krishna Potthuriad48c502020-10-20 07:00:06 -0600314 ret = pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_ASSERT);
315 if (ret != PM_RET_SUCCESS) {
316 return ret;
317 }
318 }
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800319
320 if (type == PM_TAPDELAY_INPUT) {
321 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800322 (ZYNQMP_SD_ITAPCHGWIN_MASK << shift),
323 (ZYNQMP_SD_ITAPCHGWIN << shift));
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530324
325 if (ret != PM_RET_SUCCESS) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800326 goto reset_release;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530327 }
328
Venkatesh Yadav Abbarapua2ca35d2022-07-04 11:40:27 +0530329 if (value == 0U) {
Sai Krishna Potthuri15da5822020-10-30 00:09:43 -0600330 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
331 (ZYNQMP_SD_ITAPDLYENA_MASK <<
332 shift), 0);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530333 } else {
Sai Krishna Potthuri15da5822020-10-30 00:09:43 -0600334 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
335 (ZYNQMP_SD_ITAPDLYENA_MASK <<
336 shift), (ZYNQMP_SD_ITAPDLYENA <<
337 shift));
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530338 }
339
340 if (ret != PM_RET_SUCCESS) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800341 goto reset_release;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530342 }
343
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800344 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800345 (ZYNQMP_SD_ITAPDLYSEL_MASK << shift),
346 (value << shift));
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530347
348 if (ret != PM_RET_SUCCESS) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800349 goto reset_release;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530350 }
351
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800352 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800353 (ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0);
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800354 } else if (type == PM_TAPDELAY_OUTPUT) {
355 ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
Sai Krishna Potthuri15da5822020-10-30 00:09:43 -0600356 (ZYNQMP_SD_OTAPDLYENA_MASK << shift), 0);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530357
358 if (ret != PM_RET_SUCCESS) {
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800359 goto reset_release;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530360 }
361
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800362 ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800363 (ZYNQMP_SD_OTAPDLYSEL_MASK << shift),
364 (value << shift));
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800365 } else {
366 ret = PM_RET_ERROR_ARGS;
367 }
368
369reset_release:
Sai Krishna Potthuriad48c502020-10-20 07:00:06 -0600370 if ((val & mask) == 0) {
371 (void)pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_RELEASE);
372 }
373
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800374 return ret;
375}
376
377/**
Rajan Vaja35116132018-01-17 02:39:25 -0800378 * pm_ioctl_set_pll_frac_mode() - Ioctl function for
379 * setting pll mode
Jolly Shahcb5bc752019-01-02 12:46:46 -0800380 * @pll PLL clock id
Rajan Vaja35116132018-01-17 02:39:25 -0800381 * @mode Mode fraction/integar
382 *
383 * This function sets PLL mode
384 *
385 * @return Returns status, either success or error+reason
386 */
387static enum pm_ret_status pm_ioctl_set_pll_frac_mode
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530388 (uint32_t pll, uint32_t mode)
Rajan Vaja35116132018-01-17 02:39:25 -0800389{
Jolly Shahcb5bc752019-01-02 12:46:46 -0800390 return pm_clock_set_pll_mode(pll, mode);
Rajan Vaja35116132018-01-17 02:39:25 -0800391}
392
393/**
394 * pm_ioctl_get_pll_frac_mode() - Ioctl function for
395 * getting pll mode
Jolly Shah77eb52f2019-01-02 12:49:21 -0800396 * @pll PLL clock id
Rajan Vaja35116132018-01-17 02:39:25 -0800397 * @mode Mode fraction/integar
398 *
399 * This function return current PLL mode
400 *
401 * @return Returns status, either success or error+reason
402 */
403static enum pm_ret_status pm_ioctl_get_pll_frac_mode
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530404 (uint32_t pll, uint32_t *mode)
Rajan Vaja35116132018-01-17 02:39:25 -0800405{
Jolly Shah77eb52f2019-01-02 12:49:21 -0800406 return pm_clock_get_pll_mode(pll, mode);
Rajan Vaja35116132018-01-17 02:39:25 -0800407}
408
409/**
410 * pm_ioctl_set_pll_frac_data() - Ioctl function for
411 * setting pll fraction data
Jolly Shah68116ef2019-01-02 12:42:56 -0800412 * @pll PLL clock id
Rajan Vaja35116132018-01-17 02:39:25 -0800413 * @data fraction data
414 *
415 * This function sets fraction data.
416 * It is valid for fraction mode only.
417 *
418 * @return Returns status, either success or error+reason
419 */
420static enum pm_ret_status pm_ioctl_set_pll_frac_data
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530421 (uint32_t pll, uint32_t data)
Rajan Vaja35116132018-01-17 02:39:25 -0800422{
Jolly Shah68116ef2019-01-02 12:42:56 -0800423 enum pm_node_id pll_nid;
424 enum pm_ret_status status;
425
426 /* Get PLL node ID using PLL clock ID */
427 status = pm_clock_get_pll_node_id(pll, &pll_nid);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530428 if (status != PM_RET_SUCCESS) {
Jolly Shah68116ef2019-01-02 12:42:56 -0800429 return status;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530430 }
Jolly Shah68116ef2019-01-02 12:42:56 -0800431
432 return pm_pll_set_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
Rajan Vaja35116132018-01-17 02:39:25 -0800433}
434
435/**
436 * pm_ioctl_get_pll_frac_data() - Ioctl function for
437 * getting pll fraction data
Jolly Shahb4c99462019-01-02 12:40:17 -0800438 * @pll PLL clock id
Rajan Vaja35116132018-01-17 02:39:25 -0800439 * @data fraction data
440 *
441 * This function returns fraction data value.
442 *
443 * @return Returns status, either success or error+reason
444 */
445static enum pm_ret_status pm_ioctl_get_pll_frac_data
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530446 (uint32_t pll, uint32_t *data)
Rajan Vaja35116132018-01-17 02:39:25 -0800447{
Jolly Shahb4c99462019-01-02 12:40:17 -0800448 enum pm_node_id pll_nid;
449 enum pm_ret_status status;
450
451 /* Get PLL node ID using PLL clock ID */
452 status = pm_clock_get_pll_node_id(pll, &pll_nid);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530453 if (status != PM_RET_SUCCESS) {
Jolly Shahb4c99462019-01-02 12:40:17 -0800454 return status;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530455 }
Jolly Shahb4c99462019-01-02 12:40:17 -0800456
457 return pm_pll_get_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
Rajan Vaja35116132018-01-17 02:39:25 -0800458}
459
460/**
Rajan Vaja393c0a22018-01-17 02:39:27 -0800461 * pm_ioctl_write_ggs() - Ioctl function for writing
462 * global general storage (ggs)
463 * @index GGS register index
464 * @value Register value to be written
465 *
466 * This function writes value to GGS register.
467 *
468 * @return Returns status, either success or error+reason
469 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530470static enum pm_ret_status pm_ioctl_write_ggs(uint32_t index,
471 uint32_t value)
Rajan Vaja393c0a22018-01-17 02:39:27 -0800472{
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530473 if (index >= GGS_NUM_REGS) {
Rajan Vaja393c0a22018-01-17 02:39:27 -0800474 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530475 }
Rajan Vaja393c0a22018-01-17 02:39:27 -0800476
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800477 return pm_mmio_write(GGS_BASEADDR + (index << 2),
478 0xFFFFFFFFU, value);
Rajan Vaja393c0a22018-01-17 02:39:27 -0800479}
480
481/**
482 * pm_ioctl_read_ggs() - Ioctl function for reading
483 * global general storage (ggs)
484 * @index GGS register index
485 * @value Register value
486 *
487 * This function returns GGS register value.
488 *
489 * @return Returns status, either success or error+reason
490 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530491static enum pm_ret_status pm_ioctl_read_ggs(uint32_t index,
492 uint32_t *value)
Rajan Vaja393c0a22018-01-17 02:39:27 -0800493{
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530494 if (index >= GGS_NUM_REGS) {
Rajan Vaja393c0a22018-01-17 02:39:27 -0800495 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530496 }
Rajan Vaja393c0a22018-01-17 02:39:27 -0800497
498 return pm_mmio_read(GGS_BASEADDR + (index << 2), value);
499}
500
501/**
502 * pm_ioctl_write_pggs() - Ioctl function for writing persistent
503 * global general storage (pggs)
504 * @index PGGS register index
505 * @value Register value to be written
506 *
507 * This function writes value to PGGS register.
508 *
509 * @return Returns status, either success or error+reason
510 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530511static enum pm_ret_status pm_ioctl_write_pggs(uint32_t index,
512 uint32_t value)
Rajan Vaja393c0a22018-01-17 02:39:27 -0800513{
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530514 if (index >= PGGS_NUM_REGS) {
Rajan Vaja393c0a22018-01-17 02:39:27 -0800515 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530516 }
Rajan Vaja393c0a22018-01-17 02:39:27 -0800517
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800518 return pm_mmio_write(PGGS_BASEADDR + (index << 2),
519 0xFFFFFFFFU, value);
Rajan Vaja393c0a22018-01-17 02:39:27 -0800520}
521
522/**
Siva Durga Prasad Paladugua22b8852018-09-04 17:27:12 +0530523 * pm_ioctl_afi() - Ioctl function for writing afi values
524 *
525 * @index AFI register index
526 * @value Register value to be written
527 *
528 *
529 * @return Returns status, either success or error+reason
530 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530531static enum pm_ret_status pm_ioctl_afi(uint32_t index,
532 uint32_t value)
Siva Durga Prasad Paladugua22b8852018-09-04 17:27:12 +0530533{
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530534 uint32_t mask;
535 uint32_t regarr[] = {0xFD360000U,
Venkatesh Yadav Abbarapued4f1e82022-04-29 09:58:30 +0530536 0xFD360014U,
537 0xFD370000U,
538 0xFD370014U,
539 0xFD380000U,
540 0xFD380014U,
541 0xFD390000U,
542 0xFD390014U,
543 0xFD3a0000U,
544 0xFD3a0014U,
545 0xFD3b0000U,
546 0xFD3b0014U,
547 0xFF9b0000U,
548 0xFF9b0014U,
549 0xFD615000U,
550 0xFF419000U,
Siva Durga Prasad Paladugua22b8852018-09-04 17:27:12 +0530551 };
552
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530553 if (index >= ARRAY_SIZE(regarr)) {
Siva Durga Prasad Paladugua22b8852018-09-04 17:27:12 +0530554 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530555 }
Siva Durga Prasad Paladugua22b8852018-09-04 17:27:12 +0530556
Akshay Belsareaf00b312022-08-23 11:39:35 +0530557 if (index <= AFIFM6_WRCTRL) {
Siva Durga Prasad Paladugua22b8852018-09-04 17:27:12 +0530558 mask = FABRIC_WIDTH;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530559 } else {
Siva Durga Prasad Paladugua22b8852018-09-04 17:27:12 +0530560 mask = 0xf00;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530561 }
Siva Durga Prasad Paladugua22b8852018-09-04 17:27:12 +0530562
563 return pm_mmio_write(regarr[index], mask, value);
564}
565
566/**
Rajan Vaja393c0a22018-01-17 02:39:27 -0800567 * pm_ioctl_read_pggs() - Ioctl function for reading persistent
568 * global general storage (pggs)
569 * @index PGGS register index
570 * @value Register value
571 *
572 * This function returns PGGS register value.
573 *
574 * @return Returns status, either success or error+reason
575 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530576static enum pm_ret_status pm_ioctl_read_pggs(uint32_t index,
577 uint32_t *value)
Rajan Vaja393c0a22018-01-17 02:39:27 -0800578{
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530579 if (index >= PGGS_NUM_REGS) {
Rajan Vaja393c0a22018-01-17 02:39:27 -0800580 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530581 }
Rajan Vaja393c0a22018-01-17 02:39:27 -0800582
583 return pm_mmio_read(PGGS_BASEADDR + (index << 2), value);
584}
585
586/**
Siva Durga Prasad Paladugued1d5cb2018-09-04 17:03:25 +0530587 * pm_ioctl_ulpi_reset() - Ioctl function for performing ULPI reset
588 *
589 * This function peerforms the ULPI reset sequence for resetting
590 * the ULPI transceiver.
591 *
592 * @return Returns status, either success or error+reason
593 */
594static enum pm_ret_status pm_ioctl_ulpi_reset(void)
595{
596 enum pm_ret_status ret;
597
598 ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
599 ZYNQMP_ULPI_RESET_VAL_HIGH);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530600 if (ret != PM_RET_SUCCESS) {
Siva Durga Prasad Paladugued1d5cb2018-09-04 17:03:25 +0530601 return ret;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530602 }
Siva Durga Prasad Paladugued1d5cb2018-09-04 17:03:25 +0530603
604 /* Drive ULPI assert for atleast 1ms */
605 mdelay(1);
606
607 ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
608 ZYNQMP_ULPI_RESET_VAL_LOW);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530609 if (ret != PM_RET_SUCCESS) {
Siva Durga Prasad Paladugued1d5cb2018-09-04 17:03:25 +0530610 return ret;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530611 }
Siva Durga Prasad Paladugued1d5cb2018-09-04 17:03:25 +0530612
613 /* Drive ULPI de-assert for atleast 1ms */
614 mdelay(1);
615
616 ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
617 ZYNQMP_ULPI_RESET_VAL_HIGH);
618
619 return ret;
620}
621
622/**
Siva Durga Prasad Paladuguac8526f2018-09-04 17:12:51 +0530623 * pm_ioctl_set_boot_health_status() - Ioctl for setting healthy boot status
624 *
625 * This function sets healthy bit value to indicate boot health status
626 * to firmware.
627 *
628 * @return Returns status, either success or error+reason
629 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530630static enum pm_ret_status pm_ioctl_set_boot_health_status(uint32_t value)
Siva Durga Prasad Paladuguac8526f2018-09-04 17:12:51 +0530631{
Tejas Patel6552a552020-11-22 23:37:55 -0800632 return pm_mmio_write(PMU_GLOBAL_GEN_STORAGE4,
Siva Durga Prasad Paladuguac8526f2018-09-04 17:12:51 +0530633 PM_BOOT_HEALTH_STATUS_MASK, value);
634}
635
636/**
Rajan Vaja5529a012018-01-17 02:39:23 -0800637 * pm_api_ioctl() - PM IOCTL API for device control and configs
638 * @node_id Node ID of the device
639 * @ioctl_id ID of the requested IOCTL
640 * @arg1 Argument 1 to requested IOCTL call
641 * @arg2 Argument 2 to requested IOCTL call
642 * @value Returned output value
643 *
644 * This function calls IOCTL to firmware for device control and configuration.
645 *
646 * @return Returns status, either success or error+reason
647 */
648enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530649 uint32_t ioctl_id,
650 uint32_t arg1,
651 uint32_t arg2,
652 uint32_t *value)
Rajan Vaja5529a012018-01-17 02:39:23 -0800653{
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800654 enum pm_ret_status ret;
Rajan Vaja0c0615a2021-10-12 03:30:09 -0700655 uint32_t payload[PAYLOAD_ARG_CNT];
Rajan Vaja5529a012018-01-17 02:39:23 -0800656
657 switch (ioctl_id) {
658 case IOCTL_GET_RPU_OPER_MODE:
659 ret = pm_ioctl_get_rpu_oper_mode(value);
660 break;
661 case IOCTL_SET_RPU_OPER_MODE:
662 ret = pm_ioctl_set_rpu_oper_mode(arg1);
663 break;
664 case IOCTL_RPU_BOOT_ADDR_CONFIG:
665 ret = pm_ioctl_config_boot_addr(nid, arg1);
666 break;
667 case IOCTL_TCM_COMB_CONFIG:
668 ret = pm_ioctl_config_tcm_comb(arg1);
669 break;
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800670 case IOCTL_SET_TAPDELAY_BYPASS:
671 ret = pm_ioctl_set_tapdelay_bypass(arg1, arg2);
672 break;
673 case IOCTL_SET_SGMII_MODE:
674 ret = pm_ioctl_set_sgmii_mode(nid, arg1);
675 break;
676 case IOCTL_SD_DLL_RESET:
677 ret = pm_ioctl_sd_dll_reset(nid, arg1);
678 break;
679 case IOCTL_SET_SD_TAPDELAY:
680 ret = pm_ioctl_sd_set_tapdelay(nid, arg1, arg2);
681 break;
Rajan Vaja35116132018-01-17 02:39:25 -0800682 case IOCTL_SET_PLL_FRAC_MODE:
683 ret = pm_ioctl_set_pll_frac_mode(arg1, arg2);
684 break;
685 case IOCTL_GET_PLL_FRAC_MODE:
686 ret = pm_ioctl_get_pll_frac_mode(arg1, value);
687 break;
688 case IOCTL_SET_PLL_FRAC_DATA:
689 ret = pm_ioctl_set_pll_frac_data(arg1, arg2);
690 break;
691 case IOCTL_GET_PLL_FRAC_DATA:
692 ret = pm_ioctl_get_pll_frac_data(arg1, value);
693 break;
Rajan Vaja393c0a22018-01-17 02:39:27 -0800694 case IOCTL_WRITE_GGS:
695 ret = pm_ioctl_write_ggs(arg1, arg2);
696 break;
697 case IOCTL_READ_GGS:
698 ret = pm_ioctl_read_ggs(arg1, value);
699 break;
700 case IOCTL_WRITE_PGGS:
701 ret = pm_ioctl_write_pggs(arg1, arg2);
702 break;
703 case IOCTL_READ_PGGS:
704 ret = pm_ioctl_read_pggs(arg1, value);
705 break;
Siva Durga Prasad Paladugued1d5cb2018-09-04 17:03:25 +0530706 case IOCTL_ULPI_RESET:
707 ret = pm_ioctl_ulpi_reset();
708 break;
Siva Durga Prasad Paladuguac8526f2018-09-04 17:12:51 +0530709 case IOCTL_SET_BOOT_HEALTH_STATUS:
710 ret = pm_ioctl_set_boot_health_status(arg1);
711 break;
Siva Durga Prasad Paladugua22b8852018-09-04 17:27:12 +0530712 case IOCTL_AFI:
713 ret = pm_ioctl_afi(arg1, arg2);
714 break;
Rajan Vaja5529a012018-01-17 02:39:23 -0800715 default:
Rajan Vaja0c0615a2021-10-12 03:30:09 -0700716 /* Send request to the PMU */
717 PM_PACK_PAYLOAD5(payload, PM_IOCTL, nid, ioctl_id, arg1, arg2);
718
719 ret = pm_ipi_send_sync(primary_proc, payload, value, 1);
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800720 break;
Rajan Vaja5529a012018-01-17 02:39:23 -0800721 }
722
723 return ret;
724}
Ronak Jain325bad12021-12-21 01:39:59 -0800725
726/**
727 * pm_update_ioctl_bitmask() - API to get supported IOCTL ID mask
728 * @bit_mask Returned bit mask of supported IOCTL IDs
729 */
730enum pm_ret_status atf_ioctl_bitmask(uint32_t *bit_mask)
731{
732 uint8_t supported_ids[] = {
733 IOCTL_GET_RPU_OPER_MODE,
734 IOCTL_SET_RPU_OPER_MODE,
735 IOCTL_RPU_BOOT_ADDR_CONFIG,
736 IOCTL_TCM_COMB_CONFIG,
737 IOCTL_SET_TAPDELAY_BYPASS,
738 IOCTL_SET_SGMII_MODE,
739 IOCTL_SD_DLL_RESET,
740 IOCTL_SET_SD_TAPDELAY,
741 IOCTL_SET_PLL_FRAC_MODE,
742 IOCTL_GET_PLL_FRAC_MODE,
743 IOCTL_SET_PLL_FRAC_DATA,
744 IOCTL_GET_PLL_FRAC_DATA,
745 IOCTL_WRITE_GGS,
746 IOCTL_READ_GGS,
747 IOCTL_WRITE_PGGS,
748 IOCTL_READ_PGGS,
749 IOCTL_ULPI_RESET,
750 IOCTL_SET_BOOT_HEALTH_STATUS,
751 IOCTL_AFI,
752 };
753 uint8_t i, ioctl_id;
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530754 int32_t ret;
Ronak Jain325bad12021-12-21 01:39:59 -0800755
756 for (i = 0U; i < ARRAY_SIZE(supported_ids); i++) {
757 ioctl_id = supported_ids[i];
758 if (ioctl_id >= 64U) {
759 return PM_RET_ERROR_NOTSUPPORTED;
760 }
761 ret = check_api_dependency(ioctl_id);
762 if (ret == PM_RET_SUCCESS) {
HariBabu Gattemb0c70f52022-09-29 23:59:11 -0700763 bit_mask[ioctl_id / 32U] |= BIT(ioctl_id % 32U);
Ronak Jain325bad12021-12-21 01:39:59 -0800764 }
765 }
766
767 return PM_RET_SUCCESS;
768}