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