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