LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* 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, &reg16);
+	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, &reg16);
+	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,
> &reg16);
> + 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,
> &reg16);
> + 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, &reg16);
+	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, &reg16);
+	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, &reg16);
+ 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, &reg16);
+ 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,
> &reg16);
> +    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,
> &reg16);
> +    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


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox