2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
4 * SPDX-License-Identifier: BSD-3-Clause
8 * ZynqMP system level PM-API functions for ioctl.
11 #include <arch_helpers.h>
12 #include <delay_timer.h>
15 #include "pm_api_clock.h"
16 #include "pm_api_ioctl.h"
17 #include "pm_api_sys.h"
18 #include "pm_client.h"
19 #include "pm_common.h"
21 #include "../zynqmp_def.h"
24 * pm_ioctl_get_rpu_oper_mode () - Get current RPU operation mode
25 * @mode Buffer to store value of oper mode(Split/Lock-step)
27 * This function provides current configured RPU operational mode.
29 * @return Returns status, either success or error+reason
31 static enum pm_ret_status
pm_ioctl_get_rpu_oper_mode(unsigned int *mode
)
35 val
= mmio_read_32(ZYNQMP_RPU_GLBL_CNTL
);
36 val
&= ZYNQMP_SLSPLIT_MASK
;
38 *mode
= PM_RPU_MODE_LOCKSTEP
;
40 *mode
= PM_RPU_MODE_SPLIT
;
42 return PM_RET_SUCCESS
;
46 * pm_ioctl_set_rpu_oper_mode () - Configure RPU operation mode
47 * @mode Value to set for oper mode(Split/Lock-step)
49 * This function configures RPU operational mode(Split/Lock-step).
50 * It also sets TCM combined mode in RPU lock-step and TCM non-combined
51 * mode for RPU split mode. In case of Lock step mode, RPU1's output is
54 * @return Returns status, either success or error+reason
56 static enum pm_ret_status
pm_ioctl_set_rpu_oper_mode(unsigned int mode
)
60 if (mmio_read_32(CRL_APB_RST_LPD_TOP
) && CRL_APB_RPU_AMBA_RESET
)
61 return PM_RET_ERROR_ACCESS
;
63 val
= mmio_read_32(ZYNQMP_RPU_GLBL_CNTL
);
65 if (mode
== PM_RPU_MODE_SPLIT
) {
66 val
|= ZYNQMP_SLSPLIT_MASK
;
67 val
&= ~ZYNQMP_TCM_COMB_MASK
;
68 val
&= ~ZYNQMP_SLCLAMP_MASK
;
69 } else if (mode
== PM_RPU_MODE_LOCKSTEP
) {
70 val
&= ~ZYNQMP_SLSPLIT_MASK
;
71 val
|= ZYNQMP_TCM_COMB_MASK
;
72 val
|= ZYNQMP_SLCLAMP_MASK
;
74 return PM_RET_ERROR_ARGS
;
77 mmio_write_32(ZYNQMP_RPU_GLBL_CNTL
, val
);
79 return PM_RET_SUCCESS
;
83 * pm_ioctl_config_boot_addr() - Configure RPU boot address
85 * @value Value to set for boot address (TCM/OCM)
87 * This function configures RPU boot address(memory).
89 * @return Returns status, either success or error+reason
91 static enum pm_ret_status
pm_ioctl_config_boot_addr(enum pm_node_id nid
,
94 unsigned int rpu_cfg_addr
, val
;
96 if (nid
== NODE_RPU_0
)
97 rpu_cfg_addr
= ZYNQMP_RPU0_CFG
;
98 else if (nid
== NODE_RPU_1
)
99 rpu_cfg_addr
= ZYNQMP_RPU1_CFG
;
101 return PM_RET_ERROR_ARGS
;
103 val
= mmio_read_32(rpu_cfg_addr
);
105 if (value
== PM_RPU_BOOTMEM_LOVEC
)
106 val
&= ~ZYNQMP_VINITHI_MASK
;
107 else if (value
== PM_RPU_BOOTMEM_HIVEC
)
108 val
|= ZYNQMP_VINITHI_MASK
;
110 return PM_RET_ERROR_ARGS
;
112 mmio_write_32(rpu_cfg_addr
, val
);
114 return PM_RET_SUCCESS
;
118 * pm_ioctl_config_tcm_comb() - Configure TCM combined mode
119 * @value Value to set (Split/Combined)
121 * This function configures TCM to be in split mode or combined
124 * @return Returns status, either success or error+reason
126 static enum pm_ret_status
pm_ioctl_config_tcm_comb(unsigned int value
)
130 val
= mmio_read_32(ZYNQMP_RPU_GLBL_CNTL
);
132 if (value
== PM_RPU_TCM_SPLIT
)
133 val
&= ~ZYNQMP_TCM_COMB_MASK
;
134 else if (value
== PM_RPU_TCM_COMB
)
135 val
|= ZYNQMP_TCM_COMB_MASK
;
137 return PM_RET_ERROR_ARGS
;
139 mmio_write_32(ZYNQMP_RPU_GLBL_CNTL
, val
);
141 return PM_RET_SUCCESS
;
145 * pm_ioctl_set_tapdelay_bypass() - Enable/Disable tap delay bypass
146 * @type Type of tap delay to enable/disable (e.g. QSPI)
147 * @value Enable/Disable
149 * This function enable/disable tap delay bypass.
151 * @return Returns status, either success or error+reason
153 static enum pm_ret_status
pm_ioctl_set_tapdelay_bypass(unsigned int type
,
156 if ((value
!= PM_TAPDELAY_BYPASS_ENABLE
&&
157 value
!= PM_TAPDELAY_BYPASS_DISABLE
) || type
>= PM_TAPDELAY_MAX
)
158 return PM_RET_ERROR_ARGS
;
160 return pm_mmio_write(IOU_TAPDLY_BYPASS
, TAP_DELAY_MASK
, value
<< type
);
164 * pm_ioctl_set_sgmii_mode() - Set SGMII mode for the GEM device
165 * @nid Node ID of the device
166 * @value Enable/Disable
168 * This function enable/disable SGMII mode for the GEM device.
169 * While enabling SGMII mode, it also ties the GEM PCS Signal
170 * Detect to 1 and selects EMIO for RX clock generation.
172 * @return Returns status, either success or error+reason
174 static enum pm_ret_status
pm_ioctl_set_sgmii_mode(enum pm_node_id nid
,
177 unsigned int val
, mask
, shift
;
178 enum pm_ret_status ret
;
180 if (value
!= PM_SGMII_DISABLE
&& value
!= PM_SGMII_ENABLE
)
181 return PM_RET_ERROR_ARGS
;
197 return PM_RET_ERROR_ARGS
;
200 if (value
== PM_SGMII_DISABLE
) {
201 mask
= GEM_SGMII_MASK
<< GEM_CLK_CTRL_OFFSET
* shift
;
202 ret
= pm_mmio_write(IOU_GEM_CLK_CTRL
, mask
, 0U);
204 /* Tie the GEM PCS Signal Detect to 1 */
205 mask
= SGMII_SD_MASK
<< SGMII_SD_OFFSET
* shift
;
206 val
= SGMII_PCS_SD_1
<< SGMII_SD_OFFSET
* shift
;
207 ret
= pm_mmio_write(IOU_GEM_CTRL
, mask
, val
);
208 if (ret
!= PM_RET_SUCCESS
)
211 /* Set the GEM to SGMII mode */
212 mask
= GEM_CLK_CTRL_MASK
<< GEM_CLK_CTRL_OFFSET
* shift
;
213 val
= GEM_RX_SRC_SEL_GTR
| GEM_SGMII_MODE
;
214 val
<<= GEM_CLK_CTRL_OFFSET
* shift
;
215 ret
= pm_mmio_write(IOU_GEM_CLK_CTRL
, mask
, val
);
222 * pm_ioctl_sd_dll_reset() - Reset DLL logic
223 * @nid Node ID of the device
226 * This function resets DLL logic for the SD device.
228 * @return Returns status, either success or error+reason
230 static enum pm_ret_status
pm_ioctl_sd_dll_reset(enum pm_node_id nid
,
233 unsigned int mask
, val
;
234 enum pm_ret_status ret
;
236 if (nid
== NODE_SD_0
) {
237 mask
= ZYNQMP_SD0_DLL_RST_MASK
;
238 val
= ZYNQMP_SD0_DLL_RST
;
239 } else if (nid
== NODE_SD_1
) {
240 mask
= ZYNQMP_SD1_DLL_RST_MASK
;
241 val
= ZYNQMP_SD1_DLL_RST
;
243 return PM_RET_ERROR_ARGS
;
247 case PM_DLL_RESET_ASSERT
:
248 case PM_DLL_RESET_PULSE
:
249 ret
= pm_mmio_write(ZYNQMP_SD_DLL_CTRL
, mask
, val
);
250 if (ret
!= PM_RET_SUCCESS
)
253 if (type
== PM_DLL_RESET_ASSERT
)
257 case PM_DLL_RESET_RELEASE
:
258 ret
= pm_mmio_write(ZYNQMP_SD_DLL_CTRL
, mask
, 0);
261 ret
= PM_RET_ERROR_ARGS
;
269 * pm_ioctl_sd_set_tapdelay() - Set tap delay for the SD device
270 * @nid Node ID of the device
271 * @type Type of tap delay to set (input/output)
272 * @value Value to set fot the tap delay
274 * This function sets input/output tap delay for the SD device.
276 * @return Returns status, either success or error+reason
278 static enum pm_ret_status
pm_ioctl_sd_set_tapdelay(enum pm_node_id nid
,
279 enum tap_delay_type type
,
283 enum pm_ret_status ret
;
285 if (nid
== NODE_SD_0
)
287 else if (nid
== NODE_SD_1
)
288 shift
= ZYNQMP_SD_TAP_OFFSET
;
290 return PM_RET_ERROR_ARGS
;
292 ret
= pm_ioctl_sd_dll_reset(nid
, PM_DLL_RESET_ASSERT
);
293 if (ret
!= PM_RET_SUCCESS
)
296 if (type
== PM_TAPDELAY_INPUT
) {
297 ret
= pm_mmio_write(ZYNQMP_SD_ITAP_DLY
,
298 (ZYNQMP_SD_ITAPCHGWIN_MASK
<< shift
),
299 (ZYNQMP_SD_ITAPCHGWIN
<< shift
));
300 if (ret
!= PM_RET_SUCCESS
)
302 ret
= pm_mmio_write(ZYNQMP_SD_ITAP_DLY
,
303 (ZYNQMP_SD_ITAPDLYENA_MASK
<< shift
),
304 (ZYNQMP_SD_ITAPDLYENA
<< shift
));
305 if (ret
!= PM_RET_SUCCESS
)
307 ret
= pm_mmio_write(ZYNQMP_SD_ITAP_DLY
,
308 (ZYNQMP_SD_ITAPDLYSEL_MASK
<< shift
),
310 if (ret
!= PM_RET_SUCCESS
)
312 ret
= pm_mmio_write(ZYNQMP_SD_ITAP_DLY
,
313 (ZYNQMP_SD_ITAPCHGWIN_MASK
<< shift
), 0);
314 } else if (type
== PM_TAPDELAY_OUTPUT
) {
315 ret
= pm_mmio_write(ZYNQMP_SD_OTAP_DLY
,
316 (ZYNQMP_SD_OTAPDLYENA_MASK
<< shift
),
317 (ZYNQMP_SD_OTAPDLYENA
<< shift
));
318 if (ret
!= PM_RET_SUCCESS
)
320 ret
= pm_mmio_write(ZYNQMP_SD_OTAP_DLY
,
321 (ZYNQMP_SD_OTAPDLYSEL_MASK
<< shift
),
324 ret
= PM_RET_ERROR_ARGS
;
328 pm_ioctl_sd_dll_reset(nid
, PM_DLL_RESET_RELEASE
);
333 * pm_ioctl_set_pll_frac_mode() - Ioctl function for
336 * @mode Mode fraction/integar
338 * This function sets PLL mode
340 * @return Returns status, either success or error+reason
342 static enum pm_ret_status pm_ioctl_set_pll_frac_mode
343 (unsigned int pll
, unsigned int mode
)
345 return pm_api_clk_set_pll_mode(pll
, mode
);
349 * pm_ioctl_get_pll_frac_mode() - Ioctl function for
352 * @mode Mode fraction/integar
354 * This function return current PLL mode
356 * @return Returns status, either success or error+reason
358 static enum pm_ret_status pm_ioctl_get_pll_frac_mode
359 (unsigned int pll
, unsigned int *mode
)
361 return pm_api_clk_get_pll_mode(pll
, mode
);
365 * pm_ioctl_set_pll_frac_data() - Ioctl function for
366 * setting pll fraction data
368 * @data fraction data
370 * This function sets fraction data.
371 * It is valid for fraction mode only.
373 * @return Returns status, either success or error+reason
375 static enum pm_ret_status pm_ioctl_set_pll_frac_data
376 (unsigned int pll
, unsigned int data
)
378 return pm_api_clk_set_pll_frac_data(pll
, data
);
382 * pm_ioctl_get_pll_frac_data() - Ioctl function for
383 * getting pll fraction data
385 * @data fraction data
387 * This function returns fraction data value.
389 * @return Returns status, either success or error+reason
391 static enum pm_ret_status pm_ioctl_get_pll_frac_data
392 (unsigned int pll
, unsigned int *data
)
394 return pm_api_clk_get_pll_frac_data(pll
, data
);
398 * pm_ioctl_write_ggs() - Ioctl function for writing
399 * global general storage (ggs)
400 * @index GGS register index
401 * @value Register value to be written
403 * This function writes value to GGS register.
405 * @return Returns status, either success or error+reason
407 static enum pm_ret_status
pm_ioctl_write_ggs(unsigned int index
,
410 if (index
>= GGS_NUM_REGS
)
411 return PM_RET_ERROR_ARGS
;
413 return pm_mmio_write(GGS_BASEADDR
+ (index
<< 2),
418 * pm_ioctl_read_ggs() - Ioctl function for reading
419 * global general storage (ggs)
420 * @index GGS register index
421 * @value Register value
423 * This function returns GGS register value.
425 * @return Returns status, either success or error+reason
427 static enum pm_ret_status
pm_ioctl_read_ggs(unsigned int index
,
430 if (index
>= GGS_NUM_REGS
)
431 return PM_RET_ERROR_ARGS
;
433 return pm_mmio_read(GGS_BASEADDR
+ (index
<< 2), value
);
437 * pm_ioctl_write_pggs() - Ioctl function for writing persistent
438 * global general storage (pggs)
439 * @index PGGS register index
440 * @value Register value to be written
442 * This function writes value to PGGS register.
444 * @return Returns status, either success or error+reason
446 static enum pm_ret_status
pm_ioctl_write_pggs(unsigned int index
,
449 if (index
>= PGGS_NUM_REGS
)
450 return PM_RET_ERROR_ARGS
;
452 return pm_mmio_write(PGGS_BASEADDR
+ (index
<< 2),
457 * pm_ioctl_afi() - Ioctl function for writing afi values
459 * @index AFI register index
460 * @value Register value to be written
463 * @return Returns status, either success or error+reason
465 static enum pm_ret_status
pm_ioctl_afi(unsigned int index
,
469 unsigned int regarr
[] = {0xFD360000,
487 if (index
>= ARRAY_SIZE(regarr
))
488 return PM_RET_ERROR_ARGS
;
490 if (index
< AFIFM6_WRCTRL
)
495 return pm_mmio_write(regarr
[index
], mask
, value
);
499 * pm_ioctl_read_pggs() - Ioctl function for reading persistent
500 * global general storage (pggs)
501 * @index PGGS register index
502 * @value Register value
504 * This function returns PGGS register value.
506 * @return Returns status, either success or error+reason
508 static enum pm_ret_status
pm_ioctl_read_pggs(unsigned int index
,
511 if (index
>= PGGS_NUM_REGS
)
512 return PM_RET_ERROR_ARGS
;
514 return pm_mmio_read(PGGS_BASEADDR
+ (index
<< 2), value
);
518 * pm_ioctl_ulpi_reset() - Ioctl function for performing ULPI reset
520 * This function peerforms the ULPI reset sequence for resetting
521 * the ULPI transceiver.
523 * @return Returns status, either success or error+reason
525 static enum pm_ret_status
pm_ioctl_ulpi_reset(void)
527 enum pm_ret_status ret
;
529 ret
= pm_mmio_write(CRL_APB_BOOT_PIN_CTRL
, CRL_APB_BOOT_PIN_MASK
,
530 ZYNQMP_ULPI_RESET_VAL_HIGH
);
531 if (ret
!= PM_RET_SUCCESS
)
534 /* Drive ULPI assert for atleast 1ms */
537 ret
= pm_mmio_write(CRL_APB_BOOT_PIN_CTRL
, CRL_APB_BOOT_PIN_MASK
,
538 ZYNQMP_ULPI_RESET_VAL_LOW
);
539 if (ret
!= PM_RET_SUCCESS
)
542 /* Drive ULPI de-assert for atleast 1ms */
545 ret
= pm_mmio_write(CRL_APB_BOOT_PIN_CTRL
, CRL_APB_BOOT_PIN_MASK
,
546 ZYNQMP_ULPI_RESET_VAL_HIGH
);
552 * pm_ioctl_set_boot_health_status() - Ioctl for setting healthy boot status
554 * This function sets healthy bit value to indicate boot health status
557 * @return Returns status, either success or error+reason
559 static enum pm_ret_status
pm_ioctl_set_boot_health_status(unsigned int value
)
561 return pm_mmio_write(PM_BOOT_HEALTH_STATUS_REG
,
562 PM_BOOT_HEALTH_STATUS_MASK
, value
);
566 * pm_api_ioctl() - PM IOCTL API for device control and configs
567 * @node_id Node ID of the device
568 * @ioctl_id ID of the requested IOCTL
569 * @arg1 Argument 1 to requested IOCTL call
570 * @arg2 Argument 2 to requested IOCTL call
571 * @value Returned output value
573 * This function calls IOCTL to firmware for device control and configuration.
575 * @return Returns status, either success or error+reason
577 enum pm_ret_status
pm_api_ioctl(enum pm_node_id nid
,
578 unsigned int ioctl_id
,
583 enum pm_ret_status ret
;
586 case IOCTL_GET_RPU_OPER_MODE
:
587 ret
= pm_ioctl_get_rpu_oper_mode(value
);
589 case IOCTL_SET_RPU_OPER_MODE
:
590 ret
= pm_ioctl_set_rpu_oper_mode(arg1
);
592 case IOCTL_RPU_BOOT_ADDR_CONFIG
:
593 ret
= pm_ioctl_config_boot_addr(nid
, arg1
);
595 case IOCTL_TCM_COMB_CONFIG
:
596 ret
= pm_ioctl_config_tcm_comb(arg1
);
598 case IOCTL_SET_TAPDELAY_BYPASS
:
599 ret
= pm_ioctl_set_tapdelay_bypass(arg1
, arg2
);
601 case IOCTL_SET_SGMII_MODE
:
602 ret
= pm_ioctl_set_sgmii_mode(nid
, arg1
);
604 case IOCTL_SD_DLL_RESET
:
605 ret
= pm_ioctl_sd_dll_reset(nid
, arg1
);
607 case IOCTL_SET_SD_TAPDELAY
:
608 ret
= pm_ioctl_sd_set_tapdelay(nid
, arg1
, arg2
);
610 case IOCTL_SET_PLL_FRAC_MODE
:
611 ret
= pm_ioctl_set_pll_frac_mode(arg1
, arg2
);
613 case IOCTL_GET_PLL_FRAC_MODE
:
614 ret
= pm_ioctl_get_pll_frac_mode(arg1
, value
);
616 case IOCTL_SET_PLL_FRAC_DATA
:
617 ret
= pm_ioctl_set_pll_frac_data(arg1
, arg2
);
619 case IOCTL_GET_PLL_FRAC_DATA
:
620 ret
= pm_ioctl_get_pll_frac_data(arg1
, value
);
622 case IOCTL_WRITE_GGS
:
623 ret
= pm_ioctl_write_ggs(arg1
, arg2
);
626 ret
= pm_ioctl_read_ggs(arg1
, value
);
628 case IOCTL_WRITE_PGGS
:
629 ret
= pm_ioctl_write_pggs(arg1
, arg2
);
631 case IOCTL_READ_PGGS
:
632 ret
= pm_ioctl_read_pggs(arg1
, value
);
634 case IOCTL_ULPI_RESET
:
635 ret
= pm_ioctl_ulpi_reset();
637 case IOCTL_SET_BOOT_HEALTH_STATUS
:
638 ret
= pm_ioctl_set_boot_health_status(arg1
);
641 ret
= pm_ioctl_afi(arg1
, arg2
);
644 ret
= PM_RET_ERROR_NOTSUPPORTED
;