uboot/board/pn62/misc.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2002 Wolfgang Grandegger <wg@denx.de>
   3 *
   4 * See file CREDITS for list of people who contributed to this
   5 * project.
   6 *
   7 * This program is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU General Public License as
   9 * published by the Free Software Foundation; either version 2 of
  10 * the License, or (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20 * MA 02111-1307 USA
  21 */
  22
  23#include <common.h>
  24#include <mpc824x.h>
  25#include <asm/io.h>
  26#include <pci.h>
  27
  28#include "pn62.h"
  29
  30typedef struct {
  31    pci_dev_t    devno;
  32    volatile u32 *csr;
  33
  34} i2155x_t;
  35
  36static i2155x_t i2155x = { 0, NULL };
  37
  38static struct pci_device_id i2155x_ids[] = {
  39    { 0x1011, 0x0046 },         /* i21554 */
  40    { 0x8086, 0xb555 }          /* i21555 */
  41};
  42
  43int i2155x_init(void)
  44{
  45    pci_dev_t devno;
  46    u32 val;
  47    int i;
  48
  49    /*
  50     * Find the Intel bridge.
  51     */
  52    if ((devno = pci_find_devices(i2155x_ids, 0)) < 0) {
  53        printf("Error: Intel bridge 2155x not found!\n");
  54        return -1;
  55    }
  56    i2155x.devno = devno;
  57
  58    /*
  59     * Get auto-configured base address for CSR access.
  60     */
  61    pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &val);
  62    if (val & PCI_BASE_ADDRESS_SPACE_IO) {
  63        val &= PCI_BASE_ADDRESS_IO_MASK;
  64        i2155x.csr = (volatile u32 *)(_IO_BASE + val);
  65    } else {
  66        val &= PCI_BASE_ADDRESS_MEM_MASK;
  67        i2155x.csr =  (volatile u32 *)val;
  68    }
  69
  70    /*
  71     * Translate downstream memory 2 (bar3) to base of shared memory.
  72     */
  73    i2155x_set_bar_base(3, PN62_SMEM_DEFAULT);
  74
  75    /*
  76     * Enable memory space, I/O space and bus master bits
  77     * in both Primary and Secondary command registers.
  78     */
  79    val = PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER|PCI_COMMAND_IO;
  80    pci_write_config_word(devno, 0x44, val);
  81    pci_write_config_word(devno, 0x04, val);
  82
  83    /*
  84     * Clear scratchpad registers.
  85     */
  86    for (i = 0; i < (I2155X_SCRAPAD_MAX - 1); i++) {
  87        i2155x_write_scrapad(i, 0x0);
  88    }
  89
  90    /*
  91     * Set interrupt line for Linux.
  92     */
  93    pci_write_config_byte(devno, PCI_INTERRUPT_LINE, 3);
  94
  95    return 0;
  96}
  97
  98/*
  99 * Access the Scratchpad registers 0..7 of the Intel bridge.
 100 */
 101void i2155x_write_scrapad(int idx, u32 val)
 102{
 103    if (idx >= 0 && idx < I2155X_SCRAPAD_MAX)
 104        out_le32(i2155x.csr + (I2155X_SCRAPAD_ADDR/4) + idx, val);
 105    else
 106        printf("i2155x_write_scrapad: invalid index\n");
 107}
 108
 109u32 i2155x_read_scrapad(int idx)
 110{
 111    if (idx >= 0 && idx < I2155X_SCRAPAD_MAX)
 112        return in_le32(i2155x.csr + (I2155X_SCRAPAD_ADDR/4) + idx);
 113    else
 114        printf("i2155x_read_scrapad: invalid index\n");
 115    return -1;
 116}
 117
 118void i2155x_set_bar_base(int bar, u32 base)
 119{
 120    if (bar >= 2 && bar <= 4) {
 121        pci_write_config_dword(i2155x.devno,
 122                               I2155X_BAR2_BASE + (bar - 2) * 4,
 123                               base);
 124    }
 125}
 126
 127/*
 128 * Read Vital Product Data (VPD) from the Serial EPROM attached
 129 * to the Intel bridge.
 130 */
 131int i2155x_read_vpd(int offset, int size, unsigned char *data)
 132{
 133    int i, n;
 134    u16 val16;
 135
 136    for (i = 0; i < size; i++) {
 137        pci_write_config_word(i2155x.devno, I2155X_VPD_ADDR,
 138                              offset + i - I2155X_VPD_START);
 139        for (n = 10000; n > 0; n--) {
 140            pci_read_config_word(i2155x.devno, I2155X_VPD_ADDR, &val16);
 141            if ((val16 & 0x8000) != 0) /* wait for completion */
 142                break;
 143            udelay(100);
 144        }
 145        if (n == 0) {
 146            printf("i2155x_read_vpd: TIMEOUT\n");
 147            return -1;
 148        }
 149
 150        pci_read_config_byte(i2155x.devno, I2155X_VPD_DATA, &data[i]);
 151    }
 152
 153    return i;
 154}
 155
 156static struct pci_device_id am79c95x_ids [] = {
 157        { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE },
 158        { }
 159};
 160
 161
 162/*
 163 * Initialize the AMD ethernet controllers.
 164 */
 165int am79c95x_init(void)
 166{
 167    pci_dev_t devno;
 168    int i;
 169
 170    /*
 171     * Set interrupt line for Linux.
 172     */
 173    for (i = 0; i < 2; i++) {
 174        if ((devno = pci_find_devices(am79c95x_ids, i)) < 0)
 175            break;
 176        pci_write_config_byte(devno, PCI_INTERRUPT_LINE, 2+i);
 177    }
 178    if (i < 2)
 179        printf("Error: Only %d AMD Ethernet Controller found!\n", i);
 180
 181    return 0;
 182}
 183
 184
 185void set_led(unsigned int number, unsigned int function)
 186{
 187    volatile u8 *addr;
 188
 189    if ((number >= 0) && (number < PN62_LED_MAX) &&
 190        (function >= 0) && (function <= LED_LAST_FUNCTION)) {
 191        addr = (volatile u8 *)(PN62_LED_BASE + number * 8);
 192        out_8(addr, function&0xff);
 193    }
 194}
 195
 196/*
 197 * Show fatal error indicated by Kinght Rider(tm) effect
 198 * in LEDS 0-7. LEDS 8-11 contain 4 bit error code.
 199 * Note: this function will not terminate.
 200 */
 201void fatal_error(unsigned int error_code)
 202{
 203    int i, d;
 204
 205    for (i = 0; i < 12; i++) {
 206        set_led(i, LED_0);
 207    }
 208
 209    /*
 210     * Write error code.
 211     */
 212    set_led(8,  (error_code & 0x01) ? LED_1 : LED_0);
 213    set_led(9,  (error_code & 0x02) ? LED_1 : LED_0);
 214    set_led(10, (error_code & 0x04) ? LED_1 : LED_0);
 215    set_led(11, (error_code & 0x08) ? LED_1 : LED_0);
 216
 217    /*
 218     * Yay - Knight Rider effect!
 219     */
 220    while(1) {
 221        unsigned int delay = 2000;
 222
 223        for (i = 0; i < 8; i++) {
 224            set_led(i, LED_1);
 225            for (d = 0; d < delay; d++);
 226            set_led(i, LED_0);
 227        }
 228
 229        for (i = 7; i > 0; i--) {
 230            set_led(i, LED_1);
 231            for (d = 0; d < delay; d++);
 232            set_led(i, LED_0);
 233        }
 234    }
 235}
 236