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

cmicm.c (17070B)


      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  * CMICm peripherals commands
      8  */
      9 
     10 #include <assert.h>
     11 #include <sal/core/libc.h>
     12 #include <bcm/error.h>
     13 #include <shared/bsl.h>
     14 #include <soc/types.h>
     15 #include <soc/mspi.h>
     16 #include <soc/cmicm.h>
     17 #include <shared/bsl.h>
     18 #include <appl/diag/shell.h>
     19 #include <appl/diag/system.h>
     20 #include "appl/diag/diag.h"
     21 
     22 #ifdef BCM_CMICM_SUPPORT
     23 
     24 #define CMICM_MSPI_BLOCK_SIZE 16
     25 
     26 
     27 char mspi_usage[] =
     28     "Usage :\n\t"
     29     "mspi [device = n] [CPHA=n][CPOL=n]\n\t"
     30     "mspi [device = n] [CPHA=n][CPOL=n] load <hexfile>\n\t"
     31     "mspi [device = n] [CPHA=n][CPOL=n] write <hexdata>\n\t"
     32     "mspi [device = n] [CPHA=n][CPOL=n] read <numbytes>\n\t"
     33     "mspi [device = n] [CPHA=n][CPOL=n] write <hexdata> read <numbytes>\n\t"
     34     "Optionally select a device and configres. The device number is specific to chip/board.\n\t"
     35     "<hexfile> is ASCII file, with hex bytes separated by white space\n";
     36 
     37 cmd_result_t
     38 mspi_cmd(int unit, args_t *a)
     39 {
     40     volatile cmd_result_t rv = CMD_OK;
     41     char *c , *filename;
     42     int dev,cpol, cpha, offset_size = 0;
     43     volatile int wbytes = 0, rbytes=0;
     44     int start_byte, num_wbytes, num_rbytes;
     45     uint8 wdata[256];
     46     uint8 rdata[256];
     47     parse_table_t pt;
     48 #ifndef NO_FILEIO
     49     char    input[256];
     50 #ifndef NO_CTRL_C
     51     jmp_buf ctrl_c;
     52 #endif
     53     FILE * volatile fp = NULL;
     54 #endif
     55 
     56     if (!sh_check_attached("mspi", unit)) {
     57         return(CMD_FAIL);
     58     }
     59 
     60     if (!soc_feature(unit, soc_feature_cmicm)) {
     61         return(CMD_FAIL);
     62     }
     63 
     64     if (ARG_CNT(a) == 0) {
     65         return CMD_USAGE;
     66     }
     67 
     68     sal_memset(rdata, 0, sizeof (rdata));
     69     dev=-1;
     70     cpol=-1;
     71     cpha=-1;
     72 
     73     parse_table_init(unit, &pt);
     74     parse_table_add(&pt, "Device",  PQ_DFL|PQ_INT,
     75                                  (void *)( 0), &dev, NULL);
     76     parse_table_add(&pt, "CPOL",  PQ_DFL|PQ_INT,
     77                                  (void *)( 0), &cpol, NULL);
     78     parse_table_add(&pt, "CPHA",  PQ_DFL|PQ_INT,
     79                                 (void *)( 0), &cpha, NULL);
     80 
     81     if (parse_arg_eq(a, &pt) < 0) {
     82         cli_out("%s: Error: Unknown option: %s\n", ARG_CMD(a), ARG_CUR(a));
     83         parse_arg_eq_done(&pt);
     84         return(CMD_FAIL);
     85     }
     86     parse_arg_eq_done(&pt);
     87 
     88     if ((dev != -1) || (cpol != -1) || (cpha != -1)) {
     89         if (soc_mspi_config(unit, dev, cpol, cpha) != SOC_E_NONE){
     90             cli_out("MSPI: Failure Configuring\n");
     91             return CMD_FAIL;
     92         }
     93     }
     94 
     95     if (ARG_CNT(a) == 0) {
     96         return CMD_OK;
     97     }
     98 
     99      c = ARG_GET(a);
    100 
    101     if (!sal_strcasecmp(c, "load")) {
    102         c = ARG_GET(a);
    103         filename = c;
    104         if (filename == NULL) {
    105             cli_out("MSPI: %s: Error: No file specified\n", ARG_CMD(a));
    106             return(CMD_USAGE);
    107         }
    108 #ifdef NO_FILEIO
    109         cli_out("no filesystem\n");
    110         rv = CMD_FAIL;
    111 #else
    112 #ifndef NO_CTRL_C
    113         if (!setjmp(ctrl_c)) {
    114             sh_push_ctrl_c(&ctrl_c);
    115 #endif            
    116             fp = sal_fopen(filename, "r");
    117             if (!fp) {
    118                 cli_out("MSPI: %s: Error: Unable to open file: %s\n",
    119                         ARG_CMD(a), filename);
    120                 rv = CMD_FAIL;
    121             } else {
    122                 while ((rv == CMD_OK) && (c = sal_fgets(input, sizeof(input) - 1, fp))) {
    123                     while (*c) {
    124                         if (isspace((unsigned)(*c))) { /* Skip whitespace */
    125                             c++;
    126                         } else {
    127                             if (!isxdigit((unsigned)*c) ||
    128                                 !isxdigit((unsigned)*(c+1))) {
    129                                 cli_out("MSPI: %s: Invalid character\n", ARG_CMD(a));
    130                                 rv = CMD_FAIL;
    131                                 break;
    132                             }
    133                             offset_size = sizeof(wdata);
    134                             if (wbytes >= offset_size) {
    135                                 cli_out("MSPI: %s: Data memory exceeded\n", ARG_CMD(a));
    136                                 rv = CMD_FAIL;
    137                                 break;
    138                             }
    139                             wdata[wbytes++] = (xdigit2i(*c) << 4) | xdigit2i(*(c + 1));
    140                             c += 2;
    141                         }
    142                     }
    143                 }
    144                 sal_fclose((FILE *)fp);
    145                 fp = NULL;
    146             }
    147 #ifndef NO_CTRL_C
    148         } else if (fp) {
    149             sal_fclose((FILE *)fp);
    150             fp = NULL;
    151             rv = CMD_INTR;
    152         }
    153 #endif        
    154 
    155         sh_pop_ctrl_c();
    156 #endif /* NO_FILEIO */
    157 
    158         if (rv != CMD_OK) {
    159             return rv;
    160         }
    161         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    162                     (BSL_META_U(unit,
    163                                 "MSPI: Writing %d bytes from file %s\n"), wbytes, filename));
    164         for(start_byte=0; start_byte < wbytes; start_byte+=CMICM_MSPI_BLOCK_SIZE) {
    165             num_wbytes = ((start_byte + CMICM_MSPI_BLOCK_SIZE) > wbytes) ?
    166                         (wbytes - start_byte) : CMICM_MSPI_BLOCK_SIZE;
    167             if (soc_mspi_write8(unit, (uint8 *) &wdata[start_byte], num_wbytes) != SOC_E_NONE) {
    168                 cli_out("MSPI: Write Fail\n");
    169                 return CMD_FAIL;
    170             }
    171         }
    172         return rv;
    173     }
    174 
    175     if (sal_strcasecmp(c, "write") &&
    176         sal_strcasecmp(c, "read")) {
    177         cli_out("Neither Write Nor Read\n");
    178         return CMD_USAGE;
    179     }
    180 
    181     if (!sal_strcasecmp(c, "write")) {
    182         while ((c = ARG_GET(a)) != NULL) {
    183             if (!sal_strcasecmp(c, "read")) {
    184                 break;
    185             }
    186             while (*c) {
    187                 if (isspace((int)(*c))) {
    188                     c++;
    189                 } else {
    190                     if (!isxdigit((unsigned)*c) ||
    191                         !isxdigit((unsigned)*(c+1))) {
    192                         cli_out("MSPI: %s: Invalid character\n", ARG_CMD(a));
    193                         return(CMD_FAIL);
    194                     }
    195                     offset_size = sizeof(wdata);
    196                     if (wbytes >= offset_size) {
    197                         cli_out("MSPI: %s: Data memory exceeded\n", ARG_CMD(a));
    198                         return(CMD_FAIL);
    199                     }
    200                     wdata[wbytes++] = (xdigit2i(*c) << 4) | xdigit2i(*(c + 1));
    201                     c += 2;
    202                 }
    203             }
    204         }
    205     }
    206 
    207     if (c != NULL) {
    208         if (!sal_strcasecmp(c, "read")) {
    209             if (ARG_CNT(a) == 0) {
    210                 return CMD_USAGE;
    211             }
    212             c = ARG_GET(a);
    213             if (!isint(c)) {
    214                 return CMD_USAGE;
    215             }
    216             rbytes = parse_integer(c);
    217         }
    218     }
    219 
    220     if ((wbytes > 0) && (rbytes > 0)) { /* Write and read */
    221         if ((wbytes + rbytes) > CMICM_MSPI_BLOCK_SIZE) {
    222             cli_out("MSPI: Too many bytes for single Write-read operation\n");
    223             return(CMD_FAIL);
    224         }
    225         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    226                     (BSL_META_U(unit,
    227                                 "MSPI: Writing %d bytes and Reading %d bytes\n"),
    228                      wbytes, rbytes));
    229         if (soc_mspi_writeread8(unit, (uint8 *) &wdata[0], wbytes,(uint8 *) &rdata[0], rbytes) != SOC_E_NONE) {
    230             cli_out("MSPI: Write-Read Fail\n");
    231             return CMD_FAIL;
    232         }
    233     } else if (wbytes > 0){     /* Write Only */
    234         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    235                     (BSL_META_U(unit,
    236                                 "MSPI: Writing %d bytes\n"), wbytes));
    237         for(start_byte=0; start_byte < wbytes; start_byte+=CMICM_MSPI_BLOCK_SIZE) {
    238             num_wbytes = ((start_byte + CMICM_MSPI_BLOCK_SIZE) > wbytes) ?
    239                         (wbytes - start_byte) : CMICM_MSPI_BLOCK_SIZE;
    240             if (soc_mspi_write8(unit, (uint8 *) &wdata[start_byte], num_wbytes) != SOC_E_NONE) {
    241                 cli_out("MSPI: Write Fail\n");
    242                 return CMD_FAIL;
    243             }
    244         }
    245     } else if (rbytes > 0){     /* Read Only */
    246         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    247                     (BSL_META_U(unit,
    248                                 "MSPI: Reading %d bytes\n"), rbytes));
    249         for(start_byte=0; start_byte < rbytes; start_byte+=CMICM_MSPI_BLOCK_SIZE) {
    250             num_rbytes = ((start_byte + CMICM_MSPI_BLOCK_SIZE) > rbytes) ?
    251                         (rbytes - start_byte) : CMICM_MSPI_BLOCK_SIZE;
    252             if (soc_mspi_read8(unit, (uint8 *) &rdata[start_byte], num_rbytes) != SOC_E_NONE) {
    253                 cli_out("MSPI: Read Fail\n");
    254                 return CMD_FAIL;
    255             }
    256         }
    257     } else {
    258         return CMD_USAGE;
    259     }
    260 
    261     if (rbytes > 0) {
    262         /* Dump It */
    263         for(start_byte=0; start_byte < rbytes; start_byte++) {
    264             cli_out("%02x ", rdata[start_byte]);
    265             if ((start_byte % 8) == 7) {
    266                 cli_out("\n");
    267             }
    268         }
    269         cli_out("\n");
    270     }
    271 
    272     return rv;
    273 }
    274 
    275 char dpll_usage[] =
    276     "dpll [Config = n] [<Options>] write <addr> <data>\n\t"
    277     "dpll [Config = n] [<Options>] read <addr>\n\t"
    278     "\"Config\" overrides all the options with preset values\n"
    279 #ifndef COMPILER_STRING_CONST_LIMIT
    280     "\tTakes default <options> from \"dpll_params\" config variable if present\n"
    281     "\tOptions are the following, separated by space:\n\t"
    282     "  DevSel=n : Override Mux for DPLL Selection\n\t" 
    283     "  CPOL=0/1 : Clock Polarity\n\t"
    284     "  CPHA=0/1 : Clock Phase\n\t"
    285     "  AddrBitOrder=0/1 : 0 = MSB..LSB, 1 = LSB..MSB\n\t"
    286     "  DataBitOrder=0/1 : 0 = MSB..LSB, 1 = LSB..MSB\n\t"
    287     "  AddrWidth=1/2 : No of Bytes used for Addr\n\t"
    288     "  UseBrstBit-0/1 : Reserve Bit-0 of Addr as Burst Bit\n\t"
    289     "  UseRwBit=0/1 : Use MSBit (Bit-15 / Bit-7) of Addr as R/W' Bit\n"
    290 #endif
    291 ;
    292 
    293 cmd_result_t
    294 dpll_cmd(int unit, args_t *a)
    295 {
    296     volatile cmd_result_t rv = CMD_OK;
    297     char *c;
    298     uint32 addr, data, temp;
    299     int rd_op, i;
    300     int cfg=0, mux_sel = MSPI_DPLL;
    301     int cpol=-1, cpha=-1, addr_bit_order=0, data_bit_order=0;
    302     int addr_width=2, use_brst_bit=0, use_rw_bit=0;
    303     volatile int wbytes = 2, rbytes=1;
    304     uint8 wdata[16];
    305     uint8 rdata[16];
    306     int params[8];
    307     parse_table_t pt;
    308 
    309     int preset_configs[3][8] = {
    310     /* mux_sel,cpol,cpha,addr_bit_order,data_bit_order,addr_width,use_brst_bit,use_rw_bit */
    311         {2,0,1,0,0,2,1,1}, /* Maxim DPLL */
    312         {3,1,1,1,1,1,0,1}, /* IDT DPLL */
    313         {0,0,0,0,0,2,1,1}
    314     };
    315 
    316     if (!sh_check_attached("dpll", unit)) {
    317         return(CMD_FAIL);
    318     }
    319 
    320     if (!soc_feature(unit, soc_feature_cmicm)) {
    321         return(CMD_FAIL);
    322     }
    323 
    324     if (ARG_CNT(a) == 0) {
    325         return CMD_USAGE;
    326     }
    327 
    328     if (soc_property_get_csv(unit, spn_DPLL_PARAMS,8,params) == 8) {
    329         mux_sel = params[0];
    330         cpol = params[1];
    331         cpha = params[2];
    332         addr_bit_order = params[3];
    333         data_bit_order = params[4];
    334         addr_width = params[5];
    335         use_brst_bit = params[6];
    336         use_rw_bit = params[7];
    337     }
    338 
    339     sal_memset(rdata, 0, sizeof (rdata));
    340 
    341     parse_table_init(unit, &pt);
    342     parse_table_add(&pt, "Config",  PQ_DFL|PQ_INT,
    343                                 INT_TO_PTR( 0), &cfg, NULL);
    344     parse_table_add(&pt, "DevSel",  PQ_DFL|PQ_INT,
    345                                 INT_TO_PTR(mux_sel), &mux_sel, NULL);
    346     parse_table_add(&pt, "CPOL",  PQ_DFL|PQ_BOOL,
    347                                 INT_TO_PTR(cpol), &cpol, NULL);
    348     parse_table_add(&pt, "CPHA",  PQ_DFL|PQ_BOOL,
    349                                 INT_TO_PTR(cpha), &cpha, NULL);
    350     parse_table_add(&pt, "AddrBitOrder",  PQ_DFL|PQ_BOOL,
    351                                 INT_TO_PTR(addr_bit_order), &addr_bit_order, NULL);
    352     parse_table_add(&pt, "DataBitOrder",  PQ_DFL|PQ_BOOL,
    353                                 INT_TO_PTR(data_bit_order), &data_bit_order, NULL);
    354     parse_table_add(&pt, "AddrWidth",  PQ_DFL|PQ_INT,
    355                                 INT_TO_PTR(addr_width), &addr_width, NULL);
    356     parse_table_add(&pt, "UseBrstBit",  PQ_DFL|PQ_BOOL,
    357                                 INT_TO_PTR(use_brst_bit), &use_brst_bit, NULL);
    358     parse_table_add(&pt, "UseRwBit",  PQ_DFL|PQ_BOOL,
    359                                 INT_TO_PTR(use_rw_bit), &use_rw_bit, NULL);
    360 
    361     if (parse_arg_eq(a, &pt) < 0) {
    362         cli_out("%s: Error: Unknown option: %s\n", ARG_CMD(a), ARG_CUR(a));
    363         parse_arg_eq_done(&pt);
    364         return(CMD_FAIL);
    365     }
    366     parse_arg_eq_done(&pt);
    367 
    368     if (cfg > 0) {
    369          LOG_VERBOSE(BSL_LS_SOC_COMMON,
    370                      (BSL_META_U(unit,
    371                                  "Using Preset %d\n"), cfg));
    372         mux_sel = preset_configs[cfg-1][0];
    373         cpol = preset_configs[cfg-1][1];
    374         cpha = preset_configs[cfg-1][2];
    375         addr_bit_order = preset_configs[cfg-1][3];
    376         data_bit_order = preset_configs[cfg-1][4];
    377         addr_width = preset_configs[cfg-1][5];
    378         use_brst_bit = preset_configs[cfg-1][6];
    379         use_rw_bit = preset_configs[cfg-1][7];
    380     }
    381 
    382     if (soc_mspi_config(unit, mux_sel, cpol, cpha) != SOC_E_NONE){
    383         cli_out("MSPI: Failure Configuring\n");
    384         return CMD_FAIL;
    385     }
    386 
    387     if (ARG_CNT(a) == 0) {
    388         return CMD_OK;
    389     }
    390 
    391      c = ARG_GET(a);
    392 
    393     if (!sal_strcasecmp(c, "write")) {
    394         rd_op = 0;
    395         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    396                     (BSL_META_U(unit,
    397                                 "Write DPLL\n")));
    398     } else if (!sal_strcasecmp(c, "read")) {
    399         rd_op = 1;
    400         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    401                     (BSL_META_U(unit,
    402                                 "Read DPLL\n")));
    403     } else {
    404         return CMD_USAGE;
    405     }
    406 
    407     if (ARG_CNT(a) == 0) {
    408         return CMD_USAGE;
    409     }
    410     c = ARG_GET(a);
    411     if (!isint(c)) {
    412         return CMD_USAGE;
    413     }
    414     addr = parse_integer(c);
    415 
    416     if(addr_width == 1) {
    417         if (addr_bit_order) {
    418             temp = 0;
    419             for(i=0; i<8; i++) {
    420                 if (addr & (1<<i)) {
    421                     temp |= (1<<(7-i));
    422                 }
    423             } 
    424              temp  = (temp >> use_rw_bit);
    425              temp &= ((use_brst_bit) ? 0xfe : 0xff);
    426         } else {
    427             temp = addr;
    428             temp = (temp << use_brst_bit);
    429             temp &= ((use_rw_bit) ? 0x7f : 0xff);
    430         }
    431         if (use_rw_bit && rd_op) {
    432             temp |= 0x80;
    433         }
    434         wdata[0] = temp & 0xff;
    435         wbytes = 1;
    436     } else if (addr_width == 2) {
    437         if (addr_bit_order) {
    438             temp = 0;
    439             for(i=0; i<16; i++) {
    440                 if (addr & (1<<i)) {
    441                     temp |= (1<<(15-i));
    442                 }
    443             }
    444             temp  = (temp >> use_rw_bit);
    445             temp &= ((use_brst_bit) ? 0xfffe : 0xffff);
    446         } else {
    447             temp = addr;
    448             temp = (temp << use_brst_bit);
    449             temp &= ((use_rw_bit) ? 0x7fff : 0xffff);
    450         }
    451         if (use_rw_bit && rd_op) {
    452             temp |= 0x8000;
    453         }
    454         wdata[0] = (temp >> 8) & 0xff;
    455         wdata[1] = temp & 0xff;
    456         wbytes = 2;
    457     } else {
    458         cli_out("Only 1 or 2 byte addresses supported\n");
    459         return CMD_FAIL;
    460     }
    461 
    462     if(rd_op == 0) { /* Write */
    463         if (ARG_CNT(a) == 0) {
    464             return CMD_USAGE;
    465         }
    466         c = ARG_GET(a);
    467         if (!isint(c)) {
    468             return CMD_USAGE;
    469         }
    470         data = parse_integer(c);
    471         if (data_bit_order) {
    472             temp = 0;
    473             for(i=0; i<8; i++) {
    474                 if (data & (1<<i)) {
    475                     temp |= (1<<(7-i));
    476                 }
    477             }
    478             data = temp;
    479         }
    480         wdata[wbytes] = (data & 0xff);
    481         wbytes += 1;
    482         rbytes = 0;
    483         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    484                     (BSL_META_U(unit,
    485                                 "MSPI: Writing %d bytes\n"), wbytes));
    486         if (soc_mspi_write8(unit, (uint8 *) &wdata[0], wbytes) != SOC_E_NONE) {
    487             cli_out("MSPI: Write Fail\n");
    488             return CMD_FAIL;
    489         }
    490         /* Dump It */
    491         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    492                     (BSL_META_U(unit,
    493                                 "%02x\n"), data));
    494     } else { /* Read */
    495         rbytes = 1;
    496         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    497                     (BSL_META_U(unit,
    498                                 "MSPI: Writing %d bytes and Reading %d bytes\n"),
    499                      wbytes, rbytes));
    500         if (soc_mspi_writeread8(unit, (uint8 *) &wdata[0], wbytes,(uint8 *) &rdata[0], rbytes) != SOC_E_NONE) {
    501             cli_out("MSPI: Write-Read Fail\n");
    502             return CMD_FAIL;
    503         }
    504         data = rdata[0];
    505         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    506                     (BSL_META_U(unit,
    507                                 "Read %02x\n"), data));
    508 
    509         if (data_bit_order) {
    510             temp = 0;
    511             for(i=0; i<8; i++) {
    512                 if (data & (1<<i)) {
    513                     temp |= (1<<(7-i));
    514                 }
    515             }
    516             data = temp;
    517         }
    518         /* Dump It */
    519         cli_out("%02x\n", data);
    520     }
    521     return rv;
    522 }
    523 #endif