* Re: [PATCH 02/10] powerpc: Consolidate mpic_alloc() OF address translation
From: Paul Mackerras @ 2011-12-01 1:04 UTC (permalink / raw)
To: Kyle Moffett; +Cc: linuxppc-dev
In-Reply-To: <1322593117-29938-3-git-send-email-Kyle.D.Moffett@boeing.com>
On Tue, Nov 29, 2011 at 01:58:29PM -0500, Kyle Moffett wrote:
> diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
> index 901bfbd..44f9774 100644
> --- a/arch/powerpc/platforms/powermac/pic.c
> +++ b/arch/powerpc/platforms/powermac/pic.c
> @@ -498,15 +498,10 @@ static struct mpic * __init pmac_setup_one_mpic(struct device_node *np,
> int master)
> {
> const char *name = master ? " MPIC 1 " : " MPIC 2 ";
> - struct resource r;
> struct mpic *mpic;
> unsigned int flags = master ? MPIC_PRIMARY : 0;
> int rc;
>
> - rc = of_address_to_resource(np, 0, &r);
> - if (rc)
> - return NULL;
> -
This gets me an unused variable warning, which because we compile
arch/powerpc with -Werror is fatal:
CC arch/powerpc/platforms/powermac/pic.o
/home/paulus/kernel/kvm-merge/arch/powerpc/platforms/powermac/pic.c: In function ‘pmac_setup_one_mpic’:
/home/paulus/kernel/kvm-merge/arch/powerpc/platforms/powermac/pic.c:491:6: error: unused variable ‘rc’ [-Werror=unused-variable]
cc1: all warnings being treated as errors
Need to remove the declaration of rc as well.
Paul.
^ permalink raw reply
* Re: [PATCH 1/6] 44x/pci: Continue pci setup even if there is no sdr-base in the device-tree
From: Tony Breeds @ 2011-12-01 1:11 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: LinuxPPC-dev
In-Reply-To: <1322631973.21641.42.camel@pasglop>
[-- Attachment #1: Type: text/plain, Size: 455 bytes --]
On Wed, Nov 30, 2011 at 04:46:13PM +1100, Benjamin Herrenschmidt wrote:
> If you don't expect an sdr-base as part of the normal operations of that
> bridge, don't bring a message that makes me think something is wrong :-)
>
> Just changing the severity isn't enough. you should just remove the
> message and later on, print/warn/error out if you decide you actually
> need an sdr-base (such as in the backend).
Okay no problem.
Yours Tony
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* [PATCH] powerpc/nvram: Add spinlock to oops_to_nvram to prevent oops in compression code.
From: Anton Blanchard @ 2011-12-01 1:46 UTC (permalink / raw)
To: benh, paulus, hbabu, jkenisto; +Cc: linuxppc-dev
When issuing a system reset we almost always oops in the oops_to_nvram
code because multiple CPUs are using the deflate work area. Add a
spinlock to protect it.
To play it safe I'm using trylock to avoid locking up if the NVRAM
code oopses. This means we might miss multiple CPUs oopsing at exactly
the same time but I think it's best to play it safe for now. Once we
are happy with the reliability we can change it to a full spinlock.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: linux-build/arch/powerpc/platforms/pseries/nvram.c
===================================================================
--- linux-build.orig/arch/powerpc/platforms/pseries/nvram.c 2011-12-01 09:44:27.205568463 +1100
+++ linux-build/arch/powerpc/platforms/pseries/nvram.c 2011-12-01 12:36:49.334478156 +1100
@@ -634,6 +634,8 @@ static void oops_to_nvram(struct kmsg_du
{
static unsigned int oops_count = 0;
static bool panicking = false;
+ static DEFINE_SPINLOCK(lock);
+ unsigned long flags;
size_t text_len;
unsigned int err_type = ERR_TYPE_KERNEL_PANIC_GZ;
int rc = -1;
@@ -664,6 +666,9 @@ static void oops_to_nvram(struct kmsg_du
if (clobbering_unread_rtas_event())
return;
+ if (!spin_trylock_irqsave(&lock, flags))
+ return;
+
if (big_oops_buf) {
text_len = capture_last_msgs(old_msgs, old_len,
new_msgs, new_len, big_oops_buf, big_oops_buf_sz);
@@ -679,4 +684,6 @@ static void oops_to_nvram(struct kmsg_du
(void) nvram_write_os_partition(&oops_log_partition, oops_buf,
(int) (sizeof(*oops_len) + *oops_len), err_type, ++oops_count);
+
+ spin_unlock_irqrestore(&lock, flags);
}
^ permalink raw reply
* Re: [PATCH] powerpc/nvram: Add spinlock to oops_to_nvram to prevent oops in compression code.
From: Benjamin Herrenschmidt @ 2011-12-01 2:11 UTC (permalink / raw)
To: Anton Blanchard; +Cc: jkenisto, paulus, linuxppc-dev
In-Reply-To: <20111201124645.24c6e54f@kryten>
On Thu, 2011-12-01 at 12:46 +1100, Anton Blanchard wrote:
> When issuing a system reset we almost always oops in the oops_to_nvram
> code because multiple CPUs are using the deflate work area. Add a
> spinlock to protect it.
>
> To play it safe I'm using trylock to avoid locking up if the NVRAM
> code oopses. This means we might miss multiple CPUs oopsing at exactly
> the same time but I think it's best to play it safe for now. Once we
> are happy with the reliability we can change it to a full spinlock.
How would we miss ?
trylock does loop on stwcx. failure, it doesn't loop if the lock is
-taken-, so if the lock is only used for actually dealing with the oops
the only "miss" is because somebody already got it... or am I missing
something ?
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH] powerpc/nvram: Add spinlock to oops_to_nvram to prevent oops in compression code.
From: Anton Blanchard @ 2011-12-01 2:26 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: jkenisto, paulus, linuxppc-dev
In-Reply-To: <1322705472.3729.11.camel@pasglop>
Hi Ben,
> How would we miss ?
>
> trylock does loop on stwcx. failure, it doesn't loop if the lock is
> -taken-, so if the lock is only used for actually dealing with the
> oops the only "miss" is because somebody already got it... or am I
> missing something ?
I'm thinking of two CPUs that enter at exactly the same time either
through a system reset or an ugly bug (writing junk at 0x900 so the
decrementer exception gets an oops). Probably unlikely enough that we
don't care.
Anton
^ permalink raw reply
* Re: lmb_alloc() and page memory overlap
From: Benjamin Herrenschmidt @ 2011-12-01 4:00 UTC (permalink / raw)
To: Prashant Bhole; +Cc: linuxppc-dev
In-Reply-To: <CAD6p20evHeESH1UwpB4rg8NTxndAtQW9C1S1bpJWFLmS-rOu5w@mail.gmail.com>
On Tue, 2011-11-29 at 18:51 +0530, Prashant Bhole wrote:
> Hi,
> I am using custom 460ex board with kernel version 2.6.30.
> I noticed that page_alloc() is returning a page whose memory
> is already allocated by lmb_alloc() while unflattening the device
> tree. As per my knowledge the memory allocated by lmb_alloc()
> should be reserved till the end, right?
This should have been fixed in memblock in recent kernel, at least I
believe it is. It looks like this is caused by overlapping lmb_reserve()
at boot (or lmb_reserve() overlapping an lmb_alloc'ated region which
boils down to the same thing).
Old lmb didn't deal with that well at all and that lead to corruption of
the lmb list. We fixed that in
8f7a66051b7523108c5aefb08c6a637e54aedc47
mm/memblock: properly handle overlaps and fix error path
Which got merged in 2.6.39.
If you absolutely need to stick to 2.6.30, you can try backporting the
fix to lmb.
Cheers,
Ben.
> Some more explanation of what I observed:
>
> unflatten_device_tree() allocates memory, which will be used
> for "struct node" objects in the device tree. I obtained base
> address of allocated memory in "unsigned long base_mem"
>
> Now I executed the following code after the kernel booted properly.
>
> ---------------------------------------------------------------
> extern unsigned long mem; // lmb_alloc() memory
> struct page *test_page = virt_to_page(mem);
> struct page *new_page = NULL;
>
> while(1)
> {
> new_page = NULL;
> new_page = alloc_page(GFP_KERNEL);
> if(!new_page)
> {
> printk("Allocation failed\n");
> while(1);
> }
> if(test_page == new_page)
> {
> printk("Memory already allocated by lmb_alloc\n");
> while(1);
> }
> }
> ---------------------------------------------------------------
>
> After many page allocations, I always hit the condition (test_page == new_page).
> Am I doing anything wrong here?
> Has anybody faced this kind of problem before?
>
>
> I also noticed that lmb_dump_all() shows 2 regions overlapping (last two):
>
> LMB configuration:
> rmo_size = 0x30000000
> memory.size = 0x30000000
> memory.cnt = 0x1
> memory[0x0] 0x0000000000000000 - 0x000000002fffffff, 0x30000000 bytes
> reserved.cnt = 0x6
> reserved[0x0] 0x0000000000000000 - 0x00000000006bffff, 0x6c0000 bytes
> reserved[0x1] 0x0000000000ffa000 - 0x0000000000ffcfff, 0x3000 bytes
> reserved[0x2] 0x000000002fdd0000 - 0x000000002fddffff, 0x10000 bytes
> reserved[0x3] 0x000000002fde4000 - 0x000000002fde9fff, 0x6000 bytes
> reserved[0x4] 0x000000002fdeb060 - 0x000000002ffff768, 0x214709 bytes
> reserved[0x5] 0x000000002fdee000 - 0x000000002ffff769, 0x21176a bytes
>
>
> Thanks,
> Prashant
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
^ permalink raw reply
* Re: [PATCH 6/6] 44x/currituck: Add support for the new IBM currituck platform
From: Tony Breeds @ 2011-12-01 4:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: LinuxPPC-dev
In-Reply-To: <1322634022.21641.61.camel@pasglop>
[-- Attachment #1: Type: text/plain, Size: 4483 bytes --]
On Wed, Nov 30, 2011 at 05:20:22PM +1100, Benjamin Herrenschmidt wrote:
> On Wed, 2011-11-30 at 16:24 +1100, Tony Breeds wrote:
> > + plb {
> > + compatible = "ibm,plb-4xx", "ibm,plb4"; /* Could be PLB6, doesn't matter */
>
> Then make it plb6 and add it to the probe list. Might have to whack it's
> configuration registers one day etc...
Done.
> > + * XXX: 1 TB address space, do we really care past
> > + * 4 GB and should we expand cell width?
> > + */
>
> For OPB probably not :-)
Fixed.
> That doesn't seem like a very useful pair of statements or useful debug
> message....
All the DBG cruft is gone.
> > + for(i = 0; i < MAX_RANKS; i++){
> > + reg = mfdcrx(DDR3_MR0CF + i);
> > + printf("%s: reg=0x%08x\r\n", __func__, reg);
>
> All that debug is pretty gross, keep it if you wish but make it a bit
> neater and/or wrap it in DBG
Yeah that was an oversight.
> > + if (reg & 0x01) {
>
> if (!(reg & 1))
> continue;
>
> avoids too much indent
Done.
> > + dt_fixup_memory(0x0ULL, ibm_currituck_memsize);
>
> Ok, I see why the global... I'd still prefer if the detect function just
> returned the value and the caller whacks the global.
Fixed.
> > + while ((devp = find_node_by_devtype(devp, "pci"))) {
> > + if (getprop(devp, "dma-ranges", &dma_ranges[0], sizeof(dma_ranges)) < 0) {
>
> Can't you replace &dma_ranges[0] with just dma_ranges ?
Yes, Fixed.
> > +#define SPRN_PIR 0x11E /* Processor Indentification Register */
>
> That should go elsewhere along with the other SPR definitions.
There isn't a std. place in the bootwrapper.
>
> > +void platform_init(void)
> > +{
> > + /* Cap the zImage to 512MB */
>
> Any reason ? If yes, please document it a bit more.
XXX
> > + node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type",
> > + "cpu", sizeof("cpu"));
> > + if (!node)
> > + fatal("Cannot find cpu node\n");
>
> The above will return -a- CPU node... you have several and you don't
> know which one. You should probably iterate accross all of them.
I'm just trying to get the timebase-frequency, this willbe the same on
all CPUs (at least I hope so ;P) so I don't really care which CPU node I
get.
> > + /* FIXME: Check this works */
Grr that comment shouldn't be there. It does work :)
> > +#define PVR_476CURRITUCK 0x7ff50000
>
> My understanding is that the currituck was the platform, not the chip,
> and that the chip was called something like 476FPE, am I wrong ?
No you're correct, I was confused about the boundry between 476fpe and
currituck.
> > + cmplwi cr0,r3,PVR_476CURRITUCK@h
> > + beq head_start_47x
>
> So at some point, they gave us the magic foo to do with the PVR to
> identify any 476... I'll try to dig that out of my email archives.
Yeah I have that I'll work out the correct way to the the mask and
test.
> > +++ b/arch/powerpc/platforms/44x/ppc47x.c
>
> Call the file currituck.c
Sure.
> > +static void __devinit quirk_ppc_currituck_usb_fixup(struct pci_dev *dev)
> > +{
> > + pci_write_config_dword(dev, 0xe0, 0x0114231f);
> > + pci_write_config_dword(dev, 0xe4, 0x00006c40);
> > +}
>
> Pleae document better what you are doing here and also test
> that you are indeed on the right platform so you don't end up
> whacking bits on USB controllers on other platforms that happen
> to be compiled in the same binary.
Sure, no problem.
> Ok, I'll have to fixup that vs. Kyle patches but the good thing is that
> it will make things even simpler.
Thanks.
> Now pretty much everything in this platform file is generic I believe.
> We could move it all to ppc44x_simple.c. The only things that are not
> are the USB quirk and the interrupt fixup.
>
> The USB quirk which should have a compatible test for the platform to
> make sure we don't run it on something else. For such a simple quirk, I
> think it's fine ot have it in ppc44x_simple.c or in drivers/pci/quirk.c
>
> For the interrupt fixup, we can probably address it entirely in the
> device-tree, though that means exposing a bunch of on-board bridges
> which is only midly annoying.
>
> Anyways, we can discuss that (or maybe an even better option)
> tomorrow :-)
Okay I look forward to it :)
> Again, you are mixing the SoC with the board here. afaik, currituck is
> the board, not the SoC.
Fixed.
Yours Tony
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH 6/6] 44x/currituck: Add support for the new IBM currituck platform
From: Tony Breeds @ 2011-12-01 4:16 UTC (permalink / raw)
To: Kumar Gala; +Cc: LinuxPPC-dev
In-Reply-To: <6E90E509-7B5B-4475-A2B1-9F10FD943F4E@kernel.crashing.org>
[-- Attachment #1: Type: text/plain, Size: 229 bytes --]
On Wed, Nov 30, 2011 at 07:23:40AM -0600, Kumar Gala wrote:
> Split the board support patches from the SoC support.
Will do, as I said to Ben I was confused.
> This seems like it should be PVR_476FPE
Yup. Fixed.
Yours Tony
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: lmb_alloc() and page memory overlap
From: Prashant Bhole @ 2011-12-01 4:21 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1322712006.3729.14.camel@pasglop>
On Thu, Dec 1, 2011 at 9:30 AM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Tue, 2011-11-29 at 18:51 +0530, Prashant Bhole wrote:
>> Hi,
>> I am using custom 460ex board with kernel version 2.6.30.
>> I noticed that page_alloc() is returning a page whose memory
>> is already allocated by lmb_alloc() while unflattening the device
>> tree. As per my knowledge the memory allocated by lmb_alloc()
>> should be reserved till the end, right?
>
> This should have been fixed in memblock in recent kernel, at least I
> believe it is. It looks like this is caused by overlapping lmb_reserve()
> at boot (or lmb_reserve() overlapping an lmb_alloc'ated region which
> boils down to the same thing).
>
> Old lmb didn't deal with that well at all and that lead to corruption of
> the lmb list. We fixed that in
>
> 8f7a66051b7523108c5aefb08c6a637e54aedc47
>
> =A0 =A0mm/memblock: properly handle overlaps and fix error path
>
> Which got merged in 2.6.39.
>
> If you absolutely need to stick to 2.6.30, you can try backporting the
> fix to lmb.
>
> Cheers,
> Ben.
>
I need to stick to 2.6.30, will try backporting the fix. Is this the same t=
hing
which is causing the wrong page (already allocated memory) allocation?
>> Some more explanation of what I observed:
>>
>> unflatten_device_tree() allocates memory, which will be used
>> for "struct node" objects in the device tree. I obtained base
>> address of allocated memory in "unsigned long base_mem"
>>
>> Now I executed the following code after the kernel booted properly.
>>
>> ---------------------------------------------------------------
>> extern unsigned long mem; // lmb_alloc() memory
>> struct page *test_page =3D virt_to_page(mem);
>> struct page *new_page =3D NULL;
>>
>> while(1)
>> {
>> =A0 =A0 new_page =3D NULL;
>> =A0 =A0 new_page =3D alloc_page(GFP_KERNEL);
>> =A0 =A0 if(!new_page)
>> =A0 =A0 {
>> =A0 =A0 =A0 =A0 printk("Allocation failed\n");
>> =A0 =A0 =A0 =A0 while(1);
>> =A0 =A0 }
>> =A0 =A0 if(test_page =3D=3D new_page)
>> =A0 =A0 {
>> =A0 =A0 =A0 =A0 =A0printk("Memory already allocated by lmb_alloc\n");
>> =A0 =A0 =A0 =A0 =A0while(1);
>> =A0 =A0 }
>> }
>> ---------------------------------------------------------------
>>
>> After many page allocations, I always hit the condition (test_page =3D=
=3D new_page).
>> Am I doing anything wrong here?
>> Has anybody faced this kind of problem before?
>>
>>
>> I also noticed that lmb_dump_all() shows 2 regions overlapping (last two=
):
>>
>> LMB configuration:
>> =A0rmo_size =A0 =A0=3D 0x30000000
>> =A0memory.size =3D 0x30000000
>> =A0memory.cnt =A0=3D 0x1
>> =A0memory[0x0] =A0 =A00x0000000000000000 - 0x000000002fffffff, 0x3000000=
0 bytes
>> =A0reserved.cnt =A0=3D 0x6
>> =A0reserved[0x0] =A00x0000000000000000 - 0x00000000006bffff, 0x6c0000 by=
tes
>> =A0reserved[0x1] =A00x0000000000ffa000 - 0x0000000000ffcfff, 0x3000 byte=
s
>> =A0reserved[0x2] =A00x000000002fdd0000 - 0x000000002fddffff, 0x10000 byt=
es
>> =A0reserved[0x3] =A00x000000002fde4000 - 0x000000002fde9fff, 0x6000 byte=
s
>> =A0reserved[0x4] =A00x000000002fdeb060 - 0x000000002ffff768, 0x214709 by=
tes
>> =A0reserved[0x5] =A00x000000002fdee000 - 0x000000002ffff769, 0x21176a by=
tes
>>
>>
>> Thanks,
>> Prashant
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev@lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
>
Thanks,
Prashant
^ permalink raw reply
* Re: lmb_alloc() and page memory overlap
From: Benjamin Herrenschmidt @ 2011-12-01 4:28 UTC (permalink / raw)
To: Prashant Bhole; +Cc: linuxppc-dev
In-Reply-To: <CAD6p20eX5uq=w5JU19+-x=bAPJ9tBSDanH46n22S6SFuFXbP_Q@mail.gmail.com>
> > This should have been fixed in memblock in recent kernel, at least I
> > believe it is. It looks like this is caused by overlapping lmb_reserve()
> > at boot (or lmb_reserve() overlapping an lmb_alloc'ated region which
> > boils down to the same thing).
> >
> > Old lmb didn't deal with that well at all and that lead to corruption of
> > the lmb list. We fixed that in
> >
> > 8f7a66051b7523108c5aefb08c6a637e54aedc47
> >
> > mm/memblock: properly handle overlaps and fix error path
> >
> > Which got merged in 2.6.39.
> >
> > If you absolutely need to stick to 2.6.30, you can try backporting the
> > fix to lmb.
> >
> > Cheers,
> > Ben.
> >
>
> I need to stick to 2.6.30, will try backporting the fix. Is this the same thing
> which is causing the wrong page (already allocated memory) allocation?
I can't say for sure but it looks like it could be.
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH 6/6] 44x/currituck: Add support for the new IBM currituck platform
From: Tony Breeds @ 2011-12-01 4:29 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Josh Boyer, LinuxPPC-dev
In-Reply-To: <20111201040524.GF15560@thor.bakeyournoodle.com>
[-- Attachment #1: Type: text/plain, Size: 599 bytes --]
On Thu, Dec 01, 2011 at 03:05:24PM +1100, Tony Breeds wrote:
> On Wed, Nov 30, 2011 at 05:20:22PM +1100, Benjamin Herrenschmidt wrote:
> > On Wed, 2011-11-30 at 16:24 +1100, Tony Breeds wrote:
<snip>
> > > +void platform_init(void)
> > > +{
> > > + /* Cap the zImage to 512MB */
> >
> > Any reason ? If yes, please document it a bit more.
>
> XXX
Where 'XXX' means come back and anser this point /before/ hitting send.
Basically is was lazyness.
Now that I know the memsize I'll allow the zImage to use it all but
512MB should be enought for anywone right?
Yours Tony
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* ppc4xx simple vs SoC's
From: Benjamin Herrenschmidt @ 2011-12-01 5:39 UTC (permalink / raw)
To: Josh Boyer; +Cc: linuxppc-dev
Hi Josh !
I was helping Tony with some of the Currituck stuff when I noticed an
oddity...
So we have various "SoC" config symbols such as 440EP, 460SX, etc...
that in turn select various bits & pieces that enable support for that
SoC (such as EMAC4 support or FPU support). Those only act as "enables"
for compiling of the code, there is still going to be a runtime check of
course.
Those SoC config symbols are not user selectable, they are meant to be
themselves select'ed by the board Kconfig entries.
However, the entry for ppc44x_simple doesn't select any of these,
meaning for example, AFAIK, that you don't get EMAC4 etc... I'm
surprised things work at all !
What am I missing ?
Cheers,
Ben.
^ permalink raw reply
* [PATCH] powerpc/fsl-pci: Allow 64-bit PCIe devices to DMA to any memory address
From: Kumar Gala @ 2011-12-01 6:03 UTC (permalink / raw)
To: linuxppc-dev
There is an issue on FSL-BookE 64-bit devices (P5020) in which PCIe
devices that are capable of doing 64-bit DMAs (like an Intel e1000) do
not function and crash the kernel if we have >4G of memory in the system.
The reason is that the existing code only sets up one inbound window for
access to system memory across PCIe. That window is limited to a 32-bit
address space. So on systems we'll end up utilizing SWIOTLB for dma
mappings. However SWIOTLB dma ops implement dma_alloc_coherent() as
dma_direct_alloc_coherent(). Thus we can end up with dma addresses that
are not accessible because of the inbound window limitation.
We could possibly set the SWIOTLB alloc_coherent op to
swiotlb_alloc_coherent() however that does not address the issue since
the swiotlb_alloc_coherent() will behave almost identical to
dma_direct_alloc_coherent() since the devices coherent_dma_mask will be
greater than any address allocated by swiotlb_alloc_coherent() and thus
we'll never bounce buffer it into a range that would be dma-able.
The easiest and best solution is to just make it so that a 64-bit
capable device is able to DMA to any internal system address.
We accomplish this by opening up a second inbound window that maps all
of memory above the internal SoC address width so we can set it up to
access all of the internal SoC address space if needed.
We than fixup the dma_ops and dma_offset for PCIe devices with a dma
mask greater than the maximum internal SoC address.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
arch/powerpc/sysdev/fsl_pci.c | 55 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 55 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 4ce547e..8f92446 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -65,6 +65,30 @@ static int __init fsl_pcie_check_link(struct pci_controller *hose)
}
#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
+
+#define MAX_PHYS_ADDR_BITS 40
+static u64 pci64_dma_offset = 1ull << MAX_PHYS_ADDR_BITS;
+
+static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
+{
+ if (!dev->dma_mask || !dma_supported(dev, dma_mask))
+ return -EIO;
+
+ /*
+ * Fixup PCI devices that are able to DMA to above the physical
+ * address width of the SoC such that we can address any internal
+ * SoC address from across PCI if needed
+ */
+ if ((dev->bus == &pci_bus_type) &&
+ dma_mask >= DMA_BIT_MASK(MAX_PHYS_ADDR_BITS)) {
+ set_dma_ops(dev, &dma_direct_ops);
+ set_dma_offset(dev, pci64_dma_offset);
+ }
+
+ *dev->dma_mask = dma_mask;
+ return 0;
+}
+
static int __init setup_one_atmu(struct ccsr_pci __iomem *pci,
unsigned int index, const struct resource *res,
resource_size_t offset)
@@ -228,6 +252,37 @@ static void __init setup_pci_atmu(struct pci_controller *hose,
hose->dma_window_base_cur = 0x00000000;
hose->dma_window_size = (resource_size_t)sz;
+
+ /*
+ * if we have >4G of memory setup second PCI inbound window to
+ * let devices that are 64-bit address capable to work w/o
+ * SWIOTLB and access the full range of memory
+ */
+ if (sz != mem) {
+ mem_log = __ilog2_u64(mem);
+
+ /* Size window up if we dont fit in exact power-of-2 */
+ if ((1ull << mem_log) != mem)
+ mem_log++;
+
+ piwar = (piwar & ~PIWAR_SZ_MASK) | (mem_log - 1);
+
+ /* Setup inbound memory window */
+ out_be32(&pci->piw[win_idx].pitar, 0x00000000);
+ out_be32(&pci->piw[win_idx].piwbear,
+ pci64_dma_offset >> 44);
+ out_be32(&pci->piw[win_idx].piwbar,
+ pci64_dma_offset >> 12);
+ out_be32(&pci->piw[win_idx].piwar, piwar);
+
+ /*
+ * install our own dma_set_mask handler to fixup dma_ops
+ * and dma_offset
+ */
+ ppc_md.dma_set_mask = fsl_pci_dma_set_mask;
+
+ pr_info("%s: Setup 64-bit PCI DMA window\n", name);
+ }
} else {
u64 paddr = 0;
--
1.7.3.4
^ permalink raw reply related
* Re: [PATCH 07/10] powerpc/mpic: Don't open-code dcr_resource_start
From: Michael Ellerman @ 2011-12-01 6:58 UTC (permalink / raw)
To: Kyle Moffett; +Cc: linuxppc-dev
In-Reply-To: <1322593117-29938-8-git-send-email-Kyle.D.Moffett@boeing.com>
On Tue, 2011-11-29 at 13:58 -0500, Kyle Moffett wrote:
> Don't open-code the OpenFirmware "dcr-reg" property lookup trying to map
> DCR resources. This makes the code a bit easier to read.
>
> Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com>
> ---
> arch/powerpc/sysdev/mpic.c | 7 ++-----
> 1 files changed, 2 insertions(+), 5 deletions(-)
>
> diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
> index e0216ff..6916ba5 100644
> --- a/arch/powerpc/sysdev/mpic.c
> +++ b/arch/powerpc/sysdev/mpic.c
> @@ -319,11 +319,8 @@ static void _mpic_map_dcr(struct mpic *mpic, struct device_node *node,
> struct mpic_reg_bank *rb,
> unsigned int offset, unsigned int size)
> {
> - const u32 *dbasep;
> -
> - dbasep = of_get_property(node, "dcr-reg", NULL);
> -
> - rb->dhost = dcr_map(node, *dbasep + offset, size);
> + phys_addr_t phys_addr = dcr_resource_start(node);
Gives me:
arch/powerpc/sysdev/mpic.c:321: error: too few arguments to function 'dcr_resource_start'
Because you're missing index:
unsigned int dcr_resource_start(const struct device_node *np, unsigned int index)
cheers
--
^ permalink raw reply
* Re: [PATCH 10/10] powerpc/mpic: Add in-core support for cascaded MPICs
From: Michael Ellerman @ 2011-12-01 6:59 UTC (permalink / raw)
To: Kyle Moffett; +Cc: linuxppc-dev
In-Reply-To: <1322593117-29938-11-git-send-email-Kyle.D.Moffett@boeing.com>
On Tue, 2011-11-29 at 13:58 -0500, Kyle Moffett wrote:
> diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
> index cd00ca8..a0f5d28 100644
> --- a/arch/powerpc/platforms/cell/setup.c
> +++ b/arch/powerpc/platforms/cell/setup.c
> @@ -215,15 +202,6 @@ static void __init mpic_init_IRQ(void)
> if (mpic == NULL)
> continue;
> mpic_init(mpic);
> -
> - virq = irq_of_parse_and_map(dn, 0);
> - if (virq == NO_IRQ)
> - continue;
> -
> - printk(KERN_INFO "%s : hooking up to IRQ %d\n",
> - dn->full_name, virq);
> - irq_set_handler_data(virq, mpic);
> - irq_set_chained_handler(virq, cell_mpic_cascade);
> }
> }
This leaves virq unused, which breaks the build.
cheers
--
^ permalink raw reply
* Add support for the currituck 476 platform from IBM (v2)
From: Tony Breeds @ 2011-12-01 7:39 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Josh Boyer; +Cc: LinuxPPC-dev
Patches 1 to 3
Modify the 44x PCI code to work with 476fpe/currituck.
Patch 4
Is an old patch by Christoph Egger that fell through the cracks somehow.
Patches 5 and 6
Modify the bootwrapper to handle 476fpe/currituck
Patch 7
The SoC support.
Patch 8
The currituck board support.
^ permalink raw reply
* [PATCH 1/8] 44x/pci: Use PCI_BASE_ADDRESS_MEM_PREFETCH rather than magic value.
From: Tony Breeds @ 2011-12-01 7:39 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Josh Boyer; +Cc: LinuxPPC-dev
In-Reply-To: <1322725164-4391-1-git-send-email-tony@bakeyournoodle.com>
Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>
---
arch/powerpc/sysdev/ppc4xx_pci.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
This patch was somehow missed from the original series.
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index 862f11b..16f5eba 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -1739,7 +1739,7 @@ static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port,
/* Calculate window size */
sa = (0xffffffffffffffffull << ilog2(size));
if (res->flags & IORESOURCE_PREFETCH)
- sa |= 0x8;
+ sa |= PCI_BASE_ADDRESS_MEM_PREFETCH;
if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx"))
sa |= PCI_BASE_ADDRESS_MEM_TYPE_64;
--
1.7.6.4
^ permalink raw reply related
* [PATCH 2/8] 44x/pci: Add a want_sdr flag into ppc4xx_pciex_hwops
From: Tony Breeds @ 2011-12-01 7:39 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Josh Boyer; +Cc: LinuxPPC-dev
In-Reply-To: <1322725164-4391-1-git-send-email-tony@bakeyournoodle.com>
Currituck doesn't need nor use SDR so aborting the pci setup if there is
no sdr-base would be bad.
Add a flag to ppc4xx_pciex_hwops for the backends to state if they need
SDR and then only complain and abort if they do and it's not found in
the device tree.
Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>
---
arch/powerpc/sysdev/ppc4xx_pci.c | 20 ++++++++++++++------
1 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index 16f5eba..ab3293a 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -647,6 +647,7 @@ static unsigned int ppc4xx_pciex_port_count;
struct ppc4xx_pciex_hwops
{
+ bool want_sdr;
int (*core_init)(struct device_node *np);
int (*port_init_hw)(struct ppc4xx_pciex_port *port);
int (*setup_utl)(struct ppc4xx_pciex_port *port);
@@ -916,6 +917,7 @@ static int ppc440speB_pciex_init_utl(struct ppc4xx_pciex_port *port)
static struct ppc4xx_pciex_hwops ppc440speA_pcie_hwops __initdata =
{
+ .want_sdr = true,
.core_init = ppc440spe_pciex_core_init,
.port_init_hw = ppc440speA_pciex_init_port_hw,
.setup_utl = ppc440speA_pciex_init_utl,
@@ -924,6 +926,7 @@ static struct ppc4xx_pciex_hwops ppc440speA_pcie_hwops __initdata =
static struct ppc4xx_pciex_hwops ppc440speB_pcie_hwops __initdata =
{
+ .want_sdr = true,
.core_init = ppc440spe_pciex_core_init,
.port_init_hw = ppc440speB_pciex_init_port_hw,
.setup_utl = ppc440speB_pciex_init_utl,
@@ -1034,6 +1037,7 @@ static int ppc460ex_pciex_init_utl(struct ppc4xx_pciex_port *port)
static struct ppc4xx_pciex_hwops ppc460ex_pcie_hwops __initdata =
{
+ .want_sdr = true,
.core_init = ppc460ex_pciex_core_init,
.port_init_hw = ppc460ex_pciex_init_port_hw,
.setup_utl = ppc460ex_pciex_init_utl,
@@ -1181,6 +1185,7 @@ done:
}
static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = {
+ .want_sdr = true,
.core_init = ppc460sx_pciex_core_init,
.port_init_hw = ppc460sx_pciex_init_port_hw,
.setup_utl = ppc460sx_pciex_init_utl,
@@ -1276,6 +1281,7 @@ static int ppc405ex_pciex_init_utl(struct ppc4xx_pciex_port *port)
static struct ppc4xx_pciex_hwops ppc405ex_pcie_hwops __initdata =
{
+ .want_sdr = true,
.core_init = ppc405ex_pciex_core_init,
.port_init_hw = ppc405ex_pciex_init_port_hw,
.setup_utl = ppc405ex_pciex_init_utl,
@@ -1972,13 +1978,15 @@ static void __init ppc4xx_probe_pciex_bridge(struct device_node *np)
}
port->node = of_node_get(np);
- pval = of_get_property(np, "sdr-base", NULL);
- if (pval == NULL) {
- printk(KERN_ERR "PCIE: missing sdr-base for %s\n",
- np->full_name);
- return;
+ if (ppc4xx_pciex_hwops->want_sdr == true) {
+ pval = of_get_property(np, "sdr-base", NULL);
+ if (pval == NULL) {
+ printk(KERN_ERR "PCIE: missing sdr-base for %s\n",
+ np->full_name);
+ return;
+ }
+ port->sdr_base = *pval;
}
- port->sdr_base = *pval;
/* Check if device_type property is set to "pci" or "pci-endpoint".
* Resulting from this setup this PCIe port will be configured
--
1.7.6.4
^ permalink raw reply related
* [PATCH 3/8] 44x/pci: Setup the dma_window properties for each pci_controller
From: Tony Breeds @ 2011-12-01 7:39 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Josh Boyer; +Cc: LinuxPPC-dev
In-Reply-To: <1322725164-4391-1-git-send-email-tony@bakeyournoodle.com>
Needed if you want to use swiotlb, harmless otherwise.
Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>
---
arch/powerpc/sysdev/ppc4xx_pci.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index ab3293a..45148ef 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -185,9 +185,15 @@ static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose,
out:
dma_offset_set = 1;
pci_dram_offset = res->start;
+ hose->dma_window_base_cur = res->start;
+ hose->dma_window_size = resource_size(res);
printk(KERN_INFO "4xx PCI DMA offset set to 0x%08lx\n",
pci_dram_offset);
+ printk(KERN_INFO "4xx PCI DMA window base to 0x%016llx\n",
+ (unsigned long long)hose->dma_window_base_cur);
+ printk(KERN_INFO "DMA window size 0x%016llx\n",
+ (unsigned long long)hose->dma_window_size);
return 0;
}
--
1.7.6.4
^ permalink raw reply related
* [PATCH 4/8] 44x: Removing dead CONFIG_PPC47x
From: Tony Breeds @ 2011-12-01 7:39 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Josh Boyer; +Cc: LinuxPPC-dev
In-Reply-To: <1322725164-4391-1-git-send-email-tony@bakeyournoodle.com>
From: Christoph Egger <siccegge@cs.fau.de>
CONFIG_PPC47x doesn't exist in Kconfig and no 476 processor calls this
function ppc44x_pin_tlb() as it has it's own ppc47x_pin_tlb().
This code is probably an artifact of the original 476 code that
shouldn't have made it upstream.
Signed-off-by: Christoph Egger <siccegge@cs.fau.de>
Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>
---
arch/powerpc/mm/44x_mmu.c | 4 ----
1 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/mm/44x_mmu.c b/arch/powerpc/mm/44x_mmu.c
index f60e006..5d4e3ff 100644
--- a/arch/powerpc/mm/44x_mmu.c
+++ b/arch/powerpc/mm/44x_mmu.c
@@ -78,11 +78,7 @@ static void __init ppc44x_pin_tlb(unsigned int virt, unsigned int phys)
"tlbwe %1,%3,%5\n"
"tlbwe %0,%3,%6\n"
:
-#ifdef CONFIG_PPC47x
- : "r" (PPC47x_TLB2_S_RWX),
-#else
: "r" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G),
-#endif
"r" (phys),
"r" (virt | PPC44x_TLB_VALID | PPC44x_TLB_256M),
"r" (entry),
--
1.7.6.4
^ permalink raw reply related
* [PATCH 5/8] powerpc/boot: Add extended precision shifts to the boot wrapper.
From: Tony Breeds @ 2011-12-01 7:39 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Josh Boyer; +Cc: LinuxPPC-dev
In-Reply-To: <1322725164-4391-1-git-send-email-tony@bakeyournoodle.com>
The upcomming currituck patches will need to do 64-bit shifts which will
fail with undefined symbol without this patch.
I looked at linking against libgcc but we can't guarantee that libgcc
was compiled with soft-float. Also Using ../lib/div64.S or
../kernel/misc_32.S, this will break the build as the .o's need to be
built with different flags for the bootwrapper vs the kernel. So for
now the easyest option is to just copy code from
arch/powerpc/kernel/misc_32.S I don't think this code changes too often ;P
Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>
---
arch/powerpc/boot/div64.S | 52 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 52 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/boot/div64.S b/arch/powerpc/boot/div64.S
index d271ab5..bbcb8a4 100644
--- a/arch/powerpc/boot/div64.S
+++ b/arch/powerpc/boot/div64.S
@@ -57,3 +57,55 @@ __div64_32:
stw r8,4(r3)
mr r3,r6 # return the remainder in r3
blr
+
+/*
+ * Extended precision shifts.
+ *
+ * Updated to be valid for shift counts from 0 to 63 inclusive.
+ * -- Gabriel
+ *
+ * R3/R4 has 64 bit value
+ * R5 has shift count
+ * result in R3/R4
+ *
+ * ashrdi3: arithmetic right shift (sign propagation)
+ * lshrdi3: logical right shift
+ * ashldi3: left shift
+ */
+ .globl __ashrdi3
+__ashrdi3:
+ subfic r6,r5,32
+ srw r4,r4,r5 # LSW = count > 31 ? 0 : LSW >> count
+ addi r7,r5,32 # could be xori, or addi with -32
+ slw r6,r3,r6 # t1 = count > 31 ? 0 : MSW << (32-count)
+ rlwinm r8,r7,0,32 # t3 = (count < 32) ? 32 : 0
+ sraw r7,r3,r7 # t2 = MSW >> (count-32)
+ or r4,r4,r6 # LSW |= t1
+ slw r7,r7,r8 # t2 = (count < 32) ? 0 : t2
+ sraw r3,r3,r5 # MSW = MSW >> count
+ or r4,r4,r7 # LSW |= t2
+ blr
+
+ .globl __ashldi3
+__ashldi3:
+ subfic r6,r5,32
+ slw r3,r3,r5 # MSW = count > 31 ? 0 : MSW << count
+ addi r7,r5,32 # could be xori, or addi with -32
+ srw r6,r4,r6 # t1 = count > 31 ? 0 : LSW >> (32-count)
+ slw r7,r4,r7 # t2 = count < 32 ? 0 : LSW << (count-32)
+ or r3,r3,r6 # MSW |= t1
+ slw r4,r4,r5 # LSW = LSW << count
+ or r3,r3,r7 # MSW |= t2
+ blr
+
+ .globl __lshrdi3
+__lshrdi3:
+ subfic r6,r5,32
+ srw r4,r4,r5 # LSW = count > 31 ? 0 : LSW >> count
+ addi r7,r5,32 # could be xori, or addi with -32
+ slw r6,r3,r6 # t1 = count > 31 ? 0 : MSW << (32-count)
+ srw r7,r3,r7 # t2 = count < 32 ? 0 : MSW >> (count-32)
+ or r4,r4,r6 # LSW |= t1
+ srw r3,r3,r5 # MSW = MSW >> count
+ or r4,r4,r7 # LSW |= t2
+ blr
--
1.7.6.4
^ permalink raw reply related
* [PATCH 6/8] powerpc/boot: Add mfdcrx
From: Tony Breeds @ 2011-12-01 7:39 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Josh Boyer; +Cc: LinuxPPC-dev
In-Reply-To: <1322725164-4391-1-git-send-email-tony@bakeyournoodle.com>
Needed for currituck support.
Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>
---
arch/powerpc/boot/dcr.h | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
I chose to use a #define to keep with the style of m[tf]dcr in the same file.
diff --git a/arch/powerpc/boot/dcr.h b/arch/powerpc/boot/dcr.h
index 645a7c9..cc73f7a 100644
--- a/arch/powerpc/boot/dcr.h
+++ b/arch/powerpc/boot/dcr.h
@@ -9,6 +9,12 @@
})
#define mtdcr(rn, val) \
asm volatile("mtdcr %0,%1" : : "i"(rn), "r"(val))
+#define mfdcrx(rn) \
+ ({ \
+ unsigned long rval; \
+ asm volatile("mfdcrx %0,%1" : "=r"(rval) : "r"(rn)); \
+ rval; \
+ })
/* 440GP/440GX SDRAM controller DCRs */
#define DCRN_SDRAM0_CFGADDR 0x010
--
1.7.6.4
^ permalink raw reply related
* [PATCH 7/8] 44x/476fpe: Add 476fpe SoC code
From: Tony Breeds @ 2011-12-01 7:39 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Josh Boyer; +Cc: LinuxPPC-dev
In-Reply-To: <1322725164-4391-1-git-send-email-tony@bakeyournoodle.com>
Based on original work by David 'Shaggy' Kliekamp.
Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>
---
arch/powerpc/include/asm/reg.h | 1 +
arch/powerpc/kernel/cputable.c | 14 +++++++++
arch/powerpc/kernel/head_44x.S | 2 +
arch/powerpc/platforms/44x/Kconfig | 4 ++
arch/powerpc/sysdev/ppc4xx_pci.c | 57 +++++++++++++++++++++++++++++++++++-
arch/powerpc/sysdev/ppc4xx_pci.h | 7 ++++
6 files changed, 84 insertions(+), 1 deletions(-)
I wimped out on doing the mask and test opperations in head_44x.S for the
generic 476 PVR.
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 559da19..7fdc2c0 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -951,6 +951,7 @@
#define PVR_403GCX 0x00201400
#define PVR_405GP 0x40110000
#define PVR_476 0x11a52000
+#define PVR_476FPE 0x7ff50000
#define PVR_STB03XXX 0x40310000
#define PVR_NP405H 0x41410000
#define PVR_NP405L 0x41610000
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index edae5bb..7797ae2 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -1830,6 +1830,20 @@ static struct cpu_spec __initdata cpu_specs[] = {
.machine_check = machine_check_47x,
.platform = "ppc470",
},
+ { /* 476fpe */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x7ff50000,
+ .cpu_name = "476fpe",
+ .cpu_features = CPU_FTRS_47X | CPU_FTR_476_DD2,
+ .cpu_user_features = COMMON_USER_BOOKE |
+ PPC_FEATURE_HAS_FPU,
+ .mmu_features = MMU_FTR_TYPE_47x |
+ MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL,
+ .icache_bsize = 32,
+ .dcache_bsize = 128,
+ .machine_check = machine_check_47x,
+ .platform = "ppc470",
+ },
{ /* 476 iss */
.pvr_mask = 0xffff0000,
.pvr_value = 0x00050000,
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index b725dab..bb7a9c7 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -732,6 +732,8 @@ _GLOBAL(init_cpu_state)
/* We use the PVR to differenciate 44x cores from 476 */
mfspr r3,SPRN_PVR
srwi r3,r3,16
+ cmplwi cr0,r3,PVR_476FPE@h
+ beq head_start_47x
cmplwi cr0,r3,PVR_476@h
beq head_start_47x
cmplwi cr0,r3,PVR_476_ISS@h
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
index 762322c..f0be6e0 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -308,6 +308,10 @@ config 460SX
select IBM_EMAC_ZMII
select IBM_EMAC_TAH
+config 476FPE
+ bool
+ select PPC_FPU
+
config APM821xx
bool
select PPC_FPU
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index 45148ef..ae15e6f 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -1296,6 +1296,52 @@ static struct ppc4xx_pciex_hwops ppc405ex_pcie_hwops __initdata =
#endif /* CONFIG_40x */
+#ifdef CONFIG_476FPE
+static int __init ppc_476fpe_pciex_core_init(struct device_node *np)
+{
+ return 4;
+}
+
+static void __init ppc_476fpe_pciex_check_link(struct ppc4xx_pciex_port *port)
+{
+ u32 timeout_ms = 20;
+ u32 val = 0, mask = (PECFG_TLDLP_LNKUP|PECFG_TLDLP_PRESENT);
+ void __iomem *mbase = ioremap(port->cfg_space.start + 0x10000000,
+ 0x1000);
+
+ printk(KERN_INFO "PCIE%d: Checking link...\n", port->index);
+
+ if (mbase == NULL) {
+ printk(KERN_WARNING "PCIE%d: failed to get cfg space\n",
+ port->index);
+ return;
+ }
+
+ while (timeout_ms--) {
+ val = in_le32(mbase + PECFG_TLDLP);
+
+ if ((val & mask) == mask)
+ break;
+ msleep(10);
+ }
+
+ if (val & PECFG_TLDLP_PRESENT) {
+ printk(KERN_INFO "PCIE%d: link is up !\n", port->index);
+ port->link = 1;
+ } else
+ printk(KERN_WARNING "PCIE%d: Link up failed\n", port->index);
+
+ iounmap(mbase);
+ return;
+}
+
+static struct ppc4xx_pciex_hwops ppc_476fpe_pcie_hwops __initdata =
+{
+ .core_init = ppc_476fpe_pciex_core_init,
+ .check_link = ppc_476fpe_pciex_check_link,
+};
+#endif /* CONFIG_476FPE */
+
/* Check that the core has been initied and if not, do it */
static int __init ppc4xx_pciex_check_core_init(struct device_node *np)
{
@@ -1321,6 +1367,10 @@ static int __init ppc4xx_pciex_check_core_init(struct device_node *np)
if (of_device_is_compatible(np, "ibm,plb-pciex-405ex"))
ppc4xx_pciex_hwops = &ppc405ex_pcie_hwops;
#endif
+#ifdef CONFIG_476FPE
+ if (of_device_is_compatible(np, "ibm,plb-pciex-476fpe"))
+ ppc4xx_pciex_hwops = &ppc_476fpe_pcie_hwops;
+#endif
if (ppc4xx_pciex_hwops == NULL) {
printk(KERN_WARNING "PCIE: unknown host type %s\n",
np->full_name);
@@ -1629,6 +1679,10 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port,
dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL,
sa | DCRO_PEGPL_460SX_OMR1MSKL_UOT
| DCRO_PEGPL_OMRxMSKL_VAL);
+ else if (of_device_is_compatible(port->node, "ibm,plb-pciex-476fpe"))
+ dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL,
+ sa | DCRO_PEGPL_476FPE_OMR1MSKL_UOT
+ | DCRO_PEGPL_OMRxMSKL_VAL);
else
dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL,
sa | DCRO_PEGPL_OMR1MSKL_UOT
@@ -1753,7 +1807,8 @@ static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port,
if (res->flags & IORESOURCE_PREFETCH)
sa |= PCI_BASE_ADDRESS_MEM_PREFETCH;
- if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx"))
+ if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx") ||
+ of_device_is_compatible(port->node, "ibm,plb-pciex-476fpe"))
sa |= PCI_BASE_ADDRESS_MEM_TYPE_64;
out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa));
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.h b/arch/powerpc/sysdev/ppc4xx_pci.h
index 32ce763..bb48219 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.h
+++ b/arch/powerpc/sysdev/ppc4xx_pci.h
@@ -476,6 +476,13 @@
#define DCRO_PEGPL_OMR1MSKL_UOT 0x00000002
#define DCRO_PEGPL_OMR3MSKL_IO 0x00000002
+/* 476FPE */
+#define PCCFG_LCPA 0x270
+#define PECFG_TLDLP 0x3F8
+#define PECFG_TLDLP_LNKUP 0x00000008
+#define PECFG_TLDLP_PRESENT 0x00000010
+#define DCRO_PEGPL_476FPE_OMR1MSKL_UOT 0x00000004
+
/* SDR Bit Mappings */
#define PESDRx_RCSSET_HLDPLB 0x10000000
#define PESDRx_RCSSET_RSTGU 0x01000000
--
1.7.6.4
^ permalink raw reply related
* [PATCH 8/8] 44x/currituck: Add support for the new IBM currituck platform
From: Tony Breeds @ 2011-12-01 7:39 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Josh Boyer; +Cc: LinuxPPC-dev
In-Reply-To: <1322725164-4391-1-git-send-email-tony@bakeyournoodle.com>
Based on original work by David 'Shaggy' Kliekamp.
Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>
---
arch/powerpc/boot/Makefile | 5 +-
arch/powerpc/boot/dts/currituck.dts | 237 ++++++++++++++++++++++++++
arch/powerpc/boot/treeboot-currituck.c | 119 +++++++++++++
arch/powerpc/boot/wrapper | 3 +
arch/powerpc/configs/44x/currituck_defconfig | 110 ++++++++++++
arch/powerpc/platforms/44x/Kconfig | 10 +
arch/powerpc/platforms/44x/Makefile | 1 +
arch/powerpc/platforms/44x/currituck.c | 204 ++++++++++++++++++++++
8 files changed, 688 insertions(+), 1 deletions(-)
create mode 100644 arch/powerpc/boot/dts/currituck.dts
create mode 100644 arch/powerpc/boot/treeboot-currituck.c
create mode 100644 arch/powerpc/configs/44x/currituck_defconfig
create mode 100644 arch/powerpc/platforms/44x/currituck.c
Much of the currituck.c code could go into ppc44x_simple.c but that makes
finding a home for the quirk code harder. We can always move it there later.
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 72ee8c1..ff0057f 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -45,6 +45,7 @@ $(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=405
$(obj)/cuboot-acadia.o: BOOTCFLAGS += -mcpu=405
$(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405
$(obj)/treeboot-iss4xx.o: BOOTCFLAGS += -mcpu=405
+$(obj)/treeboot-currituck.o: BOOTCFLAGS += -mcpu=405
$(obj)/virtex405-head.o: BOOTAFLAGS += -mcpu=405
@@ -79,7 +80,8 @@ src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c
cuboot-warp.c cuboot-85xx-cpm2.c cuboot-yosemite.c simpleboot.c \
virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c \
cuboot-acadia.c cuboot-amigaone.c cuboot-kilauea.c \
- gamecube-head.S gamecube.c wii-head.S wii.c treeboot-iss4xx.c
+ gamecube-head.S gamecube.c wii-head.S wii.c treeboot-iss4xx.c \
+ treeboot-currituck.c
src-boot := $(src-wlib) $(src-plat) empty.c
src-boot := $(addprefix $(obj)/, $(src-boot))
@@ -212,6 +214,7 @@ image-$(CONFIG_WARP) += cuImage.warp
image-$(CONFIG_YOSEMITE) += cuImage.yosemite
image-$(CONFIG_ISS4xx) += treeImage.iss4xx \
treeImage.iss4xx-mpic
+image-$(CONFIG_CURRITUCK) += treeImage.currituck
# Board ports in arch/powerpc/platform/8xx/Kconfig
image-$(CONFIG_MPC86XADS) += cuImage.mpc866ads
diff --git a/arch/powerpc/boot/dts/currituck.dts b/arch/powerpc/boot/dts/currituck.dts
new file mode 100644
index 0000000..b801dd0
--- /dev/null
+++ b/arch/powerpc/boot/dts/currituck.dts
@@ -0,0 +1,237 @@
+/*
+ * Device Tree Source for IBM Embedded PPC 476 Platform
+ *
+ * Copyright © 2011 Tony Breeds IBM Corporation
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+/memreserve/ 0x01f00000 0x00100000; // spin table
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ model = "ibm,currituck";
+ compatible = "ibm,currituck";
+ dcr-parent = <&{/cpus/cpu@0}>;
+
+ aliases {
+ serial0 = &UART0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ model = "PowerPC,476";
+ reg = <0>;
+ clock-frequency = <1600000000>; // 1.6 GHz
+ timebase-frequency = <100000000>; // 100Mhz
+ i-cache-line-size = <32>;
+ d-cache-line-size = <32>;
+ i-cache-size = <32768>;
+ d-cache-size = <32768>;
+ dcr-controller;
+ dcr-access-method = "native";
+ status = "ok";
+ };
+ cpu@1 {
+ device_type = "cpu";
+ model = "PowerPC,476";
+ reg = <1>;
+ clock-frequency = <1600000000>; // 1.6 GHz
+ timebase-frequency = <100000000>; // 100Mhz
+ i-cache-line-size = <32>;
+ d-cache-line-size = <32>;
+ i-cache-size = <32768>;
+ d-cache-size = <32768>;
+ dcr-controller;
+ dcr-access-method = "native";
+ status = "disabled";
+ enable-method = "spin-table";
+ cpu-release-addr = <0x0 0x01f00000>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x0>; // filled in by zImage
+ };
+
+ MPIC: interrupt-controller {
+ compatible = "chrp,open-pic";
+ interrupt-controller;
+ dcr-reg = <0xffc00000 0x00040000>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+
+ };
+
+ plb {
+ compatible = "ibm,plb6";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ clock-frequency = <200000000>; // 200Mhz
+
+ POB0: opb {
+ compatible = "ibm,opb-4xx", "ibm,opb";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ /* Wish there was a nicer way of specifying a full
+ * 32-bit range
+ */
+ ranges = <0x00000000 0x00000200 0x00000000 0x80000000
+ 0x80000000 0x00000200 0x80000000 0x80000000>;
+ clock-frequency = <100000000>;
+
+ UART0: serial@10000000 {
+ device_type = "serial";
+ compatible = "ns16750", "ns16550";
+ reg = <0x10000000 0x00000008>;
+ virtual-reg = <0xe1000000>;
+ clock-frequency = <1851851>; // PCIe refclk/MCGC0_CTL[UART]
+ current-speed = <115200>;
+ interrupt-parent = <&MPIC>;
+ interrupts = <34 2>;
+ };
+
+ IIC0: i2c@00000000 {
+ compatible = "ibm,iic-currituck", "ibm,iic";
+ reg = <0x0 0x00000014>;
+ interrupt-parent = <&MPIC>;
+ interrupts = <79 2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ rtc@68 {
+ compatible = "stm,m41t80", "m41st85";
+ reg = <0x68>;
+ };
+ };
+ };
+
+ PCIE0: pciex@10100000000 { // 4xGBIF1
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ compatible = "ibm,plb-pciex-476fpe", "ibm,plb-pciex";
+ primary;
+ port = <0x0>; /* port number */
+ reg = <0x00000101 0x00000000 0x0 0x10000000 /* Config space access */
+ 0x00000100 0x00000000 0x0 0x00001000>; /* UTL Registers space access */
+ dcr-reg = <0x80 0x20>;
+
+// pci_space < pci_addr > < cpu_addr > < size >
+ ranges = <0x02000000 0x00000000 0x80000000 0x00000110 0x80000000 0x0 0x80000000
+ 0x01000000 0x0 0x0 0x00000140 0x0 0x0 0x00010000>;
+
+ /* Inbound starting at 0 to memsize filled in by zImage */
+ dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x0>;
+
+ /* This drives busses 0 to 0xf */
+ bus-range = <0x0 0xf>;
+
+ /* Legacy interrupts (note the weird polarity, the bridge seems
+ * to invert PCIe legacy interrupts).
+ * We are de-swizzling here because the numbers are actually for
+ * port of the root complex virtual P2P bridge. But I want
+ * to avoid putting a node for it in the tree, so the numbers
+ * below are basically de-swizzled numbers.
+ * The real slot is on idsel 0, so the swizzling is 1:1
+ */
+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+ interrupt-map = <
+ 0x0 0x0 0x0 0x1 &MPIC 46 0x2 /* int A */
+ 0x0 0x0 0x0 0x2 &MPIC 47 0x2 /* int B */
+ 0x0 0x0 0x0 0x3 &MPIC 48 0x2 /* int C */
+ 0x0 0x0 0x0 0x4 &MPIC 49 0x2 /* int D */>;
+ };
+
+ PCIE1: pciex@30100000000 { // 4xGBIF0
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ compatible = "ibm,plb-pciex-476fpe", "ibm,plb-pciex";
+ primary;
+ port = <0x1>; /* port number */
+ reg = <0x00000301 0x00000000 0x0 0x10000000 /* Config space access */
+ 0x00000300 0x00000000 0x0 0x00001000>; /* UTL Registers space access */
+ dcr-reg = <0x60 0x20>;
+
+ ranges = <0x02000000 0x00000000 0x80000000 0x00000310 0x80000000 0x0 0x80000000
+ 0x01000000 0x0 0x0 0x00000340 0x0 0x0 0x00010000>;
+
+ /* Inbound starting at 0 to memsize filled in by zImage */
+ dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x0>;
+
+ /* This drives busses 0 to 0xf */
+ bus-range = <0x0 0xf>;
+
+ /* Legacy interrupts (note the weird polarity, the bridge seems
+ * to invert PCIe legacy interrupts).
+ * We are de-swizzling here because the numbers are actually for
+ * port of the root complex virtual P2P bridge. But I want
+ * to avoid putting a node for it in the tree, so the numbers
+ * below are basically de-swizzled numbers.
+ * The real slot is on idsel 0, so the swizzling is 1:1
+ */
+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+ interrupt-map = <
+ 0x0 0x0 0x0 0x1 &MPIC 38 0x2 /* int A */
+ 0x0 0x0 0x0 0x2 &MPIC 39 0x2 /* int B */
+ 0x0 0x0 0x0 0x3 &MPIC 40 0x2 /* int C */
+ 0x0 0x0 0x0 0x4 &MPIC 41 0x2 /* int D */>;
+ };
+
+ PCIE2: pciex@38100000000 { // 2xGBIF0
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ compatible = "ibm,plb-pciex-476fpe", "ibm,plb-pciex";
+ primary;
+ port = <0x2>; /* port number */
+ reg = <0x00000381 0x00000000 0x0 0x10000000 /* Config space access */
+ 0x00000380 0x00000000 0x0 0x00001000>; /* UTL Registers space access */
+ dcr-reg = <0xA0 0x20>;
+
+ ranges = <0x02000000 0x00000000 0x80000000 0x00000390 0x80000000 0x0 0x80000000
+ 0x01000000 0x0 0x0 0x000003C0 0x0 0x0 0x00010000>;
+
+ /* Inbound starting at 0 to memsize filled in by zImage */
+ dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x0>;
+
+ /* This drives busses 0 to 0xf */
+ bus-range = <0x0 0xf>;
+
+ /* Legacy interrupts (note the weird polarity, the bridge seems
+ * to invert PCIe legacy interrupts).
+ * We are de-swizzling here because the numbers are actually for
+ * port of the root complex virtual P2P bridge. But I want
+ * to avoid putting a node for it in the tree, so the numbers
+ * below are basically de-swizzled numbers.
+ * The real slot is on idsel 0, so the swizzling is 1:1
+ */
+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+ interrupt-map = <
+ 0x0 0x0 0x0 0x1 &MPIC 54 0x2 /* int A */
+ 0x0 0x0 0x0 0x2 &MPIC 55 0x2 /* int B */
+ 0x0 0x0 0x0 0x3 &MPIC 56 0x2 /* int C */
+ 0x0 0x0 0x0 0x4 &MPIC 57 0x2 /* int D */>;
+ };
+
+ };
+
+ chosen {
+ linux,stdout-path = &UART0;
+ };
+};
diff --git a/arch/powerpc/boot/treeboot-currituck.c b/arch/powerpc/boot/treeboot-currituck.c
new file mode 100644
index 0000000..925ae43
--- /dev/null
+++ b/arch/powerpc/boot/treeboot-currituck.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright © 2011 Tony Breeds IBM Corporation
+ *
+ * Based on earlier code:
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2002-2005 MontaVista Software Inc.
+ *
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ * Copyright (c) 2003, 2004 Zultys Technologies
+ *
+ * Copyright 2007 David Gibson, IBM Corporation.
+ * Copyright 2010 Ben. Herrenschmidt, IBM Corporation.
+ * Copyright © 2011 David Kleikamp IBM Corporation
+ *
+ * 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.
+ */
+#include <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "elf.h"
+#include "string.h"
+#include "stdio.h"
+#include "page.h"
+#include "ops.h"
+#include "reg.h"
+#include "io.h"
+#include "dcr.h"
+#include "4xx.h"
+#include "44x.h"
+#include "libfdt.h"
+
+BSS_STACK(4096);
+
+#define MAX_RANKS 0x4
+#define DDR3_MR0CF 0x80010011U
+
+static unsigned long long ibm_currituck_memsize;
+static unsigned long long ibm_currituck_detect_memsize(void)
+{
+ u32 reg;
+ unsigned i;
+ unsigned long long memsize = 0;
+
+ for(i = 0; i < MAX_RANKS; i++){
+ reg = mfdcrx(DDR3_MR0CF + i);
+
+ if (!(reg & 1))
+ continue;
+
+ reg &= 0x0000f000;
+ reg >>= 12;
+ memsize += (0x800000ULL << reg);
+ }
+
+ return memsize;
+}
+
+static void ibm_currituck_fixups(void)
+{
+ void *devp = finddevice("/");
+ u32 dma_ranges[7];
+
+ dt_fixup_memory(0x0ULL, ibm_currituck_memsize);
+
+ while ((devp = find_node_by_devtype(devp, "pci"))) {
+ if (getprop(devp, "dma-ranges", dma_ranges, sizeof(dma_ranges)) < 0) {
+ printf("%s: Failed to get dma-ranges\r\n", __func__);
+ continue;
+ }
+
+ dma_ranges[5] = ibm_currituck_memsize >> 32;
+ dma_ranges[6] = ibm_currituck_memsize & 0xffffffffUL;
+
+ setprop(devp, "dma-ranges", dma_ranges, sizeof(dma_ranges));
+ }
+}
+
+#define SPRN_PIR 0x11E /* Processor Indentification Register */
+void platform_init(void)
+{
+ unsigned long end_of_ram, avail_ram;
+ u32 pir_reg;
+ int node, size;
+ const u32 *timebase;
+
+ ibm_currituck_memsize = ibm_currituck_detect_memsize();
+ if (ibm_currituck_memsize >> 32)
+ end_of_ram = ~0UL;
+ else
+ end_of_ram = ibm_currituck_memsize;
+ avail_ram = end_of_ram - (unsigned long)_end;
+
+ simple_alloc_init(_end, avail_ram, 128, 64);
+ platform_ops.fixups = ibm_currituck_fixups;
+ platform_ops.exit = ibm44x_dbcr_reset;
+ pir_reg = mfspr(SPRN_PIR);
+
+ /* Make sure FDT blob is sane */
+ if (fdt_check_header(_dtb_start) != 0)
+ fatal("Invalid device tree blob\n");
+
+ node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type",
+ "cpu", sizeof("cpu"));
+ if (!node)
+ fatal("Cannot find cpu node\n");
+ timebase = fdt_getprop(_dtb_start, node, "timebase-frequency", &size);
+ if (timebase && (size == 4))
+ timebase_period_ns = 1000000000 / *timebase;
+
+ fdt_set_boot_cpuid_phys(_dtb_start, pir_reg);
+ fdt_init(_dtb_start);
+
+ serial_console_init();
+}
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index c74531a..87f4950 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -244,6 +244,9 @@ gamecube|wii)
link_address='0x600000'
platformo="$object/$platform-head.o $object/$platform.o"
;;
+treeboot-currituck)
+ link_address='0x1000000'
+ ;;
treeboot-iss4xx-mpic)
platformo="$object/treeboot-iss4xx.o"
;;
diff --git a/arch/powerpc/configs/44x/currituck_defconfig b/arch/powerpc/configs/44x/currituck_defconfig
new file mode 100644
index 0000000..4192322
--- /dev/null
+++ b/arch/powerpc/configs/44x/currituck_defconfig
@@ -0,0 +1,110 @@
+CONFIG_44x=y
+CONFIG_SMP=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_EXPERT=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PPC_47x=y
+# CONFIG_EBONY is not set
+CONFIG_CURRITUCK=y
+CONFIG_HIGHMEM=y
+CONFIG_HZ_100=y
+CONFIG_MATH_EMULATION=y
+CONFIG_IRQ_ALL_CPUS=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE=""
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_CONNECTOR=y
+CONFIG_MTD=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=35000
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+# CONFIG_SATA_PMP is not set
+CONFIG_SATA_SIL24=y
+# CONFIG_ATA_SFF is not set
+CONFIG_NETDEVICES=y
+CONFIG_E1000E=y
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_IBM_IIC=y
+# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_M41T80=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NLS_DEFAULT="n"
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DEBUG_INFO=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_XMON=y
+CONFIG_XMON_DEFAULT=y
+CONFIG_PPC_EARLY_DEBUG=y
+CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0x10000000
+CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x200
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
index f0be6e0..5d5aaf6 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -186,6 +186,16 @@ config ISS4xx
help
This option enables support for the IBM ISS simulation environment
+config CURRITUCK
+ bool "IBM Currituck (476fpe) Support"
+ depends on PPC_47x
+ default n
+ select SWIOTLB
+ select 476FPE
+ select PPC4xx_PCI_EXPRESS
+ help
+ This option enables support for the IBM Currituck (476fpe) evaluation board
+
config ICON
bool "Icon"
depends on 44x
diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile
index 553db60..d03833a 100644
--- a/arch/powerpc/platforms/44x/Makefile
+++ b/arch/powerpc/platforms/44x/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o
obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o
obj-$(CONFIG_ISS4xx) += iss4xx.o
obj-$(CONFIG_CANYONLANDS)+= canyonlands.o
+obj-$(CONFIG_CURRITUCK) += currituck.o
diff --git a/arch/powerpc/platforms/44x/currituck.c b/arch/powerpc/platforms/44x/currituck.c
new file mode 100644
index 0000000..1fdf569
--- /dev/null
+++ b/arch/powerpc/platforms/44x/currituck.c
@@ -0,0 +1,204 @@
+/*
+ * Currituck board specific routines
+ *
+ * Copyright © 2011 Tony Breeds IBM Corporation
+ *
+ * Based on earlier code:
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2002-2005 MontaVista Software Inc.
+ *
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ * Copyright (c) 2003-2005 Zultys Technologies
+ *
+ * Rewritten and ported to the merged powerpc tree:
+ * Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation.
+ * Copyright © 2011 David Kliekamp IBM Corporation
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/memblock.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/rtc.h>
+
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/time.h>
+#include <asm/uic.h>
+#include <asm/ppc4xx.h>
+#include <asm/mpic.h>
+#include <asm/mmu.h>
+
+#include <linux/pci.h>
+
+static __initdata struct of_device_id ppc47x_of_bus[] = {
+ { .compatible = "ibm,plb4", },
+ { .compatible = "ibm,plb6", },
+ { .compatible = "ibm,opb", },
+ { .compatible = "ibm,ebc", },
+ {},
+};
+
+/* The EEPROM is missing and the default values are bogus. This forces USB in
+ * to EHCI mode */
+static void __devinit quirk_ppc_currituck_usb_fixup(struct pci_dev *dev)
+{
+ if (of_machine_is_compatible("ibm,currituck")) {
+ pci_write_config_dword(dev, 0xe0, 0x0114231f);
+ pci_write_config_dword(dev, 0xe4, 0x00006c40);
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(0x1033, 0x0035, quirk_ppc_currituck_usb_fixup);
+
+static int __init ppc47x_device_probe(void)
+{
+ of_platform_bus_probe(NULL, ppc47x_of_bus, NULL);
+
+ return 0;
+}
+machine_device_initcall(ppc47x, ppc47x_device_probe);
+
+/* We can have either UICs or MPICs */
+static void __init ppc47x_init_irq(void)
+{
+ struct device_node *np;
+
+ /* Find top level interrupt controller */
+ for_each_node_with_property(np, "interrupt-controller") {
+ if (of_get_property(np, "interrupts", NULL) == NULL)
+ break;
+ }
+ if (np == NULL)
+ panic("Can't find top level interrupt controller");
+
+ /* Check type and do appropriate initialization */
+ if (of_device_is_compatible(np, "chrp,open-pic")) {
+ /* The MPIC driver will get everything it needs from the
+ * device-tree, just pass 0 to all arguments
+ */
+ struct mpic *mpic =
+ mpic_alloc(np, 0, MPIC_PRIMARY, 0, 0, " MPIC ");
+ BUG_ON(mpic == NULL);
+ mpic_init(mpic);
+ ppc_md.get_irq = mpic_get_irq;
+ } else
+ panic("Unrecognized top level interrupt controller");
+}
+
+#ifdef CONFIG_SMP
+static void __cpuinit smp_ppc47x_setup_cpu(int cpu)
+{
+ mpic_setup_this_cpu();
+}
+
+static int __cpuinit smp_ppc47x_kick_cpu(int cpu)
+{
+ struct device_node *cpunode = of_get_cpu_node(cpu, NULL);
+ const u64 *spin_table_addr_prop;
+ u32 *spin_table;
+ extern void start_secondary_47x(void);
+
+ BUG_ON(cpunode == NULL);
+
+ /* Assume spin table. We could test for the enable-method in
+ * the device-tree but currently there's little point as it's
+ * our only supported method
+ */
+ spin_table_addr_prop =
+ of_get_property(cpunode, "cpu-release-addr", NULL);
+
+ if (spin_table_addr_prop == NULL) {
+ pr_err("CPU%d: Can't start, missing cpu-release-addr !\n",
+ cpu);
+ return 1;
+ }
+
+ /* Assume it's mapped as part of the linear mapping. This is a bit
+ * fishy but will work fine for now
+ *
+ * XXX: Is there any reason to assume differently?
+ */
+ spin_table = (u32 *)__va(*spin_table_addr_prop);
+ pr_debug("CPU%d: Spin table mapped at %p\n", cpu, spin_table);
+
+ spin_table[3] = cpu;
+ smp_wmb();
+ spin_table[1] = __pa(start_secondary_47x);
+ mb();
+
+ return 0;
+}
+
+static struct smp_ops_t ppc47x_smp_ops = {
+ .probe = smp_mpic_probe,
+ .message_pass = smp_mpic_message_pass,
+ .setup_cpu = smp_ppc47x_setup_cpu,
+ .kick_cpu = smp_ppc47x_kick_cpu,
+ .give_timebase = smp_generic_give_timebase,
+ .take_timebase = smp_generic_take_timebase,
+};
+
+static void __init ppc47x_smp_init(void)
+{
+ if (mmu_has_feature(MMU_FTR_TYPE_47x))
+ smp_ops = &ppc47x_smp_ops;
+}
+
+#else /* CONFIG_SMP */
+static void __init ppc47x_smp_init(void) { }
+#endif /* CONFIG_SMP */
+
+static void __init ppc47x_setup_arch(void)
+{
+
+ /* No need to check the DMA config as we /know/ our windows are all of
+ * RAM. Lets hope that doesn't change */
+#ifdef CONFIG_SWIOTLB
+ if (memblock_end_of_DRAM() > 0xffffffff) {
+ ppc_swiotlb_enable = 1;
+ set_pci_dma_ops(&swiotlb_dma_ops);
+ ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
+ }
+#endif
+ ppc47x_smp_init();
+}
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+static int __init ppc47x_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (!of_flat_dt_is_compatible(root, "ibm,currituck"))
+ return 0;
+
+ return 1;
+}
+
+/* Use USB controller should have been hardware swizzled but it wasn't :( */
+static void ppc47x_pci_irq_fixup(struct pci_dev *dev)
+{
+ if (dev->vendor == 0x1033 && (dev->device == 0x0035 ||
+ dev->device == 0x00e0)) {
+ dev->irq = irq_create_mapping(NULL, 47);
+ pr_info("%s: Mapping irq 47 %d\n", __func__, dev->irq);
+ }
+}
+
+define_machine(ppc47x) {
+ .name = "PowerPC 47x",
+ .probe = ppc47x_probe,
+ .progress = udbg_progress,
+ .init_IRQ = ppc47x_init_irq,
+ .setup_arch = ppc47x_setup_arch,
+ .pci_irq_fixup = ppc47x_pci_irq_fixup,
+ .restart = ppc4xx_reset_system,
+ .calibrate_decr = generic_calibrate_decr,
+};
--
1.7.6.4
^ permalink raw reply related
* Re: Add support for the currituck 476 platform from IBM (v2)
From: Tony Breeds @ 2011-12-01 7:43 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Josh Boyer; +Cc: LinuxPPC-dev
In-Reply-To: <1322725164-4391-1-git-send-email-tony@bakeyournoodle.com>
[-- Attachment #1: Type: text/plain, Size: 1462 bytes --]
On Thu, Dec 01, 2011 at 06:39:16PM +1100, Tony Breeds wrote:
> Patches 1 to 3
> Modify the 44x PCI code to work with 476fpe/currituck.
> Patch 4
> Is an old patch by Christoph Egger that fell through the cracks somehow.
> Patches 5 and 6
> Modify the bootwrapper to handle 476fpe/currituck
> Patch 7
> The SoC support.
> Patch 8
> The currituck board support.
Sorry I forgot the diffstat
arch/powerpc/boot/Makefile | 5 +-
arch/powerpc/boot/dcr.h | 6 +
arch/powerpc/boot/div64.S | 52 ++++++
arch/powerpc/boot/dts/currituck.dts | 237 ++++++++++++++++++++++++++
arch/powerpc/boot/treeboot-currituck.c | 119 +++++++++++++
arch/powerpc/boot/wrapper | 3 +
arch/powerpc/configs/44x/currituck_defconfig | 110 ++++++++++++
arch/powerpc/include/asm/reg.h | 1 +
arch/powerpc/kernel/cputable.c | 14 ++
arch/powerpc/kernel/head_44x.S | 2 +
arch/powerpc/mm/44x_mmu.c | 4 -
arch/powerpc/platforms/44x/Kconfig | 14 ++
arch/powerpc/platforms/44x/Makefile | 1 +
arch/powerpc/platforms/44x/currituck.c | 204 ++++++++++++++++++++++
arch/powerpc/sysdev/ppc4xx_pci.c | 85 +++++++++-
arch/powerpc/sysdev/ppc4xx_pci.h | 7 +
16 files changed, 851 insertions(+), 13 deletions(-)
Yours Tony
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox