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

ddr.c (14965B)


      1 
      2 /*
      3  * 
      4  * 
      5  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      6  * 
      7  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      8  */
      9 
     10 #include <appl/diag/system.h>
     11 #include <appl/diag/parse.h>
     12 #include <bcm/error.h>
     13 #include <sal/appl/sal.h>
     14 #include <sal/appl/config.h>
     15 #include <shared/bsl.h>
     16 #ifdef BCM_DDR3_SUPPORT
     17 #include <soc/shmoo_ddr40.h>
     18 #include <soc/phy/ddr40.h>
     19 #include <soc/shmoo_and28.h>
     20 #include <soc/phy/ddr34.h>
     21 #include <soc/saber2.h>
     22 
     23 char cmd_ddr_mem_write_usage[] = "\n"
     24 " DDRMemWrite ci<n> range=0xstart-[0xend] data=0xdata\n"
     25 " DDRMemWrite ci0,ci1 range=0x0\n"
     26 " DDRMemWrite ci2 range=0x0-0x100"
     27 "\n";
     28 
     29 cmd_result_t
     30 cmd_ddr_mem_write(int unit, args_t *a)
     31 {
     32     uint32 data_wr[8] = {0};
     33     uint32 data = 0;
     34     int ci = 0;
     35     int addr = 0;
     36     int bank = 0;
     37     int row = 0;
     38     int col = 0;
     39     int rv_stat = CMD_OK;
     40     cmd_result_t ret_code;
     41     char *c = NULL;
     42     char *range = NULL;
     43     char *lo = NULL;
     44     char *hi = NULL;
     45     soc_pbmp_t ci_pbm;
     46     parse_table_t pt;
     47     int start_addr;
     48     int end_addr;
     49     int i;
     50     int rv;
     51     int inc;
     52 
     53     if (((c = ARG_GET(a)) == NULL) || (parse_pbmp(unit, c, &ci_pbm) < 0)) {
     54         return CMD_USAGE;
     55     }  
     56 
     57     if((lo = range = ARG_GET(a)) != NULL) {
     58         if((hi = sal_strchr(range, '-')) != NULL) {
     59             hi++;
     60         } else {
     61             hi = lo;
     62         }
     63     } else {
     64         return CMD_USAGE;
     65     }
     66 
     67     if (ARG_CNT(a)) {
     68         parse_table_init(0,&pt);
     69         parse_table_add(&pt,"data",PQ_INT,
     70                         0, &data, NULL);
     71         parse_table_add(&pt,"inc",PQ_INT,
     72                         0, &inc, NULL);
     73         if (!parseEndOk(a,&pt,&ret_code)) {
     74             return ret_code;
     75         }
     76     } else {
     77         return CMD_USAGE;
     78     }
     79 
     80     if (diag_parse_range(lo,hi,&start_addr,&end_addr,0,1<<22)) {
     81         cli_out("Invalid range. Valid range is : 0 - 0x%x\n",(1<<22));
     82         return CMD_FAIL;
     83     }
     84 
     85     /* for now 32B of data will be same */
     86     for(i=0;i<8;i++) {
     87         if (inc) {
     88             data_wr[i] = data+i;
     89         } else {
     90             data_wr[i] = data;
     91         }
     92     }
     93 
     94     SOC_PBMP_ITER(ci_pbm,ci) {
     95         cli_out("Writing ci%d DDR %s ..\n",ci,lo);
     96         for (addr=start_addr; addr <= end_addr; addr++) {
     97             bank = (addr & 0x7);
     98             col  = (addr >> 3) & 0x3f;
     99             row  = (addr >> 9) & 0x7fff;
    100             /* for debug */
    101             cli_out("Writing to ci%d,bank[%d],row[0x%04x],cols[0x%03x - 0x%03x] 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
    102                     ci,bank,row,col,col+0xf,data_wr[0],data_wr[1],data_wr[2],data_wr[3],data_wr[4],data_wr[5],data_wr[6],data_wr[7]);
    103 
    104             rv = soc_ddr40_write(unit, ci, addr,
    105                                  data_wr[0],data_wr[1],data_wr[2],
    106                                  data_wr[3],data_wr[4],data_wr[5],
    107                                  data_wr[6],data_wr[7]);
    108             if (rv != BCM_E_NONE) {
    109                 rv_stat = CMD_FAIL;
    110             }
    111         }
    112     }
    113 
    114     return rv_stat;
    115 }
    116 
    117 char cmd_ddr_mem_read_usage[] = "\n"
    118 " DDRMemRead ci<n> range=0xstart-[0xend]\n"
    119 " DDRMemRead ci0,ci1 range=0x0\n"
    120 " DDRMemRead ci2 range=0x0-0x100"
    121 "\n";
    122 
    123 cmd_result_t
    124 cmd_ddr_mem_read(int unit, args_t *a)
    125 {
    126     uint32 data_rd[8] = {0};
    127     int ci = 0;
    128     int addr = 0;
    129     int bank = 0;
    130     int row = 0;
    131     int col = 0;
    132     int rv_stat = CMD_OK;
    133     char *c = NULL;
    134     char *range = NULL;
    135     char *lo = NULL;
    136     char *hi = NULL;
    137     soc_pbmp_t ci_pbm;
    138     int start_addr;
    139     int end_addr;
    140     int rv;
    141 
    142     if (((c = ARG_GET(a)) == NULL) || (parse_pbmp(unit, c, &ci_pbm) < 0)) {
    143         return CMD_USAGE;
    144     }  
    145 
    146     if((lo = range = ARG_GET(a)) != NULL) {
    147         if((hi = sal_strchr(range, '-')) != NULL) {
    148             hi++;
    149         } else {
    150             hi = lo;
    151         }
    152     } else {
    153         return CMD_USAGE;
    154     }
    155 
    156     if (diag_parse_range(lo,hi,&start_addr,&end_addr,0,1<<22)) {
    157         cli_out("Invalid range. Valid range is : 0 - 0x%x\n",(1<<22));
    158         return CMD_FAIL;
    159     }
    160 
    161     SOC_PBMP_ITER(ci_pbm,ci) {
    162         cli_out("Reading ci%d DDR %s ..\n",ci,lo);
    163         for (addr=start_addr; addr <= end_addr; addr++) {
    164             rv = soc_ddr40_read(unit, ci, addr,
    165                                 &data_rd[0],&data_rd[1],&data_rd[2],
    166                                 &data_rd[3],&data_rd[4],&data_rd[5],
    167                                 &data_rd[6],&data_rd[7]);
    168 
    169             if (rv == BCM_E_NONE) {
    170                 /* convert the dram addr to pla_addr, to show bank,row,col */
    171                 bank = (addr & 0x7);
    172                 col  = (addr >> 3) & 0x3f;
    173                 row  = (addr >> 9) & 0x7fff;
    174                 cli_out("ci%d,bank[%d],row[%d],col[0x%03x - 0x%03x] = 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
    175                         ci,bank,row,col,col+0xf,data_rd[0],data_rd[1],data_rd[2],data_rd[3],
    176                         data_rd[4],data_rd[5],data_rd[6],data_rd[7]);
    177             } else {
    178                 rv_stat = CMD_FAIL;
    179             }
    180         }
    181     }
    182     return rv_stat;
    183 }
    184 
    185 char cmd_ddr_phy_read_usage[] = "\n"
    186 " DDRPhyRead ci<n> [addr=<0xaddr>]\n"
    187 " eg. DDRPhyRead ci0\n"
    188 "     DDRPhyRead ci0,ci1 addr=0x0\n";
    189 
    190 
    191 cmd_result_t
    192 cmd_ddr_phy_read(int unit, args_t *a)
    193 {
    194     uint32 data[4] = {0};
    195     int addr,address = -1;
    196     int reg = 0;
    197     int ci = 0;
    198     char *c = NULL;
    199     soc_pbmp_t ci_pbm;
    200     parse_table_t pt;
    201     cmd_result_t rv;
    202 
    203     if (((c = ARG_GET(a)) == NULL) || (parse_pbmp(unit, c, &ci_pbm) < 0)) {
    204         return CMD_USAGE;
    205     }
    206 
    207     if (ARG_CNT(a) > 0) {
    208         parse_table_init(0,&pt);
    209         parse_table_add(&pt,"addr",PQ_INT,
    210                         (void *) (0), &address, NULL);
    211         if (!parseEndOk(a,&pt,&rv)) {
    212             return rv;
    213         }
    214     }
    215 
    216     SOC_PBMP_ITER(ci_pbm,ci) {
    217         addr = address;
    218         if (addr == -1) {
    219 #if defined(BCM_SABER2_SUPPORT)
    220             if(SOC_IS_SABER2(unit)) {
    221                 cli_out("CI%d ( Address not valid )\n",ci);
    222                 return CMD_USAGE;
    223             }
    224 #endif
    225             /* ADDR_CTL */
    226             cli_out("CI%d ( DDR40_PHY_ADDR_CTL )\n",ci);
    227             for (addr=DDR40_PHY_ADDR_CTL_MIN; addr <= DDR40_PHY_ADDR_CTL_MAX;) {
    228                 for (reg=0;reg<4 && addr <= DDR40_PHY_ADDR_CTL_MAX;reg++) {
    229                     if(soc_ddr40_phy_reg_ci_read(unit, ci, addr, &data[reg])) {
    230                         cli_out("failed to read phy register 0x%04x\n", addr);
    231                     }
    232                     cli_out("    0x%04x: 0x%08x ",addr,data[reg]); 
    233                     addr += 4;
    234                 }
    235                 cli_out("\n");
    236             }
    237 
    238             /* BYTE_LANE0 */
    239             cli_out("CI%d ( DDR40_PHY_BYTE_LANE0 )\n",ci);
    240             for (addr=DDR40_PHY_BYTE_LANE0_ADDR_MIN; addr <= DDR40_PHY_BYTE_LANE0_ADDR_MAX;) {
    241                 for (reg=0;reg<4 && addr <= DDR40_PHY_BYTE_LANE0_ADDR_MAX;reg++) {
    242                     if(soc_ddr40_phy_reg_ci_read(unit, ci, addr, &data[reg])) {
    243                         cli_out("failed to read phy register 0x%04x\n", addr);
    244                     }
    245                     cli_out("    0x%04x: 0x%08x ",addr,data[reg]); 
    246                     addr += 4;
    247                 }
    248                 cli_out("\n");
    249             }
    250 
    251             /* BYTE_LANE1 */
    252             cli_out("CI%d ( DDR40_PHY_BYTE_LANE1 )\n",ci);
    253             for (addr=DDR40_PHY_BYTE_LANE1_ADDR_MIN; addr <= DDR40_PHY_BYTE_LANE1_ADDR_MAX;) {
    254                 for (reg=0;reg<4 && addr <= DDR40_PHY_BYTE_LANE1_ADDR_MAX;reg++) {
    255                     if(soc_ddr40_phy_reg_ci_read(unit, ci, addr, &data[reg])) {
    256                         cli_out("failed to read phy register 0x%04x\n", addr);
    257                     }
    258                     cli_out("    0x%04x: 0x%08x ",addr,data[reg]); 
    259                     addr += 4;
    260                 }
    261                 cli_out("\n");
    262             }
    263         } else {
    264 #if defined(BCM_SABER2_SUPPORT)
    265             if(SOC_IS_SABER2(unit)) {
    266                 if(soc_and28_phy_reg_read(unit, ci, addr, &data[0])) {
    267                     cli_out("failed to read phy register 0x%04x\n", addr);
    268                     return CMD_FAIL;
    269                 }
    270                 cli_out("    0x%04x: 0x%08x\n",addr,data[0]); 
    271             } else
    272 #endif
    273             if(soc_ddr40_phy_reg_ci_read(unit, ci, addr, &data[0])) {
    274                 cli_out("failed to read phy register 0x%04x\n", addr);
    275             }
    276             cli_out("    0x%04x: 0x%08x\n",addr,data[0]); 
    277         }
    278     }
    279     return CMD_OK;
    280 }
    281 
    282 char cmd_ddr_phy_write_usage[] = "\n"
    283 " DDRPhyWrite ci<n> addr=<0xaddr> data=<0xdata>\n"
    284 " eg. DDRPhyWrite ci addr=0x0 data=0x55\n"
    285 "     DDRPhyWrite ci0,ci2 addr=0x240 data=0xaa\n";
    286 
    287 
    288 cmd_result_t
    289 cmd_ddr_phy_write(int unit, args_t *a)
    290 {
    291     uint32 data = 0;
    292     int ci = 0;
    293     int addr = 0;
    294     parse_table_t pt;
    295     cmd_result_t rv;
    296     char *c = NULL;
    297     soc_pbmp_t ci_pbm;
    298 
    299     if (((c = ARG_GET(a)) == NULL) || (parse_pbmp(unit, c, &ci_pbm) < 0)) {
    300         return CMD_USAGE;
    301     }  
    302 
    303     if (ARG_CNT(a) == 2) {
    304         parse_table_init(0,&pt);
    305         parse_table_add(&pt,"addr",PQ_INT,
    306                         (void *) (0), &addr, NULL);
    307         parse_table_add(&pt,"data",PQ_INT,
    308                         (void *) (0), &data, NULL);
    309         if (!parseEndOk(a,&pt,&rv)) {
    310             return rv;
    311         }
    312     } else {
    313         cli_out("Invalid number of args.\n");
    314         return CMD_USAGE;
    315     }
    316 
    317     SOC_PBMP_ITER(ci_pbm,ci) {
    318 #if defined(BCM_SABER2_SUPPORT)
    319             if(SOC_IS_SABER2(unit)) {
    320                 if(soc_and28_phy_reg_write(unit, ci, addr, data)) {
    321                     cli_out("Writing 0x%08x to ci:%d addr=0x%08x failed.\n",
    322                             data,ci,addr);
    323                     return CMD_FAIL;
    324                 }
    325             } else
    326 #endif
    327         if(soc_ddr40_phy_reg_ci_write(unit, ci, addr, data)) {
    328             cli_out("Writing 0x%08x to ci:%d addr=0x%08x failed.\n",
    329                     data,ci,addr);
    330             return CMD_FAIL;
    331         }
    332     }
    333     return CMD_OK;
    334 }
    335 
    336 char cmd_ddr_phy_tune_usage[] = "\n"  
    337 "  DDRPhyTune ci<n> \n"
    338 " eg.  DDRPhyTune ci \n"
    339 "      DDRPhyTune ci0,ci2\n";
    340 
    341 cmd_result_t
    342 cmd_ddr_phy_tune(int unit, args_t *a)
    343 {
    344     parse_table_t pt;
    345     cmd_result_t rv;
    346     char *c = NULL;
    347     soc_pbmp_t ci_pbm;
    348 
    349     int ci      = 0;
    350     int phyType = 0;
    351     int ctlType = 1;
    352     int stat    = 0;
    353     int plot    = 0;
    354     int save    = 0;
    355     int restore = 0;
    356 #if defined(BCM_SABER2_SUPPORT)
    357     int done = 0;
    358 #endif
    359 
    360     SOC_PBMP_CLEAR(ci_pbm);
    361 
    362     if (((c = ARG_GET(a)) == NULL) || (parse_pbmp(unit, c, &ci_pbm) < 0)) {
    363         return CMD_USAGE;
    364     }  
    365 
    366     if (ARG_CNT(a) > 0) {
    367         parse_table_init(0,&pt);
    368         parse_table_add(&pt,"CtlType",PQ_INT,
    369                         (void *) (1), &ctlType, NULL);
    370         parse_table_add(&pt,"PhyType",PQ_INT,
    371                         (void *) (0), &phyType, NULL);
    372         parse_table_add(&pt,"Stat",PQ_INT,
    373                         (void *) (0), &stat, NULL);
    374         parse_table_add(&pt, "Plot", PQ_BOOL|PQ_DFL,
    375                         0, &plot, NULL);
    376         parse_table_add(&pt, "SaveCfg", PQ_BOOL|PQ_DFL,
    377                         0, &save, NULL);
    378         parse_table_add(&pt, "RestoreCfg", PQ_BOOL|PQ_DFL,
    379                         0, &restore, NULL);
    380         if (!parseEndOk(a,&pt,&rv)) {
    381             return rv;
    382         }
    383     }
    384 
    385     SOC_PBMP_ITER(ci_pbm,ci) {
    386         if (restore) {
    387 #if defined(BCM_SABER2_SUPPORT)
    388             if(SOC_IS_SABER2(unit)) {
    389                 and28_shmoo_config_param_t config_param;
    390                 sal_memset(&config_param, 0, sizeof(config_param));
    391 
    392                 /* Saber2 has one PHY 32 bit(CI0 16 bit and CI1 16 bit) 
    393                  * shmoo code is written per PHY not per CI */
    394                 if (ci != 0){
    395                   cli_out(" Saber2 has 32 bit PHY hence shmoo is running on ci0\n");
    396                 }
    397                 if (done == 0) {
    398                   if (SOC_E_NONE == (soc_sb2_and28_dram_restorecfg(unit, &config_param))) {
    399                     if (soc_and28_shmoo_ctl(unit, 0, -1, 0,
    400                                             SHMOO_AND28_ACTION_RESTORE, &config_param)) {
    401                       cli_out(" RestoreCfg ci:%d failed\n", ci);
    402                       return CMD_FAIL;
    403                     }
    404                   }else
    405                   {
    406                     cli_out(" RestoreCfg ci:%d failed\n", ci);
    407                     return CMD_FAIL;
    408                   }
    409                   done++;
    410                 }
    411             } else  
    412 #endif
    413             {
    414                 if (soc_ddr40_shmoo_restorecfg(unit, ci)) {
    415                     cli_out(" RestoreCfg ci:%d failed\n", ci);
    416                     return CMD_FAIL;
    417                 }
    418             }
    419         } else {
    420 #if defined(BCM_SABER2_SUPPORT)
    421             if(SOC_IS_SABER2(unit)) {
    422                 and28_shmoo_config_param_t config_param;
    423                 sal_memset(&config_param, 0, sizeof(config_param));
    424                 
    425                 /* Saber2 has one PHY 32 bit(CI0 16 bit and CI1 16 bit) 
    426                  * shmoo code is written per PHY not per CI */
    427                 if (ci != 0){
    428                   cli_out(" Saber2 has 32 bit PHY hence shmoo is running on ci0\n");
    429                 }
    430                 if (done == 0) {
    431                   if (save) {
    432                     if (SOC_E_NONE == (soc_and28_shmoo_ctl(unit, 0, -1, 0,
    433                                                            SHMOO_AND28_ACTION_RUN_AND_SAVE, &config_param))){
    434                       if (soc_sb2_and28_dram_savecfg(unit, &config_param)) {
    435                         cli_out(" SaveCfg ci:%d failed\n", ci);
    436                         return CMD_FAIL;
    437                       }
    438                     }else
    439                     {
    440                       cli_out(" SaveCfg ci:%d failed\n", ci);
    441                       return CMD_FAIL;
    442                     }
    443                   }else
    444                   {
    445                     
    446                     if ((soc_and28_shmoo_ctl(unit, 0, -1, 0,
    447                                              SHMOO_AND28_ACTION_RUN, &config_param))){
    448                       cli_out(" ci:%d failed\n", ci);
    449                       return CMD_FAIL;
    450                     }
    451                   }
    452                   done++;
    453                 }
    454             } else 
    455 #endif
    456             {
    457                 if(soc_ddr40_shmoo_ctl(unit, ci, phyType, ctlType, stat , plot)) {
    458                     cli_out(" ci:%d failed\n", ci);
    459                     return CMD_FAIL;
    460                 }
    461                 if (save) {
    462                     if (soc_ddr40_shmoo_savecfg(unit, ci)) {
    463                         cli_out(" SaveCfg ci:%d failed\n", ci);
    464                     }
    465                 }
    466             }
    467         }
    468     }
    469     return CMD_OK;
    470 }
    471 
    472 cmd_result_t
    473 cmd_ddr_phy_init(int unit, args_t *a)
    474 {
    475 #ifdef BCM_SABER2_SUPPORT
    476     if (SOC_IS_SABER2(unit) && SOC_DDR3_NUM_MEMORIES(unit)) {
    477         return soc_sb2_and28_dram_init_reset(unit);
    478     }
    479 #endif
    480     return CMD_NOTIMPL;
    481 }
    482 #endif
    483