uboot/board/eltec/bab7xx/dc_srom.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2002 ELTEC Elektronik AG
   3 * Frank Gottschling <fgottschling@eltec.de>
   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
  24/*
  25 * SRom I/O routines.
  26 */
  27
  28#include <common.h>
  29#include <pci.h>
  30#include "srom.h"
  31
  32#define SROM_RD         0x00004000    /* Read from Boot ROM */
  33#define SROM_WR         0x00002000    /* Write to Boot ROM */
  34#define SROM_SR         0x00000800    /* Select Serial ROM when set */
  35
  36#define DT_IN           0x00000004    /* Serial Data In */
  37#define DT_CLK          0x00000002    /* Serial ROM Clock */
  38#define DT_CS           0x00000001    /* Serial ROM Chip Select */
  39
  40static u_int         dc_srom_iobase;
  41
  42/*----------------------------------------------------------------------------*/
  43
  44static int inl(u_long addr)
  45{
  46    return le32_to_cpu(*(volatile u_long *)(addr));
  47}
  48
  49/*----------------------------------------------------------------------------*/
  50
  51static void outl (int command, u_long addr)
  52{
  53    *(volatile u_long *)(addr) = cpu_to_le32(command);
  54}
  55
  56/*----------------------------------------------------------------------------*/
  57
  58static void sendto_srom(u_int command, u_long addr)
  59{
  60    outl(command, addr);
  61    udelay(1);
  62
  63    return;
  64}
  65
  66/*----------------------------------------------------------------------------*/
  67
  68static int getfrom_srom(u_long addr)
  69{
  70    s32 tmp;
  71
  72    tmp = inl(addr);
  73    udelay(1);
  74
  75    return tmp;
  76}
  77
  78/*----------------------------------------------------------------------------*/
  79
  80static void srom_latch (u_int command, u_long addr)
  81{
  82    sendto_srom (command, addr);
  83    sendto_srom (command | DT_CLK, addr);
  84    sendto_srom (command, addr);
  85
  86    return;
  87}
  88
  89/*----------------------------------------------------------------------------*/
  90
  91static void srom_command_rd (u_int command, u_long addr)
  92{
  93    srom_latch (command, addr);
  94    srom_latch (command, addr);
  95    srom_latch ((command & 0x0000ff00) | DT_CS, addr);
  96
  97    return;
  98}
  99
 100/*----------------------------------------------------------------------------*/
 101
 102static void srom_command_wr (u_int command, u_long addr)
 103{
 104    srom_latch (command, addr);
 105    srom_latch ((command & 0x0000ff00) | DT_CS, addr);
 106    srom_latch (command, addr);
 107
 108    return;
 109}
 110
 111/*----------------------------------------------------------------------------*/
 112
 113static void srom_address(u_int command, u_long addr, u_char offset)
 114{
 115    int i;
 116    signed char a;
 117
 118    a = (char)(offset << 2);
 119    for (i=0; i<6; i++, a <<= 1)
 120    {
 121        srom_latch(command | ((a < 0) ? DT_IN : 0), addr);
 122    }
 123    udelay(1);
 124
 125    i = (getfrom_srom(addr) >> 3) & 0x01;
 126
 127    return;
 128}
 129/*----------------------------------------------------------------------------*/
 130
 131static short srom_data_rd (u_int command, u_long addr)
 132{
 133    int i;
 134    short word = 0;
 135    s32 tmp;
 136
 137    for (i=0; i<16; i++)
 138    {
 139        sendto_srom(command  | DT_CLK, addr);
 140        tmp = getfrom_srom(addr);
 141        sendto_srom(command, addr);
 142
 143        word = (word << 1) | ((tmp >> 3) & 0x01);
 144    }
 145
 146    sendto_srom(command & 0x0000ff00, addr);
 147
 148    return word;
 149}
 150
 151/*----------------------------------------------------------------------------*/
 152
 153static int srom_data_wr (u_int command, u_long addr, short val)
 154{
 155    int i;
 156    u_long longVal;
 157    s32 tmp;
 158
 159    longVal = (u_long)(le16_to_cpu(val));
 160
 161    for (i=0; i<16; i++)
 162    {
 163        tmp = (longVal & 0x8000)>>13;
 164
 165        sendto_srom (tmp | command, addr);
 166        sendto_srom (tmp | command  | DT_CLK, addr);
 167        sendto_srom (tmp | command, addr);
 168
 169        longVal = longVal<<1;
 170    }
 171
 172    sendto_srom(command & 0x0000ff00, addr);
 173    sendto_srom(command, addr);
 174
 175    tmp = 100;
 176    do
 177    {
 178        if ((getfrom_srom(dc_srom_iobase) & 0x8) == 0x8)
 179            break;
 180        udelay(1000);
 181    } while (--tmp);
 182
 183    if (tmp == 0)
 184    {
 185        printf("Write DEC21143 SRom timed out !\n");
 186        return (-1);
 187    }
 188
 189    return 0;
 190}
 191
 192
 193/*----------------------------------------------------------------------------*/
 194static short srom_rd (u_long addr, u_char offset)
 195{
 196    sendto_srom (SROM_RD | SROM_SR, addr);
 197    srom_latch (SROM_RD | SROM_SR | DT_CS, addr);
 198
 199    srom_command_rd (SROM_RD | SROM_SR | DT_IN | DT_CS, addr);
 200
 201    srom_address (SROM_RD | SROM_SR | DT_CS, addr, offset);
 202
 203    return srom_data_rd (SROM_RD | SROM_SR | DT_CS, addr);
 204}
 205
 206/*----------------------------------------------------------------------------*/
 207
 208static void srom_wr_enable (u_long addr)
 209{
 210    int i;
 211
 212    sendto_srom (SROM_WR | SROM_SR, addr);
 213    srom_latch (SROM_WR | SROM_SR | DT_CS, addr);
 214
 215    srom_latch (SROM_WR | SROM_SR | DT_IN | DT_CS, addr);
 216    srom_latch (SROM_WR | SROM_SR | DT_CS, addr);
 217    srom_latch (SROM_WR | SROM_SR | DT_CS, addr);
 218
 219    for (i=0; i<6; i++)
 220    {
 221        srom_latch (SROM_WR | SROM_SR | DT_IN | DT_CS, addr);
 222    }
 223}
 224
 225/*----------------------------------------------------------------------------*/
 226
 227static int srom_wr (u_long addr, u_char offset, short val)
 228{
 229    srom_wr_enable (addr);
 230
 231    sendto_srom (SROM_WR | SROM_SR, addr);
 232    srom_latch (SROM_WR | SROM_SR | DT_CS, addr);
 233
 234    srom_command_wr (SROM_WR | SROM_SR | DT_IN | DT_CS, addr);
 235
 236    srom_address (SROM_WR | SROM_SR | DT_CS, addr, offset);
 237
 238    return srom_data_wr (SROM_WR | SROM_SR | DT_CS, addr, val);
 239}
 240
 241/*----------------------------------------------------------------------------*/
 242/*
 243 * load data from the srom
 244 */
 245int dc_srom_load (u_short *dest)
 246{
 247    int offset;
 248    short tmp;
 249
 250    /* get srom iobase from local network controller */
 251    pci_read_config_dword(PCI_BDF(0,14,0), PCI_BASE_ADDRESS_1, &dc_srom_iobase);
 252    dc_srom_iobase &= PCI_BASE_ADDRESS_MEM_MASK;
 253    dc_srom_iobase  = pci_mem_to_phys(PCI_BDF(0,14,0), dc_srom_iobase);
 254    dc_srom_iobase += 0x48;            /* io offset for srom access */
 255
 256    memset (dest, 0, 128);
 257    for (offset=0; offset<64; offset++)
 258    {
 259        tmp = srom_rd (dc_srom_iobase, offset);
 260        *dest++ = le16_to_cpu(tmp);
 261    }
 262
 263    return (0);
 264}
 265
 266/*----------------------------------------------------------------------------*/
 267
 268/*
 269 * store data into the srom
 270 */
 271int dc_srom_store (u_short *src)
 272{
 273    int offset;
 274
 275    /* get srom iobase from local network controller */
 276    pci_read_config_dword(PCI_BDF(0,14,0), PCI_BASE_ADDRESS_1, &dc_srom_iobase);
 277    dc_srom_iobase &= PCI_BASE_ADDRESS_MEM_MASK;
 278    dc_srom_iobase  = pci_mem_to_phys(PCI_BDF(0,14,0), dc_srom_iobase);
 279    dc_srom_iobase += 0x48;            /* io offset for srom access */
 280
 281    for (offset=0; offset<64; offset++)
 282    {
 283        if (srom_wr (dc_srom_iobase, offset, *src) == -1)
 284                return (-1);
 285        src++;
 286    }
 287
 288    return (0);
 289}
 290
 291/*----------------------------------------------------------------------------*/
 292