* [PATCH 2/2] powerpc/476: Workaround for PLB6 hang
From: Dave Kleikamp @ 2011-01-26 16:17 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Dave Kleikamp
In-Reply-To: <1296058679-21352-1-git-send-email-shaggy@linux.vnet.ibm.com>
The 476FP core may hang if an instruction fetch happens during an msync
following a tlbsync. This workaround makes sure that enough instruction
cache lines are pre-fetched before executing the msync. (sync and msync
are the same to the compiler.)
Signed-off-by: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
---
arch/powerpc/mm/tlb_nohash_low.S | 35 +++++++++++++++++++++++++++++++++++
1 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S
index af405ee..7c63c0e 100644
--- a/arch/powerpc/mm/tlb_nohash_low.S
+++ b/arch/powerpc/mm/tlb_nohash_low.S
@@ -189,6 +189,13 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x)
blr
#ifdef CONFIG_PPC_47x
+
+/*
+ * 47x variant of icbt
+ */
+# define ICBT(CT,RA,RB) \
+ .long 0x7c00002c | ((CT) << 21) | ((RA) << 16) | ((RB) << 11)
+
/*
* _tlbivax_bcast is only on 47x. We don't bother doing a runtime
* check though, it will blow up soon enough if we mistakenly try
@@ -206,7 +213,35 @@ _GLOBAL(_tlbivax_bcast)
isync
eieio
tlbsync
+BEGIN_FTR_SECTION
+ b 1f
+END_FTR_SECTION_IFSET(CPU_FTR_476_DD2)
+ sync
+ wrtee r10
+ blr
+/*
+ * DD2 HW could hang if in instruction fetch happens before msync completes.
+ * Touch enough instruction cache lines to ensure cache hits
+ */
+1: mflr r9
+ bl 2f
+2: mflr r6
+ li r7,32
+ ICBT(0,r6,r7) /* touch next cache line */
+ add r6,r6,r7
+ ICBT(0,r6,r7) /* touch next cache line */
+ add r6,r6,r7
+ ICBT(0,r6,r7) /* touch next cache line */
sync
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ mtlr r9
wrtee r10
blr
#endif /* CONFIG_PPC_47x */
--
1.7.3.4
^ permalink raw reply related
* Re: About mpc85xx flash memory allocation
From: Mitsutaka Amano @ 2011-01-26 10:51 UTC (permalink / raw)
To: tiejun.chen; +Cc: linuxppc-dev
In-Reply-To: <AANLkTimNmtqV3uO1+oiODeJmrDoyK570Vpb6n5AFnTKF@mail.gmail.com>
On Tue, Jan 25, 2011 at 11:17 AM, Mitsutaka Amano
<mitsutaka.amano@gmail.com> wrote:
> On Tue, Jan 25, 2011 at 11:05 AM, tiejun.chen <tiejun.chen@windriver.com>=
wrote:
>> Mitsutaka Amano wrote:
>>> On Mon, Jan 24, 2011 at 3:48 PM, tiejun.chen <tiejun.chen@windriver.com=
> wrote:
>>>> Mitsutaka Amano wrote:
>>>>> Hi all,
>>>>>
>>>>> I'm testing the ppc platform is based on mpc85xx. 256MB Flash memory
>>>>> has been installed. Then I found this entries.
>>>>>
>>>>> /proc/vmallocinfo
>>>>> ~~~
>>>>> 0xc9100000-0xd9101000 268439552 of_flash_probe+0x290/0x814 ioremap
>>>>>
>>>>> physmap_of allocated 268MB over to the vmalloc. vmalloc space is tigh=
t.
>>>>>
>>>>> Why does we need mpc platforms to flash memory allocation? I know
>>>> This should not be dedicated to so-called mpc platform. And we always =
use
>>>> ioremap() to map the device space. And on PPC ioremap also use the sam=
e space as
>>>> vmalloc(). While bootstrap you also can see this associated message li=
ke the
>>>> follows,
>>>> ------
>>>> ......
>>>> =A0* 0xd1000000..0xffbe9000 =A0: vmalloc & ioremap
>>> Yeah. My platform says the follow message.
>>>
>>> =A0 * 0xc9000000..0xdf000000 =A0: vmalloc & ioremap
>>
>> Any reason why you don't access > 0xdf000000?
>
> Higher than 0xdf000000 has to map TLB for using other peripherals.
> it's 400MB over.
>
>>
>>>
>>> The default vmalloc & ioremap space was about 200MB. so I increased
>>> that by decreasing lowmem.
>>> But If possible, I hope to keep default maps. So I don't want to use
>>> vmalloc & ioremap
>>>
>>>>> other architectures don't allocate to the vmalloc.
>>>>> The design of the hardware? or Is there the way to use the flash
>>>> You can open /dev/mem then mmap() with a appropriate offset to access =
the device
>>>> space including flash.
>>> I use the device tree(dts) and define flash partitions. Also I use CFI
>>> driver and CFI_PHYSMAP_OF for device tree.
>>> Is there the reference driver in what uses mmap() kernel tree? I think
>>> I have to write a driver what can support dts and mmap() with a
>>> appropriate offset to access the device.
>>
>> You should not write anything again. And you can access any physical add=
ress
>> directly via /dev/mem from the user space like the following:
>>
>> fd =3D open(/dev/mem,);
>> mmap(fd + offset);
>
> Thanks for letting me know. I want to use in combination with device
> tree. So I'll write a driver based on physmap_of.c(such as mmap_of.c)
I confused and misunderstand that. it has to use as a rootfs. so It
can't use a userland program.
Of cource, it can be force mapping to the userspace. but system will
be unstable. I think.
Mitsutaka
>
> Thanks,
> Mitsutaka
>
>>
>> Tiejun
>>
>>>
>>> Thanks,
>>> Mitsutaka
>>>
>>>> Tiejun
>>>>
>>>>> memory without vmalloc?
>>>>>
>>>>> Thanks,
>>>>> Mitsutaka
>>
>>
>
^ permalink raw reply
* RE: FSL DMA engine transfer to PCI memory
From: David Laight @ 2011-01-26 10:18 UTC (permalink / raw)
Cc: linuxppc-dev
In-Reply-To: <20110125135706.45f351a2@udp111988uds.am.freescale.net>
=20
> What was the ppc you used?
The 8315E PowerQUIICC II
> On 85xx/QorIQ-family chips such as P2020, there is no DMA controller
> inside the PCIe controller itself (or are you talking about bus
> mastering by the PCIe device[1]? "interface" is a bit ambiguous),
> though it was considered part of the PCI controller on 82xx.
>=20
> The DMA engine and PCIe are both on OCeaN, so the traffic=20
> does not need to pass through the e500 Coherency Module.
> My understanding -- for what it's worth, coming from a
> software person :-) -- is that you should
> be able to get large transfer chunks using the DMA engine.
It might be possible - but the ppc's pcie would need to know
the length of the dma (or at least be told that there was more
data to arrive) before even starting the pcie transfer.
I used 128 bytes per pcie transfer (which the altera slave
can handle) but that is longer than you want a burst on
the internal (CSB in my case) bus on the ppc.
It is also longer than a cache line - so the dma engine's
memory reads might induce a cache flush.=20
> I suggest getting things working, and then seeing whether the
> performance is acceptable.
The only reason for using dma (instead of pio) is to get
long pcie transfers - otherwise it isn't really worth the
effort. Transfers are unlikely to take long enough to make
it worth taking an interrupt at the end of the dma.
My device driver implements read() and write() (and poll()
to wait for interrupts). So I do overlap the copy_to/from_user
with the next dma.
> > The generic dma controller can't even generate 64bit
> > cycles into the ppc's PCIe engine.
>=20
> Could you elaborate?
The pcie is (apparantly) a 64bit interface, to a single 32bit
transfer is actually a 64bit one with only 4 byte enables driven.
I couldn't see anything that would allow a CSB master to generate
two 32bit cycles (since it is a 32bit bus) that the pcie hardware
could convert into a single 64bit pcie transfer.
The fpga target is likely to have 32bit targets (it could have
64 bit ones, but if you've instantiated a NiosII cpu it wont!)
so you get a bus width adapter (which carefully does the cycle
with no byte enables driven) as well as the clock crossing bridge.
These both make the slave even slower than it would otherwise be!
IIRC We managed to get 2us for a read and 500ns for a write cycle.
The per byte costs are relatively small in comparison.
David
^ permalink raw reply
* [PATCH 3/4 v5] video, sm501: add OF binding to support SM501
From: Heiko Schocher @ 2011-01-26 7:21 UTC (permalink / raw)
To: linuxppc-dev
Cc: linux-fbdev, devicetree-discuss, Samuel Ortiz, Vincent Sanders,
linux-kernel, Ben Dooks, Randy Dunlap, Paul Mundt, Heiko Schocher
In-Reply-To: <1291451028-22532-1-git-send-email-hs@denx.de>
- add binding to OF, compatible name "smi,sm501"
Signed-off-by: Heiko Schocher <hs@denx.de>
cc: linux-fbdev@vger.kernel.org
cc: devicetree-discuss@ozlabs.org
cc: Ben Dooks <ben@simtec.co.uk>
cc: Vincent Sanders <vince@simtec.co.uk>
cc: Samuel Ortiz <sameo@linux.intel.com>
cc: linux-kernel@vger.kernel.org
cc: Randy Dunlap <rdunlap@xenotime.net>
cc: Paul Mundt <lethal@linux-sh.org>
---
- changes since v1:
add Ben Dooks, Vincent Sanders and Samuel Ortiz to cc, as suggested from
Paul Mundt.
- changes since v2:
add comments from Randy Dunlap:
- move parameter documentation to Documentation/fb/sm501.txt
- changes since v3:
- rebased against v2.6.38-rc2
- split in 3 patches
- of support patch
- get rid of "#if defined(CONFIG_PPC_MPC52xx)" usage
hide this in DTS, as Paul suggested.
- i/o routine patch
- edid support patch
- changes since v4
replace remaining CONFIG_PPC_MPC52xx with CONFIG_OF, as
it is no longer MPC52xx only.
- changes since v5
free edid_data after its usage, as it is no longer needed,
suggested from Paul Mundt. Also fall back to default if
kmemdup(edid_data) fails.
./scripts/checkpatch.pl 0003-video-sm501-add-OF-binding-to-support-SM501.patch
total: 0 errors, 0 warnings, 132 lines checked
0003-video-sm501-add-OF-binding-to-support-SM501.patch has no obvious style problems and is ready for submission.
Documentation/powerpc/dts-bindings/sm501.txt | 34 +++++++++++++++++++++
drivers/mfd/sm501.c | 9 +++++-
drivers/video/sm501fb.c | 42 ++++++++++++++++++++++++--
3 files changed, 81 insertions(+), 4 deletions(-)
create mode 100644 Documentation/powerpc/dts-bindings/sm501.txt
diff --git a/Documentation/powerpc/dts-bindings/sm501.txt b/Documentation/powerpc/dts-bindings/sm501.txt
new file mode 100644
index 0000000..7d319fb
--- /dev/null
+++ b/Documentation/powerpc/dts-bindings/sm501.txt
@@ -0,0 +1,34 @@
+* SM SM501
+
+The SM SM501 is a LCD controller, with proper hardware, it can also
+drive DVI monitors.
+
+Required properties:
+- compatible : should be "smi,sm501".
+- reg : contain two entries:
+ - First entry: System Configuration register
+ - Second entry: IO space (Display Controller register)
+- interrupts : SMI interrupt to the cpu should be described here.
+- interrupt-parent : the phandle for the interrupt controller that
+ services interrupts for this device.
+
+Optional properties:
+- mode : select a video mode:
+ <xres>x<yres>[-<bpp>][@<refresh>]
+- edid : verbatim EDID data block describing attached display.
+ Data from the detailed timing descriptor will be used to
+ program the display controller.
+- little-endian: availiable on big endian systems, to
+ set different foreign endian.
+- big-endian: availiable on little endian systems, to
+ set different foreign endian.
+
+Example for MPC5200:
+ display@1,0 {
+ compatible = "smi,sm501";
+ reg = <1 0x00000000 0x00800000
+ 1 0x03e00000 0x00200000>;
+ interrupts = <1 1 3>;
+ mode = "640x480-32@60";
+ edid = [edid-data];
+ };
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index 558d5f3..df3702c 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -1377,7 +1377,7 @@ static int __devinit sm501_init_dev(struct sm501_devdata *sm)
sm501_register_gpio(sm);
}
- if (pdata->gpio_i2c != NULL && pdata->gpio_i2c_nr > 0) {
+ if (pdata && pdata->gpio_i2c != NULL && pdata->gpio_i2c_nr > 0) {
if (!sm501_gpio_isregistered(sm))
dev_err(sm->dev, "no gpio available for i2c gpio.\n");
else
@@ -1422,6 +1422,7 @@ static int __devinit sm501_plat_probe(struct platform_device *dev)
sm->io_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
sm->mem_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+
if (sm->io_res == NULL || sm->mem_res == NULL) {
dev_err(&dev->dev, "failed to get IO resource\n");
ret = -ENOENT;
@@ -1735,10 +1736,16 @@ static struct pci_driver sm501_pci_driver = {
MODULE_ALIAS("platform:sm501");
+static struct of_device_id __devinitdata of_sm501_match_tbl[] = {
+ { .compatible = "smi,sm501", },
+ { /* end */ }
+};
+
static struct platform_driver sm501_plat_driver = {
.driver = {
.name = "sm501",
.owner = THIS_MODULE,
+ .of_match_table = of_sm501_match_tbl,
},
.probe = sm501_plat_probe,
.remove = sm501_plat_remove,
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index d60b2a2..92b001d 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -1729,6 +1729,15 @@ static int sm501fb_init_fb(struct fb_info *fb,
FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
+#if defined(CONFIG_OF)
+#ifdef __BIG_ENDIAN
+ if (of_get_property(info->dev->parent->of_node, "little-endian", NULL))
+ fb->flags |= FBINFO_FOREIGN_ENDIAN;
+#else
+ if (of_get_property(info->dev->parent->of_node, "big-endian", NULL))
+ fb->flags |= FBINFO_FOREIGN_ENDIAN;
+#endif
+#endif
/* fixed data */
fb->fix.type = FB_TYPE_PACKED_PIXELS;
@@ -1765,14 +1774,17 @@ static int sm501fb_init_fb(struct fb_info *fb,
fb->var.xres_virtual = fb->var.xres;
fb->var.yres_virtual = fb->var.yres;
} else {
- if (info->edid_data)
+ if (info->edid_data) {
ret = fb_find_mode(&fb->var, fb, fb_mode,
fb->monspecs.modedb,
fb->monspecs.modedb_len,
&sm501_default_mode, default_bpp);
- else
+ /* edid_data is no longer needed, free it */
+ kfree(info->edid_data);
+ } else {
ret = fb_find_mode(&fb->var, fb,
NULL, NULL, 0, NULL, 8);
+ }
switch (ret) {
case 1:
@@ -1933,8 +1945,32 @@ static int __devinit sm501fb_probe(struct platform_device *pdev)
}
if (info->pdata == NULL) {
- dev_info(dev, "using default configuration data\n");
+ int found = 0;
+#if defined(CONFIG_OF)
+ struct device_node *np = pdev->dev.parent->of_node;
+ const u8 *prop;
+ const char *cp;
+ int len;
+
info->pdata = &sm501fb_def_pdata;
+ if (np) {
+ /* Get EDID */
+ cp = of_get_property(np, "mode", &len);
+ if (cp)
+ strcpy(fb_mode, cp);
+ prop = of_get_property(np, "edid", &len);
+ if (prop && len == EDID_LENGTH) {
+ info->edid_data = kmemdup(prop, EDID_LENGTH,
+ GFP_KERNEL);
+ if (info->edid_data)
+ found = 1;
+ }
+ }
+#endif
+ if (!found) {
+ dev_info(dev, "using default configuration data\n");
+ info->pdata = &sm501fb_def_pdata;
+ }
}
/* probe for the presence of each panel */
--
1.7.3.4
^ permalink raw reply related
* [PATCH 2/4 v5] video, sm501: add edid and commandline support
From: Heiko Schocher @ 2011-01-26 7:21 UTC (permalink / raw)
To: linuxppc-dev
Cc: linux-fbdev, devicetree-discuss, Samuel Ortiz, Vincent Sanders,
linux-kernel, Ben Dooks, Randy Dunlap, Paul Mundt, Heiko Schocher
In-Reply-To: <1291451028-22532-1-git-send-email-hs@denx.de>
- add commandline options:
sm501fb.mode:
Specify resolution as "<xres>x<yres>[-<bpp>][@<refresh>]"
sm501fb.bpp:
Specify bit-per-pixel if not specified mode
- Add support for encoding display mode information
in the device tree using verbatim EDID block.
If the "edid" entry in the "smi,sm501" node is present,
the driver will build mode database using EDID data
and allow setting the display modes from this database.
Signed-off-by: Heiko Schocher <hs@denx.de>
cc: linux-fbdev@vger.kernel.org
cc: devicetree-discuss@ozlabs.org
cc: Ben Dooks <ben@simtec.co.uk>
cc: Vincent Sanders <vince@simtec.co.uk>
cc: Samuel Ortiz <sameo@linux.intel.com>
cc: linux-kernel@vger.kernel.org
cc: Randy Dunlap <rdunlap@xenotime.net>
cc: Paul Mundt <lethal@linux-sh.org>
---
- changes since v1:
add Ben Dooks, Vincent Sanders and Samuel Ortiz to cc, as suggested from
Paul Mundt.
- changes since v2:
add comments from Randy Dunlap:
- move parameter documentation to Documentation/fb/sm501.txt
- changes since v3:
- rebased against v2.6.38-rc2
- split in 3 patches
- of support patch
- i/o routine patch
- edid support patch
- changes since v4:
- add "info->pdata = &sm501fb_def_pdata;" in sm501fb_probe()
as Paul Mundt suggested (and I wrongly deleted)
- move kfree(info->edid_data); to patch 3/4
as edid_data is only allocated in the CONFIG_OF case
./scripts/checkpatch.pl 0002-video-sm501-add-edid-and-commandline-support.patch
total: 0 errors, 0 warnings, 109 lines checked
0002-video-sm501-add-edid-and-commandline-support.patch has no obvious style problems and is ready for submission.
Documentation/fb/sm501.txt | 10 +++++++
drivers/video/sm501fb.c | 65 ++++++++++++++++++++++++++++++++++++++++---
2 files changed, 70 insertions(+), 5 deletions(-)
create mode 100644 Documentation/fb/sm501.txt
diff --git a/Documentation/fb/sm501.txt b/Documentation/fb/sm501.txt
new file mode 100644
index 0000000..8d17aeb
--- /dev/null
+++ b/Documentation/fb/sm501.txt
@@ -0,0 +1,10 @@
+Configuration:
+
+You can pass the following kernel command line options to sm501 videoframebuffer:
+
+ sm501fb.bpp= SM501 Display driver:
+ Specifiy bits-per-pixel if not specified by 'mode'
+
+ sm501fb.mode= SM501 Display driver:
+ Specify resolution as
+ "<xres>x<yres>[-<bpp>][@<refresh>]"
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index c5b4b95..d60b2a2 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -41,6 +41,26 @@
#include <linux/sm501.h>
#include <linux/sm501-regs.h>
+#include "edid.h"
+
+static char *fb_mode = "640x480-16@60";
+static unsigned long default_bpp = 16;
+
+static struct fb_videomode __devinitdata sm501_default_mode = {
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 20833,
+ .left_margin = 142,
+ .right_margin = 13,
+ .upper_margin = 21,
+ .lower_margin = 1,
+ .hsync_len = 69,
+ .vsync_len = 3,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED
+};
+
#define NR_PALETTE 256
enum sm501_controller {
@@ -77,6 +97,7 @@ struct sm501fb_info {
void __iomem *regs2d; /* 2d remapped registers */
void __iomem *fbmem; /* remapped framebuffer */
size_t fbmem_len; /* length of remapped region */
+ u8 *edid_data;
};
/* per-framebuffer private data */
@@ -1725,9 +1746,16 @@ static int sm501fb_init_fb(struct fb_info *fb,
fb->var.vmode = FB_VMODE_NONINTERLACED;
fb->var.bits_per_pixel = 16;
+ if (info->edid_data) {
+ /* Now build modedb from EDID */
+ fb_edid_to_monspecs(info->edid_data, &fb->monspecs);
+ fb_videomode_to_modelist(fb->monspecs.modedb,
+ fb->monspecs.modedb_len,
+ &fb->modelist);
+ }
+
if (enable && (pd->flags & SM501FB_FLAG_USE_INIT_MODE) && 0) {
/* TODO read the mode from the current display */
-
} else {
if (pd->def_mode) {
dev_info(info->dev, "using supplied mode\n");
@@ -1737,12 +1765,34 @@ static int sm501fb_init_fb(struct fb_info *fb,
fb->var.xres_virtual = fb->var.xres;
fb->var.yres_virtual = fb->var.yres;
} else {
- ret = fb_find_mode(&fb->var, fb,
+ if (info->edid_data)
+ ret = fb_find_mode(&fb->var, fb, fb_mode,
+ fb->monspecs.modedb,
+ fb->monspecs.modedb_len,
+ &sm501_default_mode, default_bpp);
+ else
+ ret = fb_find_mode(&fb->var, fb,
NULL, NULL, 0, NULL, 8);
- if (ret == 0 || ret == 4) {
- dev_err(info->dev,
- "failed to get initial mode\n");
+ switch (ret) {
+ case 1:
+ dev_info(info->dev, "using mode specified in "
+ "@mode\n");
+ break;
+ case 2:
+ dev_info(info->dev, "using mode specified in "
+ "@mode with ignored refresh rate\n");
+ break;
+ case 3:
+ dev_info(info->dev, "using mode default "
+ "mode\n");
+ break;
+ case 4:
+ dev_info(info->dev, "using mode from list\n");
+ break;
+ default:
+ dev_info(info->dev, "ret = %d\n", ret);
+ dev_info(info->dev, "failed to find mode\n");
return -EINVAL;
}
}
@@ -2157,6 +2207,11 @@ static void __exit sm501fb_cleanup(void)
module_init(sm501fb_init);
module_exit(sm501fb_cleanup);
+module_param_named(mode, fb_mode, charp, 0);
+MODULE_PARM_DESC(mode,
+ "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
+module_param_named(bpp, default_bpp, ulong, 0);
+MODULE_PARM_DESC(bpp, "Specify bit-per-pixel if not specified mode");
MODULE_AUTHOR("Ben Dooks, Vincent Sanders");
MODULE_DESCRIPTION("SM501 Framebuffer driver");
MODULE_LICENSE("GPL v2");
--
1.7.3.4
^ permalink raw reply related
* Re: 750gx cpufreq induced kernel panic in 2.6.36
From: Benjamin Herrenschmidt @ 2011-01-26 4:32 UTC (permalink / raw)
To: kevin diggs; +Cc: linuxppc-dev
In-Reply-To: <AANLkTikJ8V-gQv93HBDH3=4o51vY5xyxQojqEV7DqNj=@mail.gmail.com>
On Tue, 2011-01-25 at 17:54 -0600, kevin diggs wrote:
> Hi,
>
> The cpufreq driver I wrote for the 750gx causes a kernel panic in 2.6.36.
>
> This is from a screen shot:
>
> [c6035f30] [c001014c] timer_interrupt+0x13c/0x19c
> [c6035f40] [c0013294] ret_from_except+0x0/0x14
> --- Exception: 901 at 0x1000c694
> LR = 0x1000f3e4
> Instruction dump:
> 4bffff48 38610008 4be7b2b1 4bffff9c 9421fff0 7c0802a6 bfc10xxx
> 90010014 7c0000a6 68008000 54008ffe <0f000000> 3d20c030 2f84xxxx
> Kernel panic - not syncing: Fatal exception in interrupt
> Call Trace:
> [c6035bf0] [c00084e4] show_stack+0x3c/0x160 (unreliable)
> [c6035c20] [c002cf44] panic+0xa4/0x1c8
> [c6035c70] [c001085c] die+0x194/0x1a0
> [c6035c90] [c0010aa8] _exception+0xfc/0x108
> [c6035d80] [c0013248] ret_from_except_full+0x0/0x4c
> --- Exception: 700 at cpufreq_notify_transition+0x20/0x128
> LR = cf750gx_pll_switch_cb+0x20/0xd0 [cf750gx]
> [c6035e40] [c02e2280] 0xc02e2280 (unreliable)
> [c6035e50] [ddc4b3dc] cf750gx_pll_switch_cb+0x20/0xd0 [cf750gx]
> [c6035e60] [c004d7ac] notifier_call_chain+0x60/0xb0
> [c6035e80] [ddc361c4] pllif_i_switch_PLLs+0xa0/0x140 [pll_if]
> [c6035e90] [ddc365fc] pllif_i_timer_f+0x4c/0x6c [pll_if]
> [c6035ea0] [c004bb24] __run_hrtimer+0x44/0xb8
> [c6035eb0] [c004c1f8] hrtimer_interrupt+0x10c/0x388
> [c6035f30] [c001014c] timer_interrupt+0x13c/0x19c
> [c6035f40] [c0013294] ret_from_except+0x0/0x14
> --- Exception: 901 at 0x1000c694
> LR = 0x1000f3e4
> Rebooting in 180 seconds.._
>
> What are exception 700 & 901?
700 is a program check (illegal instruction or BUG_ON() statement)
900 is decrementer (aka timer) interrupt.
> The 0x1000c694 address looks fishy?
That's userspace.
So you took a timer interrupt, which got into hrtimer, and something you
did caused cpufreq_notify_transition to crash, probably with a BUG_ON
(which you can probably see above what you pasted, unless you don't have
access to that part of the backtrace).
Cheers,
Ben.
> Thanks!
>
> kevin
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
^ permalink raw reply
* 750gx cpufreq induced kernel panic in 2.6.36
From: kevin diggs @ 2011-01-25 23:54 UTC (permalink / raw)
To: linuxppc-dev
Hi,
The cpufreq driver I wrote for the 750gx causes a kernel panic in 2.6.36.
This is from a screen shot:
[c6035f30] [c001014c] timer_interrupt+0x13c/0x19c
[c6035f40] [c0013294] ret_from_except+0x0/0x14
--- Exception: 901 at 0x1000c694
LR = 0x1000f3e4
Instruction dump:
4bffff48 38610008 4be7b2b1 4bffff9c 9421fff0 7c0802a6 bfc10xxx
90010014 7c0000a6 68008000 54008ffe <0f000000> 3d20c030 2f84xxxx
Kernel panic - not syncing: Fatal exception in interrupt
Call Trace:
[c6035bf0] [c00084e4] show_stack+0x3c/0x160 (unreliable)
[c6035c20] [c002cf44] panic+0xa4/0x1c8
[c6035c70] [c001085c] die+0x194/0x1a0
[c6035c90] [c0010aa8] _exception+0xfc/0x108
[c6035d80] [c0013248] ret_from_except_full+0x0/0x4c
--- Exception: 700 at cpufreq_notify_transition+0x20/0x128
LR = cf750gx_pll_switch_cb+0x20/0xd0 [cf750gx]
[c6035e40] [c02e2280] 0xc02e2280 (unreliable)
[c6035e50] [ddc4b3dc] cf750gx_pll_switch_cb+0x20/0xd0 [cf750gx]
[c6035e60] [c004d7ac] notifier_call_chain+0x60/0xb0
[c6035e80] [ddc361c4] pllif_i_switch_PLLs+0xa0/0x140 [pll_if]
[c6035e90] [ddc365fc] pllif_i_timer_f+0x4c/0x6c [pll_if]
[c6035ea0] [c004bb24] __run_hrtimer+0x44/0xb8
[c6035eb0] [c004c1f8] hrtimer_interrupt+0x10c/0x388
[c6035f30] [c001014c] timer_interrupt+0x13c/0x19c
[c6035f40] [c0013294] ret_from_except+0x0/0x14
--- Exception: 901 at 0x1000c694
LR = 0x1000f3e4
Rebooting in 180 seconds.._
What are exception 700 & 901?
The 0x1000c694 address looks fishy?
Thanks!
kevin
^ permalink raw reply
* RE: [PATCH V8 00/10] Add-Synopsys-DesignWare-HS-USB-OTG-driver
From: Tirumala Marri @ 2011-01-25 22:06 UTC (permalink / raw)
To: Greg KH; +Cc: linux-usb, linuxppc-dev
In-Reply-To: <20110123030150.GA28358@kroah.com>
-----Original Message-----
From: Greg KH [mailto:greg@kroah.com]
Sent: Saturday, January 22, 2011 7:02 PM
To: tmarri@apm.com
Cc: linux-usb@vger.kernel.org; linuxppc-dev@lists.ozlabs.org
Subject: Re: [PATCH V8 00/10] Add-Synopsys-DesignWare-HS-USB-OTG-driver
On Wed, Jan 19, 2011 at 02:57:16PM -0800, tmarri@apm.com wrote:
> From: Tirumala Marri <tmarri@apm.com>
>
> v8:
> 1. Add set_wedge to usb_ep_ops.
>
> v7:
> 1. Fix sparse tool warnings.
> 2. Fix checkpatch errors and warnings.
> 3. Rename USB_OTG config variable to USB_DWC_CONFIG
>
> Tirumala Marri (10):
> USB/ppc4xx: Add Synopsys DWC OTG Register definitions
> USB/ppc4xx: Add Synopsys DWC OTG driver framework
> USB/ppc4xx: Add Synopsys DWC OTG Core Interface Layer
> USB/ppc4xx: Add Synopsys DWC OTG HCD function
> USB/ppc4xx: Add Synopsys DWC OTG HCD interrupt function
> USB/ppc4xx: Add Synopsys DWC OTG HCD queue function
> USB/ppc4xx: Add Synopsys DWC OTG PCD function
> USB ppc4xx: Add Synopsys DWC OTG PCD interrupt function
> USB/ppc4xx:Synopsys DWC OTG driver enable gadget support
> USB ppc4xx: Add Synopsys DWC OTG driver kernel configuration and
> Makefile
>
> drivers/Makefile | 2 +
> drivers/usb/Kconfig | 3 +-
> drivers/usb/dwc_otg/Kconfig | 96 ++
Why are you creating a new subdirectory here? Shouldn't it be in
drivers/usb/otg/dwc/ instead?
> drivers/usb/dwc_otg/Makefile | 19 +
> drivers/usb/dwc_otg/dwc_otg_apmppc.c | 414 ++++++
> drivers/usb/dwc_otg/dwc_otg_cil.c | 972 ++++++++++++
> drivers/usb/dwc_otg/dwc_otg_cil.h | 1220 +++++++++++++++
> drivers/usb/dwc_otg/dwc_otg_cil_intr.c | 616 ++++++++
> drivers/usb/dwc_otg/dwc_otg_driver.h | 76 +
> drivers/usb/dwc_otg/dwc_otg_hcd.c | 2466
+++++++++++++++++++++++++++++++
> drivers/usb/dwc_otg/dwc_otg_hcd.h | 416 ++++++
> drivers/usb/dwc_otg/dwc_otg_hcd_intr.c | 1477 ++++++++++++++++++
> drivers/usb/dwc_otg/dwc_otg_hcd_queue.c | 696 +++++++++
> drivers/usb/dwc_otg/dwc_otg_param.c | 180 +++
> drivers/usb/dwc_otg/dwc_otg_pcd.c | 1766 ++++++++++++++++++++++
> drivers/usb/dwc_otg/dwc_otg_pcd.h | 139 ++
> drivers/usb/dwc_otg/dwc_otg_pcd_intr.c | 2311
+++++++++++++++++++++++++++++
> drivers/usb/dwc_otg/dwc_otg_regs.h | 1325 +++++++++++++++++
As you are in your own subdir, no need to put "dwc_otg_" at the start of
every file name, right?
Care to make these changes and resend?
[Marri] Sure I will make changes and resend.
-Marri
^ permalink raw reply
* Re: FSL DMA engine transfer to PCI memory
From: Scott Wood @ 2011-01-25 19:57 UTC (permalink / raw)
To: David Laight; +Cc: linuxppc-dev, Felix Radensky, Ira W. Snyder
In-Reply-To: <AE90C24D6B3A694183C094C60CF0A2F6D8AC29@saturn3.aculab.com>
On Tue, 25 Jan 2011 16:34:49 +0000
David Laight <David.Laight@ACULAB.COM> wrote:
>
> > > >>>> custom board based on P2020 running linux-2.6.35. The PCI
> > > >>>> device is Altera FPGA, connected directly to SoC PCI-E
> controller.
>
>
> > This sounds like your FPGA doesn't handle burst mode accesses
> > correctly.
> > A logic analyzer will help you prove it.
>
> He is doing PCIe, not PCI.
> A PCIe transfers is an HDLC packet pair, one containing the
> request, the other the response.
> In order to get any significant throughput the hdlc packet(s)
> have to contain all the data (eg 128 bytes).
> On the ppc we used that means you have to use the dma
> controller inside the PCIe interface block.
What was the ppc you used?
On 85xx/QorIQ-family chips such as P2020, there is no DMA controller
inside the PCIe controller itself (or are you talking about bus
mastering by the PCIe device[1]? "interface" is a bit ambiguous),
though it was considered part of the PCI controller on 82xx.
The DMA engine and PCIe are both on OCeaN, so the traffic does not need
to pass through the e500 Coherency Module. My understanding -- for
what it's worth, coming from a software person :-) -- is that you should
be able to get large transfer chunks using the DMA engine.
I suggest getting things working, and then seeing whether the
performance is acceptable.
> The generic dma controller can't even generate 64bit
> cycles into the ppc's PCIe engine.
Could you elaborate?
-Scott
[1] To the original poster, is there any reason you're not doing bus
mastering from the PCIe device, assuming you control the content of
the FPGA?
^ permalink raw reply
* RE: FSL DMA engine transfer to PCI memory
From: David Laight @ 2011-01-25 16:34 UTC (permalink / raw)
To: Ira W. Snyder, Felix Radensky; +Cc: Scott Wood, linuxppc-dev
In-Reply-To: <20110125162946.GA13438@ovro.caltech.edu>
=20
> > >>>> custom board based on P2020 running linux-2.6.35. The PCI
> > >>>> device is Altera FPGA, connected directly to SoC PCI-E
controller.
=20
> This sounds like your FPGA doesn't handle burst mode accesses=20
> correctly.
> A logic analyzer will help you prove it.
He is doing PCIe, not PCI.
A PCIe transfers is an HDLC packet pair, one containing the
request, the other the response.
In order to get any significant throughput the hdlc packet(s)
have to contain all the data (eg 128 bytes).
On the ppc we used that means you have to use the dma
controller inside the PCIe interface block.
The generic dma controller can't even generate 64bit
cycles into the ppc's PCIe engine.
David
^ permalink raw reply
* Re: FSL DMA engine transfer to PCI memory
From: Ira W. Snyder @ 2011-01-25 16:29 UTC (permalink / raw)
To: Felix Radensky; +Cc: Scott Wood, linuxppc-dev@ozlabs.org
In-Reply-To: <4D3EDEE2.6000809@embedded-sol.com>
On Tue, Jan 25, 2011 at 04:32:02PM +0200, Felix Radensky wrote:
> Hi Ira,
>
> On 01/25/2011 02:18 AM, Ira W. Snyder wrote:
> > On Tue, Jan 25, 2011 at 01:39:39AM +0200, Felix Radensky wrote:
> >> Hi Ira, Scott
> >>
> >> On 01/25/2011 12:26 AM, Ira W. Snyder wrote:
> >>> On Mon, Jan 24, 2011 at 11:47:22PM +0200, Felix Radensky wrote:
> >>>> Hi,
> >>>>
> >>>> I'm trying to use FSL DMA engine to perform DMA transfer from
> >>>> memory buffer obtained by kmalloc() to PCI memory. This is on
> >>>> custom board based on P2020 running linux-2.6.35. The PCI
> >>>> device is Altera FPGA, connected directly to SoC PCI-E controller.
> >>>>
> >>>> 01:00.0 Unassigned class [ff00]: Altera Corporation Unknown device
> >>>> 0004 (rev 01)
> >>>> Subsystem: Altera Corporation Unknown device 0004
> >>>> Control: I/O- Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop-
> >>>> ParErr- Stepping- SERR- FastB2B-
> >>>> Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast
> >>>> >TAbort-<TAbort-<MAbort->SERR-<PERR-
> >>>> Interrupt: pin A routed to IRQ 16
> >>>> Region 0: Memory at c0000000 (32-bit, non-prefetchable)
> >>>> [size=128K]
> >>>> Capabilities: [50] Message Signalled Interrupts: Mask- 64bit+
> >>>> Queue=0/0 Enable-
> >>>> Address: 0000000000000000 Data: 0000
> >>>> Capabilities: [78] Power Management version 3
> >>>> Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA
> >>>> PME(D0-,D1-,D2-,D3hot-,D3cold-)
> >>>> Status: D0 PME-Enable- DSel=0 DScale=0 PME-
> >>>> Capabilities: [80] Express Endpoint IRQ 0
> >>>> Device: Supported: MaxPayload 256 bytes, PhantFunc 0,
> >>>> ExtTag-
> >>>> Device: Latency L0s<64ns, L1<1us
> >>>> Device: AtnBtn- AtnInd- PwrInd-
> >>>> Device: Errors: Correctable- Non-Fatal- Fatal-
> >>>> Unsupported-
> >>>> Device: RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
> >>>> Device: MaxPayload 128 bytes, MaxReadReq 512 bytes
> >>>> Link: Supported Speed 2.5Gb/s, Width x1, ASPM L0s, Port 1
> >>>> Link: Latency L0s unlimited, L1 unlimited
> >>>> Link: ASPM Disabled RCB 64 bytes CommClk- ExtSynch-
> >>>> Link: Speed 2.5Gb/s, Width x1
> >>>> Capabilities: [100] Virtual Channel
> >>>>
> >>>>
> >>>> I can successfully writel() to PCI memory via address obtained from
> >>>> pci_ioremap_bar().
> >>>> Here's my DMA transfer routine
> >>>>
> >>>> static int dma_transfer(struct dma_chan *chan, void *dst, void *src,
> >>>> size_t len)
> >>>> {
> >>>> int rc = 0;
> >>>> dma_addr_t dma_src;
> >>>> dma_addr_t dma_dst;
> >>>> dma_cookie_t cookie;
> >>>> struct completion cmp;
> >>>> enum dma_status status;
> >>>> enum dma_ctrl_flags flags = 0;
> >>>> struct dma_device *dev = chan->device;
> >>>> struct dma_async_tx_descriptor *tx = NULL;
> >>>> unsigned long tmo = msecs_to_jiffies(FPGA_DMA_TIMEOUT_MS);
> >>>>
> >>>> dma_src = dma_map_single(dev->dev, src, len, DMA_TO_DEVICE);
> >>>> if (dma_mapping_error(dev->dev, dma_src)) {
> >>>> printk(KERN_ERR "Failed to map src for DMA\n");
> >>>> return -EIO;
> >>>> }
> >>>>
> >>>> dma_dst = (dma_addr_t)dst;
> >>>>
> >>>> flags = DMA_CTRL_ACK |
> >>>> DMA_COMPL_SRC_UNMAP_SINGLE |
> >>>> DMA_COMPL_SKIP_DEST_UNMAP |
> >>>> DMA_PREP_INTERRUPT;
> >>>>
> >>>> tx = dev->device_prep_dma_memcpy(chan, dma_dst, dma_src, len, flags);
> >>>> if (!tx) {
> >>>> printk(KERN_ERR "%s: Failed to prepare DMA transfer\n",
> >>>> __FUNCTION__);
> >>>> dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE);
> >>>> return -ENOMEM;
> >>>> }
> >>>>
> >>>> init_completion(&cmp);
> >>>> tx->callback = dma_callback;
> >>>> tx->callback_param =&cmp;
> >>>> cookie = tx->tx_submit(tx);
> >>>>
> >>>> if (dma_submit_error(cookie)) {
> >>>> printk(KERN_ERR "%s: Failed to start DMA transfer\n",
> >>>> __FUNCTION__);
> >>>> return -ENOMEM;
> >>>> }
> >>>>
> >>>> dma_async_issue_pending(chan);
> >>>>
> >>>> tmo = wait_for_completion_timeout(&cmp, tmo);
> >>>> status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
> >>>>
> >>>> if (tmo == 0) {
> >>>> printk(KERN_ERR "%s: Transfer timed out\n", __FUNCTION__);
> >>>> rc = -ETIMEDOUT;
> >>>> } else if (status != DMA_SUCCESS) {
> >>>> printk(KERN_ERR "%s: Transfer failed: status is %s\n",
> >>>> __FUNCTION__,
> >>>> status == DMA_ERROR ? "error" : "in progress");
> >>>>
> >>>> dev->device_control(chan, DMA_TERMINATE_ALL, 0);
> >>>> rc = -EIO;
> >>>> }
> >>>>
> >>>> return rc;
> >>>> }
> >>>>
> >>>> The destination address is PCI memory address returned by
> >>>> pci_ioremap_bar().
> >>>> The transfer silently fails, destination buffer doesn't change
> >>>> contents, but no
> >>>> error condition is reported.
> >>>>
> >>>> What am I doing wrong ?
> >>>>
> >>>> Thanks a lot in advance.
> >>>>
> >>> Your destination address is wrong. The device_prep_dma_memcpy() routine
> >>> works in physical addresses only (dma_addr_t type). Your source address
> >>> looks fine: you're using the result of dma_map_single(), which returns a
> >>> physical address.
> >>>
> >>> Your destination address should be something that comes from struct
> >>> pci_dev.resource[x].start + offset if necessary. In your lspci output
> >>> above, that will be 0xc0000000.
> >>>
> >>> Another possible problem: AFAIK you must use the _ONSTACK() variants
> >>> from include/linux/completion.h for struct completion which are on the
> >>> stack.
> >>>
> >>> Hope it helps,
> >>> Ira
> >> Thanks for your help. I'm now passing the result of
> >> pci_resource_start(pdev, 0)
> >> as destination address, and destination buffer changes after the
> >> transfer. But
> >> the contents of source and destination buffers are different. What
> >> else could
> >> be wrong ?
> >>
> > After you changed the dst address to pci_resource_start(pdev, 0), I
> > don't see anything wrong with the code.
> >
> > Try using memcpy_toio() to copy some bytes to the FPGA. Also try writing
> > a single byte at a time (writeb()?) in a loop. This should help
> > establish that your device is working.
> >
> > If you put some pattern in your src buffer (such as 0x0, 0x1, 0x2, ...
> > 0xff, repeat) does the destination show some pattern after the DMA
> > completes? (Such as, every 4th byte is correct.)
> >
> > Ira
>
> memcpy_toio() works fine, the data is written correctly. After
> DMA, the correct data appears at offsets 0xC, 0x1C, 0x2C, etc.
> of the destination buffer. I have 12 bytes of junk, 4 bytes of
> correct data, then again 12 bytes of junk and so on.
>
This sounds like your FPGA doesn't handle burst mode accesses correctly.
A logic analyzer will help you prove it.
Another quick test to try is using an unaligned transfer and see what
happens. The 83xx DMA controller handles unaligned transfers by doing
several small, non-burst transfers until the src and dst are aligned,
and then does cacheline size burst transfers until complete. I hunch the
85xx/86xx controller behaves the same way.
Something like this:
dma_src = dma_map_single(...);
dma_dst = pci_resource_start(pdev, 0) + 1;
Notice that the dst address is offset by one byte, so you'll need to
take that into account when comparing data after the transfer.
Ira
^ permalink raw reply
* FW: FSL DMA engine transfer to PCI memory
From: David Laight @ 2011-01-25 15:02 UTC (permalink / raw)
To: linuxppc-dev
> memcpy_toio() works fine, the data is written correctly. After
> DMA, the correct data appears at offsets 0xC, 0x1C, 0x2C, etc.
> of the destination buffer. I have 12 bytes of junk, 4 bytes of
> correct data, then again 12 bytes of junk and so on.
Does your Avalon MM slave decode the 4 byte enables?
The slave always sees 2 Avalon MM writes, one of which
will have no byte enables asserted.
(Actually it is a 64bit Avalon transfer - and a bus width adapter
gets inserted for you.)
Internal M9K memory blocks get this right...
David
^ permalink raw reply
* Re: FSL DMA engine transfer to PCI memory
From: Felix Radensky @ 2011-01-25 14:32 UTC (permalink / raw)
To: Ira W. Snyder; +Cc: Scott Wood, linuxppc-dev@ozlabs.org
In-Reply-To: <20110125001837.GD26404@ovro.caltech.edu>
Hi Ira,
On 01/25/2011 02:18 AM, Ira W. Snyder wrote:
> On Tue, Jan 25, 2011 at 01:39:39AM +0200, Felix Radensky wrote:
>> Hi Ira, Scott
>>
>> On 01/25/2011 12:26 AM, Ira W. Snyder wrote:
>>> On Mon, Jan 24, 2011 at 11:47:22PM +0200, Felix Radensky wrote:
>>>> Hi,
>>>>
>>>> I'm trying to use FSL DMA engine to perform DMA transfer from
>>>> memory buffer obtained by kmalloc() to PCI memory. This is on
>>>> custom board based on P2020 running linux-2.6.35. The PCI
>>>> device is Altera FPGA, connected directly to SoC PCI-E controller.
>>>>
>>>> 01:00.0 Unassigned class [ff00]: Altera Corporation Unknown device
>>>> 0004 (rev 01)
>>>> Subsystem: Altera Corporation Unknown device 0004
>>>> Control: I/O- Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop-
>>>> ParErr- Stepping- SERR- FastB2B-
>>>> Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast
>>>> >TAbort-<TAbort-<MAbort->SERR-<PERR-
>>>> Interrupt: pin A routed to IRQ 16
>>>> Region 0: Memory at c0000000 (32-bit, non-prefetchable)
>>>> [size=128K]
>>>> Capabilities: [50] Message Signalled Interrupts: Mask- 64bit+
>>>> Queue=0/0 Enable-
>>>> Address: 0000000000000000 Data: 0000
>>>> Capabilities: [78] Power Management version 3
>>>> Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA
>>>> PME(D0-,D1-,D2-,D3hot-,D3cold-)
>>>> Status: D0 PME-Enable- DSel=0 DScale=0 PME-
>>>> Capabilities: [80] Express Endpoint IRQ 0
>>>> Device: Supported: MaxPayload 256 bytes, PhantFunc 0,
>>>> ExtTag-
>>>> Device: Latency L0s<64ns, L1<1us
>>>> Device: AtnBtn- AtnInd- PwrInd-
>>>> Device: Errors: Correctable- Non-Fatal- Fatal-
>>>> Unsupported-
>>>> Device: RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
>>>> Device: MaxPayload 128 bytes, MaxReadReq 512 bytes
>>>> Link: Supported Speed 2.5Gb/s, Width x1, ASPM L0s, Port 1
>>>> Link: Latency L0s unlimited, L1 unlimited
>>>> Link: ASPM Disabled RCB 64 bytes CommClk- ExtSynch-
>>>> Link: Speed 2.5Gb/s, Width x1
>>>> Capabilities: [100] Virtual Channel
>>>>
>>>>
>>>> I can successfully writel() to PCI memory via address obtained from
>>>> pci_ioremap_bar().
>>>> Here's my DMA transfer routine
>>>>
>>>> static int dma_transfer(struct dma_chan *chan, void *dst, void *src,
>>>> size_t len)
>>>> {
>>>> int rc = 0;
>>>> dma_addr_t dma_src;
>>>> dma_addr_t dma_dst;
>>>> dma_cookie_t cookie;
>>>> struct completion cmp;
>>>> enum dma_status status;
>>>> enum dma_ctrl_flags flags = 0;
>>>> struct dma_device *dev = chan->device;
>>>> struct dma_async_tx_descriptor *tx = NULL;
>>>> unsigned long tmo = msecs_to_jiffies(FPGA_DMA_TIMEOUT_MS);
>>>>
>>>> dma_src = dma_map_single(dev->dev, src, len, DMA_TO_DEVICE);
>>>> if (dma_mapping_error(dev->dev, dma_src)) {
>>>> printk(KERN_ERR "Failed to map src for DMA\n");
>>>> return -EIO;
>>>> }
>>>>
>>>> dma_dst = (dma_addr_t)dst;
>>>>
>>>> flags = DMA_CTRL_ACK |
>>>> DMA_COMPL_SRC_UNMAP_SINGLE |
>>>> DMA_COMPL_SKIP_DEST_UNMAP |
>>>> DMA_PREP_INTERRUPT;
>>>>
>>>> tx = dev->device_prep_dma_memcpy(chan, dma_dst, dma_src, len, flags);
>>>> if (!tx) {
>>>> printk(KERN_ERR "%s: Failed to prepare DMA transfer\n",
>>>> __FUNCTION__);
>>>> dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE);
>>>> return -ENOMEM;
>>>> }
>>>>
>>>> init_completion(&cmp);
>>>> tx->callback = dma_callback;
>>>> tx->callback_param =&cmp;
>>>> cookie = tx->tx_submit(tx);
>>>>
>>>> if (dma_submit_error(cookie)) {
>>>> printk(KERN_ERR "%s: Failed to start DMA transfer\n",
>>>> __FUNCTION__);
>>>> return -ENOMEM;
>>>> }
>>>>
>>>> dma_async_issue_pending(chan);
>>>>
>>>> tmo = wait_for_completion_timeout(&cmp, tmo);
>>>> status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
>>>>
>>>> if (tmo == 0) {
>>>> printk(KERN_ERR "%s: Transfer timed out\n", __FUNCTION__);
>>>> rc = -ETIMEDOUT;
>>>> } else if (status != DMA_SUCCESS) {
>>>> printk(KERN_ERR "%s: Transfer failed: status is %s\n",
>>>> __FUNCTION__,
>>>> status == DMA_ERROR ? "error" : "in progress");
>>>>
>>>> dev->device_control(chan, DMA_TERMINATE_ALL, 0);
>>>> rc = -EIO;
>>>> }
>>>>
>>>> return rc;
>>>> }
>>>>
>>>> The destination address is PCI memory address returned by
>>>> pci_ioremap_bar().
>>>> The transfer silently fails, destination buffer doesn't change
>>>> contents, but no
>>>> error condition is reported.
>>>>
>>>> What am I doing wrong ?
>>>>
>>>> Thanks a lot in advance.
>>>>
>>> Your destination address is wrong. The device_prep_dma_memcpy() routine
>>> works in physical addresses only (dma_addr_t type). Your source address
>>> looks fine: you're using the result of dma_map_single(), which returns a
>>> physical address.
>>>
>>> Your destination address should be something that comes from struct
>>> pci_dev.resource[x].start + offset if necessary. In your lspci output
>>> above, that will be 0xc0000000.
>>>
>>> Another possible problem: AFAIK you must use the _ONSTACK() variants
>>> from include/linux/completion.h for struct completion which are on the
>>> stack.
>>>
>>> Hope it helps,
>>> Ira
>> Thanks for your help. I'm now passing the result of
>> pci_resource_start(pdev, 0)
>> as destination address, and destination buffer changes after the
>> transfer. But
>> the contents of source and destination buffers are different. What
>> else could
>> be wrong ?
>>
> After you changed the dst address to pci_resource_start(pdev, 0), I
> don't see anything wrong with the code.
>
> Try using memcpy_toio() to copy some bytes to the FPGA. Also try writing
> a single byte at a time (writeb()?) in a loop. This should help
> establish that your device is working.
>
> If you put some pattern in your src buffer (such as 0x0, 0x1, 0x2, ...
> 0xff, repeat) does the destination show some pattern after the DMA
> completes? (Such as, every 4th byte is correct.)
>
> Ira
memcpy_toio() works fine, the data is written correctly. After
DMA, the correct data appears at offsets 0xC, 0x1C, 0x2C, etc.
of the destination buffer. I have 12 bytes of junk, 4 bytes of
correct data, then again 12 bytes of junk and so on.
Felix.
^ permalink raw reply
* RE: FSL DMA engine transfer to PCI memory
From: David Laight @ 2011-01-25 8:56 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <4D3DF36A.5050609@embedded-sol.com>
=20
> I'm trying to use FSL DMA engine to perform DMA transfer from
> memory buffer obtained by kmalloc() to PCI memory. This is on
> custom board based on P2020 running linux-2.6.35. The PCI
> device is Altera FPGA, connected directly to SoC PCI-E controller.
You'll need to use the dma engine that is part of the PCIe
interface in order to get large PCIe transfers.
I think everything else will still generate single 32bit PCIe
transfers - which are (if your measurements match mine)
exceptionally lethargic - the ISA bus is faster!
That does work provided you remember to give the dma controller
physical addresses and byteswap absolutely everything.
(Oh, and I didn't get single word transfers to work - they locked
the dma controller - not a problem since they are faster by PIO.)
Note that the PPC Linux (Linux in general??) doesn't have a
'virtual to physical' function that works for all addresses,
you'll need to remember the physical address of the PCIe slave
and use malloc'ed memory for the descriptors (on which
virt_to_phys() actually works).
I don't think there is a standard device driver for the PCIe dma,
I couldn't even find any header files that were vaugely relevent
except in the uboot sources.
I certainly wrote some code that just assumes it is on the right
hardware!
These are the relevant bits of code ....
Global initialisation:
/* Enable the read/write dma controllers */
csb_ctrl =3D in_le32(&pex->pex_csb_ctrl);
csb_ctrl |=3D PEX_CSB_CTRL_WDMAE | PEX_CSB_CTRL_RDMAE;
out_le32(&pex->pex_csb_ctrl, csb_ctrl);
/* We don't rely on the dma polling the descriptor, I have NFI
* whether the default of 0 means 'never poll' or 'poll very
quickly'.
* Set a large slow value for sanity. */
out_le32(&pex->pex_dms_dstmr, ~0u);
Transfer setup:
/* We only support aligned writes - caller must verify */
dma_ctrl =3D PDMAD_CTRL_VALID;
dma_ctrl |=3D PDMAD_CTRL_SNOOP_CSB;
dma_ctrl |=3D PDMAD_CTRL_1ST_BYTES | PDMAD_CTRL_LAST_BYTES;
dma_ctrl |=3D PDMAD_CTRL_NEXT_VALID;
dma_ctrl |=3D len << (PDMAD_CTRL_LEN_SHIFT - 2);
/* Fill in DMA descriptor */
st_le32(&desc->pdmad_ctrl, dma_ctrl);
/* We MUST clear the status - otherwise the xfer will be skipped */
st_le32(&desc->pdmad_stat, 0);
st_le32(&desc->pdmad_src_address, src_phys);
st_le32(&desc->pdmad_dst_address, dst_phys);
st_le32(&desc->pdmad_next_desc, 0);
/* Clear old status */
st_le32(&pex_dma->pex_dma_stat, in_le32(&pex_dma->pex_dma_stat));
/* Give descriptor address to dma engine */
st_le32(&pex_dma->pex_dma_addr, virt_to_phys(desc));
/* Wait for all above memory cycles, then start xfer */
iosync();
st_le32(&pex_dma->pex_dma_ctrl, PEX_DMA_CTRL_START |
PEX_DMA_CTRL_SNOOP);
Poll for completion:
/* Wait for transfer to complete/fail */
do {
desc_stat =3D ld_le32(&desc->pdmad_stat);
} while (!(desc_stat & PDMAD_STAT_DONE));
status =3D ld_le32(&pex_dma->pex_dma_stat);
if (status =3D=3D (PEX_DMA_STAT_DSCPL | PEX_DMA_STAT_CHCPL)
&& desc_stat =3D=3D PDMAD_STAT_DONE)
/* Transfer ok */
return 0;
/* Transfer failed */
Oh, since I couldn't find it in the documentation, the first
word of the dma descriptor is 'ctrl' and the last 'next_desc'.
David
^ permalink raw reply
* RE: [PATCH] e500: Erratum cpu a005 workaround
From: Liu Yu-B13201 @ 2011-01-25 8:57 UTC (permalink / raw)
To: Gala Kumar-B11780; +Cc: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <5DA54AEE-B8AC-452B-A56C-65B35391A97C@freescale.com>
=20
> -----Original Message-----
> From: Gala Kumar-B11780=20
> Sent: Tuesday, January 25, 2011 3:01 PM
> To: Liu Yu-B13201
> Cc: linuxppc-dev@lists.ozlabs.org; Gala Kumar-B11780
> Subject: Re: [PATCH] e500: Erratum cpu a005 workaround
>=20
>=20
> On Jan 25, 2011, at 12:02 AM, Liu Yu wrote:
>=20
> > This errata can occur if a single-precision floating-point,=20
> double-precision
> > floating-point or vector floating-point instruction on a=20
> mispredicted branch
> > path signals one of the floating-point data interrupts=20
> which are enabled by the
> > SPEFSCR (FINVE, FDBZE, FUNFE or FOVFE bits). This=20
> interrupt must be recorded
> > in a one-cycle window when the misprediction is resolved. =20
> If this extremely
> > rare event should occur, the result could be:
> >=20
> > The SPE Data Exception from the mispredicted path may be reported
> > erroneously if a single-precision floating-point, double-precision
> > floating-point or vector floating-point instruction is the=20
> second instruction
> > on the correct branch path.
> >=20
> > According to errata description, some efp instructions
> > which are not supposed to trigger SPE exceptions
> > can trigger the exceptions in this case.
> > However, as we haven't emulated these instructions here,
> > a signal will send to userspace, and userspace application=20
> would exit.
> >=20
> > This patch re-issue the efp instruction that we haven't emulated,
> > so that hardware can properly execute it again if this case happen.
> >=20
> > Signed-off-by: Liu Yu <yu.liu@freescale.com>
> > ---
> > This is an erratum workaround patch.
> > It would be better if the patch can go into 2.6.38.
> >=20
> > arch/powerpc/include/asm/reg.h | 2 +
> > arch/powerpc/math-emu/math_efp.c | 53=20
> +++++++++++++++++++++++++++++++++++++-
> > 2 files changed, 54 insertions(+), 1 deletions(-)
> >=20
> > diff --git a/arch/powerpc/include/asm/reg.h=20
> b/arch/powerpc/include/asm/reg.h
> > index 6315edc..0abfd91 100644
> > --- a/arch/powerpc/include/asm/reg.h
> > +++ b/arch/powerpc/include/asm/reg.h
> > @@ -833,6 +833,8 @@
> > #define PVR_7450 0x80000000
> > #define PVR_8540 0x80200000
> > #define PVR_8560 0x80200000
> > +#define PVR_VER_E500V1 0x8020
> > +#define PVR_VER_E500V2 0x8021
> > /*
> > * For the 8xx processors, all of them report the same PVR=20
> family for
> > * the PowerPC core. The various versions of these=20
> processors must be
> > diff --git a/arch/powerpc/math-emu/math_efp.c=20
> b/arch/powerpc/math-emu/math_efp.c
> > index 41f4ef3..634830b 100644
> > --- a/arch/powerpc/math-emu/math_efp.c
> > +++ b/arch/powerpc/math-emu/math_efp.c
> > @@ -1,7 +1,7 @@
> > /*
> > * arch/powerpc/math-emu/math_efp.c
> > *
> > - * Copyright (C) 2006-2008 Freescale Semiconductor, Inc.=20
> All rights reserved.
> > + * Copyright (C) 2006-2008, 2010 Freescale Semiconductor, Inc.
> > *
> > * Author: Ebony Zhu, <ebony.zhu@freescale.com>
> > * Yu Liu, <yu.liu@freescale.com>
> > @@ -104,6 +104,8 @@
> > #define FP_EX_MASK (FP_EX_INEXACT | FP_EX_INVALID |=20
> FP_EX_DIVZERO | \
> > FP_EX_UNDERFLOW | FP_EX_OVERFLOW)
> >=20
> > +static int have_e500_cpu_a005_erratum;
> > +
> > union dw_union {
> > u64 dp[1];
> > u32 wp[2];
> > @@ -652,6 +654,15 @@ update_regs:
> > return 0;
> >=20
> > illegal:
> > + if (have_e500_cpu_a005_erratum) {
> > + /* according to e500 cpu a005 erratum, reissue=20
> efp inst */
> > + regs->nip -=3D 4;
> > +#ifdef DEBUG
> > + printk(KERN_DEBUG "re-issue efp inst: %08lx\n",=20
> speinsn);
> > +#endif
> > + return 0;
> > + }
> > +
> > printk(KERN_ERR "\nOoops! IEEE-754 compliance handler=20
> encountered un-supported instruction.\ninst code: %08lx\n", speinsn);
> > return -ENOSYS;
> > }
> > @@ -718,3 +729,43 @@ int speround_handler(struct pt_regs *regs)
> >=20
> > return 0;
> > }
> > +
> > +int __init spe_mathemu_init(void)
> > +{
> > + u32 pvr, maj, min;
> > +
> > + pvr =3D mfspr(SPRN_PVR);
> > +
> > + if ((PVR_VER(pvr) =3D=3D PVR_VER_E500V1) ||
> > + (PVR_VER(pvr) =3D=3D PVR_VER_E500V2)) {
> > + maj =3D PVR_MAJ(pvr);
> > + min =3D PVR_MIN(pvr);
> > +
> > + /*
> > + * E500 revision below 1.1, 2.3, 3.1, 4.1, 5.1
> > + * need cpu a005 errata workaround
> > + */
>=20
> This isn't the way to do this. We normally add entries in=20
> cputable.c an add a new cpu_feature_bit for the errata.
>=20
> Than above we'd do:
>=20
> if (cur_cpu_spec->cpu_features & CPU_FTR_E500_A005_ERRATUM)
>=20
>=20
IMHO, a cpu erratum is not a cpu feature.
See there're only 32 bits can be used for all PowerPC platform to represent=
cpu feature,=20
then is it worth consuming one of them to represent one e500 erratum?
Thanks,
Yu=
^ permalink raw reply
* Re: [PATCH 2/4 v4] video, sm501: add edid and commandline support
From: Heiko Schocher @ 2011-01-25 8:04 UTC (permalink / raw)
To: Paul Mundt
Cc: linux-fbdev, devicetree-discuss, Samuel Ortiz, Vincent Sanders,
linux-kernel, Ben Dooks, Randy Dunlap, linuxppc-dev
In-Reply-To: <20110125075104.GJ11673@linux-sh.org>
Hello Paul,
Paul Mundt wrote:
> On Mon, Jan 24, 2011 at 10:57:27AM +0100, Heiko Schocher wrote:
>> @@ -1884,7 +1935,6 @@ static int __devinit sm501fb_probe(struct platform_device *pdev)
>>
>> if (info->pdata == NULL) {
>> dev_info(dev, "using default configuration data\n");
>> - info->pdata = &sm501fb_def_pdata;
>> }
>>
>> /* probe for the presence of each panel */
>
> I assume this is accidental? I don't see how you're compensating for this
> in any of the other patches at least, as it's orthogonal from the default
> mode settings.
Seems so, rework this too, thanks!
bye,
heiko
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
^ permalink raw reply
* Re: [PATCH 3/4 v4] video, sm501: add OF binding to support SM501
From: Heiko Schocher @ 2011-01-25 8:02 UTC (permalink / raw)
To: Paul Mundt
Cc: linux-fbdev, devicetree-discuss, Samuel Ortiz, Vincent Sanders,
linux-kernel, Ben Dooks, Randy Dunlap, linuxppc-dev
In-Reply-To: <20110125074820.GI11673@linux-sh.org>
Hello Paul,
Paul Mundt wrote:
> On Tue, Jan 25, 2011 at 08:20:31AM +0100, Heiko Schocher wrote:
>> @@ -1934,7 +1943,29 @@ static int __devinit sm501fb_probe(struct platform_device *pdev)
>> }
>>
>> if (info->pdata == NULL) {
>> - dev_info(dev, "using default configuration data\n");
>> + int found = 0;
>> +#if defined(CONFIG_OF)
>> + struct device_node *np = pdev->dev.parent->of_node;
>> + const u8 *prop;
>> + const char *cp;
>> + int len;
>> +
>> + info->pdata = &sm501fb_def_pdata;
>> + if (np) {
>> + /* Get EDID */
>> + cp = of_get_property(np, "mode", &len);
>> + if (cp)
>> + strcpy(fb_mode, cp);
>> + prop = of_get_property(np, "edid", &len);
>> + if (prop && len == EDID_LENGTH) {
>> + info->edid_data = kmemdup(prop, EDID_LENGTH,
>> + GFP_KERNEL);
>> + found = 1;
>> + }
>> + }
>> +#endif
>> + if (!found)
>> + dev_info(dev, "using default configuration data\n");
>> }
>>
>> /* probe for the presence of each panel */
>
> Starting to get a bit pedantic.. but kmemdup() tries to do a kmalloc(),
No problem!
> and so can fail. Your other patches handle the info->edid_data == NULL
> case, in addition to the kfree(), but you're probably going to want to
> chomp that found assignment incase of the allocation failing and falling
> back on the default mode.
>
> You also don't really have any need to keep the EDID block around after
> probe as far as I can tell, so you should be able to rework this in to
> something more like:
>
> info->edid_data = kmemdup(..);
> ...
> if (info->edid_data) {
> fb_edid_to_monspecs(..);
> kfree(info->edid_data);
> fb_videomode_to_modelist(..);
> }
>
> ...
Ok, rework this part, thanks!
bye,
Heiko
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
^ permalink raw reply
* Re: [PATCH 2/4 v4] video, sm501: add edid and commandline support
From: Paul Mundt @ 2011-01-25 7:51 UTC (permalink / raw)
To: Heiko Schocher
Cc: linux-fbdev, devicetree-discuss, Samuel Ortiz, Vincent Sanders,
linux-kernel, Ben Dooks, Randy Dunlap, linuxppc-dev
In-Reply-To: <1295863047-11131-1-git-send-email-hs@denx.de>
On Mon, Jan 24, 2011 at 10:57:27AM +0100, Heiko Schocher wrote:
> @@ -1884,7 +1935,6 @@ static int __devinit sm501fb_probe(struct platform_device *pdev)
>
> if (info->pdata == NULL) {
> dev_info(dev, "using default configuration data\n");
> - info->pdata = &sm501fb_def_pdata;
> }
>
> /* probe for the presence of each panel */
I assume this is accidental? I don't see how you're compensating for this
in any of the other patches at least, as it's orthogonal from the default
mode settings.
^ permalink raw reply
* Re: [PATCH 3/4 v4] video, sm501: add OF binding to support SM501
From: Paul Mundt @ 2011-01-25 7:48 UTC (permalink / raw)
To: Heiko Schocher
Cc: linux-fbdev, devicetree-discuss, Samuel Ortiz, Vincent Sanders,
linux-kernel, Ben Dooks, Randy Dunlap, linuxppc-dev
In-Reply-To: <1295940031-28268-1-git-send-email-hs@denx.de>
On Tue, Jan 25, 2011 at 08:20:31AM +0100, Heiko Schocher wrote:
> @@ -1934,7 +1943,29 @@ static int __devinit sm501fb_probe(struct platform_device *pdev)
> }
>
> if (info->pdata == NULL) {
> - dev_info(dev, "using default configuration data\n");
> + int found = 0;
> +#if defined(CONFIG_OF)
> + struct device_node *np = pdev->dev.parent->of_node;
> + const u8 *prop;
> + const char *cp;
> + int len;
> +
> + info->pdata = &sm501fb_def_pdata;
> + if (np) {
> + /* Get EDID */
> + cp = of_get_property(np, "mode", &len);
> + if (cp)
> + strcpy(fb_mode, cp);
> + prop = of_get_property(np, "edid", &len);
> + if (prop && len == EDID_LENGTH) {
> + info->edid_data = kmemdup(prop, EDID_LENGTH,
> + GFP_KERNEL);
> + found = 1;
> + }
> + }
> +#endif
> + if (!found)
> + dev_info(dev, "using default configuration data\n");
> }
>
> /* probe for the presence of each panel */
Starting to get a bit pedantic.. but kmemdup() tries to do a kmalloc(),
and so can fail. Your other patches handle the info->edid_data == NULL
case, in addition to the kfree(), but you're probably going to want to
chomp that found assignment incase of the allocation failing and falling
back on the default mode.
You also don't really have any need to keep the EDID block around after
probe as far as I can tell, so you should be able to rework this in to
something more like:
info->edid_data = kmemdup(..);
...
if (info->edid_data) {
fb_edid_to_monspecs(..);
kfree(info->edid_data);
fb_videomode_to_modelist(..);
}
...
^ permalink raw reply
* [PATCH 3/4 v4] video, sm501: add OF binding to support SM501
From: Heiko Schocher @ 2011-01-25 7:20 UTC (permalink / raw)
To: linuxppc-dev
Cc: linux-fbdev, devicetree-discuss, Samuel Ortiz, Vincent Sanders,
linux-kernel, Ben Dooks, Randy Dunlap, Paul Mundt, Heiko Schocher
In-Reply-To: <1291451028-22532-1-git-send-email-hs@denx.de>
- add binding to OF, compatible name "smi,sm501"
Signed-off-by: Heiko Schocher <hs@denx.de>
cc: linux-fbdev@vger.kernel.org
cc: devicetree-discuss@ozlabs.org
cc: Ben Dooks <ben@simtec.co.uk>
cc: Vincent Sanders <vince@simtec.co.uk>
cc: Samuel Ortiz <sameo@linux.intel.com>
cc: linux-kernel@vger.kernel.org
cc: Randy Dunlap <rdunlap@xenotime.net>
cc: Paul Mundt <lethal@linux-sh.org>
---
- changes since v1:
add Ben Dooks, Vincent Sanders and Samuel Ortiz to cc, as suggested from
Paul Mundt.
- changes since v2:
add comments from Randy Dunlap:
- move parameter documentation to Documentation/fb/sm501.txt
- changes since v3:
- rebased against v2.6.38-rc2
- split in 3 patches
- of support patch
- get rid of "#if defined(CONFIG_PPC_MPC52xx)" usage
hide this in DTS, as Paul suggested.
- i/o routine patch
- edid support patch
- changes since v4
replace remaining CONFIG_PPC_MPC52xx with CONFIG_OF, as
it is no longer MPC52xx only.
./scripts/checkpatch.pl 0003-video-sm501-add-OF-binding-to-support-SM501.patch
total: 0 errors, 0 warnings, 117 lines checked
0003-video-sm501-add-OF-binding-to-support-SM501.patch has no obvious style problems and is ready for submission.
Documentation/powerpc/dts-bindings/sm501.txt | 34 ++++++++++++++++++++++++++
drivers/mfd/sm501.c | 16 +++++++++++-
drivers/video/sm501fb.c | 33 ++++++++++++++++++++++++-
3 files changed, 81 insertions(+), 2 deletions(-)
create mode 100644 Documentation/powerpc/dts-bindings/sm501.txt
diff --git a/Documentation/powerpc/dts-bindings/sm501.txt b/Documentation/powerpc/dts-bindings/sm501.txt
new file mode 100644
index 0000000..7d319fb
--- /dev/null
+++ b/Documentation/powerpc/dts-bindings/sm501.txt
@@ -0,0 +1,34 @@
+* SM SM501
+
+The SM SM501 is a LCD controller, with proper hardware, it can also
+drive DVI monitors.
+
+Required properties:
+- compatible : should be "smi,sm501".
+- reg : contain two entries:
+ - First entry: System Configuration register
+ - Second entry: IO space (Display Controller register)
+- interrupts : SMI interrupt to the cpu should be described here.
+- interrupt-parent : the phandle for the interrupt controller that
+ services interrupts for this device.
+
+Optional properties:
+- mode : select a video mode:
+ <xres>x<yres>[-<bpp>][@<refresh>]
+- edid : verbatim EDID data block describing attached display.
+ Data from the detailed timing descriptor will be used to
+ program the display controller.
+- little-endian: availiable on big endian systems, to
+ set different foreign endian.
+- big-endian: availiable on little endian systems, to
+ set different foreign endian.
+
+Example for MPC5200:
+ display@1,0 {
+ compatible = "smi,sm501";
+ reg = <1 0x00000000 0x00800000
+ 1 0x03e00000 0x00200000>;
+ interrupts = <1 1 3>;
+ mode = "640x480-32@60";
+ edid = [edid-data];
+ };
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index 558d5f3..5b7a8f4 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -1377,7 +1377,7 @@ static int __devinit sm501_init_dev(struct sm501_devdata *sm)
sm501_register_gpio(sm);
}
- if (pdata->gpio_i2c != NULL && pdata->gpio_i2c_nr > 0) {
+ if (pdata && pdata->gpio_i2c != NULL && pdata->gpio_i2c_nr > 0) {
if (!sm501_gpio_isregistered(sm))
dev_err(sm->dev, "no gpio available for i2c gpio.\n");
else
@@ -1422,6 +1422,14 @@ static int __devinit sm501_plat_probe(struct platform_device *dev)
sm->io_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
sm->mem_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+
+ if (sm->mem_res)
+ pr_debug("sm501 mem 0x%lx, 0x%lx\n",
+ sm->mem_res->start, sm->mem_res->end);
+ if (sm->io_res)
+ pr_debug("sm501 io 0x%lx, 0x%lx\n",
+ sm->io_res->start, sm->io_res->end);
+
if (sm->io_res == NULL || sm->mem_res == NULL) {
dev_err(&dev->dev, "failed to get IO resource\n");
ret = -ENOENT;
@@ -1735,10 +1743,16 @@ static struct pci_driver sm501_pci_driver = {
MODULE_ALIAS("platform:sm501");
+static struct of_device_id __devinitdata of_sm501_match_tbl[] = {
+ { .compatible = "smi,sm501", },
+ { /* end */ }
+};
+
static struct platform_driver sm501_plat_driver = {
.driver = {
.name = "sm501",
.owner = THIS_MODULE,
+ .of_match_table = of_sm501_match_tbl,
},
.probe = sm501_plat_probe,
.remove = sm501_plat_remove,
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index 30b53ae..bbdb359 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -1729,6 +1729,15 @@ static int sm501fb_init_fb(struct fb_info *fb,
FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
+#if defined(CONFIG_OF)
+#ifdef __BIG_ENDIAN
+ if (of_get_property(info->dev->parent->of_node, "little-endian", NULL))
+ fb->flags |= FBINFO_FOREIGN_ENDIAN;
+#else
+ if (of_get_property(info->dev->parent->of_node, "big-endian", NULL))
+ fb->flags |= FBINFO_FOREIGN_ENDIAN;
+#endif
+#endif
/* fixed data */
fb->fix.type = FB_TYPE_PACKED_PIXELS;
@@ -1934,7 +1943,29 @@ static int __devinit sm501fb_probe(struct platform_device *pdev)
}
if (info->pdata == NULL) {
- dev_info(dev, "using default configuration data\n");
+ int found = 0;
+#if defined(CONFIG_OF)
+ struct device_node *np = pdev->dev.parent->of_node;
+ const u8 *prop;
+ const char *cp;
+ int len;
+
+ info->pdata = &sm501fb_def_pdata;
+ if (np) {
+ /* Get EDID */
+ cp = of_get_property(np, "mode", &len);
+ if (cp)
+ strcpy(fb_mode, cp);
+ prop = of_get_property(np, "edid", &len);
+ if (prop && len == EDID_LENGTH) {
+ info->edid_data = kmemdup(prop, EDID_LENGTH,
+ GFP_KERNEL);
+ found = 1;
+ }
+ }
+#endif
+ if (!found)
+ dev_info(dev, "using default configuration data\n");
}
/* probe for the presence of each panel */
--
1.7.3.4
^ permalink raw reply related
* Re: [PATCH] e500: Erratum cpu a005 workaround
From: Kumar Gala @ 2011-01-25 7:01 UTC (permalink / raw)
To: Liu Yu; +Cc: B11780, linuxppc-dev
In-Reply-To: <1295935333-13045-1-git-send-email-yu.liu@freescale.com>
On Jan 25, 2011, at 12:02 AM, Liu Yu wrote:
> This errata can occur if a single-precision floating-point, =
double-precision
> floating-point or vector floating-point instruction on a mispredicted =
branch
> path signals one of the floating-point data interrupts which are =
enabled by the
> SPEFSCR (FINVE, FDBZE, FUNFE or FOVFE bits). This interrupt must be =
recorded
> in a one-cycle window when the misprediction is resolved. If this =
extremely
> rare event should occur, the result could be:
>=20
> The SPE Data Exception from the mispredicted path may be reported
> erroneously if a single-precision floating-point, double-precision
> floating-point or vector floating-point instruction is the second =
instruction
> on the correct branch path.
>=20
> According to errata description, some efp instructions
> which are not supposed to trigger SPE exceptions
> can trigger the exceptions in this case.
> However, as we haven't emulated these instructions here,
> a signal will send to userspace, and userspace application would exit.
>=20
> This patch re-issue the efp instruction that we haven't emulated,
> so that hardware can properly execute it again if this case happen.
>=20
> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> ---
> This is an erratum workaround patch.
> It would be better if the patch can go into 2.6.38.
>=20
> arch/powerpc/include/asm/reg.h | 2 +
> arch/powerpc/math-emu/math_efp.c | 53 =
+++++++++++++++++++++++++++++++++++++-
> 2 files changed, 54 insertions(+), 1 deletions(-)
>=20
> diff --git a/arch/powerpc/include/asm/reg.h =
b/arch/powerpc/include/asm/reg.h
> index 6315edc..0abfd91 100644
> --- a/arch/powerpc/include/asm/reg.h
> +++ b/arch/powerpc/include/asm/reg.h
> @@ -833,6 +833,8 @@
> #define PVR_7450 0x80000000
> #define PVR_8540 0x80200000
> #define PVR_8560 0x80200000
> +#define PVR_VER_E500V1 0x8020
> +#define PVR_VER_E500V2 0x8021
> /*
> * For the 8xx processors, all of them report the same PVR family for
> * the PowerPC core. The various versions of these processors must be
> diff --git a/arch/powerpc/math-emu/math_efp.c =
b/arch/powerpc/math-emu/math_efp.c
> index 41f4ef3..634830b 100644
> --- a/arch/powerpc/math-emu/math_efp.c
> +++ b/arch/powerpc/math-emu/math_efp.c
> @@ -1,7 +1,7 @@
> /*
> * arch/powerpc/math-emu/math_efp.c
> *
> - * Copyright (C) 2006-2008 Freescale Semiconductor, Inc. All rights =
reserved.
> + * Copyright (C) 2006-2008, 2010 Freescale Semiconductor, Inc.
> *
> * Author: Ebony Zhu, <ebony.zhu@freescale.com>
> * Yu Liu, <yu.liu@freescale.com>
> @@ -104,6 +104,8 @@
> #define FP_EX_MASK (FP_EX_INEXACT | FP_EX_INVALID | FP_EX_DIVZERO | =
\
> FP_EX_UNDERFLOW | FP_EX_OVERFLOW)
>=20
> +static int have_e500_cpu_a005_erratum;
> +
> union dw_union {
> u64 dp[1];
> u32 wp[2];
> @@ -652,6 +654,15 @@ update_regs:
> return 0;
>=20
> illegal:
> + if (have_e500_cpu_a005_erratum) {
> + /* according to e500 cpu a005 erratum, reissue efp inst =
*/
> + regs->nip -=3D 4;
> +#ifdef DEBUG
> + printk(KERN_DEBUG "re-issue efp inst: %08lx\n", =
speinsn);
> +#endif
> + return 0;
> + }
> +
> printk(KERN_ERR "\nOoops! IEEE-754 compliance handler =
encountered un-supported instruction.\ninst code: %08lx\n", speinsn);
> return -ENOSYS;
> }
> @@ -718,3 +729,43 @@ int speround_handler(struct pt_regs *regs)
>=20
> return 0;
> }
> +
> +int __init spe_mathemu_init(void)
> +{
> + u32 pvr, maj, min;
> +
> + pvr =3D mfspr(SPRN_PVR);
> +
> + if ((PVR_VER(pvr) =3D=3D PVR_VER_E500V1) ||
> + (PVR_VER(pvr) =3D=3D PVR_VER_E500V2)) {
> + maj =3D PVR_MAJ(pvr);
> + min =3D PVR_MIN(pvr);
> +
> + /*
> + * E500 revision below 1.1, 2.3, 3.1, 4.1, 5.1
> + * need cpu a005 errata workaround
> + */
This isn't the way to do this. We normally add entries in cputable.c an =
add a new cpu_feature_bit for the errata.
Than above we'd do:
if (cur_cpu_spec->cpu_features & CPU_FTR_E500_A005_ERRATUM)
> + switch (maj) {
> + case 1:
> + if (min < 1)
> + have_e500_cpu_a005_erratum =3D 1;
> + break;
> + case 2:
> + if (min < 3)
> + have_e500_cpu_a005_erratum =3D 1;
> + break;
> + case 3:
> + case 4:
> + case 5:
> + if (min < 1)
> + have_e500_cpu_a005_erratum =3D 1;
> + break;
> + default:
> + break;
> + }
> + }
> +
> + return 0;
> +}
> +
> +module_init(spe_mathemu_init);
> --=20
> 1.6.4
^ permalink raw reply
* Re: [PATCH 4/4 v5] powerpc, video: add SM501 support for charon board.
From: Heiko Schocher @ 2011-01-25 7:07 UTC (permalink / raw)
To: Paul Mundt
Cc: linux-fbdev, devicetree-discuss, Samuel Ortiz, Vincent Sanders,
linux-kernel, Ben Dooks, linuxppc-dev
In-Reply-To: <20110125064949.GF11673@linux-sh.org>
Hello Paul,
Paul Mundt wrote:
> On Tue, Jan 25, 2011 at 07:45:46AM +0100, Heiko Schocher wrote:
>> @@ -197,6 +198,15 @@
>> #address-cells = <1>;
>> };
>>
>> + display@1,0 {
>> + compatible = "smi,sm501";
>> + reg = <1 0x00000000 0x00800000
>> + 1 0x03e00000 0x00200000>;
>> + mode = "640x480-32@60";
>> + interrupts = <1 1 3>;
>> + little-endian;
>> + };
>> +
>
> The endian designation looks good, but it still doesn't explain why you
> have a remaining CONFIG_PPC_MPC52xx ifdef encapsulating the property
> check in the sm501fb patch. It shouldn't be needed at all. If the
> platform supports OF then the property will need to be set one way or the
> other, so there is no need for any board or CPU ifdeffery within the
> driver itself.
Argh, of course you are right, thanks! I post an update for the
"sm501fb of support" patch.
bye,
Heiko
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
^ permalink raw reply
* Re: [PATCH 4/4 v5] powerpc, video: add SM501 support for charon board.
From: Paul Mundt @ 2011-01-25 6:49 UTC (permalink / raw)
To: Heiko Schocher
Cc: linux-fbdev, devicetree-discuss, Samuel Ortiz, Vincent Sanders,
linux-kernel, Ben Dooks, linuxppc-dev
In-Reply-To: <1295937946-26934-1-git-send-email-hs@denx.de>
On Tue, Jan 25, 2011 at 07:45:46AM +0100, Heiko Schocher wrote:
> @@ -197,6 +198,15 @@
> #address-cells = <1>;
> };
>
> + display@1,0 {
> + compatible = "smi,sm501";
> + reg = <1 0x00000000 0x00800000
> + 1 0x03e00000 0x00200000>;
> + mode = "640x480-32@60";
> + interrupts = <1 1 3>;
> + little-endian;
> + };
> +
The endian designation looks good, but it still doesn't explain why you
have a remaining CONFIG_PPC_MPC52xx ifdef encapsulating the property
check in the sm501fb patch. It shouldn't be needed at all. If the
platform supports OF then the property will need to be set one way or the
other, so there is no need for any board or CPU ifdeffery within the
driver itself.
^ permalink raw reply
* [PATCH 4/4 v5] powerpc, video: add SM501 support for charon board.
From: Heiko Schocher @ 2011-01-25 6:45 UTC (permalink / raw)
To: linuxppc-dev
Cc: linux-fbdev, devicetree-discuss, Samuel Ortiz, Vincent Sanders,
linux-kernel, Ben Dooks, Paul Mundt, Heiko Schocher
In-Reply-To: <1291451028-22532-2-git-send-email-hs@denx.de>
Signed-off-by: Heiko Schocher <hs@denx.de>
cc: linux-fbdev@vger.kernel.org
cc: devicetree-discuss@ozlabs.org
cc: Ben Dooks <ben@simtec.co.uk>
cc: Vincent Sanders <vince@simtec.co.uk>
cc: Samuel Ortiz <sameo@linux.intel.com>
cc: linux-kernel@vger.kernel.org
cc: Paul Mundt <lethal@linux-sh.org>
---
- changes since v1:
- no board specific defconfig file for mpc52xx based boards as suggested
from Wolfram Sang
- changes since v2:
add Ben Dooks, Vincent Sanders and Samuel Ortiz and lkml to cc, as
suggested from Paul Mundt.
- changes since v3:
- rebased against v2.6.38-rc2
- changes since v4:
- added Paul Mundt to cc (Sorry forgot this in series v4)
./scripts/checkpatch.pl 0004-powerpc-video-add-SM501-support-for-charon-board.patch
total: 0 errors, 0 warnings, 22 lines checked
0004-powerpc-video-add-SM501-support-for-charon-board.patch has no obvious style problems and is ready for submission.
arch/powerpc/boot/dts/charon.dts | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/boot/dts/charon.dts b/arch/powerpc/boot/dts/charon.dts
index 9776889..0e00e50 100644
--- a/arch/powerpc/boot/dts/charon.dts
+++ b/arch/powerpc/boot/dts/charon.dts
@@ -186,6 +186,7 @@
#address-cells = <2>;
#size-cells = <1>;
ranges = < 0 0 0xfc000000 0x02000000
+ 1 0 0xe0000000 0x04000000 // CS1 range, SM501
3 0 0xe8000000 0x00080000>;
flash@0,0 {
@@ -197,6 +198,15 @@
#address-cells = <1>;
};
+ display@1,0 {
+ compatible = "smi,sm501";
+ reg = <1 0x00000000 0x00800000
+ 1 0x03e00000 0x00200000>;
+ mode = "640x480-32@60";
+ interrupts = <1 1 3>;
+ little-endian;
+ };
+
mram0@3,0 {
compatible = "mtd-ram";
reg = <3 0x00000 0x80000>;
--
1.7.3.4
^ permalink raw reply related
* [PATCH] e500: Erratum cpu a005 workaround
From: Liu Yu @ 2011-01-25 6:02 UTC (permalink / raw)
To: linuxppc-dev; +Cc: B11780, Liu Yu
This errata can occur if a single-precision floating-point, double-precision
floating-point or vector floating-point instruction on a mispredicted branch
path signals one of the floating-point data interrupts which are enabled by the
SPEFSCR (FINVE, FDBZE, FUNFE or FOVFE bits). This interrupt must be recorded
in a one-cycle window when the misprediction is resolved. If this extremely
rare event should occur, the result could be:
The SPE Data Exception from the mispredicted path may be reported
erroneously if a single-precision floating-point, double-precision
floating-point or vector floating-point instruction is the second instruction
on the correct branch path.
According to errata description, some efp instructions
which are not supposed to trigger SPE exceptions
can trigger the exceptions in this case.
However, as we haven't emulated these instructions here,
a signal will send to userspace, and userspace application would exit.
This patch re-issue the efp instruction that we haven't emulated,
so that hardware can properly execute it again if this case happen.
Signed-off-by: Liu Yu <yu.liu@freescale.com>
---
This is an erratum workaround patch.
It would be better if the patch can go into 2.6.38.
arch/powerpc/include/asm/reg.h | 2 +
arch/powerpc/math-emu/math_efp.c | 53 +++++++++++++++++++++++++++++++++++++-
2 files changed, 54 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 6315edc..0abfd91 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -833,6 +833,8 @@
#define PVR_7450 0x80000000
#define PVR_8540 0x80200000
#define PVR_8560 0x80200000
+#define PVR_VER_E500V1 0x8020
+#define PVR_VER_E500V2 0x8021
/*
* For the 8xx processors, all of them report the same PVR family for
* the PowerPC core. The various versions of these processors must be
diff --git a/arch/powerpc/math-emu/math_efp.c b/arch/powerpc/math-emu/math_efp.c
index 41f4ef3..634830b 100644
--- a/arch/powerpc/math-emu/math_efp.c
+++ b/arch/powerpc/math-emu/math_efp.c
@@ -1,7 +1,7 @@
/*
* arch/powerpc/math-emu/math_efp.c
*
- * Copyright (C) 2006-2008 Freescale Semiconductor, Inc. All rights reserved.
+ * Copyright (C) 2006-2008, 2010 Freescale Semiconductor, Inc.
*
* Author: Ebony Zhu, <ebony.zhu@freescale.com>
* Yu Liu, <yu.liu@freescale.com>
@@ -104,6 +104,8 @@
#define FP_EX_MASK (FP_EX_INEXACT | FP_EX_INVALID | FP_EX_DIVZERO | \
FP_EX_UNDERFLOW | FP_EX_OVERFLOW)
+static int have_e500_cpu_a005_erratum;
+
union dw_union {
u64 dp[1];
u32 wp[2];
@@ -652,6 +654,15 @@ update_regs:
return 0;
illegal:
+ if (have_e500_cpu_a005_erratum) {
+ /* according to e500 cpu a005 erratum, reissue efp inst */
+ regs->nip -= 4;
+#ifdef DEBUG
+ printk(KERN_DEBUG "re-issue efp inst: %08lx\n", speinsn);
+#endif
+ return 0;
+ }
+
printk(KERN_ERR "\nOoops! IEEE-754 compliance handler encountered un-supported instruction.\ninst code: %08lx\n", speinsn);
return -ENOSYS;
}
@@ -718,3 +729,43 @@ int speround_handler(struct pt_regs *regs)
return 0;
}
+
+int __init spe_mathemu_init(void)
+{
+ u32 pvr, maj, min;
+
+ pvr = mfspr(SPRN_PVR);
+
+ if ((PVR_VER(pvr) == PVR_VER_E500V1) ||
+ (PVR_VER(pvr) == PVR_VER_E500V2)) {
+ maj = PVR_MAJ(pvr);
+ min = PVR_MIN(pvr);
+
+ /*
+ * E500 revision below 1.1, 2.3, 3.1, 4.1, 5.1
+ * need cpu a005 errata workaround
+ */
+ switch (maj) {
+ case 1:
+ if (min < 1)
+ have_e500_cpu_a005_erratum = 1;
+ break;
+ case 2:
+ if (min < 3)
+ have_e500_cpu_a005_erratum = 1;
+ break;
+ case 3:
+ case 4:
+ case 5:
+ if (min < 1)
+ have_e500_cpu_a005_erratum = 1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+
+module_init(spe_mathemu_init);
--
1.6.4
^ 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