summaryrefslogtreecommitdiffstats
path: root/bsps/arm/imxrt/mcux-sdk/drivers/rdc_sema42/fsl_rdc_sema42.c
blob: 00189e49a86fd2a6b355c4cfba4c819c53df7c65 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
/*
 * Copyright 2017-2020, 2022 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "fsl_rdc_sema42.h"

/******************************************************************************
 * Definitions
 *****************************************************************************/

/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.rdc_sema42"
#endif

/* The first number write to RSTGDP when reset RDC_SEMA42 gate. */
#define RDC_SEMA42_GATE_RESET_PATTERN_1 (0xE2U)
/* The second number write to RSTGDP when reset RDC_SEMA42 gate. */
#define RDC_SEMA42_GATE_RESET_PATTERN_2 (0x1DU)

#if !defined(RDC_SEMAPHORE_GATE_COUNT)
/* Compatible remap. */
#define RDC_SEMAPHORE_GATE_LDOM(x)    RDC_SEMAPHORE_GATE0_LDOM(x)
#define RDC_SEMAPHORE_GATE_GTFSM(x)   RDC_SEMAPHORE_GATE0_GTFSM(x)
#define RDC_SEMAPHORE_GATE_LDOM_MASK  RDC_SEMAPHORE_GATE0_LDOM_MASK
#define RDC_SEMAPHORE_GATE_LDOM_SHIFT RDC_SEMAPHORE_GATE0_LDOM_SHIFT
#endif

/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/*!
 * @brief Get instance number for RDC_SEMA42 module.
 *
 * @param base RDC_SEMA42 peripheral base address.
 */
uint32_t RDC_SEMA42_GetInstance(RDC_SEMAPHORE_Type *base);

/*******************************************************************************
 * Variables
 ******************************************************************************/

/*! @brief Pointers to sema42 bases for each instance. */
static RDC_SEMAPHORE_Type *const s_sema42Bases[] = RDC_SEMAPHORE_BASE_PTRS;

#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
#if defined(RDC_SEMA42_CLOCKS)
/*! @brief Pointers to sema42 clocks for each instance. */
static const clock_ip_name_t s_sema42Clocks[] = RDC_SEMA42_CLOCKS;
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */

/******************************************************************************
 * CODE
 *****************************************************************************/

uint32_t RDC_SEMA42_GetInstance(RDC_SEMAPHORE_Type *base)
{
    uint32_t instance;

    /* Find the instance index from base address mappings. */
    for (instance = 0; instance < ARRAY_SIZE(s_sema42Bases); instance++)
    {
        if (s_sema42Bases[instance] == base)
        {
            break;
        }
    }

    assert(instance < ARRAY_SIZE(s_sema42Bases));

    return instance;
}

/*!
 * brief Initializes the RDC_SEMA42 module.
 *
 * This function initializes the RDC_SEMA42 module. It only enables the clock but does
 * not reset the gates because the module might be used by other processors
 * at the same time. To reset the gates, call either RDC_SEMA42_ResetGate or
 * RDC_SEMA42_ResetAllGates function.
 *
 * param base RDC_SEMA42 peripheral base address.
 */
void RDC_SEMA42_Init(RDC_SEMAPHORE_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
#if defined(RDC_SEMA42_CLOCKS)
    CLOCK_EnableClock(s_sema42Clocks[RDC_SEMA42_GetInstance(base)]);
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}

/*!
 * brief De-initializes the RDC_SEMA42 module.
 *
 * This function de-initializes the RDC_SEMA42 module. It only disables the clock.
 *
 * param base RDC_SEMA42 peripheral base address.
 */
void RDC_SEMA42_Deinit(RDC_SEMAPHORE_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
#if defined(RDC_SEMA42_CLOCKS)
    CLOCK_DisableClock(s_sema42Clocks[RDC_SEMA42_GetInstance(base)]);
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}

/*!
 * brief Tries to lock the RDC_SEMA42 gate.
 *
 * This function tries to lock the specific RDC_SEMA42 gate. If the gate has been
 * locked by another processor, this function returns an error code.
 *
 * param base RDC_SEMA42 peripheral base address.
 * param gateNum  Gate number to lock.
 * param masterIndex  Current processor master index.
 * param domainId  Current processor domain ID.
 *
 * retval kStatus_Success   Lock the sema42 gate successfully.
 * retval kStatus_Failed    Sema42 gate has been locked by another processor.
 */
