* Re: BootX
From: kevin diggs @ 2011-01-22 18:24 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <AANLkTikAVgH9-UQfrjoAJSemet5p_PxhxCdot8cChQu3@mail.gmail.com>
Hi,
If I enable SMP then I can build a 2.6.28 kernel with gcc 4.3.5 that
WILL boot on the PowerMac8600 (single 750GX). The previously mentioned
G4 that runs is a dual cpu beast and thus also runs SMP.
I at least know this (ok, I THINK I know):
For non-SMP: The spinlock 'acct_lock' in kernel/acct.c that IS
present in 3.4.6 (i.e. kernel 2.6.28 compiled with gcc 3.4.6). Not so
much for 4.3.5. I have not yet done a general 4.3.5 compiled 2.6.28
spinlock safari.
Don't some funky, optimizery things happen to spinlocks for the NON-smp case?
I'll see what the 4.2.x gcc does.
Thanks!
kevin
P.S.: There is one other difference for the SMP 4.3.5 compiled
2.6.28: my 750gx cpufreq driver gets disabled. It is fairly isolated
code though. Should not be able to nuke the spinlock in kernel/acct.c
On Fri, Jan 21, 2011 at 1:26 PM, kevin diggs <diggskevin38@gmail.com> wrote:
> Hi,
>
> Anyone familiar with BootX? Could my problems with the 8600 be related
> to some interaction with BootX?
>
> kevin
>
^ permalink raw reply
* Re: [PATCH V8 00/10] Add-Synopsys-DesignWare-HS-USB-OTG-driver
From: Greg KH @ 2011-01-23 3:01 UTC (permalink / raw)
To: tmarri; +Cc: linux-usb, linuxppc-dev
In-Reply-To: <1295477836-14589-1-git-send-email-tmarri@apm.com>
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?
thanks,
greg k-h
^ permalink raw reply
* About mpc85xx flash memory allocation
From: Mitsutaka Amano @ 2011-01-24 1:15 UTC (permalink / raw)
To: linuxppc-dev
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 tight.
Why does we need mpc platforms to flash memory allocation? I know
other architectures don't allocate to the vmalloc.
The design of the hardware? or Is there the way to use the flash
memory without vmalloc?
Thanks,
Mitsutaka
^ permalink raw reply
* Re: fsl-esdhc on P2020 weird endianess behavior
From: tiejun.chen @ 2011-01-24 3:26 UTC (permalink / raw)
To: Elie De Brauwer; +Cc: linuxppc-dev
In-Reply-To: <4D39B2B0.9050207@gmail.com>
Elie De Brauwer wrote:
> Hello list,
>
> I have a P2020 processor on a custom board which uses the embedded
> fsl-esdhc controller. Hardware-wise this is functional and in u-boot
> everything seems to behave (mmc part 0 gives the correct partition table
> and ext2ls/fatls are capable of reading the contents of the sd card).
>
> However as soon as I start Linux (2.6.36), I get all sorts of unwanted
> behavior. Linux is unable to detect the partition layout (but if I do a
Can you re-partition that under Linux? i.e, you can use fdisk to do this. Then
I'm a bit curious what it'll be happened.
> hexdump of the MBR, I see the endianness is swapped (last 4 bytes are aa
> 55 00 00). Also when I try to obtain the card registers they show the
> same behavior:
> # cat ./devices/soc.0/ff72e000.sdhci/mmc_host/mmc0/mmc0:0001/scr
> 0000b50200000000
>
> While for comparison the same value on my (x86) laptop gives:
> edb@lapedb:/sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.2/mmc_host/mmc0/mmc0:0001$
> cat scr
> 02b5000000000000
>
> In my config I have the following set:
> CONFIG_MMC_SDHCI=y
> CONFIG_MMC_SDHCI_IO_ACCESSORS=y
> CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER=y
> # CONFIG_MMC_SDHCI_PCI is not set
> CONFIG_MMC_SDHCI_OF=y
> CONFIG_MMC_SDHCI_OF_ESDHC=y
At least looks the config is fine.
Tiejun
>
>
> any pointers are welcome.
>
> gr
> E.
>
^ permalink raw reply
* Re: elf section .text.unlikely
From: tiejun.chen @ 2011-01-24 3:29 UTC (permalink / raw)
To: kevin diggs; +Cc: linuxppc-dev
In-Reply-To: <AANLkTinhu1fS5ESwivxSepnp-CXirm9dfV74_GEUi9qB@mail.gmail.com>
kevin diggs wrote:
> Hi,
>
> One more thing:
>
> The last message printed is:
>
> Driver 'sd' needs updating - please us bus_type methods
>
> The mesh SCSI controller seems to successfully scan the bus. The next
> message that a 3.4.6 compiled kernel prints are details about disk sda
> (from SCSI disk driver?).
>
> 4.3.5 keyboard is dead.
>
> Jog any thoughts?
Maybe the kernel already panic then serial cannot print the last messages
immediately. So after reset the target you can dump __log_buf from the u-boot
prompt to track this in detail.
Tiejun
>
> Thanks!
>
> kevin
>
> On Fri, Jan 21, 2011 at 8:31 PM, kevin diggs <diggskevin38@gmail.com> wrote:
>> For what it is worth, this section contains dump_stack, panic, and printk
>>
>> Thanks!
>>
>> kevin
>>
>> On Fri, Jan 21, 2011 at 7:40 PM, kevin diggs <diggskevin38@gmail.com> wrote:
>>> Hi,
>>>
>>> I am trying to get a PowerMac 8600 to boot past 2.6.28.
>>>
>>> I can boot 2.6.28 compiled with either 3.3.3 or 3.4.6. I can't get
>>> 2.6.28 to boot using 4.3.5. The 4.3.5 vmlinux has a section
>>> '.text.unlikely' that the 3.4.6 version does not. Anyone know what
>>> this might be?
>>>
>>> kevin
^ permalink raw reply
* Re: About mpc85xx flash memory allocation
From: tiejun.chen @ 2011-01-24 6:48 UTC (permalink / raw)
To: Mitsutaka Amano; +Cc: linuxppc-dev
In-Reply-To: <AANLkTin0RHAF8ieFqv12dFfOr_N3g3w6VVUTGOvH47uq@mail.gmail.com>
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 tight.
>
> 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 same space as
vmalloc(). While bootstrap you also can see this associated message like the
follows,
------
......
* 0xd1000000..0xffbe9000 : 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.
Tiejun
> memory without vmalloc?
>
> Thanks,
> Mitsutaka
^ permalink raw reply
* Re: fsl-esdhc on P2020 weird endianess behavior
From: Elie De Brauwer @ 2011-01-24 7:52 UTC (permalink / raw)
To: linuxppc-dev; +Cc: tiejun.chen
In-Reply-To: <4D3CF158.20704@windriver.com>
On 01/24/11 04:26, tiejun.chen wrote:
> Elie De Brauwer wrote:
>> Hello list,
>>
>> I have a P2020 processor on a custom board which uses the embedded
>> fsl-esdhc controller. Hardware-wise this is functional and in u-boot
>> everything seems to behave (mmc part 0 gives the correct partition table
>> and ext2ls/fatls are capable of reading the contents of the sd card).
>>
>> However as soon as I start Linux (2.6.36), I get all sorts of unwanted
>> behavior. Linux is unable to detect the partition layout (but if I do a
>
> Can you re-partition that under Linux? i.e, you can use fdisk to do this. Then
> I'm a bit curious what it'll be happened.
This was already partitioned under (x86) Linux, and when I plug it into
my laptop it sees the MBR (but also on target, in U-boot, the mmc part 0
command shows the correct partition table). And this does not explain
why the card registers (such as the scr pasted below) also seem to have
their endianess swapped, which will result in other side-effects, such
as improper reading of card capabilities.
>
>> hexdump of the MBR, I see the endianness is swapped (last 4 bytes are aa
>> 55 00 00). Also when I try to obtain the card registers they show the
>> same behavior:
>> # cat ./devices/soc.0/ff72e000.sdhci/mmc_host/mmc0/mmc0:0001/scr
>> 0000b50200000000
>>
>> While for comparison the same value on my (x86) laptop gives:
>> edb@lapedb:/sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.2/mmc_host/mmc0/mmc0:0001$
>> cat scr
>> 02b5000000000000
>>
>> In my config I have the following set:
>> CONFIG_MMC_SDHCI=y
>> CONFIG_MMC_SDHCI_IO_ACCESSORS=y
>> CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER=y
>> # CONFIG_MMC_SDHCI_PCI is not set
>> CONFIG_MMC_SDHCI_OF=y
>> CONFIG_MMC_SDHCI_OF_ESDHC=y
>
> At least looks the config is fine.
>
> Tiejun
>
^ permalink raw reply
* Re: fsl-esdhc on P2020 weird endianess behavior
From: tiejun.chen @ 2011-01-24 8:15 UTC (permalink / raw)
To: Elie De Brauwer; +Cc: linuxppc-dev
In-Reply-To: <4D3D2FBB.6010504@gmail.com>
Elie De Brauwer wrote:
> On 01/24/11 04:26, tiejun.chen wrote:
>> Elie De Brauwer wrote:
>>> Hello list,
>>>
>>> I have a P2020 processor on a custom board which uses the embedded
>>> fsl-esdhc controller. Hardware-wise this is functional and in u-boot
>>> everything seems to behave (mmc part 0 gives the correct partition table
>>> and ext2ls/fatls are capable of reading the contents of the sd card).
>>>
>>> However as soon as I start Linux (2.6.36), I get all sorts of unwanted
>>> behavior. Linux is unable to detect the partition layout (but if I do a
>>
>> Can you re-partition that under Linux? i.e, you can use fdisk to do
>> this. Then
>> I'm a bit curious what it'll be happened.
>
> This was already partitioned under (x86) Linux, and when I plug it into
I means you should partition the disk on the PPC Linux, not x86. As you know x86
work with LE for Linux, but PPC with BE. So I think you should partition that on
the same type machine. Can you try it?
> my laptop it sees the MBR (but also on target, in U-boot, the mmc part 0
> command shows the correct partition table). And this does not explain
I didn't check this implemented codes within u-boot. Maybe u-boot can do
something to swap MMC ending problem. You can try to get the conclusion. Firstly
you can re-partition that on PPC Linux then check if u-boot can identify it
properly. I guess u-boot still can read that successfully.
Tiejun
> why the card registers (such as the scr pasted below) also seem to have
> their endianess swapped, which will result in other side-effects, such
> as improper reading of card capabilities.
>
>>
>>> hexdump of the MBR, I see the endianness is swapped (last 4 bytes are aa
>>> 55 00 00). Also when I try to obtain the card registers they show the
>>> same behavior:
>>> # cat ./devices/soc.0/ff72e000.sdhci/mmc_host/mmc0/mmc0:0001/scr
>>> 0000b50200000000
>>>
>>> While for comparison the same value on my (x86) laptop gives:
>>> edb@lapedb:/sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.2/mmc_host/mmc0/mmc0:0001$
>>>
>>> cat scr
>>> 02b5000000000000
>>>
>>> In my config I have the following set:
>>> CONFIG_MMC_SDHCI=y
>>> CONFIG_MMC_SDHCI_IO_ACCESSORS=y
>>> CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER=y
>>> # CONFIG_MMC_SDHCI_PCI is not set
>>> CONFIG_MMC_SDHCI_OF=y
>>> CONFIG_MMC_SDHCI_OF_ESDHC=y
>>
>> At least looks the config is fine.
>>
>> Tiejun
>>
>
>
^ permalink raw reply
* Re: fsl-esdhc on P2020 weird endianess behavior
From: Elie De Brauwer @ 2011-01-24 9:03 UTC (permalink / raw)
To: linuxppc-dev; +Cc: tiejun.chen
In-Reply-To: <4D3D3512.4020105@windriver.com>
On 01/24/11 09:15, tiejun.chen wrote:
> Elie De Brauwer wrote:
>> On 01/24/11 04:26, tiejun.chen wrote:
>>> Elie De Brauwer wrote:
>>>> Hello list,
>>>>
>>>> I have a P2020 processor on a custom board which uses the embedded
>>>> fsl-esdhc controller. Hardware-wise this is functional and in u-boot
>>>> everything seems to behave (mmc part 0 gives the correct partition table
>>>> and ext2ls/fatls are capable of reading the contents of the sd card).
>>>>
>>>> However as soon as I start Linux (2.6.36), I get all sorts of unwanted
>>>> behavior. Linux is unable to detect the partition layout (but if I do a
>>>
>>> Can you re-partition that under Linux? i.e, you can use fdisk to do
>>> this. Then
>>> I'm a bit curious what it'll be happened.
>>
>> This was already partitioned under (x86) Linux, and when I plug it into
>
> I means you should partition the disk on the PPC Linux, not x86. As you know x86
> work with LE for Linux, but PPC with BE. So I think you should partition that on
> the same type machine. Can you try it?
>
>> my laptop it sees the MBR (but also on target, in U-boot, the mmc part 0
>> command shows the correct partition table). And this does not explain
>
> I didn't check this implemented codes within u-boot. Maybe u-boot can do
> something to swap MMC ending problem. You can try to get the conclusion. Firstly
> you can re-partition that on PPC Linux then check if u-boot can identify it
> properly. I guess u-boot still can read that successfully.
>
Unfortunately two wrongs don't make a right here. When I fdisk it on
target, then on target the partition gets detected, in u-boot it fails
(Unknown partition table). To be honest this was already the behavior
which I expected because the endianness swap was also seen for the card
registers. So I think something more fundamental is wrong (which in turn
smells like the "BIG_ENDIAN_32BIT_BYTE_SWAPPER" but this is used in a
very convincing way by the fsl-esdh driver...
>
>> why the card registers (such as the scr pasted below) also seem to have
>> their endianess swapped, which will result in other side-effects, such
>> as improper reading of card capabilities.
>>
>>>
>>>> hexdump of the MBR, I see the endianness is swapped (last 4 bytes are aa
>>>> 55 00 00). Also when I try to obtain the card registers they show the
>>>> same behavior:
>>>> # cat ./devices/soc.0/ff72e000.sdhci/mmc_host/mmc0/mmc0:0001/scr
>>>> 0000b50200000000
>>>>
>>>> While for comparison the same value on my (x86) laptop gives:
>>>> edb@lapedb:/sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.2/mmc_host/mmc0/mmc0:0001$
>>>>
>>>> cat scr
>>>> 02b5000000000000
>>>>
>>>> In my config I have the following set:
>>>> CONFIG_MMC_SDHCI=y
>>>> CONFIG_MMC_SDHCI_IO_ACCESSORS=y
>>>> CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER=y
>>>> # CONFIG_MMC_SDHCI_PCI is not set
>>>> CONFIG_MMC_SDHCI_OF=y
>>>> CONFIG_MMC_SDHCI_OF_ESDHC=y
>>>
>>> At least looks the config is fine.
>>>
>>> Tiejun
>>>
>>
>>
>
--
Elie De Brauwer
^ permalink raw reply
* Re: fsl-esdhc on P2020 weird endianess behavior
From: tiejun.chen @ 2011-01-24 9:28 UTC (permalink / raw)
To: Elie De Brauwer; +Cc: linuxppc-dev
In-Reply-To: <4D3D407D.4080800@gmail.com>
Elie De Brauwer wrote:
> On 01/24/11 09:15, tiejun.chen wrote:
>> Elie De Brauwer wrote:
>>> On 01/24/11 04:26, tiejun.chen wrote:
>>>> Elie De Brauwer wrote:
>>>>> Hello list,
>>>>>
>>>>> I have a P2020 processor on a custom board which uses the embedded
>>>>> fsl-esdhc controller. Hardware-wise this is functional and in u-boot
>>>>> everything seems to behave (mmc part 0 gives the correct partition
>>>>> table
>>>>> and ext2ls/fatls are capable of reading the contents of the sd card).
>>>>>
>>>>> However as soon as I start Linux (2.6.36), I get all sorts of unwanted
>>>>> behavior. Linux is unable to detect the partition layout (but if I
>>>>> do a
>>>>
>>>> Can you re-partition that under Linux? i.e, you can use fdisk to do
>>>> this. Then
>>>> I'm a bit curious what it'll be happened.
>>>
>>> This was already partitioned under (x86) Linux, and when I plug it into
>>
>> I means you should partition the disk on the PPC Linux, not x86. As
>> you know x86
>> work with LE for Linux, but PPC with BE. So I think you should
>> partition that on
>> the same type machine. Can you try it?
>>
>>> my laptop it sees the MBR (but also on target, in U-boot, the mmc part 0
>>> command shows the correct partition table). And this does not explain
>>
>> I didn't check this implemented codes within u-boot. Maybe u-boot can do
>> something to swap MMC ending problem. You can try to get the
>> conclusion. Firstly
>> you can re-partition that on PPC Linux then check if u-boot can
>> identify it
>> properly. I guess u-boot still can read that successfully.
>>
>
> Unfortunately two wrongs don't make a right here. When I fdisk it on
> target, then on target the partition gets detected, in u-boot it fails
> (Unknown partition table). To be honest this was already the behavior
> which I expected because the endianness swap was also seen for the card
> registers. So I think something more fundamental is wrong (which in turn
> smells like the "BIG_ENDIAN_32BIT_BYTE_SWAPPER" but this is used in a
> very convincing way by the fsl-esdh driver...
As you said looks you can disable 'MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER' from
the Kconfig to rebuild Linux since its unnecessary for your target.
Tiejun
>
>>
>>> why the card registers (such as the scr pasted below) also seem to have
>>> their endianess swapped, which will result in other side-effects, such
>>> as improper reading of card capabilities.
>>>
>>>>
>>>>> hexdump of the MBR, I see the endianness is swapped (last 4 bytes
>>>>> are aa
>>>>> 55 00 00). Also when I try to obtain the card registers they show the
>>>>> same behavior:
>>>>> # cat ./devices/soc.0/ff72e000.sdhci/mmc_host/mmc0/mmc0:0001/scr
>>>>> 0000b50200000000
>>>>>
>>>>> While for comparison the same value on my (x86) laptop gives:
>>>>> edb@lapedb:/sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.2/mmc_host/mmc0/mmc0:0001$
>>>>>
>>>>>
>>>>> cat scr
>>>>> 02b5000000000000
>>>>>
>>>>> In my config I have the following set:
>>>>> CONFIG_MMC_SDHCI=y
>>>>> CONFIG_MMC_SDHCI_IO_ACCESSORS=y
>>>>> CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER=y
>>>>> # CONFIG_MMC_SDHCI_PCI is not set
>>>>> CONFIG_MMC_SDHCI_OF=y
>>>>> CONFIG_MMC_SDHCI_OF_ESDHC=y
>>>>
>>>> At least looks the config is fine.
>>>>
>>>> Tiejun
>>>>
>>>
>>>
>>
>
>
^ permalink raw reply
* Re: fsl-esdhc on P2020 weird endianess behavior
From: Elie De Brauwer @ 2011-01-24 9:36 UTC (permalink / raw)
To: linuxppc-dev; +Cc: tiejun.chen
In-Reply-To: <4D3D4652.6030403@windriver.com>
On 01/24/11 10:28, tiejun.chen wrote:
> Elie De Brauwer wrote:
>> On 01/24/11 09:15, tiejun.chen wrote:
>>> Elie De Brauwer wrote:
>>>> On 01/24/11 04:26, tiejun.chen wrote:
>>>>> Elie De Brauwer wrote:
>>>>>> Hello list,
>>>>>>
>>>>>> I have a P2020 processor on a custom board which uses the embedded
>>>>>> fsl-esdhc controller. Hardware-wise this is functional and in u-boot
>>>>>> everything seems to behave (mmc part 0 gives the correct partition
>>>>>> table
>>>>>> and ext2ls/fatls are capable of reading the contents of the sd card).
>>>>>>
>>>>>> However as soon as I start Linux (2.6.36), I get all sorts of unwanted
>>>>>> behavior. Linux is unable to detect the partition layout (but if I
>>>>>> do a
>>>>>
>>>>> Can you re-partition that under Linux? i.e, you can use fdisk to do
>>>>> this. Then
>>>>> I'm a bit curious what it'll be happened.
>>>>
>>>> This was already partitioned under (x86) Linux, and when I plug it into
>>>
>>> I means you should partition the disk on the PPC Linux, not x86. As
>>> you know x86
>>> work with LE for Linux, but PPC with BE. So I think you should
>>> partition that on
>>> the same type machine. Can you try it?
>>>
>>>> my laptop it sees the MBR (but also on target, in U-boot, the mmc part 0
>>>> command shows the correct partition table). And this does not explain
>>>
>>> I didn't check this implemented codes within u-boot. Maybe u-boot can do
>>> something to swap MMC ending problem. You can try to get the
>>> conclusion. Firstly
>>> you can re-partition that on PPC Linux then check if u-boot can
>>> identify it
>>> properly. I guess u-boot still can read that successfully.
>>>
>>
>> Unfortunately two wrongs don't make a right here. When I fdisk it on
>> target, then on target the partition gets detected, in u-boot it fails
>> (Unknown partition table). To be honest this was already the behavior
>> which I expected because the endianness swap was also seen for the card
>> registers. So I think something more fundamental is wrong (which in turn
>> smells like the "BIG_ENDIAN_32BIT_BYTE_SWAPPER" but this is used in a
>> very convincing way by the fsl-esdh driver...
>
> As you said looks you can disable 'MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER' from
> the Kconfig to rebuild Linux since its unnecessary for your target.
>
Well no, since this gets selected by the fsl-esdhc driver
config MMC_SDHCI_OF_ESDHC
bool "SDHCI OF support for the Freescale eSDHC controller"
depends on MMC_SDHCI_OF
select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
help
This selects the Freescale eSDHC controller support.
If unsure, say N.
And if you look in the sdhc-of.esdhc.c
(http://lxr.linux.no/#linux+v2.6.37/drivers/mmc/host/sdhci-of-esdhc.c#L75 )
you can see that this driver is very stubborn in using the sdhci_be32bs*
variants, so it just won't compile without the BYTE_SWAPPER set. But the
entire sdhci_esdhc struct looks odd (for example they do byteswapping
for the read_b but nog for the write_b, and it gets only done for the
{read|write}_l. I'll try using the 'regular' callbacks here instead of
the byteswapped versions.
> Tiejun
>
>>
>>>
>>>> why the card registers (such as the scr pasted below) also seem to have
>>>> their endianess swapped, which will result in other side-effects, such
>>>> as improper reading of card capabilities.
>>>>
>>>>>
>>>>>> hexdump of the MBR, I see the endianness is swapped (last 4 bytes
>>>>>> are aa
>>>>>> 55 00 00). Also when I try to obtain the card registers they show the
>>>>>> same behavior:
>>>>>> # cat ./devices/soc.0/ff72e000.sdhci/mmc_host/mmc0/mmc0:0001/scr
>>>>>> 0000b50200000000
>>>>>>
>>>>>> While for comparison the same value on my (x86) laptop gives:
>>>>>> edb@lapedb:/sys/devices/pci0000:00/0000:00:1e.0/0000:15:00.2/mmc_host/mmc0/mmc0:0001$
>>>>>>
>>>>>>
>>>>>> cat scr
>>>>>> 02b5000000000000
>>>>>>
>>>>>> In my config I have the following set:
>>>>>> CONFIG_MMC_SDHCI=y
>>>>>> CONFIG_MMC_SDHCI_IO_ACCESSORS=y
>>>>>> CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER=y
>>>>>> # CONFIG_MMC_SDHCI_PCI is not set
>>>>>> CONFIG_MMC_SDHCI_OF=y
>>>>>> CONFIG_MMC_SDHCI_OF_ESDHC=y
>>>>>
>>>>> At least looks the config is fine.
>>>>>
>>>>> Tiejun
>>>>>
>>>>
>>>>
>>>
>>
>>
>
--
Elie De Brauwer
^ permalink raw reply
* [PATCH 1/4 v4] video, sm501: add I/O functions for use on powerpc
From: Heiko Schocher @ 2011-01-24 9:57 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 read/write functions for using this driver
also on powerpc plattforms
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
- use ioread/write32{be} accessors instead of
__do_readl/__do_writel{_be}
- edid support patch
./scripts/checkpatch.pl 0001-video-sm501-add-I-O-functions-for-use-on-powerpc.patch
total: 0 errors, 0 warnings, 841 lines checked
0001-video-sm501-add-I-O-functions-for-use-on-powerpc.patch has no obvious style problems and is ready for submission.
drivers/mfd/sm501.c | 125 +++++++++++++++++-----------------
drivers/video/sm501fb.c | 172 ++++++++++++++++++++++++----------------------
include/linux/sm501.h | 8 ++
3 files changed, 161 insertions(+), 144 deletions(-)
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index 5de3a76..558d5f3 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -133,10 +133,10 @@ static unsigned long decode_div(unsigned long pll2, unsigned long val,
static void sm501_dump_clk(struct sm501_devdata *sm)
{
- unsigned long misct = readl(sm->regs + SM501_MISC_TIMING);
- unsigned long pm0 = readl(sm->regs + SM501_POWER_MODE_0_CLOCK);
- unsigned long pm1 = readl(sm->regs + SM501_POWER_MODE_1_CLOCK);
- unsigned long pmc = readl(sm->regs + SM501_POWER_MODE_CONTROL);
+ unsigned long misct = smc501_readl(sm->regs + SM501_MISC_TIMING);
+ unsigned long pm0 = smc501_readl(sm->regs + SM501_POWER_MODE_0_CLOCK);
+ unsigned long pm1 = smc501_readl(sm->regs + SM501_POWER_MODE_1_CLOCK);
+ unsigned long pmc = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
unsigned long sdclk0, sdclk1;
unsigned long pll2 = 0;
@@ -193,29 +193,29 @@ static void sm501_dump_regs(struct sm501_devdata *sm)
void __iomem *regs = sm->regs;
dev_info(sm->dev, "System Control %08x\n",
- readl(regs + SM501_SYSTEM_CONTROL));
+ smc501_readl(regs + SM501_SYSTEM_CONTROL));
dev_info(sm->dev, "Misc Control %08x\n",
- readl(regs + SM501_MISC_CONTROL));
+ smc501_readl(regs + SM501_MISC_CONTROL));
dev_info(sm->dev, "GPIO Control Low %08x\n",
- readl(regs + SM501_GPIO31_0_CONTROL));
+ smc501_readl(regs + SM501_GPIO31_0_CONTROL));
dev_info(sm->dev, "GPIO Control Hi %08x\n",
- readl(regs + SM501_GPIO63_32_CONTROL));
+ smc501_readl(regs + SM501_GPIO63_32_CONTROL));
dev_info(sm->dev, "DRAM Control %08x\n",
- readl(regs + SM501_DRAM_CONTROL));
+ smc501_readl(regs + SM501_DRAM_CONTROL));
dev_info(sm->dev, "Arbitration Ctrl %08x\n",
- readl(regs + SM501_ARBTRTN_CONTROL));
+ smc501_readl(regs + SM501_ARBTRTN_CONTROL));
dev_info(sm->dev, "Misc Timing %08x\n",
- readl(regs + SM501_MISC_TIMING));
+ smc501_readl(regs + SM501_MISC_TIMING));
}
static void sm501_dump_gate(struct sm501_devdata *sm)
{
dev_info(sm->dev, "CurrentGate %08x\n",
- readl(sm->regs + SM501_CURRENT_GATE));
+ smc501_readl(sm->regs + SM501_CURRENT_GATE));
dev_info(sm->dev, "CurrentClock %08x\n",
- readl(sm->regs + SM501_CURRENT_CLOCK));
+ smc501_readl(sm->regs + SM501_CURRENT_CLOCK));
dev_info(sm->dev, "PowerModeControl %08x\n",
- readl(sm->regs + SM501_POWER_MODE_CONTROL));
+ smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL));
}
#else
@@ -231,7 +231,7 @@ static inline void sm501_dump_clk(struct sm501_devdata *sm) { }
static void sm501_sync_regs(struct sm501_devdata *sm)
{
- readl(sm->regs);
+ smc501_readl(sm->regs);
}
static inline void sm501_mdelay(struct sm501_devdata *sm, unsigned int delay)
@@ -261,11 +261,11 @@ int sm501_misc_control(struct device *dev,
spin_lock_irqsave(&sm->reg_lock, save);
- misc = readl(sm->regs + SM501_MISC_CONTROL);
+ misc = smc501_readl(sm->regs + SM501_MISC_CONTROL);
to = (misc & ~clear) | set;
if (to != misc) {
- writel(to, sm->regs + SM501_MISC_CONTROL);
+ smc501_writel(to, sm->regs + SM501_MISC_CONTROL);
sm501_sync_regs(sm);
dev_dbg(sm->dev, "MISC_CONTROL %08lx\n", misc);
@@ -294,11 +294,11 @@ unsigned long sm501_modify_reg(struct device *dev,
spin_lock_irqsave(&sm->reg_lock, save);
- data = readl(sm->regs + reg);
+ data = smc501_readl(sm->regs + reg);
data |= set;
data &= ~clear;
- writel(data, sm->regs + reg);
+ smc501_writel(data, sm->regs + reg);
sm501_sync_regs(sm);
spin_unlock_irqrestore(&sm->reg_lock, save);
@@ -322,9 +322,9 @@ int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to)
mutex_lock(&sm->clock_lock);
- mode = readl(sm->regs + SM501_POWER_MODE_CONTROL);
- gate = readl(sm->regs + SM501_CURRENT_GATE);
- clock = readl(sm->regs + SM501_CURRENT_CLOCK);
+ mode = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
+ gate = smc501_readl(sm->regs + SM501_CURRENT_GATE);
+ clock = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
mode &= 3; /* get current power mode */
@@ -356,14 +356,14 @@ int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to)
switch (mode) {
case 1:
- writel(gate, sm->regs + SM501_POWER_MODE_0_GATE);
- writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK);
+ smc501_writel(gate, sm->regs + SM501_POWER_MODE_0_GATE);
+ smc501_writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK);
mode = 0;
break;
case 2:
case 0:
- writel(gate, sm->regs + SM501_POWER_MODE_1_GATE);
- writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK);
+ smc501_writel(gate, sm->regs + SM501_POWER_MODE_1_GATE);
+ smc501_writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK);
mode = 1;
break;
@@ -372,7 +372,7 @@ int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to)
goto already;
}
- writel(mode, sm->regs + SM501_POWER_MODE_CONTROL);
+ smc501_writel(mode, sm->regs + SM501_POWER_MODE_CONTROL);
sm501_sync_regs(sm);
dev_dbg(sm->dev, "gate %08lx, clock %08lx, mode %08lx\n",
@@ -519,9 +519,9 @@ unsigned long sm501_set_clock(struct device *dev,
unsigned long req_freq)
{
struct sm501_devdata *sm = dev_get_drvdata(dev);
- unsigned long mode = readl(sm->regs + SM501_POWER_MODE_CONTROL);
- unsigned long gate = readl(sm->regs + SM501_CURRENT_GATE);
- unsigned long clock = readl(sm->regs + SM501_CURRENT_CLOCK);
+ unsigned long mode = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
+ unsigned long gate = smc501_readl(sm->regs + SM501_CURRENT_GATE);
+ unsigned long clock = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
unsigned char reg;
unsigned int pll_reg = 0;
unsigned long sm501_freq; /* the actual frequency achieved */
@@ -592,9 +592,9 @@ unsigned long sm501_set_clock(struct device *dev,
mutex_lock(&sm->clock_lock);
- mode = readl(sm->regs + SM501_POWER_MODE_CONTROL);
- gate = readl(sm->regs + SM501_CURRENT_GATE);
- clock = readl(sm->regs + SM501_CURRENT_CLOCK);
+ mode = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
+ gate = smc501_readl(sm->regs + SM501_CURRENT_GATE);
+ clock = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
clock = clock & ~(0xFF << clksrc);
clock |= reg<<clksrc;
@@ -603,14 +603,14 @@ unsigned long sm501_set_clock(struct device *dev,
switch (mode) {
case 1:
- writel(gate, sm->regs + SM501_POWER_MODE_0_GATE);
- writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK);
+ smc501_writel(gate, sm->regs + SM501_POWER_MODE_0_GATE);
+ smc501_writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK);
mode = 0;
break;
case 2:
case 0:
- writel(gate, sm->regs + SM501_POWER_MODE_1_GATE);
- writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK);
+ smc501_writel(gate, sm->regs + SM501_POWER_MODE_1_GATE);
+ smc501_writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK);
mode = 1;
break;
@@ -619,10 +619,11 @@ unsigned long sm501_set_clock(struct device *dev,
return -1;
}
- writel(mode, sm->regs + SM501_POWER_MODE_CONTROL);
+ smc501_writel(mode, sm->regs + SM501_POWER_MODE_CONTROL);
if (pll_reg)
- writel(pll_reg, sm->regs + SM501_PROGRAMMABLE_PLL_CONTROL);
+ smc501_writel(pll_reg,
+ sm->regs + SM501_PROGRAMMABLE_PLL_CONTROL);
sm501_sync_regs(sm);
@@ -902,7 +903,7 @@ static int sm501_gpio_get(struct gpio_chip *chip, unsigned offset)
struct sm501_gpio_chip *smgpio = to_sm501_gpio(chip);
unsigned long result;
- result = readl(smgpio->regbase + SM501_GPIO_DATA_LOW);
+ result = smc501_readl(smgpio->regbase + SM501_GPIO_DATA_LOW);
result >>= offset;
return result & 1UL;
@@ -915,13 +916,13 @@ static void sm501_gpio_ensure_gpio(struct sm501_gpio_chip *smchip,
/* check and modify if this pin is not set as gpio. */
- if (readl(smchip->control) & bit) {
+ if (smc501_readl(smchip->control) & bit) {
dev_info(sm501_gpio_to_dev(smchip->ourgpio)->dev,
"changing mode of gpio, bit %08lx\n", bit);
- ctrl = readl(smchip->control);
+ ctrl = smc501_readl(smchip->control);
ctrl &= ~bit;
- writel(ctrl, smchip->control);
+ smc501_writel(ctrl, smchip->control);
sm501_sync_regs(sm501_gpio_to_dev(smchip->ourgpio));
}
@@ -942,10 +943,10 @@ static void sm501_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
spin_lock_irqsave(&smgpio->lock, save);
- val = readl(regs + SM501_GPIO_DATA_LOW) & ~bit;
+ val = smc501_readl(regs + SM501_GPIO_DATA_LOW) & ~bit;
if (value)
val |= bit;
- writel(val, regs);
+ smc501_writel(val, regs);
sm501_sync_regs(sm501_gpio_to_dev(smgpio));
sm501_gpio_ensure_gpio(smchip, bit);
@@ -967,8 +968,8 @@ static int sm501_gpio_input(struct gpio_chip *chip, unsigned offset)
spin_lock_irqsave(&smgpio->lock, save);
- ddr = readl(regs + SM501_GPIO_DDR_LOW);
- writel(ddr & ~bit, regs + SM501_GPIO_DDR_LOW);
+ ddr = smc501_readl(regs + SM501_GPIO_DDR_LOW);
+ smc501_writel(ddr & ~bit, regs + SM501_GPIO_DDR_LOW);
sm501_sync_regs(sm501_gpio_to_dev(smgpio));
sm501_gpio_ensure_gpio(smchip, bit);
@@ -994,18 +995,18 @@ static int sm501_gpio_output(struct gpio_chip *chip,
spin_lock_irqsave(&smgpio->lock, save);
- val = readl(regs + SM501_GPIO_DATA_LOW);
+ val = smc501_readl(regs + SM501_GPIO_DATA_LOW);
if (value)
val |= bit;
else
val &= ~bit;
- writel(val, regs);
+ smc501_writel(val, regs);
- ddr = readl(regs + SM501_GPIO_DDR_LOW);
- writel(ddr | bit, regs + SM501_GPIO_DDR_LOW);
+ ddr = smc501_readl(regs + SM501_GPIO_DDR_LOW);
+ smc501_writel(ddr | bit, regs + SM501_GPIO_DDR_LOW);
sm501_sync_regs(sm501_gpio_to_dev(smgpio));
- writel(val, regs + SM501_GPIO_DATA_LOW);
+ smc501_writel(val, regs + SM501_GPIO_DATA_LOW);
sm501_sync_regs(sm501_gpio_to_dev(smgpio));
spin_unlock_irqrestore(&smgpio->lock, save);
@@ -1231,7 +1232,7 @@ static ssize_t sm501_dbg_regs(struct device *dev,
for (reg = 0x00; reg < 0x70; reg += 4) {
ret = sprintf(ptr, "%08x = %08x\n",
- reg, readl(sm->regs + reg));
+ reg, smc501_readl(sm->regs + reg));
ptr += ret;
}
@@ -1255,10 +1256,10 @@ static inline void sm501_init_reg(struct sm501_devdata *sm,
{
unsigned long tmp;
- tmp = readl(sm->regs + reg);
+ tmp = smc501_readl(sm->regs + reg);
tmp &= ~r->mask;
tmp |= r->set;
- writel(tmp, sm->regs + reg);
+ smc501_writel(tmp, sm->regs + reg);
}
/* sm501_init_regs
@@ -1299,7 +1300,7 @@ static void sm501_init_regs(struct sm501_devdata *sm,
static int sm501_check_clocks(struct sm501_devdata *sm)
{
- unsigned long pwrmode = readl(sm->regs + SM501_CURRENT_CLOCK);
+ unsigned long pwrmode = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
unsigned long msrc = (pwrmode & SM501_POWERMODE_M_SRC);
unsigned long m1src = (pwrmode & SM501_POWERMODE_M1_SRC);
@@ -1334,7 +1335,7 @@ static int __devinit sm501_init_dev(struct sm501_devdata *sm)
INIT_LIST_HEAD(&sm->devices);
- devid = readl(sm->regs + SM501_DEVICEID);
+ devid = smc501_readl(sm->regs + SM501_DEVICEID);
if ((devid & SM501_DEVICEID_IDMASK) != SM501_DEVICEID_SM501) {
dev_err(sm->dev, "incorrect device id %08lx\n", devid);
@@ -1342,9 +1343,9 @@ static int __devinit sm501_init_dev(struct sm501_devdata *sm)
}
/* disable irqs */
- writel(0, sm->regs + SM501_IRQ_MASK);
+ smc501_writel(0, sm->regs + SM501_IRQ_MASK);
- dramctrl = readl(sm->regs + SM501_DRAM_CONTROL);
+ dramctrl = smc501_readl(sm->regs + SM501_DRAM_CONTROL);
mem_avail = sm501_mem_local[(dramctrl >> 13) & 0x7];
dev_info(sm->dev, "SM501 At %p: Version %08lx, %ld Mb, IRQ %d\n",
@@ -1489,7 +1490,7 @@ static int sm501_plat_suspend(struct platform_device *pdev, pm_message_t state)
struct sm501_devdata *sm = platform_get_drvdata(pdev);
sm->in_suspend = 1;
- sm->pm_misc = readl(sm->regs + SM501_MISC_CONTROL);
+ sm->pm_misc = smc501_readl(sm->regs + SM501_MISC_CONTROL);
sm501_dump_regs(sm);
@@ -1513,9 +1514,9 @@ static int sm501_plat_resume(struct platform_device *pdev)
/* check to see if we are in the same state as when suspended */
- if (readl(sm->regs + SM501_MISC_CONTROL) != sm->pm_misc) {
+ if (smc501_readl(sm->regs + SM501_MISC_CONTROL) != sm->pm_misc) {
dev_info(sm->dev, "SM501_MISC_CONTROL changed over sleep\n");
- writel(sm->pm_misc, sm->regs + SM501_MISC_CONTROL);
+ smc501_writel(sm->pm_misc, sm->regs + SM501_MISC_CONTROL);
/* our suspend causes the controller state to change,
* either by something attempting setup, power loss,
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index b7dc180..c5b4b95 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -117,7 +117,7 @@ static inline int v_total(struct fb_var_screeninfo *var)
static inline void sm501fb_sync_regs(struct sm501fb_info *info)
{
- readl(info->regs);
+ smc501_readl(info->regs);
}
/* sm501_alloc_mem
@@ -262,7 +262,7 @@ static void sm501fb_setup_gamma(struct sm501fb_info *fbi,
/* set gamma values */
for (offset = 0; offset < 256 * 4; offset += 4) {
- writel(value, fbi->regs + palette + offset);
+ smc501_writel(value, fbi->regs + palette + offset);
value += 0x010101; /* Advance RGB by 1,1,1.*/
}
}
@@ -476,7 +476,8 @@ static int sm501fb_set_par_common(struct fb_info *info,
/* set start of framebuffer to the screen */
- writel(par->screen.sm_addr | SM501_ADDR_FLIP, fbi->regs + head_addr);
+ smc501_writel(par->screen.sm_addr | SM501_ADDR_FLIP,
+ fbi->regs + head_addr);
/* program CRT clock */
@@ -519,7 +520,7 @@ static void sm501fb_set_par_geometry(struct fb_info *info,
reg = info->fix.line_length;
reg |= ((var->xres * var->bits_per_pixel)/8) << 16;
- writel(reg, fbi->regs + (par->head == HEAD_CRT ?
+ smc501_writel(reg, fbi->regs + (par->head == HEAD_CRT ?
SM501_DC_CRT_FB_OFFSET : SM501_DC_PANEL_FB_OFFSET));
/* program horizontal total */
@@ -527,27 +528,27 @@ static void sm501fb_set_par_geometry(struct fb_info *info,
reg = (h_total(var) - 1) << 16;
reg |= (var->xres - 1);
- writel(reg, base + SM501_OFF_DC_H_TOT);
+ smc501_writel(reg, base + SM501_OFF_DC_H_TOT);
/* program horizontal sync */
reg = var->hsync_len << 16;
reg |= var->xres + var->right_margin - 1;
- writel(reg, base + SM501_OFF_DC_H_SYNC);
+ smc501_writel(reg, base + SM501_OFF_DC_H_SYNC);
/* program vertical total */
reg = (v_total(var) - 1) << 16;
reg |= (var->yres - 1);
- writel(reg, base + SM501_OFF_DC_V_TOT);
+ smc501_writel(reg, base + SM501_OFF_DC_V_TOT);
/* program vertical sync */
reg = var->vsync_len << 16;
reg |= var->yres + var->lower_margin - 1;
- writel(reg, base + SM501_OFF_DC_V_SYNC);
+ smc501_writel(reg, base + SM501_OFF_DC_V_SYNC);
}
/* sm501fb_pan_crt
@@ -566,15 +567,15 @@ static int sm501fb_pan_crt(struct fb_var_screeninfo *var,
xoffs = var->xoffset * bytes_pixel;
- reg = readl(fbi->regs + SM501_DC_CRT_CONTROL);
+ reg = smc501_readl(fbi->regs + SM501_DC_CRT_CONTROL);
reg &= ~SM501_DC_CRT_CONTROL_PIXEL_MASK;
reg |= ((xoffs & 15) / bytes_pixel) << 4;
- writel(reg, fbi->regs + SM501_DC_CRT_CONTROL);
+ smc501_writel(reg, fbi->regs + SM501_DC_CRT_CONTROL);
reg = (par->screen.sm_addr + xoffs +
var->yoffset * info->fix.line_length);
- writel(reg | SM501_ADDR_FLIP, fbi->regs + SM501_DC_CRT_FB_ADDR);
+ smc501_writel(reg | SM501_ADDR_FLIP, fbi->regs + SM501_DC_CRT_FB_ADDR);
sm501fb_sync_regs(fbi);
return 0;
@@ -593,10 +594,10 @@ static int sm501fb_pan_pnl(struct fb_var_screeninfo *var,
unsigned long reg;
reg = var->xoffset | (var->xres_virtual << 16);
- writel(reg, fbi->regs + SM501_DC_PANEL_FB_WIDTH);
+ smc501_writel(reg, fbi->regs + SM501_DC_PANEL_FB_WIDTH);
reg = var->yoffset | (var->yres_virtual << 16);
- writel(reg, fbi->regs + SM501_DC_PANEL_FB_HEIGHT);
+ smc501_writel(reg, fbi->regs + SM501_DC_PANEL_FB_HEIGHT);
sm501fb_sync_regs(fbi);
return 0;
@@ -622,7 +623,7 @@ static int sm501fb_set_par_crt(struct fb_info *info)
/* enable CRT DAC - note 0 is on!*/
sm501_misc_control(fbi->dev->parent, 0, SM501_MISC_DAC_POWER);
- control = readl(fbi->regs + SM501_DC_CRT_CONTROL);
+ control = smc501_readl(fbi->regs + SM501_DC_CRT_CONTROL);
control &= (SM501_DC_CRT_CONTROL_PIXEL_MASK |
SM501_DC_CRT_CONTROL_GAMMA |
@@ -684,7 +685,7 @@ static int sm501fb_set_par_crt(struct fb_info *info)
out_update:
dev_dbg(fbi->dev, "new control is %08lx\n", control);
- writel(control, fbi->regs + SM501_DC_CRT_CONTROL);
+ smc501_writel(control, fbi->regs + SM501_DC_CRT_CONTROL);
sm501fb_sync_regs(fbi);
return 0;
@@ -696,18 +697,18 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
void __iomem *ctrl_reg = fbi->regs + SM501_DC_PANEL_CONTROL;
struct sm501_platdata_fbsub *pd = fbi->pdata->fb_pnl;
- control = readl(ctrl_reg);
+ control = smc501_readl(ctrl_reg);
if (to && (control & SM501_DC_PANEL_CONTROL_VDD) == 0) {
/* enable panel power */
control |= SM501_DC_PANEL_CONTROL_VDD; /* FPVDDEN */
- writel(control, ctrl_reg);
+ smc501_writel(control, ctrl_reg);
sm501fb_sync_regs(fbi);
mdelay(10);
control |= SM501_DC_PANEL_CONTROL_DATA; /* DATA */
- writel(control, ctrl_reg);
+ smc501_writel(control, ctrl_reg);
sm501fb_sync_regs(fbi);
mdelay(10);
@@ -719,7 +720,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
else
control |= SM501_DC_PANEL_CONTROL_BIAS;
- writel(control, ctrl_reg);
+ smc501_writel(control, ctrl_reg);
sm501fb_sync_regs(fbi);
mdelay(10);
}
@@ -730,7 +731,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
else
control |= SM501_DC_PANEL_CONTROL_FPEN;
- writel(control, ctrl_reg);
+ smc501_writel(control, ctrl_reg);
sm501fb_sync_regs(fbi);
mdelay(10);
}
@@ -742,7 +743,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
else
control &= ~SM501_DC_PANEL_CONTROL_FPEN;
- writel(control, ctrl_reg);
+ smc501_writel(control, ctrl_reg);
sm501fb_sync_regs(fbi);
mdelay(10);
}
@@ -753,18 +754,18 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
else
control &= ~SM501_DC_PANEL_CONTROL_BIAS;
- writel(control, ctrl_reg);
+ smc501_writel(control, ctrl_reg);
sm501fb_sync_regs(fbi);
mdelay(10);
}
control &= ~SM501_DC_PANEL_CONTROL_DATA;
- writel(control, ctrl_reg);
+ smc501_writel(control, ctrl_reg);
sm501fb_sync_regs(fbi);
mdelay(10);
control &= ~SM501_DC_PANEL_CONTROL_VDD;
- writel(control, ctrl_reg);
+ smc501_writel(control, ctrl_reg);
sm501fb_sync_regs(fbi);
mdelay(10);
}
@@ -799,7 +800,7 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
/* update control register */
- control = readl(fbi->regs + SM501_DC_PANEL_CONTROL);
+ control = smc501_readl(fbi->regs + SM501_DC_PANEL_CONTROL);
control &= (SM501_DC_PANEL_CONTROL_GAMMA |
SM501_DC_PANEL_CONTROL_VDD |
SM501_DC_PANEL_CONTROL_DATA |
@@ -833,16 +834,16 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
BUG();
}
- writel(0x0, fbi->regs + SM501_DC_PANEL_PANNING_CONTROL);
+ smc501_writel(0x0, fbi->regs + SM501_DC_PANEL_PANNING_CONTROL);
/* panel plane top left and bottom right location */
- writel(0x00, fbi->regs + SM501_DC_PANEL_TL_LOC);
+ smc501_writel(0x00, fbi->regs + SM501_DC_PANEL_TL_LOC);
reg = var->xres - 1;
reg |= (var->yres - 1) << 16;
- writel(reg, fbi->regs + SM501_DC_PANEL_BR_LOC);
+ smc501_writel(reg, fbi->regs + SM501_DC_PANEL_BR_LOC);
/* program panel control register */
@@ -855,7 +856,7 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
if ((var->sync & FB_SYNC_VERT_HIGH_ACT) == 0)
control |= SM501_DC_PANEL_CONTROL_VSP;
- writel(control, fbi->regs + SM501_DC_PANEL_CONTROL);
+ smc501_writel(control, fbi->regs + SM501_DC_PANEL_CONTROL);
sm501fb_sync_regs(fbi);
/* ensure the panel interface is not tristated at this point */
@@ -924,7 +925,7 @@ static int sm501fb_setcolreg(unsigned regno,
val |= (green >> 8) << 8;
val |= blue >> 8;
- writel(val, base + (regno * 4));
+ smc501_writel(val, base + (regno * 4));
}
break;
@@ -980,7 +981,7 @@ static int sm501fb_blank_crt(int blank_mode, struct fb_info *info)
dev_dbg(fbi->dev, "%s(mode=%d, %p)\n", __func__, blank_mode, info);
- ctrl = readl(fbi->regs + SM501_DC_CRT_CONTROL);
+ ctrl = smc501_readl(fbi->regs + SM501_DC_CRT_CONTROL);
switch (blank_mode) {
case FB_BLANK_POWERDOWN:
@@ -1004,7 +1005,7 @@ static int sm501fb_blank_crt(int blank_mode, struct fb_info *info)
}
- writel(ctrl, fbi->regs + SM501_DC_CRT_CONTROL);
+ smc501_writel(ctrl, fbi->regs + SM501_DC_CRT_CONTROL);
sm501fb_sync_regs(fbi);
return 0;
@@ -1041,12 +1042,14 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
if (cursor->image.depth > 1)
return -EINVAL;
- hwc_addr = readl(base + SM501_OFF_HWC_ADDR);
+ hwc_addr = smc501_readl(base + SM501_OFF_HWC_ADDR);
if (cursor->enable)
- writel(hwc_addr | SM501_HWC_EN, base + SM501_OFF_HWC_ADDR);
+ smc501_writel(hwc_addr | SM501_HWC_EN,
+ base + SM501_OFF_HWC_ADDR);
else
- writel(hwc_addr & ~SM501_HWC_EN, base + SM501_OFF_HWC_ADDR);
+ smc501_writel(hwc_addr & ~SM501_HWC_EN,
+ base + SM501_OFF_HWC_ADDR);
/* set data */
if (cursor->set & FB_CUR_SETPOS) {
@@ -1060,7 +1063,7 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
//y += cursor->image.height;
- writel(x | (y << 16), base + SM501_OFF_HWC_LOC);
+ smc501_writel(x | (y << 16), base + SM501_OFF_HWC_LOC);
}
if (cursor->set & FB_CUR_SETCMAP) {
@@ -1080,8 +1083,8 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
dev_dbg(fbi->dev, "fgcol %08lx, bgcol %08lx\n", fg, bg);
- writel(bg, base + SM501_OFF_HWC_COLOR_1_2);
- writel(fg, base + SM501_OFF_HWC_COLOR_3);
+ smc501_writel(bg, base + SM501_OFF_HWC_COLOR_1_2);
+ smc501_writel(fg, base + SM501_OFF_HWC_COLOR_3);
}
if (cursor->set & FB_CUR_SETSIZE ||
@@ -1102,7 +1105,7 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
__func__, cursor->image.width, cursor->image.height);
for (op = 0; op < (64*64*2)/8; op+=4)
- writel(0x0, dst + op);
+ smc501_writel(0x0, dst + op);
for (y = 0; y < cursor->image.height; y++) {
for (x = 0; x < cursor->image.width; x++) {
@@ -1141,7 +1144,7 @@ static ssize_t sm501fb_crtsrc_show(struct device *dev,
struct sm501fb_info *info = dev_get_drvdata(dev);
unsigned long ctrl;
- ctrl = readl(info->regs + SM501_DC_CRT_CONTROL);
+ ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
ctrl &= SM501_DC_CRT_CONTROL_SEL;
return snprintf(buf, PAGE_SIZE, "%s\n", ctrl ? "crt" : "panel");
@@ -1172,7 +1175,7 @@ static ssize_t sm501fb_crtsrc_store(struct device *dev,
dev_info(dev, "setting crt source to head %d\n", head);
- ctrl = readl(info->regs + SM501_DC_CRT_CONTROL);
+ ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
if (head == HEAD_CRT) {
ctrl |= SM501_DC_CRT_CONTROL_SEL;
@@ -1184,7 +1187,7 @@ static ssize_t sm501fb_crtsrc_store(struct device *dev,
ctrl &= ~SM501_DC_CRT_CONTROL_TE;
}
- writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
+ smc501_writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
sm501fb_sync_regs(info);
return len;
@@ -1205,7 +1208,8 @@ static int sm501fb_show_regs(struct sm501fb_info *info, char *ptr,
unsigned int reg;
for (reg = start; reg < (len + start); reg += 4)
- ptr += sprintf(ptr, "%08x = %08x\n", reg, readl(mem + reg));
+ ptr += sprintf(ptr, "%08x = %08x\n", reg,
+ smc501_readl(mem + reg));
return ptr - buf;
}
@@ -1257,7 +1261,7 @@ static int sm501fb_sync(struct fb_info *info)
/* wait for the 2d engine to be ready */
while ((count > 0) &&
- (readl(fbi->regs + SM501_SYSTEM_CONTROL) &
+ (smc501_readl(fbi->regs + SM501_SYSTEM_CONTROL) &
SM501_SYSCTRL_2D_ENGINE_STATUS) != 0)
count--;
@@ -1312,45 +1316,46 @@ static void sm501fb_copyarea(struct fb_info *info, const struct fb_copyarea *are
return;
/* set the base addresses */
- writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE);
- writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_DESTINATION_BASE);
+ smc501_writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE);
+ smc501_writel(par->screen.sm_addr,
+ fbi->regs2d + SM501_2D_DESTINATION_BASE);
/* set the window width */
- writel((info->var.xres << 16) | info->var.xres,
+ smc501_writel((info->var.xres << 16) | info->var.xres,
fbi->regs2d + SM501_2D_WINDOW_WIDTH);
/* set window stride */
- writel((info->var.xres_virtual << 16) | info->var.xres_virtual,
+ smc501_writel((info->var.xres_virtual << 16) | info->var.xres_virtual,
fbi->regs2d + SM501_2D_PITCH);
/* set data format */
switch (info->var.bits_per_pixel) {
case 8:
- writel(0, fbi->regs2d + SM501_2D_STRETCH);
+ smc501_writel(0, fbi->regs2d + SM501_2D_STRETCH);
break;
case 16:
- writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH);
+ smc501_writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH);
break;
case 32:
- writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH);
+ smc501_writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH);
break;
}
/* 2d compare mask */
- writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK);
+ smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK);
/* 2d mask */
- writel(0xffffffff, fbi->regs2d + SM501_2D_MASK);
+ smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_MASK);
/* source and destination x y */
- writel((sx << 16) | sy, fbi->regs2d + SM501_2D_SOURCE);
- writel((dx << 16) | dy, fbi->regs2d + SM501_2D_DESTINATION);
+ smc501_writel((sx << 16) | sy, fbi->regs2d + SM501_2D_SOURCE);
+ smc501_writel((dx << 16) | dy, fbi->regs2d + SM501_2D_DESTINATION);
/* w/h */
- writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION);
+ smc501_writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION);
/* do area move */
- writel(0x800000cc | rtl, fbi->regs2d + SM501_2D_CONTROL);
+ smc501_writel(0x800000cc | rtl, fbi->regs2d + SM501_2D_CONTROL);
}
static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
@@ -1372,47 +1377,49 @@ static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rec
return;
/* set the base addresses */
- writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE);
- writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_DESTINATION_BASE);
+ smc501_writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE);
+ smc501_writel(par->screen.sm_addr,
+ fbi->regs2d + SM501_2D_DESTINATION_BASE);
/* set the window width */
- writel((info->var.xres << 16) | info->var.xres,
+ smc501_writel((info->var.xres << 16) | info->var.xres,
fbi->regs2d + SM501_2D_WINDOW_WIDTH);
/* set window stride */
- writel((info->var.xres_virtual << 16) | info->var.xres_virtual,
+ smc501_writel((info->var.xres_virtual << 16) | info->var.xres_virtual,
fbi->regs2d + SM501_2D_PITCH);
/* set data format */
switch (info->var.bits_per_pixel) {
case 8:
- writel(0, fbi->regs2d + SM501_2D_STRETCH);
+ smc501_writel(0, fbi->regs2d + SM501_2D_STRETCH);
break;
case 16:
- writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH);
+ smc501_writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH);
break;
case 32:
- writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH);
+ smc501_writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH);
break;
}
/* 2d compare mask */
- writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK);
+ smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK);
/* 2d mask */
- writel(0xffffffff, fbi->regs2d + SM501_2D_MASK);
+ smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_MASK);
/* colour */
- writel(rect->color, fbi->regs2d + SM501_2D_FOREGROUND);
+ smc501_writel(rect->color, fbi->regs2d + SM501_2D_FOREGROUND);
/* x y */
- writel((rect->dx << 16) | rect->dy, fbi->regs2d + SM501_2D_DESTINATION);
+ smc501_writel((rect->dx << 16) | rect->dy,
+ fbi->regs2d + SM501_2D_DESTINATION);
/* w/h */
- writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION);
+ smc501_writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION);
/* do rectangle fill */
- writel(0x800100cc, fbi->regs2d + SM501_2D_CONTROL);
+ smc501_writel(0x800100cc, fbi->regs2d + SM501_2D_CONTROL);
}
@@ -1470,11 +1477,12 @@ static int sm501_init_cursor(struct fb_info *fbi, unsigned int reg_base)
/* initialise the colour registers */
- writel(par->cursor.sm_addr, par->cursor_regs + SM501_OFF_HWC_ADDR);
+ smc501_writel(par->cursor.sm_addr,
+ par->cursor_regs + SM501_OFF_HWC_ADDR);
- writel(0x00, par->cursor_regs + SM501_OFF_HWC_LOC);
- writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_1_2);
- writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_3);
+ smc501_writel(0x00, par->cursor_regs + SM501_OFF_HWC_LOC);
+ smc501_writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_1_2);
+ smc501_writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_3);
sm501fb_sync_regs(info);
return 0;
@@ -1581,7 +1589,7 @@ static int sm501fb_start(struct sm501fb_info *info,
/* clear palette ram - undefined at power on */
for (k = 0; k < (256 * 3); k++)
- writel(0, info->regs + SM501_DC_PANEL_PALETTE + (k * 4));
+ smc501_writel(0, info->regs + SM501_DC_PANEL_PALETTE + (k * 4));
/* enable display controller */
sm501_unit_power(dev->parent, SM501_GATE_DISPLAY, 1);
@@ -1649,20 +1657,20 @@ static int sm501fb_init_fb(struct fb_info *fb,
switch (head) {
case HEAD_CRT:
pd = info->pdata->fb_crt;
- ctrl = readl(info->regs + SM501_DC_CRT_CONTROL);
+ ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
enable = (ctrl & SM501_DC_CRT_CONTROL_ENABLE) ? 1 : 0;
/* ensure we set the correct source register */
if (info->pdata->fb_route != SM501_FB_CRT_PANEL) {
ctrl |= SM501_DC_CRT_CONTROL_SEL;
- writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
+ smc501_writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
}
break;
case HEAD_PANEL:
pd = info->pdata->fb_pnl;
- ctrl = readl(info->regs + SM501_DC_PANEL_CONTROL);
+ ctrl = smc501_readl(info->regs + SM501_DC_PANEL_CONTROL);
enable = (ctrl & SM501_DC_PANEL_CONTROL_EN) ? 1 : 0;
break;
@@ -1680,7 +1688,7 @@ static int sm501fb_init_fb(struct fb_info *fb,
if (head == HEAD_CRT && info->pdata->fb_route == SM501_FB_CRT_PANEL) {
ctrl &= ~SM501_DC_CRT_CONTROL_SEL;
- writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
+ smc501_writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
enable = 0;
}
@@ -2085,7 +2093,7 @@ static int sm501fb_suspend(struct platform_device *pdev, pm_message_t state)
struct sm501fb_info *info = platform_get_drvdata(pdev);
/* store crt control to resume with */
- info->pm_crt_ctrl = readl(info->regs + SM501_DC_CRT_CONTROL);
+ info->pm_crt_ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
sm501fb_suspend_fb(info, HEAD_CRT);
sm501fb_suspend_fb(info, HEAD_PANEL);
@@ -2109,10 +2117,10 @@ static int sm501fb_resume(struct platform_device *pdev)
/* restore the items we want to be saved for crt control */
- crt_ctrl = readl(info->regs + SM501_DC_CRT_CONTROL);
+ crt_ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
crt_ctrl &= ~SM501_CRT_CTRL_SAVE;
crt_ctrl |= info->pm_crt_ctrl & SM501_CRT_CTRL_SAVE;
- writel(crt_ctrl, info->regs + SM501_DC_CRT_CONTROL);
+ smc501_writel(crt_ctrl, info->regs + SM501_DC_CRT_CONTROL);
sm501fb_resume_fb(info, HEAD_CRT);
sm501fb_resume_fb(info, HEAD_PANEL);
diff --git a/include/linux/sm501.h b/include/linux/sm501.h
index 214f932..02fde50 100644
--- a/include/linux/sm501.h
+++ b/include/linux/sm501.h
@@ -172,3 +172,11 @@ struct sm501_platdata {
struct sm501_platdata_gpio_i2c *gpio_i2c;
unsigned int gpio_i2c_nr;
};
+
+#if defined(CONFIG_PPC32)
+#define smc501_readl(addr) ioread32be((addr))
+#define smc501_writel(val, addr) iowrite32be((val), (addr))
+#else
+#define smc501_readl(addr) readl(addr)
+#define smc501_writel(val, addr) writel(val, addr)
+#endif
--
1.7.3.4
^ permalink raw reply related
* [PATCH 2/4 v4] video, sm501: add edid and commandline support
From: Heiko Schocher @ 2011-01-24 9:57 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
./scripts/checkpatch.pl 0002-video-sm501-add-edid-and-commandline-support.patch
total: 0 errors, 0 warnings, 123 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 | 67 ++++++++++++++++++++++++++++++++++++++++----
2 files changed, 71 insertions(+), 6 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..30b53ae 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;
}
}
@@ -1827,6 +1877,7 @@ static void sm501_free_init_fb(struct sm501fb_info *info,
{
struct fb_info *fbi = info->fb[head];
+ kfree(info->edid_data);
fb_dealloc_cmap(&fbi->cmap);
}
@@ -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 */
@@ -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
* [PATCH 3/4 v4] video, sm501: add OF binding to support SM501
From: Heiko Schocher @ 2011-01-24 9:57 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
./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..2ae57aa 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_PPC_MPC52xx)
+#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
* [PATCH 4/4 v4] powerpc, video: add SM501 support for charon board.
From: Heiko Schocher @ 2011-01-24 9:57 UTC (permalink / raw)
To: linuxppc-dev
Cc: linux-fbdev, devicetree-discuss, Samuel Ortiz, Vincent Sanders,
linux-kernel, Ben Dooks, 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
---
- 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
./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
* Re: BootX
From: kevin diggs @ 2011-01-24 17:51 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <AANLkTim6v25Sam+E8Bo9za1q0GJqWZitgqR0KBuKCoWz@mail.gmail.com>
Hi,
I've never done any real kernel debugging. Can anyone give any
pointers on how to do early boot debugging on an old world (buggy OF)
powermac? Can I do anything using a serial console?
A little reading last night suggested that spinlocks are supposed to
disappear for single processor machines. I do not understand why they
are present in 3.4.6 (at least the symbol anyway)? The 'acct_lock'
spin lock was also missing with gcc 4.2.4.
kevin
On Sat, Jan 22, 2011 at 12:24 PM, kevin diggs <diggskevin38@gmail.com> wrote:
> Hi,
>
> If I enable SMP then I can build a 2.6.28 kernel with gcc 4.3.5 that
> WILL boot on the PowerMac8600 (single 750GX). The previously mentioned
> G4 that runs is a dual cpu beast and thus also runs SMP.
>
> I at least know this (ok, I THINK I know):
>
> For non-SMP: The spinlock 'acct_lock' in kernel/acct.c that IS
> present in 3.4.6 (i.e. kernel 2.6.28 compiled with gcc 3.4.6). Not so
> much for 4.3.5. I have not yet done a general 4.3.5 compiled 2.6.28
> spinlock safari.
>
> Don't some funky, optimizery things happen to spinlocks for the NON-smp case?
>
> I'll see what the 4.2.x gcc does.
>
> Thanks!
>
> kevin
>
> P.S.: There is one other difference for the SMP 4.3.5 compiled
> 2.6.28: my 750gx cpufreq driver gets disabled. It is fairly isolated
> code though. Should not be able to nuke the spinlock in kernel/acct.c
>
> On Fri, Jan 21, 2011 at 1:26 PM, kevin diggs <diggskevin38@gmail.com> wrote:
>> Hi,
>>
>> Anyone familiar with BootX? Could my problems with the 8600 be related
>> to some interaction with BootX?
>>
>> kevin
>>
>
^ permalink raw reply
* FSL DMA engine transfer to PCI memory
From: Felix Radensky @ 2011-01-24 21:47 UTC (permalink / raw)
To: linuxppc-dev@ozlabs.org
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.
Felix.
^ permalink raw reply
* Re: FSL DMA engine transfer to PCI memory
From: Scott Wood @ 2011-01-24 22:44 UTC (permalink / raw)
To: Felix Radensky; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <4D3DF36A.5050609@embedded-sol.com>
On Mon, 24 Jan 2011 23:47:22 +0200
Felix Radensky <felix@embedded-sol.com> wrote:
> 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;
Why are you casting a virtual address to dma_addr_t?
> The destination address is PCI memory address returned by
> pci_ioremap_bar().
You need the physical address.
-Scott
^ permalink raw reply
* Re: FSL DMA engine transfer to PCI memory
From: Ira W. Snyder @ 2011-01-24 22:26 UTC (permalink / raw)
To: Felix Radensky; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <4D3DF36A.5050609@embedded-sol.com>
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
^ permalink raw reply
* Re: FSL DMA engine transfer to PCI memory
From: Felix Radensky @ 2011-01-24 23:39 UTC (permalink / raw)
To: Ira W. Snyder; +Cc: Scott Wood, linuxppc-dev@ozlabs.org
In-Reply-To: <20110124222641.GC26404@ovro.caltech.edu>
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 ?
Thanks.
Felix.
^ permalink raw reply
* Re: FSL DMA engine transfer to PCI memory
From: Ira W. Snyder @ 2011-01-25 0:18 UTC (permalink / raw)
To: Felix Radensky; +Cc: Scott Wood, linuxppc-dev@ozlabs.org
In-Reply-To: <4D3E0DBB.60308@embedded-sol.com>
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
^ permalink raw reply
* Re: About mpc85xx flash memory allocation
From: Mitsutaka Amano @ 2011-01-25 2:17 UTC (permalink / raw)
To: tiejun.chen; +Cc: linuxppc-dev
In-Reply-To: <4D3E3004.2040308@windriver.com>
On Tue, Jan 25, 2011 at 11:05 AM, tiejun.chen <tiejun.chen@windriver.com> w=
rote:
> 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 tight=
.
>>>>
>>>> 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 u=
se
>>> ioremap() to map the device space. And on PPC ioremap also use the same=
space as
>>> vmalloc(). While bootstrap you also can see this associated message lik=
e 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 t=
he 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 addr=
ess
> 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)
Thanks,
Mitsutaka
>
> Tiejun
>
>>
>> Thanks,
>> Mitsutaka
>>
>>> Tiejun
>>>
>>>> memory without vmalloc?
>>>>
>>>> Thanks,
>>>> Mitsutaka
>
>
^ permalink raw reply
* Re: BootX
From: kevin diggs @ 2011-01-25 4:01 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <AANLkTim6v25Sam+E8Bo9za1q0GJqWZitgqR0KBuKCoWz@mail.gmail.com>
Hi,
4.2.4 does NOT work.
4.1.2 DOES work.
Is there some magic PowerPC specific gcc patch somewhere? Should I
reorient the computer relative to the planet's magnetic field when I
compile with newer gcc? A magic handshake? what?
Is anyone using a compiler newer than 4.1.2?
Sorry, but I do not know where to go from here?
kevin
On Sat, Jan 22, 2011 at 12:24 PM, kevin diggs <diggskevin38@gmail.com> wrote:
> Hi,
>
> If I enable SMP then I can build a 2.6.28 kernel with gcc 4.3.5 that
> WILL boot on the PowerMac8600 (single 750GX). The previously mentioned
> G4 that runs is a dual cpu beast and thus also runs SMP.
>
> I at least know this (ok, I THINK I know):
>
> For non-SMP: The spinlock 'acct_lock' in kernel/acct.c that IS
> present in 3.4.6 (i.e. kernel 2.6.28 compiled with gcc 3.4.6). Not so
> much for 4.3.5. I have not yet done a general 4.3.5 compiled 2.6.28
> spinlock safari.
>
> Don't some funky, optimizery things happen to spinlocks for the NON-smp case?
>
> I'll see what the 4.2.x gcc does.
>
> Thanks!
>
> kevin
>
> P.S.: There is one other difference for the SMP 4.3.5 compiled
> 2.6.28: my 750gx cpufreq driver gets disabled. It is fairly isolated
> code though. Should not be able to nuke the spinlock in kernel/acct.c
>
> On Fri, Jan 21, 2011 at 1:26 PM, kevin diggs <diggskevin38@gmail.com> wrote:
>> Hi,
>>
>> Anyone familiar with BootX? Could my problems with the 8600 be related
>> to some interaction with BootX?
>>
>> kevin
>>
>
^ permalink raw reply
* Re: [PATCH 3/4 v4] video, sm501: add OF binding to support SM501
From: Paul Mundt @ 2011-01-25 6:38 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: <1295863058-11168-1-git-send-email-hs@denx.de>
On Mon, Jan 24, 2011 at 10:57:38AM +0100, Heiko Schocher wrote:
> - 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
>
[snip]
> diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
> index 30b53ae..2ae57aa 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_PPC_MPC52xx)
> +#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;
Missed one?
^ permalink raw reply
* [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