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) 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 */ 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 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 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 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 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