openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

qspi_flash_test.c (8854B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  */
      7 
      8 #include <appl/diag/test.h>
      9 #include <appl/diag/system.h>
     10 #include <sal/appl/io.h>
     11 #include <sal/compiler.h>
     12 #include <sal/core/thread.h>
     13 #include <sal/core/libc.h>
     14 #include <shared/bsl.h>
     15 #include "testlist.h"
     16 #include <soc/drv.h>
     17 #include <soc/mem.h>
     18 #include <soc/error.h>
     19 #include <soc/soc_flash.h>
     20 
     21 #ifdef BCM_CMICX_SUPPORT
     22 
     23 # define SPI_SPEED    62500000 /* BSPI */
     24 # define SPI_MODE     3 /* (CPOL|CPHA) */
     25 
     26 #define SWAP_ENDIAN(x) ( \
     27     (((x) << 24) & 0xff000000) | \
     28     (((x) <<  8) & 0x00ff0000) | \
     29     (((x) >>  8) & 0x0000ff00) | \
     30     (((x) >> 24) & 0x000000ff))
     31 
     32 soc_flash_conf_t testflash;
     33 
     34 char *qspi_flash_magic_str = "QSPI_FLASH";
     35 
     36 /* initialize the test */
     37 int qspi_flash_test_init(int u, args_t *a, void *p)
     38 {
     39     unsigned int speed = SPI_SPEED;
     40     unsigned int mode = SPI_MODE;
     41     soc_mem_test_t *parm = p;
     42     int rv = SOC_E_NONE;
     43     cli_out("qspi_flash_test_init...\n");
     44     parm->userdata = qspi_flash_magic_str;
     45     rv = soc_flash_init(u, speed, mode, &testflash);
     46     if (SOC_FAILURE(rv)) {
     47         cli_out("Error: QSPI flash init failed, speed = %u, mode =%u\n", speed, mode);
     48     }
     49     return rv;
     50 }
     51 
     52 static void fill_pattern(uint32 *buf, uint32 bufsize, uint32 pattern)
     53 {
     54     int i;
     55     int size = bufsize/4; /* Number of words to fill */
     56 
     57     for(i = 0; i < size; i++) {
     58         buf[i] = pattern;
     59     }
     60     return;
     61 }
     62 
     63 /* run the test */
     64 int qspi_flash_test_run(int u, args_t *a, void *p)
     65 {
     66     int rv = SOC_E_NONE;
     67     uint32 *wbuf = NULL;
     68     uint32 *rbuf = NULL;
     69     uint32 *sbuf = NULL;
     70     uint32 numsect = testflash.nr_sectors;
     71     uint32 sector, offset=0;
     72     uint32 startsect, endsect;
     73     soc_mem_test_t *parm = p;
     74 
     75     if(parm->index_end) {
     76         /* Boundary check */
     77         if((parm->index_start >= testflash.size) ||
     78            (parm->index_end >= testflash.size) ||
     79            (parm->index_end < parm->index_start)) {
     80            cli_out("IndexStart and IndexEnd not in flash boundaries 0 and 0x%zx\n", testflash.size);
     81            return(SOC_E_PARAM);
     82         }
     83         startsect = parm->index_start/testflash.sector_size;
     84         endsect = parm->index_end/testflash.sector_size;
     85     }
     86     else { /* default - test last 16 sectors */
     87         startsect = numsect - 16;
     88         endsect = numsect - 1;
     89     }
     90 
     91     cli_out("Max sectors in flash: %d, sectsize: 0x%zx\n", numsect, testflash.sector_size);
     92     cli_out("Testing sectors: %d to %d\n", startsect, endsect);
     93 
     94     wbuf = sal_alloc(testflash.sector_size, "FLASH_W");
     95     if (!wbuf) {
     96         cli_out("sal_alloc failed\n");
     97         rv = SOC_E_MEMORY;
     98         goto cleanup;
     99     }
    100 
    101     rbuf = sal_alloc(testflash.sector_size, "FLASH_R");
    102     if (!rbuf) {
    103         cli_out("sal_alloc failed\n");
    104         rv = SOC_E_MEMORY;
    105         goto cleanup;
    106     }
    107 
    108     sbuf = sal_alloc(testflash.sector_size, "FLASH_S");
    109     if (!sbuf) {
    110         cli_out("sal_alloc failed\n");
    111         rv = SOC_E_MEMORY;
    112         goto cleanup;
    113     }
    114 
    115     /* To retain  original content, we are going to test sectors
    116        only. We are not goig to erase whole flash,
    117        instead, erase sector wise, and recover that sector with
    118        original data after testing the sector */
    119 
    120     /* Test last 16 sectors to reduce the test time */
    121     for(sector = startsect; sector <= endsect; sector++) {
    122         offset = sector * testflash.sector_size;
    123         cli_out("Testing sector: %d, offset=0x%08x, size: 0x%08zx\n", sector, offset,
    124                                                           testflash.sector_size);
    125         /* Save sector data */
    126         rv = soc_flash_read(u, offset, testflash.sector_size, sbuf);
    127         if(rv != SOC_E_NONE) {
    128             cli_out("Flash read failed, sector: %d, size: 0x%08zx\n", sector,
    129                                                           testflash.sector_size);
    130             goto cleanup;
    131         }
    132 
    133         /* Sector erase and blank check */
    134         fill_pattern(wbuf, testflash.sector_size, 0);
    135 
    136         rv = soc_flash_erase(u,offset, testflash.sector_size);
    137         if(rv != SOC_E_NONE) {
    138             cli_out("Flash erase failed, sector: %d, size: 0x%08zx\n", sector,
    139                                                           testflash.sector_size);
    140             goto cleanup;
    141         }
    142 
    143         rv = soc_flash_write(u, offset, testflash.sector_size, wbuf);
    144         if(rv != SOC_E_NONE) {
    145             cli_out("Flash write failed, sector: %d, size: 0x%08zx\n", sector,
    146                                                           testflash.sector_size);
    147             goto restore;
    148         }
    149 
    150         rv = soc_flash_read(u, offset, testflash.sector_size, rbuf);
    151         if(rv != SOC_E_NONE) {
    152             cli_out("Flash read  failed, sector: %d, size: 0x%08zx\n", sector,
    153                                                           testflash.sector_size);
    154             goto restore;
    155         }
    156 
    157         rv = sal_memcmp(wbuf, rbuf,testflash.sector_size);
    158         if(rv != 0) {
    159             cli_out("Data integrity failed, sector: %d, size: 0x%08zx\n", sector,
    160                                                           testflash.sector_size);
    161             goto restore;
    162         }
    163 
    164         /* Walking 0 and 1 pattern */
    165         fill_pattern(wbuf, testflash.sector_size, 0x55555555);
    166         rv = soc_flash_erase(u,offset, testflash.sector_size);
    167         if(rv != SOC_E_NONE) {
    168             cli_out("Flash erase failed, sector: %d, size: 0x%08zx\n", sector,
    169                                                           testflash.sector_size);
    170             goto restore;
    171         }
    172         rv = soc_flash_write(u, offset, testflash.sector_size, wbuf);
    173         if(rv != SOC_E_NONE) {
    174             cli_out("Flash write failed, sector: %d, size: 0x%08zx\n", sector,
    175                                                           testflash.sector_size);
    176             goto restore;
    177         }
    178 
    179         rv = soc_flash_read(u, offset, testflash.sector_size, rbuf);
    180         if(rv != SOC_E_NONE) {
    181             cli_out("Flash read  failed, sector: %d, size: 0x%08zx\n", sector,
    182                                                           testflash.sector_size);
    183             goto restore;
    184         }
    185 
    186         rv = sal_memcmp(wbuf, rbuf,testflash.sector_size);
    187         if(rv != 0) {
    188             cli_out("Data integrity failed with walking 0s and 1s, sector: %d, size: 0x%08zx\n", sector,
    189                                                           testflash.sector_size);
    190             goto restore;
    191         }
    192 
    193 
    194         /* Walking 1 and 0 pattern */
    195         fill_pattern(wbuf, testflash.sector_size, 0xAAAAAAAA);
    196         rv = soc_flash_erase(u,offset, testflash.sector_size);
    197         if(rv != SOC_E_NONE) {
    198             cli_out("Flash erase failed, sector: %d, size: 0x%08zx\n", sector,
    199                                                           testflash.sector_size);
    200             goto restore;
    201         }
    202         rv = soc_flash_write(u, offset, testflash.sector_size, wbuf);
    203         if(rv != SOC_E_NONE) {
    204             cli_out("Flash write failed, sector: %d, size: 0x%08zx\n", sector,
    205                                                           testflash.sector_size);
    206             goto restore;
    207         }
    208 
    209         rv = soc_flash_read(u, offset, testflash.sector_size, rbuf);
    210         if(rv != SOC_E_NONE) {
    211             cli_out("Flash read  failed, sector: %d, size: 0x%08zx\n", sector,
    212                                                           testflash.sector_size);
    213             goto restore;
    214         }
    215 
    216         rv = sal_memcmp(wbuf, rbuf,testflash.sector_size);
    217         if(rv != 0) {
    218             cli_out("Data integrity failed with walking 1s and 0s, sector: %d, size: 0x%08zx\n", sector,
    219                                                           testflash.sector_size);
    220             goto restore;
    221         }
    222 
    223 restore:
    224         rv = soc_flash_erase(u,offset, testflash.sector_size);
    225         if(rv != SOC_E_NONE) {
    226             cli_out("Flash erase failed, sector: %d, size: 0x%08zx\n", sector,
    227                                                           testflash.sector_size);
    228             goto cleanup;
    229         }
    230 
    231         rv = soc_flash_write(u, offset, testflash.sector_size, sbuf);
    232         if(rv != SOC_E_NONE) {
    233             cli_out("Fatal: Flash restore failed, sector: %d, size: 0x%08zx\n", sector,
    234                                                           testflash.sector_size);
    235             goto cleanup;
    236         }
    237     } /* End for */
    238 cleanup:
    239     if(wbuf) sal_free(wbuf);
    240     if(rbuf) sal_free(rbuf);
    241     if(sbuf) sal_free(sbuf);
    242 
    243     return rv;
    244 }
    245 
    246 
    247 /* end the test */
    248 int qspi_flash_test_done(int u, void *p)
    249 {
    250     soc_mem_test_t *parm = p;
    251     parm->userdata = NULL;
    252 
    253     cli_out("QSPI flash test Done, please power cycle the system\n");
    254     return 0;
    255 }
    256 
    257 #endif /* BCM_CMICX_SUPPORT */