1 /*******************************************************************************
2  * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * MPFS HAL Embedded Software
7  *
8  */
9 /*******************************************************************************
10  * @file mss_peripherals.c
11  * @author Microchip-FPGA Embedded Systems Solutions
12  * @brief PolarFire SoC MSS functions related to peripherals.
13  *
14  */
15 /*=========================================================================*//**
16 
17  *//*=========================================================================*/
18 #include <stdio.h>
19 #include <string.h>
20 #include "mpfs_hal/mss_hal.h"
21 
22 const uint32_t LIBERO_SETTING_CONTEXT_EN[][2U] = {
23                 {LIBERO_SETTING_CONTEXT_A_EN,
24                  LIBERO_SETTING_CONTEXT_B_EN},
25                 {LIBERO_SETTING_CONTEXT_A_EN_FIC,
26                  LIBERO_SETTING_CONTEXT_B_EN_FIC},
27 };
28 
29 /* offsets used in PERIPHERAL_SETUP array */
30 #define PERIPHERAL_INDEX_OFFSET         0U /* used for sanity check */
31 #define CONTEXT_EN_INDEX_OFFSET         1U
32 #define CONTEXT_MASK_INDEX_OFFSET       2U
33 #define CONTEXT_SUBCLK_INDEX_OFFSET     3U
34 
35 const uint32_t PERIPHERAL_SETUP[][4U] = {
36         {MSS_PERIPH_MMUART0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMUART0,SUBBLK_CLOCK_CR_MMUART0_MASK},
37         {MSS_PERIPH_MMUART1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMUART1,SUBBLK_CLOCK_CR_MMUART1_MASK},
38         {MSS_PERIPH_MMUART2,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMUART2,SUBBLK_CLOCK_CR_MMUART2_MASK},
39         {MSS_PERIPH_MMUART3,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMUART3,SUBBLK_CLOCK_CR_MMUART3_MASK},
40         {MSS_PERIPH_MMUART4,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMUART4,SUBBLK_CLOCK_CR_MMUART4_MASK},
41         {MSS_PERIPH_WDOG0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_WDOG0,SUBBLK_CLOCK_NA_MASK},
42         {MSS_PERIPH_WDOG1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_WDOG1,SUBBLK_CLOCK_NA_MASK},
43         {MSS_PERIPH_WDOG2,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_WDOG2,SUBBLK_CLOCK_NA_MASK},
44         {MSS_PERIPH_WDOG3,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_WDOG3,SUBBLK_CLOCK_NA_MASK},
45         {MSS_PERIPH_WDOG4,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_WDOG4,SUBBLK_CLOCK_NA_MASK},
46         {MSS_PERIPH_SPI0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_SPI0,SUBBLK_CLOCK_CR_SPI0_MASK},
47         {MSS_PERIPH_SPI1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_SPI1,SUBBLK_CLOCK_CR_SPI1_MASK},
48         {MSS_PERIPH_I2C0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_I2C0,SUBBLK_CLOCK_CR_I2C0_MASK},
49         {MSS_PERIPH_I2C1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_I2C1,SUBBLK_CLOCK_CR_I2C1_MASK},
50         {MSS_PERIPH_CAN0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_CAN0,SUBBLK_CLOCK_CR_CAN0_MASK},
51         {MSS_PERIPH_CAN1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_CAN1,SUBBLK_CLOCK_CR_CAN1_MASK},
52         {MSS_PERIPH_MAC0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MAC0,SUBBLK_CLOCK_CR_MAC0_MASK},
53         {MSS_PERIPH_MAC1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MAC1,SUBBLK_CLOCK_CR_MAC1_MASK},
54         {MSS_PERIPH_TIMER,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_TIMER,SUBBLK_CLOCK_CR_TIMER_MASK},
55         {MSS_PERIPH_GPIO0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_GPIO0,SUBBLK_CLOCK_CR_GPIO0_MASK},
56         {MSS_PERIPH_GPIO1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_GPIO1,SUBBLK_CLOCK_CR_GPIO1_MASK},
57         {MSS_PERIPH_GPIO2,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_GPIO2,SUBBLK_CLOCK_CR_GPIO2_MASK},
58         {MSS_PERIPH_RTC,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_RTC,SUBBLK_CLOCK_CR_RTC_MASK},
59         {MSS_PERIPH_H2FINT,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_H2FINT,  SUBBLK_CLOCK_NA_MASK},
60         {MSS_PERIPH_CRYPTO,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_CRYPTO,SUBBLK_CLOCK_CR_ATHENA_MASK},
61         {MSS_PERIPH_USB,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_USB,SUBBLK_CLOCK_CR_USB_MASK},
62         {MSS_PERIPH_QSPIXIP,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_QSPIXIP,SUBBLK_CLOCK_CR_QSPI_MASK},
63         {MSS_PERIPH_ATHENA,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_ATHENA,SUBBLK_CLOCK_CR_ATHENA_MASK},
64         {MSS_PERIPH_TRACE,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMC,SUBBLK_CLOCK_CR_MMC_MASK},
65         {MSS_PERIPH_MAILBOX_SC,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMC,SUBBLK_CLOCK_CR_MMC_MASK},
66         {MSS_PERIPH_EMMC,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMC,SUBBLK_CLOCK_CR_MMC_MASK},
67         {MSS_PERIPH_CFM,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_CFM,SUBBLK_CLOCK_CR_CFM_MASK},
68         {MSS_PERIPH_FIC0,CONTEXT_EN_INDEX_FIC, CONTEXT_EN_MASK_FIC0,SUBBLK_CLOCK_CR_FIC0_MASK},
69         {MSS_PERIPH_FIC1,CONTEXT_EN_INDEX_FIC, CONTEXT_EN_MASK_FIC1,SUBBLK_CLOCK_CR_FIC1_MASK},
70         {MSS_PERIPH_FIC2,CONTEXT_EN_INDEX_FIC, CONTEXT_EN_MASK_FIC2,SUBBLK_CLOCK_CR_FIC2_MASK},
71         {MSS_PERIPH_FIC3,CONTEXT_EN_INDEX_FIC, CONTEXT_EN_MASK_FIC3,SUBBLK_CLOCK_CR_FIC3_MASK}
72 };
73 
74 /**
75  * If contexts set-up, verify allowed access to peripheral
76  * @param option - Two option, , FIC enables set separately. CONTEXT_EN_INDEX_FIC or CONTEXT_EN_INDEX
77  * @param periph_context_mask See CONTEXT_EN_MASK_ defines for options
78  * @param hart The hart ID of origin of request.
79  * @return
80  */
verify_context_enable(uint8_t option,uint32_t periph_context_mask,uint32_t hart)81 static inline uint8_t verify_context_enable(uint8_t option, uint32_t periph_context_mask , uint32_t hart)
82 {
83     uint8_t result = 1U;
84 #if ((LIBERO_SETTING_MEM_CONFIGS_ENABLED & PMP_ENABLED_MASK) == PMP_ENABLED_MASK)
85     if (hart != (uint8_t) 0U)
86     {
87         if (LIBERO_SETTING_CONTEXT_A_HART_EN & hart )
88         {
89             if (LIBERO_SETTING_CONTEXT_EN[option][0U] & periph_context_mask)
90             {
91                 result = 0U;
92             }
93         }
94 
95         if (LIBERO_SETTING_CONTEXT_B_HART_EN & hart )
96         {
97             if (LIBERO_SETTING_CONTEXT_EN[option][1U] & periph_context_mask)
98             {
99                 result = 0U;
100             }
101         }
102     }
103     else
104     {
105         hart = 0U;
106     }
107 #else
108     (void)hart;
109     (void)periph_context_mask;
110     (void)option;
111     result = 0U;
112 #endif
113     return result;
114 }
115 
116 /**
117  * Turn on/off mss peripheral as required
118  * @param peripheral_mask
119  * @param req_state
120  */
peripheral_on_off(uint32_t peripheral_mask,PERIPH_RESET_STATE req_state)121 static inline void peripheral_on_off(uint32_t peripheral_mask , PERIPH_RESET_STATE req_state)
122 {
123     if (req_state == PERIPHERAL_OFF)
124     {
125         /* Turn off clock */
126         SYSREG->SUBBLK_CLOCK_CR &= (uint32_t)~(peripheral_mask);
127         /* Hold in reset */
128         SYSREG->SOFT_RESET_CR   |= (uint32_t)(peripheral_mask);
129     }
130     else
131     {
132         /* Turn on clock */
133         SYSREG->SUBBLK_CLOCK_CR |= (peripheral_mask);
134         /* Remove soft reset */
135         SYSREG->SOFT_RESET_CR   &= (uint32_t)~(peripheral_mask);
136     }
137 }
138 
139 
140 /***************************************************************************//**
141  * See mss_peripherals.h for details of how to use this function.
142  */
mss_config_clk_rst(mss_peripherals peripheral,uint8_t hart,PERIPH_RESET_STATE req_state)143 __attribute__((weak))  uint8_t mss_config_clk_rst(mss_peripherals peripheral, uint8_t hart, PERIPH_RESET_STATE req_state)
144 {
145     uint8_t result = 1U;
146 
147     ASSERT(PERIPHERAL_SETUP[peripheral][PERIPHERAL_INDEX_OFFSET] == peripheral);
148 
149     result = verify_context_enable(PERIPHERAL_SETUP[peripheral][CONTEXT_EN_INDEX_OFFSET], PERIPHERAL_SETUP[peripheral][CONTEXT_MASK_INDEX_OFFSET] , hart);
150 
151     if (result == 0U)
152     {
153         peripheral_on_off(PERIPHERAL_SETUP[peripheral][CONTEXT_SUBCLK_INDEX_OFFSET] , req_state);
154     }
155     return result;
156 }
157 
158