From b8b47bfbe4eb1ae0e6891e49c86a5f4fb00413be Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 11 Mar 2009 15:41:51 +0900 Subject: sh: pass along struct pci_channel These patches rework the pci code for the sh architecture. Currently each board implements some kind of ioport to address mapping. Some boards use generic_io_base others try passing addresses as io ports. This is the first set of patches that try to unify the pci code as much as possible to avoid duplicated code. This will in the end lead to fewer lines board specific code and more generic code. This patch makes sure a struct pci_channel pointer is passed along to various pci functions such as pci_read_reg(), pci_write_reg(), pci_fixup_pcic(), sh7751_pcic_init() and sh7780_pcic_init(). Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-sh7751.c | 68 +++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 33 deletions(-) (limited to 'arch/sh/drivers/pci/pci-sh7751.c') diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index 3065eb184f0..9c2c01490d6 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -40,21 +40,22 @@ static int __init sh7751_pci_init(void) pr_debug("PCI: Starting intialization.\n"); /* check for SH7751/SH7751R hardware */ - id = pci_read_reg(SH7751_PCICONF0); + id = pci_read_reg(NULL, SH7751_PCICONF0); if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) && id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) { pr_debug("PCI: This is not an SH7751(R) (%x)\n", id); return -ENODEV; } - if ((ret = sh4_pci_check_direct()) != 0) + if ((ret = sh4_pci_check_direct(NULL)) != 0) return ret; return pcibios_init_platform(); } subsys_initcall(sh7751_pci_init); -static int __init __area_sdram_check(unsigned int area) +static int __init __area_sdram_check(struct pci_channel *chan, + unsigned int area) { u32 word; @@ -65,7 +66,7 @@ static int __init __area_sdram_check(unsigned int area) area, word); return 0; } - pci_write_reg(word, SH4_PCIBCR1); + pci_write_reg(chan, word, SH4_PCIBCR1); word = (u16)ctrl_inw(SH7751_BCR2); /* check BCR2 for 32bit SDRAM interface*/ @@ -74,12 +75,13 @@ static int __init __area_sdram_check(unsigned int area) area, word); return 0; } - pci_write_reg(word, SH4_PCIBCR2); + pci_write_reg(chan, word, SH4_PCIBCR2); return 1; } -int __init sh7751_pcic_init(struct sh4_pci_address_map *map) +int __init sh7751_pcic_init(struct pci_channel *chan, + struct sh4_pci_address_map *map) { u32 reg; u32 word; @@ -90,10 +92,10 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) ctrl_outl(reg, SH7751_BCR1); /* Turn the clocks back on (not done in reset)*/ - pci_write_reg(0, SH4_PCICLKR); + pci_write_reg(chan, 0, SH4_PCICLKR); /* Clear Powerdown IRQ's (not done in reset) */ word = SH4_PCIPINT_D3 | SH4_PCIPINT_D0; - pci_write_reg(word, SH4_PCIPINT); + pci_write_reg(chan, word, SH4_PCIPINT); /* * This code is unused for some boards as it is done in the @@ -103,11 +105,11 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) if (!(map->flags & SH4_PCIC_NO_RESET)) { /* toggle PCI reset pin */ word = SH4_PCICR_PREFIX | SH4_PCICR_PRST; - pci_write_reg(word, SH4_PCICR); + pci_write_reg(chan, word, SH4_PCICR); /* Wait for a long time... not 1 sec. but long enough */ mdelay(100); word = SH4_PCICR_PREFIX; - pci_write_reg(word, SH4_PCICR); + pci_write_reg(chan, word, SH4_PCICR); } /* set the command/status bits to: @@ -116,11 +118,11 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) */ word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER | SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES; - pci_write_reg(word, SH7751_PCICONF1); + pci_write_reg(chan, word, SH7751_PCICONF1); /* define this host as the host bridge */ word = PCI_BASE_CLASS_BRIDGE << 24; - pci_write_reg(word, SH7751_PCICONF2); + pci_write_reg(chan, word, SH7751_PCICONF2); /* Set IO and Mem windows to local address * Make PCI and local address the same for easy 1 to 1 mapping @@ -128,24 +130,24 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) * Window1 = map->window1.size @ cached area base = SDRAM */ word = map->window0.size - 1; - pci_write_reg(word, SH4_PCILSR0); + pci_write_reg(chan, word, SH4_PCILSR0); word = map->window1.size - 1; - pci_write_reg(word, SH4_PCILSR1); + pci_write_reg(chan, word, SH4_PCILSR1); /* Set the values on window 0 PCI config registers */ word = P2SEGADDR(map->window0.base); - pci_write_reg(word, SH4_PCILAR0); - pci_write_reg(word, SH7751_PCICONF5); + pci_write_reg(chan, word, SH4_PCILAR0); + pci_write_reg(chan, word, SH7751_PCICONF5); /* Set the values on window 1 PCI config registers */ word = PHYSADDR(map->window1.base); - pci_write_reg(word, SH4_PCILAR1); - pci_write_reg(word, SH7751_PCICONF6); + pci_write_reg(chan, word, SH4_PCILAR1); + pci_write_reg(chan, word, SH7751_PCICONF6); /* Set the local 16MB PCI memory space window to * the lowest PCI mapped address */ word = PCIBIOS_MIN_MEM & SH4_PCIMBR_MASK; pr_debug("PCI: Setting upper bits of Memory window to 0x%x\n", word); - pci_write_reg(word , SH4_PCIMBR); + pci_write_reg(chan, word , SH4_PCIMBR); /* Map IO space into PCI IO window * The IO window is 64K-PCIBIOS_MIN_IO in size @@ -160,19 +162,19 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) * correctly */ word = PCIBIOS_MIN_IO & SH4_PCIIOBR_MASK; pr_debug("PCI: Setting upper bits of IO window to 0x%x\n", word); - pci_write_reg(word, SH4_PCIIOBR); + pci_write_reg(chan, word, SH4_PCIIOBR); /* Set PCI WCRx, BCRx's, copy from BSC locations */ /* check BCR for SDRAM in specified area */ switch (map->window0.base) { - case SH7751_CS0_BASE_ADDR: word = __area_sdram_check(0); break; - case SH7751_CS1_BASE_ADDR: word = __area_sdram_check(1); break; - case SH7751_CS2_BASE_ADDR: word = __area_sdram_check(2); break; - case SH7751_CS3_BASE_ADDR: word = __area_sdram_check(3); break; - case SH7751_CS4_BASE_ADDR: word = __area_sdram_check(4); break; - case SH7751_CS5_BASE_ADDR: word = __area_sdram_check(5); break; - case SH7751_CS6_BASE_ADDR: word = __area_sdram_check(6); break; + case SH7751_CS0_BASE_ADDR: word = __area_sdram_check(chan, 0); break; + case SH7751_CS1_BASE_ADDR: word = __area_sdram_check(chan, 1); break; + case SH7751_CS2_BASE_ADDR: word = __area_sdram_check(chan, 2); break; + case SH7751_CS3_BASE_ADDR: word = __area_sdram_check(chan, 3); break; + case SH7751_CS4_BASE_ADDR: word = __area_sdram_check(chan, 4); break; + case SH7751_CS5_BASE_ADDR: word = __area_sdram_check(chan, 5); break; + case SH7751_CS6_BASE_ADDR: word = __area_sdram_check(chan, 6); break; } if (!word) @@ -180,25 +182,25 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) /* configure the wait control registers */ word = ctrl_inl(SH7751_WCR1); - pci_write_reg(word, SH4_PCIWCR1); + pci_write_reg(chan, word, SH4_PCIWCR1); word = ctrl_inl(SH7751_WCR2); - pci_write_reg(word, SH4_PCIWCR2); + pci_write_reg(chan, word, SH4_PCIWCR2); word = ctrl_inl(SH7751_WCR3); - pci_write_reg(word, SH4_PCIWCR3); + pci_write_reg(chan, word, SH4_PCIWCR3); word = ctrl_inl(SH7751_MCR); - pci_write_reg(word, SH4_PCIMCR); + pci_write_reg(chan, word, SH4_PCIMCR); /* NOTE: I'm ignoring the PCI error IRQs for now.. * TODO: add support for the internal error interrupts and * DMA interrupts... */ - pci_fixup_pcic(); + pci_fixup_pcic(chan); /* SH7751 init done, set central function init complete */ /* use round robin mode to stop a device starving/overruning */ word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM; - pci_write_reg(word, SH4_PCICR); + pci_write_reg(chan, word, SH4_PCICR); return 1; } -- cgit v1.2.3-18-g5258 From d0e3db40e2a1352aa2a2f425a7d4631bddc03d51 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 11 Mar 2009 15:46:14 +0900 Subject: sh: add init member to pci_channel data This patch adds an init callback to struct pci_channel and makes sure it is initialized properly. Code is added to call this init function from pcibios_init(). Return values are adjusted and a warning is is printed if init fails. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-sh7751.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'arch/sh/drivers/pci/pci-sh7751.c') diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index 9c2c01490d6..230db8bd974 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -32,7 +32,7 @@ * space mapping) will be called via the platform defined function * pcibios_init_platform(). */ -static int __init sh7751_pci_init(void) +int __init sh7751_pci_init(struct pci_channel *chan) { unsigned int id; int ret; @@ -40,19 +40,18 @@ static int __init sh7751_pci_init(void) pr_debug("PCI: Starting intialization.\n"); /* check for SH7751/SH7751R hardware */ - id = pci_read_reg(NULL, SH7751_PCICONF0); + id = pci_read_reg(chan, SH7751_PCICONF0); if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) && id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) { pr_debug("PCI: This is not an SH7751(R) (%x)\n", id); return -ENODEV; } - if ((ret = sh4_pci_check_direct(NULL)) != 0) + if ((ret = sh4_pci_check_direct(chan)) != 0) return ret; return pcibios_init_platform(); } -subsys_initcall(sh7751_pci_init); static int __init __area_sdram_check(struct pci_channel *chan, unsigned int area) @@ -178,7 +177,7 @@ int __init sh7751_pcic_init(struct pci_channel *chan, } if (!word) - return 0; + return -1; /* configure the wait control registers */ word = ctrl_inl(SH7751_WCR1); @@ -202,5 +201,5 @@ int __init sh7751_pcic_init(struct pci_channel *chan, word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM; pci_write_reg(chan, word, SH4_PCICR); - return 1; + return 0; } -- cgit v1.2.3-18-g5258 From 710fa3c81151948ac4d836ef52b57cef91b0ab72 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 11 Mar 2009 15:47:23 +0900 Subject: sh: avoid using PCIBIOS_MIN_xxx Replaces PCIBIOS_MIN_IO and PCIBIOS_MIN_MEM with direct struct pci_channel access. This allows us to have more than one pci channel. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-sh7751.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'arch/sh/drivers/pci/pci-sh7751.c') diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index 230db8bd974..447234c69ab 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -144,22 +144,20 @@ int __init sh7751_pcic_init(struct pci_channel *chan, /* Set the local 16MB PCI memory space window to * the lowest PCI mapped address */ - word = PCIBIOS_MIN_MEM & SH4_PCIMBR_MASK; + word = chan->mem_resource->start & SH4_PCIMBR_MASK; pr_debug("PCI: Setting upper bits of Memory window to 0x%x\n", word); pci_write_reg(chan, word , SH4_PCIMBR); - /* Map IO space into PCI IO window - * The IO window is 64K-PCIBIOS_MIN_IO in size - * IO addresses will be translated to the - * PCI IO window base address + /* Map IO space into PCI IO window: + * IO addresses will be translated to the PCI IO window base address */ pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", - PCIBIOS_MIN_IO, (64 << 10), - SH7751_PCI_IO_BASE + PCIBIOS_MIN_IO); + chan->io_resource->start, chan->io_resource->end, + SH7751_PCI_IO_BASE + chan->io_resource->start); /* Make sure the MSB's of IO window are set to access PCI space * correctly */ - word = PCIBIOS_MIN_IO & SH4_PCIIOBR_MASK; + word = chan->io_resource->start & SH4_PCIIOBR_MASK; pr_debug("PCI: Setting upper bits of IO window to 0x%x\n", word); pci_write_reg(chan, word, SH4_PCIIOBR); -- cgit v1.2.3-18-g5258 From e4c6a3604e07185046e2ce4be82a201f4447d788 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 19 Feb 2008 21:35:04 +0900 Subject: sh: add reg_base member to pci_channel Store the base address of the pci host controller registers in struct pci_channel and use the address in pci_read_reg() and pci_write_reg(). Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-sh7751.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/sh/drivers/pci/pci-sh7751.c') diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index 447234c69ab..201266b020f 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -39,6 +39,8 @@ int __init sh7751_pci_init(struct pci_channel *chan) pr_debug("PCI: Starting intialization.\n"); + chan->reg_base = 0xfe200000; + /* check for SH7751/SH7751R hardware */ id = pci_read_reg(chan, SH7751_PCICONF0); if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) && -- cgit v1.2.3-18-g5258 From ef53fdeb7e0cb139aff33665635b886700137abb Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 19 Feb 2008 21:35:14 +0900 Subject: sh: add io_base member to pci_channel Store the io window base address in struct pci_channel and use that one instead of SH77xx_PCI_IO_BASE. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-sh7751.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/sh/drivers/pci/pci-sh7751.c') diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index 201266b020f..2a6c7aab2d7 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -40,6 +40,7 @@ int __init sh7751_pci_init(struct pci_channel *chan) pr_debug("PCI: Starting intialization.\n"); chan->reg_base = 0xfe200000; + chan->io_base = 0xfe240000; /* check for SH7751/SH7751R hardware */ id = pci_read_reg(chan, SH7751_PCICONF0); @@ -153,9 +154,9 @@ int __init sh7751_pcic_init(struct pci_channel *chan, /* Map IO space into PCI IO window: * IO addresses will be translated to the PCI IO window base address */ - pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", + pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%lx\n", chan->io_resource->start, chan->io_resource->end, - SH7751_PCI_IO_BASE + chan->io_resource->start); + chan->io_base + chan->io_resource->start); /* Make sure the MSB's of IO window are set to access PCI space * correctly */ -- cgit v1.2.3-18-g5258 From 0232ba9ce031d0fd8f331fa8b3c00e16901f54e6 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 16 Apr 2009 18:01:31 +0900 Subject: sh: pci: Kill off unused SH4_PCIC_NO_RESET code. Nothing ended up using this anymore, so just kill it off. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-sh7751.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'arch/sh/drivers/pci/pci-sh7751.c') diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index 2a6c7aab2d7..af8874436d2 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -99,21 +99,6 @@ int __init sh7751_pcic_init(struct pci_channel *chan, word = SH4_PCIPINT_D3 | SH4_PCIPINT_D0; pci_write_reg(chan, word, SH4_PCIPINT); - /* - * This code is unused for some boards as it is done in the - * bootloader and doing it here means the MAC addresses loaded - * by the bootloader get lost. - */ - if (!(map->flags & SH4_PCIC_NO_RESET)) { - /* toggle PCI reset pin */ - word = SH4_PCICR_PREFIX | SH4_PCICR_PRST; - pci_write_reg(chan, word, SH4_PCICR); - /* Wait for a long time... not 1 sec. but long enough */ - mdelay(100); - word = SH4_PCICR_PREFIX; - pci_write_reg(chan, word, SH4_PCICR); - } - /* set the command/status bits to: * Wait Cycle Control + Parity Enable + Bus Master + * Mem space enable -- cgit v1.2.3-18-g5258 From 5ba7205fc49ff72e88784c94fb661f93e7ae7d36 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 19:00:32 +0900 Subject: sh: pci: Kill off the now unused hose->io_base. Nothing is using this any more, so kill it off. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-sh7751.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'arch/sh/drivers/pci/pci-sh7751.c') diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index af8874436d2..4c08fd7f665 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -40,7 +40,6 @@ int __init sh7751_pci_init(struct pci_channel *chan) pr_debug("PCI: Starting intialization.\n"); chan->reg_base = 0xfe200000; - chan->io_base = 0xfe240000; /* check for SH7751/SH7751R hardware */ id = pci_read_reg(chan, SH7751_PCICONF0); @@ -136,13 +135,6 @@ int __init sh7751_pcic_init(struct pci_channel *chan, pr_debug("PCI: Setting upper bits of Memory window to 0x%x\n", word); pci_write_reg(chan, word , SH4_PCIMBR); - /* Map IO space into PCI IO window: - * IO addresses will be translated to the PCI IO window base address - */ - pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%lx\n", - chan->io_resource->start, chan->io_resource->end, - chan->io_base + chan->io_resource->start); - /* Make sure the MSB's of IO window are set to access PCI space * correctly */ word = chan->io_resource->start & SH4_PCIIOBR_MASK; -- cgit v1.2.3-18-g5258 From 757e3c16f8bafa2a470aebf9b04671c5d4d18f49 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 21:11:07 +0900 Subject: sh: pci: Rewrite SH7751 PCI support to follow SH7780. This follows the similar sort of scheme that the refactored SH7780 code uses, using a 64MB CS3 mapping to handle the window0 case, and simply discarding window1. This vastly simplifies the code, and allows most of the board-specific setup to go die. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-sh7751.c | 135 ++++++++++++++++++++------------------- 1 file changed, 70 insertions(+), 65 deletions(-) (limited to 'arch/sh/drivers/pci/pci-sh7751.c') diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index 4c08fd7f665..c4fa0bb1397 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -1,78 +1,41 @@ /* - * Low-Level PCI Support for the SH7751 + * Low-Level PCI Support for the SH7751 * - * Dustin McIntire (dustin@sensoria.com) - * Derived from arch/i386/kernel/pci-*.c which bore the message: - * (c) 1999--2000 Martin Mares + * Copyright (C) 2003 - 2009 Paul Mundt + * Copyright (C) 2001 Dustin McIntire * - * Ported to the new API by Paul Mundt - * With cleanup by Paul van Gool - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. + * With cleanup by Paul van Gool , 2003. * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. */ -#undef DEBUG - #include #include #include #include -#include +#include #include "pci-sh4.h" #include -#include - -/* - * Initialization. Try all known PCI access methods. Note that we support - * using both PCI BIOS and direct access: in such cases, we use I/O ports - * to access config space. - * - * Note that the platform specific initialization (BSC registers, and memory - * space mapping) will be called via the platform defined function - * pcibios_init_platform(). - */ -int __init sh7751_pci_init(struct pci_channel *chan) -{ - unsigned int id; - int ret; - - pr_debug("PCI: Starting intialization.\n"); - - chan->reg_base = 0xfe200000; - - /* check for SH7751/SH7751R hardware */ - id = pci_read_reg(chan, SH7751_PCICONF0); - if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) && - id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) { - pr_debug("PCI: This is not an SH7751(R) (%x)\n", id); - return -ENODEV; - } - - if ((ret = sh4_pci_check_direct(chan)) != 0) - return ret; - - return pcibios_init_platform(); -} static int __init __area_sdram_check(struct pci_channel *chan, unsigned int area) { - u32 word; + unsigned long word; - word = ctrl_inl(SH7751_BCR1); + word = __raw_readl(SH7751_BCR1); /* check BCR for SDRAM in area */ if (((word >> area) & 1) == 0) { - printk("PCI: Area %d is not configured for SDRAM. BCR1=0x%x\n", + printk("PCI: Area %d is not configured for SDRAM. BCR1=0x%lx\n", area, word); return 0; } pci_write_reg(chan, word, SH4_PCIBCR1); - word = (u16)ctrl_inw(SH7751_BCR2); + word = __raw_readw(SH7751_BCR2); /* check BCR2 for 32bit SDRAM interface*/ if (((word >> (area << 1)) & 0x3) != 0x3) { - printk("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%x\n", + printk("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%lx\n", area, word); return 0; } @@ -81,11 +44,56 @@ static int __init __area_sdram_check(struct pci_channel *chan, return 1; } -int __init sh7751_pcic_init(struct pci_channel *chan, - struct sh4_pci_address_map *map) +static struct resource sh7751_io_resource = { + .name = "SH7751_IO", + .start = SH7751_PCI_IO_BASE, + .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, + .flags = IORESOURCE_IO +}; + +static struct resource sh7751_mem_resource = { + .name = "SH7785_mem", + .start = SH7751_PCI_MEMORY_BASE, + .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, + .flags = IORESOURCE_MEM +}; + +static struct pci_channel sh7751_pci_controller = { + .pci_ops = &sh4_pci_ops, + .mem_resource = &sh7751_mem_resource, + .mem_offset = 0x00000000, + .io_resource = &sh7751_io_resource, + .io_offset = 0x00000000, +}; + +static struct sh4_pci_address_map sh7751_pci_map = { + .window0 = { + .base = SH7751_CS3_BASE_ADDR, + .size = 0x04000000, + }, +}; + +static int __init sh7751_pci_init(void) { - u32 reg; - u32 word; + struct pci_channel *chan = &sh7751_pci_controller; + unsigned int id; + u32 word, reg; + int ret; + + printk(KERN_NOTICE "PCI: Starting intialization.\n"); + + chan->reg_base = 0xfe200000; + + /* check for SH7751/SH7751R hardware */ + id = pci_read_reg(chan, SH7751_PCICONF0); + if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) && + id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) { + pr_debug("PCI: This is not an SH7751(R) (%x)\n", id); + return -ENODEV; + } + + if ((ret = sh4_pci_check_direct(chan)) != 0) + return ret; /* Set the BCR's to enable PCI access */ reg = ctrl_inl(SH7751_BCR1); @@ -112,21 +120,13 @@ int __init sh7751_pcic_init(struct pci_channel *chan, /* Set IO and Mem windows to local address * Make PCI and local address the same for easy 1 to 1 mapping - * Window0 = map->window0.size @ non-cached area base = SDRAM - * Window1 = map->window1.size @ cached area base = SDRAM */ - word = map->window0.size - 1; + word = sh7751_pci_map.window0.size - 1; pci_write_reg(chan, word, SH4_PCILSR0); - word = map->window1.size - 1; - pci_write_reg(chan, word, SH4_PCILSR1); /* Set the values on window 0 PCI config registers */ - word = P2SEGADDR(map->window0.base); + word = P2SEGADDR(sh7751_pci_map.window0.base); pci_write_reg(chan, word, SH4_PCILAR0); pci_write_reg(chan, word, SH7751_PCICONF5); - /* Set the values on window 1 PCI config registers */ - word = PHYSADDR(map->window1.base); - pci_write_reg(chan, word, SH4_PCILAR1); - pci_write_reg(chan, word, SH7751_PCICONF6); /* Set the local 16MB PCI memory space window to * the lowest PCI mapped address @@ -144,7 +144,7 @@ int __init sh7751_pcic_init(struct pci_channel *chan, /* Set PCI WCRx, BCRx's, copy from BSC locations */ /* check BCR for SDRAM in specified area */ - switch (map->window0.base) { + switch (sh7751_pci_map.window0.base) { case SH7751_CS0_BASE_ADDR: word = __area_sdram_check(chan, 0); break; case SH7751_CS1_BASE_ADDR: word = __area_sdram_check(chan, 1); break; case SH7751_CS2_BASE_ADDR: word = __area_sdram_check(chan, 2); break; @@ -179,5 +179,10 @@ int __init sh7751_pcic_init(struct pci_channel *chan, word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM; pci_write_reg(chan, word, SH4_PCICR); + __set_io_port_base(SH7751_PCI_IO_BASE); + + register_pci_controller(chan); + return 0; } +arch_initcall(sh7751_pci_init); -- cgit v1.2.3-18-g5258