1 /*
2 * Copyright 2023-2025 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 #include <lib/mmio.h>
7 #include <lib/mmio_poll.h>
8 #include <lib/utils_def.h>
9 #include <s32cc-mc-rgm.h>
10 #include <s32cc-clk-regs.h>
11
12 #define MC_RGM_PRST(RGM, PER) ((RGM) + 0x40UL + ((PER) * 0x8UL))
13 #define MC_RGM_PRST_PERIPH_N_RST(PER) BIT_32(PER)
14 #define MC_RGM_PSTAT(RGM, PER) ((RGM) + 0x140UL + ((PER) * 0x8UL))
15 #define MC_RGM_PSTAT_PERIPH(PER) BIT_32(PER)
16
17 /* ERR051700
18 * Releasing more than one Software Resettable Domain (SRD)
19 * from reset simultaneously, by clearing the corresponding
20 * peripheral MC_RGM_PRSTn[PERIPH_x_RST] reset control may
21 * cause a false setting of the Fault Collection and
22 * Control Unit (FCCU) Non-Critical Fault (NCF) flag
23 * corresponding to a Memory-Test-Repair (MTR) Error
24 */
25 #if (ERRATA_S32_051700 == 1)
mc_rgm_periph_reset(uintptr_t rgm,uint32_t part,uint32_t value)26 void mc_rgm_periph_reset(uintptr_t rgm, uint32_t part, uint32_t value)
27 {
28 uint32_t current_bit_checked, i;
29 uint32_t current_regs, mask;
30 int bit_index;
31
32 current_regs = mmio_read_32(MC_RGM_PRST(rgm, part));
33 /* Create a mask with all changed bits */
34 mask = current_regs ^ value;
35
36 while (mask != 0U) {
37 bit_index = __builtin_ffs(mask);
38 if (bit_index < 1) {
39 break;
40 }
41
42 i = (uint32_t)bit_index - 1U;
43 current_bit_checked = BIT_32(i);
44
45 /* Check if we assert or de-assert.
46 * Also wait for completion.
47 */
48 if ((value & current_bit_checked) != 0U) {
49 mmio_setbits_32(MC_RGM_PRST(rgm, part),
50 current_bit_checked);
51 while ((mmio_read_32(MC_RGM_PRST(rgm, part)) &
52 current_bit_checked) == 0U)
53 ;
54 } else {
55 mmio_clrbits_32(MC_RGM_PRST(rgm, part),
56 current_bit_checked);
57 while ((mmio_read_32(MC_RGM_PRST(rgm, part)) &
58 current_bit_checked) != 0U)
59 ;
60 }
61
62 mask &= ~current_bit_checked;
63 }
64 }
65 #else /* ERRATA_S32_051700 */
mc_rgm_periph_reset(uintptr_t rgm,uint32_t part,uint32_t value)66 void mc_rgm_periph_reset(uintptr_t rgm, uint32_t part, uint32_t value)
67 {
68 mmio_write_32(MC_RGM_PRST(rgm, part), value);
69 }
70 #endif /* ERRATA_S32_051700 */
71
mc_rgm_release_periph(uintptr_t rgm,uint32_t part,uint32_t periph)72 void mc_rgm_release_periph(uintptr_t rgm, uint32_t part, uint32_t periph)
73 {
74 uint32_t reg;
75
76 reg = mmio_read_32(MC_RGM_PRST(rgm, part));
77 reg &= ~MC_RGM_PRST_PERIPH_N_RST(periph);
78 mc_rgm_periph_reset(rgm, part, reg);
79 }
80
mc_rgm_release_part(uintptr_t rgm,uint32_t part)81 void mc_rgm_release_part(uintptr_t rgm, uint32_t part)
82 {
83 mc_rgm_release_periph(rgm, part, 0);
84 }
85
mc_rgm_wait_part_deassert(uintptr_t rgm,uint32_t part)86 void mc_rgm_wait_part_deassert(uintptr_t rgm, uint32_t part)
87 {
88 while ((mmio_read_32(MC_RGM_PSTAT(rgm, part)) &
89 MC_RGM_PSTAT_PERIPH(0)) != 0U) {
90 }
91 }
92
mc_rgm_ddr_reset(uintptr_t rgm,uint32_t timeout)93 int mc_rgm_ddr_reset(uintptr_t rgm, uint32_t timeout)
94 {
95 uint32_t pstat, prst;
96 int err;
97
98 prst = mmio_read_32(MC_RGM_PRST(MC_RGM_BASE_ADDR, 0U));
99 if ((prst & MC_RGM_PRST_PERIPH_N_RST(3)) == 0U) {
100 return -EINVAL;
101 }
102
103 mc_rgm_release_periph(MC_RGM_BASE_ADDR, 0, 3);
104
105 err = mmio_read_32_poll_timeout(MC_RGM_PSTAT(MC_RGM_BASE_ADDR, 0U), pstat,
106 ((pstat & MC_RGM_PSTAT_PERIPH(3)) == 0U),
107 timeout);
108 return err;
109 }
110