summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorWolfgang Denk <wd@denx.de>2011-06-23 15:37:33 +0200
committerWolfgang Denk <wd@denx.de>2011-06-23 15:37:33 +0200
commit9623c158f6a5150a21c25026bfba79e7ff7912f5 (patch)
tree2c4d4209a34baa810a6f3fb409e1f8e494f01b31 /drivers
parent2ad6e27dcdbd694de8e3823d2b52b250b1a59219 (diff)
parent1ed63c549892bc3a4ce1a43f09a6a92a00054f3d (diff)
downloadu-boot-imx-9623c158f6a5150a21c25026bfba79e7ff7912f5.zip
u-boot-imx-9623c158f6a5150a21c25026bfba79e7ff7912f5.tar.gz
u-boot-imx-9623c158f6a5150a21c25026bfba79e7ff7912f5.tar.bz2
Merge branch 'master' of git://git.denx.de/u-boot-arm
* 'master' of git://git.denx.de/u-boot-arm: run arm_pci_init after relocation IXP42x PCI rewrite update/fix PDNB3 board update/fix IXDP425 / IXDPG425 boards add dvlhost (dLAN 200 AV Wireless G) board IXP NPE: add support for fixed-speed MII ports update/fix AcTux4 board update/fix AcTux3 board update/fix AcTux2 board update/fix AcTux1 board use -ffunction-sections / --gc-sections on IXP42x support CONFIG_SYS_LDSCRIPT on ARM fix "depend" target in npe directory Fix IXP code to work after relocation was added trigger hardware watchdog in IXP42x serial driver add support for IXP42x Rev. B1 and newer add XScale sub architecture (IXP/PXA) to maintainer list Conflicts: arch/arm/lib/board.c Signed-off-by: Wolfgang Denk <wd@denx.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/pci.c4
-rw-r--r--drivers/pci/pci_indirect.c13
-rw-r--r--drivers/pci/pci_ixp.c612
-rw-r--r--drivers/serial/serial_ixp.c7
4 files changed, 211 insertions, 425 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index cdfc4fb..1a0b14c 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -50,7 +50,6 @@ PCI_HOSE_OP(write, byte, u8)
PCI_HOSE_OP(write, word, u16)
PCI_HOSE_OP(write, dword, u32)
-#ifndef CONFIG_IXP425
#define PCI_OP(rw, size, type, error_code) \
int pci_##rw##_config_##size(pci_dev_t dev, int offset, type value) \
{ \
@@ -71,7 +70,6 @@ PCI_OP(read, dword, u32 *, *value = 0xffffffff)
PCI_OP(write, byte, u8, )
PCI_OP(write, word, u16, )
PCI_OP(write, dword, u32, )
-#endif /* CONFIG_IXP425 */
#define PCI_READ_VIA_DWORD_OP(size, type, off_mask) \
int pci_hose_read_config_##size##_via_dword(struct pci_controller *hose,\
@@ -190,7 +188,6 @@ int pci_last_busno(void)
return hose->last_busno;
}
-#ifndef CONFIG_IXP425
pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
{
struct pci_controller * hose;
@@ -246,7 +243,6 @@ pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
return (-1);
}
-#endif /* CONFIG_IXP425 */
pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
{
diff --git a/drivers/pci/pci_indirect.c b/drivers/pci/pci_indirect.c
index 2070d01..526a55c 100644
--- a/drivers/pci/pci_indirect.c
+++ b/drivers/pci/pci_indirect.c
@@ -11,7 +11,7 @@
#include <common.h>
-#if (!defined(__I386__) && !defined(CONFIG_IXDP425))
+#if !defined(__I386__)
#include <asm/processor.h>
#include <asm/io.h>
@@ -20,15 +20,6 @@
#define cfg_read(val, addr, type, op) *val = op((type)(addr))
#define cfg_write(val, addr, type, op) op((type *)(addr), (val))
-#ifdef CONFIG_IXP425
-extern unsigned char in_8 (volatile unsigned *addr);
-extern unsigned short in_le16 (volatile unsigned *addr);
-extern unsigned in_le32 (volatile unsigned *addr);
-extern void out_8 (volatile unsigned *addr, char val);
-extern void out_le16 (volatile unsigned *addr, unsigned short val);
-extern void out_le32 (volatile unsigned *addr, unsigned int val);
-#endif /* CONFIG_IXP425 */
-
#if defined(CONFIG_MPC8260)
#define INDIRECT_PCI_OP(rw, size, type, op, mask) \
static int \
@@ -134,4 +125,4 @@ void pci_setup_indirect(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data)
hose->cfg_data = (unsigned char *) cfg_data;
}
-#endif /* !__I386__ && !CONFIG_IXDP425 */
+#endif /* !__I386__ */
diff --git a/drivers/pci/pci_ixp.c b/drivers/pci/pci_ixp.c
index 3b303b4..5b5c915 100644
--- a/drivers/pci/pci_ixp.c
+++ b/drivers/pci/pci_ixp.c
@@ -1,5 +1,8 @@
/*
* IXP PCI Init
+ *
+ * (C) Copyright 2011
+ * Michael Schwingen, michael@schwingen.org
* (C) Copyright 2004 eslab.whut.edu.cn
* Yue Hu(huyue_whut@yahoo.com.cn), Ligong Xue(lgxue@hotmail.com)
*
@@ -22,7 +25,6 @@
* MA 02111-1307 USA
*/
-
#include <common.h>
#include <asm/processor.h>
#include <asm/io.h>
@@ -30,542 +32,336 @@
#include <asm/arch/ixp425.h>
#include <asm/arch/ixp425pci.h>
-static void non_prefetch_read (unsigned int addr, unsigned int cmd,
- unsigned int *data);
-static void non_prefetch_write (unsigned int addr, unsigned int cmd,
- unsigned int data);
-static void configure_pins (void);
-static void sys_pci_gpio_clock_config (void);
-static void pci_bus_scan (void);
-static int pci_device_exists (unsigned int deviceNo);
-static void sys_pci_bar_info_get (unsigned int devnum, unsigned int bus,
- unsigned int dev, unsigned int func);
-static void sys_pci_device_bars_write (void);
-static void calc_bars (PciBar * Bars[], unsigned int nBars,
- unsigned int startAddr);
+DECLARE_GLOBAL_DATA_PTR;
+
+static void non_prefetch_read(unsigned int addr, unsigned int cmd,
+ unsigned int *data);
+static void non_prefetch_write(unsigned int addr, unsigned int cmd,
+ unsigned int data);
+
+/*define the sub vendor and subsystem to be used */
+#define IXP425_PCI_SUB_VENDOR_SYSTEM 0x00000000
#define PCI_MEMORY_BUS 0x00000000
-#define PCI_MEMORY_PHY 0x48000000
+#define PCI_MEMORY_PHY 0x00000000
#define PCI_MEMORY_SIZE 0x04000000
-#define PCI_MEM_BUS 0x40000000
+#define PCI_MEM_BUS 0x48000000
#define PCI_MEM_PHY 0x00000000
#define PCI_MEM_SIZE 0x04000000
-#define PCI_IO_BUS 0x40000000
-#define PCI_IO_PHY 0x50000000
-#define PCI_IO_SIZE 0x10000000
+#define PCI_IO_BUS 0x00000000
+#define PCI_IO_PHY 0x00000000
+#define PCI_IO_SIZE 0x00010000
+
+/* build address value for config sycle */
+static unsigned int pci_config_addr(pci_dev_t bdf, unsigned int reg)
+{
+ unsigned int bus = PCI_BUS(bdf);
+ unsigned int dev = PCI_DEV(bdf);
+ unsigned int func = PCI_FUNC(bdf);
+ unsigned int addr;
+
+ if (bus) { /* secondary bus, use type 1 config cycle */
+ addr = bdf | (reg & ~3) | 1;
+ } else {
+ /*
+ primary bus, type 0 config cycle. address bits 31:28
+ specify the device 10:8 specify the function
+ */
+ addr = BIT((31 - dev)) | (func << 8) | (reg & ~3);
+ }
+
+ return addr;
+}
+
+static int pci_config_status(void)
+{
+ unsigned int regval;
-struct pci_controller hose;
+ regval = readl(PCI_CSR_BASE + PCI_ISR_OFFSET);
+ if ((regval & PCI_ISR_PFE) == 0)
+ return OK;
-unsigned int nDevices;
-unsigned int nMBars;
-unsigned int nIOBars;
-PciBar *memBars[IXP425_PCI_MAX_BAR];
-PciBar *ioBars[IXP425_PCI_MAX_BAR];
-PciDevice devices[IXP425_PCI_MAX_FUNC_ON_BUS];
+ /* no device present, make sure that the master abort bit is reset */
+ writel(PCI_ISR_PFE, PCI_CSR_BASE + PCI_ISR_OFFSET);
+ return ERROR;
+}
-int pci_read_config_dword (pci_dev_t dev, int where, unsigned int *val)
+static int pci_ixp_hose_read_config_dword(struct pci_controller *hose,
+ pci_dev_t bdf, int where, unsigned int *val)
{
unsigned int retval;
unsigned int addr;
+ int stat;
- /*address bits 31:28 specify the device 10:8 specify the function */
+ debug("pci_ixp_hose_read_config_dword: bdf %x, reg %x", bdf, where);
/*Set the address to be read */
- addr = BIT ((31 - dev)) | (where & ~3);
- non_prefetch_read (addr, NP_CMD_CONFIGREAD, &retval);
-
+ addr = pci_config_addr(bdf, where);
+ non_prefetch_read(addr, NP_CMD_CONFIGREAD, &retval);
*val = retval;
- return (OK);
+ stat = pci_config_status();
+ if (stat < 0)
+ *val = -1;
+ debug("-> val %x, status %x\n", *val, stat);
+ return stat;
}
-int pci_read_config_word (pci_dev_t dev, int where, unsigned short *val)
+static int pci_ixp_hose_read_config_word(struct pci_controller *hose,
+ pci_dev_t bdf, int where, unsigned short *val)
{
unsigned int n;
unsigned int retval;
unsigned int addr;
unsigned int byteEnables;
+ int stat;
+ debug("pci_ixp_hose_read_config_word: bdf %x, reg %x", bdf, where);
n = where % 4;
/*byte enables are 4 bits active low, the position of each
bit maps to the byte that it enables */
byteEnables =
- (~(BIT (n) | BIT ((n + 1)))) &
+ (~(BIT(n) | BIT((n + 1)))) &
IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
byteEnables = byteEnables << PCI_NP_CBE_BESL;
- /*address bits 31:28 specify the device 10:8 specify the function */
/*Set the address to be read */
- addr = BIT ((31 - dev)) | (where & ~3);
- non_prefetch_read (addr, byteEnables | NP_CMD_CONFIGREAD, &retval);
+ addr = pci_config_addr(bdf, where);
+ non_prefetch_read(addr, byteEnables | NP_CMD_CONFIGREAD, &retval);
/*Pick out the word we are interested in */
- *val = (retval >> (8 * n));
+ *val = retval >> (8 * n);
- return (OK);
+ stat = pci_config_status();
+ if (stat < 0)
+ *val = -1;
+ debug("-> val %x, status %x\n", *val, stat);
+ return stat;
}
-int pci_read_config_byte (pci_dev_t dev, int where, unsigned char *val)
+static int pci_ixp_hose_read_config_byte(struct pci_controller *hose,
+ pci_dev_t bdf, int where, unsigned char *val)
{
unsigned int retval;
unsigned int n;
unsigned int byteEnables;
unsigned int addr;
+ int stat;
+ debug("pci_ixp_hose_read_config_byte: bdf %x, reg %x", bdf, where);
n = where % 4;
/*byte enables are 4 bits, active low, the position of each
bit maps to the byte that it enables */
- byteEnables = (~BIT (n)) & IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
+ byteEnables = (~BIT(n)) & IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
byteEnables = byteEnables << PCI_NP_CBE_BESL;
- /*address bits 31:28 specify the device, 10:8 specify the function */
/*Set the address to be read */
- addr = BIT ((31 - dev)) | (where & ~3);
- non_prefetch_read (addr, byteEnables | NP_CMD_CONFIGREAD, &retval);
+ addr = pci_config_addr(bdf, where);
+ non_prefetch_read(addr, byteEnables | NP_CMD_CONFIGREAD, &retval);
/*Pick out the byte we are interested in */
- *val = (retval >> (8 * n));
+ *val = retval >> (8 * n);
- return (OK);
+ stat = pci_config_status();
+ if (stat < 0)
+ *val = -1;
+ debug("-> val %x, status %x\n", *val, stat);
+ return stat;
}
-int pci_write_config_byte (pci_dev_t dev, int where, unsigned char val)
+static int pci_ixp_hose_write_config_byte(struct pci_controller *hose,
+ pci_dev_t bdf, int where, unsigned char val)
{
unsigned int addr;
unsigned int byteEnables;
unsigned int n;
unsigned int ldata;
+ int stat;
+ debug("pci_ixp_hose_write_config_byte: bdf %x, reg %x, val %x",
+ bdf, where, val);
n = where % 4;
/*byte enables are 4 bits active low, the position of each
bit maps to the byte that it enables */
- byteEnables = (~BIT (n)) & IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
+ byteEnables = (~BIT(n)) & IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
byteEnables = byteEnables << PCI_NP_CBE_BESL;
ldata = val << (8 * n);
- /*address bits 31:28 specify the device 10:8 specify the function */
/*Set the address to be written */
- addr = BIT ((31 - dev)) | (where & ~3);
- non_prefetch_write (addr, byteEnables | NP_CMD_CONFIGWRITE, ldata);
+ addr = pci_config_addr(bdf, where);
+ non_prefetch_write(addr, byteEnables | NP_CMD_CONFIGWRITE, ldata);
- return (OK);
+ stat = pci_config_status();
+ debug("-> status %x\n", stat);
+ return stat;
}
-int pci_write_config_word (pci_dev_t dev, int where, unsigned short val)
+static int pci_ixp_hose_write_config_word(struct pci_controller *hose,
+ pci_dev_t bdf, int where, unsigned short val)
{
unsigned int addr;
unsigned int byteEnables;
unsigned int n;
unsigned int ldata;
+ int stat;
+ debug("pci_ixp_hose_write_config_word: bdf %x, reg %x, val %x",
+ bdf, where, val);
n = where % 4;
/*byte enables are 4 bits active low, the position of each
bit maps to the byte that it enables */
byteEnables =
- (~(BIT (n) | BIT ((n + 1)))) &
+ (~(BIT(n) | BIT((n + 1)))) &
IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
byteEnables = byteEnables << PCI_NP_CBE_BESL;
ldata = val << (8 * n);
- /*address bits 31:28 specify the device 10:8 specify the function */
/*Set the address to be written */
- addr = BIT (31 - dev) | (where & ~3);
- non_prefetch_write (addr, byteEnables | NP_CMD_CONFIGWRITE, ldata);
+ addr = pci_config_addr(bdf, where);
+ non_prefetch_write(addr, byteEnables | NP_CMD_CONFIGWRITE, ldata);
- return (OK);
+ stat = pci_config_status();
+ debug("-> status %x\n", stat);
+ return stat;
}
-int pci_write_config_dword (pci_dev_t dev, int where, unsigned int val)
+static int pci_ixp_hose_write_config_dword(struct pci_controller *hose,
+ pci_dev_t bdf, int where, unsigned int val)
{
unsigned int addr;
+ int stat;
- /*address bits 31:28 specify the device 10:8 specify the function */
+ debug("pci_ixp_hose_write_config_dword: bdf %x, reg %x, val %x",
+ bdf, where, val);
/*Set the address to be written */
- addr = BIT (31 - dev) | (where & ~3);
- non_prefetch_write (addr, NP_CMD_CONFIGWRITE, val);
+ addr = pci_config_addr(bdf, where);
+ non_prefetch_write(addr, NP_CMD_CONFIGWRITE, val);
- return (OK);
+ stat = pci_config_status();
+ debug("-> status %x\n", stat);
+ return stat;
}
-void non_prefetch_read (unsigned int addr,
- unsigned int cmd, unsigned int *data)
+static void non_prefetch_read(unsigned int addr,
+ unsigned int cmd, unsigned int *data)
{
- REG_WRITE (PCI_CSR_BASE, PCI_NP_AD_OFFSET, addr);
+ writel(addr, PCI_CSR_BASE + PCI_NP_AD_OFFSET);
/*set up and execute the read */
- REG_WRITE (PCI_CSR_BASE, PCI_NP_CBE_OFFSET, cmd);
+ writel(cmd, PCI_CSR_BASE + PCI_NP_CBE_OFFSET);
/*The result of the read is now in np_rdata */
- REG_READ (PCI_CSR_BASE, PCI_NP_RDATA_OFFSET, *data);
+ *data = readl(PCI_CSR_BASE + PCI_NP_RDATA_OFFSET);
return;
}
-void non_prefetch_write (unsigned int addr,
- unsigned int cmd, unsigned int data)
+static void non_prefetch_write(unsigned int addr,
+ unsigned int cmd, unsigned int data)
{
- REG_WRITE (PCI_CSR_BASE, PCI_NP_AD_OFFSET, addr);
+ writel(addr, PCI_CSR_BASE + PCI_NP_AD_OFFSET);
/*set up the write */
- REG_WRITE (PCI_CSR_BASE, PCI_NP_CBE_OFFSET, cmd);
+ writel(cmd, PCI_CSR_BASE + PCI_NP_CBE_OFFSET);
/*Execute the write by writing to NP_WDATA */
- REG_WRITE (PCI_CSR_BASE, PCI_NP_WDATA_OFFSET, data);
+ writel(data, PCI_CSR_BASE + PCI_NP_WDATA_OFFSET);
return;
}
-/*
- * PCI controller config registers are accessed through these functions
- * i.e. these allow us to set up our own BARs etc.
- */
-void crp_read (unsigned int offset, unsigned int *data)
+static void crp_write(unsigned int offset, unsigned int data)
{
- REG_WRITE (PCI_CSR_BASE, PCI_CRP_AD_CBE_OFFSET, offset);
- REG_READ (PCI_CSR_BASE, PCI_CRP_RDATA_OFFSET, *data);
-}
-
-void crp_write (unsigned int offset, unsigned int data)
-{
- /*The CRP address register bit 16 indicates that we want to do a write */
- REG_WRITE (PCI_CSR_BASE, PCI_CRP_AD_CBE_OFFSET,
- PCI_CRP_WRITE | offset);
- REG_WRITE (PCI_CSR_BASE, PCI_CRP_WDATA_OFFSET, data);
-}
-
-/*struct pci_controller *hose*/
-void pci_ixp_init (struct pci_controller *hose)
-{
- unsigned int regval;
-
- hose->first_busno = 0;
- hose->last_busno = 0x00;
-
- /* System memory space */
- pci_set_region (hose->regions + 0,
- PCI_MEMORY_BUS,
- PCI_MEMORY_PHY, PCI_MEMORY_SIZE, PCI_REGION_SYS_MEMORY);
-
- /* PCI memory space */
- pci_set_region (hose->regions + 1,
- PCI_MEM_BUS,
- PCI_MEM_PHY, PCI_MEM_SIZE, PCI_REGION_MEM);
- /* PCI I/O space */
- pci_set_region (hose->regions + 2,
- PCI_IO_BUS, PCI_IO_PHY, PCI_IO_SIZE, PCI_REGION_IO);
-
- hose->region_count = 3;
-
- pci_register_hose (hose);
-
-/*
- ==========================================================
- Init IXP PCI
- ==========================================================
-*/
- REG_READ (PCI_CSR_BASE, PCI_CSR_OFFSET, regval);
- regval |= 1 << 2;
- REG_WRITE (PCI_CSR_BASE, PCI_CSR_OFFSET, regval);
-
- configure_pins ();
-
- READ_GPIO_REG (IXP425_GPIO_GPOUTR, regval);
- WRITE_GPIO_REG (IXP425_GPIO_GPOUTR, regval & (~(1 << 13)));
- udelay (533);
- sys_pci_gpio_clock_config ();
- REG_WRITE (PCI_CSR_BASE, PCI_INTEN_OFFSET, 0);
- udelay (100);
- READ_GPIO_REG (IXP425_GPIO_GPOUTR, regval);
- WRITE_GPIO_REG (IXP425_GPIO_GPOUTR, regval | (1 << 13));
- udelay (533);
- crp_write (PCI_CFG_BASE_ADDRESS_0, IXP425_PCI_BAR_0_DEFAULT);
- crp_write (PCI_CFG_BASE_ADDRESS_1, IXP425_PCI_BAR_1_DEFAULT);
- crp_write (PCI_CFG_BASE_ADDRESS_2, IXP425_PCI_BAR_2_DEFAULT);
- crp_write (PCI_CFG_BASE_ADDRESS_3, IXP425_PCI_BAR_3_DEFAULT);
- crp_write (PCI_CFG_BASE_ADDRESS_4, IXP425_PCI_BAR_4_DEFAULT);
- crp_write (PCI_CFG_BASE_ADDRESS_5, IXP425_PCI_BAR_5_DEFAULT);
- /*Setup PCI-AHB and AHB-PCI address mappings */
- REG_WRITE (PCI_CSR_BASE, PCI_AHBMEMBASE_OFFSET,
- IXP425_PCI_AHBMEMBASE_DEFAULT);
-
- REG_WRITE (PCI_CSR_BASE, PCI_AHBIOBASE_OFFSET,
- IXP425_PCI_AHBIOBASE_DEFAULT);
-
- REG_WRITE (PCI_CSR_BASE, PCI_PCIMEMBASE_OFFSET,
- IXP425_PCI_PCIMEMBASE_DEFAULT);
-
- crp_write (PCI_CFG_SUB_VENDOR_ID, IXP425_PCI_SUB_VENDOR_SYSTEM);
-
- REG_READ (PCI_CSR_BASE, PCI_CSR_OFFSET, regval);
- regval |= PCI_CSR_IC | PCI_CSR_ABE | PCI_CSR_PDS;
- REG_WRITE (PCI_CSR_BASE, PCI_CSR_OFFSET, regval);
- crp_write (PCI_CFG_COMMAND, PCI_CFG_CMD_MAE | PCI_CFG_CMD_BME);
- udelay (1000);
-
- pci_write_config_word (0, PCI_CFG_COMMAND, INITIAL_PCI_CMD);
- REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PSE
- | PCI_ISR_PFE | PCI_ISR_PPE | PCI_ISR_AHBE);
-#ifdef CONFIG_PCI_SCAN_SHOW
- printf ("Device bus dev func deviceID vendorID \n");
-#endif
- pci_bus_scan ();
-}
-
-void configure_pins (void)
-{
- unsigned int regval;
-
- /* Disable clock on GPIO PIN 14 */
- READ_GPIO_REG (IXP425_GPIO_GPCLKR, regval);
- WRITE_GPIO_REG (IXP425_GPIO_GPCLKR, regval & (~(1 << 8)));
- READ_GPIO_REG (IXP425_GPIO_GPCLKR, regval);
-
- READ_GPIO_REG (IXP425_GPIO_GPOER, regval);
- WRITE_GPIO_REG (IXP425_GPIO_GPOER,
- (((~(3 << 13)) & regval) | (0xf << 8)));
- READ_GPIO_REG (IXP425_GPIO_GPOER, regval);
-
- READ_GPIO_REG (IXP425_GPIO_GPIT2R, regval);
- WRITE_GPIO_REG (IXP425_GPIO_GPIT2R,
- (regval &
- ((0x1 << 9) | (0x1 << 6) | (0x1 << 3) | 0x1)));
- READ_GPIO_REG (IXP425_GPIO_GPIT2R, regval);
-
- READ_GPIO_REG (IXP425_GPIO_GPISR, regval);
- WRITE_GPIO_REG (IXP425_GPIO_GPISR, (regval | (0xf << 8)));
- READ_GPIO_REG (IXP425_GPIO_GPISR, regval);
+ /*
+ * The CRP address register bit 16 indicates that we want to do a
+ * write
+ */
+ writel(PCI_CRP_WRITE | offset, PCI_CSR_BASE + PCI_CRP_AD_CBE_OFFSET);
+ writel(data, PCI_CSR_BASE + PCI_CRP_WDATA_OFFSET);
}
-void sys_pci_gpio_clock_config (void)
+void pci_ixp_init(struct pci_controller *hose)
{
- unsigned int regval;
-
- READ_GPIO_REG (IXP425_GPIO_GPCLKR, regval);
- regval |= 0x1 << 4;
- WRITE_GPIO_REG (IXP425_GPIO_GPCLKR, regval);
- READ_GPIO_REG (IXP425_GPIO_GPCLKR, regval);
- regval |= 0x1 << 8;
- WRITE_GPIO_REG (IXP425_GPIO_GPCLKR, regval);
-}
+ unsigned int csr;
-void pci_bus_scan (void)
-{
- unsigned int bus = 0, dev, func = 0;
- unsigned short data16;
- unsigned int data32;
- unsigned char intPin;
-
- /* Assign first device to ourselves */
- devices[0].bus = 0;
- devices[0].device = 0;
- devices[0].func = 0;
-
- crp_read (PCI_CFG_VENDOR_ID, &data32);
-
- devices[0].vendor_id = data32 & IXP425_PCI_BOTTOM_WORD_OF_LONG_MASK;
- devices[0].device_id = data32 >> 16;
- devices[0].error = FALSE;
- devices[0].bar[NO_BAR].size = 0; /*dummy - required */
-
- nDevices = 1;
-
- nMBars = 0;
- nIOBars = 0;
-
- for (dev = 0; dev < IXP425_PCI_MAX_DEV; dev++) {
-
- /*Check whether a device is present */
- if (pci_device_exists (dev) != TRUE) {
-
- /*Clear error bits in ISR, write 1 to clear */
- REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PSE
- | PCI_ISR_PFE | PCI_ISR_PPE |
- PCI_ISR_AHBE);
- continue;
- }
-
- /*A device is present, add an entry to the array */
- devices[nDevices].bus = bus;
- devices[nDevices].device = dev;
- devices[nDevices].func = func;
-
- pci_read_config_word (dev, PCI_CFG_VENDOR_ID, &data16);
-
- devices[nDevices].vendor_id = data16;
-
- pci_read_config_word (dev, PCI_CFG_DEVICE_ID, &data16);
- devices[nDevices].device_id = data16;
-
- /*The device is functioning correctly, set error to FALSE */
- devices[nDevices].error = FALSE;
-
- /*Figure out what BARs are on this device */
- sys_pci_bar_info_get (nDevices, bus, dev, func);
- /*Figure out what INTX# line the card uses */
- pci_read_config_byte (dev, PCI_CFG_DEV_INT_PIN, &intPin);
-
- /*assign the appropriate irq line */
- if (intPin > PCI_IRQ_LINES) {
- devices[nDevices].error = TRUE;
- } else if (intPin != 0) {
- /*This device uses an interrupt line */
- /*devices[nDevices].irq = ixp425PciIntTranslate[dev][intPin-1]; */
- devices[nDevices].irq = intPin;
- }
-#ifdef CONFIG_PCI_SCAN_SHOW
- printf ("%06d %03d %03d %04d %08d %08x\n", nDevices,
- devices[nDevices].vendor_id);
+ /*
+ * Specify that the AHB bus is operating in big endian mode. Set up
+ * byte lane swapping between little-endian PCI and the big-endian
+ * AHB bus
+ */
+#ifdef __ARMEB__
+ csr = PCI_CSR_ABE | PCI_CSR_PDS | PCI_CSR_ADS;
+#else
+ csr = PCI_CSR_ABE;
#endif
- nDevices++;
-
- }
-
- calc_bars (memBars, nMBars, IXP425_PCI_BAR_MEM_BASE);
- sys_pci_device_bars_write ();
-
- REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PSE
- | PCI_ISR_PFE | PCI_ISR_PPE | PCI_ISR_AHBE);
-}
-
-void sys_pci_bar_info_get (unsigned int devnum,
- unsigned int bus,
- unsigned int dev, unsigned int func)
-{
- unsigned int data32;
- unsigned int tmp;
- unsigned int size;
-
- pci_write_config_dword (devnum,
- PCI_CFG_BASE_ADDRESS_0, IXP425_PCI_BAR_QUERY);
- pci_read_config_dword (devnum, PCI_CFG_BASE_ADDRESS_0, &data32);
+ writel(csr, PCI_CSR_BASE + PCI_CSR_OFFSET);
- devices[devnum].bar[0].address = (data32 & 1);
+ writel(0, PCI_CSR_BASE + PCI_INTEN_OFFSET);
- if (data32 & 1) {
- /* IO space */
- tmp = data32 & ~0x3;
- size = ~(tmp - 1);
- devices[devnum].bar[0].size = size;
-
- if (nIOBars < IXP425_PCI_MAX_BAR) {
- ioBars[nIOBars++] = &devices[devnum].bar[0];
- }
- } else {
- /* Mem space */
- tmp = data32 & ~IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
- size = ~(tmp - 1);
- devices[devnum].bar[0].size = size;
-
- if (nMBars < IXP425_PCI_MAX_BAR) {
- memBars[nMBars++] = &devices[devnum].bar[0];
- } else {
- devices[devnum].error = TRUE;
- }
-
- }
-
- devices[devnum].bar[1].size = 0;
-}
-
-void sortBars (PciBar * Bars[], unsigned int nBars)
-{
- unsigned int i, j;
- PciBar *tmp;
-
- if (nBars == 0) {
- return;
- }
-
- /* Sort biggest to smallest */
- for (i = 0; i < nBars - 1; i++) {
- for (j = i + 1; j < nBars; j++) {
- if (Bars[j]->size > Bars[i]->size) {
- /* swap them */
- tmp = Bars[i];
- Bars[i] = Bars[j];
- Bars[j] = tmp;
- }
- }
- }
-}
+ /*
+ * We configure the PCI inbound memory windows to be
+ * 1:1 mapped to SDRAM
+ */
+ crp_write(PCI_CFG_BASE_ADDRESS_0, 0x00000000);
+ crp_write(PCI_CFG_BASE_ADDRESS_1, 0x01000000);
+ crp_write(PCI_CFG_BASE_ADDRESS_2, 0x02000000);
+ crp_write(PCI_CFG_BASE_ADDRESS_3, 0x03000000);
+
+ /*
+ * Enable CSR window at 64 MiB to allow PCI masters
+ * to continue prefetching past 64 MiB boundary.
+ */
+ crp_write(PCI_CFG_BASE_ADDRESS_4, 0x04000000);
+ /*
+ * Enable the IO window to be way up high, at 0xfffffc00
+ */
+ crp_write(PCI_CFG_BASE_ADDRESS_5, 0xfffffc01);
-void calc_bars (PciBar * Bars[], unsigned int nBars, unsigned int startAddr)
-{
- unsigned int i;
+ /*Setup PCI-AHB and AHB-PCI address mappings */
+ writel(0x00010203, PCI_CSR_BASE + PCI_AHBMEMBASE_OFFSET);
- if (nBars == 0) {
- return;
- }
+ writel(0x00000000, PCI_CSR_BASE + PCI_AHBIOBASE_OFFSET);
- for (i = 0; i < nBars; i++) {
- Bars[i]->address |= startAddr;
- startAddr += Bars[i]->size;
- }
-}
+ writel(0x48494a4b, PCI_CSR_BASE + PCI_PCIMEMBASE_OFFSET);
-void sys_pci_device_bars_write (void)
-{
- unsigned int i;
- int addr;
-
- for (i = 1; i < nDevices; i++) {
- if (devices[i].error) {
- continue;
- }
-
- pci_write_config_dword (devices[i].device,
- PCI_CFG_BASE_ADDRESS_0,
- devices[i].bar[0].address);
- addr = BIT (31 - devices[i].device) |
- (0 << PCI_NP_AD_FUNCSL) |
- (PCI_CFG_BASE_ADDRESS_0 & ~3);
- pci_write_config_dword (devices[i].device,
- PCI_CFG_DEV_INT_LINE, devices[i].irq);
-
- pci_write_config_word (devices[i].device,
- PCI_CFG_COMMAND, INITIAL_PCI_CMD);
+ crp_write(PCI_CFG_SUB_VENDOR_ID, IXP425_PCI_SUB_VENDOR_SYSTEM);
- }
-}
+ crp_write(PCI_CFG_COMMAND, PCI_CFG_CMD_MAE | PCI_CFG_CMD_BME);
+ udelay(1000);
+ /* clear error bits in status register */
+ writel(PCI_ISR_PSE | PCI_ISR_PFE | PCI_ISR_PPE | PCI_ISR_AHBE,
+ PCI_CSR_BASE + PCI_ISR_OFFSET);
-int pci_device_exists (unsigned int deviceNo)
-{
- unsigned int vendorId;
- unsigned int regval;
-
- pci_read_config_dword (deviceNo, PCI_CFG_VENDOR_ID, &vendorId);
-
- /* There are two ways to find out an empty device.
- * 1. check Master Abort bit after the access.
- * 2. check whether the vendor id read back is 0x0.
+ /*
+ * Set Initialize Complete in PCI Control Register: allow IXP4XX to
+ * respond to PCI configuration cycles.
*/
- REG_READ (PCI_CSR_BASE, PCI_ISR_OFFSET, regval);
- if ((vendorId != 0x0) && ((regval & PCI_ISR_PFE) == 0)) {
- return TRUE;
- }
- /*no device present, make sure that the master abort bit is reset */
+ csr |= PCI_CSR_IC;
+ writel(csr, PCI_CSR_BASE + PCI_CSR_OFFSET);
- REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PFE);
- return FALSE;
-}
+ hose->first_busno = 0;
+ hose->last_busno = 0;
-pci_dev_t pci_find_devices (struct pci_device_id * ids, int devNo)
-{
- unsigned int i;
- unsigned int devdidvid;
- unsigned int didvid;
- unsigned int vendorId, deviceId;
+ /* System memory space */
+ pci_set_region(hose->regions + 0,
+ PCI_MEMORY_BUS,
+ PCI_MEMORY_PHY, PCI_MEMORY_SIZE, PCI_REGION_SYS_MEMORY);
- vendorId = ids->vendor;
- deviceId = ids->device;
- didvid = ((deviceId << 16) & IXP425_PCI_TOP_WORD_OF_LONG_MASK) |
- (vendorId & IXP425_PCI_BOTTOM_WORD_OF_LONG_MASK);
+ /* PCI memory space */
+ pci_set_region(hose->regions + 1,
+ PCI_MEM_BUS,
+ PCI_MEM_PHY, PCI_MEM_SIZE, PCI_REGION_MEM);
+ /* PCI I/O space */
+ pci_set_region(hose->regions + 2,
+ PCI_IO_BUS, PCI_IO_PHY, PCI_IO_SIZE, PCI_REGION_IO);
- for (i = devNo + 1; i < nDevices; i++) {
+ hose->region_count = 3;
- pci_read_config_dword (devices[i].device, PCI_CFG_VENDOR_ID,
- &devdidvid);
+ pci_set_ops(hose,
+ pci_ixp_hose_read_config_byte,
+ pci_ixp_hose_read_config_word,
+ pci_ixp_hose_read_config_dword,
+ pci_ixp_hose_write_config_byte,
+ pci_ixp_hose_write_config_word,
+ pci_ixp_hose_write_config_dword);
- if (devdidvid == didvid) {
- return devices[i].device;
- }
- }
- return -1;
+ pci_register_hose(hose);
+ hose->last_busno = pci_hose_scan(hose);
}
diff --git a/drivers/serial/serial_ixp.c b/drivers/serial/serial_ixp.c
index dd26af4..a9acd47 100644
--- a/drivers/serial/serial_ixp.c
+++ b/drivers/serial/serial_ixp.c
@@ -30,6 +30,7 @@
#include <common.h>
#include <asm/arch/ixp425.h>
+#include <watchdog.h>
/*
* 14.7456 MHz
@@ -85,7 +86,8 @@ int serial_init (void)
void serial_putc (const char c)
{
/* wait for room in the tx FIFO on UART */
- while ((LSR(CONFIG_SYS_IXP425_CONSOLE) & LSR_TEMT) == 0);
+ while ((LSR(CONFIG_SYS_IXP425_CONSOLE) & LSR_TEMT) == 0)
+ WATCHDOG_RESET(); /* Reset HW Watchdog, if needed */
THR(CONFIG_SYS_IXP425_CONSOLE) = c;
@@ -111,7 +113,8 @@ int serial_tstc (void)
*/
int serial_getc (void)
{
- while (!(LSR(CONFIG_SYS_IXP425_CONSOLE) & LSR_DR));
+ while (!(LSR(CONFIG_SYS_IXP425_CONSOLE) & LSR_DR))
+ WATCHDOG_RESET(); /* Reset HW Watchdog, if needed */
return (char) RBR(CONFIG_SYS_IXP425_CONSOLE) & 0xff;
}