status_t RDC_SEMA42_TryLock(RDC_SEMAPHORE_Type *base, uint8_t gateNum, uint8_t masterIndex, uint8_t domainId)
{
    assert(gateNum < RDC_SEMA42_GATE_COUNT);

    status_t status = kStatus_Success;
    uint8_t regGate;

    ++masterIndex;

    regGate = (uint8_t)(RDC_SEMAPHORE_GATE_LDOM(domainId) | RDC_SEMAPHORE_GATE_GTFSM(masterIndex));

    /* Try to lock. */
    RDC_SEMA42_GATEn(base, gateNum) = masterIndex;

    /* Check locked or not. */
    if (regGate != RDC_SEMA42_GATEn(base, gateNum))
    {
        status = kStatus_Fail;
    }

    return status;
}

/*!
 * brief Locks the RDC_SEMA42 gate.
 *
 * This function locks the specific RDC_SEMA42 gate. If the gate has been
 * locked by other processors, this function waits until it is unlocked and then
 * lock it.
 *
 * param base RDC_SEMA42 peripheral base address.
 * param gateNum  Gate number to lock.
 * param masterIndex  Current processor master index.
 * param domainId  Current processor domain ID.
 */
void RDC_SEMA42_Lock(RDC_SEMAPHORE_Type *base, uint8_t gateNum, uint8_t masterIndex, uint8_t domainId)
{
    while (kStatus_Success != RDC_SEMA42_TryLock(base, gateNum, masterIndex, domainId))
    {
    }
}

/*!
 * brief Gets which domain has currently locked the gate.
 *
 * param base RDC_SEMA42 peripheral base address.
 * param gateNum  Gate number.
 *
 * return Return -1 if the gate is not locked by any domain, otherwise return the
 * domain ID.
 */
int32_t RDC_SEMA42_GetLockDomainID(RDC_SEMAPHORE_Type *base, uint8_t gateNum)
{
    assert(gateNum < RDC_SEMA42_GATE_COUNT);

    int32_t ret;
    uint8_t regGate = RDC_SEMA42_GATEn(base, gateNum);

    /* Current gate is not locked. */
    if (0U == (regGate & RDC_SEMAPHORE_GATE_GTFSM_MASK))
    {
        ret = -1;
    }
    else
    {
        ret = (int32_t)((uint8_t)((regGate & RDC_SEMAPHORE_GATE_LDOM_MASK) >> RDC_SEMAPHORE_GATE_LDOM_SHIFT));
    }

    return ret;
}

/*!
 * brief Resets the RDC_SEMA42 gate to an unlocked status.
 *
 * This function resets a RDC_SEMA42 gate to an unlocked status.
 *
 * param base RDC_SEMA42 peripheral base address.
 * param gateNum  Gate number.
 *
 * retval kStatus_Success         RDC_SEMA42 gate is reset successfully.
 * retval kStatus_Failed Some other reset process is ongoing.
 */
status_t RDC_SEMA42_ResetGate(RDC_SEMAPHORE_Type *base, uint8_t gateNum)
{
    status_t status;

    /*
     * Reset all gates if gateNum >= RDC_SEMA42_GATE_NUM_RESET_ALL
     * Reset specific gate if gateNum < RDC_SEMA42_GATE_COUNT
     */

    /* Check whether some reset is ongoing. */
    if (0U != (base->RSTGT_R & RDC_SEMAPHORE_RSTGT_R_RSTGSM_MASK))
    {
        status = kStatus_Fail;
    }
    else
    {
        /* First step. */
        base->RSTGT_W = RDC_SEMAPHORE_RSTGT_W_RSTGDP(RDC_SEMA42_GATE_RESET_PATTERN_1);
        /* Second step. */
        base->RSTGT_W =
            RDC_SEMAPHORE_RSTGT_W_RSTGDP(RDC_SEMA42_GATE_RESET_PATTERN_2) | RDC_SEMAPHORE_RSTGT_W_RSTGTN(gateNum);

        status = kStatus_Success;
    }

    return status;
}