Ghennadi Procopciuc | f7dd84a | 2024-09-16 16:22:55 +0300 | [diff] [blame^] | 1 | /* |
| 2 | * Copyright 2024 NXP |
| 3 | * |
| 4 | * SPDX-License-Identifier: BSD-3-Clause |
| 5 | */ |
| 6 | |
| 7 | #include <errno.h> |
| 8 | #include <inttypes.h> |
| 9 | #include <stdbool.h> |
| 10 | |
| 11 | #include <common/debug.h> |
| 12 | #include <lib/mmio.h> |
| 13 | #include <lib/utils_def.h> |
| 14 | #include <s32cc-mc-me.h> |
| 15 | #include <s32cc-mc-rgm.h> |
| 16 | |
| 17 | #define MC_ME_MAX_PARTITIONS (4U) |
| 18 | |
| 19 | #define MC_ME_CTL_KEY(MC_ME) ((MC_ME) + 0x0UL) |
| 20 | #define MC_ME_CTL_KEY_KEY (0x5AF0U) |
| 21 | #define MC_ME_CTL_KEY_INVERTEDKEY (0xA50FU) |
| 22 | |
| 23 | #define MC_ME_PRTN_N(MC_ME, PART) ((MC_ME) + 0x100UL + ((PART) * 0x200UL)) |
| 24 | #define MC_ME_PRTN_N_PCONF(MC_ME, PART) (MC_ME_PRTN_N(MC_ME, PART)) |
| 25 | #define MC_ME_PRTN_N_PCE BIT_32(0) |
| 26 | #define MC_ME_PRTN_N_OSSE BIT_32(2) |
| 27 | #define MC_ME_PRTN_N_PUPD(MC_ME, PART) (MC_ME_PRTN_N(MC_ME, PART) + 0x4UL) |
| 28 | #define MC_ME_PRTN_N_PCUD BIT_32(0) |
| 29 | #define MC_ME_PRTN_N_OSSUD BIT_32(2) |
| 30 | #define MC_ME_PRTN_N_STAT(MC_ME, PART) (MC_ME_PRTN_N(MC_ME, PART) + 0x8UL) |
| 31 | #define MC_ME_PRTN_N_PCS BIT_32(0) |
| 32 | #define MC_ME_PRTN_N_COFB0_STAT(MC_ME, PART) \ |
| 33 | (MC_ME_PRTN_N(MC_ME, PART) + 0x10UL) |
| 34 | #define MC_ME_PRTN_N_COFB0_CLKEN(MC_ME, PART) \ |
| 35 | (MC_ME_PRTN_N(MC_ME, PART) + 0x30UL) |
| 36 | #define MC_ME_PRTN_N_REQ(PART) BIT_32(PART) |
| 37 | |
| 38 | #define RDC_RD_CTRL(RDC, PART) ((RDC) + ((PART) * 0x4UL)) |
| 39 | #define RDC_CTRL_UNLOCK BIT_32(31) |
| 40 | #define RDC_RD_INTERCONNECT_DISABLE BIT_32(3) |
| 41 | |
| 42 | #define RDC_RD_N_STATUS(RDC, PART) ((RDC) + ((PART) * 0x4UL) + 0x80UL) |
| 43 | #define RDC_RD_INTERCONNECT_DISABLE_STAT \ |
| 44 | BIT_32(4) |
| 45 | |
| 46 | static bool is_interconnect_disabled(uintptr_t rdc, uint32_t part) |
| 47 | { |
| 48 | return ((mmio_read_32(RDC_RD_N_STATUS(rdc, part)) & |
| 49 | RDC_RD_INTERCONNECT_DISABLE_STAT) != 0U); |
| 50 | } |
| 51 | |
| 52 | static void enable_interconnect(uintptr_t rdc, uint32_t part) |
| 53 | { |
| 54 | /* Unlock RDC register write */ |
| 55 | mmio_setbits_32(RDC_RD_CTRL(rdc, part), RDC_CTRL_UNLOCK); |
| 56 | |
| 57 | /* Clear corresponding RDC_RD_INTERCONNECT bit */ |
| 58 | mmio_clrbits_32(RDC_RD_CTRL(rdc, part), RDC_RD_INTERCONNECT_DISABLE); |
| 59 | |
| 60 | /* Wait until the interface gets enabled */ |
| 61 | while (is_interconnect_disabled(rdc, part)) { |
| 62 | } |
| 63 | |
| 64 | /* Lock RDC register write */ |
| 65 | mmio_clrbits_32(RDC_RD_CTRL(rdc, part), RDC_CTRL_UNLOCK); |
| 66 | } |
| 67 | |
| 68 | static int mc_me_check_partition_nb_valid(uint32_t part) |
| 69 | { |
| 70 | if (part >= MC_ME_MAX_PARTITIONS) { |
| 71 | ERROR("Invalid partition %" PRIu32 "\n", part); |
| 72 | return -EINVAL; |
| 73 | } |
| 74 | |
| 75 | return 0; |
| 76 | } |
| 77 | |
| 78 | static void part_pconf_write_pce(uintptr_t mc_me, uint32_t pce_bit, |
| 79 | uint32_t part) |
| 80 | { |
| 81 | mmio_clrsetbits_32(MC_ME_PRTN_N_PCONF(mc_me, part), MC_ME_PRTN_N_PCE, |
| 82 | pce_bit & MC_ME_PRTN_N_PCE); |
| 83 | } |
| 84 | |
| 85 | static void mc_me_apply_hw_changes(uintptr_t mc_me) |
| 86 | { |
| 87 | mmio_write_32(MC_ME_CTL_KEY(mc_me), MC_ME_CTL_KEY_KEY); |
| 88 | mmio_write_32(MC_ME_CTL_KEY(mc_me), MC_ME_CTL_KEY_INVERTEDKEY); |
| 89 | } |
| 90 | |
| 91 | static void part_pupd_update_and_wait(uintptr_t mc_me, uint32_t part, |
| 92 | uint32_t mask) |
| 93 | { |
| 94 | uint32_t pconf, stat; |
| 95 | |
| 96 | mmio_setbits_32(MC_ME_PRTN_N_PUPD(mc_me, part), mask); |
| 97 | |
| 98 | mc_me_apply_hw_changes(mc_me); |
| 99 | |
| 100 | /* wait for the updates to apply */ |
| 101 | pconf = mmio_read_32(MC_ME_PRTN_N_PCONF(mc_me, part)); |
| 102 | do { |
| 103 | stat = mmio_read_32(MC_ME_PRTN_N_STAT(mc_me, part)); |
| 104 | } while ((stat & mask) != (pconf & mask)); |
| 105 | } |
| 106 | |
| 107 | static void part_pconf_write_osse(uintptr_t mc_me, uint32_t osse_bit, |
| 108 | uint32_t part) |
| 109 | { |
| 110 | mmio_clrsetbits_32(MC_ME_PRTN_N_PCONF(mc_me, part), MC_ME_PRTN_N_OSSE, |
| 111 | (osse_bit & MC_ME_PRTN_N_OSSE)); |
| 112 | } |
| 113 | |
| 114 | int mc_me_enable_partition(uintptr_t mc_me, uintptr_t mc_rgm, uintptr_t rdc, |
| 115 | uint32_t part) |
| 116 | { |
| 117 | uint32_t part_stat; |
| 118 | int ret; |
| 119 | |
| 120 | /* Partition 0 is already enabled by BootROM */ |
| 121 | if (part == 0U) { |
| 122 | return 0; |
| 123 | } |
| 124 | |
| 125 | ret = mc_me_check_partition_nb_valid(part); |
| 126 | if (ret != 0) { |
| 127 | return ret; |
| 128 | } |
| 129 | |
| 130 | /* Enable a partition only if it's disabled */ |
| 131 | part_stat = mmio_read_32(MC_ME_PRTN_N_STAT(mc_me, part)); |
| 132 | if ((MC_ME_PRTN_N_PCS & part_stat) != 0U) { |
| 133 | return 0; |
| 134 | } |
| 135 | |
| 136 | part_pconf_write_pce(mc_me, MC_ME_PRTN_N_PCE, part); |
| 137 | part_pupd_update_and_wait(mc_me, part, MC_ME_PRTN_N_PCUD); |
| 138 | |
| 139 | enable_interconnect(rdc, part); |
| 140 | |
| 141 | /* Release partition reset */ |
| 142 | mc_rgm_release_part(mc_rgm, part); |
| 143 | |
| 144 | /* Clear OSSE bit */ |
| 145 | part_pconf_write_osse(mc_me, 0, part); |
| 146 | |
| 147 | part_pupd_update_and_wait(mc_me, part, MC_ME_PRTN_N_OSSUD); |
| 148 | |
| 149 | mc_rgm_wait_part_deassert(mc_rgm, part); |
| 150 | |
| 151 | return 0; |
| 152 | } |
| 153 | |
| 154 | void mc_me_enable_part_cofb(uintptr_t mc_me, uint32_t partition_n, uint32_t block, |
| 155 | bool check_status) |
| 156 | { |
| 157 | uint32_t block_mask = MC_ME_PRTN_N_REQ(block); |
| 158 | uintptr_t cofb_stat_addr; |
| 159 | |
| 160 | mmio_setbits_32(MC_ME_PRTN_N_COFB0_CLKEN(mc_me, partition_n), |
| 161 | block_mask); |
| 162 | |
| 163 | mmio_setbits_32(MC_ME_PRTN_N_PCONF(mc_me, partition_n), |
| 164 | MC_ME_PRTN_N_PCE); |
| 165 | |
| 166 | part_pupd_update_and_wait(mc_me, partition_n, MC_ME_PRTN_N_PCUD); |
| 167 | |
| 168 | cofb_stat_addr = MC_ME_PRTN_N_COFB0_STAT(mc_me, partition_n); |
| 169 | if (check_status) { |
| 170 | while ((mmio_read_32(cofb_stat_addr) & block_mask) == 0U) { |
| 171 | } |
| 172 | } |
| 173 | } |