1*6281a769SCalvin Johnson /* 2*6281a769SCalvin Johnson * Copyright 2015-2016 Freescale Semiconductor, Inc. 3*6281a769SCalvin Johnson * Copyright 2017 NXP 4*6281a769SCalvin Johnson * 5*6281a769SCalvin Johnson * SPDX-License-Identifier: GPL-2.0+ 6*6281a769SCalvin Johnson */ 7*6281a769SCalvin Johnson 8*6281a769SCalvin Johnson /* 9*6281a769SCalvin Johnson * @file 10*6281a769SCalvin Johnson * @brief PFE utility commands 11*6281a769SCalvin Johnson */ 12*6281a769SCalvin Johnson 13*6281a769SCalvin Johnson #include <net/pfe_eth/pfe_eth.h> 14*6281a769SCalvin Johnson 15*6281a769SCalvin Johnson static inline void pfe_command_help(void) 16*6281a769SCalvin Johnson { 17*6281a769SCalvin Johnson printf("Usage: pfe [pe | status | expt ] <options>\n"); 18*6281a769SCalvin Johnson } 19*6281a769SCalvin Johnson 20*6281a769SCalvin Johnson static void pfe_command_pe(int argc, char * const argv[]) 21*6281a769SCalvin Johnson { 22*6281a769SCalvin Johnson if (argc >= 3 && strcmp(argv[2], "pmem") == 0) { 23*6281a769SCalvin Johnson if (argc >= 4 && strcmp(argv[3], "read") == 0) { 24*6281a769SCalvin Johnson int i; 25*6281a769SCalvin Johnson int num; 26*6281a769SCalvin Johnson int id; 27*6281a769SCalvin Johnson u32 addr; 28*6281a769SCalvin Johnson u32 size; 29*6281a769SCalvin Johnson u32 val; 30*6281a769SCalvin Johnson 31*6281a769SCalvin Johnson if (argc == 7) { 32*6281a769SCalvin Johnson num = simple_strtoul(argv[6], NULL, 0); 33*6281a769SCalvin Johnson } else if (argc == 6) { 34*6281a769SCalvin Johnson num = 1; 35*6281a769SCalvin Johnson } else { 36*6281a769SCalvin Johnson printf("Usage: pfe pe pmem read <id> <addr> [<num>]\n"); 37*6281a769SCalvin Johnson return; 38*6281a769SCalvin Johnson } 39*6281a769SCalvin Johnson 40*6281a769SCalvin Johnson id = simple_strtoul(argv[4], NULL, 0); 41*6281a769SCalvin Johnson addr = simple_strtoul(argv[5], NULL, 16); 42*6281a769SCalvin Johnson size = 4; 43*6281a769SCalvin Johnson 44*6281a769SCalvin Johnson for (i = 0; i < num; i++, addr += 4) { 45*6281a769SCalvin Johnson val = pe_pmem_read(id, addr, size); 46*6281a769SCalvin Johnson val = be32_to_cpu(val); 47*6281a769SCalvin Johnson if (!(i & 3)) 48*6281a769SCalvin Johnson printf("%08x: ", addr); 49*6281a769SCalvin Johnson printf("%08x%s", val, i == num - 1 || (i & 3) 50*6281a769SCalvin Johnson == 3 ? "\n" : " "); 51*6281a769SCalvin Johnson } 52*6281a769SCalvin Johnson 53*6281a769SCalvin Johnson } else { 54*6281a769SCalvin Johnson printf("Usage: pfe pe pmem read <parameters>\n"); 55*6281a769SCalvin Johnson } 56*6281a769SCalvin Johnson } else if (argc >= 3 && strcmp(argv[2], "dmem") == 0) { 57*6281a769SCalvin Johnson if (argc >= 4 && strcmp(argv[3], "read") == 0) { 58*6281a769SCalvin Johnson int i; 59*6281a769SCalvin Johnson int num; 60*6281a769SCalvin Johnson int id; 61*6281a769SCalvin Johnson u32 addr; 62*6281a769SCalvin Johnson u32 size; 63*6281a769SCalvin Johnson u32 val; 64*6281a769SCalvin Johnson 65*6281a769SCalvin Johnson if (argc == 7) { 66*6281a769SCalvin Johnson num = simple_strtoul(argv[6], NULL, 0); 67*6281a769SCalvin Johnson } else if (argc == 6) { 68*6281a769SCalvin Johnson num = 1; 69*6281a769SCalvin Johnson } else { 70*6281a769SCalvin Johnson printf("Usage: pfe pe dmem read <id> <addr> [<num>]\n"); 71*6281a769SCalvin Johnson return; 72*6281a769SCalvin Johnson } 73*6281a769SCalvin Johnson 74*6281a769SCalvin Johnson id = simple_strtoul(argv[4], NULL, 0); 75*6281a769SCalvin Johnson addr = simple_strtoul(argv[5], NULL, 16); 76*6281a769SCalvin Johnson size = 4; 77*6281a769SCalvin Johnson 78*6281a769SCalvin Johnson for (i = 0; i < num; i++, addr += 4) { 79*6281a769SCalvin Johnson val = pe_dmem_read(id, addr, size); 80*6281a769SCalvin Johnson val = be32_to_cpu(val); 81*6281a769SCalvin Johnson if (!(i & 3)) 82*6281a769SCalvin Johnson printf("%08x: ", addr); 83*6281a769SCalvin Johnson printf("%08x%s", val, i == num - 1 || (i & 3) 84*6281a769SCalvin Johnson == 3 ? "\n" : " "); 85*6281a769SCalvin Johnson } 86*6281a769SCalvin Johnson 87*6281a769SCalvin Johnson } else if (argc >= 4 && strcmp(argv[3], "write") == 0) { 88*6281a769SCalvin Johnson int id; 89*6281a769SCalvin Johnson u32 val; 90*6281a769SCalvin Johnson u32 addr; 91*6281a769SCalvin Johnson u32 size; 92*6281a769SCalvin Johnson 93*6281a769SCalvin Johnson if (argc != 7) { 94*6281a769SCalvin Johnson printf("Usage: pfe pe dmem write <id> <val> <addr>\n"); 95*6281a769SCalvin Johnson return; 96*6281a769SCalvin Johnson } 97*6281a769SCalvin Johnson 98*6281a769SCalvin Johnson id = simple_strtoul(argv[4], NULL, 0); 99*6281a769SCalvin Johnson val = simple_strtoul(argv[5], NULL, 16); 100*6281a769SCalvin Johnson val = cpu_to_be32(val); 101*6281a769SCalvin Johnson addr = simple_strtoul(argv[6], NULL, 16); 102*6281a769SCalvin Johnson size = 4; 103*6281a769SCalvin Johnson pe_dmem_write(id, val, addr, size); 104*6281a769SCalvin Johnson } else { 105*6281a769SCalvin Johnson printf("Usage: pfe pe dmem [read | write] <parameters>\n"); 106*6281a769SCalvin Johnson } 107*6281a769SCalvin Johnson } else if (argc >= 3 && strcmp(argv[2], "lmem") == 0) { 108*6281a769SCalvin Johnson if (argc >= 4 && strcmp(argv[3], "read") == 0) { 109*6281a769SCalvin Johnson int i; 110*6281a769SCalvin Johnson int num; 111*6281a769SCalvin Johnson u32 val; 112*6281a769SCalvin Johnson u32 offset; 113*6281a769SCalvin Johnson 114*6281a769SCalvin Johnson if (argc == 6) { 115*6281a769SCalvin Johnson num = simple_strtoul(argv[5], NULL, 0); 116*6281a769SCalvin Johnson } else if (argc == 5) { 117*6281a769SCalvin Johnson num = 1; 118*6281a769SCalvin Johnson } else { 119*6281a769SCalvin Johnson printf("Usage: pfe pe lmem read <offset> [<num>]\n"); 120*6281a769SCalvin Johnson return; 121*6281a769SCalvin Johnson } 122*6281a769SCalvin Johnson 123*6281a769SCalvin Johnson offset = simple_strtoul(argv[4], NULL, 16); 124*6281a769SCalvin Johnson 125*6281a769SCalvin Johnson for (i = 0; i < num; i++, offset += 4) { 126*6281a769SCalvin Johnson pe_lmem_read(&val, 4, offset); 127*6281a769SCalvin Johnson val = be32_to_cpu(val); 128*6281a769SCalvin Johnson printf("%08x%s", val, i == num - 1 || (i & 7) 129*6281a769SCalvin Johnson == 7 ? "\n" : " "); 130*6281a769SCalvin Johnson } 131*6281a769SCalvin Johnson 132*6281a769SCalvin Johnson } else if (argc >= 4 && strcmp(argv[3], "write") == 0) { 133*6281a769SCalvin Johnson u32 val; 134*6281a769SCalvin Johnson u32 offset; 135*6281a769SCalvin Johnson 136*6281a769SCalvin Johnson if (argc != 6) { 137*6281a769SCalvin Johnson printf("Usage: pfe pe lmem write <val> <offset>\n"); 138*6281a769SCalvin Johnson return; 139*6281a769SCalvin Johnson } 140*6281a769SCalvin Johnson 141*6281a769SCalvin Johnson val = simple_strtoul(argv[4], NULL, 16); 142*6281a769SCalvin Johnson val = cpu_to_be32(val); 143*6281a769SCalvin Johnson offset = simple_strtoul(argv[5], NULL, 16); 144*6281a769SCalvin Johnson pe_lmem_write(&val, 4, offset); 145*6281a769SCalvin Johnson } else { 146*6281a769SCalvin Johnson printf("Usage: pfe pe lmem [read | write] <parameters>\n"); 147*6281a769SCalvin Johnson } 148*6281a769SCalvin Johnson } else { 149*6281a769SCalvin Johnson if (strcmp(argv[2], "help") != 0) 150*6281a769SCalvin Johnson printf("Unknown option: %s\n", argv[2]); 151*6281a769SCalvin Johnson 152*6281a769SCalvin Johnson printf("Usage: pfe pe <parameters>\n"); 153*6281a769SCalvin Johnson } 154*6281a769SCalvin Johnson } 155*6281a769SCalvin Johnson 156*6281a769SCalvin Johnson #define NUM_QUEUES 16 157*6281a769SCalvin Johnson 158*6281a769SCalvin Johnson /* 159*6281a769SCalvin Johnson * qm_read_drop_stat 160*6281a769SCalvin Johnson * This function is used to read the drop statistics from the TMU 161*6281a769SCalvin Johnson * hw drop counter. Since the hw counter is always cleared afer 162*6281a769SCalvin Johnson * reading, this function maintains the previous drop count, and 163*6281a769SCalvin Johnson * adds the new value to it. That value can be retrieved by 164*6281a769SCalvin Johnson * passing a pointer to it with the total_drops arg. 165*6281a769SCalvin Johnson * 166*6281a769SCalvin Johnson * @param tmu TMU number (0 - 3) 167*6281a769SCalvin Johnson * @param queue queue number (0 - 15) 168*6281a769SCalvin Johnson * @param total_drops pointer to location to store total drops (or NULL) 169*6281a769SCalvin Johnson * @param do_reset if TRUE, clear total drops after updating 170*6281a769SCalvin Johnson * 171*6281a769SCalvin Johnson */ 172*6281a769SCalvin Johnson u32 qm_read_drop_stat(u32 tmu, u32 queue, u32 *total_drops, int do_reset) 173*6281a769SCalvin Johnson { 174*6281a769SCalvin Johnson static u32 qtotal[TMU_MAX_ID + 1][NUM_QUEUES]; 175*6281a769SCalvin Johnson u32 val; 176*6281a769SCalvin Johnson 177*6281a769SCalvin Johnson writel((tmu << 8) | queue, TMU_TEQ_CTRL); 178*6281a769SCalvin Johnson writel((tmu << 8) | queue, TMU_LLM_CTRL); 179*6281a769SCalvin Johnson val = readl(TMU_TEQ_DROP_STAT); 180*6281a769SCalvin Johnson qtotal[tmu][queue] += val; 181*6281a769SCalvin Johnson if (total_drops) 182*6281a769SCalvin Johnson *total_drops = qtotal[tmu][queue]; 183*6281a769SCalvin Johnson if (do_reset) 184*6281a769SCalvin Johnson qtotal[tmu][queue] = 0; 185*6281a769SCalvin Johnson return val; 186*6281a769SCalvin Johnson } 187*6281a769SCalvin Johnson 188*6281a769SCalvin Johnson static ssize_t tmu_queue_stats(char *buf, int tmu, int queue) 189*6281a769SCalvin Johnson { 190*6281a769SCalvin Johnson ssize_t len = 0; 191*6281a769SCalvin Johnson u32 drops; 192*6281a769SCalvin Johnson 193*6281a769SCalvin Johnson printf("%d-%02d, ", tmu, queue); 194*6281a769SCalvin Johnson 195*6281a769SCalvin Johnson drops = qm_read_drop_stat(tmu, queue, NULL, 0); 196*6281a769SCalvin Johnson 197*6281a769SCalvin Johnson /* Select queue */ 198*6281a769SCalvin Johnson writel((tmu << 8) | queue, TMU_TEQ_CTRL); 199*6281a769SCalvin Johnson writel((tmu << 8) | queue, TMU_LLM_CTRL); 200*6281a769SCalvin Johnson 201*6281a769SCalvin Johnson printf("(teq) drop: %10u, tx: %10u (llm) head: %08x, tail: %08x, drop: %10u\n", 202*6281a769SCalvin Johnson drops, readl(TMU_TEQ_TRANS_STAT), 203*6281a769SCalvin Johnson readl(TMU_LLM_QUE_HEADPTR), readl(TMU_LLM_QUE_TAILPTR), 204*6281a769SCalvin Johnson readl(TMU_LLM_QUE_DROPCNT)); 205*6281a769SCalvin Johnson 206*6281a769SCalvin Johnson return len; 207*6281a769SCalvin Johnson } 208*6281a769SCalvin Johnson 209*6281a769SCalvin Johnson static ssize_t tmu_queues(char *buf, int tmu) 210*6281a769SCalvin Johnson { 211*6281a769SCalvin Johnson ssize_t len = 0; 212*6281a769SCalvin Johnson int queue; 213*6281a769SCalvin Johnson 214*6281a769SCalvin Johnson for (queue = 0; queue < 16; queue++) 215*6281a769SCalvin Johnson len += tmu_queue_stats(buf + len, tmu, queue); 216*6281a769SCalvin Johnson 217*6281a769SCalvin Johnson return len; 218*6281a769SCalvin Johnson } 219*6281a769SCalvin Johnson 220*6281a769SCalvin Johnson static inline void hif_status(void) 221*6281a769SCalvin Johnson { 222*6281a769SCalvin Johnson printf("hif:\n"); 223*6281a769SCalvin Johnson 224*6281a769SCalvin Johnson printf(" tx curr bd: %x\n", readl(HIF_TX_CURR_BD_ADDR)); 225*6281a769SCalvin Johnson printf(" tx status: %x\n", readl(HIF_TX_STATUS)); 226*6281a769SCalvin Johnson printf(" tx dma status: %x\n", readl(HIF_TX_DMA_STATUS)); 227*6281a769SCalvin Johnson 228*6281a769SCalvin Johnson printf(" rx curr bd: %x\n", readl(HIF_RX_CURR_BD_ADDR)); 229*6281a769SCalvin Johnson printf(" rx status: %x\n", readl(HIF_RX_STATUS)); 230*6281a769SCalvin Johnson printf(" rx dma status: %x\n", readl(HIF_RX_DMA_STATUS)); 231*6281a769SCalvin Johnson 232*6281a769SCalvin Johnson printf("hif nocopy:\n"); 233*6281a769SCalvin Johnson 234*6281a769SCalvin Johnson printf(" tx curr bd: %x\n", readl(HIF_NOCPY_TX_CURR_BD_ADDR)); 235*6281a769SCalvin Johnson printf(" tx status: %x\n", readl(HIF_NOCPY_TX_STATUS)); 236*6281a769SCalvin Johnson printf(" tx dma status: %x\n", readl(HIF_NOCPY_TX_DMA_STATUS)); 237*6281a769SCalvin Johnson 238*6281a769SCalvin Johnson printf(" rx curr bd: %x\n", readl(HIF_NOCPY_RX_CURR_BD_ADDR)); 239*6281a769SCalvin Johnson printf(" rx status: %x\n", readl(HIF_NOCPY_RX_STATUS)); 240*6281a769SCalvin Johnson printf(" rx dma status: %x\n", readl(HIF_NOCPY_RX_DMA_STATUS)); 241*6281a769SCalvin Johnson } 242*6281a769SCalvin Johnson 243*6281a769SCalvin Johnson static void gpi(int id, void *base) 244*6281a769SCalvin Johnson { 245*6281a769SCalvin Johnson u32 val; 246*6281a769SCalvin Johnson 247*6281a769SCalvin Johnson printf("%s%d:\n", __func__, id); 248*6281a769SCalvin Johnson 249*6281a769SCalvin Johnson printf(" tx under stick: %x\n", readl(base + GPI_FIFO_STATUS)); 250*6281a769SCalvin Johnson val = readl(base + GPI_FIFO_DEBUG); 251*6281a769SCalvin Johnson printf(" tx pkts: %x\n", (val >> 23) & 0x3f); 252*6281a769SCalvin Johnson printf(" rx pkts: %x\n", (val >> 18) & 0x3f); 253*6281a769SCalvin Johnson printf(" tx bytes: %x\n", (val >> 9) & 0x1ff); 254*6281a769SCalvin Johnson printf(" rx bytes: %x\n", (val >> 0) & 0x1ff); 255*6281a769SCalvin Johnson printf(" overrun: %x\n", readl(base + GPI_OVERRUN_DROPCNT)); 256*6281a769SCalvin Johnson } 257*6281a769SCalvin Johnson 258*6281a769SCalvin Johnson static void bmu(int id, void *base) 259*6281a769SCalvin Johnson { 260*6281a769SCalvin Johnson printf("%s%d:\n", __func__, id); 261*6281a769SCalvin Johnson 262*6281a769SCalvin Johnson printf(" buf size: %x\n", (1 << readl(base + BMU_BUF_SIZE))); 263*6281a769SCalvin Johnson printf(" buf count: %x\n", readl(base + BMU_BUF_CNT)); 264*6281a769SCalvin Johnson printf(" buf rem: %x\n", readl(base + BMU_REM_BUF_CNT)); 265*6281a769SCalvin Johnson printf(" buf curr: %x\n", readl(base + BMU_CURR_BUF_CNT)); 266*6281a769SCalvin Johnson printf(" free err: %x\n", readl(base + BMU_FREE_ERR_ADDR)); 267*6281a769SCalvin Johnson } 268*6281a769SCalvin Johnson 269*6281a769SCalvin Johnson #define PESTATUS_ADDR_CLASS 0x800 270*6281a769SCalvin Johnson #define PEMBOX_ADDR_CLASS 0x890 271*6281a769SCalvin Johnson #define PESTATUS_ADDR_TMU 0x80 272*6281a769SCalvin Johnson #define PEMBOX_ADDR_TMU 0x290 273*6281a769SCalvin Johnson #define PESTATUS_ADDR_UTIL 0x0 274*6281a769SCalvin Johnson 275*6281a769SCalvin Johnson static void pfe_pe_status(int argc, char * const argv[]) 276*6281a769SCalvin Johnson { 277*6281a769SCalvin Johnson int do_clear = 0; 278*6281a769SCalvin Johnson u32 id; 279*6281a769SCalvin Johnson u32 dmem_addr; 280*6281a769SCalvin Johnson u32 cpu_state; 281*6281a769SCalvin Johnson u32 activity_counter; 282*6281a769SCalvin Johnson u32 rx; 283*6281a769SCalvin Johnson u32 tx; 284*6281a769SCalvin Johnson u32 drop; 285*6281a769SCalvin Johnson char statebuf[5]; 286*6281a769SCalvin Johnson u32 class_debug_reg = 0; 287*6281a769SCalvin Johnson 288*6281a769SCalvin Johnson if (argc == 4 && strcmp(argv[3], "clear") == 0) 289*6281a769SCalvin Johnson do_clear = 1; 290*6281a769SCalvin Johnson 291*6281a769SCalvin Johnson for (id = CLASS0_ID; id < MAX_PE; id++) { 292*6281a769SCalvin Johnson if (id >= TMU0_ID) { 293*6281a769SCalvin Johnson if (id == TMU2_ID) 294*6281a769SCalvin Johnson continue; 295*6281a769SCalvin Johnson if (id == TMU0_ID) 296*6281a769SCalvin Johnson printf("tmu:\n"); 297*6281a769SCalvin Johnson dmem_addr = PESTATUS_ADDR_TMU; 298*6281a769SCalvin Johnson } else { 299*6281a769SCalvin Johnson if (id == CLASS0_ID) 300*6281a769SCalvin Johnson printf("class:\n"); 301*6281a769SCalvin Johnson dmem_addr = PESTATUS_ADDR_CLASS; 302*6281a769SCalvin Johnson class_debug_reg = readl(CLASS_PE0_DEBUG + id * 4); 303*6281a769SCalvin Johnson } 304*6281a769SCalvin Johnson 305*6281a769SCalvin Johnson cpu_state = pe_dmem_read(id, dmem_addr, 4); 306*6281a769SCalvin Johnson dmem_addr += 4; 307*6281a769SCalvin Johnson memcpy(statebuf, (char *)&cpu_state, 4); 308*6281a769SCalvin Johnson statebuf[4] = '\0'; 309*6281a769SCalvin Johnson activity_counter = pe_dmem_read(id, dmem_addr, 4); 310*6281a769SCalvin Johnson dmem_addr += 4; 311*6281a769SCalvin Johnson rx = pe_dmem_read(id, dmem_addr, 4); 312*6281a769SCalvin Johnson if (do_clear) 313*6281a769SCalvin Johnson pe_dmem_write(id, 0, dmem_addr, 4); 314*6281a769SCalvin Johnson dmem_addr += 4; 315*6281a769SCalvin Johnson tx = pe_dmem_read(id, dmem_addr, 4); 316*6281a769SCalvin Johnson if (do_clear) 317*6281a769SCalvin Johnson pe_dmem_write(id, 0, dmem_addr, 4); 318*6281a769SCalvin Johnson dmem_addr += 4; 319*6281a769SCalvin Johnson drop = pe_dmem_read(id, dmem_addr, 4); 320*6281a769SCalvin Johnson if (do_clear) 321*6281a769SCalvin Johnson pe_dmem_write(id, 0, dmem_addr, 4); 322*6281a769SCalvin Johnson dmem_addr += 4; 323*6281a769SCalvin Johnson 324*6281a769SCalvin Johnson if (id >= TMU0_ID) { 325*6281a769SCalvin Johnson printf("%d: state=%4s ctr=%08x rx=%x qstatus=%x\n", 326*6281a769SCalvin Johnson id - TMU0_ID, statebuf, 327*6281a769SCalvin Johnson cpu_to_be32(activity_counter), 328*6281a769SCalvin Johnson cpu_to_be32(rx), cpu_to_be32(tx)); 329*6281a769SCalvin Johnson } else { 330*6281a769SCalvin Johnson printf("%d: pc=1%04x ldst=%04x state=%4s ctr=%08x rx=%x tx=%x drop=%x\n", 331*6281a769SCalvin Johnson id - CLASS0_ID, class_debug_reg & 0xFFFF, 332*6281a769SCalvin Johnson class_debug_reg >> 16, 333*6281a769SCalvin Johnson statebuf, cpu_to_be32(activity_counter), 334*6281a769SCalvin Johnson cpu_to_be32(rx), cpu_to_be32(tx), 335*6281a769SCalvin Johnson cpu_to_be32(drop)); 336*6281a769SCalvin Johnson } 337*6281a769SCalvin Johnson } 338*6281a769SCalvin Johnson } 339*6281a769SCalvin Johnson 340*6281a769SCalvin Johnson static void pfe_command_status(int argc, char * const argv[]) 341*6281a769SCalvin Johnson { 342*6281a769SCalvin Johnson if (argc >= 3 && strcmp(argv[2], "pe") == 0) { 343*6281a769SCalvin Johnson pfe_pe_status(argc, argv); 344*6281a769SCalvin Johnson } else if (argc == 3 && strcmp(argv[2], "bmu") == 0) { 345*6281a769SCalvin Johnson bmu(1, BMU1_BASE_ADDR); 346*6281a769SCalvin Johnson bmu(2, BMU2_BASE_ADDR); 347*6281a769SCalvin Johnson } else if (argc == 3 && strcmp(argv[2], "hif") == 0) { 348*6281a769SCalvin Johnson hif_status(); 349*6281a769SCalvin Johnson } else if (argc == 3 && strcmp(argv[2], "gpi") == 0) { 350*6281a769SCalvin Johnson gpi(0, EGPI1_BASE_ADDR); 351*6281a769SCalvin Johnson gpi(1, EGPI2_BASE_ADDR); 352*6281a769SCalvin Johnson gpi(3, HGPI_BASE_ADDR); 353*6281a769SCalvin Johnson } else if (argc == 3 && strcmp(argv[2], "tmu0_queues") == 0) { 354*6281a769SCalvin Johnson tmu_queues(NULL, 0); 355*6281a769SCalvin Johnson } else if (argc == 3 && strcmp(argv[2], "tmu1_queues") == 0) { 356*6281a769SCalvin Johnson tmu_queues(NULL, 1); 357*6281a769SCalvin Johnson } else if (argc == 3 && strcmp(argv[2], "tmu3_queues") == 0) { 358*6281a769SCalvin Johnson tmu_queues(NULL, 3); 359*6281a769SCalvin Johnson } else { 360*6281a769SCalvin Johnson printf("Usage: pfe status [pe <clear> | bmu | gpi | hif | tmuX_queues ]\n"); 361*6281a769SCalvin Johnson } 362*6281a769SCalvin Johnson } 363*6281a769SCalvin Johnson 364*6281a769SCalvin Johnson #define EXPT_DUMP_ADDR 0x1fa8 365*6281a769SCalvin Johnson #define EXPT_REG_COUNT 20 366*6281a769SCalvin Johnson static const char *register_names[EXPT_REG_COUNT] = { 367*6281a769SCalvin Johnson " pc", "ECAS", " EID", " ED", 368*6281a769SCalvin Johnson " sp", " r1", " r2", " r3", 369*6281a769SCalvin Johnson " r4", " r5", " r6", " r7", 370*6281a769SCalvin Johnson " r8", " r9", " r10", " r11", 371*6281a769SCalvin Johnson " r12", " r13", " r14", " r15" 372*6281a769SCalvin Johnson }; 373*6281a769SCalvin Johnson 374*6281a769SCalvin Johnson static void pfe_command_expt(int argc, char * const argv[]) 375*6281a769SCalvin Johnson { 376*6281a769SCalvin Johnson unsigned int id, i, val, addr; 377*6281a769SCalvin Johnson 378*6281a769SCalvin Johnson if (argc == 3) { 379*6281a769SCalvin Johnson id = simple_strtoul(argv[2], NULL, 0); 380*6281a769SCalvin Johnson addr = EXPT_DUMP_ADDR; 381*6281a769SCalvin Johnson printf("Exception information for PE %d:\n", id); 382*6281a769SCalvin Johnson for (i = 0; i < EXPT_REG_COUNT; i++) { 383*6281a769SCalvin Johnson val = pe_dmem_read(id, addr, 4); 384*6281a769SCalvin Johnson val = be32_to_cpu(val); 385*6281a769SCalvin Johnson printf("%s:%08x%s", register_names[i], val, 386*6281a769SCalvin Johnson (i & 3) == 3 ? "\n" : " "); 387*6281a769SCalvin Johnson addr += 4; 388*6281a769SCalvin Johnson } 389*6281a769SCalvin Johnson } else { 390*6281a769SCalvin Johnson printf("Usage: pfe expt <id>\n"); 391*6281a769SCalvin Johnson } 392*6281a769SCalvin Johnson } 393*6281a769SCalvin Johnson 394*6281a769SCalvin Johnson #ifdef PFE_RESET_WA 395*6281a769SCalvin Johnson /*This function sends a dummy packet to HIF through TMU3 */ 396*6281a769SCalvin Johnson static void send_dummy_pkt_to_hif(void) 397*6281a769SCalvin Johnson { 398*6281a769SCalvin Johnson u32 buf; 399*6281a769SCalvin Johnson static u32 dummy_pkt[] = { 400*6281a769SCalvin Johnson 0x4200800a, 0x01000003, 0x00018100, 0x00000000, 401*6281a769SCalvin Johnson 0x33221100, 0x2b785544, 0xd73093cb, 0x01000608, 402*6281a769SCalvin Johnson 0x04060008, 0x2b780200, 0xd73093cb, 0x0a01a8c0, 403*6281a769SCalvin Johnson 0x33221100, 0xa8c05544, 0x00000301, 0x00000000, 404*6281a769SCalvin Johnson 0x00000000, 0x00000000, 0x00000000, 0xbe86c51f }; 405*6281a769SCalvin Johnson 406*6281a769SCalvin Johnson /*Allocate BMU2 buffer */ 407*6281a769SCalvin Johnson buf = readl(BMU2_BASE_ADDR + BMU_ALLOC_CTRL); 408*6281a769SCalvin Johnson 409*6281a769SCalvin Johnson debug("Sending a dummy pkt to HIF %x\n", buf); 410*6281a769SCalvin Johnson buf += 0x80; 411*6281a769SCalvin Johnson memcpy((void *)DDR_PFE_TO_VIRT(buf), dummy_pkt, sizeof(dummy_pkt)); 412*6281a769SCalvin Johnson 413*6281a769SCalvin Johnson /*Write length and pkt to TMU*/ 414*6281a769SCalvin Johnson writel(0x03000042, TMU_PHY_INQ_PKTPTR); 415*6281a769SCalvin Johnson writel(buf, TMU_PHY_INQ_PKTINFO); 416*6281a769SCalvin Johnson } 417*6281a769SCalvin Johnson 418*6281a769SCalvin Johnson static void pfe_command_stop(int argc, char * const argv[]) 419*6281a769SCalvin Johnson { 420*6281a769SCalvin Johnson int pfe_pe_id, hif_stop_loop = 10; 421*6281a769SCalvin Johnson u32 rx_status; 422*6281a769SCalvin Johnson 423*6281a769SCalvin Johnson printf("Stopping PFE...\n"); 424*6281a769SCalvin Johnson 425*6281a769SCalvin Johnson /*Mark all descriptors as LAST_BD */ 426*6281a769SCalvin Johnson hif_rx_desc_disable(); 427*6281a769SCalvin Johnson 428*6281a769SCalvin Johnson /*If HIF Rx BDP is busy send a dummy packet */ 429*6281a769SCalvin Johnson do { 430*6281a769SCalvin Johnson rx_status = readl(HIF_RX_STATUS); 431*6281a769SCalvin Johnson if (rx_status & BDP_CSR_RX_DMA_ACTV) 432*6281a769SCalvin Johnson send_dummy_pkt_to_hif(); 433*6281a769SCalvin Johnson udelay(10); 434*6281a769SCalvin Johnson } while (hif_stop_loop--); 435*6281a769SCalvin Johnson 436*6281a769SCalvin Johnson if (readl(HIF_RX_STATUS) & BDP_CSR_RX_DMA_ACTV) 437*6281a769SCalvin Johnson printf("Unable to stop HIF\n"); 438*6281a769SCalvin Johnson 439*6281a769SCalvin Johnson /*Disable Class PEs */ 440*6281a769SCalvin Johnson for (pfe_pe_id = CLASS0_ID; pfe_pe_id <= CLASS_MAX_ID; pfe_pe_id++) { 441*6281a769SCalvin Johnson /*Inform PE to stop */ 442*6281a769SCalvin Johnson pe_dmem_write(pfe_pe_id, cpu_to_be32(1), PEMBOX_ADDR_CLASS, 4); 443*6281a769SCalvin Johnson udelay(10); 444*6281a769SCalvin Johnson 445*6281a769SCalvin Johnson /*Read status */ 446*6281a769SCalvin Johnson if (!pe_dmem_read(pfe_pe_id, PEMBOX_ADDR_CLASS + 4, 4)) 447*6281a769SCalvin Johnson printf("Failed to stop PE%d\n", pfe_pe_id); 448*6281a769SCalvin Johnson } 449*6281a769SCalvin Johnson 450*6281a769SCalvin Johnson /*Disable TMU PEs */ 451*6281a769SCalvin Johnson for (pfe_pe_id = TMU0_ID; pfe_pe_id <= TMU_MAX_ID; pfe_pe_id++) { 452*6281a769SCalvin Johnson if (pfe_pe_id == TMU2_ID) 453*6281a769SCalvin Johnson continue; 454*6281a769SCalvin Johnson 455*6281a769SCalvin Johnson /*Inform PE to stop */ 456*6281a769SCalvin Johnson pe_dmem_write(pfe_pe_id, 1, PEMBOX_ADDR_TMU, 4); 457*6281a769SCalvin Johnson udelay(10); 458*6281a769SCalvin Johnson 459*6281a769SCalvin Johnson /*Read status */ 460*6281a769SCalvin Johnson if (!pe_dmem_read(pfe_pe_id, PEMBOX_ADDR_TMU + 4, 4)) 461*6281a769SCalvin Johnson printf("Failed to stop PE%d\n", pfe_pe_id); 462*6281a769SCalvin Johnson } 463*6281a769SCalvin Johnson } 464*6281a769SCalvin Johnson #endif 465*6281a769SCalvin Johnson 466*6281a769SCalvin Johnson static int pfe_command(cmd_tbl_t *cmdtp, int flag, int argc, 467*6281a769SCalvin Johnson char * const argv[]) 468*6281a769SCalvin Johnson { 469*6281a769SCalvin Johnson if (argc == 1 || strcmp(argv[1], "help") == 0) { 470*6281a769SCalvin Johnson pfe_command_help(); 471*6281a769SCalvin Johnson return CMD_RET_SUCCESS; 472*6281a769SCalvin Johnson } 473*6281a769SCalvin Johnson 474*6281a769SCalvin Johnson if (strcmp(argv[1], "pe") == 0) { 475*6281a769SCalvin Johnson pfe_command_pe(argc, argv); 476*6281a769SCalvin Johnson } else if (strcmp(argv[1], "status") == 0) { 477*6281a769SCalvin Johnson pfe_command_status(argc, argv); 478*6281a769SCalvin Johnson } else if (strcmp(argv[1], "expt") == 0) { 479*6281a769SCalvin Johnson pfe_command_expt(argc, argv); 480*6281a769SCalvin Johnson #ifdef PFE_RESET_WA 481*6281a769SCalvin Johnson } else if (strcmp(argv[1], "stop") == 0) { 482*6281a769SCalvin Johnson pfe_command_stop(argc, argv); 483*6281a769SCalvin Johnson #endif 484*6281a769SCalvin Johnson } else { 485*6281a769SCalvin Johnson printf("Unknown option: %s\n", argv[1]); 486*6281a769SCalvin Johnson pfe_command_help(); 487*6281a769SCalvin Johnson return CMD_RET_FAILURE; 488*6281a769SCalvin Johnson } 489*6281a769SCalvin Johnson return CMD_RET_SUCCESS; 490*6281a769SCalvin Johnson } 491*6281a769SCalvin Johnson 492*6281a769SCalvin Johnson U_BOOT_CMD( 493*6281a769SCalvin Johnson pfe, 7, 1, pfe_command, 494*6281a769SCalvin Johnson "Performs PFE lib utility functions", 495*6281a769SCalvin Johnson "Usage:\n" 496*6281a769SCalvin Johnson "pfe <options>" 497*6281a769SCalvin Johnson ); 498