uboot/board/mpl/pati/cmd_pati.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2001
   3 * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 *
   7 * Adapted for PATI
   8 */
   9
  10#include <common.h>
  11#include <command.h>
  12#define PLX9056_LOC
  13#include "plx9056.h"
  14#include "pati.h"
  15#include "pci_eeprom.h"
  16
  17extern void show_pld_regs(void);
  18extern int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
  19
  20extern void user_led0(int led_on);
  21extern void user_led1(int led_on);
  22
  23/* ------------------------------------------------------------------------- */
  24#if defined(CONFIG_SYS_PCI_CON_DEVICE)
  25extern void pci_con_disc(void);
  26extern void pci_con_connect(void);
  27#endif
  28
  29/******************************************************************************
  30 * Eeprom Support
  31 ******************************************************************************/
  32unsigned long get32(unsigned long addr)
  33{
  34        unsigned long *p=(unsigned long *)addr;
  35        return *p;
  36}
  37
  38void set32(unsigned long addr,unsigned long data)
  39{
  40        unsigned long *p=(unsigned long *)addr;
  41        *p=data;
  42}
  43
  44#define PCICFG_GET_REG(x)       (get32((x) + PCI_CONFIG_BASE))
  45#define PCICFG_SET_REG(x,y)     (set32((x) + PCI_CONFIG_BASE,(y)))
  46
  47
  48/******************************************************************************
  49 * reload_pci_eeprom
  50 ******************************************************************************/
  51
  52static void reload_pci_eeprom(void)
  53{
  54        unsigned long reg;
  55        /* Set Bit 29 and clear it again */
  56        reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
  57        udelay(1);
  58        /* set it*/
  59        reg|=(1<<29);
  60        PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
  61        /* EECLK @ 33MHz = 125kHz
  62         * -> extra long load = 32 * 16bit = 512Bit @ 125kHz = 4.1msec
  63         * use 20msec
  64         */
  65        udelay(20000); /* wait 20ms */
  66        reg &= ~(1<<29); /* set it low */
  67        PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
  68        udelay(1); /* wait some time */
  69}
  70
  71/******************************************************************************
  72 * clock_pci_eeprom
  73 ******************************************************************************/
  74
  75static void clock_pci_eeprom(void)
  76{
  77        unsigned long reg;
  78        /* clock is low, data is valid */
  79        reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
  80        udelay(1);
  81        /* set clck high */
  82        reg|=(1<<24);
  83        PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
  84        udelay(1); /* wait some time */
  85        reg &= ~(1<<24); /* set clock low */
  86        PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
  87        udelay(1); /* wait some time */
  88}
  89
  90/******************************************************************************
  91 * send_pci_eeprom_cmd
  92 ******************************************************************************/
  93static void send_pci_eeprom_cmd(unsigned long cmd, unsigned char len)
  94{
  95        unsigned long reg;
  96        int i;
  97        reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
  98        /* Clear all EEPROM bits */
  99        reg &= ~(0xF << 24);
 100        /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */
 101        PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
 102        udelay(1); /* wait some time */
 103        /* Enable EEPROM Chip Select */
 104        reg |= (1 << 25);
 105        PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
 106        /* Send EEPROM command - one bit at a time */
 107        for (i = (int)(len-1); i >= 0; i--) {
 108                /* Check if current bit is 0 or 1 */
 109                if (cmd & (1 << i))
 110                        PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,(reg | (1<<26)));
 111                else
 112                        PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
 113                clock_pci_eeprom();
 114        }
 115}
 116
 117/******************************************************************************
 118 * write_pci_eeprom_offs
 119 ******************************************************************************/
 120static void write_pci_eeprom_offs(unsigned short offset, unsigned short value)
 121{
 122        unsigned long reg;
 123        int bitpos, cmdshft, cmdlen, timeout;
 124        /* we're using the Eeprom 93CS66 */
 125        cmdshft  = 2;
 126        cmdlen = EE66_CMD_LEN;
 127        /* Send Write_Enable command to EEPROM */
 128        send_pci_eeprom_cmd((EE_WREN << cmdshft),cmdlen);
 129        /* Send EEPROM Write command and offset to EEPROM */
 130        send_pci_eeprom_cmd((EE_WRITE << cmdshft) | (offset / 2),cmdlen);
 131        reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
 132        /* Clear all EEPROM bits */
 133        reg &= ~(0xF << 24);
 134        /* Make sure EEDO Input is disabled for some PLX chips */
 135        reg &= ~(1 << 31);
 136        /* Enable EEPROM Chip Select */
 137        reg |= (1 << 25);
 138        /* Write 16-bit value to EEPROM - one bit at a time */
 139        for (bitpos = 15; bitpos >= 0; bitpos--) {
 140                /* Get bit value and shift into result */
 141                if (value & (1 << bitpos))
 142                        PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,(reg | (1<<26)));
 143                else
 144                        PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg );
 145                clock_pci_eeprom();
 146        } /* for */
 147        /* Deselect Chip */
 148        PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg & ~(1 << 25));
 149        /* Re-select Chip */
 150        PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg | (1 << 25));
 151        /* A small delay is needed to let EEPROM complete */
 152        timeout = 0;
 153        do {
 154                udelay(10);
 155                reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
 156                timeout++;
 157        } while (((reg & (1 << 27)) == 0) && timeout < 20000);
 158        /* Send Write_Disable command to EEPROM */
 159        send_pci_eeprom_cmd((EE_WDS << cmdshft),cmdlen);
 160        /* Clear Chip Select and all other EEPROM bits */
 161        PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg & ~(0xF << 24));
 162}
 163
 164
 165/******************************************************************************
 166 * read_pci_eeprom_offs
 167 ******************************************************************************/
 168static void read_pci_eeprom_offs(unsigned short offset, unsigned short *pvalue)
 169{
 170        unsigned long reg;
 171        int bitpos, cmdshft, cmdlen;
 172        /* we're using the Eeprom 93CS66 */
 173        cmdshft  = 2;
 174        cmdlen = EE66_CMD_LEN;
 175        /* Send EEPROM read command and offset to EEPROM */
 176        send_pci_eeprom_cmd((EE_READ << cmdshft) | (offset / 2),cmdlen);
 177        /* Set EEPROM write output bit */
 178        reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
 179        /* Set EEDO Input enable */
 180        reg |= (1 << 31);
 181        PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg | (1 << 26));
 182        /* Get 16-bit value from EEPROM - one bit at a time */
 183        for (bitpos = 0; bitpos < 16; bitpos++) {
 184                clock_pci_eeprom();
 185                udelay(10);
 186                reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
 187                /* Get bit value and shift into result */
 188                if (reg & (1 << 27))
 189                        *pvalue = (unsigned short)((*pvalue << 1) | 1);
 190                else
 191                        *pvalue = (unsigned short)(*pvalue << 1);
 192        }
 193        /* Clear EEDO Input enable */
 194        reg &= ~(1 << 31);
 195        /* Clear Chip Select and all other EEPROM bits */
 196        PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg & ~(0xF << 24));
 197}
 198
 199
 200/******************************************************************************
 201 * EEPROM read/writes
 202******************************************************************************/
 203
 204#undef EEPROM_DBG
 205static int pati_pci_eeprom_erase(void)
 206{
 207        int i;
 208        printf("Erasing EEPROM ");
 209        for( i=0; i < PATI_EEPROM_LAST_OFFSET; i+=2) {
 210                write_pci_eeprom_offs(i,0xffff);
 211                if((i%0x10))
 212                        printf(".");
 213        }
 214        printf("\nDone\n");
 215        return 0;
 216}
 217
 218static int pati_pci_eeprom_prg(void)
 219{
 220        int i;
 221        i=0;
 222        printf("Programming EEPROM ");
 223        while(pati_eeprom[i].offset<0xffff) {
 224                write_pci_eeprom_offs(pati_eeprom[i].offset,pati_eeprom[i].value);
 225                #ifdef EEPROM_DBG
 226                printf("0x%04X: 0x%04X\n",pati_eeprom[i].offset, pati_eeprom[i].value);
 227                #else
 228                if((i%0x10))
 229                        printf(".");
 230                #endif
 231                i++;
 232        }
 233        printf("\nDone\n");
 234        return 0;
 235}
 236
 237static int pati_pci_eeprom_write(unsigned short offset, unsigned long addr, unsigned short size)
 238{
 239        int i;
 240        unsigned short value;
 241        unsigned short *buffer =(unsigned short *)addr;
 242        if((offset + size) > PATI_EEPROM_LAST_OFFSET) {
 243                size = PATI_EEPROM_LAST_OFFSET - offset;
 244        }
 245        printf("Write To EEPROM from 0x%lX to 0x%X 0x%X words\n", addr, offset, size/2);
 246        for( i = offset; i< (offset + size); i+=2) {
 247                value = *buffer++;
 248                write_pci_eeprom_offs(i,value);
 249                #ifdef EEPROM_DBG
 250                printf("0x%04X: 0x%04X\n",i, value);
 251                #else
 252                if((i%0x10))
 253                        printf(".");
 254                #endif
 255        }
 256        printf("\nDone\n");
 257        return 0;
 258}
 259
 260static int pati_pci_eeprom_read(unsigned short offset, unsigned long addr, unsigned short size)
 261{
 262        int i;
 263        unsigned short value = 0;
 264        unsigned short *buffer =(unsigned short *)addr;
 265        if((offset + size) > PATI_EEPROM_LAST_OFFSET) {
 266                size = PATI_EEPROM_LAST_OFFSET - offset;
 267        }
 268        printf("Read from EEPROM from 0x%X to 0x%lX 0x%X words\n", offset, addr, size/2);
 269        for( i = offset; i< (offset + size); i+=2) {
 270                read_pci_eeprom_offs(i,&value);
 271                *buffer++=value;
 272                #ifdef EEPROM_DBG
 273                printf("0x%04X: 0x%04X\n",i, value);
 274                #else
 275                if((i%0x10))
 276                        printf(".");
 277                #endif
 278        }
 279        printf("\nDone\n");
 280        return 0;
 281}
 282
 283/******************************************************************************
 284 * PCI Bridge Registers Dump
 285*******************************************************************************/
 286static void display_pci_regs(void)
 287{
 288        printf(" PCI9056_SPACE0_RANGE     %08lX\n",PCICFG_GET_REG(PCI9056_SPACE0_RANGE));
 289        printf(" PCI9056_SPACE0_REMAP     %08lX\n",PCICFG_GET_REG(PCI9056_SPACE0_REMAP));
 290        printf(" PCI9056_LOCAL_DMA_ARBIT  %08lX\n",PCICFG_GET_REG(PCI9056_LOCAL_DMA_ARBIT));
 291        printf(" PCI9056_ENDIAN_DESC      %08lX\n",PCICFG_GET_REG(PCI9056_ENDIAN_DESC));
 292        printf(" PCI9056_EXP_ROM_RANGE    %08lX\n",PCICFG_GET_REG(PCI9056_EXP_ROM_RANGE));
 293        printf(" PCI9056_EXP_ROM_REMAP    %08lX\n",PCICFG_GET_REG(PCI9056_EXP_ROM_REMAP));
 294        printf(" PCI9056_SPACE0_ROM_DESC  %08lX\n",PCICFG_GET_REG(PCI9056_SPACE0_ROM_DESC));
 295        printf(" PCI9056_DM_RANGE         %08lX\n",PCICFG_GET_REG(PCI9056_DM_RANGE));
 296        printf(" PCI9056_DM_MEM_BASE      %08lX\n",PCICFG_GET_REG(PCI9056_DM_MEM_BASE));
 297        printf(" PCI9056_DM_IO_BASE       %08lX\n",PCICFG_GET_REG(PCI9056_DM_IO_BASE));
 298        printf(" PCI9056_DM_PCI_MEM_REMAP %08lX\n",PCICFG_GET_REG(PCI9056_DM_PCI_MEM_REMAP));
 299        printf(" PCI9056_DM_PCI_IO_CONFIG %08lX\n",PCICFG_GET_REG(PCI9056_DM_PCI_IO_CONFIG));
 300        printf(" PCI9056_SPACE1_RANGE     %08lX\n",PCICFG_GET_REG(PCI9056_SPACE1_RANGE));
 301        printf(" PCI9056_SPACE1_REMAP     %08lX\n",PCICFG_GET_REG(PCI9056_SPACE1_REMAP));
 302        printf(" PCI9056_SPACE1_DESC      %08lX\n",PCICFG_GET_REG(PCI9056_SPACE1_DESC));
 303        printf(" PCI9056_DM_DAC           %08lX\n",PCICFG_GET_REG(PCI9056_DM_DAC));
 304        printf(" PCI9056_MAILBOX0         %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX0));
 305        printf(" PCI9056_MAILBOX1         %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX1));
 306        printf(" PCI9056_MAILBOX2         %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX2));
 307        printf(" PCI9056_MAILBOX3         %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX3));
 308        printf(" PCI9056_MAILBOX4         %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX4));
 309        printf(" PCI9056_MAILBOX5         %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX5));
 310        printf(" PCI9056_MAILBOX6         %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX6));
 311        printf(" PCI9056_MAILBOX7         %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX7));
 312        printf(" PCI9056_PCI_TO_LOC_DBELL %08lX\n",PCICFG_GET_REG(PCI9056_PCI_TO_LOC_DBELL));
 313        printf(" PCI9056_LOC_TO_PCI_DBELL %08lX\n",PCICFG_GET_REG(PCI9056_LOC_TO_PCI_DBELL));
 314        printf(" PCI9056_INT_CTRL_STAT    %08lX\n",PCICFG_GET_REG(PCI9056_INT_CTRL_STAT));
 315        printf(" PCI9056_EEPROM_CTRL_STAT %08lX\n",PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT));
 316        printf(" PCI9056_PERM_VENDOR_ID   %08lX\n",PCICFG_GET_REG(PCI9056_PERM_VENDOR_ID));
 317        printf(" PCI9056_REVISION_ID      %08lX\n",PCICFG_GET_REG(PCI9056_REVISION_ID));
 318        printf(" \n");
 319        printf(" PCI9056_VENDOR_ID        %08lX\n",PCICFG_GET_REG(PCI9056_VENDOR_ID));
 320        printf(" PCI9056_COMMAND          %08lX\n",PCICFG_GET_REG(PCI9056_COMMAND));
 321        printf(" PCI9056_REVISION         %08lX\n",PCICFG_GET_REG(PCI9056_REVISION));
 322        printf(" PCI9056_CACHE_SIZE       %08lX\n",PCICFG_GET_REG(PCI9056_CACHE_SIZE));
 323        printf(" PCI9056_RTR_BASE         %08lX\n",PCICFG_GET_REG(PCI9056_RTR_BASE));
 324        printf(" PCI9056_RTR_IO_BASE      %08lX\n",PCICFG_GET_REG(PCI9056_RTR_IO_BASE));
 325        printf(" PCI9056_LOCAL_BASE0      %08lX\n",PCICFG_GET_REG(PCI9056_LOCAL_BASE0));
 326        printf(" PCI9056_LOCAL_BASE1      %08lX\n",PCICFG_GET_REG(PCI9056_LOCAL_BASE1));
 327        printf(" PCI9056_UNUSED_BASE1     %08lX\n",PCICFG_GET_REG(PCI9056_UNUSED_BASE1));
 328        printf(" PCI9056_UNUSED_BASE2     %08lX\n",PCICFG_GET_REG(PCI9056_UNUSED_BASE2));
 329        printf(" PCI9056_CIS_PTR          %08lX\n",PCICFG_GET_REG(PCI9056_CIS_PTR));
 330        printf(" PCI9056_SUB_ID           %08lX\n",PCICFG_GET_REG(PCI9056_SUB_ID));
 331        printf(" PCI9056_EXP_ROM_BASE     %08lX\n",PCICFG_GET_REG(PCI9056_EXP_ROM_BASE));
 332        printf(" PCI9056_CAP_PTR          %08lX\n",PCICFG_GET_REG(PCI9056_CAP_PTR));
 333        printf(" PCI9056_INT_LINE         %08lX\n",PCICFG_GET_REG(PCI9056_INT_LINE));
 334        printf(" PCI9056_PM_CAP_ID        %08lX\n",PCICFG_GET_REG(PCI9056_PM_CAP_ID));
 335        printf(" PCI9056_PM_CSR           %08lX\n",PCICFG_GET_REG(PCI9056_PM_CSR));
 336        printf(" PCI9056_HS_CAP_ID        %08lX\n",PCICFG_GET_REG(PCI9056_HS_CAP_ID));
 337        printf(" PCI9056_VPD_CAP_ID       %08lX\n",PCICFG_GET_REG(PCI9056_VPD_CAP_ID));
 338        printf(" PCI9056_VPD_DATA         %08lX\n",PCICFG_GET_REG(PCI9056_VPD_DATA));
 339}
 340
 341
 342int do_pati(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 343{
 344        if (strcmp(argv[1], "info") == 0)
 345        {
 346                show_pld_regs();
 347                return 0;
 348        }
 349        if (strcmp(argv[1], "pci") == 0)
 350        {
 351                display_pci_regs();
 352                return 0;
 353        }
 354        if (strcmp(argv[1], "led") == 0)
 355        {
 356                int led_nr,led_on;
 357                led_nr = (int)simple_strtoul(argv[2], NULL, 10);
 358                led_on = (int)simple_strtoul(argv[3], NULL, 10);
 359                if(!led_nr)
 360                        user_led0(led_on);
 361                else
 362                        user_led1(led_on);
 363                return 0;
 364        }
 365#if defined(CONFIG_SYS_PCI_CON_DEVICE)
 366        if (strcmp(argv[1], "con") == 0) {
 367                pci_con_connect();
 368                return 0;
 369        }
 370        if (strcmp(argv[1], "disc") == 0) {
 371                pci_con_disc();
 372                return 0;
 373        }
 374#endif
 375        if (strcmp(argv[1], "eeprom") == 0) {
 376                unsigned long addr;
 377                int size, offset;
 378                offset = 0;
 379                size = PATI_EEPROM_LAST_OFFSET;
 380                if(argc>2) {
 381                        if(argc>3) {
 382                                addr = simple_strtoul(argv[3], NULL, 16);
 383                                if(argc>4)
 384                                        offset = (int) simple_strtoul(argv[4], NULL, 16);
 385                                if(argc>5)
 386                                        size = (int) simple_strtoul(argv[5], NULL, 16);
 387                                if (strcmp(argv[2], "read") == 0) {
 388                                        return (pati_pci_eeprom_read(offset, addr, size));
 389                                }
 390                                if (strcmp(argv[2], "write") == 0) {
 391                                        return (pati_pci_eeprom_write(offset, addr, size));
 392                                }
 393                        }
 394                        if (strcmp(argv[2], "prg") == 0) {
 395                                return (pati_pci_eeprom_prg());
 396                        }
 397                        if (strcmp(argv[2], "era") == 0) {
 398                                return (pati_pci_eeprom_erase());
 399                        }
 400                        if (strcmp(argv[2], "reload") == 0) {
 401                                reload_pci_eeprom();
 402                                return 0;
 403                        }
 404
 405
 406                }
 407        }
 408
 409        return (do_mplcommon(cmdtp, flag, argc, argv));
 410}
 411
 412U_BOOT_CMD(
 413        pati,   8,      1,      do_pati,
 414        "PATI specific Cmds",
 415        "info - displays board information\n"
 416        "pati pci  - displays PCI registers\n"
 417        "pati led <nr> <on> \n"
 418        "          - switch LED <nr> <on>\n"
 419        "pati flash mem [SrcAddr]\n"
 420        "          - updates U-Boot with image in memory\n"
 421        "pati eeprom <cmd> - PCI EEPROM sub-system\n"
 422        "    read <addr> <offset> <size>\n"
 423        "          - read PCI EEPROM to <addr> from <offset> <size> words\n"
 424        "    write <addr> <offset> <size>\n"
 425        "          - write PCI EEPROM from <addr> to <offset> <size> words\n"
 426        "    prg   - programm PCI EEPROM with default values\n"
 427        "    era   - erase PCI EEPROM (write all word to 0xffff)\n"
 428        "    reload- Reload PCI Bridge with EEPROM Values\n"
 429        "    NOTE: <addr> must start on word boundary\n"
 430        "          <offset> and <size> must be even byte values"
 431);
 432
 433/* ------------------------------------------------------------------------- */
 434