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