* Re: Mapping huge user buffers for DMA
From: Stephen Williams @ 2005-08-31 0:35 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <200508310210.51561.roger.larsson@norran.net>
Roger Larsson wrote:
> On Tuesday 30 August 2005 19.27, Stephen Williams wrote:
>
>>I have a PPC405GPr system with an image processing device, that
>>is creating potentially huge amounts of data. In one setup I
>>have a 256Meg system, and I'm trying to map a 192Meg destination
>>buffer using map_user_kiovec and an array of kiobufs.
>
>
> Never tried to map that amount at once. Our code looks, or looked, like this.
> Found some code...
> /usr/src/linuxppc_2_4_devel/arch/cris/drivers/examples/kiobuftest.c
That's similar to where I'm at now, and I'm finding it inadequate.
>>I'm finding, however, that I'm getting an Oops in map_user_kiovec
>>when it tries this, and I'm wondering where I need to look for
>>any limits I might be overrunning.
>
>
> What does the Oops say??
> Hmm... How much space will the vector itself require?
If placed into a single kiobuf, it would need 49,152 page pointers,
which would be 192K bytes for the maplist. Since the kernel uses
kmalloc to allocate the maplist, that won't work. Thus, I've
created an array of kiobufs to hold a smaller chunk of the pages
for the user buffer.
The Oops is a sig11 within the map_user_kiovec. (?!)
I also see errors from the kernel being unable to allocate
pages, so it seems like something is not handling an OOM
situation very well.
>
>>Also, I've been considering skipping kiobufs all together and
>>instead using code like this (lifted from map_user_kiobuf)
>>
>> /* Try to fault in all of the necessary pages */
>> down_read(&mm->mmap_sem);
>> /* rw==READ means read from disk, write into memory area */
>> err = get_user_pages(current, mm, va, pgcount,
>> (rw==READ), 0, iobuf->maplist, NULL);
>> up_read(&mm->mmap_sem);
>>
>>to get the user pages directly. This is really what I want, and
>>I do not need the other functionality of kiobufs. Is the
>>get_user_pages function kosher for use by drivers? Is there
>>a limit to what get_user_pages may map?
>
>
> Isn't this the way it is done in 2.6 anyway?
Well that's how the map_user_kiovec in 2.4 does it. I'm just
wondering if I were to do it myself using get_user_pages, would
I be peeking around the curtain at interfaces not meant to be
public. I'm thinking I need to ues get_user_pages myself to
avoid the extra overhead of kiobufs, and I can use vmalloc'ed
memory to hold those page pointers for later unmap so I don't
run up against the kmalloc limit.
--
Steve Williams "The woods are lovely, dark and deep.
steve at icarus.com But I have promises to keep,
http://www.icarus.com and lines to code before I sleep,
http://www.picturel.com And lines to code before I sleep."
^ permalink raw reply
* Re: Mapping huge user buffers for DMA
From: Roger Larsson @ 2005-08-31 0:10 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <431496FC.3090208@icarus.com>
On Tuesday 30 August 2005 19.27, Stephen Williams wrote:
> I have a PPC405GPr system with an image processing device, that
> is creating potentially huge amounts of data. In one setup I
> have a 256Meg system, and I'm trying to map a 192Meg destination
> buffer using map_user_kiovec and an array of kiobufs.
Never tried to map that amount at once. Our code looks, or looked, like this.
Found some code...
/usr/src/linuxppc_2_4_devel/arch/cris/drivers/examples/kiobuftest.c
>
> I'm finding, however, that I'm getting an Oops in map_user_kiovec
> when it tries this, and I'm wondering where I need to look for
> any limits I might be overrunning.
What does the Oops say??
Hmm... How much space will the vector itself require?
>
> Also, I've been considering skipping kiobufs all together and
> instead using code like this (lifted from map_user_kiobuf)
>
> /* Try to fault in all of the necessary pages */
> down_read(&mm->mmap_sem);
> /* rw==READ means read from disk, write into memory area */
> err = get_user_pages(current, mm, va, pgcount,
> (rw==READ), 0, iobuf->maplist, NULL);
> up_read(&mm->mmap_sem);
>
> to get the user pages directly. This is really what I want, and
> I do not need the other functionality of kiobufs. Is the
> get_user_pages function kosher for use by drivers? Is there
> a limit to what get_user_pages may map?
Isn't this the way it is done in 2.6 anyway?
/RogerL
^ permalink raw reply
* Re: Marvell MV6436xx ethernet driver patch
From: Dale Farnsworth @ 2005-08-30 23:32 UTC (permalink / raw)
To: Nicolas DET; +Cc: linuxppc-dev
In-Reply-To: <20050830181958.D856F1C0008A@mwinf0706.wanadoo.fr>
On Tue, Aug 30, 2005 at 08:16:12PM +0100, Nicolas DET wrote:
> You can find enclosed a patch for the Marvell MV643xx ethernet driver.
>
> It's also there:
> http://arrakin.homedns.org/~nicolas/mv643xx_eth.tar.gz (tarball)
> http://arrakin.homedns.org/~nicolas/mv643xx_eth.diff.bz2
>
> The diff is against the kernel 2.6.13 (kernel.org).
Thank you for working on this driver, Nicolas.
> The main changes (AFAIR):
> * Workaround for the TCP/UDP hw checksum
I implemented something similar a while back, but found it too ugly to
keep around. Fortunately, there is already a much simpler workaround for
the hw checksum bug in linux-2.6.git. See
http://oss.sgi.com/archives/netdev/2005-08/msg00124.html
> * Use hardware for statistics
This is good. We need to remove the code it replaces rather than
have it partially ifdeffed out. Can you do that and split this part
out as a separate patch and submit to netdev@vger.kernel.org ?
> * Define and use SRAM (for pegasos II archp/ppc/chrp_pegasos_eth.c)
Good. This is pegasos-specific and it would be good to split this
patch out from the mv643xx driver bits. Descriptors in SRAM is a big win.
> * Able to use max burst size from/to DDR (serious transfer boost)
This is a good idea. I suspect that most of the gain is from
turning off snooping and flushing/invalidating the cache explicitly.
Implementation-wise, I'd rather we not manipulate the MV643XX_ETH_BAR_?
registers directly in the driver. Today that is done in platform
setup code. This has promise but needs to be reworked.
> * Option can be selected through the menu (drivers/net/Kconfig)
Do these really need to be user configurable?
The following shouldn't be user options, IMHO:
MV643XX_CHECKSUM_OFFLOAD_TX -- on
MV643XX_CHECKSUM_OFFLOAD_TX_WORKAROUND -- on
MV64XXX_HWSTATS -- on
MV643XX_COAL -- on
MV64XXX_USESRAM -- on/off depending on platform
MV64XXX_MAXBURST -- on/off depending on platform
I'm not as sure about MV643XX_NAPI, but I think it should always be on
for GigE drivers. Is it worth being able to turn off NAPI?
Some general comments:
Several Kconfig hunks seem unrelated to MV643XX
Several lines in the patch have trailing whitespace.
C++ style comments (//) aren't acceptable.
Why the addition of EXTRA_BYTES to the definition of RX_SKB_SIZE? Did
you see problems without it?
-Dale Farnsworth
^ permalink raw reply
* [PATCH 2/2] ppc32: Add cputable entry for 750CXe DD2.4 ("Gekko")
From: Arthur Othieno @ 2005-08-30 23:45 UTC (permalink / raw)
To: akpm; +Cc: gc-linux-devel, linuxppc-embedded
In-Reply-To: <20050830233759.GA16375@mars>
Add a table entry for 750CXe DD2.4 ("Gekko") as found in the GameCube
from Nintendo:
http://www-306.ibm.com/chips/techlib/techlib.nsf/techdocs/291C8D0EF3EAEC1687256B72005C745C#C1
Signed-off-by: Arthur Othieno <a.othieno@bluewin.ch>
cputable.c | 14 ++++++++++++++
1 files changed, 14 insertions(+)
diff -uprN a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c
--- a/arch/ppc/kernel/cputable.c 2005-08-30 18:18:28.000000000 -0400
+++ b/arch/ppc/kernel/cputable.c 2005-08-30 19:21:15.000000000 -0400
@@ -240,6 +240,20 @@ struct cpu_spec cpu_specs[] = {
.num_pmcs = 4,
.cpu_setup = __setup_cpu_750cx
},
+ { /* 750CXe "Gekko" (83214) */
+ .pvr_mask = 0xffffffff,
+ .pvr_value = 0x00083214,
+ .cpu_name = "750CXe",
+ .cpu_features = CPU_FTR_COMMON |
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+ CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
+ .cpu_user_features = COMMON_PPC,
+ .icache_bsize = 32,
+ .dcache_bsize = 32,
+ .num_pmcs = 4,
+ .cpu_setup = __setup_cpu_750cx
+ },
{ /* 745/755 */
.pvr_mask = 0xfffff000,
.pvr_value = 0x00083000,
^ permalink raw reply
* [PATCH 1/2] ppc32: Re-order cputable for 750CXe DD2.4 entry
From: Arthur Othieno @ 2005-08-30 23:42 UTC (permalink / raw)
To: akpm; +Cc: gc-linux-devel, linuxppc-embedded
In-Reply-To: <20050830233759.GA16375@mars>
"745/755" (pvr_value:0x00083000) is a catch-all entry.
Since arch/ppc/kernel/misc.S:identify_cpu() returns on first match,
move this lower in the table so 750CXe DD2.4 (pvr_value:0x00083214)
may be correctly enumerated.
Signed-off-by: Arthur Othieno <a.othieno@bluewin.ch>
cputable.c | 28 ++++++++++++++--------------
1 files changed, 14 insertions(+), 14 deletions(-)
diff -uprN a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c
--- a/arch/ppc/kernel/cputable.c 2005-08-30 15:29:31.000000000 -0400
+++ b/arch/ppc/kernel/cputable.c 2005-08-30 18:18:28.000000000 -0400
@@ -198,20 +198,6 @@ struct cpu_spec cpu_specs[] = {
.num_pmcs = 4,
.cpu_setup = __setup_cpu_750
},
- { /* 745/755 */
- .pvr_mask = 0xfffff000,
- .pvr_value = 0x00083000,
- .cpu_name = "745/755",
- .cpu_features = CPU_FTR_COMMON |
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
- CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
- CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
- .cpu_user_features = COMMON_PPC,
- .icache_bsize = 32,
- .dcache_bsize = 32,
- .num_pmcs = 4,
- .cpu_setup = __setup_cpu_750
- },
{ /* 750CX (80100 and 8010x?) */
.pvr_mask = 0xfffffff0,
.pvr_value = 0x00080100,
@@ -254,6 +240,20 @@ struct cpu_spec cpu_specs[] = {
.num_pmcs = 4,
.cpu_setup = __setup_cpu_750cx
},
+ { /* 745/755 */
+ .pvr_mask = 0xfffff000,
+ .pvr_value = 0x00083000,
+ .cpu_name = "745/755",
+ .cpu_features = CPU_FTR_COMMON |
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+ CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
+ CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
+ .cpu_user_features = COMMON_PPC,
+ .icache_bsize = 32,
+ .dcache_bsize = 32,
+ .num_pmcs = 4,
+ .cpu_setup = __setup_cpu_750
+ },
{ /* 750FX rev 1.x */
.pvr_mask = 0xffffff00,
.pvr_value = 0x70000100,
^ permalink raw reply
* Remove progress msgs from MMU_init()
From: Mark A. Greer @ 2005-08-30 23:38 UTC (permalink / raw)
To: linuxppc-dev
This dates back to a discussion in May. This patch addresses point 1)
in the email below by ripping out the progress msgs from MMU_init().
This would allow us to get rid of all the xxx_set_bat() routines in the
various platform files.
Does anyone object to this patch?
Mark
http://ozlabs.org/pipermail/linuxppc-dev/2005-May/019120.html
^ permalink raw reply
* [PATCH 0/2] ppc32: Add cputable entry for 750CXe DD2.4
From: Arthur Othieno @ 2005-08-30 23:37 UTC (permalink / raw)
To: akpm; +Cc: gc-linux-devel, linuxppc-embedded
Greetings,
This adds a cputable entry for 750CXe DD2.4, as found in the
GameCube from Nintendo. To be correctly enumerated, however,
the table has to be slightly re-ordered first.
Details within. Thanks.
Arthur
^ permalink raw reply
* Re: Marvell MV6436xx ethernet driver patch
From: Christoph Hellwig @ 2005-08-30 19:09 UTC (permalink / raw)
To: Nicolas DET; +Cc: akpm, linuxppc-dev, Sven Luther, Kumar Gala
In-Reply-To: <20050830181119.E3A491C000B2@mwinf1203.wanadoo.fr>
On Tue, Aug 30, 2005 at 08:07:33PM +0100, Nicolas DET wrote:
> By the way, I noticed that page_address() sometimes returns NULL when using
> highmem (with a lot of mem).
You can only use page_address() on kernel-mapped memory. For
non-GFP_KERNEL allocation you need to use kmap/kmap_atomic to map it
into kernel-virtual memory space.
^ permalink raw reply
* Marvell MV6436xx ethernet driver patch
From: Nicolas DET @ 2005-08-30 19:07 UTC (permalink / raw)
To: Sven Luther; +Cc: akpm, linuxppc-dev, Kumar Gala
[-- Attachment #1: Type: text/plain, Size: 307 bytes --]
Amiga............: SimpleMail http://simplemail.sourceforge.net/
Unix.............: Metamail ftp://ftp.bellcore.com/nsb/
Windows/Macintosh: Eudora http://www.qualcomm.com/
General info about MIME can be found at:
http://www.cis.ohio-state.edu/hypertext/faq/usenet/mail/mime-faq/top.html
[-- Attachment #2: Type: text/plain, Size: 858 bytes --]
Hello,
You can find enclosed a patch for the Marvell MV643xx ethernet driver.
It's also there:
http://arrakin.homedns.org/~nicolas/mv643xx_eth.tar.gz (tarball)
http://arrakin.homedns.org/~nicolas/mv643xx_eth.diff.bz2
The diff is against the kernel 2.6.13 (kernel.org).
The main changes (AFAIR):
* Workaround for the TCP/UDP hw checksum
* Use hardware for statistics
* Define and use SRAM (for pegasos II archp/ppc/chrp_pegasos_eth.c)
* Able to use max burst size from/to DDR (serious transfer boost)
* Option can be selected through the menu (drivers/net/Kconfig)
* ...
some testing...
By the way, I noticed that page_address() sometimes returns NULL when using
highmem (with a lot of mem).
You are welcome to review this patch. Some parts (especially the TX bug
workaroud) will be appreciated IMO.
Regards,
--
Nicolas DET
MorphOS & Linux developer
[-- Attachment #3: mv643xx_eth.diff.bz2 --]
[-- Type: application/octet-stream, Size: 14098 bytes --]
^ permalink raw reply
* Re: [PATCH] MPC8xx PCMCIA driver
From: Marcelo Tosatti @ 2005-08-30 15:07 UTC (permalink / raw)
To: Paul Mackerras, Dan Malek; +Cc: Jeff Garzik, linux-kernel, linux-ppc-embedded
In-Reply-To: <17171.57693.981385.165290@cargo.ozlabs.ibm.com>
Hi Paul, Jeff,
On Tue, Aug 30, 2005 at 02:32:29PM +1000, Paul Mackerras wrote:
> Marcelo Tosatti writes:
>
> > The memory map structure which contains device configuration/registers
> > is _always_ directly mapped with pte's (the 8xx is a chip with builtin
> > UART/network/etc functionality).
> >
> > I don't think there is a need to use read/write acessors.
Bullshit, yep :)
> Generally on PowerPC you need to use at least the eieio instruction to
> prevent reordering of the loads and stores to the device. It's
> possible that 8xx is sufficiently in-order that you get away without
> putting in barrier instructions (eieio or sync), but it's not good
> practice to omit them.
On 8xx, guarded mappings seem to ensure synchronous operation of
load/store instructions.
Since the internal memory map is guarded, eieio is redudant (ie thats
why it gets away without explicit barriers now).
>From MPC860UM.pdf: 5.2.5.2.1 eieio Behavior
The purpose of eieio is to prevent loads and stores from executing
speculatively when appropriate. This might be desirable for a FIFO,
where performing a read or write changes the FIFO's data. This should
not be done unless it is certain that the instruction will be completed
and not cancelled. The same function as eieio can be accomplished by
defining a memory space as having the guarded attribute in the MMU, in
which case, the eieio instruction is redundant. However, eieio could be
useful in the rare event that a region where speculative accesses are
not allowed lies in the middle of a non-guarded page.
There is nothing which prevents compiler reordering though, as Jeff
notes.
> You can use accessors such as in_be32 and in_le32 in this situation,
> when you have a kernel virtual address that is already mapped to the
> device.
Do you think it would be worth to have lighterweight versions of
in_be32/in_le32 functions (without eieio and isync) ? Would avoid the
increase in code size and consequently cache footprint.
The IMMAP is referenced directly _all over_ the 8xx core code, must be
fixed.
> There are multiple reasons:
>
> * Easier reviewing. One cannot easily distinguish between writing to
> normal kernel virtual memory and "magic" memory that produces magicaly
> side effects such as initiating DMA of a net packet.
>
> * Compiler safety. As the code is written now, you have no guarantees
> that the compiler won't combine two stores to the same location, etc.
> Accessor macros are a convenient place to add compiler barriers or
> 'volatile' notations that the MPC8xx code lacks.
>
> * Maintainable. foo_read[bwl] or foo_read{8,16,32} are preferred
> because that's the way other bus accessors look like -- yes even
> embedded SoC buses benefit from these code patterns. You want your
> driver to look like other drivers as much as possible.
>
> * Convenience. The accessors can be a zero overhead memory read/write
> at a minimum. But they can also be convenient places to use special
> memory read/write instructions that specify uncached memop, compiler
> barriers, memory barriers, etc.
^ permalink raw reply
* Mapping huge user buffers for DMA
From: Stephen Williams @ 2005-08-30 17:27 UTC (permalink / raw)
To: linuxppc-embedded
I have a PPC405GPr system with an image processing device, that
is creating potentially huge amounts of data. In one setup I
have a 256Meg system, and I'm trying to map a 192Meg destination
buffer using map_user_kiovec and an array of kiobufs.
I'm finding, however, that I'm getting an Oops in map_user_kiovec
when it tries this, and I'm wondering where I need to look for
any limits I might be overrunning.
Also, I've been considering skipping kiobufs all together and
instead using code like this (lifted from map_user_kiobuf)
/* Try to fault in all of the necessary pages */
down_read(&mm->mmap_sem);
/* rw==READ means read from disk, write into memory area */
err = get_user_pages(current, mm, va, pgcount,
(rw==READ), 0, iobuf->maplist, NULL);
up_read(&mm->mmap_sem);
to get the user pages directly. This is really what I want, and
I do not need the other functionality of kiobufs. Is the
get_user_pages function kosher for use by drivers? Is there
a limit to what get_user_pages may map?
--
Steve Williams "The woods are lovely, dark and deep.
steve at icarus.com But I have promises to keep,
http://www.icarus.com and lines to code before I sleep,
http://www.picturel.com And lines to code before I sleep."
^ permalink raw reply
* [PATCH] ppc32: export cacheable_memcpy()
From: Eugene Surovegin @ 2005-08-30 16:49 UTC (permalink / raw)
To: linuxppc-dev
Add declaration and cacheable_memcpy(). I'll be needing this
function in new 4xx EMAC driver I'm going to submit to netdev soon.
IMHO, the better place for the declaration would be
asm-powerpc/string.h, unfortunately, ppc64 doesn't have this function,
so asm-ppc/system.h is the next best place.
Signed-off-by: Eugene Surovegin <ebs@ebshome.net>
---
arch/ppc/kernel/ppc_ksyms.c | 1 +
include/asm-ppc/system.h | 1 +
2 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -263,6 +263,7 @@ EXPORT_SYMBOL(__ashrdi3);
EXPORT_SYMBOL(__ashldi3);
EXPORT_SYMBOL(__lshrdi3);
EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(cacheable_memcpy);
EXPORT_SYMBOL(memset);
EXPORT_SYMBOL(memmove);
EXPORT_SYMBOL(memscan);
diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h
--- a/include/asm-ppc/system.h
+++ b/include/asm-ppc/system.h
@@ -84,6 +84,7 @@ extern void cvt_fd(float *from, double *
extern void cvt_df(double *from, float *to, unsigned long *fpscr);
extern int call_rtas(const char *, int, int, unsigned long *, ...);
extern void cacheable_memzero(void *p, unsigned int nb);
+extern void *cacheable_memcpy(void *, const void *, unsigned int);
extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long);
extern void bad_page_fault(struct pt_regs *, unsigned long, int);
extern void die(const char *, struct pt_regs *, long);
^ permalink raw reply
* Re: Address mapping PPC 405
From: Matt Porter @ 2005-08-30 15:38 UTC (permalink / raw)
To: Jon Masters; +Cc: linuxppc-embedded
In-Reply-To: <431260BA.7000107@jonmasters.org>
On Mon, Aug 29, 2005 at 02:11:22AM +0100, Jon Masters wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Grant Likely wrote:
>
> | On 8/28/05, Jon Masters <jonmasters@gmail.com> wrote:
> |
> |>On 8/26/05, P. Sadik <psadik@gmail.com> wrote:
> |>
> |>Lovely. We don't do it that way on 405 but we could - since the MMU is
> |>heavy soft assisted we could do that - we actually have everything run
> |>through the MMU once we've done initial MMU setup, but we do have the
> |>ability to mark ranges of addresses for IO and have the concept of TLB
> |>pinning to lock ranges of kernel addresses in large translated (BAT
> |>like for bigger PPC users) regions using just a few TLB slots. There
> |>is also a ZPR (zone protection register), but that's mostly used to
> |>fake the usual USER/KERNEL page distinction.
>
> | I believe TLB pinning was removed in 2.6 in favor of large TLB entries
> | for kernel space. Matt Porter pointed this out to me about a week
> | ago. This will not matter of course if you're not using 2.6.
>
> Maybe so. I'm thinking this is likely on 2.4 but I'd be interested to
> know what you mean - this isn't hugetlb (that's different), and TLB
> pinning on 2.4 means you only use a couple of (large) entries anyway. I
> can go read the source I suppose :-)
The following is 405 specific.
Well, on 2.4 we have CONFIG_PIN_TLB which covers the first 32MB of
kernel lowmem with two fixed 16MB TLB entries. In 2.6, all of kernel
lowmem is mapped by large pages of 16MB and 4MB sizes.
hugetlbfs, ioremap, and io_block_map could all be hooked into the 405
large page replacement support. I've been looking at doing this for
405 and 440 in my copious spare time. :)
-Matt
^ permalink raw reply
* Re: Address mapping PPC 405
From: Matt Porter @ 2005-08-30 15:09 UTC (permalink / raw)
To: Grant Likely; +Cc: jonathan, linuxppc-embedded
In-Reply-To: <528646bc05082817268abfb1d@mail.gmail.com>
On Sun, Aug 28, 2005 at 06:26:06PM -0600, Grant Likely wrote:
> On 8/28/05, Jon Masters <jonmasters@gmail.com> wrote:
> > On 8/26/05, P. Sadik <psadik@gmail.com> wrote:
> >
> > Lovely. We don't do it that way on 405 but we could - since the MMU is
> > heavy soft assisted we could do that - we actually have everything run
> > through the MMU once we've done initial MMU setup, but we do have the
> > ability to mark ranges of addresses for IO and have the concept of TLB
> > pinning to lock ranges of kernel addresses in large translated (BAT
> > like for bigger PPC users) regions using just a few TLB slots. There
> > is also a ZPR (zone protection register), but that's mostly used to
> > fake the usual USER/KERNEL page distinction.
> I believe TLB pinning was removed in 2.6 in favor of large TLB entries
> for kernel space. Matt Porter pointed this out to me about a week
> ago. This will not matter of course if you're not using 2.6.
>
> Matt, is there any documentation covering the new design in the kernel tree?
The docs are in the original threads from 3+ years ago. You'll need
to read them all to have proper context about the tradeoffs between
permanently pinning a couple TLBs versus faulting large TLB
replacement.
http://ozlabs.org/pipermail/linuxppc-embedded/2002-May/007257.html
http://ozlabs.org/pipermail/linuxppc-embedded/2002-May/007317.html
http://ozlabs.org/pipermail/linuxppc-embedded/2002-June/007370.html
http://ozlabs.org/pipermail/linuxppc-embedded/2002-June/007404.html
-Matt
^ permalink raw reply
* [PATCH] ppc32: Added PCI support MPC83xx
From: Kumar Gala @ 2005-08-30 14:59 UTC (permalink / raw)
To: Andrew Morton; +Cc: tony.li, linux-kernel, linuxppc-embedded
Adds support for the two PCI busses on MPC83xx and the MPC834x SYS/PIBS
reference board.
The code initializes PCI inbound/outbound windows, allocates and registers
PCI memory/io space. Be aware that setup of the PCI buses on the PIBs board
is expected to be done by the firmware.
Signed-off-by: Tony Li <tony.li@freescale.com>
Signed-off-by: Kumar Gala <kumar.gala@freescale.com>
---
commit 13043c8ebd73fe09301e28202dd9a31fa93603c0
tree 6e4f0e096286648a3ae905a1cbe07b16cefded15
parent 5218c33e36a0612c44f7bf7460a00743f2cae5d9
author Kumar K. Gala <kumar.gala@freescale.com> Tue, 30 Aug 2005 09:57:28 -0500
committer Kumar K. Gala <kumar.gala@freescale.com> Tue, 30 Aug 2005 09:57:28 -0500
arch/ppc/Kconfig | 10 +
arch/ppc/platforms/83xx/mpc834x_sys.c | 35 ++++-
arch/ppc/platforms/83xx/mpc834x_sys.h | 40 +++--
arch/ppc/syslib/ppc83xx_pci.h | 151 ++++++++++++++++++++
arch/ppc/syslib/ppc83xx_setup.c | 250 +++++++++++++++++++++++++++++++++
arch/ppc/syslib/ppc83xx_setup.h | 19 ++-
6 files changed, 474 insertions(+), 31 deletions(-)
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -713,6 +713,11 @@ config MPC834x_SYS
help
This option enables support for the MPC 834x SYS evaluation board.
+ Be aware that PCI buses can only function when SYS board is plugged
+ into the PIB (Platform IO Board) board from Freescale which provide
+ 3 PCI slots. The PIBs PCI initialization is the bootloader's
+ responsiblilty.
+
endchoice
config PQ2ADS
@@ -1193,6 +1198,11 @@ config PCI
config PCI_DOMAINS
bool
default PCI
+
+config MPC83xx_PCI2
+ bool " Supprt for 2nd PCI host controller"
+ depends on PCI && MPC834x
+ default y if MPC834x_SYS
config PCI_QSPAN
bool "QSpan PCI"
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c
--- a/arch/ppc/platforms/83xx/mpc834x_sys.c
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.c
@@ -62,9 +62,29 @@ extern unsigned long total_memory; /* in
unsigned char __res[sizeof (bd_t)];
#ifdef CONFIG_PCI
-#error "PCI is not supported"
-/* NEED mpc83xx_map_irq & mpc83xx_exclude_device
- see platforms/85xx/mpc85xx_ads_common.c */
+int
+mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+ static char pci_irq_table[][4] =
+ /*
+ * PCI IDSEL/INTPIN->INTLINE
+ * A B C D
+ */
+ {
+ {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x11 */
+ {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x12 */
+ {PIRQD, PIRQA, PIRQB, PIRQC} /* idsel 0x13 */
+ };
+
+ const long min_idsel = 0x11, max_idsel = 0x13, irqs_per_slot = 4;
+ return PCI_IRQ_TABLE_LOOKUP;
+}
+
+int
+mpc83xx_exclude_device(u_char bus, u_char devfn)
+{
+ return PCIBIOS_SUCCESSFUL;
+}
#endif /* CONFIG_PCI */
/* ************************************************************************
@@ -88,7 +108,7 @@ mpc834x_sys_setup_arch(void)
#ifdef CONFIG_PCI
/* setup PCI host bridges */
- mpc83xx_sys_setup_hose();
+ mpc83xx_setup_hose();
#endif
mpc83xx_early_serial_map();
@@ -175,10 +195,17 @@ mpc834x_sys_init_IRQ(void)
IRQ_SENSE_LEVEL, /* EXT 1 */
IRQ_SENSE_LEVEL, /* EXT 2 */
0, /* EXT 3 */
+#ifdef CONFIG_PCI
+ IRQ_SENSE_LEVEL, /* EXT 4 */
+ IRQ_SENSE_LEVEL, /* EXT 5 */
+ IRQ_SENSE_LEVEL, /* EXT 6 */
+ IRQ_SENSE_LEVEL, /* EXT 7 */
+#else
0, /* EXT 4 */
0, /* EXT 5 */
0, /* EXT 6 */
0, /* EXT 7 */
+#endif
};
ipic_init(binfo->bi_immr_base + 0x00700, 0, MPC83xx_IPIC_IRQ_OFFSET, senses, 8);
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.h b/arch/ppc/platforms/83xx/mpc834x_sys.h
--- a/arch/ppc/platforms/83xx/mpc834x_sys.h
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.h
@@ -26,7 +26,7 @@
#define VIRT_IMMRBAR ((uint)0xfe000000)
#define BCSR_PHYS_ADDR ((uint)0xf8000000)
-#define BCSR_SIZE ((uint)(32 * 1024))
+#define BCSR_SIZE ((uint)(128 * 1024))
#define BCSR_MISC_REG2_OFF 0x07
#define BCSR_MISC_REG2_PORESET 0x01
@@ -34,23 +34,25 @@
#define BCSR_MISC_REG3_OFF 0x08
#define BCSR_MISC_REG3_CNFLOCK 0x80
-#ifdef CONFIG_PCI
-/* PCI interrupt controller */
-#define PIRQA MPC83xx_IRQ_IRQ4
-#define PIRQB MPC83xx_IRQ_IRQ5
-#define PIRQC MPC83xx_IRQ_IRQ6
-#define PIRQD MPC83xx_IRQ_IRQ7
-
-#define MPC834x_SYS_PCI1_LOWER_IO 0x00000000
-#define MPC834x_SYS_PCI1_UPPER_IO 0x00ffffff
-
-#define MPC834x_SYS_PCI1_LOWER_MEM 0x80000000
-#define MPC834x_SYS_PCI1_UPPER_MEM 0x9fffffff
-
-#define MPC834x_SYS_PCI1_IO_BASE 0xe2000000
-#define MPC834x_SYS_PCI1_MEM_OFFSET 0x00000000
-
-#define MPC834x_SYS_PCI1_IO_SIZE 0x01000000
-#endif /* CONFIG_PCI */
+#define PIRQA MPC83xx_IRQ_EXT4
+#define PIRQB MPC83xx_IRQ_EXT5
+#define PIRQC MPC83xx_IRQ_EXT6
+#define PIRQD MPC83xx_IRQ_EXT7
+
+#define MPC83xx_PCI1_LOWER_IO 0x00000000
+#define MPC83xx_PCI1_UPPER_IO 0x00ffffff
+#define MPC83xx_PCI1_LOWER_MEM 0x80000000
+#define MPC83xx_PCI1_UPPER_MEM 0x9fffffff
+#define MPC83xx_PCI1_IO_BASE 0xe2000000
+#define MPC83xx_PCI1_MEM_OFFSET 0x00000000
+#define MPC83xx_PCI1_IO_SIZE 0x01000000
+
+#define MPC83xx_PCI2_LOWER_IO 0x00000000
+#define MPC83xx_PCI2_UPPER_IO 0x00ffffff
+#define MPC83xx_PCI2_LOWER_MEM 0xa0000000
+#define MPC83xx_PCI2_UPPER_MEM 0xbfffffff
+#define MPC83xx_PCI2_IO_BASE 0xe3000000
+#define MPC83xx_PCI2_MEM_OFFSET 0x00000000
+#define MPC83xx_PCI2_IO_SIZE 0x01000000
#endif /* __MACH_MPC83XX_SYS_H__ */
diff --git a/arch/ppc/syslib/ppc83xx_pci.h b/arch/ppc/syslib/ppc83xx_pci.h
new file mode 100644
--- /dev/null
+++ b/arch/ppc/syslib/ppc83xx_pci.h
@@ -0,0 +1,151 @@
+/* Created by Tony Li <tony.li@freescale.com>
+ * Copyright (c) 2005 freescale semiconductor
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __PPC_SYSLIB_PPC83XX_PCI_H
+#define __PPC_SYSLIB_PPC83XX_PCI_H
+
+typedef struct immr_clk {
+ u32 spmr; /* system PLL mode Register */
+ u32 occr; /* output clock control Register */
+ u32 sccr; /* system clock control Register */
+ u8 res0[0xF4];
+} immr_clk_t;
+
+/*
+ * Sequencer
+ */
+typedef struct immr_ios {
+ u32 potar0;
+ u8 res0[4];
+ u32 pobar0;
+ u8 res1[4];
+ u32 pocmr0;
+ u8 res2[4];
+ u32 potar1;
+ u8 res3[4];
+ u32 pobar1;
+ u8 res4[4];
+ u32 pocmr1;
+ u8 res5[4];
+ u32 potar2;
+ u8 res6[4];
+ u32 pobar2;
+ u8 res7[4];
+ u32 pocmr2;
+ u8 res8[4];
+ u32 potar3;
+ u8 res9[4];
+ u32 pobar3;
+ u8 res10[4];
+ u32 pocmr3;
+ u8 res11[4];
+ u32 potar4;
+ u8 res12[4];
+ u32 pobar4;
+ u8 res13[4];
+ u32 pocmr4;
+ u8 res14[4];
+ u32 potar5;
+ u8 res15[4];
+ u32 pobar5;
+ u8 res16[4];
+ u32 pocmr5;
+ u8 res17[4];
+ u8 res18[0x60];
+ u32 pmcr;
+ u8 res19[4];
+ u32 dtcr;
+ u8 res20[4];
+} immr_ios_t;
+#define POTAR_TA_MASK 0x000fffff
+#define POBAR_BA_MASK 0x000fffff
+#define POCMR_EN 0x80000000
+#define POCMR_IO 0x40000000 /* 0--memory space 1--I/O space */
+#define POCMR_SE 0x20000000 /* streaming enable */
+#define POCMR_DST 0x10000000 /* 0--PCI1 1--PCI2 */
+#define POCMR_CM_MASK 0x000fffff
+
+/*
+ * PCI Controller Control and Status Registers
+ */
+typedef struct immr_pcictrl {
+ u32 esr;
+ u32 ecdr;
+ u32 eer;
+ u32 eatcr;
+ u32 eacr;
+ u32 eeacr;
+ u32 edlcr;
+ u32 edhcr;
+ u32 gcr;
+ u32 ecr;
+ u32 gsr;
+ u8 res0[12];
+ u32 pitar2;
+ u8 res1[4];
+ u32 pibar2;
+ u32 piebar2;
+ u32 piwar2;
+ u8 res2[4];
+ u32 pitar1;
+ u8 res3[4];
+ u32 pibar1;
+ u32 piebar1;
+ u32 piwar1;
+ u8 res4[4];
+ u32 pitar0;
+ u8 res5[4];
+ u32 pibar0;
+ u8 res6[4];
+ u32 piwar0;
+ u8 res7[132];
+} immr_pcictrl_t;
+#define PITAR_TA_MASK 0x000fffff
+#define PIBAR_MASK 0xffffffff
+#define PIEBAR_EBA_MASK 0x000fffff
+#define PIWAR_EN 0x80000000
+#define PIWAR_PF 0x20000000
+#define PIWAR_RTT_MASK 0x000f0000
+#define PIWAR_RTT_NO_SNOOP 0x00040000
+#define PIWAR_RTT_SNOOP 0x00050000
+#define PIWAR_WTT_MASK 0x0000f000
+#define PIWAR_WTT_NO_SNOOP 0x00004000
+#define PIWAR_WTT_SNOOP 0x00005000
+#define PIWAR_IWS_MASK 0x0000003F
+#define PIWAR_IWS_4K 0x0000000B
+#define PIWAR_IWS_8K 0x0000000C
+#define PIWAR_IWS_16K 0x0000000D
+#define PIWAR_IWS_32K 0x0000000E
+#define PIWAR_IWS_64K 0x0000000F
+#define PIWAR_IWS_128K 0x00000010
+#define PIWAR_IWS_256K 0x00000011
+#define PIWAR_IWS_512K 0x00000012
+#define PIWAR_IWS_1M 0x00000013
+#define PIWAR_IWS_2M 0x00000014
+#define PIWAR_IWS_4M 0x00000015
+#define PIWAR_IWS_8M 0x00000016
+#define PIWAR_IWS_16M 0x00000017
+#define PIWAR_IWS_32M 0x00000018
+#define PIWAR_IWS_64M 0x00000019
+#define PIWAR_IWS_128M 0x0000001A
+#define PIWAR_IWS_256M 0x0000001B
+#define PIWAR_IWS_512M 0x0000001C
+#define PIWAR_IWS_1G 0x0000001D
+#define PIWAR_IWS_2G 0x0000001E
+
+#endif /* __PPC_SYSLIB_PPC83XX_PCI_H */
diff --git a/arch/ppc/syslib/ppc83xx_setup.c b/arch/ppc/syslib/ppc83xx_setup.c
--- a/arch/ppc/syslib/ppc83xx_setup.c
+++ b/arch/ppc/syslib/ppc83xx_setup.c
@@ -11,6 +11,17 @@
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Added PCI support -- Tony Li <tony.li@freescale.com>
*/
#include <linux/config.h>
@@ -31,6 +42,10 @@
#include <asm/delay.h>
#include <syslib/ppc83xx_setup.h>
+#if defined(CONFIG_PCI)
+#include <asm/delay.h>
+#include <syslib/ppc83xx_pci.h>
+#endif
phys_addr_t immrbar;
@@ -162,4 +177,237 @@ mpc83xx_halt(void)
for(;;);
}
-/* PCI SUPPORT DOES NOT EXIT, MODEL after ppc85xx_setup.c */
+#if defined(CONFIG_PCI)
+void __init
+mpc83xx_setup_pci1(struct pci_controller *hose)
+{
+ u16 reg16;
+ volatile immr_pcictrl_t * pci_ctrl;
+ volatile immr_ios_t * ios;
+ bd_t *binfo = (bd_t *) __res;
+
+ pci_ctrl = ioremap(binfo->bi_immr_base + 0x8500, sizeof(immr_pcictrl_t));
+ ios = ioremap(binfo->bi_immr_base + 0x8400, sizeof(immr_ios_t));
+
+ /*
+ * Configure PCI Outbound Translation Windows
+ */
+ ios->potar0 = (MPC83xx_PCI1_LOWER_MEM >> 12) & POTAR_TA_MASK;
+ ios->pobar0 = (MPC83xx_PCI1_LOWER_MEM >> 12) & POBAR_BA_MASK;
+ ios->pocmr0 = POCMR_EN |
+ (((0xffffffff - (MPC83xx_PCI1_UPPER_MEM -
+ MPC83xx_PCI1_LOWER_MEM)) >> 12) & POCMR_CM_MASK);
+
+ /* mapped to PCI1 IO space */
+ ios->potar1 = (MPC83xx_PCI1_LOWER_IO >> 12) & POTAR_TA_MASK;
+ ios->pobar1 = (MPC83xx_PCI1_IO_BASE >> 12) & POBAR_BA_MASK;
+ ios->pocmr1 = POCMR_EN | POCMR_IO |
+ (((0xffffffff - (MPC83xx_PCI1_UPPER_IO -
+ MPC83xx_PCI1_LOWER_IO)) >> 12) & POCMR_CM_MASK);
+
+ /*
+ * Configure PCI Inbound Translation Windows
+ */
+ pci_ctrl->pitar1 = 0x0;
+ pci_ctrl->pibar1 = 0x0;
+ pci_ctrl->piebar1 = 0x0;
+ pci_ctrl->piwar1 = PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP | PIWAR_IWS_2G;
+
+ /*
+ * Release PCI RST signal
+ */
+ pci_ctrl->gcr = 0;
+ udelay(2000);
+ pci_ctrl->gcr = 1;
+ udelay(2000);
+
+ reg16 = 0xff;
+ early_read_config_word(hose, hose->first_busno, 0, PCI_COMMAND, ®16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ early_write_config_word(hose, hose->first_busno, 0, PCI_COMMAND, reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ early_write_config_word(hose, hose->first_busno, 0, PCI_STATUS, 0xffff);
+ early_write_config_byte(hose, hose->first_busno, 0, PCI_LATENCY_TIMER, 0x80);
+
+ iounmap(pci_ctrl);
+ iounmap(ios);
+}
+
+void __init
+mpc83xx_setup_pci2(struct pci_controller *hose)
+{
+ u16 reg16;
+ volatile immr_pcictrl_t * pci_ctrl;
+ volatile immr_ios_t * ios;
+ bd_t *binfo = (bd_t *) __res;
+
+ pci_ctrl = ioremap(binfo->bi_immr_base + 0x8600, sizeof(immr_pcictrl_t));
+ ios = ioremap(binfo->bi_immr_base + 0x8400, sizeof(immr_ios_t));
+
+ /*
+ * Configure PCI Outbound Translation Windows
+ */
+ ios->potar3 = (MPC83xx_PCI2_LOWER_MEM >> 12) & POTAR_TA_MASK;
+ ios->pobar3 = (MPC83xx_PCI2_LOWER_MEM >> 12) & POBAR_BA_MASK;
+ ios->pocmr3 = POCMR_EN | POCMR_DST |
+ (((0xffffffff - (MPC83xx_PCI2_UPPER_MEM -
+ MPC83xx_PCI2_LOWER_MEM)) >> 12) & POCMR_CM_MASK);
+
+ /* mapped to PCI2 IO space */
+ ios->potar4 = (MPC83xx_PCI2_LOWER_IO >> 12) & POTAR_TA_MASK;
+ ios->pobar4 = (MPC83xx_PCI2_IO_BASE >> 12) & POBAR_BA_MASK;
+ ios->pocmr4 = POCMR_EN | POCMR_DST | POCMR_IO |
+ (((0xffffffff - (MPC83xx_PCI2_UPPER_IO -
+ MPC83xx_PCI2_LOWER_IO)) >> 12) & POCMR_CM_MASK);
+
+ /*
+ * Configure PCI Inbound Translation Windows
+ */
+ pci_ctrl->pitar1 = 0x0;
+ pci_ctrl->pibar1 = 0x0;
+ pci_ctrl->piebar1 = 0x0;
+ pci_ctrl->piwar1 = PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP | PIWAR_IWS_2G;
+
+ /*
+ * Release PCI RST signal
+ */
+ pci_ctrl->gcr = 0;
+ udelay(2000);
+ pci_ctrl->gcr = 1;
+ udelay(2000);
+
+ reg16 = 0xff;
+ early_read_config_word(hose, hose->first_busno, 0, PCI_COMMAND, ®16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ early_write_config_word(hose, hose->first_busno, 0, PCI_COMMAND, reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ early_write_config_word(hose, hose->first_busno, 0, PCI_STATUS, 0xffff);
+ early_write_config_byte(hose, hose->first_busno, 0, PCI_LATENCY_TIMER, 0x80);
+
+ iounmap(pci_ctrl);
+ iounmap(ios);
+}
+
+/*
+ * PCI buses can be enabled only if SYS board combinates with PIB
+ * (Platform IO Board) board which provide 3 PCI slots. There is 2 PCI buses
+ * and 3 PCI slots, so people must configure the routes between them before
+ * enable PCI bus. This routes are under the control of PCA9555PW device which
+ * can be accessed via I2C bus 2 and are configured by firmware. Refer to
+ * Freescale to get more information about firmware configuration.
+ */
+
+extern int mpc83xx_exclude_device(u_char bus, u_char devfn);
+extern int mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel,
+ unsigned char pin);
+void __init
+mpc83xx_setup_hose(void)
+{
+ u32 val32;
+ volatile immr_clk_t * clk;
+ struct pci_controller * hose1;
+#ifdef CONFIG_MPC83xx_PCI2
+ struct pci_controller * hose2;
+#endif
+ bd_t * binfo = (bd_t *)__res;
+
+ clk = ioremap(binfo->bi_immr_base + 0xA00,
+ sizeof(immr_clk_t));
+
+ /*
+ * Configure PCI controller and PCI_CLK_OUTPUT both in 66M mode
+ */
+ val32 = clk->occr;
+ udelay(2000);
+ clk->occr = 0xff000000;
+ udelay(2000);
+
+ iounmap(clk);
+
+ hose1 = pcibios_alloc_controller();
+ if(!hose1)
+ return;
+
+ ppc_md.pci_swizzle = common_swizzle;
+ ppc_md.pci_map_irq = mpc83xx_map_irq;
+
+ hose1->bus_offset = 0;
+ hose1->first_busno = 0;
+ hose1->last_busno = 0xff;
+
+ setup_indirect_pci(hose1, binfo->bi_immr_base + PCI1_CFG_ADDR_OFFSET,
+ binfo->bi_immr_base + PCI1_CFG_DATA_OFFSET);
+ hose1->set_cfg_type = 1;
+
+ mpc83xx_setup_pci1(hose1);
+
+ hose1->pci_mem_offset = MPC83xx_PCI1_MEM_OFFSET;
+ hose1->mem_space.start = MPC83xx_PCI1_LOWER_MEM;
+ hose1->mem_space.end = MPC83xx_PCI1_UPPER_MEM;
+
+ hose1->io_base_phys = MPC83xx_PCI1_IO_BASE;
+ hose1->io_space.start = MPC83xx_PCI1_LOWER_IO;
+ hose1->io_space.end = MPC83xx_PCI1_UPPER_IO;
+#ifdef CONFIG_MPC83xx_PCI2
+ isa_io_base = (unsigned long)ioremap(MPC83xx_PCI1_IO_BASE,
+ MPC83xx_PCI1_IO_SIZE + MPC83xx_PCI2_IO_SIZE);
+#else
+ isa_io_base = (unsigned long)ioremap(MPC83xx_PCI1_IO_BASE,
+ MPC83xx_PCI1_IO_SIZE);
+#endif /* CONFIG_MPC83xx_PCI2 */
+ hose1->io_base_virt = (void *)isa_io_base;
+ /* setup resources */
+ pci_init_resource(&hose1->io_resource,
+ MPC83xx_PCI1_LOWER_IO,
+ MPC83xx_PCI1_UPPER_IO,
+ IORESOURCE_IO, "PCI host bridge 1");
+ pci_init_resource(&hose1->mem_resources[0],
+ MPC83xx_PCI1_LOWER_MEM,
+ MPC83xx_PCI1_UPPER_MEM,
+ IORESOURCE_MEM, "PCI host bridge 1");
+
+ ppc_md.pci_exclude_device = mpc83xx_exclude_device;
+ hose1->last_busno = pciauto_bus_scan(hose1, hose1->first_busno);
+
+#ifdef CONFIG_MPC83xx_PCI2
+ hose2 = pcibios_alloc_controller();
+ if(!hose2)
+ return;
+
+ hose2->bus_offset = hose1->last_busno + 1;
+ hose2->first_busno = hose1->last_busno + 1;
+ hose2->last_busno = 0xff;
+ setup_indirect_pci(hose2, binfo->bi_immr_base + PCI2_CFG_ADDR_OFFSET,
+ binfo->bi_immr_base + PCI2_CFG_DATA_OFFSET);
+ hose2->set_cfg_type = 1;
+
+ mpc83xx_setup_pci2(hose2);
+
+ hose2->pci_mem_offset = MPC83xx_PCI2_MEM_OFFSET;
+ hose2->mem_space.start = MPC83xx_PCI2_LOWER_MEM;
+ hose2->mem_space.end = MPC83xx_PCI2_UPPER_MEM;
+
+ hose2->io_base_phys = MPC83xx_PCI2_IO_BASE;
+ hose2->io_space.start = MPC83xx_PCI2_LOWER_IO;
+ hose2->io_space.end = MPC83xx_PCI2_UPPER_IO;
+ hose2->io_base_virt = (void *)(isa_io_base + MPC83xx_PCI1_IO_SIZE);
+ /* setup resources */
+ pci_init_resource(&hose2->io_resource,
+ MPC83xx_PCI2_LOWER_IO,
+ MPC83xx_PCI2_UPPER_IO,
+ IORESOURCE_IO, "PCI host bridge 2");
+ pci_init_resource(&hose2->mem_resources[0],
+ MPC83xx_PCI2_LOWER_MEM,
+ MPC83xx_PCI2_UPPER_MEM,
+ IORESOURCE_MEM, "PCI host bridge 2");
+
+ hose2->last_busno = pciauto_bus_scan(hose2, hose2->first_busno);
+#endif /* CONFIG_MPC83xx_PCI2 */
+}
+#endif /*CONFIG_PCI*/
diff --git a/arch/ppc/syslib/ppc83xx_setup.h b/arch/ppc/syslib/ppc83xx_setup.h
--- a/arch/ppc/syslib/ppc83xx_setup.h
+++ b/arch/ppc/syslib/ppc83xx_setup.h
@@ -12,6 +12,14 @@
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __PPC_SYSLIB_PPC83XX_SETUP_H
@@ -19,7 +27,6 @@
#include <linux/config.h>
#include <linux/init.h>
-#include <asm/ppcboot.h>
extern unsigned long mpc83xx_find_end_of_memory(void) __init;
extern long mpc83xx_time_init(void) __init;
@@ -31,13 +38,11 @@ extern void mpc83xx_halt(void);
extern void mpc83xx_setup_hose(void) __init;
/* PCI config */
-#if 0
-#define PCI1_CFG_ADDR_OFFSET (FIXME)
-#define PCI1_CFG_DATA_OFFSET (FIXME)
+#define PCI1_CFG_ADDR_OFFSET (0x8300)
+#define PCI1_CFG_DATA_OFFSET (0x8304)
-#define PCI2_CFG_ADDR_OFFSET (FIXME)
-#define PCI2_CFG_DATA_OFFSET (FIXME)
-#endif
+#define PCI2_CFG_ADDR_OFFSET (0x8380)
+#define PCI2_CFG_DATA_OFFSET (0x8384)
/* Serial Config */
#ifdef CONFIG_SERIAL_MANY_PORTS
^ permalink raw reply
* Re: [PATCH] ppc32 :Added PCI support for MPC83xx
From: Kumar Gala @ 2005-08-30 14:47 UTC (permalink / raw)
To: Li Tony-r64360; +Cc: Chu hanjin-r52514, linux-kernel, linuxppc-embedded
In-Reply-To: <9FCDBA58F226D911B202000BDBAD467302C7C0CC@zch01exm40.ap.freescale.net>
Tony,
I'm going to assume that I only need the following lines:
> 0, /* EXT 3 */
> - 0, /* EXT 4 */
> - 0, /* EXT 5 */
> - 0, /* EXT 6 */
> - 0, /* EXT 7 */
> + IRQ_SENSE_LEVEL, /* EXT 4 */
> + IRQ_SENSE_LEVEL, /* EXT 5 */
> + IRQ_SENSE_LEVEL, /* EXT 6 */
> + IRQ_SENSE_LEVEL, /* EXT 7 */
Please, in the future either just create a patch an top of original
patch which shows just the new delta or start from the patch that I
sent since that is going to be my starting point. Your patch has a
lot of reformatting changes which make it extremely difficult to
review (hard to tell if the change is because of some fix or just
whitespace).
- kumar
On Aug 30, 2005, at 3:55 AM, Li Tony-r64360 wrote:
> MPC83xx cpu has two PCI buses. This patch adds support for them.
>
> After system boot. The code initializes PCI inbound/outbound
> windows, allocate and register PCI memory/io space. Be aware
> that this patch depand on the firmware.
>
> Signed-off-by: Tony Li <tony.li@freescale.com>
>
> ---
> author Tony Li <tony.li@freescale.com> Tue, 30 Aug 2005
> committer Tony Li <tony.li@freescale.com> Tue, 30 Aug 2005
>
> diff -urN -X dontdiff linux-2.6.13-rc6/arch/ppc/Kconfig
> linux-2.6.13-rc6-pci/arch/ppc/Kconfig
> --- linux-2.6.13-rc6/arch/ppc/Kconfig 2005-08-09 18:00:47.000000000
> +0800
> +++ linux-2.6.13-rc6-pci/arch/ppc/Kconfig 2005-08-19
> 18:17:27.000000000
> +0800
> @@ -712,6 +712,11 @@
> bool "Freescale MPC834x SYS"
> help
> This option enables support for the MPC 834x SYS evaluation board.
> + Be aware that PCI buses can only function when SYS board is
> plugged
> on
> + PIB (Platform IO Board) board from Freescale which provide 3 PCI
> slots.
> + Just like PC,the board level initalization is bootloader`s
> responsiblilty.
> + The PCI deponds on bootloader configurate board corretly. Refer to
> Freescale
> + to get more information about this.
>
> endchoice
>
> @@ -1191,6 +1196,10 @@
> bool
> default PCI
>
> +config MPC834x_PCI2
> + bool
> + default y if PCI && MPC834x_SYS
> +
> config PCI_QSPAN
> bool "QSpan PCI"
> depends on !4xx && !CPM2 && 8xx
> diff -urN -X dontdiff
> linux-2.6.13-rc6/arch/ppc/platforms/83xx/mpc834x_sys.c
> linux-2.6.13-rc6-pci/arch/ppc/platforms/83xx/mpc834x_sys.c
> --- linux-2.6.13-rc6/arch/ppc/platforms/83xx/mpc834x_sys.c 2005-08-09
> 18:00:47.000000000 +0800
> +++ linux-2.6.13-rc6-pci/arch/ppc/platforms/83xx/mpc834x_sys.c
> 2005-08-30 16:38:52.000000000 +0800
> @@ -62,9 +62,28 @@
> unsigned char __res[sizeof (bd_t)];
>
> #ifdef CONFIG_PCI
> -#error "PCI is not supported"
> -/* NEED mpc83xx_map_irq & mpc83xx_exclude_device
> - see platforms/85xx/mpc85xx_ads_common.c */
> +int
> +mpc83xx_ads_map_irq(struct pci_dev *dev,unsigned char idsel,unsigned
> char pin)
> +{
> + char pci_irq_table[][4]=
> + /*
> + * PCI IDSEL&INTPIN -> INTLINE
> + * INTA INTB INTC INTD
> + */
> + {
> + {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x11 */
> + {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x12 */
> + {PIRQD, PIRQA, PIRQB, PIRQC} /* idsel 0x13 */
> + };
> + /* MPC8349 MDS board specific */
> + const long min_idsel=0x11,max_idsel=0x13,irqs_per_slot=4;
> + return PCI_IRQ_TABLE_LOOKUP;
> +}
> +int
> +mpc83xx_ads_exclude_device(u_char bus, u_char devfn)
> +{
> + return PCIBIOS_SUCCESSFUL;
> +}
> #endif /* CONFIG_PCI */
>
> /*
> **********************************************************************
> **
> @@ -88,7 +107,7 @@
>
> #ifdef CONFIG_PCI
> /* setup PCI host bridges */
> - mpc83xx_sys_setup_hose();
> + mpc83xx_setup_hose();
> #endif
> mpc83xx_early_serial_map();
>
> @@ -175,10 +194,10 @@
> IRQ_SENSE_LEVEL, /* EXT 1 */
> IRQ_SENSE_LEVEL, /* EXT 2 */
> 0, /* EXT 3 */
> - 0, /* EXT 4 */
> - 0, /* EXT 5 */
> - 0, /* EXT 6 */
> - 0, /* EXT 7 */
> + IRQ_SENSE_LEVEL, /* EXT 4 */
> + IRQ_SENSE_LEVEL, /* EXT 5 */
> + IRQ_SENSE_LEVEL, /* EXT 6 */
> + IRQ_SENSE_LEVEL, /* EXT 7 */
> };
>
> ipic_init(binfo->bi_immr_base + 0x00700, 0, MPC83xx_IPIC_IRQ_OFFSET,
> senses, 8);
> diff -urN -X dontdiff
> linux-2.6.13-rc6/arch/ppc/platforms/83xx/mpc834x_sys.h
> linux-2.6.13-rc6-pci/arch/ppc/platforms/83xx/mpc834x_sys.h
> --- linux-2.6.13-rc6/arch/ppc/platforms/83xx/mpc834x_sys.h 2005-06-18
> 03:48:29.000000000 +0800
> +++ linux-2.6.13-rc6-pci/arch/ppc/platforms/83xx/mpc834x_sys.h
> 2005-08-23 10:00:08.000000000 +0800
> @@ -26,7 +26,7 @@
> #define VIRT_IMMRBAR ((uint)0xfe000000)
>
> #define BCSR_PHYS_ADDR ((uint)0xf8000000)
> -#define BCSR_SIZE ((uint)(32 * 1024))
> +#define BCSR_SIZE ((uint)(128 * 1024))
>
> #define BCSR_MISC_REG2_OFF 0x07
> #define BCSR_MISC_REG2_PORESET 0x01
> @@ -35,22 +35,34 @@
> #define BCSR_MISC_REG3_CNFLOCK 0x80
>
> #ifdef CONFIG_PCI
> -/* PCI interrupt controller */
> -#define PIRQA MPC83xx_IRQ_IRQ4
> -#define PIRQB MPC83xx_IRQ_IRQ5
> -#define PIRQC MPC83xx_IRQ_IRQ6
> -#define PIRQD MPC83xx_IRQ_IRQ7
> -
> -#define MPC834x_SYS_PCI1_LOWER_IO 0x00000000
> -#define MPC834x_SYS_PCI1_UPPER_IO 0x00ffffff
>
> -#define MPC834x_SYS_PCI1_LOWER_MEM 0x80000000
> -#define MPC834x_SYS_PCI1_UPPER_MEM 0x9fffffff
> +#define PCI1_CFG_ADDR_OFFSET (0x8300)
> +#define PCI1_CFG_DATA_OFFSET (0x8304)
>
> -#define MPC834x_SYS_PCI1_IO_BASE 0xe2000000
> -#define MPC834x_SYS_PCI1_MEM_OFFSET 0x00000000
> +#define PCI2_CFG_ADDR_OFFSET (0x8380)
> +#define PCI2_CFG_DATA_OFFSET (0x8384)
> +
> +#define PIRQA MPC83xx_IRQ_EXT4
> +#define PIRQB MPC83xx_IRQ_EXT5
> +#define PIRQC MPC83xx_IRQ_EXT6
> +#define PIRQD MPC83xx_IRQ_EXT7
> +
> +#define MPC83xx_PCI1_LOWER_IO 0x00000000
> +#define MPC83xx_PCI1_UPPER_IO 0x00ffffff
> +#define MPC83xx_PCI1_LOWER_MEM 0x80000000
> +#define MPC83xx_PCI1_UPPER_MEM 0x9fffffff
> +#define MPC83xx_PCI1_IO_BASE 0xe2000000
> +#define MPC83xx_PCI1_MEM_OFFSET 0x00000000
> +#define MPC83xx_PCI1_IO_SIZE 0x01000000
> +
> +#define MPC83xx_PCI2_LOWER_IO 0x00000000
> +#define MPC83xx_PCI2_UPPER_IO 0x00ffffff
> +#define MPC83xx_PCI2_LOWER_MEM 0xa0000000
> +#define MPC83xx_PCI2_UPPER_MEM 0xbfffffff
> +#define MPC83xx_PCI2_IO_BASE 0xe3000000
> +#define MPC83xx_PCI2_MEM_OFFSET 0x00000000
> +#define MPC83xx_PCI2_IO_SIZE 0x01000000
>
> -#define MPC834x_SYS_PCI1_IO_SIZE 0x01000000
> #endif /* CONFIG_PCI */
>
> #endif /* __MACH_MPC83XX_SYS_H__ */
> diff -urN -X dontdiff linux-2.6.13-rc6/arch/ppc/syslib/ppc834x_pci.h
> linux-2.6.13-rc6-pci/arch/ppc/syslib/ppc834x_pci.h
> --- linux-2.6.13-rc6/arch/ppc/syslib/ppc834x_pci.h 1970-01-01
> 08:30:00.000000000 +0830
> +++ linux-2.6.13-rc6-pci/arch/ppc/syslib/ppc834x_pci.h 2005-08-19
> 18:30:11.000000000 +0800
> @@ -0,0 +1,161 @@
> +/* Created by Tony Li <tony.li@freescale.com> 2005.6
> + * Copyright (c) 2005 freescale semiconductor
> + *
> + * This program is free software; you can redistribute it and/or
> modify it
> + * under the terms of the GNU General Public License as
> published by
> the
> + * Free Software Foundation; either version 2 of the License, or
> (at
> your
> + * option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> along
> + * with this program; if not, write to the Free Software Foundation,
> Inc.,
> + * 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +#ifndef __MPC834X_PCI_H__
> +#define __MPC834X_PCI_H__
> +
> +typedef struct immr_clk {
> + u32 spmr; /* system PLL mode Register */
> + u32 occr; /* output clock control Register */
> + u32 sccr; /* system clock control Register */
> + u8 res0[0xF4];
> +} immr_clk_t;
> +
> +/*
> + * PCI Software Configuration Registers
> + */
> +typedef struct immr_pciconf {
> + u32 config_address;
> + u32 config_data;
> + u32 int_ack;
> + u8 res[116];
> +} immr_pciconf_t;
> +
> +/*
> + * Sequencer
> + */
> +typedef struct immr_ios {
> + u32 potar0;
> + u8 res0[4];
> + u32 pobar0;
> + u8 res1[4];
> + u32 pocmr0;
> + u8 res2[4];
> + u32 potar1;
> + u8 res3[4];
> + u32 pobar1;
> + u8 res4[4];
> + u32 pocmr1;
> + u8 res5[4];
> + u32 potar2;
> + u8 res6[4];
> + u32 pobar2;
> + u8 res7[4];
> + u32 pocmr2;
> + u8 res8[4];
> + u32 potar3;
> + u8 res9[4];
> + u32 pobar3;
> + u8 res10[4];
> + u32 pocmr3;
> + u8 res11[4];
> + u32 potar4;
> + u8 res12[4];
> + u32 pobar4;
> + u8 res13[4];
> + u32 pocmr4;
> + u8 res14[4];
> + u32 potar5;
> + u8 res15[4];
> + u32 pobar5;
> + u8 res16[4];
> + u32 pocmr5;
> + u8 res17[4];
> + u8 res18[0x60];
> + u32 pmcr;
> + u8 res19[4];
> + u32 dtcr;
> + u8 res20[4];
> +} immr_ios_t;
> +#define POTAR_TA_MASK 0x000fffff
> +#define POBAR_BA_MASK 0x000fffff
> +#define POCMR_EN 0x80000000
> +#define POCMR_IO 0x40000000 /* 0--memory space 1--I/O space */
> +#define POCMR_SE 0x20000000 /* streaming enable */
> +#define POCMR_DST 0x10000000 /* 0--PCI1 1--PCI2 */
> +#define POCMR_CM_MASK 0x000fffff
> +
> +/*
> + * PCI Controller Control and Status Registers
> + */
> +typedef struct immr_pcictrl {
> + u32 esr;
> + u32 ecdr;
> + u32 eer;
> + u32 eatcr;
> + u32 eacr;
> + u32 eeacr;
> + u32 edlcr;
> + u32 edhcr;
> + u32 gcr;
> + u32 ecr;
> + u32 gsr;
> + u8 res0[12];
> + u32 pitar2;
> + u8 res1[4];
> + u32 pibar2;
> + u32 piebar2;
> + u32 piwar2;
> + u8 res2[4];
> + u32 pitar1;
> + u8 res3[4];
> + u32 pibar1;
> + u32 piebar1;
> + u32 piwar1;
> + u8 res4[4];
> + u32 pitar0;
> + u8 res5[4];
> + u32 pibar0;
> + u8 res6[4];
> + u32 piwar0;
> + u8 res7[132];
> +} immr_pcictrl_t;
> +#define PITAR_TA_MASK 0x000fffff
> +#define PIBAR_MASK 0xffffffff
> +#define PIEBAR_EBA_MASK 0x000fffff
> +#define PIWAR_EN 0x80000000
> +#define PIWAR_PF 0x20000000
> +#define PIWAR_RTT_MASK 0x000f0000
> +#define PIWAR_RTT_NO_SNOOP 0x00040000
> +#define PIWAR_RTT_SNOOP 0x00050000
> +#define PIWAR_WTT_MASK 0x0000f000
> +#define PIWAR_WTT_NO_SNOOP 0x00004000
> +#define PIWAR_WTT_SNOOP 0x00005000
> +#define PIWAR_IWS_MASK 0x0000003F
> +#define PIWAR_IWS_4K 0x0000000B
> +#define PIWAR_IWS_8K 0x0000000C
> +#define PIWAR_IWS_16K 0x0000000D
> +#define PIWAR_IWS_32K 0x0000000E
> +#define PIWAR_IWS_64K 0x0000000F
> +#define PIWAR_IWS_128K 0x00000010
> +#define PIWAR_IWS_256K 0x00000011
> +#define PIWAR_IWS_512K 0x00000012
> +#define PIWAR_IWS_1M 0x00000013
> +#define PIWAR_IWS_2M 0x00000014
> +#define PIWAR_IWS_4M 0x00000015
> +#define PIWAR_IWS_8M 0x00000016
> +#define PIWAR_IWS_16M 0x00000017
> +#define PIWAR_IWS_32M 0x00000018
> +#define PIWAR_IWS_64M 0x00000019
> +#define PIWAR_IWS_128M 0x0000001A
> +#define PIWAR_IWS_256M 0x0000001B
> +#define PIWAR_IWS_512M 0x0000001C
> +#define PIWAR_IWS_1G 0x0000001D
> +#define PIWAR_IWS_2G 0x0000001E
> +
> +#endif /*__MPC834X_PCI_H__*/
> diff -urN -X dontdiff linux-2.6.13-rc6/arch/ppc/syslib/ppc83xx_setup.c
> linux-2.6.13-rc6-pci/arch/ppc/syslib/ppc83xx_setup.c
> --- linux-2.6.13-rc6/arch/ppc/syslib/ppc83xx_setup.c 2005-08-09
> 18:00:47.000000000 +0800
> +++ linux-2.6.13-rc6-pci/arch/ppc/syslib/ppc83xx_setup.c 2005-08-23
> 10:18:04.000000000 +0800
> @@ -11,6 +11,20 @@
> * under the terms of the GNU General Public License as
> published by
> the
> * Free Software Foundation; either version 2 of the License, or
> (at
> your
> * option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> along
> + * with this program; if not, write to the Free Software Foundation,
> Inc.,
> + * 675 Mass Ave, Cambridge, MA 02139, USA.
> + *
> + * July 2005, Tony Li<tony.li@freescale.com>
> + * Added PCI support
> + * PCI can be enabled only if MPC834x SYS board combined with
> PIB(Platform
> + * IO Board) board in which three physical PCI slots locate.
> */
>
> #include <linux/config.h>
> @@ -19,7 +33,7 @@
> #include <linux/init.h>
> #include <linux/pci.h>
> #include <linux/serial.h>
> -#include <linux/tty.h> /* for linux/serial_core.h */
> +#include <linux/tty.h> /* for linux/serial_core.h */
> #include <linux/serial_core.h>
> #include <linux/serial_8250.h>
>
> @@ -31,27 +45,29 @@
> #include <asm/delay.h>
>
> #include <syslib/ppc83xx_setup.h>
> +#if defined(CONFIG_PCI)
> +#include <asm/delay.h>
> +#include <syslib/ppc834x_pci.h>
> +#endif
>
> phys_addr_t immrbar;
>
> /* Return the amount of memory */
> -unsigned long __init
> -mpc83xx_find_end_of_memory(void)
> +unsigned long __init mpc83xx_find_end_of_memory(void)
> {
> - bd_t *binfo;
> + bd_t *binfo;
>
> - binfo = (bd_t *) __res;
> + binfo = (bd_t *) __res;
>
> - return binfo->bi_memsize;
> + return binfo->bi_memsize;
> }
>
> -long __init
> -mpc83xx_time_init(void)
> +long __init mpc83xx_time_init(void)
> {
> #define SPCR_OFFS 0x00000110
> #define SPCR_TBEN 0x00400000
>
> - bd_t *binfo = (bd_t *)__res;
> + bd_t *binfo = (bd_t *) __res;
> u32 *spcr = ioremap(binfo->bi_immr_base + SPCR_OFFS, 4);
>
> *spcr |= SPCR_TBEN;
> @@ -62,11 +78,10 @@
> }
>
> /* The decrementer counts at the system (internal) clock freq divided
> by 4 */
> -void __init
> -mpc83xx_calibrate_decr(void)
> +void __init mpc83xx_calibrate_decr(void)
> {
> - bd_t *binfo = (bd_t *) __res;
> - unsigned int freq, divisor;
> + bd_t *binfo = (bd_t *) __res;
> + unsigned int freq, divisor;
>
> freq = binfo->bi_busfreq;
> divisor = 4;
> @@ -75,15 +90,14 @@
> }
>
> #ifdef CONFIG_SERIAL_8250
> -void __init
> -mpc83xx_early_serial_map(void)
> +void __init mpc83xx_early_serial_map(void)
> {
> #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
> struct uart_port serial_req;
> #endif
> struct plat_serial8250_port *pdata;
> bd_t *binfo = (bd_t *) __res;
> - pdata = (struct plat_serial8250_port *)
> ppc_sys_get_pdata(MPC83xx_DUART);
> + pdata = (struct plat_serial8250_port
> *)ppc_sys_get_pdata(MPC83xx_DUART);
>
> /* Setup serial port access */
> pdata[0].uartclk = binfo->bi_busfreq;
> @@ -91,7 +105,7 @@
> pdata[0].membase = ioremap(pdata[0].mapbase, 0x100);
>
> #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
> - memset(&serial_req, 0, sizeof (serial_req));
> + memset(&serial_req, 0, sizeof(serial_req));
> serial_req.iotype = SERIAL_IO_MEM;
> serial_req.mapbase = pdata[0].mapbase;
> serial_req.membase = pdata[0].membase;
> @@ -114,8 +128,7 @@
> }
> #endif
>
> -void
> -mpc83xx_restart(char *cmd)
> +void mpc83xx_restart(char *cmd)
> {
> volatile unsigned char __iomem *reg;
> unsigned char tmp;
> @@ -129,7 +142,7 @@
> * Otherwise the reset asserts but doesn't clear.
> */
> tmp = in_8(reg + BCSR_MISC_REG3_OFF);
> - tmp |= BCSR_MISC_REG3_CNFLOCK; /* low true, high false */
> + tmp |= BCSR_MISC_REG3_CNFLOCK; /* low true, high false */
> out_8(reg + BCSR_MISC_REG3_OFF, tmp);
>
> /*
> @@ -145,21 +158,252 @@
> tmp |= BCSR_MISC_REG2_PORESET;
> out_8(reg + BCSR_MISC_REG2_OFF, tmp);
>
> - for(;;);
> + for (;;) ;
> }
>
> -void
> -mpc83xx_power_off(void)
> +void mpc83xx_power_off(void)
> {
> local_irq_disable();
> - for(;;);
> + for (;;) ;
> }
>
> -void
> -mpc83xx_halt(void)
> +void mpc83xx_halt(void)
> {
> local_irq_disable();
> - for(;;);
> + for (;;) ;
> +}
> +
> +#if defined(CONFIG_PCI)
> +void __init mpc83xx_setup_pci1(struct pci_controller *hose)
> +{
> + unsigned short reg16;
> + volatile immr_pcictrl_t *pci_ctrl;
> + volatile immr_ios_t *ios;
> + bd_t *binfo = (bd_t *) __res;
> +
> + pci_ctrl = ioremap(binfo->bi_immr_base + 0x8500,
> + sizeof(immr_pcictrl_t));
> + ios = ioremap(binfo->bi_immr_base + 0x8400, sizeof(immr_ios_t));
> +
> + /*
> + * Configure PCI Outbound Translation Windows
> + */
> + ios->potar0 = (MPC83xx_PCI1_LOWER_MEM >> 12) & POTAR_TA_MASK;
> + ios->pobar0 = (MPC83xx_PCI1_LOWER_MEM >> 12) & POBAR_BA_MASK;
> + ios->pocmr0 = POCMR_EN |
> + (((~0UL -
> + (MPC83xx_PCI1_UPPER_MEM -
> + MPC83xx_PCI1_LOWER_MEM)) >> 12) & POCMR_CM_MASK);
> +
> + /* mapped to PCI1 IO space 0x0 to local 0xe2000000 */
> + ios->potar1 = (MPC83xx_PCI1_LOWER_IO >> 12) & POTAR_TA_MASK;
> + ios->pobar1 = (MPC83xx_PCI1_IO_BASE >> 12) & POBAR_BA_MASK;
> + ios->pocmr1 = POCMR_EN | POCMR_IO |
> + (((~0UL -
> + (MPC83xx_PCI1_UPPER_IO -
> + MPC83xx_PCI1_LOWER_IO)) >> 12) & POCMR_CM_MASK);
> +
> + /*
> + * Configure PCI Inbound Translation Windows
> + */
> + pci_ctrl->pitar1 = 0x0;
> + pci_ctrl->pibar1 = 0x0;
> + pci_ctrl->piebar1 = 0x0;
> + pci_ctrl->piwar1 =
> + PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP |
> + PIWAR_IWS_2G;
> +
> + /*
> + * Release PCI RST signal
> + */
> + pci_ctrl->gcr = 0;
> + udelay(2000);
> + pci_ctrl->gcr = 1;
> + udelay(2000);
> +
> + reg16 = 0xff;
> + early_read_config_word(hose, hose->first_busno, 0, PCI_COMMAND,
> ®16);
> + reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
> + early_write_config_word(hose, hose->first_busno, 0, PCI_COMMAND,
> reg16);
> +
> + /*
> + * Clear non-reserved bits in status register.
> + */
> + early_write_config_word(hose, hose->first_busno, 0, PCI_STATUS,
> 0xffff);
> + early_write_config_byte(hose, hose->first_busno, 0,
> PCI_LATENCY_TIMER,
> + 0x80);
> }
>
> -/* PCI SUPPORT DOES NOT EXIT, MODEL after ppc85xx_setup.c */
> +void __init mpc834x_ads_setup_pci2(struct pci_controller *hose)
> +{
> + unsigned short reg16;
> + volatile immr_pcictrl_t *pci_ctrl;
> + volatile immr_ios_t *ios;
> + bd_t *binfo = (bd_t *) __res;
> +
> + pci_ctrl = ioremap(binfo->bi_immr_base + 0x8600,
> + sizeof(immr_pcictrl_t));
> + ios = ioremap(binfo->bi_immr_base + 0x8400, sizeof(immr_ios_t));
> +
> + /*
> + * Configure PCI Outbound Translation Windows
> + */
> + ios->potar3 = (MPC83xx_PCI2_LOWER_MEM >> 12) & POTAR_TA_MASK;
> + ios->pobar3 = (MPC83xx_PCI2_LOWER_MEM >> 12) & POBAR_BA_MASK;
> + ios->pocmr3 = POCMR_EN | POCMR_DST |
> + (((~0UL -
> + (MPC83xx_PCI2_UPPER_MEM -
> + MPC83xx_PCI2_LOWER_MEM)) >> 12) & POCMR_CM_MASK);
> +
> + /* mapped to PCI2 IO space 0x0 to local 0xe3000000 */
> + ios->potar4 = (MPC83xx_PCI2_LOWER_IO >> 12) & POTAR_TA_MASK;
> + ios->pobar4 = (MPC83xx_PCI2_IO_BASE >> 12) & POBAR_BA_MASK;
> + ios->pocmr4 = POCMR_EN | POCMR_DST | POCMR_IO |
> + (((~0UL -
> + (MPC83xx_PCI2_UPPER_IO -
> + MPC83xx_PCI2_LOWER_IO)) >> 12) & POCMR_CM_MASK);
> +
> + /*
> + * Configure PCI Inbound Translation Windows
> + */
> + pci_ctrl->pitar1 = 0x0;
> + pci_ctrl->pibar1 = 0x0;
> + pci_ctrl->piebar1 = 0x0;
> + pci_ctrl->piwar1 =
> + PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP |
> + PIWAR_IWS_2G;
> +
> + /*
> + * Release PCI RST signal
> + */
> + pci_ctrl->gcr = 0;
> + udelay(2000);
> + pci_ctrl->gcr = 1;
> + udelay(2000);
> +
> + reg16 = 0xff;
> + early_read_config_word(hose, hose->first_busno, 0, PCI_COMMAND,
> ®16);
> + reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
> + early_write_config_word(hose, hose->first_busno, 0, PCI_COMMAND,
> reg16);
> +
> + /*
> + * Clear non-reserved bits in status register.
> + */
> + early_write_config_word(hose, hose->first_busno, 0, PCI_STATUS,
> 0xffff);
> + early_write_config_byte(hose, hose->first_busno, 0,
> PCI_LATENCY_TIMER,
> + 0x80);
> +}
> +
> +extern int mpc83xx_ads_map_irq(struct pci_dev *dev, unsigned char
> idsel,
> + unsigned char pin);
> +extern int mpc83xx_ads_exclude_device(u_char bus, u_char devfn);
> +
> +/*
> + * PCI buses can be enabled only if SYS board combinates with
> PIB(Platform IO Board) board
> + * which provide 3 PCI slots. There is 2 PCI buses and 3 PCI slots,so
> people must configure
> + * the routes between them before enable PCI bus. This routes are
> under
> the control of PCA9555PW
> + * device which can be accessed via I2C bus 2 and are configured by
> firmware. Refer to Freescale to
> + * get more information about firmware configuration.
> + */
> +void __init mpc83xx_setup_hose(void)
> +{
> + unsigned long val32;
> + volatile immr_clk_t *clk;
> + volatile struct pci_controller *hose1;
> +#ifdef CONFIG_MPC834x_PCI2
> + volatile struct pci_controller *hose2;
> +#endif
> + volatile bd_t *binfo = (bd_t *) __res;
> +
> + clk = ioremap(binfo->bi_immr_base + 0xA00, sizeof(immr_clk_t));
> +
> + /*
> + * Configure PCI controller and PCI_CLK_OUTPUT both in 66M mode
> + */
> + val32 = clk->occr;
> + udelay(2000);
> + clk->occr = 0xff000000;
> + udelay(2000);
> +
> + hose1 = pcibios_alloc_controller();
> + if (!hose1)
> + return;
> +
> + ppc_md.pci_swizzle = common_swizzle;
> + ppc_md.pci_map_irq = mpc83xx_ads_map_irq;
> +
> + hose1->bus_offset = 0;
> + hose1->first_busno = 0;
> + hose1->last_busno = 0xff;
> +
> + setup_indirect_pci(hose1, binfo->bi_immr_base +
> PCI1_CFG_ADDR_OFFSET,
> + binfo->bi_immr_base + PCI1_CFG_DATA_OFFSET);
> + hose1->set_cfg_type = 1;
> +
> + mpc83xx_setup_pci1(hose1);
> +
> + hose1->pci_mem_offset = MPC83xx_PCI1_MEM_OFFSET;
> + hose1->mem_space.start = MPC83xx_PCI1_LOWER_MEM;
> + hose1->mem_space.end = MPC83xx_PCI1_UPPER_MEM;
> +
> + hose1->io_base_phys = MPC83xx_PCI1_IO_BASE;
> + hose1->io_space.start = MPC83xx_PCI1_LOWER_IO;
> + hose1->io_space.end = MPC83xx_PCI1_UPPER_IO;
> +#ifdef CONFIG_MPC834x_PCI2
> + isa_io_base = (unsigned long)ioremap(MPC83xx_PCI1_IO_BASE,
> + MPC83xx_PCI1_IO_SIZE +
> + MPC83xx_PCI2_IO_SIZE);
> +#else
> + isa_io_base = (unsigned long)ioremap(MPC83xx_PCI1_IO_BASE,
> + MPC83xx_PCI1_IO_SIZE);
> +#endif /* CONFIG_MPC834x_PCI2 */
> + hose1->io_base_virt = (void *)isa_io_base;
> + /* setup resources */
> + pci_init_resource(&hose1->io_resource,
> + MPC83xx_PCI1_LOWER_IO,
> + MPC83xx_PCI1_UPPER_IO,
> + IORESOURCE_IO, "PCI host bridge 1");
> + pci_init_resource(&hose1->mem_resources[0],
> + MPC83xx_PCI1_LOWER_MEM,
> + MPC83xx_PCI1_UPPER_MEM,
> + IORESOURCE_MEM, "PCI host bridge 1");
> +
> + ppc_md.pci_exclude_device = mpc83xx_ads_exclude_device;
> + hose1->last_busno = pciauto_bus_scan(hose1, hose1->first_busno);
> +
> +#ifdef CONFIG_MPC834x_PCI2
> + hose2 = pcibios_alloc_controller();
> + if (!hose2)
> + return;
> +
> + hose2->bus_offset = hose1->last_busno + 1;
> + hose2->first_busno = hose1->last_busno + 1;
> + hose2->last_busno = 0xff;
> + setup_indirect_pci(hose2, binfo->bi_immr_base +
> PCI2_CFG_ADDR_OFFSET,
> + binfo->bi_immr_base + PCI2_CFG_DATA_OFFSET);
> + hose2->set_cfg_type = 1;
> +
> + mpc834x_ads_setup_pci2(hose2);
> +
> + hose2->pci_mem_offset = MPC83xx_PCI2_MEM_OFFSET;
> + hose2->mem_space.start = MPC83xx_PCI2_LOWER_MEM;
> + hose2->mem_space.end = MPC83xx_PCI2_UPPER_MEM;
> +
> + hose2->io_base_phys = MPC83xx_PCI2_IO_BASE;
> + hose2->io_space.start = MPC83xx_PCI2_LOWER_IO;
> + hose2->io_space.end = MPC83xx_PCI2_UPPER_IO;
> + hose2->io_base_virt = (void *)(isa_io_base + MPC83xx_PCI1_IO_SIZE);
> + /* setup resources */
> + pci_init_resource(&hose2->io_resource,
> + MPC83xx_PCI2_LOWER_IO,
> + MPC83xx_PCI2_UPPER_IO,
> + IORESOURCE_IO, "PCI host bridge 2");
> + pci_init_resource(&hose2->mem_resources[0],
> + MPC83xx_PCI2_LOWER_MEM,
> + MPC83xx_PCI2_UPPER_MEM,
> + IORESOURCE_MEM, "PCI host bridge 2");
> +
> + hose2->last_busno = pciauto_bus_scan(hose2, hose2->first_busno);
> +#endif /* CONFIG_MPC834x_PCI2 */
> +}
> +#endif /*CONFIG_PCI */
> diff -urN -X dontdiff linux-2.6.13-rc6/arch/ppc/syslib/ppc83xx_setup.h
> linux-2.6.13-rc6-pci/arch/ppc/syslib/ppc83xx_setup.h
> --- linux-2.6.13-rc6/arch/ppc/syslib/ppc83xx_setup.h 2005-06-18
> 03:48:29.000000000 +0800
> +++ linux-2.6.13-rc6-pci/arch/ppc/syslib/ppc83xx_setup.h 2005-08-23
> 10:25:43.000000000 +0800
> @@ -12,6 +12,14 @@
> * Free Software Foundation; either version 2 of the License, or
> (at
> your
> * option) any later version.
> *
> + * This program is distributed in the hope that it will be useful,
> but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> along
> + * with this program; if not, write to the Free Software Foundation,
> Inc.,
> + * 675 Mass Ave, Cambridge, MA 02139, USA.
> */
>
> #ifndef __PPC_SYSLIB_PPC83XX_SETUP_H
> @@ -20,6 +28,7 @@
> #include <linux/config.h>
> #include <linux/init.h>
> #include <asm/ppcboot.h>
> +#include <asm/mpc83xx.h>
>
> extern unsigned long mpc83xx_find_end_of_memory(void) __init;
> extern long mpc83xx_time_init(void) __init;
> @@ -30,15 +39,6 @@
> extern void mpc83xx_halt(void);
> extern void mpc83xx_setup_hose(void) __init;
>
> -/* PCI config */
> -#if 0
> -#define PCI1_CFG_ADDR_OFFSET (FIXME)
> -#define PCI1_CFG_DATA_OFFSET (FIXME)
> -
> -#define PCI2_CFG_ADDR_OFFSET (FIXME)
> -#define PCI2_CFG_DATA_OFFSET (FIXME)
> -#endif
> -
> /* Serial Config */
> #ifdef CONFIG_SERIAL_MANY_PORTS
> #define RS_TABLE_SIZE 64
> @@ -50,4 +50,4 @@
> #define BASE_BAUD 115200
> #endif
>
> -#endif /* __PPC_SYSLIB_PPC83XX_SETUP_H */
> +#endif /* __PPC_SYSLIB_PPC83XX_SETUP_H */
>
^ permalink raw reply
* Re: [PATCH] ppc32 :Added PCI support for MPC83xx
From: Dan Malek @ 2005-08-30 14:36 UTC (permalink / raw)
To: Li Tony-r64360; +Cc: linuxppc-embedded, Chu hanjin-r52514, linux-kernel
In-Reply-To: <9FCDBA58F226D911B202000BDBAD467302BEB8C6@zch01exm40.ap.freescale.net>
On Aug 29, 2005, at 11:02 PM, Li Tony-r64360 wrote:
> I think it is OK. The external interrupt can be edged. And it works
> well in my board.
No, it can't. PCI interrupts must be level sensitive because multiple
slots can share an interrupt.
Thanks.
-- Dan
^ permalink raw reply
* RE: [PATCH] ppc32 :Added PCI support for MPC83xx
From: Li Tony-r64360 @ 2005-08-30 3:02 UTC (permalink / raw)
To: Gala Kumar K.-galak; +Cc: Chu hanjin-r52514, linux-kernel, linuxppc-embedded
I think it is OK. The external interrupt can be edged. And it works well in my board.
Tony Li
-----Original Message-----
From: Gala Kumar K.-galak
Sent: Tuesday, August 30, 2005 1:43 AM
To: Li Tony-r64360
Cc: linuxppc-embedded; linux-kernel@vger.kernel.org; Gala Kumar K.-galak; Chu hanjin-r52514
Subject: Re: [PATCH] ppc32 :Added PCI support for MPC83xx
I noticed that you aren't updating the senses array in mpc834x_sys_init_IRQ for the PCI interrupt lines, is this correct?
Should they not be IRQ_SENSE_LEVEL?
Also, I've done a bit of cosmetic cleanup to the patch, take a look and let me know if it works. Once we close on the IRQ sense issue I will send this upstream.
- kumar
---
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -713,6 +713,12 @@ config MPC834x_SYS
help
This option enables support for the MPC 834x SYS evaluation board.
+ Be aware that PCI buses can only function when SYS board is plugged on
+ PIB (Platform IO Board) board from Freescale which provide 3 PCI slots.
+ Just like PC,the board level initalization is bootloader`s responsiblilty.
+ The PCI deponds on bootloader configurate board corretly. Refer to Freescale
+ to get more information about this.
+
endchoice
config PQ2ADS
@@ -1193,6 +1199,11 @@ config PCI
config PCI_DOMAINS
bool
default PCI
+
+config MPC83xx_PCI2
+ bool " Supprt for 2nd PCI host controller"
+ depends on PCI && MPC834x
+ default y if MPC834x_SYS
config PCI_QSPAN
bool "QSpan PCI"
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c
--- a/arch/ppc/platforms/83xx/mpc834x_sys.c
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.c
@@ -62,9 +62,29 @@ extern unsigned long total_memory; /* in
unsigned char __res[sizeof (bd_t)];
#ifdef CONFIG_PCI
-#error "PCI is not supported"
-/* NEED mpc83xx_map_irq & mpc83xx_exclude_device
- see platforms/85xx/mpc85xx_ads_common.c */
+int
+mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char
+pin) {
+ static char pci_irq_table[][4] =
+ /*
+ * PCI IDSEL/INTPIN->INTLINE
+ * A B C D
+ */
+ {
+ {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x11 */
+ {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x12 */
+ {PIRQD, PIRQA, PIRQB, PIRQC} /* idsel 0x13 */
+ };
+
+ const long min_idsel = 0x11, max_idsel = 0x13, irqs_per_slot = 4;
+ return PCI_IRQ_TABLE_LOOKUP;
+}
+
+int
+mpc83xx_exclude_device(u_char bus, u_char devfn) {
+ return PCIBIOS_SUCCESSFUL;
+}
#endif /* CONFIG_PCI */
/* ************************************************************************
@@ -88,7 +108,7 @@ mpc834x_sys_setup_arch(void)
#ifdef CONFIG_PCI
/* setup PCI host bridges */
- mpc83xx_sys_setup_hose();
+ mpc83xx_setup_hose();
#endif
mpc83xx_early_serial_map();
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.h b/arch/ppc/platforms/83xx/mpc834x_sys.h
--- a/arch/ppc/platforms/83xx/mpc834x_sys.h
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.h
@@ -26,7 +26,7 @@
#define VIRT_IMMRBAR ((uint)0xfe000000)
#define BCSR_PHYS_ADDR ((uint)0xf8000000)
-#define BCSR_SIZE ((uint)(32 * 1024))
+#define BCSR_SIZE ((uint)(128 * 1024))
#define BCSR_MISC_REG2_OFF 0x07
#define BCSR_MISC_REG2_PORESET 0x01
@@ -34,23 +34,25 @@
#define BCSR_MISC_REG3_OFF 0x08
#define BCSR_MISC_REG3_CNFLOCK 0x80
-#ifdef CONFIG_PCI
-/* PCI interrupt controller */
-#define PIRQA MPC83xx_IRQ_IRQ4
-#define PIRQB MPC83xx_IRQ_IRQ5
-#define PIRQC MPC83xx_IRQ_IRQ6
-#define PIRQD MPC83xx_IRQ_IRQ7
-
-#define MPC834x_SYS_PCI1_LOWER_IO 0x00000000
-#define MPC834x_SYS_PCI1_UPPER_IO 0x00ffffff
-
-#define MPC834x_SYS_PCI1_LOWER_MEM 0x80000000
-#define MPC834x_SYS_PCI1_UPPER_MEM 0x9fffffff
-
-#define MPC834x_SYS_PCI1_IO_BASE 0xe2000000
-#define MPC834x_SYS_PCI1_MEM_OFFSET 0x00000000
-
-#define MPC834x_SYS_PCI1_IO_SIZE 0x01000000
-#endif /* CONFIG_PCI */
+#define PIRQA MPC83xx_IRQ_EXT4
+#define PIRQB MPC83xx_IRQ_EXT5
+#define PIRQC MPC83xx_IRQ_EXT6
+#define PIRQD MPC83xx_IRQ_EXT7
+
+#define MPC83xx_PCI1_LOWER_IO 0x00000000
+#define MPC83xx_PCI1_UPPER_IO 0x00ffffff
+#define MPC83xx_PCI1_LOWER_MEM 0x80000000
+#define MPC83xx_PCI1_UPPER_MEM 0x9fffffff
+#define MPC83xx_PCI1_IO_BASE 0xe2000000
+#define MPC83xx_PCI1_MEM_OFFSET 0x00000000
+#define MPC83xx_PCI1_IO_SIZE 0x01000000
+
+#define MPC83xx_PCI2_LOWER_IO 0x00000000
+#define MPC83xx_PCI2_UPPER_IO 0x00ffffff
+#define MPC83xx_PCI2_LOWER_MEM 0xa0000000
+#define MPC83xx_PCI2_UPPER_MEM 0xbfffffff
+#define MPC83xx_PCI2_IO_BASE 0xe3000000
+#define MPC83xx_PCI2_MEM_OFFSET 0x00000000
+#define MPC83xx_PCI2_IO_SIZE 0x01000000
#endif /* __MACH_MPC83XX_SYS_H__ */
diff --git a/arch/ppc/syslib/ppc83xx_pci.h b/arch/ppc/syslib/ppc83xx_pci.h new file mode 100644
--- /dev/null
+++ b/arch/ppc/syslib/ppc83xx_pci.h
@@ -0,0 +1,151 @@
+/* Created by Tony Li <tony.li@freescale.com>
+ * Copyright (c) 2005 freescale semiconductor
+ *
+ * This program is free software; you can redistribute it and/or
+modify it
+ * under the terms of the GNU General Public License as published by
+the
+ * Free Software Foundation; either version 2 of the License, or (at
+your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+along
+ * with this program; if not, write to the Free Software Foundation,
+Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __PPC_SYSLIB_PPC83XX_PCI_H
+#define __PPC_SYSLIB_PPC83XX_PCI_H
+
+typedef struct immr_clk {
+ u32 spmr; /* system PLL mode Register */
+ u32 occr; /* output clock control Register */
+ u32 sccr; /* system clock control Register */
+ u8 res0[0xF4];
+} immr_clk_t;
+
+/*
+ * Sequencer
+ */
+typedef struct immr_ios {
+ u32 potar0;
+ u8 res0[4];
+ u32 pobar0;
+ u8 res1[4];
+ u32 pocmr0;
+ u8 res2[4];
+ u32 potar1;
+ u8 res3[4];
+ u32 pobar1;
+ u8 res4[4];
+ u32 pocmr1;
+ u8 res5[4];
+ u32 potar2;
+ u8 res6[4];
+ u32 pobar2;
+ u8 res7[4];
+ u32 pocmr2;
+ u8 res8[4];
+ u32 potar3;
+ u8 res9[4];
+ u32 pobar3;
+ u8 res10[4];
+ u32 pocmr3;
+ u8 res11[4];
+ u32 potar4;
+ u8 res12[4];
+ u32 pobar4;
+ u8 res13[4];
+ u32 pocmr4;
+ u8 res14[4];
+ u32 potar5;
+ u8 res15[4];
+ u32 pobar5;
+ u8 res16[4];
+ u32 pocmr5;
+ u8 res17[4];
+ u8 res18[0x60];
+ u32 pmcr;
+ u8 res19[4];
+ u32 dtcr;
+ u8 res20[4];
+} immr_ios_t;
+#define POTAR_TA_MASK 0x000fffff
+#define POBAR_BA_MASK 0x000fffff
+#define POCMR_EN 0x80000000
+#define POCMR_IO 0x40000000 /* 0--memory space 1--I/O space */
+#define POCMR_SE 0x20000000 /* streaming enable */
+#define POCMR_DST 0x10000000 /* 0--PCI1 1--PCI2 */
+#define POCMR_CM_MASK 0x000fffff
+
+/*
+ * PCI Controller Control and Status Registers */ typedef struct
+immr_pcictrl {
+ u32 esr;
+ u32 ecdr;
+ u32 eer;
+ u32 eatcr;
+ u32 eacr;
+ u32 eeacr;
+ u32 edlcr;
+ u32 edhcr;
+ u32 gcr;
+ u32 ecr;
+ u32 gsr;
+ u8 res0[12];
+ u32 pitar2;
+ u8 res1[4];
+ u32 pibar2;
+ u32 piebar2;
+ u32 piwar2;
+ u8 res2[4];
+ u32 pitar1;
+ u8 res3[4];
+ u32 pibar1;
+ u32 piebar1;
+ u32 piwar1;
+ u8 res4[4];
+ u32 pitar0;
+ u8 res5[4];
+ u32 pibar0;
+ u8 res6[4];
+ u32 piwar0;
+ u8 res7[132];
+} immr_pcictrl_t;
+#define PITAR_TA_MASK 0x000fffff
+#define PIBAR_MASK 0xffffffff
+#define PIEBAR_EBA_MASK 0x000fffff
+#define PIWAR_EN 0x80000000
+#define PIWAR_PF 0x20000000
+#define PIWAR_RTT_MASK 0x000f0000
+#define PIWAR_RTT_NO_SNOOP 0x00040000
+#define PIWAR_RTT_SNOOP 0x00050000
+#define PIWAR_WTT_MASK 0x0000f000
+#define PIWAR_WTT_NO_SNOOP 0x00004000
+#define PIWAR_WTT_SNOOP 0x00005000
+#define PIWAR_IWS_MASK 0x0000003F
+#define PIWAR_IWS_4K 0x0000000B
+#define PIWAR_IWS_8K 0x0000000C
+#define PIWAR_IWS_16K 0x0000000D
+#define PIWAR_IWS_32K 0x0000000E
+#define PIWAR_IWS_64K 0x0000000F
+#define PIWAR_IWS_128K 0x00000010
+#define PIWAR_IWS_256K 0x00000011
+#define PIWAR_IWS_512K 0x00000012
+#define PIWAR_IWS_1M 0x00000013
+#define PIWAR_IWS_2M 0x00000014
+#define PIWAR_IWS_4M 0x00000015
+#define PIWAR_IWS_8M 0x00000016
+#define PIWAR_IWS_16M 0x00000017
+#define PIWAR_IWS_32M 0x00000018
+#define PIWAR_IWS_64M 0x00000019
+#define PIWAR_IWS_128M 0x0000001A
+#define PIWAR_IWS_256M 0x0000001B
+#define PIWAR_IWS_512M 0x0000001C
+#define PIWAR_IWS_1G 0x0000001D
+#define PIWAR_IWS_2G 0x0000001E
+
+#endif /* __PPC_SYSLIB_PPC83XX_PCI_H */
diff --git a/arch/ppc/syslib/ppc83xx_setup.c b/arch/ppc/syslib/ppc83xx_setup.c
--- a/arch/ppc/syslib/ppc83xx_setup.c
+++ b/arch/ppc/syslib/ppc83xx_setup.c
@@ -11,6 +11,17 @@
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ along
+ * with this program; if not, write to the Free Software Foundation,
+ Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Added PCI support -- Tony Li <tony.li@freescale.com>
*/
#include <linux/config.h>
@@ -31,6 +42,10 @@
#include <asm/delay.h>
#include <syslib/ppc83xx_setup.h>
+#if defined(CONFIG_PCI)
+#include <asm/delay.h>
+#include <syslib/ppc83xx_pci.h>
+#endif
phys_addr_t immrbar;
@@ -162,4 +177,237 @@ mpc83xx_halt(void)
for(;;);
}
-/* PCI SUPPORT DOES NOT EXIT, MODEL after ppc85xx_setup.c */
+#if defined(CONFIG_PCI)
+void __init
+mpc83xx_setup_pci1(struct pci_controller *hose) {
+ u16 reg16;
+ volatile immr_pcictrl_t * pci_ctrl;
+ volatile immr_ios_t * ios;
+ bd_t *binfo = (bd_t *) __res;
+
+ pci_ctrl = ioremap(binfo->bi_immr_base + 0x8500, sizeof(immr_pcictrl_t));
+ ios = ioremap(binfo->bi_immr_base + 0x8400, sizeof(immr_ios_t));
+
+ /*
+ * Configure PCI Outbound Translation Windows
+ */
+ ios->potar0 = (MPC83xx_PCI1_LOWER_MEM >> 12) & POTAR_TA_MASK;
+ ios->pobar0 = (MPC83xx_PCI1_LOWER_MEM >> 12) & POBAR_BA_MASK;
+ ios->pocmr0 = POCMR_EN |
+ (((0xffffffff - (MPC83xx_PCI1_UPPER_MEM -
+ MPC83xx_PCI1_LOWER_MEM)) >> 12) & POCMR_CM_MASK);
+
+ /* mapped to PCI1 IO space */
+ ios->potar1 = (MPC83xx_PCI1_LOWER_IO >> 12) & POTAR_TA_MASK;
+ ios->pobar1 = (MPC83xx_PCI1_IO_BASE >> 12) & POBAR_BA_MASK;
+ ios->pocmr1 = POCMR_EN | POCMR_IO |
+ (((0xffffffff - (MPC83xx_PCI1_UPPER_IO -
+ MPC83xx_PCI1_LOWER_IO)) >> 12) & POCMR_CM_MASK);
+
+ /*
+ * Configure PCI Inbound Translation Windows
+ */
+ pci_ctrl->pitar1 = 0x0;
+ pci_ctrl->pibar1 = 0x0;
+ pci_ctrl->piebar1 = 0x0;
+ pci_ctrl->piwar1 = PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP |
+PIWAR_WTT_SNOOP | PIWAR_IWS_2G;
+
+ /*
+ * Release PCI RST signal
+ */
+ pci_ctrl->gcr = 0;
+ udelay(2000);
+ pci_ctrl->gcr = 1;
+ udelay(2000);
+
+ reg16 = 0xff;
+ early_read_config_word(hose, hose->first_busno, 0, PCI_COMMAND, ®16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ early_write_config_word(hose, hose->first_busno, 0, PCI_COMMAND,
+reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ early_write_config_word(hose, hose->first_busno, 0, PCI_STATUS, 0xffff);
+ early_write_config_byte(hose, hose->first_busno, 0, PCI_LATENCY_TIMER,
+0x80);
+
+ iounmap(pci_ctrl);
+ iounmap(ios);
+}
+
+void __init
+mpc83xx_setup_pci2(struct pci_controller *hose) {
+ u16 reg16;
+ volatile immr_pcictrl_t * pci_ctrl;
+ volatile immr_ios_t * ios;
+ bd_t *binfo = (bd_t *) __res;
+
+ pci_ctrl = ioremap(binfo->bi_immr_base + 0x8600, sizeof(immr_pcictrl_t));
+ ios = ioremap(binfo->bi_immr_base + 0x8400, sizeof(immr_ios_t));
+
+ /*
+ * Configure PCI Outbound Translation Windows
+ */
+ ios->potar3 = (MPC83xx_PCI2_LOWER_MEM >> 12) & POTAR_TA_MASK;
+ ios->pobar3 = (MPC83xx_PCI2_LOWER_MEM >> 12) & POBAR_BA_MASK;
+ ios->pocmr3 = POCMR_EN | POCMR_DST |
+ (((0xffffffff - (MPC83xx_PCI2_UPPER_MEM -
+ MPC83xx_PCI2_LOWER_MEM)) >> 12) & POCMR_CM_MASK);
+
+ /* mapped to PCI2 IO space */
+ ios->potar4 = (MPC83xx_PCI2_LOWER_IO >> 12) & POTAR_TA_MASK;
+ ios->pobar4 = (MPC83xx_PCI2_IO_BASE >> 12) & POBAR_BA_MASK;
+ ios->pocmr4 = POCMR_EN | POCMR_DST | POCMR_IO |
+ (((0xffffffff - (MPC83xx_PCI2_UPPER_IO -
+ MPC83xx_PCI2_LOWER_IO)) >> 12) & POCMR_CM_MASK);
+
+ /*
+ * Configure PCI Inbound Translation Windows
+ */
+ pci_ctrl->pitar1 = 0x0;
+ pci_ctrl->pibar1 = 0x0;
+ pci_ctrl->piebar1 = 0x0;
+ pci_ctrl->piwar1 = PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP |
+PIWAR_WTT_SNOOP | PIWAR_IWS_2G;
+
+ /*
+ * Release PCI RST signal
+ */
+ pci_ctrl->gcr = 0;
+ udelay(2000);
+ pci_ctrl->gcr = 1;
+ udelay(2000);
+
+ reg16 = 0xff;
+ early_read_config_word(hose, hose->first_busno, 0, PCI_COMMAND, ®16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ early_write_config_word(hose, hose->first_busno, 0, PCI_COMMAND,
+reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ early_write_config_word(hose, hose->first_busno, 0, PCI_STATUS, 0xffff);
+ early_write_config_byte(hose, hose->first_busno, 0, PCI_LATENCY_TIMER,
+0x80);
+
+ iounmap(pci_ctrl);
+ iounmap(ios);
+}
+
+/*
+ * PCI buses can be enabled only if SYS board combinates with PIB
+ * (Platform IO Board) board which provide 3 PCI slots. There is 2 PCI
+buses
+ * and 3 PCI slots, so people must configure the routes between them
+before
+ * enable PCI bus. This routes are under the control of PCA9555PW
+device which
+ * can be accessed via I2C bus 2 and are configured by firmware. Refer
+to
+ * Freescale to get more information about firmware configuration.
+ */
+
+extern int mpc83xx_exclude_device(u_char bus, u_char devfn); extern int
+mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel,
+ unsigned char pin);
+void __init
+mpc83xx_setup_hose(void)
+{
+ u32 val32;
+ volatile immr_clk_t * clk;
+ struct pci_controller * hose1;
+#ifdef CONFIG_MPC83xx_PCI2
+ struct pci_controller * hose2;
+#endif
+ bd_t * binfo = (bd_t *)__res;
+
+ clk = ioremap(binfo->bi_immr_base + 0xA00,
+ sizeof(immr_clk_t));
+
+ /*
+ * Configure PCI controller and PCI_CLK_OUTPUT both in 66M mode
+ */
+ val32 = clk->occr;
+ udelay(2000);
+ clk->occr = 0xff000000;
+ udelay(2000);
+
+ iounmap(clk);
+
+ hose1 = pcibios_alloc_controller();
+ if(!hose1)
+ return;
+
+ ppc_md.pci_swizzle = common_swizzle;
+ ppc_md.pci_map_irq = mpc83xx_map_irq;
+
+ hose1->bus_offset = 0;
+ hose1->first_busno = 0;
+ hose1->last_busno = 0xff;
+
+ setup_indirect_pci(hose1, binfo->bi_immr_base + PCI1_CFG_ADDR_OFFSET,
+ binfo->bi_immr_base + PCI1_CFG_DATA_OFFSET);
+ hose1->set_cfg_type = 1;
+
+ mpc83xx_setup_pci1(hose1);
+
+ hose1->pci_mem_offset = MPC83xx_PCI1_MEM_OFFSET;
+ hose1->mem_space.start = MPC83xx_PCI1_LOWER_MEM;
+ hose1->mem_space.end = MPC83xx_PCI1_UPPER_MEM;
+
+ hose1->io_base_phys = MPC83xx_PCI1_IO_BASE;
+ hose1->io_space.start = MPC83xx_PCI1_LOWER_IO;
+ hose1->io_space.end = MPC83xx_PCI1_UPPER_IO; #ifdef
+CONFIG_MPC83xx_PCI2
+ isa_io_base = (unsigned long)ioremap(MPC83xx_PCI1_IO_BASE,
+ MPC83xx_PCI1_IO_SIZE + MPC83xx_PCI2_IO_SIZE); #else
+ isa_io_base = (unsigned long)ioremap(MPC83xx_PCI1_IO_BASE,
+ MPC83xx_PCI1_IO_SIZE);
+#endif /* CONFIG_MPC83xx_PCI2 */
+ hose1->io_base_virt = (void *)isa_io_base;
+ /* setup resources */
+ pci_init_resource(&hose1->io_resource,
+ MPC83xx_PCI1_LOWER_IO,
+ MPC83xx_PCI1_UPPER_IO,
+ IORESOURCE_IO, "PCI host bridge 1");
+ pci_init_resource(&hose1->mem_resources[0],
+ MPC83xx_PCI1_LOWER_MEM,
+ MPC83xx_PCI1_UPPER_MEM,
+ IORESOURCE_MEM, "PCI host bridge 1");
+
+ ppc_md.pci_exclude_device = mpc83xx_exclude_device;
+ hose1->last_busno = pciauto_bus_scan(hose1, hose1->first_busno);
+
+#ifdef CONFIG_MPC83xx_PCI2
+ hose2 = pcibios_alloc_controller();
+ if(!hose2)
+ return;
+
+ hose2->bus_offset = hose1->last_busno + 1;
+ hose2->first_busno = hose1->last_busno + 1;
+ hose2->last_busno = 0xff;
+ setup_indirect_pci(hose2, binfo->bi_immr_base + PCI2_CFG_ADDR_OFFSET,
+ binfo->bi_immr_base + PCI2_CFG_DATA_OFFSET);
+ hose2->set_cfg_type = 1;
+
+ mpc83xx_setup_pci2(hose2);
+
+ hose2->pci_mem_offset = MPC83xx_PCI2_MEM_OFFSET;
+ hose2->mem_space.start = MPC83xx_PCI2_LOWER_MEM;
+ hose2->mem_space.end = MPC83xx_PCI2_UPPER_MEM;
+
+ hose2->io_base_phys = MPC83xx_PCI2_IO_BASE;
+ hose2->io_space.start = MPC83xx_PCI2_LOWER_IO;
+ hose2->io_space.end = MPC83xx_PCI2_UPPER_IO;
+ hose2->io_base_virt = (void *)(isa_io_base + MPC83xx_PCI1_IO_SIZE);
+ /* setup resources */
+ pci_init_resource(&hose2->io_resource,
+ MPC83xx_PCI2_LOWER_IO,
+ MPC83xx_PCI2_UPPER_IO,
+ IORESOURCE_IO, "PCI host bridge 2");
+ pci_init_resource(&hose2->mem_resources[0],
+ MPC83xx_PCI2_LOWER_MEM,
+ MPC83xx_PCI2_UPPER_MEM,
+ IORESOURCE_MEM, "PCI host bridge 2");
+
+ hose2->last_busno = pciauto_bus_scan(hose2, hose2->first_busno);
+#endif /* CONFIG_MPC83xx_PCI2 */ } #endif /*CONFIG_PCI*/
diff --git a/arch/ppc/syslib/ppc83xx_setup.h b/arch/ppc/syslib/ppc83xx_setup.h
--- a/arch/ppc/syslib/ppc83xx_setup.h
+++ b/arch/ppc/syslib/ppc83xx_setup.h
@@ -12,6 +12,14 @@
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ along
+ * with this program; if not, write to the Free Software Foundation,
+ Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __PPC_SYSLIB_PPC83XX_SETUP_H
@@ -19,7 +27,6 @@
#include <linux/config.h>
#include <linux/init.h>
-#include <asm/ppcboot.h>
extern unsigned long mpc83xx_find_end_of_memory(void) __init; extern long mpc83xx_time_init(void) __init; @@ -31,13 +38,11 @@ extern void mpc83xx_halt(void); extern void mpc83xx_setup_hose(void) __init;
/* PCI config */
-#if 0
-#define PCI1_CFG_ADDR_OFFSET (FIXME)
-#define PCI1_CFG_DATA_OFFSET (FIXME)
+#define PCI1_CFG_ADDR_OFFSET (0x8300)
+#define PCI1_CFG_DATA_OFFSET (0x8304)
-#define PCI2_CFG_ADDR_OFFSET (FIXME)
-#define PCI2_CFG_DATA_OFFSET (FIXME)
-#endif
+#define PCI2_CFG_ADDR_OFFSET (0x8380)
+#define PCI2_CFG_DATA_OFFSET (0x8384)
/* Serial Config */
#ifdef CONFIG_SERIAL_MANY_PORTS
^ permalink raw reply
* [PATCH] ppc32 :Added PCI support for MPC83xx
From: Li Tony-r64360 @ 2005-08-30 8:55 UTC (permalink / raw)
To: 'linuxppc-embedded@ozlabs.org'
Cc: Li Tony-r64360, 'linux-kernel@vger.kernel.org',
Chu hanjin-r52514
[-- Attachment #1: Type: text/plain, Size: 23435 bytes --]
MPC83xx cpu has two PCI buses. This patch adds support for them.
After system boot. The code initializes PCI inbound/outbound
windows, allocate and register PCI memory/io space. Be aware
that this patch depand on the firmware.
Signed-off-by: Tony Li <tony.li@freescale.com <mailto:tony.li@freescale.com> >
---
author Tony Li <tony.li@freescale.com <mailto:tony.li@freescale.com> > Tue, 30 Aug 2005
committer Tony Li <tony.li@freescale.com <mailto:tony.li@freescale.com> > Tue, 30 Aug 2005
diff -urN -X dontdiff linux-2.6.13-rc6/arch/ppc/Kconfig linux-2.6.13-rc6-pci/arch/ppc/Kconfig
--- linux-2.6.13-rc6/arch/ppc/Kconfig 2005-08-09 18:00:47.000000000 +0800
+++ linux-2.6.13-rc6-pci/arch/ppc/Kconfig 2005-08-19 18:17:27.000000000 +0800
@@ -712,6 +712,11 @@
bool "Freescale MPC834x SYS"
help
This option enables support for the MPC 834x SYS evaluation board.
+ Be aware that PCI buses can only function when SYS board is plugged on
+ PIB (Platform IO Board) board from Freescale which provide 3 PCI slots.
+ Just like PC,the board level initalization is bootloader`s responsiblilty.
+ The PCI deponds on bootloader configurate board corretly. Refer to Freescale
+ to get more information about this.
endchoice
@@ -1191,6 +1196,10 @@
bool
default PCI
+config MPC834x_PCI2
+ bool
+ default y if PCI && MPC834x_SYS
+
config PCI_QSPAN
bool "QSpan PCI"
depends on !4xx && !CPM2 && 8xx
diff -urN -X dontdiff linux-2.6.13-rc6/arch/ppc/platforms/83xx/mpc834x_sys.c linux-2.6.13-rc6-pci/arch/ppc/platforms/83xx/mpc834x_sys.c
--- linux-2.6.13-rc6/arch/ppc/platforms/83xx/mpc834x_sys.c 2005-08-09 18:00:47.000000000 +0800
+++ linux-2.6.13-rc6-pci/arch/ppc/platforms/83xx/mpc834x_sys.c 2005-08-30 16:38:52.000000000 +0800
@@ -62,9 +62,28 @@
unsigned char __res[sizeof (bd_t)];
#ifdef CONFIG_PCI
-#error "PCI is not supported"
-/* NEED mpc83xx_map_irq & mpc83xx_exclude_device
- see platforms/85xx/mpc85xx_ads_common.c */
+int
+mpc83xx_ads_map_irq(struct pci_dev *dev,unsigned char idsel,unsigned char pin)
+{
+ char pci_irq_table[][4]=
+ /*
+ * PCI IDSEL&INTPIN -> INTLINE
+ * INTA INTB INTC INTD
+ */
+ {
+ {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x11 */
+ {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x12 */
+ {PIRQD, PIRQA, PIRQB, PIRQC} /* idsel 0x13 */
+ };
+ /* MPC8349 MDS board specific */
+ const long min_idsel=0x11,max_idsel=0x13,irqs_per_slot=4;
+ return PCI_IRQ_TABLE_LOOKUP;
+}
+int
+mpc83xx_ads_exclude_device(u_char bus, u_char devfn)
+{
+ return PCIBIOS_SUCCESSFUL;
+}
#endif /* CONFIG_PCI */
/* ************************************************************************
@@ -88,7 +107,7 @@
#ifdef CONFIG_PCI
/* setup PCI host bridges */
- mpc83xx_sys_setup_hose();
+ mpc83xx_setup_hose();
#endif
mpc83xx_early_serial_map();
@@ -175,10 +194,10 @@
IRQ_SENSE_LEVEL, /* EXT 1 */
IRQ_SENSE_LEVEL, /* EXT 2 */
0, /* EXT 3 */
- 0, /* EXT 4 */
- 0, /* EXT 5 */
- 0, /* EXT 6 */
- 0, /* EXT 7 */
+ IRQ_SENSE_LEVEL, /* EXT 4 */
+ IRQ_SENSE_LEVEL, /* EXT 5 */
+ IRQ_SENSE_LEVEL, /* EXT 6 */
+ IRQ_SENSE_LEVEL, /* EXT 7 */
};
ipic_init(binfo->bi_immr_base + 0x00700, 0, MPC83xx_IPIC_IRQ_OFFSET, senses, 8);
diff -urN -X dontdiff linux-2.6.13-rc6/arch/ppc/platforms/83xx/mpc834x_sys.h linux-2.6.13-rc6-pci/arch/ppc/platforms/83xx/mpc834x_sys.h
--- linux-2.6.13-rc6/arch/ppc/platforms/83xx/mpc834x_sys.h 2005-06-18 03:48:29.000000000 +0800
+++ linux-2.6.13-rc6-pci/arch/ppc/platforms/83xx/mpc834x_sys.h 2005-08-23 10:00:08.000000000 +0800
@@ -26,7 +26,7 @@
#define VIRT_IMMRBAR ((uint)0xfe000000)
#define BCSR_PHYS_ADDR ((uint)0xf8000000)
-#define BCSR_SIZE ((uint)(32 * 1024))
+#define BCSR_SIZE ((uint)(128 * 1024))
#define BCSR_MISC_REG2_OFF 0x07
#define BCSR_MISC_REG2_PORESET 0x01
@@ -35,22 +35,34 @@
#define BCSR_MISC_REG3_CNFLOCK 0x80
#ifdef CONFIG_PCI
-/* PCI interrupt controller */
-#define PIRQA MPC83xx_IRQ_IRQ4
-#define PIRQB MPC83xx_IRQ_IRQ5
-#define PIRQC MPC83xx_IRQ_IRQ6
-#define PIRQD MPC83xx_IRQ_IRQ7
-
-#define MPC834x_SYS_PCI1_LOWER_IO 0x00000000
-#define MPC834x_SYS_PCI1_UPPER_IO 0x00ffffff
-#define MPC834x_SYS_PCI1_LOWER_MEM 0x80000000
-#define MPC834x_SYS_PCI1_UPPER_MEM 0x9fffffff
+#define PCI1_CFG_ADDR_OFFSET (0x8300)
+#define PCI1_CFG_DATA_OFFSET (0x8304)
-#define MPC834x_SYS_PCI1_IO_BASE 0xe2000000
-#define MPC834x_SYS_PCI1_MEM_OFFSET 0x00000000
+#define PCI2_CFG_ADDR_OFFSET (0x8380)
+#define PCI2_CFG_DATA_OFFSET (0x8384)
+
+#define PIRQA MPC83xx_IRQ_EXT4
+#define PIRQB MPC83xx_IRQ_EXT5
+#define PIRQC MPC83xx_IRQ_EXT6
+#define PIRQD MPC83xx_IRQ_EXT7
+
+#define MPC83xx_PCI1_LOWER_IO 0x00000000
+#define MPC83xx_PCI1_UPPER_IO 0x00ffffff
+#define MPC83xx_PCI1_LOWER_MEM 0x80000000
+#define MPC83xx_PCI1_UPPER_MEM 0x9fffffff
+#define MPC83xx_PCI1_IO_BASE 0xe2000000
+#define MPC83xx_PCI1_MEM_OFFSET 0x00000000
+#define MPC83xx_PCI1_IO_SIZE 0x01000000
+
+#define MPC83xx_PCI2_LOWER_IO 0x00000000
+#define MPC83xx_PCI2_UPPER_IO 0x00ffffff
+#define MPC83xx_PCI2_LOWER_MEM 0xa0000000
+#define MPC83xx_PCI2_UPPER_MEM 0xbfffffff
+#define MPC83xx_PCI2_IO_BASE 0xe3000000
+#define MPC83xx_PCI2_MEM_OFFSET 0x00000000
+#define MPC83xx_PCI2_IO_SIZE 0x01000000
-#define MPC834x_SYS_PCI1_IO_SIZE 0x01000000
#endif /* CONFIG_PCI */
#endif /* __MACH_MPC83XX_SYS_H__ */
diff -urN -X dontdiff linux-2.6.13-rc6/arch/ppc/syslib/ppc834x_pci.h linux-2.6.13-rc6-pci/arch/ppc/syslib/ppc834x_pci.h
--- linux-2.6.13-rc6/arch/ppc/syslib/ppc834x_pci.h 1970-01-01 08:30:00.000000000 +0830
+++ linux-2.6.13-rc6-pci/arch/ppc/syslib/ppc834x_pci.h 2005-08-19 18:30:11.000000000 +0800
@@ -0,0 +1,161 @@
+/* Created by Tony Li <tony.li@freescale.com <mailto:tony.li@freescale.com> > 2005.6
+ * Copyright (c) 2005 freescale semiconductor
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MPC834X_PCI_H__
+#define __MPC834X_PCI_H__
+
+typedef struct immr_clk {
+ u32 spmr; /* system PLL mode Register */
+ u32 occr; /* output clock control Register */
+ u32 sccr; /* system clock control Register */
+ u8 res0[0xF4];
+} immr_clk_t;
+
+/*
+ * PCI Software Configuration Registers
+ */
+typedef struct immr_pciconf {
+ u32 config_address;
+ u32 config_data;
+ u32 int_ack;
+ u8 res[116];
+} immr_pciconf_t;
+
+/*
+ * Sequencer
+ */
+typedef struct immr_ios {
+ u32 potar0;
+ u8 res0[4];
+ u32 pobar0;
+ u8 res1[4];
+ u32 pocmr0;
+ u8 res2[4];
+ u32 potar1;
+ u8 res3[4];
+ u32 pobar1;
+ u8 res4[4];
+ u32 pocmr1;
+ u8 res5[4];
+ u32 potar2;
+ u8 res6[4];
+ u32 pobar2;
+ u8 res7[4];
+ u32 pocmr2;
+ u8 res8[4];
+ u32 potar3;
+ u8 res9[4];
+ u32 pobar3;
+ u8 res10[4];
+ u32 pocmr3;
+ u8 res11[4];
+ u32 potar4;
+ u8 res12[4];
+ u32 pobar4;
+ u8 res13[4];
+ u32 pocmr4;
+ u8 res14[4];
+ u32 potar5;
+ u8 res15[4];
+ u32 pobar5;
+ u8 res16[4];
+ u32 pocmr5;
+ u8 res17[4];
+ u8 res18[0x60];
+ u32 pmcr;
+ u8 res19[4];
+ u32 dtcr;
+ u8 res20[4];
+} immr_ios_t;
+#define POTAR_TA_MASK 0x000fffff
+#define POBAR_BA_MASK 0x000fffff
+#define POCMR_EN 0x80000000
+#define POCMR_IO 0x40000000 /* 0--memory space 1--I/O space */
+#define POCMR_SE 0x20000000 /* streaming enable */
+#define POCMR_DST 0x10000000 /* 0--PCI1 1--PCI2 */
+#define POCMR_CM_MASK 0x000fffff
+
+/*
+ * PCI Controller Control and Status Registers
+ */
+typedef struct immr_pcictrl {
+ u32 esr;
+ u32 ecdr;
+ u32 eer;
+ u32 eatcr;
+ u32 eacr;
+ u32 eeacr;
+ u32 edlcr;
+ u32 edhcr;
+ u32 gcr;
+ u32 ecr;
+ u32 gsr;
+ u8 res0[12];
+ u32 pitar2;
+ u8 res1[4];
+ u32 pibar2;
+ u32 piebar2;
+ u32 piwar2;
+ u8 res2[4];
+ u32 pitar1;
+ u8 res3[4];
+ u32 pibar1;
+ u32 piebar1;
+ u32 piwar1;
+ u8 res4[4];
+ u32 pitar0;
+ u8 res5[4];
+ u32 pibar0;
+ u8 res6[4];
+ u32 piwar0;
+ u8 res7[132];
+} immr_pcictrl_t;
+#define PITAR_TA_MASK 0x000fffff
+#define PIBAR_MASK 0xffffffff
+#define PIEBAR_EBA_MASK 0x000fffff
+#define PIWAR_EN 0x80000000
+#define PIWAR_PF 0x20000000
+#define PIWAR_RTT_MASK 0x000f0000
+#define PIWAR_RTT_NO_SNOOP 0x00040000
+#define PIWAR_RTT_SNOOP 0x00050000
+#define PIWAR_WTT_MASK 0x0000f000
+#define PIWAR_WTT_NO_SNOOP 0x00004000
+#define PIWAR_WTT_SNOOP 0x00005000
+#define PIWAR_IWS_MASK 0x0000003F
+#define PIWAR_IWS_4K 0x0000000B
+#define PIWAR_IWS_8K 0x0000000C
+#define PIWAR_IWS_16K 0x0000000D
+#define PIWAR_IWS_32K 0x0000000E
+#define PIWAR_IWS_64K 0x0000000F
+#define PIWAR_IWS_128K 0x00000010
+#define PIWAR_IWS_256K 0x00000011
+#define PIWAR_IWS_512K 0x00000012
+#define PIWAR_IWS_1M 0x00000013
+#define PIWAR_IWS_2M 0x00000014
+#define PIWAR_IWS_4M 0x00000015
+#define PIWAR_IWS_8M 0x00000016
+#define PIWAR_IWS_16M 0x00000017
+#define PIWAR_IWS_32M 0x00000018
+#define PIWAR_IWS_64M 0x00000019
+#define PIWAR_IWS_128M 0x0000001A
+#define PIWAR_IWS_256M 0x0000001B
+#define PIWAR_IWS_512M 0x0000001C
+#define PIWAR_IWS_1G 0x0000001D
+#define PIWAR_IWS_2G 0x0000001E
+
+#endif /*__MPC834X_PCI_H__*/
diff -urN -X dontdiff linux-2.6.13-rc6/arch/ppc/syslib/ppc83xx_setup.c linux-2.6.13-rc6-pci/arch/ppc/syslib/ppc83xx_setup.c
--- linux-2.6.13-rc6/arch/ppc/syslib/ppc83xx_setup.c 2005-08-09 18:00:47.000000000 +0800
+++ linux-2.6.13-rc6-pci/arch/ppc/syslib/ppc83xx_setup.c 2005-08-23 10:18:04.000000000 +0800
@@ -11,6 +11,20 @@
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * July 2005, Tony Li<tony.li@freescale.com <mailto:tony.li@freescale.com> >
+ * Added PCI support
+ * PCI can be enabled only if MPC834x SYS board combined with PIB(Platform
+ * IO Board) board in which three physical PCI slots locate.
*/
#include <linux/config.h>
@@ -19,7 +33,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/serial.h>
-#include <linux/tty.h> /* for linux/serial_core.h */
+#include <linux/tty.h> /* for linux/serial_core.h */
#include <linux/serial_core.h>
#include <linux/serial_8250.h>
@@ -31,27 +45,29 @@
#include <asm/delay.h>
#include <syslib/ppc83xx_setup.h>
+#if defined(CONFIG_PCI)
+#include <asm/delay.h>
+#include <syslib/ppc834x_pci.h>
+#endif
phys_addr_t immrbar;
/* Return the amount of memory */
-unsigned long __init
-mpc83xx_find_end_of_memory(void)
+unsigned long __init mpc83xx_find_end_of_memory(void)
{
- bd_t *binfo;
+ bd_t *binfo;
- binfo = (bd_t *) __res;
+ binfo = (bd_t *) __res;
- return binfo->bi_memsize;
+ return binfo->bi_memsize;
}
-long __init
-mpc83xx_time_init(void)
+long __init mpc83xx_time_init(void)
{
#define SPCR_OFFS 0x00000110
#define SPCR_TBEN 0x00400000
- bd_t *binfo = (bd_t *)__res;
+ bd_t *binfo = (bd_t *) __res;
u32 *spcr = ioremap(binfo->bi_immr_base + SPCR_OFFS, 4);
*spcr |= SPCR_TBEN;
@@ -62,11 +78,10 @@
}
/* The decrementer counts at the system (internal) clock freq divided by 4 */
-void __init
-mpc83xx_calibrate_decr(void)
+void __init mpc83xx_calibrate_decr(void)
{
- bd_t *binfo = (bd_t *) __res;
- unsigned int freq, divisor;
+ bd_t *binfo = (bd_t *) __res;
+ unsigned int freq, divisor;
freq = binfo->bi_busfreq;
divisor = 4;
@@ -75,15 +90,14 @@
}
#ifdef CONFIG_SERIAL_8250
-void __init
-mpc83xx_early_serial_map(void)
+void __init mpc83xx_early_serial_map(void)
{
#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
struct uart_port serial_req;
#endif
struct plat_serial8250_port *pdata;
bd_t *binfo = (bd_t *) __res;
- pdata = (struct plat_serial8250_port *) ppc_sys_get_pdata(MPC83xx_DUART);
+ pdata = (struct plat_serial8250_port *)ppc_sys_get_pdata(MPC83xx_DUART);
/* Setup serial port access */
pdata[0].uartclk = binfo->bi_busfreq;
@@ -91,7 +105,7 @@
pdata[0].membase = ioremap(pdata[0].mapbase, 0x100);
#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
- memset(&serial_req, 0, sizeof (serial_req));
+ memset(&serial_req, 0, sizeof(serial_req));
serial_req.iotype = SERIAL_IO_MEM;
serial_req.mapbase = pdata[0].mapbase;
serial_req.membase = pdata[0].membase;
@@ -114,8 +128,7 @@
}
#endif
-void
-mpc83xx_restart(char *cmd)
+void mpc83xx_restart(char *cmd)
{
volatile unsigned char __iomem *reg;
unsigned char tmp;
@@ -129,7 +142,7 @@
* Otherwise the reset asserts but doesn't clear.
*/
tmp = in_8(reg + BCSR_MISC_REG3_OFF);
- tmp |= BCSR_MISC_REG3_CNFLOCK; /* low true, high false */
+ tmp |= BCSR_MISC_REG3_CNFLOCK; /* low true, high false */
out_8(reg + BCSR_MISC_REG3_OFF, tmp);
/*
@@ -145,21 +158,252 @@
tmp |= BCSR_MISC_REG2_PORESET;
out_8(reg + BCSR_MISC_REG2_OFF, tmp);
- for(;;);
+ for (;;) ;
}
-void
-mpc83xx_power_off(void)
+void mpc83xx_power_off(void)
{
local_irq_disable();
- for(;;);
+ for (;;) ;
}
-void
-mpc83xx_halt(void)
+void mpc83xx_halt(void)
{
local_irq_disable();
- for(;;);
+ for (;;) ;
+}
+
+#if defined(CONFIG_PCI)
+void __init mpc83xx_setup_pci1(struct pci_controller *hose)
+{
+ unsigned short reg16;
+ volatile immr_pcictrl_t *pci_ctrl;
+ volatile immr_ios_t *ios;
+ bd_t *binfo = (bd_t *) __res;
+
+ pci_ctrl = ioremap(binfo->bi_immr_base + 0x8500,
+ sizeof(immr_pcictrl_t));
+ ios = ioremap(binfo->bi_immr_base + 0x8400, sizeof(immr_ios_t));
+
+ /*
+ * Configure PCI Outbound Translation Windows
+ */
+ ios->potar0 = (MPC83xx_PCI1_LOWER_MEM >> 12) & POTAR_TA_MASK;
+ ios->pobar0 = (MPC83xx_PCI1_LOWER_MEM >> 12) & POBAR_BA_MASK;
+ ios->pocmr0 = POCMR_EN |
+ (((~0UL -
+ (MPC83xx_PCI1_UPPER_MEM -
+ MPC83xx_PCI1_LOWER_MEM)) >> 12) & POCMR_CM_MASK);
+
+ /* mapped to PCI1 IO space 0x0 to local 0xe2000000 */
+ ios->potar1 = (MPC83xx_PCI1_LOWER_IO >> 12) & POTAR_TA_MASK;
+ ios->pobar1 = (MPC83xx_PCI1_IO_BASE >> 12) & POBAR_BA_MASK;
+ ios->pocmr1 = POCMR_EN | POCMR_IO |
+ (((~0UL -
+ (MPC83xx_PCI1_UPPER_IO -
+ MPC83xx_PCI1_LOWER_IO)) >> 12) & POCMR_CM_MASK);
+
+ /*
+ * Configure PCI Inbound Translation Windows
+ */
+ pci_ctrl->pitar1 = 0x0;
+ pci_ctrl->pibar1 = 0x0;
+ pci_ctrl->piebar1 = 0x0;
+ pci_ctrl->piwar1 =
+ PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP |
+ PIWAR_IWS_2G;
+
+ /*
+ * Release PCI RST signal
+ */
+ pci_ctrl->gcr = 0;
+ udelay(2000);
+ pci_ctrl->gcr = 1;
+ udelay(2000);
+
+ reg16 = 0xff;
+ early_read_config_word(hose, hose->first_busno, 0, PCI_COMMAND, ®16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ early_write_config_word(hose, hose->first_busno, 0, PCI_COMMAND, reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ early_write_config_word(hose, hose->first_busno, 0, PCI_STATUS, 0xffff);
+ early_write_config_byte(hose, hose->first_busno, 0, PCI_LATENCY_TIMER,
+ 0x80);
}
-/* PCI SUPPORT DOES NOT EXIT, MODEL after ppc85xx_setup.c */
+void __init mpc834x_ads_setup_pci2(struct pci_controller *hose)
+{
+ unsigned short reg16;
+ volatile immr_pcictrl_t *pci_ctrl;
+ volatile immr_ios_t *ios;
+ bd_t *binfo = (bd_t *) __res;
+
+ pci_ctrl = ioremap(binfo->bi_immr_base + 0x8600,
+ sizeof(immr_pcictrl_t));
+ ios = ioremap(binfo->bi_immr_base + 0x8400, sizeof(immr_ios_t));
+
+ /*
+ * Configure PCI Outbound Translation Windows
+ */
+ ios->potar3 = (MPC83xx_PCI2_LOWER_MEM >> 12) & POTAR_TA_MASK;
+ ios->pobar3 = (MPC83xx_PCI2_LOWER_MEM >> 12) & POBAR_BA_MASK;
+ ios->pocmr3 = POCMR_EN | POCMR_DST |
+ (((~0UL -
+ (MPC83xx_PCI2_UPPER_MEM -
+ MPC83xx_PCI2_LOWER_MEM)) >> 12) & POCMR_CM_MASK);
+
+ /* mapped to PCI2 IO space 0x0 to local 0xe3000000 */
+ ios->potar4 = (MPC83xx_PCI2_LOWER_IO >> 12) & POTAR_TA_MASK;
+ ios->pobar4 = (MPC83xx_PCI2_IO_BASE >> 12) & POBAR_BA_MASK;
+ ios->pocmr4 = POCMR_EN | POCMR_DST | POCMR_IO |
+ (((~0UL -
+ (MPC83xx_PCI2_UPPER_IO -
+ MPC83xx_PCI2_LOWER_IO)) >> 12) & POCMR_CM_MASK);
+
+ /*
+ * Configure PCI Inbound Translation Windows
+ */
+ pci_ctrl->pitar1 = 0x0;
+ pci_ctrl->pibar1 = 0x0;
+ pci_ctrl->piebar1 = 0x0;
+ pci_ctrl->piwar1 =
+ PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP |
+ PIWAR_IWS_2G;
+
+ /*
+ * Release PCI RST signal
+ */
+ pci_ctrl->gcr = 0;
+ udelay(2000);
+ pci_ctrl->gcr = 1;
+ udelay(2000);
+
+ reg16 = 0xff;
+ early_read_config_word(hose, hose->first_busno, 0, PCI_COMMAND, ®16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ early_write_config_word(hose, hose->first_busno, 0, PCI_COMMAND, reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ early_write_config_word(hose, hose->first_busno, 0, PCI_STATUS, 0xffff);
+ early_write_config_byte(hose, hose->first_busno, 0, PCI_LATENCY_TIMER,
+ 0x80);
+}
+
+extern int mpc83xx_ads_map_irq(struct pci_dev *dev, unsigned char idsel,
+ unsigned char pin);
+extern int mpc83xx_ads_exclude_device(u_char bus, u_char devfn);
+
+/*
+ * PCI buses can be enabled only if SYS board combinates with PIB(Platform IO Board) board
+ * which provide 3 PCI slots. There is 2 PCI buses and 3 PCI slots,so people must configure
+ * the routes between them before enable PCI bus. This routes are under the control of PCA9555PW
+ * device which can be accessed via I2C bus 2 and are configured by firmware. Refer to Freescale to
+ * get more information about firmware configuration.
+ */
+void __init mpc83xx_setup_hose(void)
+{
+ unsigned long val32;
+ volatile immr_clk_t *clk;
+ volatile struct pci_controller *hose1;
+#ifdef CONFIG_MPC834x_PCI2
+ volatile struct pci_controller *hose2;
+#endif
+ volatile bd_t *binfo = (bd_t *) __res;
+
+ clk = ioremap(binfo->bi_immr_base + 0xA00, sizeof(immr_clk_t));
+
+ /*
+ * Configure PCI controller and PCI_CLK_OUTPUT both in 66M mode
+ */
+ val32 = clk->occr;
+ udelay(2000);
+ clk->occr = 0xff000000;
+ udelay(2000);
+
+ hose1 = pcibios_alloc_controller();
+ if (!hose1)
+ return;
+
+ ppc_md.pci_swizzle = common_swizzle;
+ ppc_md.pci_map_irq = mpc83xx_ads_map_irq;
+
+ hose1->bus_offset = 0;
+ hose1->first_busno = 0;
+ hose1->last_busno = 0xff;
+
+ setup_indirect_pci(hose1, binfo->bi_immr_base + PCI1_CFG_ADDR_OFFSET,
+ binfo->bi_immr_base + PCI1_CFG_DATA_OFFSET);
+ hose1->set_cfg_type = 1;
+
+ mpc83xx_setup_pci1(hose1);
+
+ hose1->pci_mem_offset = MPC83xx_PCI1_MEM_OFFSET;
+ hose1->mem_space.start = MPC83xx_PCI1_LOWER_MEM;
+ hose1->mem_space.end = MPC83xx_PCI1_UPPER_MEM;
+
+ hose1->io_base_phys = MPC83xx_PCI1_IO_BASE;
+ hose1->io_space.start = MPC83xx_PCI1_LOWER_IO;
+ hose1->io_space.end = MPC83xx_PCI1_UPPER_IO;
+#ifdef CONFIG_MPC834x_PCI2
+ isa_io_base = (unsigned long)ioremap(MPC83xx_PCI1_IO_BASE,
+ MPC83xx_PCI1_IO_SIZE +
+ MPC83xx_PCI2_IO_SIZE);
+#else
+ isa_io_base = (unsigned long)ioremap(MPC83xx_PCI1_IO_BASE,
+ MPC83xx_PCI1_IO_SIZE);
+#endif /* CONFIG_MPC834x_PCI2 */
+ hose1->io_base_virt = (void *)isa_io_base;
+ /* setup resources */
+ pci_init_resource(&hose1->io_resource,
+ MPC83xx_PCI1_LOWER_IO,
+ MPC83xx_PCI1_UPPER_IO,
+ IORESOURCE_IO, "PCI host bridge 1");
+ pci_init_resource(&hose1->mem_resources[0],
+ MPC83xx_PCI1_LOWER_MEM,
+ MPC83xx_PCI1_UPPER_MEM,
+ IORESOURCE_MEM, "PCI host bridge 1");
+
+ ppc_md.pci_exclude_device = mpc83xx_ads_exclude_device;
+ hose1->last_busno = pciauto_bus_scan(hose1, hose1->first_busno);
+
+#ifdef CONFIG_MPC834x_PCI2
+ hose2 = pcibios_alloc_controller();
+ if (!hose2)
+ return;
+
+ hose2->bus_offset = hose1->last_busno + 1;
+ hose2->first_busno = hose1->last_busno + 1;
+ hose2->last_busno = 0xff;
+ setup_indirect_pci(hose2, binfo->bi_immr_base + PCI2_CFG_ADDR_OFFSET,
+ binfo->bi_immr_base + PCI2_CFG_DATA_OFFSET);
+ hose2->set_cfg_type = 1;
+
+ mpc834x_ads_setup_pci2(hose2);
+
+ hose2->pci_mem_offset = MPC83xx_PCI2_MEM_OFFSET;
+ hose2->mem_space.start = MPC83xx_PCI2_LOWER_MEM;
+ hose2->mem_space.end = MPC83xx_PCI2_UPPER_MEM;
+
+ hose2->io_base_phys = MPC83xx_PCI2_IO_BASE;
+ hose2->io_space.start = MPC83xx_PCI2_LOWER_IO;
+ hose2->io_space.end = MPC83xx_PCI2_UPPER_IO;
+ hose2->io_base_virt = (void *)(isa_io_base + MPC83xx_PCI1_IO_SIZE);
+ /* setup resources */
+ pci_init_resource(&hose2->io_resource,
+ MPC83xx_PCI2_LOWER_IO,
+ MPC83xx_PCI2_UPPER_IO,
+ IORESOURCE_IO, "PCI host bridge 2");
+ pci_init_resource(&hose2->mem_resources[0],
+ MPC83xx_PCI2_LOWER_MEM,
+ MPC83xx_PCI2_UPPER_MEM,
+ IORESOURCE_MEM, "PCI host bridge 2");
+
+ hose2->last_busno = pciauto_bus_scan(hose2, hose2->first_busno);
+#endif /* CONFIG_MPC834x_PCI2 */
+}
+#endif /*CONFIG_PCI */
diff -urN -X dontdiff linux-2.6.13-rc6/arch/ppc/syslib/ppc83xx_setup.h linux-2.6.13-rc6-pci/arch/ppc/syslib/ppc83xx_setup.h
--- linux-2.6.13-rc6/arch/ppc/syslib/ppc83xx_setup.h 2005-06-18 03:48:29.000000000 +0800
+++ linux-2.6.13-rc6-pci/arch/ppc/syslib/ppc83xx_setup.h 2005-08-23 10:25:43.000000000 +0800
@@ -12,6 +12,14 @@
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __PPC_SYSLIB_PPC83XX_SETUP_H
@@ -20,6 +28,7 @@
#include <linux/config.h>
#include <linux/init.h>
#include <asm/ppcboot.h>
+#include <asm/mpc83xx.h>
extern unsigned long mpc83xx_find_end_of_memory(void) __init;
extern long mpc83xx_time_init(void) __init;
@@ -30,15 +39,6 @@
extern void mpc83xx_halt(void);
extern void mpc83xx_setup_hose(void) __init;
-/* PCI config */
-#if 0
-#define PCI1_CFG_ADDR_OFFSET (FIXME)
-#define PCI1_CFG_DATA_OFFSET (FIXME)
-
-#define PCI2_CFG_ADDR_OFFSET (FIXME)
-#define PCI2_CFG_DATA_OFFSET (FIXME)
-#endif
-
/* Serial Config */
#ifdef CONFIG_SERIAL_MANY_PORTS
#define RS_TABLE_SIZE 64
@@ -50,4 +50,4 @@
#define BASE_BAUD 115200
#endif
-#endif /* __PPC_SYSLIB_PPC83XX_SETUP_H */
+#endif /* __PPC_SYSLIB_PPC83XX_SETUP_H */
[-- Attachment #2: Type: text/html, Size: 33857 bytes --]
^ permalink raw reply
* RE: [PATCH] ppc32 :Added PCI support for MPC83xx
From: Li Tony-r64360 @ 2005-08-30 8:42 UTC (permalink / raw)
To: Gala Kumar K.-galak; +Cc: Chu hanjin-r52514, linux-kernel, linuxppc-embedded
Yes, you are right. I missed this. I will send a new patch with this corrected.
Tony Li
-----Original Message-----
From: Gala Kumar K.-galak
Sent: Tuesday, August 30, 2005 12:28 PM
To: Li Tony-r64360
Cc: linuxppc-embedded; linux-kernel@vger.kernel.org; Chu hanjin-r52514
Subject: Re: [PATCH] ppc32 :Added PCI support for MPC83xx
Hmm, well the PCI spec seems to be clear on the fact that PCI interrupts should be level sensitive.
- kumar
On Aug 29, 2005, at 10:02 PM, Li Tony-r64360 wrote:
> I think it is OK. The external interrupt can be edged. And it works
> well in my board.
>
> Tony Li
>
> -----Original Message-----
> From: Gala Kumar K.-galak
> Sent: Tuesday, August 30, 2005 1:43 AM
> To: Li Tony-r64360
> Cc: linuxppc-embedded; linux-kernel@vger.kernel.org; Gala Kumar
> K.-galak; Chu hanjin-r52514
> Subject: Re: [PATCH] ppc32 :Added PCI support for MPC83xx
>
> I noticed that you aren't updating the senses array in
> mpc834x_sys_init_IRQ for the PCI interrupt lines, is this correct?
> Should they not be IRQ_SENSE_LEVEL?
>
> Also, I've done a bit of cosmetic cleanup to the patch, take a look
> and let me know if it works. Once we close on the IRQ sense issue I
> will send this upstream.
>
> - kumar
>
> ---
>
> diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
> --- a/arch/ppc/Kconfig
> +++ b/arch/ppc/Kconfig
> @@ -713,6 +713,12 @@ config MPC834x_SYS
> help
> This option enables support for the MPC 834x SYS evaluation
> board.
>
> + Be aware that PCI buses can only function when SYS board is
> plugged on
> + PIB (Platform IO Board) board from Freescale which provide 3
> PCI slots.
> + Just like PC,the board level initalization is bootloader`s
> responsiblilty.
> + The PCI deponds on bootloader configurate board corretly.
> Refer to Freescale
> + to get more information about this.
> +
> endchoice
>
> config PQ2ADS
> @@ -1193,6 +1199,11 @@ config PCI
> config PCI_DOMAINS
> bool
> default PCI
> +
> +config MPC83xx_PCI2
> + bool " Supprt for 2nd PCI host controller"
> + depends on PCI && MPC834x
> + default y if MPC834x_SYS
>
> config PCI_QSPAN
> bool "QSpan PCI"
> diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c
> b/arch/ppc/platforms/83xx/mpc834x_sys.c
> --- a/arch/ppc/platforms/83xx/mpc834x_sys.c
> +++ b/arch/ppc/platforms/83xx/mpc834x_sys.c
> @@ -62,9 +62,29 @@ extern unsigned long total_memory; /* in
> unsigned char __res[sizeof (bd_t)];
>
> #ifdef CONFIG_PCI
> -#error "PCI is not supported"
> -/* NEED mpc83xx_map_irq & mpc83xx_exclude_device
> - see platforms/85xx/mpc85xx_ads_common.c */
> +int
> +mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned
> char
>
> +pin) {
> + static char pci_irq_table[][4] =
> + /*
> + * PCI IDSEL/INTPIN->INTLINE
> + * A B C D
> + */
> + {
> + {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x11 */
> + {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x12 */
> + {PIRQD, PIRQA, PIRQB, PIRQC} /* idsel 0x13 */
> + };
> +
> + const long min_idsel = 0x11, max_idsel = 0x13, irqs_per_slot =
> 4;
> + return PCI_IRQ_TABLE_LOOKUP;
> +}
> +
> +int
> +mpc83xx_exclude_device(u_char bus, u_char devfn) {
> + return PCIBIOS_SUCCESSFUL;
> +}
> #endif /* CONFIG_PCI */
>
> /*
> **********************************************************************
> **
> @@ -88,7 +108,7 @@ mpc834x_sys_setup_arch(void)
>
> #ifdef CONFIG_PCI
> /* setup PCI host bridges */
> - mpc83xx_sys_setup_hose();
> + mpc83xx_setup_hose();
> #endif
> mpc83xx_early_serial_map();
>
> diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.h
> b/arch/ppc/platforms/83xx/mpc834x_sys.h
> --- a/arch/ppc/platforms/83xx/mpc834x_sys.h
> +++ b/arch/ppc/platforms/83xx/mpc834x_sys.h
> @@ -26,7 +26,7 @@
> #define VIRT_IMMRBAR ((uint)0xfe000000)
>
> #define BCSR_PHYS_ADDR ((uint)0xf8000000)
> -#define BCSR_SIZE ((uint)(32 * 1024))
> +#define BCSR_SIZE ((uint)(128 * 1024))
>
> #define BCSR_MISC_REG2_OFF 0x07
> #define BCSR_MISC_REG2_PORESET 0x01
> @@ -34,23 +34,25 @@
> #define BCSR_MISC_REG3_OFF 0x08
> #define BCSR_MISC_REG3_CNFLOCK 0x80
>
> -#ifdef CONFIG_PCI
> -/* PCI interrupt controller */
> -#define PIRQA MPC83xx_IRQ_IRQ4
> -#define PIRQB MPC83xx_IRQ_IRQ5
> -#define PIRQC MPC83xx_IRQ_IRQ6
> -#define PIRQD MPC83xx_IRQ_IRQ7
> -
> -#define MPC834x_SYS_PCI1_LOWER_IO 0x00000000
> -#define MPC834x_SYS_PCI1_UPPER_IO 0x00ffffff
> -
> -#define MPC834x_SYS_PCI1_LOWER_MEM 0x80000000
> -#define MPC834x_SYS_PCI1_UPPER_MEM 0x9fffffff
> -
> -#define MPC834x_SYS_PCI1_IO_BASE 0xe2000000
> -#define MPC834x_SYS_PCI1_MEM_OFFSET 0x00000000
> -
> -#define MPC834x_SYS_PCI1_IO_SIZE 0x01000000
> -#endif /* CONFIG_PCI */
> +#define PIRQA MPC83xx_IRQ_EXT4
> +#define PIRQB MPC83xx_IRQ_EXT5
> +#define PIRQC MPC83xx_IRQ_EXT6
> +#define PIRQD MPC83xx_IRQ_EXT7
> +
> +#define MPC83xx_PCI1_LOWER_IO 0x00000000
> +#define MPC83xx_PCI1_UPPER_IO 0x00ffffff
> +#define MPC83xx_PCI1_LOWER_MEM 0x80000000
> +#define MPC83xx_PCI1_UPPER_MEM 0x9fffffff
> +#define MPC83xx_PCI1_IO_BASE 0xe2000000
> +#define MPC83xx_PCI1_MEM_OFFSET 0x00000000
> +#define MPC83xx_PCI1_IO_SIZE 0x01000000
> +
> +#define MPC83xx_PCI2_LOWER_IO 0x00000000
> +#define MPC83xx_PCI2_UPPER_IO 0x00ffffff
> +#define MPC83xx_PCI2_LOWER_MEM 0xa0000000
> +#define MPC83xx_PCI2_UPPER_MEM 0xbfffffff
> +#define MPC83xx_PCI2_IO_BASE 0xe3000000
> +#define MPC83xx_PCI2_MEM_OFFSET 0x00000000
> +#define MPC83xx_PCI2_IO_SIZE 0x01000000
>
> #endif /* __MACH_MPC83XX_SYS_H__ */
> diff --git a/arch/ppc/syslib/ppc83xx_pci.h
> b/arch/ppc/syslib/ppc83xx_pci.h new file mode 100644
> --- /dev/null
> +++ b/arch/ppc/syslib/ppc83xx_pci.h
> @@ -0,0 +1,151 @@
> +/* Created by Tony Li <tony.li@freescale.com>
> + * Copyright (c) 2005 freescale semiconductor
> + *
> + * This program is free software; you can redistribute it and/or
> +modify it
> + * under the terms of the GNU General Public License as
> published by
>
> +the
> + * Free Software Foundation; either version 2 of the License, or
> (at
> +your
> + * option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> +along
> + * with this program; if not, write to the Free Software Foundation,
> +Inc.,
> + * 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +#ifndef __PPC_SYSLIB_PPC83XX_PCI_H
> +#define __PPC_SYSLIB_PPC83XX_PCI_H
> +
> +typedef struct immr_clk {
> + u32 spmr; /* system PLL mode Register */
> + u32 occr; /* output clock control Register */
> + u32 sccr; /* system clock control Register */
> + u8 res0[0xF4];
> +} immr_clk_t;
> +
> +/*
> + * Sequencer
> + */
> +typedef struct immr_ios {
> + u32 potar0;
> + u8 res0[4];
> + u32 pobar0;
> + u8 res1[4];
> + u32 pocmr0;
> + u8 res2[4];
> + u32 potar1;
> + u8 res3[4];
> + u32 pobar1;
> + u8 res4[4];
> + u32 pocmr1;
> + u8 res5[4];
> + u32 potar2;
> + u8 res6[4];
> + u32 pobar2;
> + u8 res7[4];
> + u32 pocmr2;
> + u8 res8[4];
> + u32 potar3;
> + u8 res9[4];
> + u32 pobar3;
> + u8 res10[4];
> + u32 pocmr3;
> + u8 res11[4];
> + u32 potar4;
> + u8 res12[4];
> + u32 pobar4;
> + u8 res13[4];
> + u32 pocmr4;
> + u8 res14[4];
> + u32 potar5;
> + u8 res15[4];
> + u32 pobar5;
> + u8 res16[4];
> + u32 pocmr5;
> + u8 res17[4];
> + u8 res18[0x60];
> + u32 pmcr;
> + u8 res19[4];
> + u32 dtcr;
> + u8 res20[4];
> +} immr_ios_t;
> +#define POTAR_TA_MASK 0x000fffff
> +#define POBAR_BA_MASK 0x000fffff
> +#define POCMR_EN 0x80000000
> +#define POCMR_IO 0x40000000 /* 0--memory space 1--I/O space */
> +#define POCMR_SE 0x20000000 /* streaming enable */
> +#define POCMR_DST 0x10000000 /* 0--PCI1 1--PCI2 */
> +#define POCMR_CM_MASK 0x000fffff
> +
> +/*
> + * PCI Controller Control and Status Registers */ typedef struct
> +immr_pcictrl {
> + u32 esr;
> + u32 ecdr;
> + u32 eer;
> + u32 eatcr;
> + u32 eacr;
> + u32 eeacr;
> + u32 edlcr;
> + u32 edhcr;
> + u32 gcr;
> + u32 ecr;
> + u32 gsr;
> + u8 res0[12];
> + u32 pitar2;
> + u8 res1[4];
> + u32 pibar2;
> + u32 piebar2;
> + u32 piwar2;
> + u8 res2[4];
> + u32 pitar1;
> + u8 res3[4];
> + u32 pibar1;
> + u32 piebar1;
> + u32 piwar1;
> + u8 res4[4];
> + u32 pitar0;
> + u8 res5[4];
> + u32 pibar0;
> + u8 res6[4];
> + u32 piwar0;
> + u8 res7[132];
> +} immr_pcictrl_t;
> +#define PITAR_TA_MASK 0x000fffff
> +#define PIBAR_MASK 0xffffffff
> +#define PIEBAR_EBA_MASK 0x000fffff
> +#define PIWAR_EN 0x80000000
> +#define PIWAR_PF 0x20000000
> +#define PIWAR_RTT_MASK 0x000f0000
> +#define PIWAR_RTT_NO_SNOOP 0x00040000
> +#define PIWAR_RTT_SNOOP 0x00050000
> +#define PIWAR_WTT_MASK 0x0000f000
> +#define PIWAR_WTT_NO_SNOOP 0x00004000
> +#define PIWAR_WTT_SNOOP 0x00005000
> +#define PIWAR_IWS_MASK 0x0000003F
> +#define PIWAR_IWS_4K 0x0000000B
> +#define PIWAR_IWS_8K 0x0000000C
> +#define PIWAR_IWS_16K 0x0000000D
> +#define PIWAR_IWS_32K 0x0000000E
> +#define PIWAR_IWS_64K 0x0000000F
> +#define PIWAR_IWS_128K 0x00000010
> +#define PIWAR_IWS_256K 0x00000011
> +#define PIWAR_IWS_512K 0x00000012
> +#define PIWAR_IWS_1M 0x00000013
> +#define PIWAR_IWS_2M 0x00000014
> +#define PIWAR_IWS_4M 0x00000015
> +#define PIWAR_IWS_8M 0x00000016
> +#define PIWAR_IWS_16M 0x00000017
> +#define PIWAR_IWS_32M 0x00000018
> +#define PIWAR_IWS_64M 0x00000019
> +#define PIWAR_IWS_128M 0x0000001A
> +#define PIWAR_IWS_256M 0x0000001B
> +#define PIWAR_IWS_512M 0x0000001C
> +#define PIWAR_IWS_1G 0x0000001D
> +#define PIWAR_IWS_2G 0x0000001E
> +
> +#endif /* __PPC_SYSLIB_PPC83XX_PCI_H */
> diff --git a/arch/ppc/syslib/ppc83xx_setup.c
> b/arch/ppc/syslib/ppc83xx_setup.c
> --- a/arch/ppc/syslib/ppc83xx_setup.c
> +++ b/arch/ppc/syslib/ppc83xx_setup.c
> @@ -11,6 +11,17 @@
> * under the terms of the GNU General Public License as
> published by
> the
> * Free Software Foundation; either version 2 of the License, or
> (at
> your
> * option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + along
> + * with this program; if not, write to the Free Software Foundation,
> + Inc.,
> + * 675 Mass Ave, Cambridge, MA 02139, USA.
> + *
> + * Added PCI support -- Tony Li <tony.li@freescale.com>
> */
>
> #include <linux/config.h>
> @@ -31,6 +42,10 @@
> #include <asm/delay.h>
>
> #include <syslib/ppc83xx_setup.h>
> +#if defined(CONFIG_PCI)
> +#include <asm/delay.h>
> +#include <syslib/ppc83xx_pci.h>
> +#endif
>
> phys_addr_t immrbar;
>
> @@ -162,4 +177,237 @@ mpc83xx_halt(void)
> for(;;);
> }
>
> -/* PCI SUPPORT DOES NOT EXIT, MODEL after ppc85xx_setup.c */
> +#if defined(CONFIG_PCI)
> +void __init
> +mpc83xx_setup_pci1(struct pci_controller *hose) {
> + u16 reg16;
> + volatile immr_pcictrl_t * pci_ctrl;
> + volatile immr_ios_t * ios;
> + bd_t *binfo = (bd_t *) __res;
> +
> + pci_ctrl = ioremap(binfo->bi_immr_base + 0x8500,
> sizeof(immr_pcictrl_t));
> + ios = ioremap(binfo->bi_immr_base + 0x8400, sizeof(immr_ios_t));
> +
> + /*
> + * Configure PCI Outbound Translation Windows
> + */
> + ios->potar0 = (MPC83xx_PCI1_LOWER_MEM >> 12) & POTAR_TA_MASK;
> + ios->pobar0 = (MPC83xx_PCI1_LOWER_MEM >> 12) & POBAR_BA_MASK;
> + ios->pocmr0 = POCMR_EN |
> + (((0xffffffff - (MPC83xx_PCI1_UPPER_MEM -
> + MPC83xx_PCI1_LOWER_MEM)) >> 12) &
> POCMR_CM_MASK);
> +
> + /* mapped to PCI1 IO space */
> + ios->potar1 = (MPC83xx_PCI1_LOWER_IO >> 12) & POTAR_TA_MASK;
> + ios->pobar1 = (MPC83xx_PCI1_IO_BASE >> 12) & POBAR_BA_MASK;
> + ios->pocmr1 = POCMR_EN | POCMR_IO |
> + (((0xffffffff - (MPC83xx_PCI1_UPPER_IO -
> + MPC83xx_PCI1_LOWER_IO)) >> 12) &
> POCMR_CM_MASK);
> +
> + /*
> + * Configure PCI Inbound Translation Windows
> + */
> + pci_ctrl->pitar1 = 0x0;
> + pci_ctrl->pibar1 = 0x0;
> + pci_ctrl->piebar1 = 0x0;
> + pci_ctrl->piwar1 = PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP |
> +PIWAR_WTT_SNOOP | PIWAR_IWS_2G;
> +
> + /*
> + * Release PCI RST signal
> + */
> + pci_ctrl->gcr = 0;
> + udelay(2000);
> + pci_ctrl->gcr = 1;
> + udelay(2000);
> +
> + reg16 = 0xff;
> + early_read_config_word(hose, hose->first_busno, 0, PCI_COMMAND,
> ®16);
> + reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER |
> PCI_COMMAND_MEMORY;
> + early_write_config_word(hose, hose->first_busno, 0, PCI_COMMAND,
>
> +reg16);
> +
> + /*
> + * Clear non-reserved bits in status register.
> + */
> + early_write_config_word(hose, hose->first_busno, 0, PCI_STATUS,
> 0xffff);
> + early_write_config_byte(hose, hose->first_busno, 0,
> PCI_LATENCY_TIMER,
> +0x80);
> +
> + iounmap(pci_ctrl);
> + iounmap(ios);
> +}
> +
> +void __init
> +mpc83xx_setup_pci2(struct pci_controller *hose) {
> + u16 reg16;
> + volatile immr_pcictrl_t * pci_ctrl;
> + volatile immr_ios_t * ios;
> + bd_t *binfo = (bd_t *) __res;
> +
> + pci_ctrl = ioremap(binfo->bi_immr_base + 0x8600,
> sizeof(immr_pcictrl_t));
> + ios = ioremap(binfo->bi_immr_base + 0x8400, sizeof(immr_ios_t));
> +
> + /*
> + * Configure PCI Outbound Translation Windows
> + */
> + ios->potar3 = (MPC83xx_PCI2_LOWER_MEM >> 12) & POTAR_TA_MASK;
> + ios->pobar3 = (MPC83xx_PCI2_LOWER_MEM >> 12) & POBAR_BA_MASK;
> + ios->pocmr3 = POCMR_EN | POCMR_DST |
> + (((0xffffffff - (MPC83xx_PCI2_UPPER_MEM -
> + MPC83xx_PCI2_LOWER_MEM)) >> 12) &
> POCMR_CM_MASK);
> +
> + /* mapped to PCI2 IO space */
> + ios->potar4 = (MPC83xx_PCI2_LOWER_IO >> 12) & POTAR_TA_MASK;
> + ios->pobar4 = (MPC83xx_PCI2_IO_BASE >> 12) & POBAR_BA_MASK;
> + ios->pocmr4 = POCMR_EN | POCMR_DST | POCMR_IO |
> + (((0xffffffff - (MPC83xx_PCI2_UPPER_IO -
> + MPC83xx_PCI2_LOWER_IO)) >> 12) &
> POCMR_CM_MASK);
> +
> + /*
> + * Configure PCI Inbound Translation Windows
> + */
> + pci_ctrl->pitar1 = 0x0;
> + pci_ctrl->pibar1 = 0x0;
> + pci_ctrl->piebar1 = 0x0;
> + pci_ctrl->piwar1 = PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP |
> +PIWAR_WTT_SNOOP | PIWAR_IWS_2G;
> +
> + /*
> + * Release PCI RST signal
> + */
> + pci_ctrl->gcr = 0;
> + udelay(2000);
> + pci_ctrl->gcr = 1;
> + udelay(2000);
> +
> + reg16 = 0xff;
> + early_read_config_word(hose, hose->first_busno, 0, PCI_COMMAND,
> ®16);
> + reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER |
> PCI_COMMAND_MEMORY;
> + early_write_config_word(hose, hose->first_busno, 0, PCI_COMMAND,
>
> +reg16);
> +
> + /*
> + * Clear non-reserved bits in status register.
> + */
> + early_write_config_word(hose, hose->first_busno, 0, PCI_STATUS,
> 0xffff);
> + early_write_config_byte(hose, hose->first_busno, 0,
> PCI_LATENCY_TIMER,
> +0x80);
> +
> + iounmap(pci_ctrl);
> + iounmap(ios);
> +}
> +
> +/*
> + * PCI buses can be enabled only if SYS board combinates with PIB
> + * (Platform IO Board) board which provide 3 PCI slots. There is 2
> PCI
> +buses
> + * and 3 PCI slots, so people must configure the routes between them
> +before
> + * enable PCI bus. This routes are under the control of PCA9555PW
> +device which
> + * can be accessed via I2C bus 2 and are configured by firmware.
> Refer
> +to
> + * Freescale to get more information about firmware configuration.
> + */
> +
> +extern int mpc83xx_exclude_device(u_char bus, u_char devfn);
> extern int
>
> +mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel,
> + unsigned char pin);
> +void __init
> +mpc83xx_setup_hose(void)
> +{
> + u32 val32;
> + volatile immr_clk_t * clk;
> + struct pci_controller * hose1;
> +#ifdef CONFIG_MPC83xx_PCI2
> + struct pci_controller * hose2;
> +#endif
> + bd_t * binfo = (bd_t *)__res;
> +
> + clk = ioremap(binfo->bi_immr_base + 0xA00,
> + sizeof(immr_clk_t));
> +
> + /*
> + * Configure PCI controller and PCI_CLK_OUTPUT both in 66M mode
> + */
> + val32 = clk->occr;
> + udelay(2000);
> + clk->occr = 0xff000000;
> + udelay(2000);
> +
> + iounmap(clk);
> +
> + hose1 = pcibios_alloc_controller();
> + if(!hose1)
> + return;
> +
> + ppc_md.pci_swizzle = common_swizzle;
> + ppc_md.pci_map_irq = mpc83xx_map_irq;
> +
> + hose1->bus_offset = 0;
> + hose1->first_busno = 0;
> + hose1->last_busno = 0xff;
> +
> + setup_indirect_pci(hose1, binfo->bi_immr_base +
> PCI1_CFG_ADDR_OFFSET,
> + binfo->bi_immr_base + PCI1_CFG_DATA_OFFSET);
> + hose1->set_cfg_type = 1;
> +
> + mpc83xx_setup_pci1(hose1);
> +
> + hose1->pci_mem_offset = MPC83xx_PCI1_MEM_OFFSET;
> + hose1->mem_space.start = MPC83xx_PCI1_LOWER_MEM;
> + hose1->mem_space.end = MPC83xx_PCI1_UPPER_MEM;
> +
> + hose1->io_base_phys = MPC83xx_PCI1_IO_BASE;
> + hose1->io_space.start = MPC83xx_PCI1_LOWER_IO;
> + hose1->io_space.end = MPC83xx_PCI1_UPPER_IO; #ifdef
> +CONFIG_MPC83xx_PCI2
> + isa_io_base = (unsigned long)ioremap(MPC83xx_PCI1_IO_BASE,
> + MPC83xx_PCI1_IO_SIZE + MPC83xx_PCI2_IO_SIZE);
> #else
> + isa_io_base = (unsigned long)ioremap(MPC83xx_PCI1_IO_BASE,
> + MPC83xx_PCI1_IO_SIZE);
> +#endif /* CONFIG_MPC83xx_PCI2 */
> + hose1->io_base_virt = (void *)isa_io_base;
> + /* setup resources */
> + pci_init_resource(&hose1->io_resource,
> + MPC83xx_PCI1_LOWER_IO,
> + MPC83xx_PCI1_UPPER_IO,
> + IORESOURCE_IO, "PCI host bridge 1");
> + pci_init_resource(&hose1->mem_resources[0],
> + MPC83xx_PCI1_LOWER_MEM,
> + MPC83xx_PCI1_UPPER_MEM,
> + IORESOURCE_MEM, "PCI host bridge 1");
> +
> + ppc_md.pci_exclude_device = mpc83xx_exclude_device;
> + hose1->last_busno = pciauto_bus_scan(hose1, hose1->first_busno);
> +
> +#ifdef CONFIG_MPC83xx_PCI2
> + hose2 = pcibios_alloc_controller();
> + if(!hose2)
> + return;
> +
> + hose2->bus_offset = hose1->last_busno + 1;
> + hose2->first_busno = hose1->last_busno + 1;
> + hose2->last_busno = 0xff;
> + setup_indirect_pci(hose2, binfo->bi_immr_base +
> PCI2_CFG_ADDR_OFFSET,
> + binfo->bi_immr_base + PCI2_CFG_DATA_OFFSET);
> + hose2->set_cfg_type = 1;
> +
> + mpc83xx_setup_pci2(hose2);
> +
> + hose2->pci_mem_offset = MPC83xx_PCI2_MEM_OFFSET;
> + hose2->mem_space.start = MPC83xx_PCI2_LOWER_MEM;
> + hose2->mem_space.end = MPC83xx_PCI2_UPPER_MEM;
> +
> + hose2->io_base_phys = MPC83xx_PCI2_IO_BASE;
> + hose2->io_space.start = MPC83xx_PCI2_LOWER_IO;
> + hose2->io_space.end = MPC83xx_PCI2_UPPER_IO;
> + hose2->io_base_virt = (void *)(isa_io_base +
> MPC83xx_PCI1_IO_SIZE);
> + /* setup resources */
> + pci_init_resource(&hose2->io_resource,
> + MPC83xx_PCI2_LOWER_IO,
> + MPC83xx_PCI2_UPPER_IO,
> + IORESOURCE_IO, "PCI host bridge 2");
> + pci_init_resource(&hose2->mem_resources[0],
> + MPC83xx_PCI2_LOWER_MEM,
> + MPC83xx_PCI2_UPPER_MEM,
> + IORESOURCE_MEM, "PCI host bridge 2");
> +
> + hose2->last_busno = pciauto_bus_scan(hose2, hose2->first_busno);
>
> +#endif /* CONFIG_MPC83xx_PCI2 */ } #endif /*CONFIG_PCI*/
> diff --git a/arch/ppc/syslib/ppc83xx_setup.h
> b/arch/ppc/syslib/ppc83xx_setup.h
> --- a/arch/ppc/syslib/ppc83xx_setup.h
> +++ b/arch/ppc/syslib/ppc83xx_setup.h
> @@ -12,6 +12,14 @@
> * Free Software Foundation; either version 2 of the License, or
> (at
> your
> * option) any later version.
> *
> + * This program is distributed in the hope that it will be useful,
> but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + along
> + * with this program; if not, write to the Free Software Foundation,
> + Inc.,
> + * 675 Mass Ave, Cambridge, MA 02139, USA.
> */
>
> #ifndef __PPC_SYSLIB_PPC83XX_SETUP_H
> @@ -19,7 +27,6 @@
>
> #include <linux/config.h>
> #include <linux/init.h>
> -#include <asm/ppcboot.h>
>
> extern unsigned long mpc83xx_find_end_of_memory(void) __init; extern
> long mpc83xx_time_init(void) __init; @@ -31,13 +38,11 @@ extern void
> mpc83xx_halt(void); extern void mpc83xx_setup_hose(void) __init;
>
> /* PCI config */
> -#if 0
> -#define PCI1_CFG_ADDR_OFFSET (FIXME)
> -#define PCI1_CFG_DATA_OFFSET (FIXME)
> +#define PCI1_CFG_ADDR_OFFSET (0x8300)
> +#define PCI1_CFG_DATA_OFFSET (0x8304)
>
> -#define PCI2_CFG_ADDR_OFFSET (FIXME)
> -#define PCI2_CFG_DATA_OFFSET (FIXME)
> -#endif
> +#define PCI2_CFG_ADDR_OFFSET (0x8380)
> +#define PCI2_CFG_DATA_OFFSET (0x8384)
>
> /* Serial Config */
> #ifdef CONFIG_SERIAL_MANY_PORTS
>
^ permalink raw reply
* Re: Cross compile krb5 issue for ppc
From: Wolfgang Denk @ 2005-08-30 8:21 UTC (permalink / raw)
To: JohnsonCheng; +Cc: linux-ppc-embedded
In-Reply-To: <20050830041704.3ECDE68166@ozlabs.org>
In message <20050830041704.3ECDE68166@ozlabs.org> you wrote:
>
> When I cross compile krb5-1.4.1 for ppc on x86, I got the following error
> message.
...
> Cannot test for constructor/destructor support when cross compiling
Yes, this is a very typical situation. Many packages are not exactly
well-behaving in a cross environment, so you need more or less
extensive tweaking.
> Do anybody can give me advice or tell me where to get krb5 library for ppc?
It's included with the ELDK.
Also, if you look at the ELDK's patches and spec files you can see
easily what needs to be done to build it in a cross environment.
Best regards,
Wolfgang Denk
--
Software Engineering: Embedded and Realtime Systems, Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
Most legends have their basis in facts.
-- Kirk, "And The Children Shall Lead", stardate 5029.5
^ permalink raw reply
* Re: [PATCH 00/14] ppc32: Remove board ports that are no longer maintained
From: Eugene Surovegin @ 2005-08-30 7:44 UTC (permalink / raw)
To: Kumar Gala; +Cc: Andrew Morton, Gala Kumar K.-galak, linuxppc-embedded
In-Reply-To: <0048AEBE-072F-4250-9D32-EC019D0BDBB9@freescale.com>
On Mon, Aug 29, 2005 at 08:46:22PM -0500, Kumar Gala wrote:
>
> On Jul 27, 2005, at 2:57 PM, Andrew Morton wrote:
>
> >Kumar Gala <galak@freescale.com> wrote:
> >
> >>
> >>The following board ports are no longer maintained or have become
> >> obsolete:
> >>
> >> adir
> >> ash
> >> beech
> >> cedar
> >> ep405
> >> k2
> >> mcpn765
> >> menf1
> >> oak
> >> pcore
> >> rainier
> >> redwood
> >> sm850
> >> spd823ts
> >>
> >> We are there for removing support for them.
> >>
> >
> >I'll merge all these into -mm for now, but will hold off sending
> >any of
> >them upstream pending confirmation of which patches we really want to
> >proceed with.
>
> No one has screamed about anything but ep405 so all the others should
> go to Linus now.
Matt told me he would probably get ash soon. There is even a path in
the -mm queue which should fix ethernet on this board.
Matt?
--
Eugene
^ permalink raw reply
* Re: [PATCH] MPC8xx PCMCIA driver
From: Russell King @ 2005-08-30 7:06 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: linux-kernel, linux-ppc-embedded
In-Reply-To: <20050830024840.GA5381@dmt.cnet>
On Mon, Aug 29, 2005 at 11:48:40PM -0300, Marcelo Tosatti wrote:
> Here goes the 8xx PCMCIA driver, originally written by Magnus Damm, with
> several improvements and fixes.
Please don't copy me on PCMCIA stuff - I don't look after PCMCIA anymore.
Please use the linux-pcmcia mailing list on lists.infradead.org. Thanks.
> Russell: The driver is using pccard_nonstatic_ops for card window
> management, even though the driver its marked SS_STATIC_MAP (using
> mem->static_map).
>
> Otherwise card IO windows aren't allocated properly.
This seems very wrong. Are you suggesting that IO windows need to be
dynamic and memory windows static? If so, the pcmcia code isn't
designed to cope with that.
--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core
^ permalink raw reply
* Re: linuxppc-2.4.30-pre1 crashes with root fs on Xilinx SystemACE
From: Peter Ryser @ 2005-08-30 6:18 UTC (permalink / raw)
To: Keith J Outwater; +Cc: linuxppc-embedded
In-Reply-To: <OF9C3C40D4.4EC5E6BD-ON0725706C.0064A09D-0725706C.0065B9FC@mck.us.ray.com>
Hi Keith,
I sent you a private email but for other interested people:
Downloading the latest linuxppc-2.4 kernel I could boot from and access
System ACE CF without problems on a ML403 (Virtex-4, 4VFX12) and a ML310
(Virtex-II Pro, 2VP30) using EDK 7.1.2. In both cases I started with
config_xilinx_ml300.
- Peter
Keith J Outwater wrote:
>Hello -
>Per a previous suggestion from this list, I rsynced the linuxppc-2.4
>kernel sources from MontaVista and modified the kernel to run on my custom
>ppc405/VirtexII Pro based system with U-Boot as the bootloader.
>When I try to use the SystemACE device as the root filesystem, the kernel
>crashes with a sig 11. Looking at the 'oops' output it appears the
>SystemACE driver may be to blame. The crash is random - sometimes I get
>all the way to login as root and then things crash on a file copy or a
>file read.
>Before I start digging deeper, is anyone running a VirtexIIPro based
>system with the root filesystem in the CF card attached to a SystemACE?
>I'm wondering if I really have the best kernel and SystemACE driver.
>BTW, I'm developing the hardware design using Xilinx EDK 7.02i.
>Thanks,
>Keith
>_______________________________________________
>Linuxppc-embedded mailing list
>Linuxppc-embedded@ozlabs.org
>https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
>
>
>
^ permalink raw reply
* [PATCH] cpm_uart: Fix baseaddress for SMC 1 and 2
From: Kumar Gala @ 2005-08-30 4:48 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel, linuxppc-embedded
Base addess register for SMC 1 and 2 are never initialized.
This means that they will not work unless a bootloader already
configured them.
The DPRAM already have space reserved, this patch just makes sure
the base addess register is updated correctly on initialization.
Signed-off-by: Rune Torgersen <runet@innovsys.com>
Signed-off-by: Kumar Gala <kumar.gala@freescale.com>
---
commit b9ecc8e4b5db64f0b4ee36dbdd6758e4ce3c2025
tree c6d9da4a2bec187d4fc794b91441323c04642dda
parent 66256c2b92e3edafca1e86e64fcffe5c72cc39e7
author Kumar K. Gala <kumar.gala@freescale.com> Mon, 29 Aug 2005 23:30:56 -0500
committer Kumar K. Gala <kumar.gala@freescale.com> Mon, 29 Aug 2005 23:30:56 -0500
drivers/serial/cpm_uart/cpm_uart_cpm2.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -266,6 +266,7 @@ int cpm_uart_init_portdesc(void)
cpm_uart_ports[UART_SMC1].smcp = (smc_t *) & cpm2_immr->im_smc[0];
cpm_uart_ports[UART_SMC1].smcup =
(smc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SMC1];
+ *(u16 *)(&cpm2_immr->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1;
cpm_uart_ports[UART_SMC1].port.mapbase =
(unsigned long)&cpm2_immr->im_smc[0];
cpm_uart_ports[UART_SMC1].smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
@@ -278,6 +279,7 @@ int cpm_uart_init_portdesc(void)
cpm_uart_ports[UART_SMC2].smcp = (smc_t *) & cpm2_immr->im_smc[1];
cpm_uart_ports[UART_SMC2].smcup =
(smc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SMC2];
+ *(u16 *)(&cpm2_immr->im_dprambase[PROFF_SMC2_BASE]) = PROFF_SMC2;
cpm_uart_ports[UART_SMC2].port.mapbase =
(unsigned long)&cpm2_immr->im_smc[1];
cpm_uart_ports[UART_SMC2].smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox