1 /*
2  * Copyright 2023-2024 NXP
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/devicetree.h>
8 #include <soc.h>
9 
10 #define FLEXRAM_DT_NODE    DT_INST(0, nxp_flexram)
11 #define IOMUXC_GPR_DT_NODE DT_NODELABEL(iomuxcgpr)
12 
13 #if defined(CONFIG_MEMC_NXP_FLEXRAM_MAGIC_ADDR_API) || \
14 	defined(CONFIG_MEMC_NXP_FLEXRAM_ERROR_INTERRUPT)
15 #define FLEXRAM_INTERRUPTS_USED
16 #endif
17 
18 #if DT_PROP_HAS_IDX(FLEXRAM_DT_NODE, flexram_bank_spec, 0)
19 #define FLEXRAM_RUNTIME_BANKS_USED 1
20 #endif
21 
22 #ifdef FLEXRAM_INTERRUPTS_USED
23 enum memc_flexram_interrupt_cause {
24 #ifdef CONFIG_MEMC_NXP_FLEXRAM_ERROR_INTERRUPT
25 	flexram_ocram_access_error,
26 	flexram_itcm_access_error,
27 	flexram_dtcm_access_error,
28 #endif
29 #ifdef CONFIG_MEMC_NXP_FLEXRAM_MAGIC_ADDR_API
30 	flexram_ocram_magic_addr,
31 	flexram_itcm_magic_addr,
32 	flexram_dtcm_magic_addr,
33 #endif /* CONFIG_MEMC_NXP_FLEXRAM_MAGIC_ADDR_API */
34 };
35 
36 typedef void (*flexram_callback_t)(enum memc_flexram_interrupt_cause, void *user_data);
37 
38 void memc_flexram_register_callback(flexram_callback_t callback, void *user_data);
39 #endif /* FLEXRAM_INTERRUPTS_USED */
40 
41 #ifdef FLEXRAM_RUNTIME_BANKS_USED
42 
43 /*
44  * call from platform_init to set up flexram if using runtime map
45  * must be inlined because cannot use stack
46  */
47 #define GPR_FLEXRAM_REG_FILL(node_id, prop, idx) \
48 	(((uint32_t)DT_PROP_BY_IDX(node_id, prop, idx)) << (2 * idx))
memc_flexram_dt_partition(void)49 static inline void memc_flexram_dt_partition(void)
50 {
51 	/* iomuxc_gpr must be const (in ROM region) because used in reconfiguring ram */
52 	static IOMUXC_GPR_Type *const iomuxc_gpr =
53 		(IOMUXC_GPR_Type *)DT_REG_ADDR(IOMUXC_GPR_DT_NODE);
54 	/* do not create stack variables or use any data from ram in this function */
55 #if defined(CONFIG_SOC_SERIES_IMXRT11XX)
56 	iomuxc_gpr->GPR17 = (DT_FOREACH_PROP_ELEM_SEP(FLEXRAM_DT_NODE, flexram_bank_spec,
57 						GPR_FLEXRAM_REG_FILL, (+))) & 0xFFFF;
58 	iomuxc_gpr->GPR18 = (((DT_FOREACH_PROP_ELEM_SEP(FLEXRAM_DT_NODE, flexram_bank_spec,
59 						GPR_FLEXRAM_REG_FILL, (+)))) >> 16) & 0xFFFF;
60 #elif defined(CONFIG_SOC_SERIES_IMXRT10XX)
61 	iomuxc_gpr->GPR17 = DT_FOREACH_PROP_ELEM_SEP(FLEXRAM_DT_NODE, flexram_bank_spec,
62 						GPR_FLEXRAM_REG_FILL, (+));
63 #endif
64 	iomuxc_gpr->GPR16 |= IOMUXC_GPR_GPR16_FLEXRAM_BANK_CFG_SEL_MASK;
65 }
66 #endif /* FLEXRAM_RUNTIME_BANKS_USED */
67 
68 #ifdef CONFIG_MEMC_NXP_FLEXRAM_MAGIC_ADDR_API
69 /** @brief Sets magic address for OCRAM
70  *
71  * Magic address allows core interrupt from FlexRAM when address
72  * is accessed.
73  *
74  * @param ocram_addr: An address in OCRAM to set magic function on.
75  * @retval 0 on success
76  * @retval -EINVAL if ocram_addr is not in OCRAM
77  * @retval -ENODEV if there is no OCRAM allocation in flexram
78  */
79 int memc_flexram_set_ocram_magic_addr(uint32_t ocram_addr);
80 
81 /** @brief Sets magic address for ITCM
82  *
83  * Magic address allows core interrupt from FlexRAM when address
84  * is accessed.
85  *
86  * @param itcm_addr: An address in ITCM to set magic function on.
87  * @retval 0 on success
88  * @retval -EINVAL if itcm_addr is not in ITCM
89  * @retval -ENODEV if there is no ITCM allocation in flexram
90  */
91 int memc_flexram_set_itcm_magic_addr(uint32_t itcm_addr);
92 
93 /** @brief Sets magic address for DTCM
94  *
95  * Magic address allows core interrupt from FlexRAM when address
96  * is accessed.
97  *
98  * @param dtcm_addr: An address in DTCM to set magic function on.
99  * @retval 0 on success
100  * @retval -EINVAL if dtcm_addr is not in DTCM
101  * @retval -ENODEV if there is no DTCM allocation in flexram
102  */
103 int memc_flexram_set_dtcm_magic_addr(uint32_t dtcm_addr);
104 
105 #endif /* CONFIG_MEMC_NXP_FLEXRAM_MAGIC_ADDR_API */
106