xref: /rk3399_ARM-atf/drivers/nxp/clk/s32cc/mc_rgm.c (revision f2ab12441fdcc8d98ee7da3f406d0f1045ca1b59)
1b47d085aSGhennadi Procopciuc /*
2*f2ab1244SKhristine Andreea Barbulescu  * Copyright 2023-2025 NXP
3b47d085aSGhennadi Procopciuc  *
4b47d085aSGhennadi Procopciuc  * SPDX-License-Identifier: BSD-3-Clause
5b47d085aSGhennadi Procopciuc  */
6b47d085aSGhennadi Procopciuc #include <lib/mmio.h>
7b47d085aSGhennadi Procopciuc #include <lib/utils_def.h>
8b47d085aSGhennadi Procopciuc #include <s32cc-mc-rgm.h>
9b47d085aSGhennadi Procopciuc 
1011a7c540SGhennadi Procopciuc #define MC_RGM_PRST(RGM, PER)		((RGM) + 0x40UL + ((PER) * 0x8UL))
1111a7c540SGhennadi Procopciuc #define MC_RGM_PRST_PERIPH_N_RST(PER)	BIT_32(PER)
1211a7c540SGhennadi Procopciuc #define MC_RGM_PSTAT(RGM, PER)		((RGM) + 0x140UL + ((PER) * 0x8UL))
1311a7c540SGhennadi Procopciuc #define MC_RGM_PSTAT_PERIPH(PER)	BIT_32(PER)
14b47d085aSGhennadi Procopciuc 
15b47d085aSGhennadi Procopciuc /*  ERR051700
16b47d085aSGhennadi Procopciuc  *  Releasing more than one Software Resettable Domain (SRD)
17b47d085aSGhennadi Procopciuc  *  from reset simultaneously, by clearing the corresponding
18b47d085aSGhennadi Procopciuc  *  peripheral MC_RGM_PRSTn[PERIPH_x_RST] reset control may
19b47d085aSGhennadi Procopciuc  *  cause a false setting of the Fault Collection and
20b47d085aSGhennadi Procopciuc  *  Control Unit (FCCU) Non-Critical Fault (NCF) flag
21b47d085aSGhennadi Procopciuc  *  corresponding to a Memory-Test-Repair (MTR) Error
22b47d085aSGhennadi Procopciuc  */
23b47d085aSGhennadi Procopciuc #if (ERRATA_S32_051700 == 1)
24b47d085aSGhennadi Procopciuc void mc_rgm_periph_reset(uintptr_t rgm, uint32_t part, uint32_t value)
25b47d085aSGhennadi Procopciuc {
26b47d085aSGhennadi Procopciuc 	uint32_t current_bit_checked, i;
27b47d085aSGhennadi Procopciuc 	uint32_t current_regs, mask;
28b47d085aSGhennadi Procopciuc 	int bit_index;
29b47d085aSGhennadi Procopciuc 
30b47d085aSGhennadi Procopciuc 	current_regs = mmio_read_32(MC_RGM_PRST(rgm, part));
31b47d085aSGhennadi Procopciuc 	/* Create a mask with all changed bits */
32b47d085aSGhennadi Procopciuc 	mask = current_regs ^ value;
33b47d085aSGhennadi Procopciuc 
34b47d085aSGhennadi Procopciuc 	while (mask != 0U) {
35b47d085aSGhennadi Procopciuc 		bit_index = __builtin_ffs(mask);
36b47d085aSGhennadi Procopciuc 		if (bit_index < 1) {
37b47d085aSGhennadi Procopciuc 			break;
38b47d085aSGhennadi Procopciuc 		}
39b47d085aSGhennadi Procopciuc 
40b47d085aSGhennadi Procopciuc 		i = (uint32_t)bit_index - 1U;
41b47d085aSGhennadi Procopciuc 		current_bit_checked = BIT_32(i);
42b47d085aSGhennadi Procopciuc 
43b47d085aSGhennadi Procopciuc 		/* Check if we assert or de-assert.
44b47d085aSGhennadi Procopciuc 		 * Also wait for completion.
45b47d085aSGhennadi Procopciuc 		 */
46b47d085aSGhennadi Procopciuc 		if ((value & current_bit_checked) != 0U) {
47b47d085aSGhennadi Procopciuc 			mmio_setbits_32(MC_RGM_PRST(rgm, part),
48b47d085aSGhennadi Procopciuc 					current_bit_checked);
49b47d085aSGhennadi Procopciuc 			while ((mmio_read_32(MC_RGM_PRST(rgm, part)) &
50b47d085aSGhennadi Procopciuc 				 current_bit_checked) == 0U)
51b47d085aSGhennadi Procopciuc 				;
52b47d085aSGhennadi Procopciuc 		} else {
53b47d085aSGhennadi Procopciuc 			mmio_clrbits_32(MC_RGM_PRST(rgm, part),
54b47d085aSGhennadi Procopciuc 					current_bit_checked);
55b47d085aSGhennadi Procopciuc 			while ((mmio_read_32(MC_RGM_PRST(rgm, part)) &
56b47d085aSGhennadi Procopciuc 					    current_bit_checked) != 0U)
57b47d085aSGhennadi Procopciuc 				;
58b47d085aSGhennadi Procopciuc 		}
59b47d085aSGhennadi Procopciuc 
60b47d085aSGhennadi Procopciuc 		mask &= ~current_bit_checked;
61b47d085aSGhennadi Procopciuc 	}
62b47d085aSGhennadi Procopciuc }
63b47d085aSGhennadi Procopciuc #else /* ERRATA_S32_051700 */
64b47d085aSGhennadi Procopciuc void mc_rgm_periph_reset(uintptr_t rgm, uint32_t part, uint32_t value)
65b47d085aSGhennadi Procopciuc {
66b47d085aSGhennadi Procopciuc 	mmio_write_32(MC_RGM_PRST(rgm, part), value);
67b47d085aSGhennadi Procopciuc }
68b47d085aSGhennadi Procopciuc #endif /* ERRATA_S32_051700 */
6911a7c540SGhennadi Procopciuc 
70*f2ab1244SKhristine Andreea Barbulescu void mc_rgm_release_periph(uintptr_t rgm, uint32_t part, uint32_t periph)
7111a7c540SGhennadi Procopciuc {
7211a7c540SGhennadi Procopciuc 	uint32_t reg;
7311a7c540SGhennadi Procopciuc 
7411a7c540SGhennadi Procopciuc 	reg = mmio_read_32(MC_RGM_PRST(rgm, part));
75*f2ab1244SKhristine Andreea Barbulescu 	reg &= ~MC_RGM_PRST_PERIPH_N_RST(periph);
7611a7c540SGhennadi Procopciuc 	mc_rgm_periph_reset(rgm, part, reg);
7711a7c540SGhennadi Procopciuc }
7811a7c540SGhennadi Procopciuc 
79*f2ab1244SKhristine Andreea Barbulescu void mc_rgm_release_part(uintptr_t rgm, uint32_t part)
80*f2ab1244SKhristine Andreea Barbulescu {
81*f2ab1244SKhristine Andreea Barbulescu 	mc_rgm_release_periph(rgm, part, 0);
82*f2ab1244SKhristine Andreea Barbulescu }
83*f2ab1244SKhristine Andreea Barbulescu 
8411a7c540SGhennadi Procopciuc void mc_rgm_wait_part_deassert(uintptr_t rgm, uint32_t part)
8511a7c540SGhennadi Procopciuc {
8611a7c540SGhennadi Procopciuc 	while ((mmio_read_32(MC_RGM_PSTAT(rgm, part)) &
8711a7c540SGhennadi Procopciuc 		MC_RGM_PSTAT_PERIPH(0)) != 0U) {
8811a7c540SGhennadi Procopciuc 	}
8911a7c540SGhennadi Procopciuc }
90