blob: 60e80d907cb92220ba9818282f9ae87330312ee6 [file] [log] [blame]
Rajan Vaja5529a012018-01-17 02:39:23 -08001/*
2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3 *
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 */
32static enum pm_ret_status pm_ioctl_get_rpu_oper_mode(unsigned int *mode)
33{
34 unsigned int val;
35
36 val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
37 val &= ZYNQMP_SLSPLIT_MASK;
Jolly Shah69fb5bf2018-02-07 16:25:41 -080038 if (val == 0)
Rajan Vaja5529a012018-01-17 02:39:23 -080039 *mode = PM_RPU_MODE_LOCKSTEP;
Jolly Shah69fb5bf2018-02-07 16:25:41 -080040 else
41 *mode = PM_RPU_MODE_SPLIT;
Rajan Vaja5529a012018-01-17 02:39:23 -080042
43 return PM_RET_SUCCESS;
44}
45
46/**
47 * pm_ioctl_set_rpu_oper_mode () - Configure RPU operation mode
48 * @mode Value to set for oper mode(Split/Lock-step)
49 *
50 * This function configures RPU operational mode(Split/Lock-step).
51 * It also sets TCM combined mode in RPU lock-step and TCM non-combined
52 * mode for RPU split mode. In case of Lock step mode, RPU1's output is
53 * clamped.
54 *
55 * @return Returns status, either success or error+reason
56 */
57static enum pm_ret_status pm_ioctl_set_rpu_oper_mode(unsigned int mode)
58{
59 unsigned int val;
60
Justin Chadwell42d18ca2019-09-18 14:13:42 +010061 if (mmio_read_32(CRL_APB_RST_LPD_TOP) & CRL_APB_RPU_AMBA_RESET)
Rajan Vaja5529a012018-01-17 02:39:23 -080062 return PM_RET_ERROR_ACCESS;
63
64 val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
65
66 if (mode == PM_RPU_MODE_SPLIT) {
67 val |= ZYNQMP_SLSPLIT_MASK;
68 val &= ~ZYNQMP_TCM_COMB_MASK;
69 val &= ~ZYNQMP_SLCLAMP_MASK;
70 } else if (mode == PM_RPU_MODE_LOCKSTEP) {
71 val &= ~ZYNQMP_SLSPLIT_MASK;
72 val |= ZYNQMP_TCM_COMB_MASK;
73 val |= ZYNQMP_SLCLAMP_MASK;
74 } else {
75 return PM_RET_ERROR_ARGS;
76 }
77
78 mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
79
80 return PM_RET_SUCCESS;
81}
82
83/**
84 * pm_ioctl_config_boot_addr() - Configure RPU boot address
85 * @nid Node ID of RPU
86 * @value Value to set for boot address (TCM/OCM)
87 *
88 * This function configures RPU boot address(memory).
89 *
90 * @return Returns status, either success or error+reason
91 */
92static enum pm_ret_status pm_ioctl_config_boot_addr(enum pm_node_id nid,
93 unsigned int value)
94{
95 unsigned int rpu_cfg_addr, val;
96
97 if (nid == NODE_RPU_0)
98 rpu_cfg_addr = ZYNQMP_RPU0_CFG;
99 else if (nid == NODE_RPU_1)
100 rpu_cfg_addr = ZYNQMP_RPU1_CFG;
101 else
102 return PM_RET_ERROR_ARGS;
103
104 val = mmio_read_32(rpu_cfg_addr);
105
106 if (value == PM_RPU_BOOTMEM_LOVEC)
107 val &= ~ZYNQMP_VINITHI_MASK;
108 else if (value == PM_RPU_BOOTMEM_HIVEC)
109 val |= ZYNQMP_VINITHI_MASK;
110 else
111 return PM_RET_ERROR_ARGS;
112
113 mmio_write_32(rpu_cfg_addr, val);
114
115 return PM_RET_SUCCESS;
116}
117
118/**
119 * pm_ioctl_config_tcm_comb() - Configure TCM combined mode
120 * @value Value to set (Split/Combined)
121 *
122 * This function configures TCM to be in split mode or combined
123 * mode.
124 *
125 * @return Returns status, either success or error+reason
126 */
127static enum pm_ret_status pm_ioctl_config_tcm_comb(unsigned int value)
128{
129 unsigned int val;
130
131 val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
132
133 if (value == PM_RPU_TCM_SPLIT)
134 val &= ~ZYNQMP_TCM_COMB_MASK;
135 else if (value == PM_RPU_TCM_COMB)
136 val |= ZYNQMP_TCM_COMB_MASK;
137 else
138 return PM_RET_ERROR_ARGS;
139
140 mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
141
142 return PM_RET_SUCCESS;
143}
144
145/**
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800146 * pm_ioctl_set_tapdelay_bypass() - Enable/Disable tap delay bypass
147 * @type Type of tap delay to enable/disable (e.g. QSPI)
148 * @value Enable/Disable
149 *
150 * This function enable/disable tap delay bypass.
151 *
152 * @return Returns status, either success or error+reason
153 */
154static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(unsigned int type,
155 unsigned int value)
156{
157 if ((value != PM_TAPDELAY_BYPASS_ENABLE &&
158 value != PM_TAPDELAY_BYPASS_DISABLE) || type >= PM_TAPDELAY_MAX)
159 return PM_RET_ERROR_ARGS;
160
161 return pm_mmio_write(IOU_TAPDLY_BYPASS, TAP_DELAY_MASK, value << type);
162}
163
164/**
165 * pm_ioctl_set_sgmii_mode() - Set SGMII mode for the GEM device
166 * @nid Node ID of the device
167 * @value Enable/Disable
168 *
169 * This function enable/disable SGMII mode for the GEM device.
170 * While enabling SGMII mode, it also ties the GEM PCS Signal
171 * Detect to 1 and selects EMIO for RX clock generation.
172 *
173 * @return Returns status, either success or error+reason
174 */
175static enum pm_ret_status pm_ioctl_set_sgmii_mode(enum pm_node_id nid,
176 unsigned int value)
177{
178 unsigned int val, mask, shift;
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800179 enum pm_ret_status ret;
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800180
181 if (value != PM_SGMII_DISABLE && value != PM_SGMII_ENABLE)
182 return PM_RET_ERROR_ARGS;
183
184 switch (nid) {
185 case NODE_ETH_0:
186 shift = 0;
187 break;
188 case NODE_ETH_1:
189 shift = 1;
190 break;
191 case NODE_ETH_2:
192 shift = 2;
193 break;
194 case NODE_ETH_3:
195 shift = 3;
196 break;
197 default:
198 return PM_RET_ERROR_ARGS;
199 }
200
201 if (value == PM_SGMII_DISABLE) {
202 mask = GEM_SGMII_MASK << GEM_CLK_CTRL_OFFSET * shift;
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800203 ret = pm_mmio_write(IOU_GEM_CLK_CTRL, mask, 0U);
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800204 } else {
205 /* Tie the GEM PCS Signal Detect to 1 */
206 mask = SGMII_SD_MASK << SGMII_SD_OFFSET * shift;
207 val = SGMII_PCS_SD_1 << SGMII_SD_OFFSET * shift;
208 ret = pm_mmio_write(IOU_GEM_CTRL, mask, val);
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800209 if (ret != PM_RET_SUCCESS)
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800210 return ret;
211
212 /* Set the GEM to SGMII mode */
213 mask = GEM_CLK_CTRL_MASK << GEM_CLK_CTRL_OFFSET * shift;
214 val = GEM_RX_SRC_SEL_GTR | GEM_SGMII_MODE;
215 val <<= GEM_CLK_CTRL_OFFSET * shift;
216 ret = pm_mmio_write(IOU_GEM_CLK_CTRL, mask, val);
217 }
218
219 return ret;
220}
221
222/**
223 * pm_ioctl_sd_dll_reset() - Reset DLL logic
224 * @nid Node ID of the device
225 * @type Reset type
226 *
227 * This function resets DLL logic for the SD device.
228 *
229 * @return Returns status, either success or error+reason
230 */
231static enum pm_ret_status pm_ioctl_sd_dll_reset(enum pm_node_id nid,
232 unsigned int type)
233{
234 unsigned int mask, val;
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800235 enum pm_ret_status ret;
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800236
237 if (nid == NODE_SD_0) {
238 mask = ZYNQMP_SD0_DLL_RST_MASK;
239 val = ZYNQMP_SD0_DLL_RST;
240 } else if (nid == NODE_SD_1) {
241 mask = ZYNQMP_SD1_DLL_RST_MASK;
242 val = ZYNQMP_SD1_DLL_RST;
243 } else {
244 return PM_RET_ERROR_ARGS;
245 }
246
247 switch (type) {
248 case PM_DLL_RESET_ASSERT:
249 case PM_DLL_RESET_PULSE:
250 ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, val);
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800251 if (ret != PM_RET_SUCCESS)
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800252 return ret;
253
254 if (type == PM_DLL_RESET_ASSERT)
255 break;
256 mdelay(1);
Daniel Boulby8942a1b2018-06-22 14:16:03 +0100257 /* Fallthrough */
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800258 case PM_DLL_RESET_RELEASE:
259 ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, 0);
260 break;
261 default:
262 ret = PM_RET_ERROR_ARGS;
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800263 break;
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800264 }
265
266 return ret;
267}
268
269/**
270 * pm_ioctl_sd_set_tapdelay() - Set tap delay for the SD device
271 * @nid Node ID of the device
272 * @type Type of tap delay to set (input/output)
273 * @value Value to set fot the tap delay
274 *
275 * This function sets input/output tap delay for the SD device.
276 *
277 * @return Returns status, either success or error+reason
278 */
279static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid,
280 enum tap_delay_type type,
281 unsigned int value)
282{
283 unsigned int shift;
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800284 enum pm_ret_status ret;
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800285
286 if (nid == NODE_SD_0)
287 shift = 0;
288 else if (nid == NODE_SD_1)
289 shift = ZYNQMP_SD_TAP_OFFSET;
290 else
291 return PM_RET_ERROR_ARGS;
292
293 ret = pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_ASSERT);
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800294 if (ret != PM_RET_SUCCESS)
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800295 return ret;
296
297 if (type == PM_TAPDELAY_INPUT) {
298 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800299 (ZYNQMP_SD_ITAPCHGWIN_MASK << shift),
300 (ZYNQMP_SD_ITAPCHGWIN << shift));
301 if (ret != PM_RET_SUCCESS)
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800302 goto reset_release;
303 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800304 (ZYNQMP_SD_ITAPDLYENA_MASK << shift),
305 (ZYNQMP_SD_ITAPDLYENA << shift));
306 if (ret != PM_RET_SUCCESS)
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800307 goto reset_release;
308 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800309 (ZYNQMP_SD_ITAPDLYSEL_MASK << shift),
310 (value << shift));
311 if (ret != PM_RET_SUCCESS)
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800312 goto reset_release;
313 ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800314 (ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0);
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800315 } else if (type == PM_TAPDELAY_OUTPUT) {
316 ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800317 (ZYNQMP_SD_OTAPDLYENA_MASK << shift),
318 (ZYNQMP_SD_OTAPDLYENA << shift));
319 if (ret != PM_RET_SUCCESS)
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800320 goto reset_release;
321 ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800322 (ZYNQMP_SD_OTAPDLYSEL_MASK << shift),
323 (value << shift));
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800324 } else {
325 ret = PM_RET_ERROR_ARGS;
326 }
327
328reset_release:
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800329 pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_RELEASE);
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800330 return ret;
331}
332
333/**
Rajan Vaja35116132018-01-17 02:39:25 -0800334 * pm_ioctl_set_pll_frac_mode() - Ioctl function for
335 * setting pll mode
Jolly Shahcb5bc752019-01-02 12:46:46 -0800336 * @pll PLL clock id
Rajan Vaja35116132018-01-17 02:39:25 -0800337 * @mode Mode fraction/integar
338 *
339 * This function sets PLL mode
340 *
341 * @return Returns status, either success or error+reason
342 */
343static enum pm_ret_status pm_ioctl_set_pll_frac_mode
344 (unsigned int pll, unsigned int mode)
345{
Jolly Shahcb5bc752019-01-02 12:46:46 -0800346 return pm_clock_set_pll_mode(pll, mode);
Rajan Vaja35116132018-01-17 02:39:25 -0800347}
348
349/**
350 * pm_ioctl_get_pll_frac_mode() - Ioctl function for
351 * getting pll mode
Jolly Shah77eb52f2019-01-02 12:49:21 -0800352 * @pll PLL clock id
Rajan Vaja35116132018-01-17 02:39:25 -0800353 * @mode Mode fraction/integar
354 *
355 * This function return current PLL mode
356 *
357 * @return Returns status, either success or error+reason
358 */
359static enum pm_ret_status pm_ioctl_get_pll_frac_mode
360 (unsigned int pll, unsigned int *mode)
361{
Jolly Shah77eb52f2019-01-02 12:49:21 -0800362 return pm_clock_get_pll_mode(pll, mode);
Rajan Vaja35116132018-01-17 02:39:25 -0800363}
364
365/**
366 * pm_ioctl_set_pll_frac_data() - Ioctl function for
367 * setting pll fraction data
Jolly Shah68116ef2019-01-02 12:42:56 -0800368 * @pll PLL clock id
Rajan Vaja35116132018-01-17 02:39:25 -0800369 * @data fraction data
370 *
371 * This function sets fraction data.
372 * It is valid for fraction mode only.
373 *
374 * @return Returns status, either success or error+reason
375 */
376static enum pm_ret_status pm_ioctl_set_pll_frac_data
377 (unsigned int pll, unsigned int data)
378{
Jolly Shah68116ef2019-01-02 12:42:56 -0800379 enum pm_node_id pll_nid;
380 enum pm_ret_status status;
381
382 /* Get PLL node ID using PLL clock ID */
383 status = pm_clock_get_pll_node_id(pll, &pll_nid);
384 if (status != PM_RET_SUCCESS)
385 return status;
386
387 return pm_pll_set_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
Rajan Vaja35116132018-01-17 02:39:25 -0800388}
389
390/**
391 * pm_ioctl_get_pll_frac_data() - Ioctl function for
392 * getting pll fraction data
Jolly Shahb4c99462019-01-02 12:40:17 -0800393 * @pll PLL clock id
Rajan Vaja35116132018-01-17 02:39:25 -0800394 * @data fraction data
395 *
396 * This function returns fraction data value.
397 *
398 * @return Returns status, either success or error+reason
399 */
400static enum pm_ret_status pm_ioctl_get_pll_frac_data
401 (unsigned int pll, unsigned int *data)
402{
Jolly Shahb4c99462019-01-02 12:40:17 -0800403 enum pm_node_id pll_nid;
404 enum pm_ret_status status;
405
406 /* Get PLL node ID using PLL clock ID */
407 status = pm_clock_get_pll_node_id(pll, &pll_nid);
408 if (status != PM_RET_SUCCESS)
409 return status;
410
411 return pm_pll_get_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
Rajan Vaja35116132018-01-17 02:39:25 -0800412}
413
414/**
Rajan Vaja393c0a22018-01-17 02:39:27 -0800415 * pm_ioctl_write_ggs() - Ioctl function for writing
416 * global general storage (ggs)
417 * @index GGS register index
418 * @value Register value to be written
419 *
420 * This function writes value to GGS register.
421 *
422 * @return Returns status, either success or error+reason
423 */
424static enum pm_ret_status pm_ioctl_write_ggs(unsigned int index,
425 unsigned int value)
426{
427 if (index >= GGS_NUM_REGS)
428 return PM_RET_ERROR_ARGS;
429
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800430 return pm_mmio_write(GGS_BASEADDR + (index << 2),
431 0xFFFFFFFFU, value);
Rajan Vaja393c0a22018-01-17 02:39:27 -0800432}
433
434/**
435 * pm_ioctl_read_ggs() - Ioctl function for reading
436 * global general storage (ggs)
437 * @index GGS register index
438 * @value Register value
439 *
440 * This function returns GGS register value.
441 *
442 * @return Returns status, either success or error+reason
443 */
444static enum pm_ret_status pm_ioctl_read_ggs(unsigned int index,
445 unsigned int *value)
446{
447 if (index >= GGS_NUM_REGS)
448 return PM_RET_ERROR_ARGS;
449
450 return pm_mmio_read(GGS_BASEADDR + (index << 2), value);
451}
452
453/**
454 * pm_ioctl_write_pggs() - Ioctl function for writing persistent
455 * global general storage (pggs)
456 * @index PGGS register index
457 * @value Register value to be written
458 *
459 * This function writes value to PGGS register.
460 *
461 * @return Returns status, either success or error+reason
462 */
463static enum pm_ret_status pm_ioctl_write_pggs(unsigned int index,
464 unsigned int value)
465{
466 if (index >= PGGS_NUM_REGS)
467 return PM_RET_ERROR_ARGS;
468
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800469 return pm_mmio_write(PGGS_BASEADDR + (index << 2),
470 0xFFFFFFFFU, value);
Rajan Vaja393c0a22018-01-17 02:39:27 -0800471}
472
473/**
Siva Durga Prasad Paladugua22b8852018-09-04 17:27:12 +0530474 * pm_ioctl_afi() - Ioctl function for writing afi values
475 *
476 * @index AFI register index
477 * @value Register value to be written
478 *
479 *
480 * @return Returns status, either success or error+reason
481 */
482static enum pm_ret_status pm_ioctl_afi(unsigned int index,
483 unsigned int value)
484{
485 unsigned int mask;
486 unsigned int regarr[] = {0xFD360000,
487 0xFD360014,
488 0xFD370000,
489 0xFD370014,
490 0xFD380000,
491 0xFD380014,
492 0xFD390000,
493 0xFD390014,
494 0xFD3a0000,
495 0xFD3a0014,
496 0xFD3b0000,
497 0xFD3b0014,
498 0xFF9b0000,
499 0xFF9b0014,
500 0xFD615000,
501 0xFF419000,
502 };
503
504 if (index >= ARRAY_SIZE(regarr))
505 return PM_RET_ERROR_ARGS;
506
507 if (index < AFIFM6_WRCTRL)
508 mask = FABRIC_WIDTH;
509 else
510 mask = 0xf00;
511
512 return pm_mmio_write(regarr[index], mask, value);
513}
514
515/**
Rajan Vaja393c0a22018-01-17 02:39:27 -0800516 * pm_ioctl_read_pggs() - Ioctl function for reading persistent
517 * global general storage (pggs)
518 * @index PGGS register index
519 * @value Register value
520 *
521 * This function returns PGGS register value.
522 *
523 * @return Returns status, either success or error+reason
524 */
525static enum pm_ret_status pm_ioctl_read_pggs(unsigned int index,
526 unsigned int *value)
527{
528 if (index >= PGGS_NUM_REGS)
529 return PM_RET_ERROR_ARGS;
530
531 return pm_mmio_read(PGGS_BASEADDR + (index << 2), value);
532}
533
534/**
Siva Durga Prasad Paladugued1d5cb2018-09-04 17:03:25 +0530535 * pm_ioctl_ulpi_reset() - Ioctl function for performing ULPI reset
536 *
537 * This function peerforms the ULPI reset sequence for resetting
538 * the ULPI transceiver.
539 *
540 * @return Returns status, either success or error+reason
541 */
542static enum pm_ret_status pm_ioctl_ulpi_reset(void)
543{
544 enum pm_ret_status ret;
545
546 ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
547 ZYNQMP_ULPI_RESET_VAL_HIGH);
548 if (ret != PM_RET_SUCCESS)
549 return ret;
550
551 /* Drive ULPI assert for atleast 1ms */
552 mdelay(1);
553
554 ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
555 ZYNQMP_ULPI_RESET_VAL_LOW);
556 if (ret != PM_RET_SUCCESS)
557 return ret;
558
559 /* Drive ULPI de-assert for atleast 1ms */
560 mdelay(1);
561
562 ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
563 ZYNQMP_ULPI_RESET_VAL_HIGH);
564
565 return ret;
566}
567
568/**
Siva Durga Prasad Paladuguac8526f2018-09-04 17:12:51 +0530569 * pm_ioctl_set_boot_health_status() - Ioctl for setting healthy boot status
570 *
571 * This function sets healthy bit value to indicate boot health status
572 * to firmware.
573 *
574 * @return Returns status, either success or error+reason
575 */
576static enum pm_ret_status pm_ioctl_set_boot_health_status(unsigned int value)
577{
578 return pm_mmio_write(PM_BOOT_HEALTH_STATUS_REG,
579 PM_BOOT_HEALTH_STATUS_MASK, value);
580}
581
582/**
Rajan Vaja5529a012018-01-17 02:39:23 -0800583 * pm_api_ioctl() - PM IOCTL API for device control and configs
584 * @node_id Node ID of the device
585 * @ioctl_id ID of the requested IOCTL
586 * @arg1 Argument 1 to requested IOCTL call
587 * @arg2 Argument 2 to requested IOCTL call
588 * @value Returned output value
589 *
590 * This function calls IOCTL to firmware for device control and configuration.
591 *
592 * @return Returns status, either success or error+reason
593 */
594enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
595 unsigned int ioctl_id,
596 unsigned int arg1,
597 unsigned int arg2,
598 unsigned int *value)
599{
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800600 enum pm_ret_status ret;
Rajan Vaja5529a012018-01-17 02:39:23 -0800601
602 switch (ioctl_id) {
603 case IOCTL_GET_RPU_OPER_MODE:
604 ret = pm_ioctl_get_rpu_oper_mode(value);
605 break;
606 case IOCTL_SET_RPU_OPER_MODE:
607 ret = pm_ioctl_set_rpu_oper_mode(arg1);
608 break;
609 case IOCTL_RPU_BOOT_ADDR_CONFIG:
610 ret = pm_ioctl_config_boot_addr(nid, arg1);
611 break;
612 case IOCTL_TCM_COMB_CONFIG:
613 ret = pm_ioctl_config_tcm_comb(arg1);
614 break;
Rajan Vajaaea41bb2018-01-17 02:39:24 -0800615 case IOCTL_SET_TAPDELAY_BYPASS:
616 ret = pm_ioctl_set_tapdelay_bypass(arg1, arg2);
617 break;
618 case IOCTL_SET_SGMII_MODE:
619 ret = pm_ioctl_set_sgmii_mode(nid, arg1);
620 break;
621 case IOCTL_SD_DLL_RESET:
622 ret = pm_ioctl_sd_dll_reset(nid, arg1);
623 break;
624 case IOCTL_SET_SD_TAPDELAY:
625 ret = pm_ioctl_sd_set_tapdelay(nid, arg1, arg2);
626 break;
Rajan Vaja35116132018-01-17 02:39:25 -0800627 case IOCTL_SET_PLL_FRAC_MODE:
628 ret = pm_ioctl_set_pll_frac_mode(arg1, arg2);
629 break;
630 case IOCTL_GET_PLL_FRAC_MODE:
631 ret = pm_ioctl_get_pll_frac_mode(arg1, value);
632 break;
633 case IOCTL_SET_PLL_FRAC_DATA:
634 ret = pm_ioctl_set_pll_frac_data(arg1, arg2);
635 break;
636 case IOCTL_GET_PLL_FRAC_DATA:
637 ret = pm_ioctl_get_pll_frac_data(arg1, value);
638 break;
Rajan Vaja393c0a22018-01-17 02:39:27 -0800639 case IOCTL_WRITE_GGS:
640 ret = pm_ioctl_write_ggs(arg1, arg2);
641 break;
642 case IOCTL_READ_GGS:
643 ret = pm_ioctl_read_ggs(arg1, value);
644 break;
645 case IOCTL_WRITE_PGGS:
646 ret = pm_ioctl_write_pggs(arg1, arg2);
647 break;
648 case IOCTL_READ_PGGS:
649 ret = pm_ioctl_read_pggs(arg1, value);
650 break;
Siva Durga Prasad Paladugued1d5cb2018-09-04 17:03:25 +0530651 case IOCTL_ULPI_RESET:
652 ret = pm_ioctl_ulpi_reset();
653 break;
Siva Durga Prasad Paladuguac8526f2018-09-04 17:12:51 +0530654 case IOCTL_SET_BOOT_HEALTH_STATUS:
655 ret = pm_ioctl_set_boot_health_status(arg1);
656 break;
Siva Durga Prasad Paladugua22b8852018-09-04 17:27:12 +0530657 case IOCTL_AFI:
658 ret = pm_ioctl_afi(arg1, arg2);
659 break;
Rajan Vaja5529a012018-01-17 02:39:23 -0800660 default:
661 ret = PM_RET_ERROR_NOTSUPPORTED;
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800662 break;
Rajan Vaja5529a012018-01-17 02:39:23 -0800663 }
664
665 return ret;
666}