* [PATCH 6/9] ppc32: Remove __init qualifier from mpc52xx pci resources fixups
From: Sylvain Munaut @ 2005-12-20 20:43 UTC (permalink / raw)
To: Andrew Morton; +Cc: Tom Rini, Sylvain Munaut, Linux PPC Embedded
In-Reply-To: <0.20051220_213752_1ebc_tnt@patchsend.246tNt.com>
ppc32: Remove __init qualifier from mpc52xx pci resources fixups
The mpc52xx_pci_fixup_resources is not only called at init but also
when there is a pci hotplug like when a cardbus card is plugged in.
So that function is needed after init too.
Thanks to Asier Llano Palacios for reporting this.
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
---
commit 7834134483a1ae663b805714fcd741c1caf41171
tree 56da4218fa2a0bd1541b7743e79415fc48715ba1
parent 0311bddd40fe347ea69a5659f02e1beb8fe96ea8
author Sylvain Munaut <tnt@246tNt.com> Sun, 18 Dec 2005 11:48:56 +0100
committer Sylvain Munaut <tnt@246tNt.com> Sun, 18 Dec 2005 11:48:56 +0100
arch/ppc/syslib/mpc52xx_pci.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/ppc/syslib/mpc52xx_pci.c b/arch/ppc/syslib/mpc52xx_pci.c
index 4ac1908..e6cb3e2 100644
--- a/arch/ppc/syslib/mpc52xx_pci.c
+++ b/arch/ppc/syslib/mpc52xx_pci.c
@@ -151,7 +151,7 @@ mpc52xx_pci_setup(struct mpc52xx_pci __i
#endif
}
-static void __init
+static void
mpc52xx_pci_fixup_resources(struct pci_dev *dev)
{
int i;
^ permalink raw reply related
* [PATCH 5/9] ppc32: Modify Freescale MPC52xx IRQ mapping to _not_ use irq 0
From: Sylvain Munaut @ 2005-12-20 20:42 UTC (permalink / raw)
To: Andrew Morton; +Cc: Tom Rini, Sylvain Munaut, Linux PPC Embedded
In-Reply-To: <0.20051220_213752_1ebc_tnt@patchsend.246tNt.com>
ppc32: Modify Freescale MPC52xx IRQ mapping to _not_ use irq 0
AFAIK IRQ number 0 is a perfectly valid IRQ number. But it seems there
are numerous places where it's considered to be invalid or "no irq" value.
Since that value is problematic, the IRQ mapping is changed to not
use it.
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
---
commit 0311bddd40fe347ea69a5659f02e1beb8fe96ea8
tree 16003ab98c67face9c25bdb247e241d88dd596f5
parent ae62fed2708efa333d41f7b36893e5fdbd0f6730
author Sylvain Munaut <tnt@246tNt.com> Sun, 18 Dec 2005 11:20:17 +0100
committer Sylvain Munaut <tnt@246tNt.com> Sun, 18 Dec 2005 11:20:17 +0100
include/asm-ppc/mpc52xx.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/asm-ppc/mpc52xx.h b/include/asm-ppc/mpc52xx.h
index e5f80c2..04d5630 100644
--- a/include/asm-ppc/mpc52xx.h
+++ b/include/asm-ppc/mpc52xx.h
@@ -107,7 +107,7 @@ enum ppc_sys_devices {
#define MPC52xx_SDMA_IRQ_NUM 17
#define MPC52xx_PERP_IRQ_NUM 23
-#define MPC52xx_CRIT_IRQ_BASE 0
+#define MPC52xx_CRIT_IRQ_BASE 1
#define MPC52xx_MAIN_IRQ_BASE (MPC52xx_CRIT_IRQ_BASE + MPC52xx_CRIT_IRQ_NUM)
#define MPC52xx_SDMA_IRQ_BASE (MPC52xx_MAIN_IRQ_BASE + MPC52xx_MAIN_IRQ_NUM)
#define MPC52xx_PERP_IRQ_BASE (MPC52xx_SDMA_IRQ_BASE + MPC52xx_SDMA_IRQ_NUM)
^ permalink raw reply related
* [PATCH 4/9] ppc32: Fix static IO mapping for Freescale MPC52xx
From: Sylvain Munaut @ 2005-12-20 20:42 UTC (permalink / raw)
To: Andrew Morton; +Cc: Tom Rini, Sylvain Munaut, Linux PPC Embedded
In-Reply-To: <0.20051220_213752_1ebc_tnt@patchsend.246tNt.com>
ppc32: Fix static IO mapping for Freescale MPC52xx
The current iomapping used MBAR_SIZE for the size argument
of io_block_mapping, resulting in a call to setbat with a
size argument of 64k which is invalid.
This patch correct this and maps the whole 0xf0000000->0xffffffff
range so that devices on the local bus are also included in
the BAT mapping.
Thanks to Bernhard Kuhn from Metrowerks for pointing this out.
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
---
commit ae62fed2708efa333d41f7b36893e5fdbd0f6730
tree a1a4da53edb2f235be6658558eeb606a0b2580e9
parent 1661f915e8bd58e52fe3326e038efe74068702e0
author Sylvain Munaut <tnt@246tNt.com> Sun, 18 Dec 2005 11:13:15 +0100
committer Sylvain Munaut <tnt@246tNt.com> Sun, 18 Dec 2005 11:13:15 +0100
arch/ppc/syslib/mpc52xx_setup.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/ppc/syslib/mpc52xx_setup.c b/arch/ppc/syslib/mpc52xx_setup.c
index bb23745..a4a4b02 100644
--- a/arch/ppc/syslib/mpc52xx_setup.c
+++ b/arch/ppc/syslib/mpc52xx_setup.c
@@ -84,9 +84,11 @@ mpc52xx_set_bat(void)
void __init
mpc52xx_map_io(void)
{
- /* Here we only map the MBAR */
+ /* Here we map the MBAR and the whole upper zone. MBAR is only
+ 64k but we can't map only 64k with BATs. Map the whole
+ 0xf0000000 range is ok and helps eventual lpb devices placed there */
io_block_mapping(
- MPC52xx_MBAR_VIRT, MPC52xx_MBAR, MPC52xx_MBAR_SIZE, _PAGE_IO);
+ MPC52xx_MBAR_VIRT, MPC52xx_MBAR, 0x10000000, _PAGE_IO);
}
^ permalink raw reply related
* [PATCH 3/9] ppc32/serial: Change mpc52xx_uart.c to use the Low Density Serial port major
From: Sylvain Munaut @ 2005-12-20 20:41 UTC (permalink / raw)
To: Andrew Morton; +Cc: Tom Rini, Sylvain Munaut, Linux PPC Embedded
In-Reply-To: <0.20051220_213752_1ebc_tnt@patchsend.246tNt.com>
ppc32/serial: Change mpc52xx_uart.c to use the Low Density Serial port major
Before this patch we were just using the "classic" /dev/ttySx devices.
However when another on the system is loaded that uses those (like drivers
for serial PCMCIA), that creates a conflict for the minors. Therefore, we
now use /dev/ttyPSC[0:5] (note the 0-based numbering !) with some minors
we've been assigned in the "Low Density Serial port major"
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
---
commit 1661f915e8bd58e52fe3326e038efe74068702e0
tree 04215b96380f2d7d218a223d837b9eabe2f120f4
parent c83b03a94291bdd952c6b1b20ab15981456e8625
author Sylvain Munaut <tnt@246tNt.com> Sat, 17 Dec 2005 23:21:16 +0100
committer Sylvain Munaut <tnt@246tNt.com> Sat, 17 Dec 2005 23:21:16 +0100
drivers/serial/mpc52xx_uart.c | 26 +++++++++++++++-----------
1 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 4dcf031..1288d62 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -37,11 +37,11 @@
* by the bootloader or in the platform init code.
*
* The idx field must be equal to the PSC index ( e.g. 0 for PSC1, 1 for PSC2,
- * and so on). So the PSC1 is mapped to /dev/ttyS0, PSC2 to /dev/ttyS1 and so
- * on. But be warned, it's an ABSOLUTE REQUIREMENT ! This is needed mainly for
- * the console code : without this 1:1 mapping, at early boot time, when we are
- * parsing the kernel args console=ttyS?, we wouldn't know wich PSC it will be
- * mapped to.
+ * and so on). So the PSC1 is mapped to /dev/ttyPSC0, PSC2 to /dev/ttyPSC1 and
+ * so on. But be warned, it's an ABSOLUTE REQUIREMENT ! This is needed mainly
+ * fpr the console code : without this 1:1 mapping, at early boot time, when we
+ * are parsing the kernel args console=ttyPSC?, we wouldn't know wich PSC it
+ * will be mapped to.
*/
#include <linux/config.h>
@@ -65,6 +65,10 @@
#include <linux/serial_core.h>
+/* We've been assigned a range on the "Low-density serial ports" major */
+#define SERIAL_PSC_MAJOR 204
+#define SERIAL_PSC_MINOR 148
+
#define ISR_PASS_LIMIT 256 /* Max number of iteration in the interrupt */
@@ -671,12 +675,12 @@ mpc52xx_console_setup(struct console *co
static struct uart_driver mpc52xx_uart_driver;
static struct console mpc52xx_console = {
- .name = "ttyS",
+ .name = "ttyPSC",
.write = mpc52xx_console_write,
.device = uart_console_device,
.setup = mpc52xx_console_setup,
.flags = CON_PRINTBUFFER,
- .index = -1, /* Specified on the cmdline (e.g. console=ttyS0 ) */
+ .index = -1, /* Specified on the cmdline (e.g. console=ttyPSC0 ) */
.data = &mpc52xx_uart_driver,
};
@@ -703,10 +707,10 @@ console_initcall(mpc52xx_console_init);
static struct uart_driver mpc52xx_uart_driver = {
.owner = THIS_MODULE,
.driver_name = "mpc52xx_psc_uart",
- .dev_name = "ttyS",
- .devfs_name = "ttyS",
- .major = TTY_MAJOR,
- .minor = 64,
+ .dev_name = "ttyPSC",
+ .devfs_name = "ttyPSC",
+ .major = SERIAL_PSC_MAJOR,
+ .minor = SERIAL_PSC_MINOR,
.nr = MPC52xx_PSC_MAXNUM,
.cons = MPC52xx_PSC_CONSOLE,
};
^ permalink raw reply related
* [PATCH 2/9] ppc32/serial: Fix compiler errors with GCC 4.x in mpc52xx_uart.c
From: Sylvain Munaut @ 2005-12-20 20:41 UTC (permalink / raw)
To: Andrew Morton; +Cc: Tom Rini, Sylvain Munaut, Linux PPC Embedded
In-Reply-To: <0.20051220_213752_1ebc_tnt@patchsend.246tNt.com>
ppc32/serial: Fix compiler errors with GCC 4.x in mpc52xx_uart.c
Signed-off-by: Wolfgang Denk <wd@denx.de>
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
---
commit c83b03a94291bdd952c6b1b20ab15981456e8625
tree 81e1121a440a4624a4cd7f112fe44fca438ee140
parent 144f9d12ec7d04b38f83a131c4e544f78d2d47b2
author Sylvain Munaut <tnt@246tNt.com> Sat, 17 Dec 2005 23:12:39 +0100
committer Sylvain Munaut <tnt@246tNt.com> Sat, 17 Dec 2005 23:12:39 +0100
drivers/serial/mpc52xx_uart.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index b8727d9..4dcf031 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -668,7 +668,7 @@ mpc52xx_console_setup(struct console *co
}
-extern struct uart_driver mpc52xx_uart_driver;
+static struct uart_driver mpc52xx_uart_driver;
static struct console mpc52xx_console = {
.name = "ttyS",
^ permalink raw reply related
* [PATCH 1/9] ppc32: Remove useless file arch/ppc/platforms/mpc5200.c
From: Sylvain Munaut @ 2005-12-20 20:40 UTC (permalink / raw)
To: Andrew Morton; +Cc: Tom Rini, Sylvain Munaut, Linux PPC Embedded
In-Reply-To: <0.20051220_213752_1ebc_tnt@patchsend.246tNt.com>
ppc32: Remove useless file arch/ppc/platforms/mpc5200.c
That file is a left-over of the 'old' OCP model that
should have been erased during the change to platform
model but I forgot it ...
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
---
commit 144f9d12ec7d04b38f83a131c4e544f78d2d47b2
tree 629ebc02993d06ff02b87e2d0effb257ef842328
parent 48ea753075aa15699bd5fac26faa08431aaa697b
author Sylvain Munaut <tnt@246tNt.com> Sat, 17 Dec 2005 23:03:25 +0100
committer Sylvain Munaut <tnt@246tNt.com> Sat, 17 Dec 2005 23:03:25 +0100
arch/ppc/platforms/mpc5200.c | 53 ------------------------------------------
1 files changed, 0 insertions(+), 53 deletions(-)
diff --git a/arch/ppc/platforms/mpc5200.c b/arch/ppc/platforms/mpc5200.c
deleted file mode 100644
index a58db43..0000000
--- a/arch/ppc/platforms/mpc5200.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * arch/ppc/platforms/mpc5200.c
- *
- * OCP Definitions for the boards based on MPC5200 processor. Contains
- * definitions for every common peripherals. (Mostly all but PSCs)
- *
- * Maintainer : Sylvain Munaut <tnt@246tNt.com>
- *
- * Copyright 2004 Sylvain Munaut <tnt@246tNt.com>
- *
- * 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.
- */
-
-#include <asm/ocp.h>
-#include <asm/mpc52xx.h>
-
-
-static struct ocp_fs_i2c_data mpc5200_i2c_def = {
- .flags = FS_I2C_CLOCK_5200,
-};
-
-
-/* Here is the core_ocp struct.
- * With all the devices common to all board. Even if port multiplexing is
- * not setup for them (if the user don't want them, just don't select the
- * config option). The potentially conflicting devices (like PSCs) goes in
- * board specific file.
- */
-struct ocp_def core_ocp[] = {
- {
- .vendor = OCP_VENDOR_FREESCALE,
- .function = OCP_FUNC_IIC,
- .index = 0,
- .paddr = MPC52xx_I2C1,
- .irq = OCP_IRQ_NA, /* MPC52xx_IRQ_I2C1 - Buggy */
- .pm = OCP_CPM_NA,
- .additions = &mpc5200_i2c_def,
- },
- {
- .vendor = OCP_VENDOR_FREESCALE,
- .function = OCP_FUNC_IIC,
- .index = 1,
- .paddr = MPC52xx_I2C2,
- .irq = OCP_IRQ_NA, /* MPC52xx_IRQ_I2C2 - Buggy */
- .pm = OCP_CPM_NA,
- .additions = &mpc5200_i2c_def,
- },
- { /* Terminating entry */
- .vendor = OCP_VENDOR_INVALID
- }
-};
^ permalink raw reply related
* [PATCH 0/9] Some Freescale MPC52xx related updates
From: Sylvain Munaut @ 2005-12-20 20:40 UTC (permalink / raw)
To: Andrew Morton; +Cc: Tom Rini, Sylvain Munaut, Linux PPC Embedded
Hello Andrew & all,
This set of patches contains misc updates that are in my local
tree since sometimes now and I think they're good to go upstream.
They've been posted separatly on the ppc mailing list at some point
and tested by several people. So far I received no negative feedback.
Most are trivial compile fix, small improvements, ...
Thanks,
Sylvain Munaut
^ permalink raw reply
* Re: TLB preloading on 8xx
From: Dan Malek @ 2005-12-20 19:45 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: linux-ppc-embedded
In-Reply-To: <20051220173730.GB6404@dmt.cnet>
On Dec 20, 2005, at 12:37 PM, Marcelo Tosatti wrote:
> Sum up the costs of disabling interrupts and disabling translation,
> and you
> end up with a slow dog. Damn, the TLB exceptions are indeed efficient.
Like I've always said, make the TLB miss exception path very
short and efficient. You have to consider the total system impact
of running this code, which includes replacing lots of cache
lines that will affect the performance of the application.
Don't be looking for "tricks" in the exception path, look for
ways outside of that we can better structure the page tables
so we can _remove_ code from the exception handler, not
add to it. What you are doing here is an attempt to do
that, but you are executing lots more code to do this
preload than the TLB miss exception would do.
Keep trying, though, this was a good idea to test :-)
Thanks.
-- Dan
^ permalink raw reply
* Re: RFC: Rev 0.5 Booting the Linux/ppc kernel without Open Firmware
From: Arnd Bergmann @ 2005-12-20 18:58 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc64-dev, linuxppc-dev
In-Reply-To: <Pine.LNX.4.44.0512201106280.22417-100000@gate.crashing.org>
On Dinsdag 20 Dezember 2005 18:26, Kumar Gala wrote:
>
> > AFAICS, that requires at least two things:
> > - The device needs to be created when the bus is probed, i.e.
> > of_device_register can not be called from inside the driver
> > module_init() function.
> >
>
> This is already handled by the platform device in the kernel.
Ok, i was a bit misinformed about how platform devices currently work,
for some reason I thought that there was only a single entry point
for register_device and register_driver, which is untrue.
Sorry for the confusion here.
> I still dont see what a new bus type get us. I'm going to have to have
> specific code to parse and build and register my devices. If that could
> ends up registering a platform device or a newflatOF device I dont see any
> real difference.
After looking into it a bit more, I found that we already have
two different types of platform devices here: the standard struct
platform_device and the of_platform_device that is currently used
only on powermac and (maybe surprisingly) is not based on a
platform_device at all but on of_device.
Using the basic platform_device has the big advantage that you
can't access the device_node information (unless we implement the
device::firmware_data infrastructure for powerpc, which looks
increasingly appealing).
> > The alternative would be to represent all of the device tree
> > in /sys/devices, but IMHO that should better be part of
> > /sys/firmware with symlinks to the linux internal device tree
> > representation.
>
> Today I have:
> /sys/devices/platform/
> fsl-gianfar.1
> fsl-i2c.1
> fsl-i2c.2
> fsl-sec2.1
> fsl-usb2-dr.1
> fsl-usb2-mph.1
> serial8250
> serial8250.0
The problem I see with these is that currently they are all created
by platform specific code or driver specific code that knows exactly
that these devices exist on the hardware.
When moving to the device tree, you need some criteria to decide
which devices to add and which not. One way to do this would be
to only add devices that are a direct child of an SOC bus. If you
would simply add every single device_node as a platform_device,
you end up with a huge number of entries in /sys/devices/platform/
that are either unused completely or already represented elsewhere
like /sys/devices/pci*/*.
One idea I just had (forgive me if that is bullshit, it's getting late
here) is to really do the /sys/firmware stuff by embedding a kobject
in every device_node. The existing bus types that already know about
device_node (pci, vio, macio, of_platform, ...) get converted to
use that (e.g. pci stores the device_node in pci_dev:dev:firmware_data
instead of pci_dev:sysdata) and create the appropriate symlink in sysfs.
When an of_platform_driver registers, we can still give it all devices
because we can create the of_platform_device on the fly by doing the
match on the device_node first.
Arnd <><
^ permalink raw reply
* TLB preloading on 8xx
From: Marcelo Tosatti @ 2005-12-20 17:37 UTC (permalink / raw)
To: linux-ppc-embedded
Hi,
Been playing with TLB preloading on 8xx for the past weeks, and I must
say that results are frustrating.
Most of the TLB setup work involves writing to special purpose
registers, using "mtspr", which is a serializing instruction (it blocks
all execution units).
Sum up the costs of disabling interrupts and disabling translation, and you
end up with a slow dog. Damn, the TLB exceptions are indeed efficient.
The test used to measure pagefault latency is LMbench's "lat_pagefault".
vanilla:
[root@CAS /]# ./lat_pagefault -N10 out.prof
Pagefaults on out.prof: 36.3728 microseconds
d-tlb-preload:
[root@CAS /]# ./lat_pagefault -N10 out.prof
Pagefaults on out.prof: 43.7793 microseconds
diff -Nur --exclude-from=linux-2.6-git-dec01/Documentation/dontdiff linux-2.6-git-dec01.orig/arch/ppc/kernel/head_8xx.S linux-2.6-git-dec01/arch/ppc/kernel/head_8xx.S
--- linux-2.6-git-dec01.orig/arch/ppc/kernel/head_8xx.S 2005-12-05 09:47:27.000000000 -0600
+++ linux-2.6-git-dec01/arch/ppc/kernel/head_8xx.S 2005-12-15 12:37:07.449818656 -0600
@@ -804,7 +828,156 @@
SYNC
blr
+
+_GLOBAL(__tlb_data_load)
+ rlwinm r8, r4, 0, 0, 19 /* extract page address */
+ ori r8, r8, MD_EVALID /* set valid bit */
+ slw r3, r3, 28
+ rlwimi r8, r3, 0, 28, 31 /* load ASID from r3 */
+#ifdef CONFIG_8xx_CPU6
+ li r9, 0x3780;
+ stw r9, 4(r7);
+ lwz r9, 4(r7);
+#endif
+ mtspr SPRN_MD_EPN, r8
+
+ mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */
+ lwz r11, 0(r10) /* Get the level 1 entry */
+ ori r11,r11,1 /* Set valid bit */
+
+ /* Insert the Guarded flag into the TWC from the Linux PTE.
+ * It is bit 27 of both the Linux PTE and the TWC (at least
+ * I got that right :-). It will be better when we can put
+ * this into the Linux pgd/pmd and load it in the operation
+ * above.
+ */
+ mr r12, r5
+ rlwimi r11, r12, 0, 27, 27
+
+ /*
+ * Some fields of MD_TWC are cleared by the CPU on a DTLB miss.
+ * Must do it manually for TLB preload.
+ * clear 23-26 (access protection group)
+ * clear 28-29 (page size) and 30 (write-through)
+ */
+ li r12, 0
+ rlwimi r11, r12, 0, 23, 26
+ rlwimi r11, r12, 0, 28, 30
+#ifdef CONFIG_8xx_CPU6
+ li r9, 0x3b80;
+ stw r9, 4(r7);
+ lwz r9, 4(r7);
+#endif
+ mtspr SPRN_MD_TWC, r11 /* Set segment attributes */
+
+ mr r8, r5
+ mr r11, r8
+ rlwinm r8, r8, 0, 0, 20
+ ori r8, r8, 1 /* set valid bit */
+ /* Update 'changed', among others.
+ */
+ andi. r11, r11, _PAGE_RW
+ li r11, 0x00f0
+ beq 1f
+ ori r8, r8, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
+// stw r8, 0(r5) /* and update pte in table */
+ ori r11, r11, _PAGE_HWWRITE
+ /* The Linux PTE won't go exactly into the MMU TLB.
+ * Software indicator bits 21, 22 and 28 must be clear.
+ * Software indicator bits 24, 25, 26, and 27 must be
+ * set. All other Linux PTE bits control the behavior
+ * of the MMU.
+ */
+1:
+ rlwimi r8, r11, 0, 23, 28 /* Set 24-27, clear 28 */
+ /* 23 is set if page is _PAGE_RW */
+#ifdef CONFIG_8xx_CPU6
+ li r9, 0x3d80;
+ stw r9, 4(r7);
+ lwz r9, 4(r7);
+#endif
+ mtspr SPRN_MD_RPN, r8 /* Update TLB entry */
+
+ mfmsr r11
+ lwz r6, 0(r7) /* restore Link Register */
+ mtlr r6
+ li r6, 0x7fff
+ rlwimi r11, r6, 0, 27, 27 /* set DR */
+ mtmsr r11
+ tovirt(r7, r7)
+ blr
+
+/*
+ * Load a D-TLB entry.
+ * r3: context number
+ * r4: effective address
+ * r5: PTE pointer
+ * r6: PMD (level-1 entry)
+ * r7: temp location
+ */
+_GLOBAL(tlb_data_load)
+ lwz r5, 0(r5)
+ mflr r6
+ stw r6, 0(r7) /* save Link Register */
+ mfmsr r11
+ li r6, 0
+ rlwimi r11, r6, 0, 27, 27 /* clear DR (data translat.)*/
+ mtmsr r11
+ lis r6, __tlb_data_load@h
+ ori r6, r6, __tlb_data_load@l
+ tophys(r7, r7)
+ mtlr r6
+ blr
+
+/*
+ * Load a I-TLB entry.
+ * r3: context number
+ * r4: effective address
+ * r5: PTE pointer
+ * r6: PMD (level-1 entry)
+ * r7: temp location
+ */
+_GLOBAL(tlb_instr_load)
+ rlwinm r8, r4, 0, 0, 19 /* extract page address */
+ ori r8, r8, MI_EVALID /* set valid bit */
+ slw r3, r3, 28
+ rlwimi r8, r3, 0, 28, 31 /* load ASID from r3 */
#ifdef CONFIG_8xx_CPU6
+ li r9, 0x2780;
+ stw r9, 0(r7);
+ lwz r9, 0(r7);
+#endif
+
+ mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */
+ tovirt(r10, r10)
+ lwz r11, 0(r10) /* Get the level 1 entry */
+ ori r11,r11,1 /* Set valid bit */
+#ifdef CONFIG_8xx_CPU6
+ li r9, 0x2b80;
+ stw r9, 0(r7);
+ lwz r9, 0(r7);
+#endif
+ mtspr SPRN_MI_TWC, r11 /* Set segment attributes */
+
+ lwz r8, 0(r5)
+ rlwinm r8, r8, 0, 0, 19
+ ori r8, r8, 1 /* set valid bit */
+ /* The Linux PTE won't go exactly into the MMU TLB.
+ * Software indicator bits 21, 22 and 28 must be clear.
+ * Software indicator bits 24, 25, 26, and 27 must be
+ * set. All other Linux PTE bits control the behavior
+ * of the MMU.
+ */
+ li r11, 0x00f0
+ rlwimi r8, r11, 0, 24, 28 /* Set 24-27, clear 28 */
+#ifdef CONFIG_8xx_CPU6
+ li r9, 0x2d80;
+ stw r9, 0(r7);
+ lwz r9, 0(r7);
+#endif
+ mtspr SPRN_MI_RPN, r8 /* Update TLB entry */
+ blr
+
/* It's here because it is unique to the 8xx.
* It is important we get called with interrupts disabled. I used to
* do that, but it appears that all code that calls this already had
@@ -820,7 +993,6 @@
mtspr 22, r3 /* Update Decrementer */
SYNC
blr
-#endif
/*
* We put a few things here that have to be page-aligned.
diff -Nur --exclude-from=linux-2.6-git-dec01/Documentation/dontdiff linux-2.6-git-dec01.orig/arch/ppc/mm/init.c linux-2.6-git-dec01/arch/ppc/mm/init.c
--- linux-2.6-git-dec01.orig/arch/ppc/mm/init.c 2005-12-05 09:47:28.000000000 -0600
+++ linux-2.6-git-dec01/arch/ppc/mm/init.c 2005-12-15 13:16:42.787712408 -0600
@@ -583,6 +583,54 @@
kunmap(page);
}
+extern void tlb_data_load(unsigned long id, unsigned long address, pte_t *pte,
+ unsigned long pmdval, unsigned long *tmpval);
+
+extern void tlb_instr_load(unsigned long id, unsigned long address, pte_t *pte,
+ unsigned long pmdval, unsigned long *tmpval);
+
+void tlb_preload(struct vm_area_struct *vma, unsigned long address,
+ pte_t pte)
+{
+ struct mm_struct *mm;
+ pmd_t *pmd;
+ pte_t *ptep;
+ int mapping_executable = 0;
+ unsigned long flags, tmpval;
+ unsigned long tmp[4];
+
+ if ((vma->vm_flags & VM_EXEC) == VM_EXEC)
+ mapping_executable = 1;
+
+ local_irq_save(flags);
+
+ mm = vma->vm_mm;
+ pmd = pmd_offset(pgd_offset(mm, address), address);
+ if (!pmd_none(*pmd)) {
+ if (mfspr(SPRN_M_CASID) != (mm->context)) {
+ printk(KERN_ERR "CASID:%lx mm->context:%lx\n",
+ mfspr(SPRN_M_CASID), (mm->context));
+ BUG();
+ }
+ ptep = pte_offset_map(pmd, address);
+ if (!pte_present(pte) || !ptep)
+ goto out;
+ if (!mapping_executable)
+ tlb_data_load(mm->context, address, ptep,
+ pmd_val(*pmd), &tmp);
+#ifdef NOTYET
+ else
+ tlb_instr_load(mm->context, address, ptep,
+ pmd_val(*pmd), &tmp);
+#endif
+out:
+ pte_unmap(ptep);
+ }
+ local_irq_restore(flags);
+}
+
+extern void tlbie_efficient(unsigned long address, struct vm_area_struct *vma);
+
/*
* This is called at the end of handling a user page fault, when the
* fault has been handled by updating a PTE in the linux page tables.
@@ -614,6 +662,7 @@
flush_dcache_icache_page(page);
set_bit(PG_arch_1, &page->flags);
}
+ tlb_preload(vma, address, pte);
}
#ifdef CONFIG_PPC_STD_MMU
^ permalink raw reply
* Re: linux DMA capabilities in MV64460
From: Mark A. Greer @ 2005-12-20 17:54 UTC (permalink / raw)
To: Brian Waite; +Cc: linuxppc-embedded
In-Reply-To: <200512200927.35976.bwaite@irobot.com>
On Tue, Dec 20, 2005 at 09:27:35AM -0500, Brian Waite wrote:
> On Monday 19 December 2005 8:01 pm, Mark A. Greer wrote:
> > >
> > > up the mv64460. One source told me:
> > > > In order to do PCI bursts, you'll need to use a DMA engine. The
> > > > MV64460 does contain a DMA engine, but you'd need to write a driver
> > > > to access it.
> >
> > That is not correct (assuming the quote is not out of context).
> > The bridge supports bursting on the PCI bus as long as the bridge is
> > configured correctly and the PCI device is making an appropriate request.
> > Note, however, that there are many errata for the Marvell parts including
> > some with cache coherency.
> There are many many errata regarding cache coherency. Also, the PCI bandwidth
> the bridge is capable of with coherency enabled is very small. You will most
> likely need to use sw coherency for any real speed.
I've managed to get reasonable speed with coherency on but you have to
jack the burst sizes to the max (see my comment below). The speed was
hugely affected by the burst size; coherency enabled had only a minor impact.
The problem for me, however, was the board(s) I have do not have the
necessary hw coherency errata workarounds implemented so the bridge
eventually hangs with coherency enabled.
Unfortunately, I think I deleted the file with my performance
results in one of my cleanup binges. IIRC, though, I got ~750 Mbps
with coherency off and ~725 Mbps with it on using an e1000 & a 750fx
or gx clocked around 800 MHz.
> > If your system is running with coherency on,
> > you may have to limit your bursts to 32 bytes (i.e., the size of one
> > cache line).
> You will have to limit your self to 32 byte bursts with coherency. This is a
> requirement not an errata.
That is only true for the 64360. The 64460 does not have that
restriction AFAICT.
<snip>
Mark
^ permalink raw reply
* Re: RFC: Rev 0.5 Booting the Linux/ppc kernel without Open Firmware
From: Kumar Gala @ 2005-12-20 17:26 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc64-dev, linuxppc-dev
In-Reply-To: <200512201118.05404.arnd@arndb.de>
On Tue, 20 Dec 2005, Arnd Bergmann wrote:
> On Maandag 19 Dezember 2005 21:49, Kumar Gala wrote:
> > I'm still in favor of just leaving these devices as straight platform
> > devices. Unless there is something that is bus specific that each device
> > on the bus conforms to I dont see any reason to create a new bus type.
>
> How do platform devices work with module autoloading? What I'm interested
> in is to have stuff like the Fedora installer or kernels with modular
> drivers 'just work' because they can use the same way to load their
> modules that is already used for PCI devices.
>
> AFAICS, that requires at least two things:
> - The device needs to be created when the bus is probed, i.e.
> of_device_register can not be called from inside the driver
> module_init() function.
>
This is already handled by the platform device in the kernel.
> - The bus type needs to create a modalias file so user space can
> do the matching with the of device table in the modules.
Seems like a simple thing to add to platform device.
> Both of these should be a lot easier to implement with a special
> bus type that creates entries in sysfs for a subset of the OF
> device tree.
I still dont see what a new bus type get us. I'm going to have to have
specific code to parse and build and register my devices. If that could
ends up registering a platform device or a newflatOF device I dont see any
real difference.
> The alternative would be to represent all of the device tree
> in /sys/devices, but IMHO that should better be part of
> /sys/firmware with symlinks to the linux internal device tree
> representation.
Today I have:
/sys/devices/platform/
fsl-gianfar.1
fsl-i2c.1
fsl-i2c.2
fsl-sec2.1
fsl-usb2-dr.1
fsl-usb2-mph.1
serial8250
serial8250.0
- kumar
^ permalink raw reply
* yaboot mailing lists - new home
From: Paul Nasrat @ 2005-12-20 16:08 UTC (permalink / raw)
To: Ethan Benson, linuxppc-dev; +Cc: linuxppc64-dev
Following the hardware failure on penguinppc.org I've managed to arrange
hosting thanks to the kind administrators at ozlabs
https://ozlabs.org/mailman/listinfo/yaboot-devel
https://ozlabs.org/mailman/listinfo/yaboot-users
I haven't pushed any content there yet, but I think we were aiming at a
test release shortly so having the lists back will help.
Paul
^ permalink raw reply
* Re: [PATCH 3/3] ppc32: Adds MPC885ADS, MPC866ADS and MPC8272ADS-specific platform stuff for fs_enet
From: Kumar Gala @ 2005-12-20 15:02 UTC (permalink / raw)
To: Vitaly Bordug; +Cc: linuxppc-embedded list
In-Reply-To: <43A6B3E3.6030105@ru.mvista.com>
I really dont care for how fs_platform_info is laid out and what we
are passing into the driver vs what it can figure out itself or
maintain itself going forward. I guess we will clean this up when we
move to a flat device tree.
- kumar
On Dec 19, 2005, at 7:21 AM, Vitaly Bordug wrote:
> Added proper ppc_sys identification and fs_platform_info's for MPC
> 885ADS,
> 866ADS and 8272ADS, utilizing function assignment to remove/do not use
> platform devices which conflict with PD-incompatible drivers.
>
> Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>
>
>
> ---
>
> arch/ppc/Kconfig | 47 ++++
> arch/ppc/platforms/Makefile | 4
> arch/ppc/platforms/fads.h | 2
> arch/ppc/platforms/mpc8272ads_setup.c | 235 ++++++++++++++++++++
> arch/ppc/platforms/mpc866ads_setup.c | 269 +++++++++++++++++++++++
> arch/ppc/platforms/mpc885ads_setup.c | 387 ++++++++++++++++++++++
> +++++++++++
> arch/ppc/platforms/pq2ads.h | 4
> arch/ppc/platforms/pq2ads_pd.h | 114 ++++++++++
> 8 files changed, 1061 insertions(+), 1 deletions(-)
> create mode 100644 arch/ppc/platforms/mpc8272ads_setup.c
> create mode 100644 arch/ppc/platforms/mpc866ads_setup.c
> create mode 100644 arch/ppc/platforms/mpc885ads_setup.c
> create mode 100644 arch/ppc/platforms/pq2ads_pd.h
>
> applies-to: f51b03be0daf16352ec61e3499f61c95adf115e7
> 5406392976524c1e504f2a612f49eac2b41dc16c
> diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
> index cc3f64c..ac32793 100644
> --- a/arch/ppc/Kconfig
> +++ b/arch/ppc/Kconfig
> @@ -506,6 +506,53 @@ config WINCEPT
>
> endchoice
>
> +menu "Freescale Ethernet driver platform-specific options"
> + depends on FS_ENET
> +
> + config MPC8xx_SECOND_ETH
> + bool "Second Ethernet channel"
> + depends on (MPC885ADS || MPC86XADS)
> + default y
> + help
> + This enables support for second Ethernet on MPC885ADS and
> MPC86xADS boards.
> + The latter will use SCC1, for 885ADS you can select it below.
> +
> + choice
> + prompt "Second Ethernet channel"
> + depends on MPC8xx_SECOND_ETH
> + default MPC8xx_SECOND_ETH_FEC2
> +
> + config MPC8xx_SECOND_ETH_FEC2
> + bool "FEC2"
> + depends on MPC885ADS
> + help
> + Enable FEC2 to serve as 2-nd Ethernet channel. Note that SMC2
> + (often 2-nd UART) will not work if this is enabled.
> +
> + config MPC8xx_SECOND_ETH_SCC1
> + bool "SCC1"
> + depends on MPC86XADS
> + select MPC8xx_SCC_ENET_FIXED
> + help
> + Enable SCC1 to serve as 2-nd Ethernet channel. Note that SMC1
> + (often 1-nd UART) will not work if this is enabled.
> +
> + config MPC8xx_SECOND_ETH_SCC3
> + bool "SCC3"
> + depends on MPC885ADS
> + help
> + Enable SCC3 to serve as 2-nd Ethernet channel. Note that SMC1
> + (often 1-nd UART) will not work if this is enabled.
> +
> + endchoice
> +
> + config MPC8xx_SCC_ENET_FIXED
> + depends on MPC8xx_SECOND_ETH_SCC
> + default n
> + bool "Use fixed MII-less mode for SCC Ethernet"
> +
> +endmenu
> +
> choice
> prompt "Machine Type"
> depends on 6xx || POWER3 || POWER4
> diff --git a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile
> index 7c5cdab..ee50b0d 100644
> --- a/arch/ppc/platforms/Makefile
> +++ b/arch/ppc/platforms/Makefile
> @@ -22,6 +22,8 @@ ifeq ($(CONFIG_PPC_PMAC),y)
> obj-$(CONFIG_NVRAM) += pmac_nvram.o
> obj-$(CONFIG_CPU_FREQ_PMAC) += pmac_cpufreq.o
> endif
> +
> +obj-$(CONFIG_ADS8272) += mpc8272ads_setup.o
> obj-$(CONFIG_PMAC_BACKLIGHT) += pmac_backlight.o
> obj-$(CONFIG_PREP_RESIDUAL) += residual.o
> obj-$(CONFIG_PQ2ADS) += pq2ads.o
> @@ -45,6 +47,8 @@ obj-$(CONFIG_SBC82xx) += sbc82xx.o
> obj-$(CONFIG_SPRUCE) += spruce.o
> obj-$(CONFIG_LITE5200) += lite5200.o
> obj-$(CONFIG_EV64360) += ev64360.o
> +obj-$(CONFIG_MPC86XADS) += mpc866ads_setup.o
> +obj-$(CONFIG_MPC885ADS) += mpc885ads_setup.o
>
> ifeq ($(CONFIG_SMP),y)
> obj-$(CONFIG_PPC_PMAC) += pmac_smp.o
> diff --git a/arch/ppc/platforms/fads.h b/arch/ppc/platforms/fads.h
> index a48fb8d..e1c0b1b 100644
> --- a/arch/ppc/platforms/fads.h
> +++ b/arch/ppc/platforms/fads.h
> @@ -112,7 +112,7 @@
>
> /* CPM Ethernet through SCC1 or SCC2 */
>
> -#ifdef CONFIG_SCC1_ENET /* Probably 860 variant */
> +#if defined(CONFIG_SCC1_ENET) || defined
> (CONFIG_MPC8xx_SECOND_ETH_SCC1) /* Probably 860 variant */
> /* Bits in parallel I/O port registers that have to be set/cleared
> * to configure the pins for SCC1 use.
> * TCLK - CLK1, RCLK - CLK2.
> diff --git a/arch/ppc/platforms/mpc8272ads_setup.c b/arch/ppc/
> platforms/mpc8272ads_setup.c
> new file mode 100644
> index 0000000..0f228ad
> --- /dev/null
> +++ b/arch/ppc/platforms/mpc8272ads_setup.c
> @@ -0,0 +1,235 @@
> +/*
> + * arch/ppc/platforms/82xx/pq2ads_pd.c
> + *
> + * MPC82xx Board-specific PlatformDevice descriptions
> + *
> + * 2005 (c) MontaVista Software, Inc.
> + * Vitaly Bordug <vbordug@ru.mvista.com>
> + *
> + * 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.
> + */
> +
> +
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/device.h>
> +#include <linux/ioport.h>
> +#include <linux/fs_enet_pd.h>
> +
> +#include <asm/io.h>
> +#include <asm/mpc8260.h>
> +#include <asm/cpm2.h>
> +#include <asm/immap_cpm2.h>
> +#include <asm/irq.h>
> +#include <asm/ppc_sys.h>
> +#include <asm/ppcboot.h>
> +
> +#include "pq2ads_pd.h"
> +
> +static void init_fcc1_ioports(void);
> +static void init_fcc2_ioports(void);
> +
> +static struct fs_mii_bus_info mii_bus_info = {
> + .method = fsmii_bitbang,
> + .id = 0,
> + .i.bitbang = {
> + .mdio_port = fsiop_portc,
> + .mdio_bit = 18,
> + .mdc_port = fsiop_portc,
> + .mdc_bit = 19,
> + .delay = 1,
> + },
> +};
> +
> +static struct fs_platform_info mpc82xx_fcc1_pdata = {
> + .fs_no = fsid_fcc1,
> + .cp_page = CPM_CR_FCC1_PAGE,
> + .cp_block = CPM_CR_FCC1_SBLOCK,
> + .clk_trx = (PC_F1RXCLK | PC_F1TXCLK),
> + .clk_route = CMX1_CLK_ROUTE,
> + .clk_mask = CMX1_CLK_MASK,
> + .init_ioports = init_fcc1_ioports,
> +
> + .phy_addr = 0,
> +#ifdef PHY_INTERRUPT
> + .phy_irq = PHY_INTERRUPT,
> +#else
> + .phy_irq = -1;
> +#endif
> + .mem_offset = FCC1_MEM_OFFSET,
> + .bus_info = &mii_bus_info,
> + .rx_ring = 32,
> + .tx_ring = 32,
> + .rx_copybreak = 240,
> + .use_napi = 0,
> + .napi_weight = 17,
> +};
> +
> +static struct fs_platform_info mpc82xx_fcc2_pdata = {
> + .fs_no = fsid_fcc2,
> + .cp_page = CPM_CR_FCC2_PAGE,
> + .cp_block = CPM_CR_FCC2_SBLOCK,
> + .clk_trx = (PC_F2RXCLK | PC_F2TXCLK),
> + .clk_route = CMX2_CLK_ROUTE,
> + .clk_mask = CMX2_CLK_MASK,
> + .init_ioports = init_fcc2_ioports,
> +
> + .phy_addr = 3,
> +#ifdef PHY_INTERRUPT
> + .phy_irq = PHY_INTERRUPT,
> +#else
> + .phy_irq = -1;
> +#endif
> + .mem_offset = FCC2_MEM_OFFSET,
> + .bus_info = &mii_bus_info,
> + .rx_ring = 32,
> + .tx_ring = 32,
> + .rx_copybreak = 240,
> + .use_napi = 0,
> + .napi_weight = 17,
> +};
> +
> +static void init_fcc1_ioports(void)
> +{
> + struct io_port *io;
> + u32 tempval;
> + cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
> + u32 *bcsr = ioremap(BCSR_ADDR+4, sizeof(u32));
> +
> + io = &immap->im_ioport;
> +
> + /* Enable the PHY */
> + clrbits32(bcsr, BCSR1_FETHIEN);
> + setbits32(bcsr, BCSR1_FETH_RST);
> +
> + /* FCC1 pins are on port A/C. */
> + /* Configure port A and C pins for FCC1 Ethernet. */
> +
> + tempval = in_be32(&io->iop_pdira);
> + tempval &= ~PA1_DIRA0;
> + tempval |= PA1_DIRA1;
> + out_be32(&io->iop_pdira, tempval);
> +
> + tempval = in_be32(&io->iop_psora);
> + tempval &= ~PA1_PSORA0;
> + tempval |= PA1_PSORA1;
> + out_be32(&io->iop_psora, tempval);
> +
> + setbits32(&io->iop_ppara,PA1_DIRA0 | PA1_DIRA1);
> +
> + /* Alter clocks */
> + tempval = PC_F1TXCLK|PC_F1RXCLK;
> +
> + clrbits32(&io->iop_psorc, tempval);
> + clrbits32(&io->iop_pdirc, tempval);
> + setbits32(&io->iop_pparc, tempval);
> +
> + clrbits32(&immap->im_cpmux.cmx_fcr, CMX1_CLK_MASK);
> + setbits32(&immap->im_cpmux.cmx_fcr, CMX1_CLK_ROUTE);
> + iounmap(bcsr);
> + iounmap(immap);
> +}
> +
> +static void init_fcc2_ioports(void)
> +{
> + cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
> + u32 *bcsr = ioremap(BCSR_ADDR+12, sizeof(u32));
> +
> + struct io_port *io;
> + u32 tempval;
> +
> + immap = cpm2_immr;
> +
> + io = &immap->im_ioport;
> +
> + /* Enable the PHY */
> + clrbits32(bcsr, BCSR3_FETHIEN2);
> + setbits32(bcsr, BCSR3_FETH2_RST);
> +
> + /* FCC2 are port B/C. */
> + /* Configure port A and C pins for FCC2 Ethernet. */
> +
> + tempval = in_be32(&io->iop_pdirb);
> + tempval &= ~PB2_DIRB0;
> + tempval |= PB2_DIRB1;
> + out_be32(&io->iop_pdirb, tempval);
> +
> + tempval = in_be32(&io->iop_psorb);
> + tempval &= ~PB2_PSORB0;
> + tempval |= PB2_PSORB1;
> + out_be32(&io->iop_psorb, tempval);
> +
> + setbits32(&io->iop_pparb,PB2_DIRB0 | PB2_DIRB1);
> +
> + tempval = PC_F2RXCLK|PC_F2TXCLK;
> +
> + /* Alter clocks */
> + clrbits32(&io->iop_psorc,tempval);
> + clrbits32(&io->iop_pdirc,tempval);
> + setbits32(&io->iop_pparc,tempval);
> +
> + clrbits32(&immap->im_cpmux.cmx_fcr, CMX2_CLK_MASK);
> + setbits32(&immap->im_cpmux.cmx_fcr, CMX2_CLK_ROUTE);
> +
> + iounmap(bcsr);
> + iounmap(immap);
> +}
> +
> +
> +static void __init mpc8272ads_fixup_enet_pdata(struct
> platform_device *pdev,
> + int idx)
> +{
> + bd_t* bi = (void*)__res;
> + int fs_no = fsid_fcc1+pdev->id-1;
> +
> + mpc82xx_fcc1_pdata.dpram_offset = mpc82xx_fcc2_pdata.dpram_offset
> = (u32)cpm2_immr->im_dprambase;
> + mpc82xx_fcc1_pdata.fcc_regs_c = mpc82xx_fcc2_pdata.fcc_regs_c =
> (u32)cpm2_immr->im_fcc_c;
> +
> + switch(fs_no) {
> + case fsid_fcc1:
> + memcpy(&mpc82xx_fcc1_pdata.macaddr,bi->bi_enetaddr,6);
> + pdev->dev.platform_data = &mpc82xx_fcc1_pdata;
> + break;
> + case fsid_fcc2:
> + memcpy(&mpc82xx_fcc2_pdata.macaddr,bi->bi_enetaddr,6);
> + mpc82xx_fcc2_pdata.macaddr[5] ^= 1;
> + pdev->dev.platform_data = &mpc82xx_fcc2_pdata;
> + break;
> + }
> + printk("all\n");
> +}
> +
> +static int mpc8272ads_platform_notify(struct device *dev)
> +{
> + static const struct platform_notify_dev_map dev_map[] = {
> + {
> + .bus_id = "fsl-cpm-fcc",
> + .rtn = mpc8272ads_fixup_enet_pdata
> + },
> + {
> + .bus_id = NULL
> + }
> + };
> + platform_notify_map(dev_map,dev);
> +
> + return 0;
> +
> +}
> +
> +int __init mpc8272ads_init(void)
> +{
> + printk(KERN_NOTICE "mpc8272ads: Init\n");
> +
> + platform_notify = mpc8272ads_platform_notify;
> +
> + ppc_sys_device_initfunc();
> + ppc_sys_device_set_func_all(FUNC_DISABLED);
> + ppc_sys_device_setfunc(MPC82xx_CPM_FCC1, FUNC_ENABLED);
> + ppc_sys_device_setfunc(MPC82xx_CPM_FCC2, FUNC_ENABLED);
> +
> + return 0;
> +}
> +
> +arch_initcall(mpc8272ads_init);
> diff --git a/arch/ppc/platforms/mpc866ads_setup.c b/arch/ppc/
> platforms/mpc866ads_setup.c
> new file mode 100644
> index 0000000..ed1b050
> --- /dev/null
> +++ b/arch/ppc/platforms/mpc866ads_setup.c
> @@ -0,0 +1,269 @@
> +/*arch/ppc/platforms/mpc885ads-setup.c
> + *
> + * Platform setup for the Freescale mpc885ads board
> + *
> + * Vitaly Bordug <vbordug@ru.mvista.com>
> + *
> + * Copyright 2005 MontaVista Software Inc.
> + *
> + * 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.
> + */
> +
> +#include <linux/config.h>
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/param.h>
> +#include <linux/string.h>
> +#include <linux/ioport.h>
> +#include <linux/device.h>
> +
> +#include <linux/fs_enet_pd.h>
> +#include <linux/mii.h>
> +
> +#include <asm/delay.h>
> +#include <asm/io.h>
> +#include <asm/machdep.h>
> +#include <asm/page.h>
> +#include <asm/processor.h>
> +#include <asm/system.h>
> +#include <asm/time.h>
> +#include <asm/ppcboot.h>
> +#include <asm/8xx_immap.h>
> +#include <asm/commproc.h>
> +#include <asm/ppc_sys.h>
> +#include <asm/mpc8xx.h>
> +
> +extern unsigned char __res[];
> +
> +static struct fs_mii_bus_info fec_mii_bus_info = {
> + .method = fsmii_fec,
> + .id = 0,
> +};
> +
> +static struct fs_mii_bus_info scc_mii_bus_info = {
> + .method = fsmii_fixed,
> + .id = 0,
> + .i.fixed.speed = 10,
> + .i.fixed.duplex = 0,
> +};
> +
> +static struct fs_platform_info mpc8xx_fec_pdata[] = {
> + {
> + .rx_ring = 128,
> + .tx_ring = 16,
> + .rx_copybreak = 240,
> +
> + .use_napi = 1,
> + .napi_weight = 17,
> +
> + .phy_addr = 15,
> + .phy_irq = -1,
> +
> + .use_rmii = 0,
> +
> + .bus_info = &fec_mii_bus_info,
> + }
> +};
> +
> +static struct fs_platform_info mpc8xx_scc_pdata = {
> + .rx_ring = 64,
> + .tx_ring = 8,
> + .rx_copybreak = 240,
> +
> + .use_napi = 1,
> + .napi_weight = 17,
> +
> + .phy_addr = -1,
> + .phy_irq = -1,
> +
> + .bus_info = &scc_mii_bus_info,
> +};
> +
> +void __init board_init(void)
> +{
> + volatile cpm8xx_t *cp = cpmp;
> + unsigned *bcsr_io;
> +
> + bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
> +
> + if (bcsr_io == NULL) {
> + printk(KERN_CRIT "Could not remap BCSR1\n");
> + return;
> + }
> +#ifdef CONFIG_SERIAL_CPM_SMC1
> + cp->cp_simode &= ~(0xe0000000 >> 17); /* brg1 */
> + clrbits32(bcsr_io,(0x80000000 >> 7));
> +#else
> + setbits32(bcsr_io,(0x80000000 >> 7));
> +
> + cp->cp_pbpar &= ~(0x000000c0);
> + cp->cp_pbdir |= 0x000000c0;
> + cp->cp_smc[0].smc_smcmr = 0;
> + cp->cp_smc[0].smc_smce = 0;
> +#endif
> +
> +#ifdef CONFIG_SERIAL_CPM_SMC2
> + cp->cp_simode &= ~(0xe0000000 >> 1);
> + cp->cp_simode |= (0x20000000 >> 1); /* brg2 */
> + clrbits32(bcsr_io,(0x80000000 >> 13));
> +#else
> + clrbits32(bcsr_io,(0x80000000 >> 13));
> + cp->cp_pbpar &= ~(0x00000c00);
> + cp->cp_pbdir |= 0x00000c00;
> + cp->cp_smc[1].smc_smcmr = 0;
> + cp->cp_smc[1].smc_smce = 0;
> +#endif
> + iounmap(bcsr_io);
> +}
> +
> +static void setup_fec1_ioports(void)
> +{
> + immap_t *immap = (immap_t *) IMAP_ADDR;
> +
> + setbits16(&immap->im_ioport.iop_pdpar, 0x1fff);
> + setbits16(&immap->im_ioport.iop_pddir, 0x1fff);
> +}
> +
> +static void setup_scc1_ioports(void)
> +{
> + immap_t *immap = (immap_t *) IMAP_ADDR;
> + unsigned *bcsr_io;
> +
> + bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
> +
> + if (bcsr_io == NULL) {
> + printk(KERN_CRIT "Could not remap BCSR1\n");
> + return;
> + }
> +
> + /* Enable the PHY.
> + */
> + clrbits32(bcsr_io,BCSR1_ETHEN);
> +
> + /* Configure port A pins for Txd and Rxd.
> + */
> + /* Disable receive and transmit in case EPPC-Bug started it.
> + */
> + setbits16(&immap->im_ioport.iop_papar, PA_ENET_RXD | PA_ENET_TXD);
> + clrbits16(&immap->im_ioport.iop_padir, PA_ENET_RXD | PA_ENET_TXD);
> + clrbits16(&immap->im_ioport.iop_paodr, PA_ENET_TXD);
> +
> + /* Configure port C pins to enable CLSN and RENA.
> + */
> + clrbits16(&immap->im_ioport.iop_pcpar, PC_ENET_CLSN | PC_ENET_RENA);
> + clrbits16(&immap->im_ioport.iop_pcdir, PC_ENET_CLSN | PC_ENET_RENA);
> + setbits16(&immap->im_ioport.iop_pcso, PC_ENET_CLSN | PC_ENET_RENA);
> + /* Configure port A for TCLK and RCLK.
> + */
> + setbits16(&immap->im_ioport.iop_papar, PA_ENET_TCLK | PA_ENET_RCLK);
> + clrbits16(&immap->im_ioport.iop_padir, PA_ENET_TCLK | PA_ENET_RCLK);
> + clrbits32(&immap->im_cpm.cp_pbpar, PB_ENET_TENA);
> + clrbits32(&immap->im_cpm.cp_pbdir, PB_ENET_TENA);
> +
> + /* Configure Serial Interface clock routing.
> + * First, clear all SCC bits to zero, then set the ones we want.
> + */
> + clrbits32(&immap->im_cpm.cp_sicr, SICR_ENET_MASK);
> + setbits32(&immap->im_cpm.cp_sicr, SICR_ENET_CLKRT);
> +
> + /* In the original SCC enet driver the following code is placed at
> + the end of the initialization */
> + setbits32(&immap->im_cpm.cp_pbpar, PB_ENET_TENA);
> + setbits32(&immap->im_cpm.cp_pbdir, PB_ENET_TENA);
> +
> +}
> +
> +static void mpc866ads_fixup_enet_pdata(struct platform_device
> *pdev, int fs_no)
> +{
> + struct fs_platform_info *fpi = pdev->dev.platform_data;
> +
> + volatile cpm8xx_t *cp;
> + bd_t *bd = (bd_t *) __res;
> + char *e;
> + int i;
> +
> + /* Get pointer to Communication Processor */
> + cp = cpmp;
> + switch (fs_no) {
> + case fsid_fec1:
> + fpi = &mpc8xx_fec_pdata[0];
> + fpi->init_ioports = &setup_fec1_ioports;
> +
> + break;
> + case fsid_scc1:
> + fpi = &mpc8xx_scc_pdata;
> + fpi->init_ioports = &setup_scc1_ioports;
> +
> + break;
> + default:
> + break;
> + }
> +
> + pdev->dev.platform_data = fpi;
> + fpi->fs_no = fs_no;
> +
> + e = (unsigned char *)&bd->bi_enetaddr;
> + for (i = 0; i < 6; i++)
> + fpi->macaddr[i] = *e++;
> +
> + fpi->macaddr[5 - pdev->id]++;
> +
> +}
> +
> +static void mpc866ads_fixup_fec_enet_pdata(struct platform_device
> *pdev,
> + int idx)
> +{
> + /* This is for FEC devices only */
> + if (strcmp(pdev->name, "fsl-cpm-fec"))
> + return;
> + mpc866ads_fixup_enet_pdata(pdev, fsid_fec1 + pdev->id - 1);
> +}
> +
> +static void mpc866ads_fixup_scc_enet_pdata(struct platform_device
> *pdev,
> + int idx)
> +{
> + /* This is for SCC devices only */
> + if (strcmp(pdev->name, "fsl-cpm-scc"))
> + return;
> +
> + mpc866ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
> +}
> +
> +static int mpc866ads_platform_notify(struct device *dev)
> +{
> + static const struct platform_notify_dev_map dev_map[] = {
> + {
> + .bus_id = "fsl-cpm-fec",
> + .rtn = mpc866ads_fixup_fec_enet_pdata,
> + },
> + {
> + .bus_id = "fsl-cpm-scc",
> + .rtn = mpc866ads_fixup_scc_enet_pdata,
> + },
> + {
> + .bus_id = NULL
> + }
> + };
> +
> + platform_notify_map(dev_map,dev);
> +
> + return 0;
> +}
> +
> +int __init mpc866ads_init(void)
> +{
> + printk(KERN_NOTICE "mpc866ads: Init\n");
> +
> + platform_notify = mpc866ads_platform_notify;
> +
> + ppc_sys_device_initfunc();
> + ppc_sys_device_set_func_all(FUNC_DISABLED);
> + ppc_sys_device_setfunc(MPC8xx_CPM_SCC1, FUNC_ENABLED);
> + ppc_sys_device_setfunc(MPC8xx_CPM_FEC1, FUNC_ENABLED);
> +
> + return 0;
> +}
> +
> +arch_initcall(mpc866ads_init);
> diff --git a/arch/ppc/platforms/mpc885ads_setup.c b/arch/ppc/
> platforms/mpc885ads_setup.c
> new file mode 100644
> index 0000000..feefa91
> --- /dev/null
> +++ b/arch/ppc/platforms/mpc885ads_setup.c
> @@ -0,0 +1,387 @@
> +/*arch/ppc/platforms/mpc885ads-setup.c
> + *
> + * Platform setup for the Freescale mpc885ads board
> + *
> + * Vitaly Bordug <vbordug@ru.mvista.com>
> + *
> + * Copyright 2005 MontaVista Software Inc.
> + *
> + * 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.
> + */
> +
> +#include <linux/config.h>
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/param.h>
> +#include <linux/string.h>
> +#include <linux/ioport.h>
> +#include <linux/device.h>
> +
> +#include <linux/fs_enet_pd.h>
> +#include <linux/mii.h>
> +
> +#include <asm/delay.h>
> +#include <asm/io.h>
> +#include <asm/machdep.h>
> +#include <asm/page.h>
> +#include <asm/processor.h>
> +#include <asm/system.h>
> +#include <asm/time.h>
> +#include <asm/ppcboot.h>
> +#include <asm/8xx_immap.h>
> +#include <asm/commproc.h>
> +#include <asm/ppc_sys.h>
> +
> +extern unsigned char __res[];
> +
> +static void __init mpc885ads_scc_phy_init(char);
> +
> +static struct fs_mii_bus_info fec_mii_bus_info = {
> + .method = fsmii_fec,
> + .id = 0,
> +};
> +
> +static struct fs_mii_bus_info scc_mii_bus_info = {
> +#ifdef CONFIG_SCC_ENET_8xx_FIXED
> + .method = fsmii_fixed,
> +#else
> + .method = fsmii_fec,
> +#endif
> +
> + .id = 0,
> +};
> +
> +static struct fs_platform_info mpc8xx_fec_pdata[] = {
> + {
> + .rx_ring = 128,
> + .tx_ring = 16,
> + .rx_copybreak = 240,
> +
> + .use_napi = 1,
> + .napi_weight = 17,
> +
> + .phy_addr = 0,
> + .phy_irq = SIU_IRQ7,
> +
> + .bus_info = &fec_mii_bus_info,
> + }, {
> + .rx_ring = 128,
> + .tx_ring = 16,
> + .rx_copybreak = 240,
> +
> + .use_napi = 1,
> + .napi_weight = 17,
> +
> + .phy_addr = 1,
> + .phy_irq = SIU_IRQ7,
> +
> + .bus_info = &fec_mii_bus_info,
> + }
> +};
> +
> +static struct fs_platform_info mpc8xx_scc_pdata = {
> + .rx_ring = 64,
> + .tx_ring = 8,
> + .rx_copybreak = 240,
> +
> + .use_napi = 1,
> + .napi_weight = 17,
> +
> + .phy_addr = 2,
> +#ifdef CONFIG_MPC8xx_SCC_ENET_FIXED
> + .phy_irq = -1,
> +#else
> + .phy_irq = SIU_IRQ7,
> +#endif
> +
> + .bus_info = &scc_mii_bus_info,
> +};
> +
> +void __init board_init(void)
> +{
> + volatile cpm8xx_t *cp = cpmp;
> + unsigned int *bcsr_io;
> +
> +#ifdef CONFIG_FS_ENET
> + immap_t *immap = (immap_t *) IMAP_ADDR;
> +#endif
> + bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
> +
> + if (bcsr_io == NULL) {
> + printk(KERN_CRIT "Could not remap BCSR\n");
> + return;
> + }
> +#ifdef CONFIG_SERIAL_CPM_SMC1
> + cp->cp_simode &= ~(0xe0000000 >> 17); /* brg1 */
> + clrbits32(bcsr_io, BCSR1_RS232EN_1);
> +#else
> + setbits32(bcsr_io,BCSR1_RS232EN_1);
> + cp->cp_smc[0].smc_smcmr = 0;
> + cp->cp_smc[0].smc_smce = 0;
> +#endif
> +
> +#ifdef CONFIG_SERIAL_CPM_SMC2
> + cp->cp_simode &= ~(0xe0000000 >> 1);
> + cp->cp_simode |= (0x20000000 >> 1); /* brg2 */
> + clrbits32(bcsr_io,BCSR1_RS232EN_2);
> +#else
> + setbits32(bcsr_io,BCSR1_RS232EN_2);
> + cp->cp_smc[1].smc_smcmr = 0;
> + cp->cp_smc[1].smc_smce = 0;
> +#endif
> + iounmap(bcsr_io);
> +
> +#ifdef CONFIG_FS_ENET
> + /* use MDC for MII (common) */
> + setbits16(&immap->im_ioport.iop_pdpar, 0x0080);
> + clrbits16(&immap->im_ioport.iop_pddir, 0x0080);
> +#endif
> +}
> +
> +static void setup_fec1_ioports(void)
> +{
> + immap_t *immap = (immap_t *) IMAP_ADDR;
> +
> + /* configure FEC1 pins */
> + setbits16(&immap->im_ioport.iop_papar, 0xf830);
> + setbits16(&immap->im_ioport.iop_padir, 0x0830);
> + clrbits16(&immap->im_ioport.iop_padir, 0xf000);
> + setbits32(&immap->im_cpm.cp_pbpar, 0x00001001);
> +
> + clrbits32(&immap->im_cpm.cp_pbdir, 0x00001001);
> + setbits16(&immap->im_ioport.iop_pcpar, 0x000c);
> + clrbits16(&immap->im_ioport.iop_pcdir, 0x000c);
> + setbits32(&immap->im_cpm.cp_pepar, 0x00000003);
> +
> + setbits32(&immap->im_cpm.cp_pedir, 0x00000003);
> + clrbits32(&immap->im_cpm.cp_peso, 0x00000003);
> + clrbits32(&immap->im_cpm.cp_cptr, 0x00000100);
> +}
> +
> +static void setup_fec2_ioports(void)
> +{
> + immap_t *immap = (immap_t *) IMAP_ADDR;
> +
> + /* configure FEC2 pins */
> + setbits32(&immap->im_cpm.cp_pepar, 0x0003fffc);
> + setbits32(&immap->im_cpm.cp_pedir, 0x0003fffc);
> + setbits32(&immap->im_cpm.cp_peso, 0x00037800);
> + clrbits32(&immap->im_cpm.cp_peso, 0x000087fc);
> + clrbits32(&immap->im_cpm.cp_cptr, 0x00000080);
> +}
> +
> +static void setup_scc3_ioports(void)
> +{
> + immap_t *immap = (immap_t *) IMAP_ADDR;
> + unsigned *bcsr_io;
> +
> + bcsr_io = ioremap(BCSR_ADDR, BCSR_SIZE);
> +
> + if (bcsr_io == NULL) {
> + printk(KERN_CRIT "Could not remap BCSR\n");
> + return;
> + }
> +
> + /* Enable the PHY.
> + */
> + setbits32(bcsr_io+4, BCSR4_ETH10_RST);
> + /* Configure port A pins for Txd and Rxd.
> + */
> + setbits16(&immap->im_ioport.iop_papar, PA_ENET_RXD | PA_ENET_TXD);
> + clrbits16(&immap->im_ioport.iop_padir, PA_ENET_RXD | PA_ENET_TXD);
> +
> + /* Configure port C pins to enable CLSN and RENA.
> + */
> + clrbits16(&immap->im_ioport.iop_pcpar, PC_ENET_CLSN | PC_ENET_RENA);
> + clrbits16(&immap->im_ioport.iop_pcdir, PC_ENET_CLSN | PC_ENET_RENA);
> + setbits16(&immap->im_ioport.iop_pcso, PC_ENET_CLSN | PC_ENET_RENA);
> +
> + /* Configure port E for TCLK and RCLK.
> + */
> + setbits32(&immap->im_cpm.cp_pepar, PE_ENET_TCLK | PE_ENET_RCLK);
> + clrbits32(&immap->im_cpm.cp_pepar, PE_ENET_TENA);
> + clrbits32(&immap->im_cpm.cp_pedir,
> + PE_ENET_TCLK | PE_ENET_RCLK | PE_ENET_TENA);
> + clrbits32(&immap->im_cpm.cp_peso, PE_ENET_TCLK | PE_ENET_RCLK);
> + setbits32(&immap->im_cpm.cp_peso, PE_ENET_TENA);
> +
> + /* Configure Serial Interface clock routing.
> + * First, clear all SCC bits to zero, then set the ones we want.
> + */
> + clrbits32(&immap->im_cpm.cp_sicr, SICR_ENET_MASK);
> + setbits32(&immap->im_cpm.cp_sicr, SICR_ENET_CLKRT);
> +
> + /* Disable Rx and Tx. SMC1 sshould be stopped if SCC3 eternet are
> used.
> + */
> + immap->im_cpm.cp_smc[0].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
> + /* On the MPC885ADS SCC ethernet PHY is initialized in the full
> duplex mode
> + * by H/W setting after reset. SCC ethernet controller support
> only half duplex.
> + * This discrepancy of modes causes a lot of carrier lost errors.
> + */
> +
> + /* In the original SCC enet driver the following code is placed at
> + the end of the initialization */
> + setbits32(&immap->im_cpm.cp_pepar, PE_ENET_TENA);
> + clrbits32(&immap->im_cpm.cp_pedir, PE_ENET_TENA);
> + setbits32(&immap->im_cpm.cp_peso, PE_ENET_TENA);
> +
> + setbits32(bcsr_io+1, BCSR1_ETHEN);
> + iounmap(bcsr_io);
> +}
> +
> +static void mpc885ads_fixup_enet_pdata(struct platform_device
> *pdev, int fs_no)
> +{
> + struct fs_platform_info *fpi = pdev->dev.platform_data;
> +
> + volatile cpm8xx_t *cp;
> + bd_t *bd = (bd_t *) __res;
> + char *e;
> + int i;
> +
> + /* Get pointer to Communication Processor */
> + cp = cpmp;
> + switch (fs_no) {
> + case fsid_fec1:
> + fpi = &mpc8xx_fec_pdata[0];
> + fpi->init_ioports = &setup_fec1_ioports;
> + break;
> + case fsid_fec2:
> + fpi = &mpc8xx_fec_pdata[1];
> + fpi->init_ioports = &setup_fec2_ioports;
> + break;
> + case fsid_scc3:
> + fpi = &mpc8xx_scc_pdata;
> + fpi->init_ioports = &setup_scc3_ioports;
> + mpc885ads_scc_phy_init(fpi->phy_addr);
> + break;
> + default:
> + break;
> + }
> +
> + pdev->dev.platform_data = fpi;
> + fpi->fs_no = fs_no;
> +
> + e = (unsigned char *)&bd->bi_enetaddr;
> + for (i = 0; i < 6; i++)
> + fpi->macaddr[i] = *e++;
> +
> + fpi->macaddr[5 - pdev->id]++;
> +
> +}
> +
> +static void mpc885ads_fixup_fec_enet_pdata(struct platform_device
> *pdev,
> + int idx)
> +{
> + /* This is for FEC devices only */
> + if (!strstr(pdev->name, "fsl-cpm-fec"))
> + return;
> + mpc885ads_fixup_enet_pdata(pdev, fsid_fec1 + pdev->id - 1);
> +}
> +
> +static void __init mpc885ads_fixup_scc_enet_pdata(struct
> platform_device *pdev,
> + int idx)
> +{
> + /* This is for SCC devices only */
> + if (!strstr(pdev->name, "fsl-cpm-scc"))
> + return;
> +
> + mpc885ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
> +}
> +
> +/* SCC ethernet controller does not have MII management channel.
> FEC1 MII
> + * channel is used to communicate with the 10Mbit PHY.
> + */
> +
> +#define MII_ECNTRL_PINMUX 0x4
> +#define FEC_ECNTRL_PINMUX 0x00000004
> +#define FEC_RCNTRL_MII_MODE 0x00000004
> +
> +/* Make MII read/write commands.
> + */
> +#define mk_mii_write(REG, VAL, PHY_ADDR) (0x50020000 | (((REG)
> & 0x1f) << 18) | \
> + ((VAL) & 0xffff) | ((PHY_ADDR) << 23))
> +
> +static void mpc885ads_scc_phy_init(char phy_addr)
> +{
> + volatile immap_t *immap;
> + volatile fec_t *fecp;
> + bd_t *bd;
> +
> + bd = (bd_t *) __res;
> + immap = (immap_t *) IMAP_ADDR; /* pointer to internal registers */
> + fecp = &(immap->im_cpm.cp_fec);
> +
> + /* Enable MII pins of the FEC1
> + */
> + setbits16(&immap->im_ioport.iop_pdpar, 0x0080);
> + clrbits16(&immap->im_ioport.iop_pddir, 0x0080);
> + /* Set MII speed to 2.5 MHz
> + */
> + out_be32(&fecp->fec_mii_speed,
> + ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1);
> +
> + /* Enable FEC pin MUX
> + */
> + setbits32(&fecp->fec_ecntrl, MII_ECNTRL_PINMUX);
> + setbits32(&fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE);
> +
> + out_be32(&fecp->fec_mii_data,
> + mk_mii_write(MII_BMCR, BMCR_ISOLATE, phy_addr));
> + udelay(100);
> + out_be32(&fecp->fec_mii_data,
> + mk_mii_write(MII_ADVERTISE,
> + ADVERTISE_10HALF | ADVERTISE_CSMA, phy_addr));
> + udelay(100);
> +
> + /* Disable FEC MII settings
> + */
> + clrbits32(&fecp->fec_ecntrl, MII_ECNTRL_PINMUX);
> + clrbits32(&fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE);
> + out_be32(&fecp->fec_mii_speed, 0);
> +}
> +
> +static int mpc885ads_platform_notify(struct device *dev)
> +{
> +
> + static const struct platform_notify_dev_map dev_map[] = {
> + {
> + .bus_id = "fsl-cpm-fec",
> + .rtn = mpc885ads_fixup_fec_enet_pdata,
> + },
> + {
> + .bus_id = "fsl-cpm-scc",
> + .rtn = mpc885ads_fixup_scc_enet_pdata,
> + },
> + {
> + .bus_id = NULL
> + }
> + };
> +
> + platform_notify_map(dev_map,dev);
> +
> +}
> +
> +int __init mpc885ads_init(void)
> +{
> + printk(KERN_NOTICE "mpc885ads: Init\n");
> +
> + platform_notify = mpc885ads_platform_notify;
> +
> + ppc_sys_device_initfunc();
> + ppc_sys_device_set_func_all(FUNC_DISABLED);
> + ppc_sys_device_setfunc(MPC8xx_CPM_FEC1, FUNC_ENABLED);
> +
> +#ifdef CONFIG_MPC8xx_SECOND_ETH_SCC3
> + ppc_sys_device_setfunc(MPC8xx_CPM_SCC1, FUNC_ENABLED);
> +
> +#endif
> +#ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
> + ppc_sys_device_setfunc(MPC8xx_CPM_FEC2, FUNC_ENABLED);
> +#endif
> +
> + return 0;
> +}
> +
> +arch_initcall(mpc885ads_init);
> diff --git a/arch/ppc/platforms/pq2ads.h b/arch/ppc/platforms/pq2ads.h
> index 067d9a5..6b26dd3 100644
> --- a/arch/ppc/platforms/pq2ads.h
> +++ b/arch/ppc/platforms/pq2ads.h
> @@ -13,6 +13,10 @@
>
> #include <asm/ppcboot.h>
>
> +#if defined(CONFIG_ADS8272)
> +#define BOARD_CHIP_NAME "8272"
> +#endif
> +
> /* Memory map is configured by the PROM startup.
> * We just map a few things we need. The CSR is actually 4 byte-wide
> * registers that can be accessed as 8-, 16-, or 32-bit values.
> diff --git a/arch/ppc/platforms/pq2ads_pd.h b/arch/ppc/platforms/
> pq2ads_pd.h
> new file mode 100644
> index 0000000..8f14a43
> --- /dev/null
> +++ b/arch/ppc/platforms/pq2ads_pd.h
> @@ -0,0 +1,114 @@
> +#ifndef __PQ2ADS_PD_H
> +#define __PQ2ADS_PD_H
> +/*
> + * arch/ppc/platforms/82xx/pq2ads_pd.h
> + *
> + * Some defines for MPC82xx board-specific PlatformDevice
> descriptions
> + *
> + * 2005 (c) MontaVista Software, Inc.
> + * Vitaly Bordug <vbordug@ru.mvista.com>
> + *
> + * 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.
> + */
> +
> +/* FCC1 Clock Source Configuration. These can be redefined in the
> board specific file.
> + Can only choose from CLK9-12 */
> +
> +#define F1_RXCLK 11
> +#define F1_TXCLK 10
> +
> +/* FCC2 Clock Source Configuration. These can be redefined in the
> board specific file.
> + Can only choose from CLK13-16 */
> +#define F2_RXCLK 15
> +#define F2_TXCLK 16
> +
> +/* FCC3 Clock Source Configuration. These can be redefined in the
> board specific file.
> + Can only choose from CLK13-16 */
> +#define F3_RXCLK 13
> +#define F3_TXCLK 14
> +
> +/* Automatically generates register configurations */
> +#define PC_CLK(x) ((uint)(1<<(x-1))) /* FCC CLK I/O ports */
> +
> +#define CMXFCR_RF1CS(x) ((uint)((x-5)<<27)) /* FCC1 Receive Clock
> Source */
> +#define CMXFCR_TF1CS(x) ((uint)((x-5)<<24)) /* FCC1 Transmit Clock
> Source */
> +#define CMXFCR_RF2CS(x) ((uint)((x-9)<<19)) /* FCC2 Receive Clock
> Source */
> +#define CMXFCR_TF2CS(x) ((uint)((x-9)<<16)) /* FCC2 Transmit Clock
> Source */
> +#define CMXFCR_RF3CS(x) ((uint)((x-9)<<11)) /* FCC3 Receive Clock
> Source */
> +#define CMXFCR_TF3CS(x) ((uint)((x-9)<<8)) /* FCC3 Transmit Clock
> Source */
> +
> +#define PC_F1RXCLK PC_CLK(F1_RXCLK)
> +#define PC_F1TXCLK PC_CLK(F1_TXCLK)
> +#define CMX1_CLK_ROUTE (CMXFCR_RF1CS(F1_RXCLK) | CMXFCR_TF1CS
> (F1_TXCLK))
> +#define CMX1_CLK_MASK ((uint)0xff000000)
> +
> +#define PC_F2RXCLK PC_CLK(F2_RXCLK)
> +#define PC_F2TXCLK PC_CLK(F2_TXCLK)
> +#define CMX2_CLK_ROUTE (CMXFCR_RF2CS(F2_RXCLK) | CMXFCR_TF2CS
> (F2_TXCLK))
> +#define CMX2_CLK_MASK ((uint)0x00ff0000)
> +
> +#define PC_F3RXCLK PC_CLK(F3_RXCLK)
> +#define PC_F3TXCLK PC_CLK(F3_TXCLK)
> +#define CMX3_CLK_ROUTE (CMXFCR_RF3CS(F3_RXCLK) | CMXFCR_TF3CS
> (F3_TXCLK))
> +#define CMX3_CLK_MASK ((uint)0x0000ff00)
> +
> +/* I/O Pin assignment for FCC1. I don't yet know the best way to
> do this,
> + * but there is little variation among the choices.
> + */
> +#define PA1_COL 0x00000001U
> +#define PA1_CRS 0x00000002U
> +#define PA1_TXER 0x00000004U
> +#define PA1_TXEN 0x00000008U
> +#define PA1_RXDV 0x00000010U
> +#define PA1_RXER 0x00000020U
> +#define PA1_TXDAT 0x00003c00U
> +#define PA1_RXDAT 0x0003c000U
> +#define PA1_PSORA0 (PA1_RXDAT | PA1_TXDAT)
> +#define PA1_PSORA1 (PA1_COL | PA1_CRS | PA1_TXER | PA1_TXEN | \
> + PA1_RXDV | PA1_RXER)
> +#define PA1_DIRA0 (PA1_RXDAT | PA1_CRS | PA1_COL | PA1_RXER |
> PA1_RXDV)
> +#define PA1_DIRA1 (PA1_TXDAT | PA1_TXEN | PA1_TXER)
> +
> +
> +/* I/O Pin assignment for FCC2. I don't yet know the best way to
> do this,
> + * but there is little variation among the choices.
> + */
> +#define PB2_TXER 0x00000001U
> +#define PB2_RXDV 0x00000002U
> +#define PB2_TXEN 0x00000004U
> +#define PB2_RXER 0x00000008U
> +#define PB2_COL 0x00000010U
> +#define PB2_CRS 0x00000020U
> +#define PB2_TXDAT 0x000003c0U
> +#define PB2_RXDAT 0x00003c00U
> +#define PB2_PSORB0 (PB2_RXDAT | PB2_TXDAT | PB2_CRS | PB2_COL | \
> + PB2_RXER | PB2_RXDV | PB2_TXER)
> +#define PB2_PSORB1 (PB2_TXEN)
> +#define PB2_DIRB0 (PB2_RXDAT | PB2_CRS | PB2_COL | PB2_RXER |
> PB2_RXDV)
> +#define PB2_DIRB1 (PB2_TXDAT | PB2_TXEN | PB2_TXER)
> +
> +
> +/* I/O Pin assignment for FCC3. I don't yet know the best way to
> do this,
> + * but there is little variation among the choices.
> + */
> +#define PB3_RXDV 0x00004000U
> +#define PB3_RXER 0x00008000U
> +#define PB3_TXER 0x00010000U
> +#define PB3_TXEN 0x00020000U
> +#define PB3_COL 0x00040000U
> +#define PB3_CRS 0x00080000U
> +#define PB3_TXDAT 0x0f000000U
> +#define PB3_RXDAT 0x00f00000U
> +#define PB3_PSORB0 (PB3_RXDAT | PB3_TXDAT | PB3_CRS | PB3_COL | \
> + PB3_RXER | PB3_RXDV | PB3_TXER | PB3_TXEN)
> +#define PB3_PSORB1 0
> +#define PB3_DIRB0 (PB3_RXDAT | PB3_CRS | PB3_COL | PB3_RXER |
> PB3_RXDV)
> +#define PB3_DIRB1 (PB3_TXDAT | PB3_TXEN | PB3_TXER)
> +
> +#define FCC_MEM_OFFSET(x) (CPM_FCC_SPECIAL_BASE + (x*128))
> +#define FCC1_MEM_OFFSET FCC_MEM_OFFSET(0)
> +#define FCC2_MEM_OFFSET FCC_MEM_OFFSET(1)
> +
> +#endif
> ---
> Sincerely,
> Vitaly
>
^ permalink raw reply
* Re: [PATCH 1/3] ppc32: Make platform devices being able to assign functions (update)
From: Kumar Gala @ 2005-12-20 14:49 UTC (permalink / raw)
To: Vitaly Bordug; +Cc: linuxppc-embedded list
In-Reply-To: <43A77F81.9030102@ru.mvista.com>
On Dec 19, 2005, at 9:50 PM, Vitaly Bordug wrote:
> Implemented by modification of the .name field of the platform
> device,
> when PDs with the
> same names are to be used within different drivers, as
> <device_name> -> <device_name>:<function>
> Corresponding drivers should change the .name in struct
> device_driver to
> reflect upper of course.
>
> Also helper platform_notify_map function added, making assignment of
> board-specific platform_info more consistent and generic.
>
> Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>
>
>
> ---
>
> arch/ppc/syslib/ppc_sys.c | 136 ++++++++++++++++++++++++++++++++++
> ++++++++++-
> include/asm-ppc/mpc10x.h | 1
> include/asm-ppc/mpc52xx.h | 1
> include/asm-ppc/mpc8260.h | 1
> include/asm-ppc/mpc83xx.h | 1
> include/asm-ppc/mpc85xx.h | 1
> include/asm-ppc/mpc8xx.h | 1
> include/asm-ppc/ppc_sys.h | 24 ++++++++
> 8 files changed, 164 insertions(+), 2 deletions(-)
>
> applies-to: 4ce1b1890dc687cb1cf77f98e7a95b94c7ef3a93
> a8450a334dc930d7284800c457d91ed55a1a3dd7
> diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
> index c0b93c4..26d2658 100644
> --- a/arch/ppc/syslib/ppc_sys.c
> +++ b/arch/ppc/syslib/ppc_sys.c
> @@ -15,11 +15,23 @@
> */
>
> #include <linux/string.h>
> +#include <linux/bootmem.h>
> #include <asm/ppc_sys.h>
>
> int (*ppc_sys_device_fixup) (struct platform_device * pdev);
>
> static int ppc_sys_inited;
> +static int ppc_sys_func_inited;
> +
> +static const char *ppc_sys_func_names[] = {
> + [FUNC_ENABLED] = "dummy",
> + [FUNC_ETH] = "eth",
> + [FUNC_UART] = "uart",
> + [FUNC_HLDC] = "hldc",
> + [FUNC_USB] = "usb",
> + [FUNC_IRDA] = "irda",
> + [FUNC_DISABLED] = "off",
> +};
We should probably qualify the enum names a bit further for name
space pollution.
>
> void __init identify_ppc_sys_by_id(u32 id)
> {
> @@ -38,13 +50,13 @@ void __init identify_ppc_sys_by_id(u32 i
> void __init identify_ppc_sys_by_name(char *name)
> {
> unsigned int i = 0;
> - while (ppc_sys_specs[i].ppc_sys_name[0])
> - {
> + while (ppc_sys_specs[i].ppc_sys_name[0]) {
> if (!strcmp(ppc_sys_specs[i].ppc_sys_name, name))
> break;
> i++;
> }
> cur_ppc_sys_spec = &ppc_sys_specs[i];
> +
> return;
> }
>
> @@ -128,6 +140,126 @@ void ppc_sys_device_remove(enum ppc_sys_
> }
> }
>
> +/* Platform-notify mapping
> + * Helper function for BSP code to assign board-specific platfom-
> divice bits
> + */
> +
> +void platform_notify_map(const struct platform_notify_dev_map *map,
> + struct device *dev)
> +{
> + struct platform_device *pdev;
> + int len, idx;
> + const char *s;
> +
> + /* do nothing if no device or no bus_id */
> + if (!dev || !dev->bus_id)
> + return;
> +
> + /* call per device map */
> + while (map->bus_id != NULL) {
> + idx = -1;
> + s = strrchr(dev->bus_id, '.');
> + if (s != NULL)
> + idx = (int)simple_strtol(s + 1, NULL, 10);
> + else
> + s = dev->bus_id;
> +
> + len = s - dev->bus_id;
> +
> + if (!strncmp(dev->bus_id, map->bus_id, len)) {
> + pdev = container_of(dev, struct platform_device, dev);
> + map->rtn(pdev, idx);
> + }
> + map++;
> + }
> +}
> +
> +/*
> + Function assignment stuff.
> + Intended to work as follows:
> + the device name defined in foo_devices.c will be concatenated
> with :"func",
> + where func is string map of respective function from
> platfom_device_func enum
> +
> + The FUNC_ENABLED function is intended to remove all assignments,
> making the device to appear
> + in platform bus with unmodified name.
> + */
> +
> +/*
> + Here we'll replace .name pointers with fixed-lenght strings
Nit: lenght -> length
> + Hereby, this should be called *before* any func stuff triggeded.
> + */
> +void ppc_sys_device_initfunc(void)
> +{
> + int i;
> + const char *name;
> + static char new_names[NUM_PPC_SYS_DEVS][BUS_ID_SIZE];
> + enum ppc_sys_devices cur_dev;
> +
> + /* If inited yet, do nothing */
> + if (ppc_sys_func_inited)
> + return;
> +
> + for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
> + if ((cur_dev = cur_ppc_sys_spec->device_list[i]) < 0)
> + continue;
> +
> + if (ppc_sys_platform_devices[cur_dev].name) {
> + /*backup name */
> + name = ppc_sys_platform_devices[cur_dev].name;
> + strlcpy(new_names[i], name, BUS_ID_SIZE);
> + ppc_sys_platform_devices[cur_dev].name = new_names[i];
> + }
> + }
> +
> + ppc_sys_func_inited = 1;
> +}
> +
I really dont like mixing the function "enet, usb, serial, ..." with
the state enable/disabled. We should separate these two items.
> +/*The "engine" of the func stuff. Here we either concat specified
> function string description
> + to the name, or remove it if FUNC_ENABLED parameter is passed here*/
> +void ppc_sys_device_setfunc(enum ppc_sys_devices dev,
> + enum platform_device_func func)
> +{
> + char *s;
> + char *name = (char *)ppc_sys_platform_devices[dev].name;
> + char tmp[BUS_ID_SIZE];
> +
> + if (!ppc_sys_func_inited) {
> + printk(KERN_ERR "Unable to alter function - not inited!\n");
> + return;
> + }
> +
> + if (ppc_sys_inited) {
> + platform_device_unregister(&ppc_sys_platform_devices[dev]);
> + }
> +
> + if ((s = (char *)strchr(name, ':')) != NULL) { /* reassign */
> + /* Either change the name after ':' or remove func modifications */
> + if (func != FUNC_ENABLED)
> + strlcpy(s + 1, ppc_sys_func_names[func], BUS_ID_SIZE);
> + else
> + *s = 0;
> + } else if (func != FUNC_ENABLED) {
> + /* do assignment if it is not just "enable" request */
> + sprintf(tmp, "%s:%s", name, ppc_sys_func_names[func]);
> + strlcpy(name, tmp, BUS_ID_SIZE);
> + }
> +
> + if (ppc_sys_inited) {
> + platform_device_register(&ppc_sys_platform_devices[dev]);
> + }
> +}
> +
> +void ppc_sys_device_set_func_all(enum platform_device_func func)
> +{
> + enum ppc_sys_devices cur_dev;
> + int i;
> +
> + for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
> + cur_dev = cur_ppc_sys_spec->device_list[i];
> + ppc_sys_device_setfunc(cur_dev, func);
> + }
> +}
> +
> static int __init ppc_sys_init(void)
> {
> unsigned int i, dev_id, ret = 0;
> diff --git a/include/asm-ppc/mpc10x.h b/include/asm-ppc/mpc10x.h
> index 77b1e09..976ad3d 100644
> --- a/include/asm-ppc/mpc10x.h
> +++ b/include/asm-ppc/mpc10x.h
> @@ -165,6 +165,7 @@ enum ppc_sys_devices {
> MPC10X_DMA1,
> MPC10X_UART0,
> MPC10X_UART1,
> + NUM_PPC_SYS_DEVS,
> };
>
> int mpc10x_bridge_init(struct pci_controller *hose,
> diff --git a/include/asm-ppc/mpc52xx.h b/include/asm-ppc/mpc52xx.h
> index e5f80c2..b2cb44f 100644
> --- a/include/asm-ppc/mpc52xx.h
> +++ b/include/asm-ppc/mpc52xx.h
> @@ -49,6 +49,7 @@ enum ppc_sys_devices {
> MPC52xx_ATA,
> MPC52xx_I2C1,
> MPC52xx_I2C2,
> + NUM_PPC_SYS_DEVS,
> };
>
>
> diff --git a/include/asm-ppc/mpc8260.h b/include/asm-ppc/mpc8260.h
> index 3214526..6ba69a8 100644
> --- a/include/asm-ppc/mpc8260.h
> +++ b/include/asm-ppc/mpc8260.h
> @@ -83,6 +83,7 @@ enum ppc_sys_devices {
> MPC82xx_CPM_SMC2,
> MPC82xx_CPM_USB,
> MPC82xx_SEC1,
> + NUM_PPC_SYS_DEVS,
> };
>
> #ifndef __ASSEMBLY__
> diff --git a/include/asm-ppc/mpc83xx.h b/include/asm-ppc/mpc83xx.h
> index 7cdf60f..3c23fc4 100644
> --- a/include/asm-ppc/mpc83xx.h
> +++ b/include/asm-ppc/mpc83xx.h
> @@ -108,6 +108,7 @@ enum ppc_sys_devices {
> MPC83xx_USB2_DR,
> MPC83xx_USB2_MPH,
> MPC83xx_MDIO,
> + NUM_PPC_SYS_DEVS,
> };
>
> #endif /* CONFIG_83xx */
> diff --git a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h
> index 9d14bae..2a77884 100644
> --- a/include/asm-ppc/mpc85xx.h
> +++ b/include/asm-ppc/mpc85xx.h
> @@ -135,6 +135,7 @@ enum ppc_sys_devices {
> MPC85xx_eTSEC4,
> MPC85xx_IIC2,
> MPC85xx_MDIO,
> + NUM_PPC_SYS_DEVS,
> };
>
> /* Internal interrupts are all Level Sensitive, and Positive
> Polarity */
> diff --git a/include/asm-ppc/mpc8xx.h b/include/asm-ppc/mpc8xx.h
> index 46f159c..90e3d59 100644
> --- a/include/asm-ppc/mpc8xx.h
> +++ b/include/asm-ppc/mpc8xx.h
> @@ -111,6 +111,7 @@ enum ppc_sys_devices {
> MPC8xx_CPM_SMC1,
> MPC8xx_CPM_SMC2,
> MPC8xx_CPM_USB,
> + NUM_PPC_SYS_DEVS,
> };
>
> #ifndef BOARD_CHIP_NAME
> diff --git a/include/asm-ppc/ppc_sys.h b/include/asm-ppc/ppc_sys.h
> index 83d8c77..76f259f 100644
> --- a/include/asm-ppc/ppc_sys.h
> +++ b/include/asm-ppc/ppc_sys.h
> @@ -47,6 +47,21 @@ struct ppc_sys_spec {
> enum ppc_sys_devices *device_list;
> };
>
> +struct platform_notify_dev_map {
> + const char *bus_id;
> + void (*rtn)(struct platform_device * pdev, int idx);
> +};
> +
> +enum platform_device_func {
> + FUNC_ENABLED = 0,
> + FUNC_ETH = 1,
> + FUNC_UART = 2,
> + FUNC_HLDC = 3,
> + FUNC_USB = 4,
> + FUNC_IRDA = 5,
> + FUNC_DISABLED = 6,
> +};
> +
> /* describes all specific chips and which devices they have on
> them */
> extern struct ppc_sys_spec ppc_sys_specs[];
> extern struct ppc_sys_spec *cur_ppc_sys_spec;
> @@ -72,5 +87,14 @@ extern void *ppc_sys_get_pdata(enum ppc_
> /* remove a device from the system */
> extern void ppc_sys_device_remove(enum ppc_sys_devices dev);
>
> +/*Function assignment stuff*/
> +void ppc_sys_device_initfunc(void);
> +void ppc_sys_device_setfunc(enum ppc_sys_devices dev,
> + enum platform_device_func func);
> +void ppc_sys_device_set_func_all(enum platform_device_func func);
> +
> +void platform_notify_map(const struct platform_notify_dev_map *map,
> + struct device *dev);
> +
> #endif /* __ASM_PPC_SYS_H */
> #endif /* __KERNEL__ */
> ---
> 0.99.9.GIT
>
^ permalink raw reply
* Re: linux DMA capabilities in MV64460
From: Brian Waite @ 2005-12-20 14:27 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <20051220010136.GA31165@mag.az.mvista.com>
On Monday 19 December 2005 8:01 pm, Mark A. Greer wrote:
> >
> > up the mv64460. One source told me:
> > > In order to do PCI bursts, you'll need to use a DMA engine. The
> > > MV64460 does contain a DMA engine, but you'd need to write a driver
> > > to access it.
>
> That is not correct (assuming the quote is not out of context).
> The bridge supports bursting on the PCI bus as long as the bridge is
> configured correctly and the PCI device is making an appropriate request.
> Note, however, that there are many errata for the Marvell parts including
> some with cache coherency.
There are many many errata regarding cache coherency. Also, the PCI bandwidth
the bridge is capable of with coherency enabled is very small. You will most
likely need to use sw coherency for any real speed.
> If your system is running with coherency on,
> you may have to limit your bursts to 32 bytes (i.e., the size of one
> cache line).
You will have to limit your self to 32 byte bursts with coherency. This is a
requirement not an errata.
> > Is there a summary of what is possible and/or not possible with the 4
> > IDMA channels on the mv64460?
>
> The only real documentation is the bridge's user manual from Marvell.
> Unfortunately, you must sign an NDA to get access to it so I can't share
> mine with you. You will need access to that info to get very far so I
> recommend you contact the people in your company that can make that
> happen, ASAP.
Ask for the errata sheets while your at it. You WILL need them :)
You really do need the chipset docs to do anything intelligent with the IDMA
controllers.
Thanks
Brian
^ permalink raw reply
* Re: RFC: Rev 0.5 Booting the Linux/ppc kernel without Open Firmware
From: Arnd Bergmann @ 2005-12-20 10:18 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc64-dev, linuxppc-dev
In-Reply-To: <Pine.LNX.4.44.0512191446570.4542-100000@gate.crashing.org>
On Maandag 19 Dezember 2005 21:49, Kumar Gala wrote:
> I'm still in favor of just leaving these devices as straight platform
> devices. Unless there is something that is bus specific that each device
> on the bus conforms to I dont see any reason to create a new bus type.
How do platform devices work with module autoloading? What I'm interested
in is to have stuff like the Fedora installer or kernels with modular
drivers 'just work' because they can use the same way to load their
modules that is already used for PCI devices.
AFAICS, that requires at least two things:
- The device needs to be created when the bus is probed, i.e.
of_device_register can not be called from inside the driver
module_init() function.
- The bus type needs to create a modalias file so user space can
do the matching with the of device table in the modules.
Both of these should be a lot easier to implement with a special
bus type that creates entries in sysfs for a subset of the OF
device tree.
The alternative would be to represent all of the device tree
in /sys/devices, but IMHO that should better be part of
/sys/firmware with symlinks to the linux internal device tree
representation.
Arnd <><
^ permalink raw reply
* ppc440 EBC question
From: Peter Fercher @ 2005-12-20 7:52 UTC (permalink / raw)
To: 'linux-ppc-embedded'
[-- Attachment #1: Type: text/plain, Size: 129 bytes --]
does somebody have a hint where to find an example how to
talk to devices attached to the ppc440 external bus controller
thanks
[-- Attachment #2: Type: text/html, Size: 638 bytes --]
^ permalink raw reply
* Re: MPC8272ADS stability issues
From: Dmytro Bablinyuk @ 2005-12-20 5:22 UTC (permalink / raw)
To: Laurie, Ian; +Cc: linuxppc-embedded
In-Reply-To: <F311526ED41F0F449EAFC93A85287CCC02A8F205@USCHD00MX15ASU.APAC.AVNET.COM>
>
> Does anyone have any news regarding any resolution of this issue?
>
We cannot guarantee that this is solution for everybody BUT:
We had similar problems with our MPC8272ADS and this morning we
discovered that core voltage exceeds recommended values - the core
voltage on 8272ADS was 1.6V instead of 1.5V.
Where according to MPC8272EC, Rev. 1.2, 05/2005 page 7
--8<--
Table 4. Recommended Operating Conditions
Caution: These are the recommended and tested operating conditions.
Proper operation outside of these conditions is not guaranteed.
Rating Symbol Value Unit
Core supply voltage VDD 1.425 – 1.575 V
--8<--
We run memory test, as for now, for almost 9 hours and so far without
problems. Though before board was crashing every 1-4 hours. We don't
know whether this is source of the problem - we will keep testing it.
Power supply for MPC8272ADS generates ± 5V, ± 12V, +3.3V - they are all ok.
Core voltage is generated by U45 on the 8272ADS board. There is a
trimmer pot RP1 for adjusting the core voltage - we never checked it
before since we assumed that it should be set properly by factory. But
today we found that U45 gives 1.6V instead of 1.5V, which is outside of
recommended values and datasheet says "Proper operation outside of these
conditions is not guaranteed".
So, check you core voltage (U45) - it might help.
Dmytro
^ permalink raw reply
* [PATCH] MPC8349 MDS USB HOST support
From: Li Yang-r58472 @ 2005-12-20 3:57 UTC (permalink / raw)
To: linux-usb-devel, linuxppc-embedded
Hi,
Here is the patch we have in Freescale released BSP. I post it here in case anyone may need it without the BSP. It's for kernel 2.6.11, and won't have big problem for newer kernel, I think. The patch is not done by myself, and maybe submitted later formally after merge with OTG and clean up. Here goes the patch.
diff -Nur linux/drivers/usb/core/hcd.c linux-8349-2.6/drivers/usb/core/hcd.c
--- linux/drivers/usb/core/hcd.c 2005-03-02 15:38:10.000000000 +0800
+++ linux-8349-2.6/drivers/usb/core/hcd.c 2005-08-15 13:54:13.000000000 +0800
@@ -1116,13 +1116,20 @@
if (hcd->self.controller->dma_mask) {
if (usb_pipecontrol (urb->pipe)
&& !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
+#ifdef CONFIG_FSL_USB20
+ urb->setup_dma = (unsigned long)urb->setup_packet;
+#else
urb->setup_dma = dma_map_single (
hcd->self.controller,
urb->setup_packet,
sizeof (struct usb_ctrlrequest),
DMA_TO_DEVICE);
+#endif
if (urb->transfer_buffer_length != 0
&& !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP))
+#ifdef CONFIG_FSL_USB20
+ urb->transfer_dma = (unsigned long)urb->transfer_buffer;
+#else
urb->transfer_dma = dma_map_single (
hcd->self.controller,
urb->transfer_buffer,
@@ -1130,6 +1137,7 @@
usb_pipein (urb->pipe)
? DMA_FROM_DEVICE
: DMA_TO_DEVICE);
+#endif
}
status = hcd->driver->urb_enqueue (hcd, ep, urb, mem_flags);
@@ -1469,6 +1477,8 @@
// It would catch exit/unlink paths for all urbs.
/* lower level hcd code should use *_dma exclusively */
+#ifdef CONFIG_FSL_USB20
+#else
if (hcd->self.controller->dma_mask) {
if (usb_pipecontrol (urb->pipe)
&& !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
@@ -1484,7 +1494,7 @@
? DMA_FROM_DEVICE
: DMA_TO_DEVICE);
}
-
+#endif
/* pass ownership to the completion handler */
urb->complete (urb, regs);
atomic_dec (&urb->use_count);
diff -Nur linux/drivers/usb/core/hub.c linux-8349-2.6/drivers/usb/core/hub.c
--- linux/drivers/usb/core/hub.c 2005-03-02 15:38:08.000000000 +0800
+++ linux-8349-2.6/drivers/usb/core/hub.c 2005-08-15 13:56:05.000000000 +0800
@@ -2155,7 +2155,11 @@
} else if (udev->speed != USB_SPEED_HIGH
&& hdev->speed == USB_SPEED_HIGH) {
udev->tt = &hub->tt;
+#ifdef CONFIG_FSL_USB20
+ udev->ttport = port1+1;
+#else
udev->ttport = port1;
+#endif
}
/* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way?
diff -Nur linux/drivers/usb/host/ehci.h linux-8349-2.6/drivers/usb/host/ehci.h
--- linux/drivers/usb/host/ehci.h 2005-03-02 15:38:25.000000000 +0800
+++ linux-8349-2.6/drivers/usb/host/ehci.h 2005-08-15 10:25:52.000000000 +0800
@@ -59,6 +59,9 @@
#define DEFAULT_I_TDPS 1024 /* some HCs can do less */
unsigned periodic_size;
__le32 *periodic; /* hw periodic table */
+#ifdef CONFIG_FSL_USB20
+ u32 orig_periodic;
+#endif
dma_addr_t periodic_dma;
unsigned i_thresh; /* uframes HC might cache */
@@ -70,11 +73,17 @@
unsigned long reset_done [EHCI_MAX_ROOT_PORTS];
/* per-HC memory pools (could be per-bus, but ...) */
+#ifdef CONFIG_FSL_USB20
+ t_MemorySegment *qh_pool; /* qh per active urb */
+ t_MemorySegment *qtd_pool; /* one or more per qh */
+ t_MemorySegment *itd_pool; /* itd per iso urb */
+ t_MemorySegment *sitd_pool; /* sitd per split iso urb */
+#else
struct dma_pool *qh_pool; /* qh per active urb */
struct dma_pool *qtd_pool; /* one or more per qh */
struct dma_pool *itd_pool; /* itd per iso urb */
struct dma_pool *sitd_pool; /* sitd per split iso urb */
-
+#endif
struct timer_list watchdog;
struct notifier_block reboot_notifier;
unsigned long actions;
@@ -230,9 +239,26 @@
u32 frame_list; /* points to periodic list */
/* ASYNCLISTADDR: offset 0x18 */
u32 async_next; /* address of next async queue head */
-
+#ifdef CONFIG_FSL_USB20
+ /* ASYNCTTSTS: offset 0x1c */
+ u32 async_tt_status; /* async queue status for embedded TT */
+ /* BURSTSIZE: offset 0x20 */
+ u32 burst_size; /* programmable burst size */
+ /* TXFILLTUNING: offset 0x24 */
+ u32 txfilltuning; /* host transmit pre-buffer packet tuning */
+ /* TXTTFILLTUNING: offset 0x28 */
+ u32 txttfilltuning; /* host TT transmit pre-buffer packet tuning */
+ u32 reserved0;
+ /* ULPIVIEWPORT: offset 0x30 */
+ u32 ulpi_view_port; /* ULPI view port */
+ /* ENDPTNAK: offset 0x34 */
+ u32 endpoint_nack; /* endpoint nack */
+ /* ENDPTNAKEN: offset 0x38 */
+ u32 endpoint_nack_en; /* endpoint nack enable */
+ u32 reserved1;
+#else
u32 reserved [9];
-
+#endif
/* CONFIGFLAG: offset 0x40 */
u32 configured_flag;
#define FLAG_CF (1<<0) /* true: we'll support "high speed" */
diff -Nur linux/drivers/usb/host/ehci-hcd.c linux-8349-2.6/drivers/usb/host/ehci-hcd.c
--- linux/drivers/usb/host/ehci-hcd.c 2005-03-02 15:38:38.000000000 +0800
+++ linux-8349-2.6/drivers/usb/host/ehci-hcd.c 2005-08-15 10:40:35.000000000 +0800
@@ -16,6 +16,13 @@
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#ifdef CONFIG_FSL_USB20
+#ifdef CONFIG_USB_DEBUG
+ #define DEBUG
+#else
+ #undef DEBUG
+#endif
+#else
#include <linux/config.h>
#ifdef CONFIG_USB_DEBUG
@@ -101,8 +108,17 @@
#define DRIVER_AUTHOR "David Brownell"
#define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
-static const char hcd_name [] = "ehci_hcd";
+#endif
+#ifdef CONFIG_FSL_USB20
+#if defined (CONFIG_MPH_USB_SUPPORT)
+static const char hcd_name [] = "fsl-usb2-mph";
+#elif defined (CONFIG_DR_USB_SUPPORT)
+static const char hcd_name [] = "fsl-usb2-dr";
+#endif
+#else
+static const char hcd_name [] = "ehci_hcd";
+#endif
#undef EHCI_VERBOSE_DEBUG
#undef EHCI_URB_TRACE
@@ -112,6 +128,7 @@
#endif
/* magic numbers that can affect system performance */
+
#define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */
#define EHCI_TUNE_RL_HS 4 /* nak throttle; see 4.9 */
#define EHCI_TUNE_RL_TT 0
@@ -126,13 +143,18 @@
/* Initial IRQ latency: faster than hw default */
static int log2_irq_thresh = 0; // 0 to 6
+#ifdef CONFIG_FSL_USB20
+#else
module_param (log2_irq_thresh, int, S_IRUGO);
MODULE_PARM_DESC (log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
-
+#endif
/* initial park setting: slower than hw default */
static unsigned park = 0;
+#ifdef CONFIG_FSL_USB20
+#else
module_param (park, uint, S_IRUGO);
MODULE_PARM_DESC (park, "park setting; 1-3 back-to-back async packets");
+#endif
#define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
@@ -190,7 +212,27 @@
writel (temp, &ehci->regs->command);
return handshake (&ehci->regs->status, STS_HALT, STS_HALT, 16 * 125);
}
+#ifdef CONFIG_FSL_USB20
+static void mpc8349_usb_reset(void);
+/* reset a non-running (STS_HALT == 1) controller */
+static int ehci_reset (struct ehci_hcd *ehci)
+{
+ int retval;
+ u32 command = readl (&ehci->regs->command);
+ command |= CMD_RESET;
+ dbg_cmd (ehci, "reset", command);
+ writel (command, &ehci->regs->command);
+ ehci_to_hcd(ehci)->state = USB_STATE_HALT;
+ ehci->next_statechange = jiffies;
+ retval = handshake (&ehci->regs->command, CMD_RESET, 0, 250 * 1000);
+
+ if (retval)
+ return retval;
+ mpc8349_usb_reset ();
+ return retval;
+}
+#else
/* reset a non-running (STS_HALT == 1) controller */
static int ehci_reset (struct ehci_hcd *ehci)
{
@@ -203,7 +245,7 @@
ehci->next_statechange = jiffies;
return handshake (&ehci->regs->command, CMD_RESET, 0, 250 * 1000);
}
-
+#endif
/* idle the controller (from running) */
static void ehci_quiesce (struct ehci_hcd *ehci)
{
@@ -276,7 +318,7 @@
spin_unlock_irqrestore (&ehci->lock, flags);
}
-#ifdef CONFIG_PCI
+#if defined(CONFIG_PCI) && !defined(CONFIG_FSL_USB20)
/* EHCI 0.96 (and later) section 5.1 says how to kick BIOS/SMM/...
* off the controller (maybe it can boot from highspeed USB disks).
@@ -285,18 +327,22 @@
{
if (cap & (1 << 16)) {
int msec = 5000;
+
struct pci_dev *pdev =
to_pci_dev(ehci_to_hcd(ehci)->self.controller);
/* request handoff to OS */
cap |= 1 << 24;
+
pci_write_config_dword(pdev, where, cap);
/* and wait a while for it to happen */
do {
msleep(10);
msec -= 10;
+
pci_read_config_dword(pdev, where, &cap);
+
} while ((cap & (1 << 16)) && msec);
if (cap & (1 << 16)) {
ehci_err (ehci, "BIOS handoff failed (%d, %04x)\n",
@@ -332,7 +378,10 @@
{
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
u32 temp;
+#ifdef CONFIG_FSL_USB20
+#else
unsigned count = 256/4;
+#endif
spin_lock_init (&ehci->lock);
@@ -340,8 +389,14 @@
ehci->regs = hcd->regs + HC_LENGTH (readl (&ehci->caps->hc_capbase));
dbg_hcs_params (ehci, "reset");
dbg_hcc_params (ehci, "reset");
+
-#ifdef CONFIG_PCI
+#ifdef CONFIG_FSL_USB20
+ mpc8349_usb_reset ();
+ ehci->is_arc_rh_tt = 1;
+#endif
+
+#if defined(CONFIG_PCI) && !defined(CONFIG_FSL_USB20)
/* EHCI 0.96 and later may have "extended capabilities" */
if (hcd->self.controller->bus == &pci_bus_type) {
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
@@ -395,7 +450,7 @@
HCS_N_PCC(ehci->hcs_params),
HCS_N_PORTS(ehci->hcs_params));
-#ifdef CONFIG_PCI
+#if defined(CONFIG_PCI) && !defined(CONFIG_FSL_USB20)
if (hcd->self.controller->bus == &pci_bus_type) {
struct pci_dev *pdev;
@@ -465,7 +520,7 @@
}
writel (ehci->periodic_dma, &ehci->regs->frame_list);
-#ifdef CONFIG_PCI
+#if defined(CONFIG_PCI) && !defined(CONFIG_FSL_USB20)
if (hcd->self.controller->bus == &pci_bus_type) {
struct pci_dev *pdev;
u16 port_wake;
@@ -829,7 +884,7 @@
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
u32 status;
int bh;
-
+
spin_lock (&ehci->lock);
status = readl (&ehci->regs->status);
@@ -1181,6 +1236,9 @@
/*-------------------------------------------------------------------------*/
/* EHCI 1.0 doesn't require PCI */
+#ifdef CONFIG_FSL_USB20
+
+#else
#ifdef CONFIG_PCI
@@ -1236,3 +1294,4 @@
pci_unregister_driver (&ehci_pci_driver);
}
module_exit (cleanup);
+#endif
diff -Nur linux/drivers/usb/host/ehci-mem.c linux-8349-2.6/drivers/usb/host/ehci-mem.c
--- linux/drivers/usb/host/ehci-mem.c 2005-03-02 15:38:26.000000000 +0800
+++ linux-8349-2.6/drivers/usb/host/ehci-mem.c 2005-08-15 10:46:53.000000000 +0800
@@ -49,8 +49,13 @@
{
struct ehci_qtd *qtd;
dma_addr_t dma;
-
+#ifdef CONFIG_FSL_USB20
+ qtd = MEM_Get( ehci->qtd_pool);
+ dma = virt_to_phys(qtd);
+ memset(qtd, 0, sizeof(*qtd));
+#else
qtd = dma_pool_alloc (ehci->qtd_pool, flags, &dma);
+#endif
if (qtd != NULL) {
ehci_qtd_init (qtd, dma);
}
@@ -59,7 +64,11 @@
static inline void ehci_qtd_free (struct ehci_hcd *ehci, struct ehci_qtd *qtd)
{
+#ifdef CONFIG_FSL_USB20
+ MEM_Put(ehci->qtd_pool, qtd);
+#else
dma_pool_free (ehci->qtd_pool, qtd, qtd->qtd_dma);
+#endif
}
@@ -75,8 +84,12 @@
}
if (qh->dummy)
ehci_qtd_free (ehci, qh->dummy);
+#ifdef CONFIG_FSL_USB20
+ MEM_Put(ehci->qh_pool, qh);
+#else
usb_put_dev (qh->dev);
dma_pool_free (ehci->qh_pool, qh, qh->qh_dma);
+#endif
}
static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, int flags)
@@ -84,8 +97,14 @@
struct ehci_qh *qh;
dma_addr_t dma;
+#ifdef CONFIG_FSL_USB20
+ qh = (struct ehci_qh *) MEM_Get(ehci->qh_pool);
+ dma = virt_to_phys(qh);
+ memset(qh, 0, sizeof(*qh));
+#else
qh = (struct ehci_qh *)
dma_pool_alloc (ehci->qh_pool, flags, &dma);
+#endif
if (!qh)
return qh;
@@ -100,7 +119,11 @@
qh->dummy = ehci_qtd_alloc (ehci, flags);
if (qh->dummy == NULL) {
ehci_dbg (ehci, "no dummy td\n");
+#ifdef CONFIG_FSL_USB20
+ MEM_Put(ehci->qh_pool, qh);
+#else
dma_pool_free (ehci->qh_pool, qh, qh->qh_dma);
+#endif
qh = NULL;
}
return qh;
@@ -133,26 +156,46 @@
/* DMA consistent memory and pools */
if (ehci->qtd_pool)
+#ifdef CONFIG_FSL_USB20
+ MEM_Free(ehci->qtd_pool);
+#else
dma_pool_destroy (ehci->qtd_pool);
+#endif
ehci->qtd_pool = NULL;
if (ehci->qh_pool) {
+#ifdef CONFIG_FSL_USB20
+ MEM_Free(ehci->qh_pool);
+#else
dma_pool_destroy (ehci->qh_pool);
+#endif
ehci->qh_pool = NULL;
}
if (ehci->itd_pool)
+#ifdef CONFIG_FSL_USB20
+ MEM_Free(ehci->itd_pool);
+#else
dma_pool_destroy (ehci->itd_pool);
+#endif
ehci->itd_pool = NULL;
if (ehci->sitd_pool)
+#ifdef CONFIG_FSL_USB20
+ MEM_Free(ehci->sitd_pool);
+#else
dma_pool_destroy (ehci->sitd_pool);
+#endif
ehci->sitd_pool = NULL;
if (ehci->periodic)
+#ifdef CONFIG_FSL_USB20
+ kfree((void *)ehci->orig_periodic);
+#else
dma_free_coherent (ehci_to_hcd(ehci)->self.controller,
ehci->periodic_size * sizeof (u32),
ehci->periodic, ehci->periodic_dma);
+#endif
ehci->periodic = NULL;
/* shadow periodic table */
@@ -165,23 +208,31 @@
static int ehci_mem_init (struct ehci_hcd *ehci, int flags)
{
int i;
+ int err;
/* QTDs for control/bulk/intr transfers */
+#ifdef CONFIG_FSL_USB20
+ err = MEM_Init("ehci_qtd_pool", (void **)&ehci->qtd_pool, 128, sizeof(struct ehci_qtd), 0, 0, 32);
+#else
ehci->qtd_pool = dma_pool_create ("ehci_qtd",
ehci_to_hcd(ehci)->self.controller,
sizeof (struct ehci_qtd),
32 /* byte alignment (for hw parts) */,
4096 /* can't cross 4K */);
+#endif
if (!ehci->qtd_pool) {
goto fail;
}
-
+#ifdef CONFIG_FSL_USB20
+ err = MEM_Init("ehci_qh_pool", (void **)&ehci->qh_pool, 128, sizeof(struct ehci_qh), 0, 0, 64);
+#else
/* QHs for control/bulk/intr transfers */
ehci->qh_pool = dma_pool_create ("ehci_qh",
ehci_to_hcd(ehci)->self.controller,
sizeof (struct ehci_qh),
32 /* byte alignment (for hw parts) */,
4096 /* can't cross 4K */);
+#endif
if (!ehci->qh_pool) {
goto fail;
}
@@ -191,30 +242,47 @@
}
/* ITD for high speed ISO transfers */
+#ifdef CONFIG_FSL_USB20
+ err = MEM_Init("ehci_itd_pool", (void **)&ehci->itd_pool, 128, sizeof(struct ehci_itd), 0, 0, 32);
+#else
ehci->itd_pool = dma_pool_create ("ehci_itd",
ehci_to_hcd(ehci)->self.controller,
sizeof (struct ehci_itd),
32 /* byte alignment (for hw parts) */,
4096 /* can't cross 4K */);
+#endif
if (!ehci->itd_pool) {
goto fail;
}
/* SITD for full/low speed split ISO transfers */
+#ifdef CONFIG_FSL_USB20
+ err = MEM_Init("ehci_sitd_pool", (void**)&ehci->sitd_pool, 128, sizeof(struct ehci_sitd), 0, 0, 32);
+#else
ehci->sitd_pool = dma_pool_create ("ehci_sitd",
ehci_to_hcd(ehci)->self.controller,
sizeof (struct ehci_sitd),
32 /* byte alignment (for hw parts) */,
4096 /* can't cross 4K */);
+#endif
if (!ehci->sitd_pool) {
goto fail;
}
/* Hardware periodic table */
+#ifdef CONFIG_FSL_USB20
+ ehci->orig_periodic =(u32)kmalloc((int)(ehci->periodic_size * sizeof (u32))+0x1000,GFP_KERNEL);
+ if(ehci->orig_periodic%0x1000)
+ ehci->periodic = (__le32 *)(((ehci->orig_periodic>>12)<<12)+0x1000);
+ else
+ ehci->periodic = (__le32 *)ehci->orig_periodic;
+ ehci->periodic_dma = virt_to_phys(ehci->periodic);
+#else
ehci->periodic = (__le32 *)
dma_alloc_coherent (ehci_to_hcd(ehci)->self.controller,
ehci->periodic_size * sizeof(__le32),
&ehci->periodic_dma, 0);
+#endif
if (ehci->periodic == NULL) {
goto fail;
}
diff -Nur linux/drivers/usb/host/ehci-q.c linux-8349-2.6/drivers/usb/host/ehci-q.c
--- linux/drivers/usb/host/ehci-q.c 2005-03-02 15:38:19.000000000 +0800
+++ linux-8349-2.6/drivers/usb/host/ehci-q.c 2005-08-15 10:50:13.000000000 +0800
@@ -500,7 +500,11 @@
is_input = usb_pipein (urb->pipe);
if (usb_pipecontrol (urb->pipe)) {
/* SETUP pid */
+#ifdef CONFIG_FSL_USB20
+ qtd_fill (qtd, virt_to_phys(urb->setup_packet), sizeof (struct usb_ctrlrequest),
+#else
qtd_fill (qtd, urb->setup_dma, sizeof (struct usb_ctrlrequest),
+#endif
token | (2 /* "setup" */ << 8), 8);
/* ... and always at least one more pid */
@@ -518,7 +522,11 @@
* data transfer stage: buffer setup
*/
if (likely (len > 0))
+#ifdef CONFIG_FSL_USB20
+ buf = virt_to_phys(urb->transfer_buffer);
+#else
buf = urb->transfer_dma;
+#endif
else
buf = 0;
@@ -712,8 +720,11 @@
info1 |= maxp << 16;
info2 |= (EHCI_TUNE_MULT_TT << 30);
+#ifdef CONFIG_FSL_USB20
+ info2 |= (urb->dev->ttport-1) << 23;
+#else
info2 |= urb->dev->ttport << 23;
-
+#endif
/* set the address of the TT; for ARC's integrated
* root hub tt, leave it zeroed.
*/
@@ -863,7 +874,11 @@
dummy = qh->dummy;
dma = dummy->qtd_dma;
+#ifdef CONFIG_FSL_USB20
+ memcpy(dummy,qtd,sizeof(struct ehci_qtd));
+#else
*dummy = *qtd;
+#endif
dummy->qtd_dma = dma;
list_del (&qtd->qtd_list);
@@ -925,6 +940,7 @@
if (likely (qh != NULL)) {
if (likely (qh->qh_state == QH_STATE_IDLE))
qh_link_async (ehci, qh_get (qh));
+
}
spin_unlock_irqrestore (&ehci->lock, flags);
if (unlikely (qh == NULL)) {
diff -Nur linux/drivers/usb/host/ehci-sched.c linux-8349-2.6/drivers/usb/host/ehci-sched.c
--- linux/drivers/usb/host/ehci-sched.c 2005-03-02 15:37:53.000000000 +0800
+++ linux-8349-2.6/drivers/usb/host/ehci-sched.c 2005-08-15 10:53:16.000000000 +0800
@@ -699,8 +699,11 @@
} else {
u32 addr;
-
+#ifdef CONFIG_FSL_USB20
+ addr = (u32)((dev->ttport-1) << 24);
+#else
addr = dev->ttport << 24;
+#endif
addr |= dev->tt->hub->devnum << 16;
addr |= epnum << 8;
addr |= dev->devnum;
@@ -759,15 +762,23 @@
itd = list_entry (entry, struct ehci_itd,
itd_list);
+#ifdef CONFIG_FSL_USB20
+ MEM_Put(ehci->itd_pool, itd);
+#else
dma_pool_free (ehci->itd_pool, itd,
itd->itd_dma);
+#endif
} else {
struct ehci_sitd *sitd;
sitd = list_entry (entry, struct ehci_sitd,
sitd_list);
+#ifdef CONFIG_FSL_USB20
+ MEM_Put(ehci->sitd_pool, sitd);
+#else
dma_pool_free (ehci->sitd_pool, sitd,
sitd->sitd_dma);
+#endif
}
}
@@ -865,8 +876,11 @@
)
{
unsigned i;
+#ifdef CONFIG_FSL_USB20
+ dma_addr_t dma = virt_to_phys(urb->transfer_buffer);
+#else
dma_addr_t dma = urb->transfer_dma;
-
+#endif
/* how many uframes are needed for these transfers */
iso_sched->span = urb->number_of_packets * stream->interval;
@@ -956,8 +970,14 @@
if (!itd) {
spin_unlock_irqrestore (&ehci->lock, flags);
+#ifdef CONFIG_FSL_USB20
+ itd = MEM_Get(ehci->itd_pool);
+ itd_dma = virt_to_phys(itd);
+
+#else
itd = dma_pool_alloc (ehci->itd_pool, mem_flags,
&itd_dma);
+#endif
spin_lock_irqsave (&ehci->lock, flags);
}
@@ -1559,8 +1579,13 @@
if (!sitd) {
spin_unlock_irqrestore (&ehci->lock, flags);
+#ifdef CONFIG_FSL_USB20
+ sitd = MEM_Get (ehci->sitd_pool);
+ sitd_dma = virt_to_phys(sitd);
+#else
sitd = dma_pool_alloc (ehci->sitd_pool, mem_flags,
&sitd_dma);
+#endif
spin_lock_irqsave (&ehci->lock, flags);
}
diff -Nur linux/drivers/usb/host/fsl-usb.c linux-8349-2.6/drivers/usb/host/fsl-usb.c
--- linux/drivers/usb/host/fsl-usb.c 1970-01-01 08:00:00.000000000 +0800
+++ linux-8349-2.6/drivers/usb/host/fsl-usb.c 2005-08-25 11:50:08.000000000 +0800
@@ -0,0 +1,303 @@
+/*
+ * 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.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/reboot.h>
+#include <linux/timer.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/usb.h>
+
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/byteorder.h>
+#include <asm/uaccess.h>
+
+#include <asm/unaligned.h>
+
+#include "../core/hcd.h"
+#include "fsl-usb.h"
+
+#define DRIVER_VERSION "$Revision: 1.11 $"
+#define DRIVER_AUTHOR "Hunter Wu"
+#define DRIVER_DESC "USB 2.0 Freescale EHCI Driver"
+#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC
+
+MODULE_DESCRIPTION("MPC8249 USB Host Controller Driver");
+
+#include "ehci-hcd.c"
+
+void mpc8349_board_init(void)
+{
+ volatile unsigned char *bcsr5_p;
+
+ /* if SYS board is plug into PIB board, force to use the PHY on SYS board */
+ bcsr5_p = (volatile unsigned char *)(CFG_BCSR_BASE + 0x00000005);
+ if ( (*bcsr5_p & BCSR5_INT_USB) == 0 )
+ *bcsr5_p = (*bcsr5_p | BCSR5_INT_USB);
+}
+
+void mpc8349_usb_clk_cfg(void)
+{
+ unsigned long sccr;
+ volatile unsigned long *p;
+
+ p = (volatile unsigned long *)(CFG_IMMR_BASE + SCCR_OFFS); /* SCCR */
+ sccr = *p;
+
+#if defined(CONFIG_MPH_USB_SUPPORT)
+ sccr &= ~SCCR_USB_MPHCM_11;
+ sccr |= SCCR_USB_MPHCM_11; /* USB CLK 1:3 CSB CLK */
+ *p = sccr;
+#elif defined(CONFIG_DR_USB_SUPPORT)
+ sccr &= ~SCCR_USB_DRCM_11;
+ sccr |= SCCR_USB_DRCM_11; /* USB CLK 1:3 CSB CLK */
+ *p = sccr;
+#endif
+
+}
+
+void mpc8349_usb_pin_cfg(void)
+{
+ unsigned long sicrl;
+ volatile unsigned long *p;
+
+ p = (volatile unsigned long *)(CFG_IMMR_BASE + SICRL_OFFS); /* SCCR */
+ sicrl = *p;
+
+#if defined(CONFIG_MPH_USB_SUPPORT)
+#ifdef CONFIG_MPH0_USB_ENABLE
+ sicrl &= ~SICRL_USB0;
+ *p = sicrl;
+#endif
+
+#ifdef CONFIG_MPH1_USB_ENABLE
+ sicrl &= ~SICRL_USB1;
+ *p = sicrl;
+#endif
+#elif defined(CONFIG_DR_USB_SUPPORT)
+ sicrl &= ~SICRL_USB0;
+ sicrl |= SICRL_USB1 ;
+ *p = sicrl;
+#if defined(CONFIG_DR_UTMI)
+ sicrl &= ~SICRL_USB0;
+ sicrl |= SICRL_USB0;
+ *p = sicrl;
+#endif
+
+#endif
+}
+
+static void mpc8349_usb_reset(void)
+{
+ u32 portsc;
+
+#if defined(CONFIG_MPH_USB_SUPPORT)
+ t_USB_MPH_MAP *p_MphMemMap;
+ /* Enable PHY interface in the control reg. */
+ p_MphMemMap = (t_USB_MPH_MAP *)MPC83xx_USB_MPH_BASE;
+ p_MphMemMap->control = 0x00000004;
+ p_MphMemMap->snoop1 = 0x0000001b;
+#ifdef CONFIG_MPH0_USB_ENABLE
+ portsc = readl(&p_MphMemMap->port_status[0]);
+ portsc &= ~PORT_TS;
+#if defined(CONFIG_MPH0_ULPI)
+ portsc |= PORT_TS_ULPI;
+#elif defined (CONFIG_MPH0_SERIAL)
+ portsc |= PORT_TS_SERIAL;
+#endif
+ writel(portsc,&p_MphMemMap->port_status[0]);
+#endif
+
+#ifdef CONFIG_MPH1_USB_ENABLE
+ portsc = readl(&p_MphMemMap->port_status[1]);
+ portsc &= ~PORT_TS;
+#if defined(CONFIG_MPH1_ULPI)
+ portsc |= PORT_TS_ULPI;
+#elif defined (CONFIG_MPH1_SERIAL)
+ portsc |= PORT_TS_SERIAL;
+#endif
+ writel(portsc,&p_MphMemMap->port_status[1]);
+#endif
+
+ p_MphMemMap->pri_ctrl = 0x0000000c;
+ p_MphMemMap->age_cnt_thresh = 0x00000040;
+ p_MphMemMap->si_ctrl= 0x00000001;
+
+#elif defined(CONFIG_DR_USB_SUPPORT)
+ t_USB_DR_MAP *p_DrMemMap;
+ p_DrMemMap = (t_USB_DR_MAP *)MPC83xx_USB_DR_BASE;
+ p_DrMemMap->control = 0x00000004;
+ p_DrMemMap->snoop1 = 0x0000001b;
+ portsc = readl(&p_DrMemMap->port_status[0]);
+ portsc &= ~PORT_TS;
+#if defined(CONFIG_DR_ULPI)
+ portsc |= PORT_TS_ULPI;
+#elif defined(CONFIG_DR_SERIAL)
+ portsc |= PORT_TS_SERIAL;
+#elif defined(CONFIG_DR_UTMI)
+ portsc |= PORT_TS_ULPI;
+#endif
+
+ writel(portsc,&p_DrMemMap->port_status[0]);
+ writel(0x00000003,&p_DrMemMap->usbmode);
+ p_DrMemMap->pri_ctrl = 0x0000000c;
+ p_DrMemMap->age_cnt_thresh = 0x00000040;
+ p_DrMemMap->si_ctrl= 0x00000001;
+#endif
+}
+
+
+static int __init
+fsl_usb20_probe(struct device *dev)
+{
+ struct usb_hcd *hcd;
+ struct ehci_hcd *ehci;
+ int retval;
+#if defined (CONFIG_MPH_USB_SUPPORT)
+ t_USB_MPH_MAP *p_MphMemMap;
+#elif defined (CONFIG_DR_USB_SUPPORT)
+ t_USB_DR_MAP *p_DrMemMap;
+#endif
+ mpc8349_board_init();
+ mpc8349_usb_clk_cfg();
+ mpc8349_usb_pin_cfg();
+
+ hcd = usb_create_hcd(&ehci_driver);
+ if (!hcd) {
+ retval = 0;
+ goto err1;
+ }
+
+ ehci = hcd_to_ehci(hcd);
+ dev_set_drvdata(dev, ehci);
+
+#if defined(CONFIG_MPH_USB_SUPPORT)
+ p_MphMemMap = (t_USB_MPH_MAP *)MPC83xx_USB_MPH_BASE;
+
+ hcd->regs = (void *)(&p_MphMemMap->hc_capbase);
+ hcd->irq = MPC83xx_USB_MPH_IVEC;
+
+#elif defined (CONFIG_DR_USB_SUPPORT)
+ /* Enable PHY interface in the control reg. */
+ p_DrMemMap = (t_USB_DR_MAP *)MPC83xx_USB_DR_BASE;
+ hcd->regs = (void *)(&p_DrMemMap->hc_capbase);/* Set the interrupt that is called for this USB. */
+ hcd->irq = MPC83xx_USB_DR_IVEC;
+
+#endif
+
+ hcd->self.controller = dev;
+ hcd->self.bus_name = dev->bus_id;
+ hcd->product_desc ="fsl usb20";
+
+ retval = request_irq(hcd->irq, usb_hcd_irq, SA_INTERRUPT,hcd->driver->description, hcd);
+ if (retval != 0)
+ goto err2;
+ retval = usb_register_bus(&hcd->self);
+ if (retval < 0)
+ goto err3;
+
+ retval=ehci_hc_reset(hcd);
+
+ if (retval < 0)
+ goto err4;
+
+ if ((retval = ehci_start (hcd)) < 0) {
+ goto err4;
+ }
+
+ return 0;
+err4:
+ usb_deregister_bus(&hcd->self);
+err3:
+ free_irq(hcd->irq, hcd);
+err2:
+ usb_put_hcd(hcd);
+err1:
+ printk("init error, %d\n", retval);
+ return retval;
+}
+
+static int __init_or_module
+fsl_usb20_remove(struct device *dev)
+{
+ struct ehci_hcd *ehci = dev_get_drvdata(dev);
+ struct usb_hcd *hcd = ehci_to_hcd(ehci);
+
+
+ if (HCD_IS_RUNNING(hcd->state))
+ hcd->state = USB_STATE_QUIESCING;
+
+ usb_disconnect(&hcd->self.root_hub);
+
+ hcd->driver->stop (hcd);
+
+ usb_deregister_bus(&hcd->self);
+
+ free_irq(hcd->irq, hcd);
+
+ usb_put_hcd(hcd);
+ return 0;
+}
+
+#define fsl_usb20_suspend NULL
+#define fsl_usb20_resume NULL
+
+static struct device_driver fsl_usb20_driver = {
+ .name = (char *) hcd_name,
+ .bus = &platform_bus_type,
+
+ .probe = fsl_usb20_probe,
+ .remove = fsl_usb20_remove,
+
+ .suspend = fsl_usb20_suspend,
+ .resume = fsl_usb20_resume,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int __init mpc8349_usb_hc_init(void)
+{
+ if (usb_disabled())
+ return -ENODEV;
+
+ printk(KERN_INFO"driver %s, %s\n", hcd_name, DRIVER_VERSION);
+ return driver_register(&fsl_usb20_driver);
+}
+
+
+static void __exit mpc8349_usb_hc_deinit(void)
+{
+ driver_unregister(&fsl_usb20_driver);
+}
+MODULE_DESCRIPTION (DRIVER_INFO);
+MODULE_AUTHOR (DRIVER_AUTHOR);
+MODULE_LICENSE ("GPL");
+module_init(mpc8349_usb_hc_init);
+module_exit(mpc8349_usb_hc_deinit);
diff -Nur linux/drivers/usb/host/fsl-usb.h linux-8349-2.6/drivers/usb/host/fsl-usb.h
--- linux/drivers/usb/host/fsl-usb.h 1970-01-01 08:00:00.000000000 +0800
+++ linux-8349-2.6/drivers/usb/host/fsl-usb.h 2005-08-25 11:49:00.000000000 +0800
@@ -0,0 +1,406 @@
+/* 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 _MPC8349_USB_EHCI_H
+#define _MPC8349_USB_EHCI_H
+
+/**************************************************************************/
+/*@Description t_USB_MPH_MAP - USB Multi-Port-Host internal memory map.*/
+/***************************************************************************/
+typedef struct{
+ volatile u32 id; /* Identification register */
+ volatile u32 hwgeneral;
+ volatile u32 hwhost;
+ volatile u8 RESERVED01[0x004]; /* Reserved area */
+ volatile u32 hwtxbuf;
+ volatile u32 hwrxbuf;
+ volatile u8 RESERVED02[0x0e8]; /* Reserved area */
+
+ /* Capability Registers */
+ volatile u32 hc_capbase;
+ volatile u32 hcs_params; /* HCSPARAMS - offset 0x4 */
+ volatile u32 hcc_params; /* HCCPARAMS - offset 0x8 */
+ volatile u8 portroute [8]; /* nibbles for routing - offset 0xC */
+ volatile u8 RESERVED03[0x02c]; /* Reserved area */
+
+ /* Operational Registers */
+ volatile u32 command;
+ volatile u32 status;
+ volatile u32 intr_enable;
+ volatile u32 frame_index; /* current microframe number */
+ volatile u32 segment; /* address bits 63:32 if needed */
+ volatile u32 frame_list; /* points to periodic list */
+ volatile u32 async_next; /* address of next async queue head */
+ volatile u32 async_tt_status; /* async queue status for embedded TT */
+ volatile u32 burst_size; /* programmable burst size */
+ volatile u32 txfilltuning; /* host transmit pre-buffer packet tuning */
+ volatile u32 txttfilltuning; /* host TT transmit pre-buffer packet tuning */
+ volatile u8 RESERVED04[4];
+ volatile u32 ulpi_view_port; /* ULPI view port */
+ volatile u32 endpoint_nack; /* endpoint nack */
+ volatile u32 endpoint_nack_en; /* endpoint nack enable */
+ volatile u8 RESERVED05[4];
+ volatile u32 configured_flag;
+ volatile u32 port_status [2]; /* up to N_PORTS */
+
+ volatile u8 RESERVED06[0x01c]; /* Reserved area */
+ volatile u32 usbmode;
+ volatile u8 RESERVED07[0x254]; /* Reserved area */
+ volatile u32 snoop1;
+ volatile u32 snoop2;
+ volatile u32 age_cnt_thresh;
+ volatile u32 si_ctrl;
+ volatile u32 pri_ctrl;
+ volatile u8 RESERVED08[0x0ec]; /* Reserved area */
+ volatile u32 control;
+ volatile u8 RESERVED09[0xaf8]; /* Reserved area */
+} t_USB_MPH_MAP;
+
+/**************************************************************************/
+/** @Description t_USB_DR_MAP - USB Dual-Role internal memory map. */
+/***************************************************************************/
+typedef struct{
+ volatile u32 id; /* Identification register */
+ volatile u32 hwgeneral;
+ volatile u32 hwhost;
+ volatile u32 hwdevice;
+ volatile u32 hwtxbuf;
+ volatile u32 hwrxbuf;
+ volatile u8 RESERVED01[0x0e8]; /* Reserved area */
+
+ /* Capability Registers */
+ volatile u32 hc_capbase;
+ volatile u32 hcs_params; /* HCSPARAMS - offset 0x4 */
+ volatile u32 hcc_params; /* HCCPARAMS - offset 0x8 */
+ volatile u8 portroute [8]; /* nibbles for routing - offset 0xC */
+ volatile u8 RESERVED02[0x00c]; /* Reserved area */
+ volatile u32 dciversion;
+ volatile u32 dccparms;
+ volatile u8 RESERVED03[0x018]; /* Reserved area */
+
+ /* Operational Registers */
+ volatile u32 command;
+ volatile u32 status;
+ volatile u32 intr_enable;
+ volatile u32 frame_index; /* current microframe number */
+ union t_host_slave_regs {
+ struct t_ehci_regs
+ {
+ volatile u32 segment; /* address bits 63:32 if needed */
+ volatile u32 frame_list; /* points to periodic list */
+ volatile u32 async_next; /* address of next async queue head */
+ } host_regs;
+ struct t_slave_regs {
+ volatile u8 RESERVED04 [0x04];
+ volatile u32 deviceaddr;
+ volatile u32 endpoint_list_addr; /* points to periodic list */
+ } slave_regs;
+ } host_slave_regs;
+ volatile u32 async_tt_status; /* async queue status for embedded TT */
+ volatile u32 burst_size; /* programmable burst size */
+ volatile u32 txfilltuning; /* host transmit pre-buffer packet tuning */
+ volatile u32 txttfilltuning; /* host TT transmit pre-buffer packet tuning */
+ volatile u8 RESERVED04[4];
+ volatile u32 ulpi_view_port; /* ULPI view port */
+ volatile u32 endpoint_nack; /* endpoint nack */
+ volatile u32 endpoint_nack_en; /* endpoint nack enable */
+ volatile u8 RESERVED05[4];
+ volatile u32 configured_flag;
+ volatile u32 port_status [1]; /* up to N_PORTS */
+
+ volatile u8 RESERVED06[0x01c]; /* Reserved area */
+ volatile u32 otgsc;
+ volatile u32 usbmode;
+ volatile u32 endptsetupstat;
+ volatile u32 endptprime;
+ volatile u32 endptflush;
+ volatile u32 endptstatus;
+ volatile u32 endptcomplete;
+ volatile u32 endptctrl[6];
+ volatile u8 RESERVED07[0x228]; /* Reserved area */
+ volatile u32 snoop1;
+ volatile u32 snoop2;
+ volatile u32 age_cnt_thresh;
+ volatile u32 si_ctrl;
+ volatile u32 pri_ctrl;
+ volatile u8 RESERVED08[0x0ec]; /* Reserved area */
+ volatile u32 control;
+ volatile u8 RESERVED09[0xaf8]; /* Reserved area */
+} __attribute__ ((packed)) t_USB_DR_MAP, * t_pUSB_DR_MAP;
+
+
+
+#define PORT_OFF 0
+#define PORT_ULPI 1
+#define PORT_UTMI 2
+#define PORT_SERIAL 3
+#define PORT_SERIAL_OTG 4
+
+
+#define PORT_TS 0xc0000000
+#define PORT_TS_UTMI 0x00000000
+#define PORT_TS_ULPI 0x80000000
+#define PORT_TS_SERIAL 0xc0000000
+#define PORT_TW 0x10000000
+#define PORT_SPD 0x0c000000
+#define PORT_FSC 0x01000000
+#define PORT_PP 0x00001000
+
+
+
+#define CFG_IMMR_BASE (0xfe000000)
+#define MPC83xx_USB_MPH_BASE (CFG_IMMR_BASE + 0x22000)
+#define MPC83xx_USB_DR_BASE (CFG_IMMR_BASE + 0x23000)
+#define MPC83xx_USB_DR_IVEC (38)
+#define MPC83xx_USB_MPH_IVEC (39)
+#define CFG_BCSR_BASE (0xfe100000)
+#define BCSR5_INT_USB (0x02)
+
+#define e_USB_MPH 0
+#define e_USB_DR 1
+#define e_ULPI 0
+#define e_UTMI_8BIT 1
+#define e_UTMI_16BIT 2
+#define e_SERIAL 3
+
+#define SCCR_OFFS 0xA08
+#define SCCR_USB_MPHCM_11 0x00c00000
+#define SCCR_USB_MPHCM_01 0x00400000
+#define SCCR_USB_MPHCM_10 0x00800000
+#define SCCR_USB_DRCM_11 0x00300000
+#define SCCR_USB_DRCM_01 0x00100000
+#define SCCR_USB_DRCM_10 0x00200000
+
+#define SICRL_OFFS 0x114
+#define SICRL_USB1 0x40000000
+#define SICRL_USB0 0x20000000
+
+#define SICRH_OFFS 0x118
+#define SICRH_USB_UTMI 0x00020000
+
+#define SPCR_OFFS 0x00000110
+#define SPCR_TBEN 0x00400000
+
+#define POWER_OF_2(n) (!(n & (n-1)))
+
+/*------------------------------------------------------*/
+
+typedef struct
+{
+ char Name[4]; /* this segment's name */
+ spinlock_t lock;
+ u16 Num; /* number of blocks in segment */
+ int Size; /* size of blocks in segment */
+ /* in case of TMP_DEF - */
+ /* only the data */
+ u32 GetFailures; /* number of times get failed */
+ int LocallyAllocated; /* TRUE if memory was allocated */
+ /* at MEM_Init. */
+ u8 *p_Base; /* base address of segment */
+ void **p_First; /* first block in segment */
+ void **p_Last; /* last block in segment */
+ int (*f_MemPut)(void* Handle, void *p_Block );
+ /* a routine for returning a memory block */
+
+ u16 PrefixSize; /* replaces B_OFFSET - how many */
+ /* bytes to reserve before the data */
+ u16 PostfixSize ; /* replaces B_TRAILER - how many */
+ /* bytes to reserve after the data */
+ /* Trailer also includes a pad needed for */
+ /* padding the entire block to 4 byte */
+ /* alignment for faster access to the */
+ /* control field */
+ u16 Alignment; /* requested alignment for the data field */
+ u16 AlignPad; /* pad the offset field so that the data */
+ /* field shall have the proper alignment */
+ u16 EndPad; /* Pad to make entire block size a */
+ /* multiple of Alignment */
+} t_MemorySegment;
+
+#define PAD_ALIGNMENT( align, x ) ( ((x)%(align)) ? ((align)-((x)%(align))) : 0 )
+
+
+void *MEM_Get( void* Handle )
+{
+ unsigned long flags;
+ u8 *p_F;
+ t_MemorySegment *p ;
+
+ p = (t_MemorySegment *)Handle;
+
+ spin_lock_irqsave(&p->lock,flags);
+
+ /* check if the chain is not empty */
+ if( !(*(p->p_First)) )
+ {
+ p->GetFailures++;
+ spin_unlock_irqrestore(p->lock,flags);
+ return 0;
+ }
+ /* advance first pointer and return the old head of chain */
+ p_F = ((u8 *)p->p_First) + ( 4 + p->AlignPad + p->PrefixSize );
+ p->p_First = (void **) *(p->p_First); /* skip the next pointer */
+
+ spin_unlock_irqrestore(&p->lock,flags);
+
+ return (void *)p_F;
+}
+
+
+int MEM_Put_Default( void * Handle, void *p_Block )
+{
+ unsigned long flags;
+ t_MemorySegment *p = (t_MemorySegment *)Handle;
+ u8 *p_B = (u8 *)p_Block;
+
+ /* if handle is NULL, use user's free routine */
+ if( Handle == 0 )
+ {
+ kfree( p_Block );
+ return 0;
+ }
+
+ spin_lock_irqsave(&p->lock,flags);
+
+ /* get the pointer to the start of the memory */
+ p_B -= ( 4 + p->AlignPad + p->PrefixSize ); /* skip back over next pointer */
+ /* chain to end and advance last pointer */
+ *((void **)p_B) = 0;
+ *(p->p_Last) = (void *)p_B;
+ p->p_Last = (void **)p_B;
+
+ spin_unlock_irqrestore(&p->lock,flags);
+ return 0;
+}
+
+int MEM_Init( char Name[],
+ void* *p_Handle,
+ u16 Num,
+ u16 Size ,
+ u16 PrefixSize,
+ u16 PostfixSize,
+ u16 Alignment )
+{
+ t_MemorySegment *p;
+ u8 *p_Blocks;
+ int i ;
+ int blockSize;
+
+ /* always allocate a dummy block at the end */
+ Num++;
+
+ /* make sure size is always a multiple of 4 */
+ if( Size & 3 )
+ {
+ Size &= ~3;
+ Size += 4;
+ }
+
+ if (Alignment < 4 )
+ Alignment = 4;
+
+ /** make sure that the alignment is a power of two */
+ if( !POWER_OF_2(Alignment) )
+ {
+ printk("MEM_Init: requested alignment is not a power of two.\n");
+ return -EINVAL;
+ }
+
+ /* prepare in case of error */
+ *p_Handle = 0;
+
+ /* first allocate the segment descriptor */
+ p = (t_MemorySegment *)kmalloc( sizeof(t_MemorySegment),GFP_KERNEL );
+
+ if( !p )
+ return -ENOMEM;
+ /* calculate blockSize */
+
+ /* store info about this segment */
+ spin_lock_init (&p->lock);
+ p->Num = (u16)(Num - 1);
+ p->Size = Size;
+ p->GetFailures = 0L;
+ p->f_MemPut = MEM_Put_Default;
+ p->LocallyAllocated = 1;
+ p->PrefixSize = PrefixSize;
+ p->Alignment = Alignment;
+ p->AlignPad = (u16)PAD_ALIGNMENT((u16)4, (u16)PrefixSize+4);
+ p->PostfixSize = PostfixSize;
+ /* Make sure the entire size is a multiple of Alignment */
+ p->EndPad = (u16)PAD_ALIGNMENT((u16)Alignment, 4 + p->AlignPad + PrefixSize + Size + PostfixSize);
+
+ blockSize = 4 + p->AlignPad + PrefixSize + Size + PostfixSize + p->EndPad;
+
+ p_Blocks = (u8 *)kmalloc(( Alignment + Num * blockSize ),GFP_KERNEL);
+
+ if( !p_Blocks )
+ {
+ kfree( p );
+ return -ENOMEM;
+ }
+ /* store the memory segment address */
+ p->p_Base = p_Blocks;
+
+ p_Blocks += (PrefixSize+4);
+ p_Blocks += (PAD_ALIGNMENT( Alignment, (u32)p_Blocks));
+ p_Blocks -= (PrefixSize+4+p->AlignPad);
+
+ /* store name */
+ strncpy( p->Name, Name, 4 );
+
+ /* finally, initialize the blocks */
+ p->p_Last = p->p_First = (void **)p_Blocks;
+ for(i = 0; i < (Num-1); i++)
+ {
+ /* get next block */
+ p_Blocks += blockSize;
+
+ /* attach to end of chain */
+ if( p->p_Last )
+ *(p->p_Last) = (void *)p_Blocks;
+
+ /* advance last pointer */
+ p->p_Last = (void **)p_Blocks;
+ }
+
+ /* zero next pointer in last block */
+ *(p->p_Last) = 0;
+
+ /* return handle to caller */
+ *p_Handle = (void *)p;
+
+ return 0;
+}
+
+
+
+void MEM_Free( void* p_Handle)
+{
+ t_MemorySegment *p = (t_MemorySegment*)p_Handle;
+
+ if ( p && p->LocallyAllocated)
+ kfree (p->p_Base);
+ kfree(p);
+}
+
+#define MEM_Put(Handle, p_Block) \
+ ((t_MemorySegment *)Handle)->f_MemPut( Handle, p_Block)
+
+
+
+
+#endif /* __STD_EXT_H */
diff -Nur linux/drivers/usb/host/Kconfig linux-8349-2.6/drivers/usb/host/Kconfig
--- linux/drivers/usb/host/Kconfig 2004-12-25 05:35:29.000000000 +0800
+++ linux-8349-2.6/drivers/usb/host/Kconfig 2005-08-16 14:58:56.000000000 +0800
@@ -5,6 +5,7 @@
boolean
default y if USB_ARCH_HAS_OHCI
default y if ARM # SL-811
+ default y if FSL_USB20 # MPC83xx SYS
default PCI
# many non-PCI hcds implement OHCI
@@ -24,7 +25,7 @@
config USB_EHCI_HCD
tristate "EHCI HCD (USB 2.0) support"
- depends on USB && PCI
+ depends on (USB && PCI) || (USB && FSL_USB20)
---help---
The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0
"high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware.
diff -Nur linux/drivers/usb/host/Makefile linux-8349-2.6/drivers/usb/host/Makefile
--- linux/drivers/usb/host/Makefile 2004-12-25 05:35:39.000000000 +0800
+++ linux-8349-2.6/drivers/usb/host/Makefile 2005-08-15 13:41:35.000000000 +0800
@@ -2,8 +2,11 @@
# Makefile for USB Host Controller Driver
# framework and drivers
#
-
+ifeq ($(CONFIG_FSL_USB20),y)
+obj-$(CONFIG_USB_EHCI_HCD) += fsl-usb.o
+else
obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o
+endif
obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o
obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o
obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o
diff -Nur linux/arch/ppc/platforms/83xx/Kconfig linux-8349-2.6/arch/ppc/platforms/83xx/Kconfig
--- linux/arch/ppc/platforms/83xx/Kconfig 2005-03-03 01:46:54.000000000 +0800
+++ linux-8349-2.6/arch/ppc/platforms/83xx/Kconfig 2005-08-25 11:44:57.000000000 +0800
@@ -27,4 +27,78 @@
depends on 83xx
default y
+config FSL_USB20
+ bool "MPC834x USB20 Host Support"
+ depends on MPC834x_SYS
+
+
+menu "USB20 Host Configuration"
+ depends on FSL_USB20
+
+choice
+ prompt "MPC83xx USB20 host Mode"
+ depends on FSL_USB20
+ default MPH_USB_SUPPORT
+
+config MPH_USB_SUPPORT
+ bool "MPH_MODE"
+
+config DR_USB_SUPPORT
+ bool "DR_MODE"
+
+endchoice
+
+config MPH0_USB_ENABLE
+ bool "MPH0 USB HOST Enable"
+ depends on MPH_USB_SUPPORT
+
+choice
+ prompt "MPH0 PHY Interface Selection"
+ depends on MPH0_USB_ENABLE
+ default MPH0_ULPI
+
+config MPH0_ULPI
+ bool "ULPI"
+
+config MPH0_SERIAL
+ bool "Serial"
+
+endchoice
+
+config MPH1_USB_ENABLE
+ bool "MPH1 USB HOST Enable"
+ depends on MPH_USB_SUPPORT
+
+choice
+ prompt "MPH1 PHY Interface Selection"
+ depends on MPH1_USB_ENABLE
+ default MPH1_ULPI
+
+config MPH1_ULPI
+ bool "ULPI"
+
+config MPH1_SERIAL
+ bool "Serial"
+
+endchoice
+
+
+choice
+ prompt "DR PHY Interface Selection"
+ depends on DR_USB_SUPPORT
+ default DR_ULPI
+
+config DR_ULPI
+ bool "ULPI"
+
+config DR_SERIAL
+ bool "Serial"
+
+config DR_UTMI
+ bool "UTMI"
+
+endchoice
+
+endmenu
+
endmenu
--
Leo Li
Freescale Semiconductor
LeoLi@freescale.com
^ permalink raw reply
* [PATCH]ppc32: Adds PQ2FADS flash SIMM support as physmap device
From: Vitaly Bordug @ 2005-12-20 3:57 UTC (permalink / raw)
To: linuxppc-embedded list
Implemented more correct way to support physmapped flash on PQ2FADS
than map in mtd (which is already removed from the mtd tree).
The areas intended to contain bootloader are protected readonly.
Note that CFI and JEDEC stuff should be configured properly in order
this to work, e.g. for 8272 CFI should support 4-chip flash interleave.
Also fixed compilation warning.
Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>
---
commit 3af1e7e029c4fd50236078e48e79f8112a999de8
tree f84ee4fe92d616a0f640e1e86601a003d887b807
parent a8450a334dc930d7284800c457d91ed55a1a3dd7
author Vitaly Bordug <vbordug@ru.mvista.com> Sun, 18 Dec 2005 21:26:13 +0300
committer Vitaly Bordug <vbordug@ru.mvista.com> Sun, 18 Dec 2005 21:26:13 +0300
arch/ppc/syslib/m8260_setup.c | 71 ++++++++++++++++++++++++++++++++++++++++-
1 files changed, 70 insertions(+), 1 deletions(-)
diff --git a/arch/ppc/syslib/m8260_setup.c b/arch/ppc/syslib/m8260_setup.c
index 76a2aa4..693e8dc 100644
--- a/arch/ppc/syslib/m8260_setup.c
+++ b/arch/ppc/syslib/m8260_setup.c
@@ -20,6 +20,13 @@
#include <linux/seq_file.h>
#include <linux/irq.h>
+#if defined(CONFIG_MTD) && defined(CONFIG_MTD_PHYSMAP)
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#endif
+
#include <asm/mmu.h>
#include <asm/io.h>
#include <asm/pgtable.h>
@@ -28,9 +35,58 @@
#include <asm/machdep.h>
#include <asm/bootinfo.h>
#include <asm/time.h>
+#include <asm/ppc_sys.h>
#include "cpm2_pic.h"
+#ifdef CONFIG_MTD_PHYSMAP
+#define PQ2FADS_BANK_WIDTH 4
+#endif
+
+#if defined(CONFIG_MTD_PARTITIONS)
+/*
+ NOTE: bank width and interleave relative to the installed flash
+ should have been chosen within MTD_CFI_GEOMETRY options.
+ */
+
+static struct mtd_partition pq2fads_partitions[] = {
+ {
+#if defined(CONFIG_ADS8272)
+ .name = "HRCW",
+ .size = 0x40000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "User FS",
+ .size = 0x5c0000,
+ .offset = 0x40000,
+#else
+ .name = "User FS",
+ .size = 0x600000,
+ .offset = 0,
+#endif
+ }, {
+ .name = "uImage",
+ .size = 0x100000,
+ .offset = 0x600000,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "bootloader",
+ .size = 0x40000,
+ .offset = 0x700000,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "bootloader env",
+ .size = 0x40000,
+ .offset = 0x740000,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }
+};
+
+#define pq2fads_part_num (sizeof (pq2fads_partitions) / sizeof (pq2fads_partitions[0]))
+
+#endif
+
unsigned char __res[sizeof(bd_t)];
extern void pq2_find_bridges(void);
@@ -46,6 +102,9 @@ m82xx_board_setup(void)
static void __init
m8260_setup_arch(void)
{
+#if defined(CONFIG_MTD) && defined(CONFIG_MTD_PHYSMAP)
+ bd_t *binfo = (bd_t *)__res;
+#endif
/* Print out Vendor and Machine info. */
printk(KERN_INFO "%s %s port\n", CPUINFO_VENDOR, CPUINFO_MACHINE);
@@ -64,7 +123,17 @@ m8260_setup_arch(void)
#endif
identify_ppc_sys_by_name_and_id(BOARD_CHIP_NAME,
- in_be32(CPM_MAP_ADDR + CPM_IMMR_OFFSET));
+ in_be32((void*)(CPM_MAP_ADDR + CPM_IMMR_OFFSET)));
+
+#if defined (CONFIG_ADS8272) || defined (CONFIG_PQ2FADS)
+#if defined(CONFIG_MTD_PHYSMAP)
+ physmap_configure(binfo->bi_flashstart, binfo->bi_flashsize,
+ PQ2FADS_BANK_WIDTH, NULL);
+#ifdef CONFIG_MTD_PARTITIONS
+ physmap_set_partitions(pq2fads_partitions, pq2fads_part_num);
+#endif /* CONFIG_MTD_PARTITIONS */
+#endif /* CONFIG_MTD_PHYSMAP */
+#endif
m82xx_board_setup();
}
^ permalink raw reply related
* [PATCH 1/3] ppc32: Make platform devices being able to assign functions (update)
From: Vitaly Bordug @ 2005-12-20 3:50 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-embedded list
Implemented by modification of the .name field of the platform device,
when PDs with the
same names are to be used within different drivers, as
<device_name> -> <device_name>:<function>
Corresponding drivers should change the .name in struct device_driver to
reflect upper of course.
Also helper platform_notify_map function added, making assignment of
board-specific platform_info more consistent and generic.
Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>
---
arch/ppc/syslib/ppc_sys.c | 136 ++++++++++++++++++++++++++++++++++++++++++++-
include/asm-ppc/mpc10x.h | 1
include/asm-ppc/mpc52xx.h | 1
include/asm-ppc/mpc8260.h | 1
include/asm-ppc/mpc83xx.h | 1
include/asm-ppc/mpc85xx.h | 1
include/asm-ppc/mpc8xx.h | 1
include/asm-ppc/ppc_sys.h | 24 ++++++++
8 files changed, 164 insertions(+), 2 deletions(-)
applies-to: 4ce1b1890dc687cb1cf77f98e7a95b94c7ef3a93
a8450a334dc930d7284800c457d91ed55a1a3dd7
diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
index c0b93c4..26d2658 100644
--- a/arch/ppc/syslib/ppc_sys.c
+++ b/arch/ppc/syslib/ppc_sys.c
@@ -15,11 +15,23 @@
*/
#include <linux/string.h>
+#include <linux/bootmem.h>
#include <asm/ppc_sys.h>
int (*ppc_sys_device_fixup) (struct platform_device * pdev);
static int ppc_sys_inited;
+static int ppc_sys_func_inited;
+
+static const char *ppc_sys_func_names[] = {
+ [FUNC_ENABLED] = "dummy",
+ [FUNC_ETH] = "eth",
+ [FUNC_UART] = "uart",
+ [FUNC_HLDC] = "hldc",
+ [FUNC_USB] = "usb",
+ [FUNC_IRDA] = "irda",
+ [FUNC_DISABLED] = "off",
+};
void __init identify_ppc_sys_by_id(u32 id)
{
@@ -38,13 +50,13 @@ void __init identify_ppc_sys_by_id(u32 i
void __init identify_ppc_sys_by_name(char *name)
{
unsigned int i = 0;
- while (ppc_sys_specs[i].ppc_sys_name[0])
- {
+ while (ppc_sys_specs[i].ppc_sys_name[0]) {
if (!strcmp(ppc_sys_specs[i].ppc_sys_name, name))
break;
i++;
}
cur_ppc_sys_spec = &ppc_sys_specs[i];
+
return;
}
@@ -128,6 +140,126 @@ void ppc_sys_device_remove(enum ppc_sys_
}
}
+/* Platform-notify mapping
+ * Helper function for BSP code to assign board-specific platfom-divice bits
+ */
+
+void platform_notify_map(const struct platform_notify_dev_map *map,
+ struct device *dev)
+{
+ struct platform_device *pdev;
+ int len, idx;
+ const char *s;
+
+ /* do nothing if no device or no bus_id */
+ if (!dev || !dev->bus_id)
+ return;
+
+ /* call per device map */
+ while (map->bus_id != NULL) {
+ idx = -1;
+ s = strrchr(dev->bus_id, '.');
+ if (s != NULL)
+ idx = (int)simple_strtol(s + 1, NULL, 10);
+ else
+ s = dev->bus_id;
+
+ len = s - dev->bus_id;
+
+ if (!strncmp(dev->bus_id, map->bus_id, len)) {
+ pdev = container_of(dev, struct platform_device, dev);
+ map->rtn(pdev, idx);
+ }
+ map++;
+ }
+}
+
+/*
+ Function assignment stuff.
+ Intended to work as follows:
+ the device name defined in foo_devices.c will be concatenated with :"func",
+ where func is string map of respective function from platfom_device_func enum
+
+ The FUNC_ENABLED function is intended to remove all assignments, making the device to appear
+ in platform bus with unmodified name.
+ */
+
+/*
+ Here we'll replace .name pointers with fixed-lenght strings
+ Hereby, this should be called *before* any func stuff triggeded.
+ */
+void ppc_sys_device_initfunc(void)
+{
+ int i;
+ const char *name;
+ static char new_names[NUM_PPC_SYS_DEVS][BUS_ID_SIZE];
+ enum ppc_sys_devices cur_dev;
+
+ /* If inited yet, do nothing */
+ if (ppc_sys_func_inited)
+ return;
+
+ for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
+ if ((cur_dev = cur_ppc_sys_spec->device_list[i]) < 0)
+ continue;
+
+ if (ppc_sys_platform_devices[cur_dev].name) {
+ /*backup name */
+ name = ppc_sys_platform_devices[cur_dev].name;
+ strlcpy(new_names[i], name, BUS_ID_SIZE);
+ ppc_sys_platform_devices[cur_dev].name = new_names[i];
+ }
+ }
+
+ ppc_sys_func_inited = 1;
+}
+
+/*The "engine" of the func stuff. Here we either concat specified function string description
+ to the name, or remove it if FUNC_ENABLED parameter is passed here*/
+void ppc_sys_device_setfunc(enum ppc_sys_devices dev,
+ enum platform_device_func func)
+{
+ char *s;
+ char *name = (char *)ppc_sys_platform_devices[dev].name;
+ char tmp[BUS_ID_SIZE];
+
+ if (!ppc_sys_func_inited) {
+ printk(KERN_ERR "Unable to alter function - not inited!\n");
+ return;
+ }
+
+ if (ppc_sys_inited) {
+ platform_device_unregister(&ppc_sys_platform_devices[dev]);
+ }
+
+ if ((s = (char *)strchr(name, ':')) != NULL) { /* reassign */
+ /* Either change the name after ':' or remove func modifications */
+ if (func != FUNC_ENABLED)
+ strlcpy(s + 1, ppc_sys_func_names[func], BUS_ID_SIZE);
+ else
+ *s = 0;
+ } else if (func != FUNC_ENABLED) {
+ /* do assignment if it is not just "enable" request */
+ sprintf(tmp, "%s:%s", name, ppc_sys_func_names[func]);
+ strlcpy(name, tmp, BUS_ID_SIZE);
+ }
+
+ if (ppc_sys_inited) {
+ platform_device_register(&ppc_sys_platform_devices[dev]);
+ }
+}
+
+void ppc_sys_device_set_func_all(enum platform_device_func func)
+{
+ enum ppc_sys_devices cur_dev;
+ int i;
+
+ for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
+ cur_dev = cur_ppc_sys_spec->device_list[i];
+ ppc_sys_device_setfunc(cur_dev, func);
+ }
+}
+
static int __init ppc_sys_init(void)
{
unsigned int i, dev_id, ret = 0;
diff --git a/include/asm-ppc/mpc10x.h b/include/asm-ppc/mpc10x.h
index 77b1e09..976ad3d 100644
--- a/include/asm-ppc/mpc10x.h
+++ b/include/asm-ppc/mpc10x.h
@@ -165,6 +165,7 @@ enum ppc_sys_devices {
MPC10X_DMA1,
MPC10X_UART0,
MPC10X_UART1,
+ NUM_PPC_SYS_DEVS,
};
int mpc10x_bridge_init(struct pci_controller *hose,
diff --git a/include/asm-ppc/mpc52xx.h b/include/asm-ppc/mpc52xx.h
index e5f80c2..b2cb44f 100644
--- a/include/asm-ppc/mpc52xx.h
+++ b/include/asm-ppc/mpc52xx.h
@@ -49,6 +49,7 @@ enum ppc_sys_devices {
MPC52xx_ATA,
MPC52xx_I2C1,
MPC52xx_I2C2,
+ NUM_PPC_SYS_DEVS,
};
diff --git a/include/asm-ppc/mpc8260.h b/include/asm-ppc/mpc8260.h
index 3214526..6ba69a8 100644
--- a/include/asm-ppc/mpc8260.h
+++ b/include/asm-ppc/mpc8260.h
@@ -83,6 +83,7 @@ enum ppc_sys_devices {
MPC82xx_CPM_SMC2,
MPC82xx_CPM_USB,
MPC82xx_SEC1,
+ NUM_PPC_SYS_DEVS,
};
#ifndef __ASSEMBLY__
diff --git a/include/asm-ppc/mpc83xx.h b/include/asm-ppc/mpc83xx.h
index 7cdf60f..3c23fc4 100644
--- a/include/asm-ppc/mpc83xx.h
+++ b/include/asm-ppc/mpc83xx.h
@@ -108,6 +108,7 @@ enum ppc_sys_devices {
MPC83xx_USB2_DR,
MPC83xx_USB2_MPH,
MPC83xx_MDIO,
+ NUM_PPC_SYS_DEVS,
};
#endif /* CONFIG_83xx */
diff --git a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h
index 9d14bae..2a77884 100644
--- a/include/asm-ppc/mpc85xx.h
+++ b/include/asm-ppc/mpc85xx.h
@@ -135,6 +135,7 @@ enum ppc_sys_devices {
MPC85xx_eTSEC4,
MPC85xx_IIC2,
MPC85xx_MDIO,
+ NUM_PPC_SYS_DEVS,
};
/* Internal interrupts are all Level Sensitive, and Positive Polarity */
diff --git a/include/asm-ppc/mpc8xx.h b/include/asm-ppc/mpc8xx.h
index 46f159c..90e3d59 100644
--- a/include/asm-ppc/mpc8xx.h
+++ b/include/asm-ppc/mpc8xx.h
@@ -111,6 +111,7 @@ enum ppc_sys_devices {
MPC8xx_CPM_SMC1,
MPC8xx_CPM_SMC2,
MPC8xx_CPM_USB,
+ NUM_PPC_SYS_DEVS,
};
#ifndef BOARD_CHIP_NAME
diff --git a/include/asm-ppc/ppc_sys.h b/include/asm-ppc/ppc_sys.h
index 83d8c77..76f259f 100644
--- a/include/asm-ppc/ppc_sys.h
+++ b/include/asm-ppc/ppc_sys.h
@@ -47,6 +47,21 @@ struct ppc_sys_spec {
enum ppc_sys_devices *device_list;
};
+struct platform_notify_dev_map {
+ const char *bus_id;
+ void (*rtn)(struct platform_device * pdev, int idx);
+};
+
+enum platform_device_func {
+ FUNC_ENABLED = 0,
+ FUNC_ETH = 1,
+ FUNC_UART = 2,
+ FUNC_HLDC = 3,
+ FUNC_USB = 4,
+ FUNC_IRDA = 5,
+ FUNC_DISABLED = 6,
+};
+
/* describes all specific chips and which devices they have on them */
extern struct ppc_sys_spec ppc_sys_specs[];
extern struct ppc_sys_spec *cur_ppc_sys_spec;
@@ -72,5 +87,14 @@ extern void *ppc_sys_get_pdata(enum ppc_
/* remove a device from the system */
extern void ppc_sys_device_remove(enum ppc_sys_devices dev);
+/*Function assignment stuff*/
+void ppc_sys_device_initfunc(void);
+void ppc_sys_device_setfunc(enum ppc_sys_devices dev,
+ enum platform_device_func func);
+void ppc_sys_device_set_func_all(enum platform_device_func func);
+
+void platform_notify_map(const struct platform_notify_dev_map *map,
+ struct device *dev);
+
#endif /* __ASM_PPC_SYS_H */
#endif /* __KERNEL__ */
---
0.99.9.GIT
^ permalink raw reply related
* ramdisk loading address in U-Boot
From: HappyPhot @ 2005-12-20 1:45 UTC (permalink / raw)
To: linuxppc-embedded
Hi:
I build a ramdisk image and mkimage for U-Boot
by using -a and -e = 4000000.
In U-Boot command line, I type "tftpboot 2000000 ramdisk_image".
After bootm , the ramdisk is loaded to "0fdea000", like:
## initrd at 0x02000040 ... 0x02185BD0 (len=1596305=0x185B91)
Loading Ramdisk to 0fdea000, end 0ff6fb91 ... OK
## Transferring control to Linux ....
Why was the ramdisk loaded into 0fdea000, instead of 4000000 ?
thank you,
/HappyPhot
^ permalink raw reply
* Re: linux DMA capabilities in MV64460
From: Mark A. Greer @ 2005-12-20 1:01 UTC (permalink / raw)
To: Phil Nitschke; +Cc: linuxppc-embedded
In-Reply-To: <kw3bkovcup.fsf@lamorak.int.avalon.com.au>
Hi Phil,
[Note: I'm cc'ing linuxppc-embedded for others to reference and to
add their thoughts.]
---
On Tue, Dec 20, 2005 at 10:49:58AM +1030, Phil Nitschke wrote:
> Hi Mark,
>
> I'm developing a device driver to run in the 2.6.10 kernel. I want to
That's a pretty old kernel. Do you have the option of using a more
recent one like 2.6.14?
> get large amounts of data from a custom peripheral on the PCI bus. The
> software is running on an Artesyn PmPPC7448, which includes a Discovery
> III bridge.
Can you share exact platform you're using?
> The custom device is a digitizer, which runs at over 200 million samples
> per second, so we're looking to use a fair amount of PCI bandwidth to
> get the data into main memory. Burst reads/writes seem like the only
> way.
>
> I have seen that you wrote some code for the mainstream kernel that sets
> up the mv64460. One source told me:
>
> > In order to do PCI bursts, you'll need to use a DMA engine. The
> > MV64460 does contain a DMA engine, but you'd need to write a driver
> > to access it.
That is not correct (assuming the quote is not out of context).
The bridge supports bursting on the PCI bus as long as the bridge is
configured correctly and the PCI device is making an appropriate request.
Note, however, that there are many errata for the Marvell parts including
some with cache coherency. If your system is running with coherency on,
you may have to limit your bursts to 32 bytes (i.e., the size of one
cache line).
You can see how the bursting is set up on the bridge by looking at the
platform file for your board (e.g., <file:arch/ppc/platforms/katana.c> in
the latest linux kernel)--search for 'BURST'.
> Is there a summary of what is possible and/or not possible with the 4
> IDMA channels on the mv64460?
The only real documentation is the bridge's user manual from Marvell.
Unfortunately, you must sign an NDA to get access to it so I can't share
mine with you. You will need access to that info to get very far so I
recommend you contact the people in your company that can make that
happen, ASAP.
> For example, if the device that I'm trying to get data from supported a
> DMA engine capable of initiating bursts on the PCI bus (it currently
> can't do this), does the current kernel code support that?
That's a hardware feature so its not really an issue of kernel support
other than ensuring that the firmware and/or kernel configures the bridge
correctly. IOW, it can be supported by software but its an issue of
whether your hardware supports it (and it actually works).
> Or if I wanted to suck the data into main memory using the mv64460 IDMA
> controller (assuming the device couldn't initiate its own burst writes),
> is there a standard kernel interface to allow me to do this?
Yes. You would make a "dma ctlr driver" for the dma ctlr(s).
I don't know what the best example would be but hopefully someone else
has a suggestion.
> Sorry if the questions are silly or inappropriately directed.
Not at all. Those were good questions.
> At the
> moment I'm still trying to understand some really basic things, like
> what determines the difference between burst reads and ordinary reads,
> and what is the difference between SDMA and IDMA, etc ;-)
You may want to pick up "PCI System Architecture" from Mindshare, Inc.
There are ones for PCI-X and PCI-Express too, I think. Well worth the money.
> Many thanks for any help/suggestions/information you can offer.
>
> --
> Phil
I hope this helps,
Mark
^ permalink raw reply
* [PATCH] powerpc: Fix compile problem in pci.c for ppc32
From: Kumar Gala @ 2005-12-19 21:49 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
pci_address_to_pio is missing a closing curly brace
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
commit a86f866f7b31e01c729ee7498228c547a51d8514
tree 7cc7df7f28735a34618d450cc46bfd3c86d8725b
parent c211d7347a735eb5d5996433f3eef7159c3fe41a
author Kumar Gala <galak@kernel.crashing.org> Mon, 19 Dec 2005 15:52:42 -0600
committer Kumar Gala <galak@kernel.crashing.org> Mon, 19 Dec 2005 15:52:42 -0600
arch/ppc/kernel/pci.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 664af8b..7d4c0e3 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -1823,7 +1823,7 @@ unsigned long pci_address_to_pio(phys_ad
unsigned long base =
(unsigned long)hose->io_base_virt - _IO_BASE;
return base + (address - hose->io_base_phys);
-
+ }
}
return (unsigned int)-1;
}
^ permalink raw reply related
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