1 /*
2 * Copyright (c) 2017-2020 Arm Limited
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "musca_s1_scc_drv.h"
18 /* Use __ISB(), __DSB() */
19 #include "cmsis.h"
20
21 /** Setter bit manipulation macro */
22 #define SET_BIT(WORD, BIT_INDEX) ((WORD) |= (1u << (BIT_INDEX)))
23 /** Clearing bit manipulation macro */
24 #define CLR_BIT(WORD, BIT_INDEX) ((WORD) &= ~(1u << (BIT_INDEX)))
25
26 struct musca_s1_scc_reg_map_t {
27 /* 0x000-0x800 Reserved (offset) */
28 const uint32_t reserved0[512];
29 /* 0x800 RW Clock Control Selection Register */
30 volatile uint32_t clk_ctrl_sel;
31 /* 0x804 RW Clock PLL Prediv Control Register */
32 volatile uint32_t clk_pll_prediv_ctrl;
33 /* 0x808 RW Body Bias Generator CLK Div Register */
34 volatile uint32_t clk_bbgen_div_clk;
35 /* 0x80C Reserved */
36 const uint32_t reserved1;
37 /* 0x810 RW QSPI Post PLL CLK divider Register */
38 volatile uint32_t clk_postdiv_qspi;
39 /* 0x814 RW RTC Post PLL CLK div ctrl Register */
40 volatile uint32_t clk_postdiv_ctrl_rtc;
41 /* 0x818 Reserved */
42 const uint32_t reserved2;
43 /* 0x81C RW TEST CLK Post PLL CLK Div Register */
44 volatile uint32_t clk_postdiv_ctrl_test;
45 /* 0x820 RW Post PLL CLK divider bypass Register */
46 volatile uint32_t ctrl_bypass_div;
47 /* 0x824 RW PLL0 Control Register */
48 volatile uint32_t pll_ctrl_pll0_clk;
49 /* 0x828-0x82C Reserved */
50 const uint32_t reserved3[2];
51 /* 0x830 RW Clock gate enable control Register */
52 volatile uint32_t clk_ctrl_enable;
53 /* 0x834 RW PLL Status Register */
54 volatile uint32_t clk_status;
55 /* 0x838-0x83C Reserved */
56 const uint32_t reserved4[2];
57 /* 0x840 RW Reset Control Register */
58 volatile uint32_t reset_ctrl;
59 /* 0x844 Reserved */
60 const uint32_t reserved5;
61 /* 0x848 RW Debug Control Register */
62 volatile uint32_t dbg_ctrl;
63 /* 0x84C RW SRAM Control Register */
64 volatile uint32_t sram_ctrl;
65 /* 0x850 RW MPC Interupt Control Register */
66 volatile uint32_t intr_ctrl;
67 /* 0x854 Reserved */
68 const uint32_t reserved6;
69 /* 0x858 RW Reset vector for CPU0 SRAM */
70 volatile uint32_t cpu0_vtor;
71 /* 0x85C RW Reset vector for CPU0 MRAM */
72 volatile uint32_t cpu0_vtor_1;
73 /* 0x860 RW Reset vector for CPU1 SRAM */
74 volatile uint32_t cpu1_vtor;
75 /* 0x864 RW Reset vector for CPU1 MRAM */
76 volatile uint32_t cpu1_vtor_1;
77 /* 0x868 RW Main function in data select */
78 volatile uint32_t iomux_main_insel;
79 /* 0x874 Reserved */
80 const uint32_t reserved7;
81 /* 0x870 RW Main function out data select */
82 volatile uint32_t iomux_main_outsel;
83 /* 0x874 Reserved */
84 const uint32_t reserved8;
85 /* 0x878 RW Main function out enable select */
86 volatile uint32_t iomux_main_oensel;
87 /* 0x87C Reserved */
88 const uint32_t reserved9;
89 /* 0x880 RW Main function default in select */
90 volatile uint32_t iomux_main_default_in;
91 /* 0x884 Reserved */
92 const uint32_t reserved10;
93 /* 0x888 RW Alt function 1 in data select */
94 volatile uint32_t iomux_altf1_insel;
95 /* 0x88C Reserved */
96 const uint32_t reserved11;
97 /* 0x890 RW Alt function 1 out data select */
98 volatile uint32_t iomux_altf1_outsel;
99 /* 0x894 Reserved */
100 const uint32_t reserved12;
101 /* 0x898 RW Alt function 1 out enable select */
102 volatile uint32_t iomux_altf1_oensel;
103 /* 0x89C Reserved */
104 const uint32_t reserved13;
105 /* 0x8A0 RW Alt function 1 default in select */
106 volatile uint32_t iomux_altf1_default_in;
107 /* 0x8A4 Reserved */
108 const uint32_t reserved14;
109 /* 0x8A8 RW Alt function 2 in data select */
110 volatile uint32_t iomux_altf2_insel;
111 /* 0x8AC Reserved */
112 const uint32_t reserved15;
113 /* 0x8B0 RW Alt function 2 out data select */
114 volatile uint32_t iomux_altf2_outsel;
115 /* 0x8B4 Reserved */
116 const uint32_t reserved16;
117 /* 0x8B8 RW Alt function 2 out enable select */
118 volatile uint32_t iomux_altf2_oensel;
119 /* 0x8BC Reserved */
120 const uint32_t reserved17;
121 /* 0x8C0 RW Alt function 2 default in select */
122 volatile uint32_t iomux_altf2_default_in;
123 /* 0x8C4-0x8E4 Reserved */
124 const uint32_t reserved18[9];
125 /* 0x8E8 RW Drive Select 0 */
126 volatile uint32_t iopad_ds0;
127 /* 0x8EC Reserved */
128 const uint32_t reserved19;
129 /* 0x8F0 RW Drive Select 1 */
130 volatile uint32_t iopad_ds1;
131 /* 0x8F4 Reserved */
132 const uint32_t reserved20;
133 /* 0x8F8 RW Pull Enable */
134 volatile uint32_t iopad_pe;
135 /* 0x8FC Reserved */
136 const uint32_t reserved21;
137 /* 0x900 RW Pull Select */
138 volatile uint32_t iopad_ps;
139 /* 0x904 Reserved */
140 const uint32_t reserved22;
141 /* 0x908 RW Slew Select */
142 volatile uint32_t iopad_sr;
143 /* 0x90C Reserved */
144 const uint32_t reserved23;
145 /* 0x910 RW Input Select */
146 volatile uint32_t iopad_is;
147 /* 0x914 Reserved */
148 const uint32_t reserved24;
149 /* 0x918 RW PVT control register */
150 volatile uint32_t pvt_ctrl;
151 /* 0x91C-0x938 Reserved */
152 const uint32_t reserved25[8];
153 /* 0x93C RW Static configuration */
154 volatile uint32_t static_conf_sig1;
155 /* 0x940-0x994 Reserved */
156 const uint32_t reserved26[22];
157 /* 0x998 RW eMRAM control 0 register */
158 volatile uint32_t scc_mram_ctrl0;
159 /* 0x99C RW eMRAM control 1 register */
160 volatile uint32_t scc_mram_ctrl1;
161 /* 0x9A0 RW eMRAM control 2 register */
162 volatile uint32_t scc_mram_ctrl2;
163 /* 0x9A4-0x9AC Reserved */
164 const uint32_t reserved27[3];
165 /* 0x9B0 RW eMRAM data input 0 register */
166 volatile uint32_t scc_mram_din0;
167 /* 0x9B4 RW eMRAM data input 1 register */
168 volatile uint32_t scc_mram_din1;
169 /* 0x9B8 RW eMRAM data input 2 register */
170 volatile uint32_t scc_mram_din2;
171 /* 0x9BC Reserved */
172 const uint32_t reserved28;
173 /* 0x9C0 RW eMRAM data output 0 register */
174 volatile uint32_t scc_mram_dout0;
175 /* 0x9C4 RW eMRAM data output 1 register */
176 volatile uint32_t scc_mram_dout1;
177 /* 0x9C8 RW eMRAM data output 2 register */
178 volatile uint32_t scc_mram_dout2;
179 /* 0x9CC-0x9DC Reserved */
180 const uint32_t reserved29[5];
181 /* 0x9E0 RW CLK pahes shift control register */
182 volatile uint32_t selection_control_reg;
183 /* 0x9E4-0xA00 Reserved */
184 const uint32_t reserved30[8];
185 /* 0xA04 RW SSE-200 OTP control register */
186 volatile uint32_t sse_otp_ctrl;
187 /* 0xA08-0xA1C Reserved */
188 const uint32_t reserved31[6];
189 /* 0xA20 RW Body-Biasing control register */
190 volatile uint32_t bbgen_ctrl;
191 /* 0xA24 RW Spaer control register */
192 volatile uint32_t spare_ctrl1;
193 /* 0xA28-0xBFC Reserved */
194 const uint32_t reserved32[118];
195 /* 0xC00 RO Chip ID 0x0797_0477 */
196 const uint32_t chip_id;
197 /* 0xC04 RO I/O in status */
198 const uint32_t io_in_status;
199 };
200
201 /**
202 * \brief Musca-S1 SCC eMRAM control 0 register bit fields
203 */
204 #define SCC_MRAM_CTRL0_MRAM_CLK_EN 0u
205 /*!< eMRAM control register 0 Enable eMRAM clock offset */
206 #define SCC_MRAM_CTRL0_PROC_SPEC_CLK_EN 1u
207 /*!< eMRAM control register 0 Enable eMRAM controller clock offset */
208 #define SCC_MRAM_CTRL0_AUTOSTOP_EN 2u
209 /*!< eMRAM control register 0 Enable autostop offset */
210 #define SCC_MRAM_CTRL0_MRAM_INV_CLK_SEL 3u
211 /*!< eMRAM control register 0 Select clock inversion offset */
212 #define SCC_MRAM_CTRL0_FAST_READ_EN 4u
213 /*!< eMRAM control register 0 Enable fast read offset */
214 #define SCC_MRAM_CTRL0_MRAM_DOUT_SEL 5u
215 /*!< eMRAM control register 0 Select eMRAM0 output data offset */
216 #define SCC_MRAM_CTRL0_PG_VDD_0 8u
217 /*!< eMRAM control register 0 eMRAM0 PG VDD offset */
218 #define SCC_MRAM_CTRL0_PG_VDD18_0 9u
219 /*!< eMRAM control register 0 eMRAM1 PG VDD18_0 offset */
220 #define SCC_MRAM_CTRL0_PG_VDD_1 10u
221 /*!< eMRAM control register 0 eMRAM1 PG VDD offset */
222 #define SCC_MRAM_CTRL0_PG_VDD18_1 11u
223 /*!< eMRAM control register 0 eMRAM1 PG VDD18 offset */
224 #define SCC_MRAM_CTRL0_WRITE_CSN_CLKS 12u
225 /*!< eMRAM control register 0 WRITE_CSN_CLKS offset */
226 #define SCC_MRAM_CTRL0_CSN_HIGH_CLKS 16u
227 /*!< eMRAM control register 0 CSN_HIGH_CLKS offset */
228 #define SCC_MRAM_CTRL0_READ_CSN_CLKS 20u
229 /*!< eMRAM control register 0 Number of clocks for single read offset */
230 #define SCC_MRAM_CTRL0_MRAM_OTP_CLK_EN 29u
231 /*!< eMRAM control register 0 Enable eMRAM OTP clock offset */
232 #define SCC_MRAM_CTRL0_MRAM_CLK_SYNC_BYPASS 30u
233 /*!< eMRAM control register 0 Bypass eMRAM clock divider sync offset */
234 #define SCC_MRAM_CTRL0_MRAM_DA_EN 31u
235 /*!< eMRAM control register 0 Enable eMRAM direct access offset */
236
237 /**
238 * \brief Clears selected alternate functions for selected pins
239 *
240 * \param[in] dev SCC registers base address \ref musca_s1_scc_reg_map_t
241 * \param[in] func_mask Bitmask of alternate functions to clear
242 * \ref gpio_altfunc_mask_t
243 * \param[in] pin_mask Pin mask for the alternate functions
244 */
scc_clear_alt_func(struct musca_s1_scc_reg_map_t * scc_regs,enum gpio_altfunc_mask_t func_mask,uint32_t pin_mask)245 static void scc_clear_alt_func(struct musca_s1_scc_reg_map_t* scc_regs,
246 enum gpio_altfunc_mask_t func_mask,
247 uint32_t pin_mask)
248 {
249 if (func_mask & GPIO_MAIN_FUNC_MASK) {
250 scc_regs->iomux_main_insel &= ~pin_mask;
251 scc_regs->iomux_main_outsel &= ~pin_mask;
252 scc_regs->iomux_main_oensel &= ~pin_mask;
253 }
254 if (func_mask & GPIO_ALTFUNC_1_MASK) {
255 scc_regs->iomux_altf1_insel &= ~pin_mask;
256 scc_regs->iomux_altf1_outsel &= ~pin_mask;
257 scc_regs->iomux_altf1_oensel &= ~pin_mask;
258 }
259 if (func_mask & GPIO_ALTFUNC_2_MASK) {
260 scc_regs->iomux_altf2_insel &= ~pin_mask;
261 scc_regs->iomux_altf2_outsel &= ~pin_mask;
262 scc_regs->iomux_altf2_oensel &= ~pin_mask;
263 }
264 }
265
musca_s1_scc_set_alt_func(struct musca_s1_scc_dev_t * dev,enum gpio_altfunc_t altfunc,uint32_t pin_mask)266 void musca_s1_scc_set_alt_func(struct musca_s1_scc_dev_t* dev,
267 enum gpio_altfunc_t altfunc, uint32_t pin_mask)
268 {
269 struct musca_s1_scc_reg_map_t* scc_regs =
270 (struct musca_s1_scc_reg_map_t*) dev->cfg->base;
271 enum gpio_altfunc_mask_t altfunc_to_clear = GPIO_ALTFUNC_NONE;
272 volatile uint32_t *insel = NULL;
273 volatile uint32_t *outsel = NULL;
274 volatile uint32_t *oensel = NULL;
275
276 if (altfunc >= GPIO_ALTFUNC_MAX) {
277 /* If no altfunction is selected, then nothing to do.
278 * This is possible during init and we do not
279 * want to change the reset values set by the HW
280 */
281 return;
282 }
283
284 switch (altfunc) {
285 case GPIO_MAIN_FUNC:
286 insel = &scc_regs->iomux_main_insel;
287 outsel = &scc_regs->iomux_main_outsel;
288 oensel = &scc_regs->iomux_main_oensel;
289 altfunc_to_clear = GPIO_MAIN_FUNC_NEG_MASK;
290 break;
291
292 case GPIO_ALTFUNC_1:
293 insel = &scc_regs->iomux_altf1_insel;
294 outsel = &scc_regs->iomux_altf1_outsel;
295 oensel = &scc_regs->iomux_altf1_oensel;
296 altfunc_to_clear = GPIO_ALTFUNC_1_NEG_MASK;
297 break;
298
299 case GPIO_ALTFUNC_2:
300 insel = &scc_regs->iomux_altf2_insel;
301 outsel = &scc_regs->iomux_altf2_outsel;
302 oensel = &scc_regs->iomux_altf2_oensel;
303 altfunc_to_clear = GPIO_ALTFUNC_2_NEG_MASK;
304 break;
305 default:
306 break;
307 }
308
309 /* Select the wanted function's output enable bit first.
310 * This way the output won't be disabled which is desired
311 * if we switch from output to output function
312 */
313 *oensel |= pin_mask;
314
315 /* Clear all alternate function registers which are not selected */
316 scc_clear_alt_func(scc_regs, altfunc_to_clear, pin_mask);
317
318 /* Enable input and output data line */
319 *insel |= pin_mask;
320 *outsel |= pin_mask;
321 }
322
musca_s1_scc_set_pinmode(struct musca_s1_scc_dev_t * dev,uint32_t pin_mask,enum pinmode_select_t mode)323 void musca_s1_scc_set_pinmode(struct musca_s1_scc_dev_t* dev, uint32_t pin_mask,
324 enum pinmode_select_t mode)
325 {
326 struct musca_s1_scc_reg_map_t* scc_regs =
327 (struct musca_s1_scc_reg_map_t*) dev->cfg->base;
328
329 switch (mode) {
330 case PINMODE_NONE:
331 scc_regs->iopad_pe &= ~pin_mask;
332 break;
333 case PINMODE_PULL_DOWN:
334 /* If the pull select bit is set to 0 it means pull down */
335 scc_regs->iopad_ps &= ~pin_mask;
336 scc_regs->iopad_pe |= pin_mask;
337 break;
338 case PINMODE_PULL_UP:
339 /* If the pull select bit is set to 1 it means pull up */
340 scc_regs->iopad_ps |= pin_mask;
341 scc_regs->iopad_pe |= pin_mask;
342 break;
343 default:
344 break;
345 }
346 }
347
musca_s1_scc_set_default_in(struct musca_s1_scc_dev_t * dev,enum gpio_altfunc_t altfunc,uint32_t default_in_mask,uint32_t default_in_value)348 void musca_s1_scc_set_default_in(struct musca_s1_scc_dev_t* dev,
349 enum gpio_altfunc_t altfunc,
350 uint32_t default_in_mask,
351 uint32_t default_in_value)
352 {
353 struct musca_s1_scc_reg_map_t* scc_regs =
354 (struct musca_s1_scc_reg_map_t*) dev->cfg->base;
355 uint32_t iomux_value = 0;
356
357 if (altfunc >= GPIO_ALTFUNC_MAX) {
358 /* If no altfunction is selected, then nothing to do */
359 return;
360 }
361
362 switch (altfunc) {
363 case GPIO_MAIN_FUNC:
364 iomux_value = scc_regs->iomux_main_default_in & ~default_in_mask;
365 iomux_value |= (default_in_value & default_in_mask);
366 scc_regs->iomux_main_default_in = iomux_value;
367 scc_regs->iomux_main_insel =
368 (scc_regs->iomux_main_insel & ~default_in_mask);
369 break;
370
371 case GPIO_ALTFUNC_1:
372 iomux_value = scc_regs->iomux_altf1_default_in & ~default_in_mask;
373 iomux_value |= (default_in_value & default_in_mask);
374 scc_regs->iomux_altf1_default_in = iomux_value;
375 scc_regs->iomux_altf1_insel =
376 (scc_regs->iomux_altf1_insel & ~default_in_mask);
377 break;
378
379 case GPIO_ALTFUNC_2:
380 iomux_value = scc_regs->iomux_altf2_default_in & ~default_in_mask;
381 iomux_value |= (default_in_value & default_in_mask);
382 scc_regs->iomux_altf2_default_in = iomux_value;
383 scc_regs->iomux_altf2_insel =
384 (scc_regs->iomux_altf2_insel & ~default_in_mask);
385 break;
386 default:
387 break;
388 }
389 }
390
musca_s1_scc_mram_fast_read_enable(struct musca_s1_scc_dev_t * dev)391 void musca_s1_scc_mram_fast_read_enable(struct musca_s1_scc_dev_t* dev)
392 {
393 struct musca_s1_scc_reg_map_t* scc_regs =
394 (struct musca_s1_scc_reg_map_t*) dev->cfg->base;
395 __DSB();
396 SET_BIT(scc_regs->scc_mram_ctrl0, SCC_MRAM_CTRL0_FAST_READ_EN);
397 __DSB();
398 __ISB();
399 }
400
musca_s1_scc_mram_fast_read_disable(struct musca_s1_scc_dev_t * dev)401 void musca_s1_scc_mram_fast_read_disable(struct musca_s1_scc_dev_t* dev)
402 {
403 struct musca_s1_scc_reg_map_t* scc_regs =
404 (struct musca_s1_scc_reg_map_t*) dev->cfg->base;
405 __DSB();
406 CLR_BIT(scc_regs->scc_mram_ctrl0, SCC_MRAM_CTRL0_FAST_READ_EN);
407 __DSB();
408 __ISB();
409 }
410
musca_s1_scc_mram_is_fast_read_enabled(struct musca_s1_scc_dev_t * dev)411 bool musca_s1_scc_mram_is_fast_read_enabled(struct musca_s1_scc_dev_t* dev)
412 {
413 struct musca_s1_scc_reg_map_t* scc_regs =
414 (struct musca_s1_scc_reg_map_t*) dev->cfg->base;
415 return (bool)(scc_regs->scc_mram_ctrl0 &
416 (1u << SCC_MRAM_CTRL0_FAST_READ_EN));
417 }
418