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 /*******************************************************************************
11  * @file mss_io.h
12  * @author Microchip-FPGA Embedded Systems Solutions
13  * @brief MSS IO related code
14  *
15  */
16 #include <string.h>
17 #include <stdio.h>
18 
19 #include "mpfs_hal/mss_hal.h"
20 
21 /*******************************************************************************
22  * external functions
23  */
24 
25 
26 /*
27  * IOMUX values from Libero
28  */
29 IOMUX_CONFIG   iomux_config_values = {
30     LIBERO_SETTING_IOMUX0_CR, /* Selects whether the peripheral is connected to
31                                  the Fabric or IOMUX structure. */
32     LIBERO_SETTING_IOMUX1_CR, /* BNK4 SDV PAD 0 to 7, each IO has 4 bits   */
33     LIBERO_SETTING_IOMUX2_CR, /* BNK4 SDV PAD 8 to 13     */
34     LIBERO_SETTING_IOMUX3_CR, /* BNK2 SDV PAD 14 to 21    */
35     LIBERO_SETTING_IOMUX4_CR, /* BNK2 SDV PAD 22 to 29    */
36     LIBERO_SETTING_IOMUX5_CR, /* BNK2 PAD 30 to 37        */
37     LIBERO_SETTING_IOMUX6_CR  /* Sets whether the MMC/SD Voltage select lines
38                                  are inverted on entry to the IOMUX structure */
39 };
40 
41 #ifdef LIBERO_SETTING_ALT_IOMUX1_CR
42 IOMUX_CONFIG   iomux_alt_config_values = {
43     LIBERO_SETTING_ALT_IOMUX0_CR, /* Selects whether the peripheral is connected to
44                                  the Fabric or IOMUX structure. */
45     LIBERO_SETTING_ALT_IOMUX1_CR, /* BNK4 SDV PAD 0 to 7, each IO has 4 bits   */
46     LIBERO_SETTING_ALT_IOMUX2_CR, /* BNK4 SDV PAD 8 to 13     */
47     LIBERO_SETTING_ALT_IOMUX3_CR, /* BNK2 SDV PAD 14 to 21    */
48     LIBERO_SETTING_ALT_IOMUX4_CR, /* BNK2 SDV PAD 22 to 29    */
49     LIBERO_SETTING_ALT_IOMUX5_CR, /* BNK2 PAD 30 to 37        */
50     LIBERO_SETTING_ALT_IOMUX6_CR  /* Sets whether the MMC/SD Voltage select lines
51                                  are inverted on entry to the IOMUX structure */
52 };
53 #endif
54 
55 /*
56  * Bank 4 and 2 settings, the 38 MSSIO.
57  */
58 MSSIO_BANK4_CONFIG mssio_bank4_io_config = {
59     /* LIBERO_SETTING_mssio_bank4_io_cfg_0_cr
60         x_vddi Ratio Rx<0-2> == 001
61         drv<3-6> == 1111
62         7:clamp   == 0
63         enhyst   == 0
64         lockdn_en == 1
65         10:wpd  == 0
66         atp_en`== 0
67         lpmd_ibuf  == 0
68         lpmd_obuf == 0
69         persist == 0
70         */
71     LIBERO_SETTING_MSSIO_BANK4_IO_CFG_0_1_CR,
72     LIBERO_SETTING_MSSIO_BANK4_IO_CFG_2_3_CR,
73     LIBERO_SETTING_MSSIO_BANK4_IO_CFG_4_5_CR,
74     LIBERO_SETTING_MSSIO_BANK4_IO_CFG_6_7_CR,
75     LIBERO_SETTING_MSSIO_BANK4_IO_CFG_8_9_CR,
76     LIBERO_SETTING_MSSIO_BANK4_IO_CFG_10_11_CR,
77     LIBERO_SETTING_MSSIO_BANK4_IO_CFG_12_13_CR,
78 };
79 
80 /*
81  * Bank 4 and 2 settings, the 38 MSSIO.
82  */
83 #ifdef LIBERO_SETTING_ALT_IOMUX1_CR
84 MSSIO_BANK4_CONFIG mssio_alt_bank4_io_config = {
85     /* LIBERO_SETTING_mssio_bank4_io_cfg_0_cr
86         x_vddi Ratio Rx<0-2> == 001
87         drv<3-6> == 1111
88         7:clamp   == 0
89         enhyst   == 0
90         lockdn_en == 1
91         10:wpd  == 0
92         atp_en`== 0
93         lpmd_ibuf  == 0
94         lpmd_obuf == 0
95         persist == 0
96         */
97     LIBERO_SETTING_ALT_MSSIO_BANK4_IO_CFG_0_1_CR,
98     LIBERO_SETTING_ALT_MSSIO_BANK4_IO_CFG_2_3_CR,
99     LIBERO_SETTING_ALT_MSSIO_BANK4_IO_CFG_4_5_CR,
100     LIBERO_SETTING_ALT_MSSIO_BANK4_IO_CFG_6_7_CR,
101     LIBERO_SETTING_ALT_MSSIO_BANK4_IO_CFG_8_9_CR,
102     LIBERO_SETTING_ALT_MSSIO_BANK4_IO_CFG_10_11_CR,
103     LIBERO_SETTING_ALT_MSSIO_BANK4_IO_CFG_12_13_CR,
104 };
105 #endif
106 
107 /*
108  * Bank 4 and 2 settings, the 38 MSSIO.
109  */
110 MSSIO_BANK2_CONFIG mssio_bank2_io_config = {
111     /* LIBERO_SETTING_mssio_bank4_io_cfg_0_cr
112         x_vddi Ratio Rx<0-2> == 001
113         drv<3-6> == 1111
114         7:clamp   == 0
115         enhyst   == 0
116         lockdn_en == 1
117         10:wpd  == 0
118         atp_en`== 0
119         lpmd_ibuf  == 0
120         lpmd_obuf == 0
121         persist == 0
122         */
123     LIBERO_SETTING_MSSIO_BANK2_IO_CFG_0_1_CR,
124     LIBERO_SETTING_MSSIO_BANK2_IO_CFG_2_3_CR,
125     LIBERO_SETTING_MSSIO_BANK2_IO_CFG_4_5_CR,
126     LIBERO_SETTING_MSSIO_BANK2_IO_CFG_6_7_CR,
127     LIBERO_SETTING_MSSIO_BANK2_IO_CFG_8_9_CR,
128     LIBERO_SETTING_MSSIO_BANK2_IO_CFG_10_11_CR,
129     LIBERO_SETTING_MSSIO_BANK2_IO_CFG_12_13_CR,
130     LIBERO_SETTING_MSSIO_BANK2_IO_CFG_14_15_CR,
131     LIBERO_SETTING_MSSIO_BANK2_IO_CFG_16_17_CR,
132     LIBERO_SETTING_MSSIO_BANK2_IO_CFG_18_19_CR,
133     LIBERO_SETTING_MSSIO_BANK2_IO_CFG_20_21_CR,
134     LIBERO_SETTING_MSSIO_BANK2_IO_CFG_22_23_CR
135 };
136 
137 #ifdef LIBERO_SETTING_ALT_IOMUX1_CR
138 MSSIO_BANK2_CONFIG mssio_alt_bank2_io_config = {
139     /* LIBERO_SETTING_mssio_bank4_io_cfg_0_cr
140         x_vddi Ratio Rx<0-2> == 001
141         drv<3-6> == 1111
142         7:clamp   == 0
143         enhyst   == 0
144         lockdn_en == 1
145         10:wpd  == 0
146         atp_en`== 0
147         lpmd_ibuf  == 0
148         lpmd_obuf == 0
149         persist == 0
150         */
151     LIBERO_SETTING_ALT_MSSIO_BANK2_IO_CFG_0_1_CR,
152     LIBERO_SETTING_ALT_MSSIO_BANK2_IO_CFG_2_3_CR,
153     LIBERO_SETTING_ALT_MSSIO_BANK2_IO_CFG_4_5_CR,
154     LIBERO_SETTING_ALT_MSSIO_BANK2_IO_CFG_6_7_CR,
155     LIBERO_SETTING_ALT_MSSIO_BANK2_IO_CFG_8_9_CR,
156     LIBERO_SETTING_ALT_MSSIO_BANK2_IO_CFG_10_11_CR,
157     LIBERO_SETTING_ALT_MSSIO_BANK2_IO_CFG_12_13_CR,
158     LIBERO_SETTING_ALT_MSSIO_BANK2_IO_CFG_14_15_CR,
159     LIBERO_SETTING_ALT_MSSIO_BANK2_IO_CFG_16_17_CR,
160     LIBERO_SETTING_ALT_MSSIO_BANK2_IO_CFG_18_19_CR,
161     LIBERO_SETTING_ALT_MSSIO_BANK2_IO_CFG_20_21_CR,
162     LIBERO_SETTING_ALT_MSSIO_BANK2_IO_CFG_22_23_CR
163 };
164 #endif
165 
166 /*******************************************************************************
167  * Local functions
168  */
169 static uint8_t io_mux_and_bank_config(void);
170 
171 /***************************************************************************//**
172  *    MSSIO OFF Mode
173  *
174  *    The following settings are applied if MMSIO unused/off
175  *
176  *      The IO Buffers are disabled.
177  *      Output drivers are disabled (set the drv<3:0> bits to 0000, output
178  *      enable "mss_oe" bit to 0)
179  *      Disable the WPU bit set to 0 and enable the WPD bit set to 1.
180  *      Receivers are disabled. (Ibufmd<2:0> set to 7)
181  *
182  *      MSS can enable OFF mode through configurator bit for selective MSSIO
183  *      from Bank2/Bank4 by making drv<3:0>/mss_oe bit to "0" for that
184  *      particular MSSIO making Output driver disabled and ibufmd <2:0>  bit to
185  *      "7" for that particular MSSIO making input receiver disabled.
186  *
187  */
188 
189 /***************************************************************************//**
190  * mssio_setup()
191  *
192  * Setup the IOMUX and IO bank 2 and 4.
193  *
194  * To setup bank 2 and 4, ncode and pcode scb registers in system
195  * register block are set as per Libero supplied values.
196  * These need to be transferred to I/0
197  *
198  * @return 0 => pass
199  */
mssio_setup(void)200 uint8_t mssio_setup(void)
201 {
202     uint8_t ret_status = 0U;
203     ret_status = io_mux_and_bank_config();
204     set_bank2_and_bank4_volts(DEFAULT_MSSIO_CONFIGURATION);
205     return (ret_status);
206 }
207 
208 /***************************************************************************//**
209  * io_mux_and_bank_config(void)
210  * sets up the IOMUX and bank 2 and 4 pcodes and n codes
211  * @return 0 => OK
212  */
io_mux_and_bank_config(void)213 static uint8_t io_mux_and_bank_config(void)
214 {
215     /* Configure IO mux's
216      *
217      * IOMUX1_CR - IOMUX5_CR, five 32-bit registers, with four bits four bits
218      * for each I/O determine what is connected to each pad
219      *
220      * All internal peripherals are also connected to the fabric (apart from
221      * MMC/SDIO/GPIO/USB). The IOMUX0 register configures whether the IO
222      * function is connected to the fabric or the IOMUX.
223      *
224      * IOMUX6_CR Sets whether the MMC/SD Voltage select lines are inverted on
225      * entry to the IOMUX structure
226      *
227      * */
228     config_32_copy((void *)(&(SYSREG->IOMUX0_CR)),
229                 &(iomux_config_values),
230                 sizeof(IOMUX_CONFIG));
231 
232     /*
233      * Configure MSS IO banks
234      *    sets pcode and ncode using (mssio_bank2_cfg_cr/mssio_bank4_cfg_cr)
235      *
236      * The MSS IO pad configuration is provided by nineteen system registers
237      * each configuring two IO's using 15-bits per IO
238      * - (mssio_bank*_io_cfg_*_*_cr).
239 
240         | mssio_bank*_io_cfg_*_*_cr | offset        | info |
241         | field                     | offset        | info |
242         |:-------------------------:|:-------------:|:-----|
243         |      io_cfg_ibufmd_0      |0              |      |
244         |      io_cfg_ibufmd_1      |1              |      |
245         |      io_cfg_ibufmd_2      |2              |      |
246         |      io_cfg_drv_0         |3              |      |
247         |      Io_cfg_drv_1         |4              |      |
248         |      Io_cfg_drv_2         |5              |      |
249         |      io_cfg_drv_3         |6              |      |
250         |      io_cfg_clamp         |7              |      |
251         |      io_cfg_enhyst        |8              |      |
252         |      io_cfg_lockdn_en     |9              |      |
253         |      io_cfg_wpd           |10             |      |
254         |      io_cfg_wpu           |11             |      |
255         |      io_cfg_atp_en        |12             |      |
256         |      io_cfg_lp_persist_en |13             |      |
257         |      io_cfg_lp_bypass_en  |14             |      |
258      * */
259 
260     config_32_copy((void *)(&(SYSREG->MSSIO_BANK4_IO_CFG_0_1_CR)),
261                 &(mssio_bank4_io_config),
262                 sizeof(MSSIO_BANK4_CONFIG));
263 
264     config_32_copy((void *)(&(SYSREG->MSSIO_BANK2_IO_CFG_0_1_CR)),
265                 &(mssio_bank2_io_config),
266                 sizeof(MSSIO_BANK2_CONFIG));
267 
268     set_bank2_and_bank4_volts(DEFAULT_MSSIO_CONFIGURATION);
269 
270     return(0L);
271 }
272 
273 /***************************************************************************//**
274  * io_mux_and_bank_config_alt(void)
275  * Configures alt setting
276  * @return
277  */
278 #ifdef LIBERO_SETTING_ALT_IOMUX1_CR
279 #if ((LIBERO_SETTING_MSSIO_CONFIGURATION_OPTIONS & (EMMC_CONFIGURED_MASK | SD_CONFIGURED_MASK)) == (EMMC_CONFIGURED_MASK | SD_CONFIGURED_MASK))
io_mux_and_bank_config_alt(void)280 static uint8_t io_mux_and_bank_config_alt(void)
281 {
282     /* Configure IO mux's
283      *
284      * IOMUX1_CR - IOMUX5_CR, five 32-bit registers, with four bits four bits
285      * for each I/O determine what is connected to each pad
286      *
287      * All internal peripherals are also connected to the fabric (apart from
288      * MMC/SDIO/GPIO/USB). The IOMUX0 register configures whether the IO
289      * function is connected to the fabric or the IOMUX.
290      *
291      * IOMUX6_CR Sets whether the MMC/SD Voltage select lines are inverted on
292      * entry to the IOMUX structure
293      *
294      * */
295 
296     config_32_copy((void *)(&(SYSREG->IOMUX0_CR)),
297                 &(iomux_alt_config_values),
298                 sizeof(IOMUX_CONFIG));
299 
300     /*
301      * Configure MSS IO banks
302      *    sets pcode and ncode using (mssio_bank2_cfg_cr/mssio_bank4_cfg_cr)
303      *
304      * The MSS IO pad configuration is provided by nineteen system registers
305      * each configuring two IO's using 15-bits per IO
306      * - (mssio_bank*_io_cfg_*_*_cr).
307 
308         | mssio_bank*_io_cfg_*_*_cr | offset        | info |
309         | field                     | offset        | info |
310         |:-------------------------:|:-------------:|:-----|
311         |      io_cfg_ibufmd_0      |0              |      |
312         |      io_cfg_ibufmd_1      |1              |      |
313         |      io_cfg_ibufmd_2      |2              |      |
314         |      io_cfg_drv_0         |3              |      |
315         |      Io_cfg_drv_1         |4              |      |
316         |      Io_cfg_drv_2         |5              |      |
317         |      io_cfg_drv_3         |6              |      |
318         |      io_cfg_clamp         |7              |      |
319         |      io_cfg_enhyst        |8              |      |
320         |      io_cfg_lockdn_en     |9              |      |
321         |      io_cfg_wpd           |10             |      |
322         |      io_cfg_wpu           |11             |      |
323         |      io_cfg_atp_en        |12             |      |
324         |      io_cfg_lp_persist_en |13             |      |
325         |      io_cfg_lp_bypass_en  |14             |      |
326      * */
327 
328     config_32_copy((void *)(&(SYSREG->MSSIO_BANK4_IO_CFG_0_1_CR)),
329                 &(mssio_alt_bank4_io_config),
330                 sizeof(MSSIO_BANK4_CONFIG));
331 
332     config_32_copy((void *)(&(SYSREG->MSSIO_BANK2_IO_CFG_0_1_CR)),
333                 &(mssio_alt_bank2_io_config),
334                 sizeof(MSSIO_BANK2_CONFIG));
335 
336     set_bank2_and_bank4_volts(DEFAULT_MSSIO_CONFIGURATION);
337 
338     return(0L);
339 }
340 #endif
341 #endif
342 
343 /**
344  * set_bank2_and_bank4_volts(void)
345  * sets bank voltage parameters
346  *   bank_pcode
347  *   bank_ncode
348  *   vs
349  * @return
350  */
set_bank2_and_bank4_volts(MSSIO_CONFIG_OPTION config)351 void set_bank2_and_bank4_volts(MSSIO_CONFIG_OPTION config)
352 {
353 
354     switch(config)
355     {
356         default:
357         SCB_REGS->MSSIO_BANK2_CFG_CR.MSSIO_BANK2_CFG_CR =\
358                     (uint32_t)LIBERO_SETTING_MSSIO_BANK2_CFG_CR;
359         SCB_REGS->MSSIO_BANK4_CFG_CR.MSSIO_BANK4_CFG_CR =\
360                     (uint32_t)LIBERO_SETTING_MSSIO_BANK4_CFG_CR;
361         break;
362 
363 #ifdef LIBERO_SETTING_MSSIO_CONFIGURATION_OPTIONS
364         case ALT_MSSIO_CONFIGURATION:
365             break;
366 #endif
367 
368     }
369     return;
370 }
371 
372 /***************************************************************************//**
373  * alternate_io_configured()
374  * Answers question is alternate I/O configuration present
375  * @return true/false
376  */
mss_is_alternate_io_configured(void)377 uint8_t  mss_is_alternate_io_configured(void)
378 {
379     uint8_t result = false;
380 #ifdef LIBERO_SETTING_MSSIO_CONFIGURATION_OPTIONS
381     if ((LIBERO_SETTING_MSSIO_CONFIGURATION_OPTIONS & (EMMC_CONFIGURED_MASK | SD_CONFIGURED_MASK)) == (EMMC_CONFIGURED_MASK | SD_CONFIGURED_MASK))
382     {
383         result = true;
384     }
385 #endif
386     return result;
387 }
388 
389 /***************************************************************************//**
390  * alternate_io_setting_sd()
391  * Answers question is alternate setting SD?
392  * @return returns true if sd is alternate setting
393  */
mss_is_alternate_io_setting_sd(void)394 uint8_t  mss_is_alternate_io_setting_sd(void)
395 {
396     uint8_t result = false;
397 #ifdef LIBERO_SETTING_MSSIO_CONFIGURATION_OPTIONS
398     if ((LIBERO_SETTING_MSSIO_CONFIGURATION_OPTIONS & (EMMC_CONFIGURED_MASK | SD_CONFIGURED_MASK)) == (EMMC_CONFIGURED_MASK | SD_CONFIGURED_MASK))
399     {
400         if ((LIBERO_SETTING_MSSIO_CONFIGURATION_OPTIONS & DEFAULT_ON_START_MASK)!=DEFAULT_ON_START_MASK)
401         {
402             result = true;
403         }
404     }
405 #endif
406     return result;
407 }
408 
409 /***************************************************************************//**
410  * alternate_io_setting_sd()
411  * Answers question is alternate setting emmc?
412  * @return returns true if sd is alternate setting
413  */
mss_is_alternate_io_setting_emmc(void)414 uint8_t  mss_is_alternate_io_setting_emmc(void)
415 {
416     uint8_t result = false;
417 #ifdef LIBERO_SETTING_MSSIO_CONFIGURATION_OPTIONS
418     if ((LIBERO_SETTING_MSSIO_CONFIGURATION_OPTIONS & (EMMC_CONFIGURED_MASK | SD_CONFIGURED_MASK)) == (EMMC_CONFIGURED_MASK | SD_CONFIGURED_MASK))
419     {
420         if ((LIBERO_SETTING_MSSIO_CONFIGURATION_OPTIONS & DEFAULT_ON_START_MASK)==DEFAULT_ON_START_MASK)
421         {
422             result = true;
423         }
424     }
425 #endif
426     return result;
427 }
428 
429 /**
430  * Determines if MSSIO alt switch support in MSS configurator version
431  * Does not indicate if alternate has been configured.
432  * Indicates you can use the following to determine setup
433  *  mss_io_defaut_setting(void)
434  *  mss_is_alternate_io_configured(void)
435  *  mss_is_alternate_io_setting_emmc(void)
436  *  mss_is_alternate_io_setting_sd(void)
437  *
438  * @return return true/false
439  */
mss_does_xml_ver_support_switch(void)440 uint8_t  mss_does_xml_ver_support_switch(void)
441 {
442     uint8_t result = false;
443 #ifdef LIBERO_SETTING_HEADER_GENERATOR_VERSION_MAJOR
444     uint32_t header_ver = (LIBERO_SETTING_HEADER_GENERATOR_VERSION_MAJOR*100) + (LIBERO_SETTING_HEADER_GENERATOR_VERSION_MINOR*10) + LIBERO_SETTING_HEADER_GENERATOR_VERSION_PATCH;
445     uint32_t xml_ver = (LIBERO_SETTING_XML_VERSION_MAJOR*100) + (LIBERO_SETTING_XML_VERSION_MINOR*10) + LIBERO_SETTING_XML_VERSION_PATCH;
446 
447     if ((header_ver >= 64U) && (xml_ver >= 56U))
448     {
449         result = true;
450     }
451 #else
452     (void)result;
453 #endif
454     return result;
455 }
456 
457 
458 /**
459  * mss_io_default_setting(void)
460  * @return returns what is configured on default if mss configurator version supports this.
461  */
462 #ifdef LIBERO_SETTING_ALT_IOMUX1_CR
mss_io_default_setting(void)463 uint8_t  mss_io_default_setting(void)
464 {
465     uint8_t result;
466 
467     if  ( mss_does_xml_ver_support_switch() == false )
468     {
469         result = NO_SUPPORT_MSSIO_CONFIGURATION;
470     }
471     else
472     {
473 #ifdef LIBERO_SETTING_MSSIO_CONFIGURATION_OPTIONS
474 #if ((LIBERO_SETTING_MSSIO_CONFIGURATION_OPTIONS & (SD_CONFIGURED_MASK | DEFAULT_ON_START_MASK)) == (SD_CONFIGURED_MASK | DEFAULT_ON_START_MASK))
475 
476     result = SD_MSSIO_CONFIGURATION;
477 
478 #elif  ((LIBERO_SETTING_MSSIO_CONFIGURATION_OPTIONS & (EMMC_CONFIGURED_MASK | DEFAULT_ON_START_MASK)) == (EMMC_CONFIGURED_MASK))
479 
480     result = SD_MSSIO_CONFIGURATION;
481 #else
482     result = NOT_SETUP_MSSIO_CONFIGURATION;
483 #endif
484 #endif
485     }
486 
487     return(result);
488 }
489 #endif
490 
491 /**
492  * Set the MSSIO to a desired config
493  * @param option  SD or eMMC
494  * @return
495  */
switch_mssio_config(MSS_IO_OPTIONS option)496 uint8_t switch_mssio_config(MSS_IO_OPTIONS option)
497 {
498     uint8_t result = false;
499 #ifdef LIBERO_SETTING_MSSIO_CONFIGURATION_OPTIONS
500 #if ((LIBERO_SETTING_MSSIO_CONFIGURATION_OPTIONS & (EMMC_CONFIGURED_MASK | SD_CONFIGURED_MASK)) == (EMMC_CONFIGURED_MASK | SD_CONFIGURED_MASK))
501     switch(option)
502     {
503         case SD_MSSIO_CONFIGURATION:
504             if (mss_is_alternate_io_setting_sd() == true)
505             {
506                 io_mux_and_bank_config_alt();
507 
508             }
509             else
510             {
511                 io_mux_and_bank_config();
512             }
513             break;
514 
515         case EMMC_MSSIO_CONFIGURATION:
516             if (mss_is_alternate_io_setting_emmc() == true)
517             {
518                 io_mux_and_bank_config_alt();
519             }
520             else
521             {
522                 io_mux_and_bank_config();
523             }
524             break;
525 
526         case NO_SUPPORT_MSSIO_CONFIGURATION:
527             break;
528 
529         case NOT_SETUP_MSSIO_CONFIGURATION:
530             break;
531     }
532     result = true;
533 #else
534     (void)option;
535     result = false;
536 #endif
537 #endif
538     return result;
539 }
540 
541 /**
542  * switch_external_mux()
543  * Requires fpga switch hdl. This comes with reference icicle kit design.
544  * You will need to create your own or copy when creating your own fpga design
545  * along with an external mux in your board design if you wish to use SD/eMMC
546  * muxing in your hardware design.
547  * Please note this function will cause a hang if you do not have support
548  * for switching in your fpga design, nlu use if you have this support if your
549  * fabric design.
550  * @param option SD_MSSIO_CONFIGURATION/EMMC_MSSIO_CONFIGURATION
551  * @return
552  */
switch_external_mux(MSS_IO_OPTIONS option)553 __attribute__((weak)) uint8_t switch_external_mux(MSS_IO_OPTIONS option)
554 {
555     uint8_t result = false;
556 
557     volatile uint32_t *reg_pt = (uint32_t *)ICICLE_KIT_REF_DESIGN_FPGS_SWITCH_ADDRESS;
558     switch(option)
559     {
560         case SD_MSSIO_CONFIGURATION:
561             *reg_pt = 1UL;
562             break;
563 
564         case EMMC_MSSIO_CONFIGURATION:
565             *reg_pt = 0UL;
566             break;
567 
568         case NO_SUPPORT_MSSIO_CONFIGURATION:
569             break;
570 
571         case NOT_SETUP_MSSIO_CONFIGURATION:
572             break;
573     }
574     result = true;
575 
576     return result;
577 }
578 
579 
580 #ifdef EXAMPLE_MSSIO_APP_CODE
581 #include "drivers/mss_gpio/mss_gpio.h"
582 /**
583  *
584  * @return 0 => OK
585  */
gpio_toggle_test(void)586 int32_t gpio_toggle_test(void)
587 {
588     SYSREG->TEMP0 = 0x11111111;
589 
590     for (int l = 0 ; l < 14 ; l++)
591     {
592         for (int i = 0 ; i < 14 ; i++)
593         {
594             SYSREG->TEMP0 = 0x12345678;
595             MSS_GPIO_set_output(GPIO0_LO, i, 0x0);
596         }
597         for (int i = 0 ; i < 24 ; i++)
598         {
599             SYSREG->TEMP0 = 0x12345678;
600             MSS_GPIO_set_output(GPIO1_LO, i, 0x0);
601         }
602         SYSREG->TEMP0 = 0xFFFFFFFFUL;
603         for (int i = 0 ; i < 14 ; i++)
604         {
605             SYSREG->TEMP0 = 0x12345678;
606             MSS_GPIO_set_output(GPIO0_LO, i, 0x1);
607         }
608         for (int i = 0 ; i < 24 ; i++)
609         {
610             SYSREG->TEMP0 = 0x12345678;
611             MSS_GPIO_set_output(GPIO1_LO, i, 0x1);
612         }
613     }
614     return(0UL);
615 }
616 
617 
618 /**
619  *
620  * @return 0 => OK
621  */
gpio_set_config(void)622 int32_t gpio_set_config(void)
623 {
624     SYSREG->SOFT_RESET_CR &= ~((1U<<20U)|(1U<<21U)|(1U<<22U));
625     SYSREG->SUBBLK_CLOCK_CR |= ((1U<<20U)|(1U<<21U)|(1U<<22U));
626     MSS_GPIO_init(GPIO0_LO);
627     MSS_GPIO_init(GPIO1_LO);
628     for (int i = 0 ; i < 14 ; i++)
629     {
630         MSS_GPIO_config(GPIO0_LO, i, MSS_GPIO_OUTPUT_MODE);
631     }
632     for (int i = 0 ; i < 24 ; i++)
633     {
634         MSS_GPIO_config(GPIO1_LO, i, MSS_GPIO_OUTPUT_MODE);
635     }
636     return(0UL);
637 }
638 #endif
639 
640