Question about e300 core decrementer interrupt
Dear all, I have a problem in MPC5121 sleep mode. As you know MPC5121 use e300c4 core. When I make the e300c4 core into sleep mode, it will return to full power mode when the“decrementer interrupt” occurred. But in the e300 core reference manual said that the “decrementer interrupt”have no effect when e300 core in sleep mode, because the time base and decrementer are disabled while the core is in sleep mode. Can anybody explain about this procedure ? Another question is how can I disable the“decrementer interrupt”without disable int,smi, or mcpinternal signals. Any help or suggestion would be very helpful. Thank you for your time. -- Best Regards, Li Tao ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Queries regarding I2C and GPIO driver for Freescale MPC5121e in Linux 2.6.24 of BSP: MPC512xADS_20090603-ltib.iso
Hi all, I am a newbie to the powerpc linux kernel, but I have worked on some drivers in arm architecture. I am finding powerpc architecture to be fully different than that. I am working on Freescale MPC5121e with the BSP MPC512xADS_20090603-ltib.iso running in it on the ADS512101 Rev4.1 development kit. Can anyone help me in finding some documentation for understanding and working on the powerpc kernel. Any links to the powerpc forums will also be appreciable. - Currently I am going to develop an I2C client driver for one slave microcontroller of our project. I have some knowledge in the I2C client driver making(legacy style and new style). I made a basic I2C client driver to probe for the chip address and for testing I gave it the chip address 0x68(I2C chip address of the M4T162 RTC, present on the board). But while inserting my driver I am getting failure message for the detection of my chip. So I would like to know what other formalities am I lagging in my I2C chip driver. - Also I am in a need for the GPIO driver for my controller ot get interrupt on ht estate change. When I searched in the kernel code I could not find any procedure to do that, also I could not find out the procedure to access either any GPIO pin macros or any register to remap with ioremap(). So please guide me in finding the proper way to do the GPIO accessing and interrupt registration. Will the ioremap() work on powerpc arch? If yes where can I find the memory mapping(register definitions) to use for my GPIO driver making. Thanks for patience in reading my queries. Any help is appreciable. Thanks Regards, Uma ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: AW: PowerPC PCI DMA issues (prefetch/coherency?)
Hi Prodyut, Yes, I am using the 440EPx (same as the sequoia board). Our ideDriver is DMA'ing blocks of 192-byte data over the PCI bus (using the Sil0680A PCI-IDE bridge). Most of the DMA's (depending on timing) end up being partially corrupted when we try to parse the data in the virtual page. We have confirmed the data is good before the PCI-IDE bridge. We are creating two 8K pages and map them to physical DMA memory using single-entry scatter/gather structs. When a DMA block is corrupted, we see a random portion of it (always a multiple of 16byte cache lines) is overwritten with old data from the last time the buffer was used. Regards, Adam On Thu, 2009-09-03 at 13:27 -0700, Prodyut Hazarika wrote: Hi Adam, Are you sure there is L2 cache on the 440? It depends on the SoC you are using. SoC like 460EX (Canyonlands board) have L2Cache. It seems you are using a Sequoia board, which has a 440EPx SoC. 440EPx has a 440 cpu core, but no L2Cache. Could you please tell me which SoC you are using? You can also refer to the appropriate dts file to see if there is L2C. For example, in canyonlands.dts (460EX based board), we have the L2C entry. L2C0: l2c { ... } I am seeing this problem with our custom IDE driver which is based on pretty old code. Our driver uses pci_alloc_consistent() to allocate the physical DMA memory and alloc_pages() to allocate a virtual page. It then uses pci_map_sg() to map to a scatter/gather buffer. Perhaps I should convert these to the DMA API calls as you suggest. Could you give more details on the consistency problem? It is a good idea to change to the new DMA APIs, but pci_alloc_consistent() should work too Thanks Prodyut On Thu, 2009-09-03 at 19:57 +1000, Benjamin Herrenschmidt wrote: On Thu, 2009-09-03 at 09:05 +0100, Chris Pringle wrote: Hi Adam, If you have a look in include/asm-ppc/pgtable.h for the following section: #ifdef CONFIG_44x #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_GUARDED) #else #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED) #endif Try adding _PAGE_COHERENT to the appropriate line above and see if that fixes your issue - this causes the 'M' bit to be set on the page which sure enforce cache coherency. If it doesn't, you'll need to check the 'M' bit isn't being masked out in head_44x.S (it was originally masked out on arch/powerpc, but was fixed in later kernels when the cache coherency issues with non-SMP systems were resolved). I have some doubts about the usefulness of doing that for 4xx. AFAIK, the 440 core just ignores M. The problem lies probably elsewhere. Maybe the L2 cache coherency isn't enabled or not working ? The L1 cache on 440 is simply not coherent, so drivers have to make sure they use the appropriate DMA APIs which will do cache flushing when needed. Adam, what driver is causing you that sort of problems ? Cheers, Ben. -- Adam Zilkie Software Designer, International Datacasting Corp. This message and the documents attached hereto are intended only for the addressee and may contain privileged or confidential information. Any unauthorized disclosure is strictly prohibited. If you have received this message in error, please notify us immediately so that we may correct our internal records. Please then delete the original message. Thank you. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: AW: PowerPC PCI DMA issues (prefetch/coherency?)
Hi Adam, Yes, I am using the 440EPx (same as the sequoia board). Our ideDriver is DMA'ing blocks of 192-byte data over the PCI bus (using the Sil0680A PCI-IDE bridge). Most of the DMA's (depending on timing) end up being partially corrupted when we try to parse the data in the virtual page. We have confirmed the data is good before the PCI-IDE bridge. We are creating two 8K pages and map them to physical DMA memory using single-entry scatter/gather structs. When a DMA block is corrupted, we see a random portion of it (always a multiple of 16byte cache lines) is overwritten with old data from the last time the buffer was used. This looks like a cache coherency problem. Can you ensure that the TLB entries corresponding to the DMA region has the CacheInhibit bit set. You will need a BDI connected to your system. Also, you will need to invalidate and flush the lines appropriately, since in 440 cores, L1Cache coherency is managed entirely by software. Please look at drivers/net/ibm_newemac/mal.c and core.c for example on how to do it. Thanks Prodyut On Thu, 2009-09-03 at 13:27 -0700, Prodyut Hazarika wrote: Hi Adam, Are you sure there is L2 cache on the 440? It depends on the SoC you are using. SoC like 460EX (Canyonlands board) have L2Cache. It seems you are using a Sequoia board, which has a 440EPx SoC. 440EPx has a 440 cpu core, but no L2Cache. Could you please tell me which SoC you are using? You can also refer to the appropriate dts file to see if there is L2C. For example, in canyonlands.dts (460EX based board), we have the L2C entry. L2C0: l2c { ... } I am seeing this problem with our custom IDE driver which is based on pretty old code. Our driver uses pci_alloc_consistent() to allocate the physical DMA memory and alloc_pages() to allocate a virtual page. It then uses pci_map_sg() to map to a scatter/gather buffer. Perhaps I should convert these to the DMA API calls as you suggest. Could you give more details on the consistency problem? It is a good idea to change to the new DMA APIs, but pci_alloc_consistent() should work too Thanks Prodyut On Thu, 2009-09-03 at 19:57 +1000, Benjamin Herrenschmidt wrote: On Thu, 2009-09-03 at 09:05 +0100, Chris Pringle wrote: Hi Adam, If you have a look in include/asm-ppc/pgtable.h for the following section: #ifdef CONFIG_44x #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_GUARDED) #else #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED) #endif Try adding _PAGE_COHERENT to the appropriate line above and see if that fixes your issue - this causes the 'M' bit to be set on the page which sure enforce cache coherency. If it doesn't, you'll need to check the 'M' bit isn't being masked out in head_44x.S (it was originally masked out on arch/powerpc, but was fixed in later kernels when the cache coherency issues with non-SMP systems were resolved). I have some doubts about the usefulness of doing that for 4xx. AFAIK, the 440 core just ignores M. The problem lies probably elsewhere. Maybe the L2 cache coherency isn't enabled or not working ? The L1 cache on 440 is simply not coherent, so drivers have to make sure they use the appropriate DMA APIs which will do cache flushing when needed. Adam, what driver is causing you that sort of problems ? Cheers, Ben. -- Adam Zilkie Software Designer, International Datacasting Corp. This message and the documents attached hereto are intended only for the addressee and may contain privileged or confidential information. Any unauthorized disclosure is strictly prohibited. If you have received this message in error, please notify us immediately so that we may correct our internal records. Please then delete the original message. Thank you. CONFIDENTIALITY NOTICE: This e-mail message, including any attachments, is for the sole use of the intended recipient(s) and contains information that is confidential and proprietary to AppliedMicro Corporation or its subsidiaries. It is to be used solely for the purpose of furthering the parties' business relationship. All unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply e-mail and destroy all copies of the original message. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc/85xx: Fix SMP compile error and allow NULL for smp_ops
The following commit introduced a compile error since it removed the implementation of smp_85xx_basic_setup: commit 77c0a700c1c292edafa11c1e52821ce4636f81b0 Author: Benjamin Herrenschmidt b...@kernel.crashing.org Date: Fri Aug 28 14:25:04 2009 +1000 powerpc: Properly start decrementer on BookE secondary CPUs Make it so that smp_ops probe() and setup_cpu() can be set to NULL. Signed-off-by: Kumar Gala ga...@kernel.crashing.org --- arch/powerpc/kernel/smp.c | 10 +++--- arch/powerpc/platforms/85xx/smp.c | 13 +++-- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 96f107c..d387b39 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -269,7 +269,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus) cpu_callin_map[boot_cpuid] = 1; if (smp_ops) - max_cpus = smp_ops-probe(); + if (smp_ops-probe) + max_cpus = smp_ops-probe(); + else + max_cpus = NR_CPUS; else max_cpus = 1; @@ -493,7 +496,8 @@ int __devinit start_secondary(void *unused) preempt_disable(); cpu_callin_map[cpu] = 1; - smp_ops-setup_cpu(cpu); + if (smp_ops-setup_cpu) + smp_ops-setup_cpu(cpu); if (smp_ops-take_timebase) smp_ops-take_timebase(); @@ -556,7 +560,7 @@ void __init smp_cpus_done(unsigned int max_cpus) old_mask = current-cpus_allowed; set_cpus_allowed(current, cpumask_of_cpu(boot_cpuid)); - if (smp_ops) + if (smp_ops smp_ops-setup_cpu) smp_ops-setup_cpu(boot_cpuid); set_cpus_allowed(current, old_mask); diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 94f901d..d3cf357 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -85,28 +85,21 @@ smp_85xx_setup_cpu(int cpu_nr) } struct smp_ops_t smp_85xx_ops = { + .message_pass = NULL, + .probe = NULL, .kick_cpu = smp_85xx_kick_cpu, + .setup_cpu = NULL, }; -static int __init smp_dummy_probe(void) -{ - return NR_CPUS; -} - void __init mpc85xx_smp_init(void) { struct device_node *np; - smp_85xx_ops.message_pass = NULL; - np = of_find_node_by_type(NULL, open-pic); if (np) { smp_85xx_ops.probe = smp_mpic_probe; smp_85xx_ops.setup_cpu = smp_85xx_setup_cpu; smp_85xx_ops.message_pass = smp_mpic_message_pass; - } else { - smp_85xx_ops.probe = smp_dummy_probe; - smp_85xx_ops.setup_cpu = smp_85xx_basic_setup; } if (cpu_has_feature(CPU_FTR_DBELL)) -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: AW: PowerPC PCI DMA issues (prefetch/coherency?)
We have found that using flush_dcache_range() after each DMA solves the problem. Ideally, we'd like to be able to allocate the virtual page in cache inhibited memory to avoid the performance loss from all the flush calls. To do this, we'd have to change our TLB sizes and reserve a TLB in memory as cache inhibited (using the 'I' bit). Will update if this works as well. Thanks for your help in this. Aren't you using dma_alloc_coherent to get buffers that are shared between CPU and external devices? Thanks Prodyut On Tue, 2009-09-08 at 11:59 -0700, Prodyut Hazarika wrote: Hi Adam, Yes, I am using the 440EPx (same as the sequoia board). Our ideDriver is DMA'ing blocks of 192-byte data over the PCI bus (using the Sil0680A PCI-IDE bridge). Most of the DMA's (depending on timing) end up being partially corrupted when we try to parse the data in the virtual page. We have confirmed the data is good before the PCI-IDE bridge. We are creating two 8K pages and map them to physical DMA memory using single-entry scatter/gather structs. When a DMA block is corrupted, we see a random portion of it (always a multiple of 16byte cache lines) is overwritten with old data from the last time the buffer was used. This looks like a cache coherency problem. Can you ensure that the TLB entries corresponding to the DMA region has the CacheInhibit bit set. You will need a BDI connected to your system. Also, you will need to invalidate and flush the lines appropriately, since in 440 cores, L1Cache coherency is managed entirely by software. Please look at drivers/net/ibm_newemac/mal.c and core.c for example on how to do it. Thanks Prodyut On Thu, 2009-09-03 at 13:27 -0700, Prodyut Hazarika wrote: Hi Adam, Are you sure there is L2 cache on the 440? It depends on the SoC you are using. SoC like 460EX (Canyonlands board) have L2Cache. It seems you are using a Sequoia board, which has a 440EPx SoC. 440EPx has a 440 cpu core, but no L2Cache. Could you please tell me which SoC you are using? You can also refer to the appropriate dts file to see if there is L2C. For example, in canyonlands.dts (460EX based board), we have the L2C entry. L2C0: l2c { ... } I am seeing this problem with our custom IDE driver which is based on pretty old code. Our driver uses pci_alloc_consistent() to allocate the physical DMA memory and alloc_pages() to allocate a virtual page. It then uses pci_map_sg() to map to a scatter/gather buffer. Perhaps I should convert these to the DMA API calls as you suggest. Could you give more details on the consistency problem? It is a good idea to change to the new DMA APIs, but pci_alloc_consistent() should work too Thanks Prodyut On Thu, 2009-09-03 at 19:57 +1000, Benjamin Herrenschmidt wrote: On Thu, 2009-09-03 at 09:05 +0100, Chris Pringle wrote: Hi Adam, If you have a look in include/asm-ppc/pgtable.h for the following section: #ifdef CONFIG_44x #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_GUARDED) #else #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED) #endif Try adding _PAGE_COHERENT to the appropriate line above and see if that fixes your issue - this causes the 'M' bit to be set on the page which sure enforce cache coherency. If it doesn't, you'll need to check the 'M' bit isn't being masked out in head_44x.S (it was originally masked out on arch/powerpc, but was fixed in later kernels when the cache coherency issues with non-SMP systems were resolved). I have some doubts about the usefulness of doing that for 4xx. AFAIK, the 440 core just ignores M. The problem lies probably elsewhere. Maybe the L2 cache coherency isn't enabled or not working ? The L1 cache on 440 is simply not coherent, so drivers have to make sure they use the appropriate DMA APIs which will do cache flushing when needed. Adam, what driver is causing you that sort of problems ? Cheers, Ben. -- Adam Zilkie Software Designer, International Datacasting Corp. This message and the documents attached hereto are intended only for the addressee and may contain privileged or confidential information. Any unauthorized disclosure is strictly prohibited. If you have received this message in error, please notify us immediately so that we may correct our internal records. Please then delete the original message. Thank you. CONFIDENTIALITY NOTICE: This e-mail message, including any attachments, is for the sole use of the intended recipient(s) and contains information that is confidential and proprietary to AppliedMicro Corporation or its subsidiaries. It is to be used solely for the purpose of furthering the parties' business relationship. All unauthorized
RE: AW: PowerPC PCI DMA issues (prefetch/coherency?)
On Tue, 2009-09-08 at 14:01 -0400, Adam Zilkie wrote: Hi Prodyut, Yes, I am using the 440EPx (same as the sequoia board). Our ideDriver is DMA'ing blocks of 192-byte data over the PCI bus (using the Sil0680A PCI-IDE bridge). Most of the DMA's (depending on timing) end up being partially corrupted when we try to parse the data in the virtual page. We have confirmed the data is good before the PCI-IDE bridge. We are creating two 8K pages and map them to physical DMA memory using single-entry scatter/gather structs. When a DMA block is corrupted, we see a random portion of it (always a multiple of 16byte cache lines) is overwritten with old data from the last time the buffer was used. Smells to me like you aren't properly using the dma or pci dma APIs to flush/invalidate the cache around your transfers. Ben. Regards, Adam On Thu, 2009-09-03 at 13:27 -0700, Prodyut Hazarika wrote: Hi Adam, Are you sure there is L2 cache on the 440? It depends on the SoC you are using. SoC like 460EX (Canyonlands board) have L2Cache. It seems you are using a Sequoia board, which has a 440EPx SoC. 440EPx has a 440 cpu core, but no L2Cache. Could you please tell me which SoC you are using? You can also refer to the appropriate dts file to see if there is L2C. For example, in canyonlands.dts (460EX based board), we have the L2C entry. L2C0: l2c { ... } I am seeing this problem with our custom IDE driver which is based on pretty old code. Our driver uses pci_alloc_consistent() to allocate the physical DMA memory and alloc_pages() to allocate a virtual page. It then uses pci_map_sg() to map to a scatter/gather buffer. Perhaps I should convert these to the DMA API calls as you suggest. Could you give more details on the consistency problem? It is a good idea to change to the new DMA APIs, but pci_alloc_consistent() should work too Thanks Prodyut On Thu, 2009-09-03 at 19:57 +1000, Benjamin Herrenschmidt wrote: On Thu, 2009-09-03 at 09:05 +0100, Chris Pringle wrote: Hi Adam, If you have a look in include/asm-ppc/pgtable.h for the following section: #ifdef CONFIG_44x #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_GUARDED) #else #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED) #endif Try adding _PAGE_COHERENT to the appropriate line above and see if that fixes your issue - this causes the 'M' bit to be set on the page which sure enforce cache coherency. If it doesn't, you'll need to check the 'M' bit isn't being masked out in head_44x.S (it was originally masked out on arch/powerpc, but was fixed in later kernels when the cache coherency issues with non-SMP systems were resolved). I have some doubts about the usefulness of doing that for 4xx. AFAIK, the 440 core just ignores M. The problem lies probably elsewhere. Maybe the L2 cache coherency isn't enabled or not working ? The L1 cache on 440 is simply not coherent, so drivers have to make sure they use the appropriate DMA APIs which will do cache flushing when needed. Adam, what driver is causing you that sort of problems ? Cheers, Ben. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc/85xx: Fix SMP compile error and allow NULL for smp_ops
On Tue, 2009-09-08 at 14:21 -0500, Kumar Gala wrote: struct smp_ops_t smp_85xx_ops = { + .message_pass = NULL, + .probe = NULL, .kick_cpu = smp_85xx_kick_cpu, + .setup_cpu = NULL, }; Why explicitely setting those to NULL ? Cheers, Ben. -static int __init smp_dummy_probe(void) -{ - return NR_CPUS; -} - void __init mpc85xx_smp_init(void) { struct device_node *np; - smp_85xx_ops.message_pass = NULL; - np = of_find_node_by_type(NULL, open-pic); if (np) { smp_85xx_ops.probe = smp_mpic_probe; smp_85xx_ops.setup_cpu = smp_85xx_setup_cpu; smp_85xx_ops.message_pass = smp_mpic_message_pass; - } else { - smp_85xx_ops.probe = smp_dummy_probe; - smp_85xx_ops.setup_cpu = smp_85xx_basic_setup; } if (cpu_has_feature(CPU_FTR_DBELL)) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: AW: PowerPC PCI DMA issues (prefetch/coherency?)
On Tue, 2009-09-08 at 15:30 -0400, Adam Zilkie wrote: All, We have found that using flush_dcache_range() after each DMA solves the problem. Ideally, we'd like to be able to allocate the virtual page in cache inhibited memory to avoid the performance loss from all the flush calls. To do this, we'd have to change our TLB sizes and reserve a TLB in memory as cache inhibited (using the 'I' bit). Will update if this works as well. Thanks for your help in this. I think the problem is that you are manipulating the TLB directly, which you shouldn't have to do. You also shouldn't have to use flush_dcache_range() yourself neither. It should all be handled by the DMA and PCI DMA APIs, you are just not using those correctly. You have two choice. You can either allocate memory permanently mapped with I=1, in which case, use pci_alloc_consistent() (or dma_alloc_coherent(), same thing). Or you can use normal memory and ensure you flush/invalidate the cache at the right time, which you can do with something like pci_map_sg/pci_unmap_sg (or dma_* variants) or the dma_sync_* functions. It's all pretty standard mechanisms in Linux, other platforms also have non-coherent DMA (such as some ARMs) and those functions are generic. Cheers, Ben. Regards, Adam On Tue, 2009-09-08 at 11:59 -0700, Prodyut Hazarika wrote: Hi Adam, Yes, I am using the 440EPx (same as the sequoia board). Our ideDriver is DMA'ing blocks of 192-byte data over the PCI bus (using the Sil0680A PCI-IDE bridge). Most of the DMA's (depending on timing) end up being partially corrupted when we try to parse the data in the virtual page. We have confirmed the data is good before the PCI-IDE bridge. We are creating two 8K pages and map them to physical DMA memory using single-entry scatter/gather structs. When a DMA block is corrupted, we see a random portion of it (always a multiple of 16byte cache lines) is overwritten with old data from the last time the buffer was used. This looks like a cache coherency problem. Can you ensure that the TLB entries corresponding to the DMA region has the CacheInhibit bit set. You will need a BDI connected to your system. Also, you will need to invalidate and flush the lines appropriately, since in 440 cores, L1Cache coherency is managed entirely by software. Please look at drivers/net/ibm_newemac/mal.c and core.c for example on how to do it. Thanks Prodyut On Thu, 2009-09-03 at 13:27 -0700, Prodyut Hazarika wrote: Hi Adam, Are you sure there is L2 cache on the 440? It depends on the SoC you are using. SoC like 460EX (Canyonlands board) have L2Cache. It seems you are using a Sequoia board, which has a 440EPx SoC. 440EPx has a 440 cpu core, but no L2Cache. Could you please tell me which SoC you are using? You can also refer to the appropriate dts file to see if there is L2C. For example, in canyonlands.dts (460EX based board), we have the L2C entry. L2C0: l2c { ... } I am seeing this problem with our custom IDE driver which is based on pretty old code. Our driver uses pci_alloc_consistent() to allocate the physical DMA memory and alloc_pages() to allocate a virtual page. It then uses pci_map_sg() to map to a scatter/gather buffer. Perhaps I should convert these to the DMA API calls as you suggest. Could you give more details on the consistency problem? It is a good idea to change to the new DMA APIs, but pci_alloc_consistent() should work too Thanks Prodyut On Thu, 2009-09-03 at 19:57 +1000, Benjamin Herrenschmidt wrote: On Thu, 2009-09-03 at 09:05 +0100, Chris Pringle wrote: Hi Adam, If you have a look in include/asm-ppc/pgtable.h for the following section: #ifdef CONFIG_44x #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_GUARDED) #else #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED) #endif Try adding _PAGE_COHERENT to the appropriate line above and see if that fixes your issue - this causes the 'M' bit to be set on the page which sure enforce cache coherency. If it doesn't, you'll need to check the 'M' bit isn't being masked out in head_44x.S (it was originally masked out on arch/powerpc, but was fixed in later kernels when the cache coherency issues with non-SMP systems were resolved). I have some doubts about the usefulness of doing that for 4xx. AFAIK, the 440 core just ignores M. The problem lies probably elsewhere. Maybe the L2 cache coherency isn't enabled or not working ? The L1 cache on 440 is simply not coherent, so drivers have to make sure they use the appropriate DMA APIs which will do cache flushing when needed. Adam, what driver is causing you that sort of problems ? Cheers, Ben.
RE: AW: PowerPC PCI DMA issues (prefetch/coherency?)
We are using pci_alloc_consistent() Adam On Tue, 2009-09-08 at 12:56 -0700, Prodyut Hazarika wrote: We have found that using flush_dcache_range() after each DMA solves the problem. Ideally, we'd like to be able to allocate the virtual page in cache inhibited memory to avoid the performance loss from all the flush calls. To do this, we'd have to change our TLB sizes and reserve a TLB in memory as cache inhibited (using the 'I' bit). Will update if this works as well. Thanks for your help in this. Aren't you using dma_alloc_coherent to get buffers that are shared between CPU and external devices? Thanks Prodyut On Tue, 2009-09-08 at 11:59 -0700, Prodyut Hazarika wrote: Hi Adam, Yes, I am using the 440EPx (same as the sequoia board). Our ideDriver is DMA'ing blocks of 192-byte data over the PCI bus (using the Sil0680A PCI-IDE bridge). Most of the DMA's (depending on timing) end up being partially corrupted when we try to parse the data in the virtual page. We have confirmed the data is good before the PCI-IDE bridge. We are creating two 8K pages and map them to physical DMA memory using single-entry scatter/gather structs. When a DMA block is corrupted, we see a random portion of it (always a multiple of 16byte cache lines) is overwritten with old data from the last time the buffer was used. This looks like a cache coherency problem. Can you ensure that the TLB entries corresponding to the DMA region has the CacheInhibit bit set. You will need a BDI connected to your system. Also, you will need to invalidate and flush the lines appropriately, since in 440 cores, L1Cache coherency is managed entirely by software. Please look at drivers/net/ibm_newemac/mal.c and core.c for example on how to do it. Thanks Prodyut On Thu, 2009-09-03 at 13:27 -0700, Prodyut Hazarika wrote: Hi Adam, Are you sure there is L2 cache on the 440? It depends on the SoC you are using. SoC like 460EX (Canyonlands board) have L2Cache. It seems you are using a Sequoia board, which has a 440EPx SoC. 440EPx has a 440 cpu core, but no L2Cache. Could you please tell me which SoC you are using? You can also refer to the appropriate dts file to see if there is L2C. For example, in canyonlands.dts (460EX based board), we have the L2C entry. L2C0: l2c { ... } I am seeing this problem with our custom IDE driver which is based on pretty old code. Our driver uses pci_alloc_consistent() to allocate the physical DMA memory and alloc_pages() to allocate a virtual page. It then uses pci_map_sg() to map to a scatter/gather buffer. Perhaps I should convert these to the DMA API calls as you suggest. Could you give more details on the consistency problem? It is a good idea to change to the new DMA APIs, but pci_alloc_consistent() should work too Thanks Prodyut On Thu, 2009-09-03 at 19:57 +1000, Benjamin Herrenschmidt wrote: On Thu, 2009-09-03 at 09:05 +0100, Chris Pringle wrote: Hi Adam, If you have a look in include/asm-ppc/pgtable.h for the following section: #ifdef CONFIG_44x #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_GUARDED) #else #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED) #endif Try adding _PAGE_COHERENT to the appropriate line above and see if that fixes your issue - this causes the 'M' bit to be set on the page which sure enforce cache coherency. If it doesn't, you'll need to check the 'M' bit isn't being masked out in head_44x.S (it was originally masked out on arch/powerpc, but was fixed in later kernels when the cache coherency issues with non-SMP systems were resolved). I have some doubts about the usefulness of doing that for 4xx. AFAIK, the 440 core just ignores M. The problem lies probably elsewhere. Maybe the L2 cache coherency isn't enabled or not working ? The L1 cache on 440 is simply not coherent, so drivers have to make sure they use the appropriate DMA APIs which will do cache flushing when needed. Adam, what driver is causing you that sort of problems ? Cheers, Ben. -- Adam Zilkie Software Designer, International Datacasting Corp. This message and the documents attached hereto are intended only for the addressee and may contain privileged or confidential information. Any unauthorized disclosure is strictly prohibited. If you have received this message in error, please notify us immediately so that we may correct our internal records. Please then delete the original message. Thank you. CONFIDENTIALITY NOTICE: This e-mail message, including any attachments, is for the sole
RE: AW: PowerPC PCI DMA issues (prefetch/coherency?)
All, We have found that using flush_dcache_range() after each DMA solves the problem. Ideally, we'd like to be able to allocate the virtual page in cache inhibited memory to avoid the performance loss from all the flush calls. To do this, we'd have to change our TLB sizes and reserve a TLB in memory as cache inhibited (using the 'I' bit). Will update if this works as well. Thanks for your help in this. Regards, Adam On Tue, 2009-09-08 at 11:59 -0700, Prodyut Hazarika wrote: Hi Adam, Yes, I am using the 440EPx (same as the sequoia board). Our ideDriver is DMA'ing blocks of 192-byte data over the PCI bus (using the Sil0680A PCI-IDE bridge). Most of the DMA's (depending on timing) end up being partially corrupted when we try to parse the data in the virtual page. We have confirmed the data is good before the PCI-IDE bridge. We are creating two 8K pages and map them to physical DMA memory using single-entry scatter/gather structs. When a DMA block is corrupted, we see a random portion of it (always a multiple of 16byte cache lines) is overwritten with old data from the last time the buffer was used. This looks like a cache coherency problem. Can you ensure that the TLB entries corresponding to the DMA region has the CacheInhibit bit set. You will need a BDI connected to your system. Also, you will need to invalidate and flush the lines appropriately, since in 440 cores, L1Cache coherency is managed entirely by software. Please look at drivers/net/ibm_newemac/mal.c and core.c for example on how to do it. Thanks Prodyut On Thu, 2009-09-03 at 13:27 -0700, Prodyut Hazarika wrote: Hi Adam, Are you sure there is L2 cache on the 440? It depends on the SoC you are using. SoC like 460EX (Canyonlands board) have L2Cache. It seems you are using a Sequoia board, which has a 440EPx SoC. 440EPx has a 440 cpu core, but no L2Cache. Could you please tell me which SoC you are using? You can also refer to the appropriate dts file to see if there is L2C. For example, in canyonlands.dts (460EX based board), we have the L2C entry. L2C0: l2c { ... } I am seeing this problem with our custom IDE driver which is based on pretty old code. Our driver uses pci_alloc_consistent() to allocate the physical DMA memory and alloc_pages() to allocate a virtual page. It then uses pci_map_sg() to map to a scatter/gather buffer. Perhaps I should convert these to the DMA API calls as you suggest. Could you give more details on the consistency problem? It is a good idea to change to the new DMA APIs, but pci_alloc_consistent() should work too Thanks Prodyut On Thu, 2009-09-03 at 19:57 +1000, Benjamin Herrenschmidt wrote: On Thu, 2009-09-03 at 09:05 +0100, Chris Pringle wrote: Hi Adam, If you have a look in include/asm-ppc/pgtable.h for the following section: #ifdef CONFIG_44x #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_GUARDED) #else #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED) #endif Try adding _PAGE_COHERENT to the appropriate line above and see if that fixes your issue - this causes the 'M' bit to be set on the page which sure enforce cache coherency. If it doesn't, you'll need to check the 'M' bit isn't being masked out in head_44x.S (it was originally masked out on arch/powerpc, but was fixed in later kernels when the cache coherency issues with non-SMP systems were resolved). I have some doubts about the usefulness of doing that for 4xx. AFAIK, the 440 core just ignores M. The problem lies probably elsewhere. Maybe the L2 cache coherency isn't enabled or not working ? The L1 cache on 440 is simply not coherent, so drivers have to make sure they use the appropriate DMA APIs which will do cache flushing when needed. Adam, what driver is causing you that sort of problems ? Cheers, Ben. -- Adam Zilkie Software Designer, International Datacasting Corp. This message and the documents attached hereto are intended only for the addressee and may contain privileged or confidential information. Any unauthorized disclosure is strictly prohibited. If you have received this message in error, please notify us immediately so that we may correct our internal records. Please then delete the original message. Thank you. CONFIDENTIALITY NOTICE: This e-mail message, including any attachments, is for the sole use of the intended recipient(s) and contains information that is confidential and proprietary to AppliedMicro Corporation or its subsidiaries. It is to be used solely for the purpose of furthering the parties' business relationship. All unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient,
Re: [RFC] [PATCH] Write to HVC terminal from purgatory code
On Mon, Sep 07, 2009 at 10:44:07AM +0530, M. Mohan Kumar wrote: Write to HVC terminal from purgatory code Current x86/x86-64 kexec-tools print the message I'm in purgatory to serial console/VGA while executing the purgatory code. Implement this feature for POWERPC pseries platform by using the H_PUT_TERM_CHAR hypervisor call by printng to hvc console. This change seems reasonable to me, can any of the ppc people offer a review? Signed-off-by: M. Mohan Kumar mo...@in.ibm.com --- kexec/arch/ppc64/fs2dt.c | 47 +++- kexec/arch/ppc64/kexec-elf-ppc64.c |7 + kexec/arch/ppc64/kexec-ppc64.h |1 + purgatory/arch/ppc64/Makefile |1 + purgatory/arch/ppc64/console-ppc64.c | 14 + purgatory/arch/ppc64/hvCall.S | 28 +++ purgatory/arch/ppc64/hvCall.h |8 + purgatory/arch/ppc64/purgatory-ppc64.c |1 + 8 files changed, 106 insertions(+), 1 deletions(-) create mode 100644 purgatory/arch/ppc64/hvCall.S create mode 100644 purgatory/arch/ppc64/hvCall.h diff --git a/kexec/arch/ppc64/fs2dt.c b/kexec/arch/ppc64/fs2dt.c index b01ff86..bd9d36c 100644 --- a/kexec/arch/ppc64/fs2dt.c +++ b/kexec/arch/ppc64/fs2dt.c @@ -434,6 +434,9 @@ static void putnode(void) if (!strcmp(basename,/chosen/)) { size_t cmd_len = 0; char *param = NULL; + char filename[MAXPATH]; + char buff[64]; Is always 64 big enough? It seems a bit arbitrary. + int fd; cmd_len = strlen(local_cmdline); if (cmd_len != 0) { @@ -446,7 +449,6 @@ static void putnode(void) /* ... if not, grab root= from the old command line */ if (!param) { - char filename[MAXPATH]; FILE *fp; char *last_cmdline = NULL; char *old_param; @@ -483,8 +485,51 @@ static void putnode(void) dt += (cmd_len + 3)/4; fprintf(stderr, Modified cmdline:%s\n, local_cmdline); + + /* + * Determine the platform type/stdout type, so that purgatory + * code can print 'I'm in purgatory' message. Currently only + * pseries/hvcterminal is supported. + */ + strcpy(filename, pathname); + strcat(filename, linux,stdout-path); + fd = open(filename, O_RDONLY); + if (fd == -1) { + printf(Unable to find linux,stdout-path, printing + from purgatory is diabled\n); + goto no_debug; + } + if (fstat(fd, statbuf)) { + printf(Unable to stat linux,stdout-path, printing + from purgatory is diabled\n); + close(fd); + goto no_debug; + } + read(fd, buff, statbuf.st_size); + close(fd); + strcpy(filename, /proc/device-tree/); + strcat(filename, buff); + strcat(filename, /compatible); + fd = open(filename, O_RDONLY); + if (fd == -1) { + printf(Unable to find linux,stdout-path/compatible, + printing from purgatory is diabled\n); + goto no_debug; + } + if (fstat(fd, statbuf)) { + printf(Unable to stat linux,stdout-path/compatible, + printing from purgatory is diabled\n); + close(fd); + goto no_debug; + } + read(fd, buff, statbuf.st_size); + if (!strcmp(buff, hvterm1) || + !strcmp(buff, hvterm-protocol)) + my_debug = 1; + close(fd); } +no_debug: for (i=0; i numlist; i++) { dp = namelist[i]; strcpy(dn, dp-d_name); diff --git a/kexec/arch/ppc64/kexec-elf-ppc64.c b/kexec/arch/ppc64/kexec-elf-ppc64.c index 21533cb..65fc42f 100644 --- a/kexec/arch/ppc64/kexec-elf-ppc64.c +++ b/kexec/arch/ppc64/kexec-elf-ppc64.c @@ -41,6 +41,8 @@ uint64_t initrd_base, initrd_size; unsigned char reuse_initrd = 0; const char *ramdisk; +/* Used for enabling printing message from purgatory code */ +int my_debug = 0; int elf_ppc64_probe(const char *buf, off_t len) { @@ -296,6 +298,8 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len, toc_addr = my_r2(info-rhdr); elf_rel_set_symbol(info-rhdr, my_toc, toc_addr, sizeof(toc_addr)); + /* Set debug */ + elf_rel_set_symbol(info-rhdr, debug, my_debug, sizeof(my_debug)); #ifdef DEBUG my_kernel = 0;
Re: [FTRACE] Enabling function_graph causes OOPS
On Mon, 2009-08-03 at 16:10 +0530, Sachin Sant wrote: Steven Rostedt wrote: Thanks, I've seen issues with my PPC box and function graph, but the bugs were also caused by other changes. I'll boot up my PPC64 box and see if I see the same issues you have. Hi Steven, I can still recreate this issue with 2.6.31-rc5. Let me know if i can provide any information to find a solution for this. Hi Sachin, I'm going through old email, and I found this. Do you still see this error. I don't recall seeing it myself. Thanks, -- Steve ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] [SCSI] mpt fusion: Fix 32 bit platforms with 64 bit resources
From: Pravin Bathija pbath...@amcc.com Powerpc 44x uses 36 bit real address while the real address defined in MPT Fusion driver is of type 32 bit. This causes ioremap to fail and driver fails to initialize. This fix changes the data types representing the real address from unsigned long 32-bit types to phys_addr_t which is 64-bit. The driver has been tested, the disks get discovered correctly and can do IO. Signed-off-by: Pravin Bathija pbath...@amcc.com Acked-by: Feng Kan f...@amcc.com Acked-by: Prodyut Hazarika phazar...@amcc.com Acked-by: Loc Ho l...@amcc.com Acked-by: Tirumala Reddy Marri tma...@amcc.com Acked-by: Victor Gallardo vgalla...@amcc.com --- drivers/message/fusion/mptbase.c | 34 +- drivers/message/fusion/mptbase.h |5 +++-- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 5d496a9..d5b0f15 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -1510,11 +1510,12 @@ static int mpt_mapresources(MPT_ADAPTER *ioc) { u8 __iomem *mem; + u8 __iomem *port; int ii; - unsigned longmem_phys; - unsigned longport; - u32 msize; - u32 psize; + phys_addr_t mem_phys; + phys_addr_t port_phys; + resource_size_t msize; + resource_size_t psize; u8 revision; int r = -ENODEV; struct pci_dev *pdev; @@ -1552,13 +1553,13 @@ mpt_mapresources(MPT_ADAPTER *ioc) } mem_phys = msize = 0; - port = psize = 0; + port_phys = psize = 0; for (ii = 0; ii DEVICE_COUNT_RESOURCE; ii++) { if (pci_resource_flags(pdev, ii) PCI_BASE_ADDRESS_SPACE_IO) { if (psize) continue; /* Get I/O space! */ - port = pci_resource_start(pdev, ii); + port_phys = pci_resource_start(pdev, ii); psize = pci_resource_len(pdev, ii); } else { if (msize) @@ -1580,14 +1581,23 @@ mpt_mapresources(MPT_ADAPTER *ioc) return -EINVAL; } ioc-memmap = mem; - dinitprintk(ioc, printk(MYIOC_s_INFO_FMT mem = %p, mem_phys = %lx\n, - ioc-name, mem, mem_phys)); + dinitprintk(ioc, printk(MYIOC_s_INFO_FMT mem = %p, mem_phys = %llx\n, + ioc-name, mem, (u64)mem_phys)); ioc-mem_phys = mem_phys; ioc-chip = (SYSIF_REGS __iomem *)mem; /* Save Port IO values in case we need to do downloadboot */ - ioc-pio_mem_phys = port; + port = ioremap(port_phys, psize); + if (port == NULL) { + printk(MYIOC_s_ERR_FMT : ERROR - Unable to map adapter +port !\n, ioc-name); + return -EINVAL; + } + ioc-portmap = port; + dinitprintk(ioc, printk(MYIOC_s_INFO_FMT port=%p, port_phys=%llx\n, + ioc-name, port, (u64)port_phys)); + ioc-pio_mem_phys = port_phys; ioc-pio_chip = (SYSIF_REGS __iomem *)port; return 0; @@ -1822,6 +1832,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) if (ioc-alt_ioc) ioc-alt_ioc-alt_ioc = NULL; iounmap(ioc-memmap); + iounmap(ioc-portmap); if (r != -5) pci_release_selected_regions(pdev, ioc-bars); @@ -2583,6 +2594,11 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc) ioc-memmap = NULL; } + if (ioc-portmap != NULL) { + iounmap(ioc-portmap); + ioc-portmap = NULL; + } + pci_disable_device(ioc-pcidev); pci_release_selected_regions(ioc-pcidev, ioc-bars); diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index b3e981d..8e12bf8 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -584,8 +584,8 @@ typedef struct _MPT_ADAPTER SYSIF_REGS __iomem *chip; /* == c8817000 (mmap) */ SYSIF_REGS __iomem *pio_chip; /* Programmed IO (downloadboot) */ u8 bus_type; - u32 mem_phys; /* == f402 (mmap) */ - u32 pio_mem_phys; /* Programmed IO (downloadboot) */ + phys_addr_t mem_phys; /* == f402 (mmap) */ + phys_addr_t pio_mem_phys; /* Programmed IO (downloadboot) */ int mem_size; /* mmap memory size */ int number_of_buses; int devices_per_bus; @@ -635,6 +635,7 @@ typedef struct _MPT_ADAPTER int bars; /*
[PATCH] Don't set DABR on 64-bit BookE, use DAC1 instead
Also remove a duplicate setting of it in the context switch path on BookE. Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- arch/powerpc/kernel/process.c | 14 +++--- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 678ff13..0a32164 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -284,14 +284,13 @@ int set_dabr(unsigned long dabr) return ppc_md.set_dabr(dabr); /* XXX should we have a CPU_FTR_HAS_DABR ? */ -#if defined(CONFIG_PPC64) || defined(CONFIG_6xx) - mtspr(SPRN_DABR, dabr); -#endif - #if defined(CONFIG_BOOKE) mtspr(SPRN_DAC1, dabr); +#elif defined(CONFIG_PPC_BOOK3S) + mtspr(SPRN_DABR, dabr); #endif + return 0; } @@ -372,15 +371,16 @@ struct task_struct *__switch_to(struct task_struct *prev, #endif /* CONFIG_SMP */ - if (unlikely(__get_cpu_var(current_dabr) != new-thread.dabr)) - set_dabr(new-thread.dabr); - #if defined(CONFIG_BOOKE) /* If new thread DAC (HW breakpoint) is the same then leave it */ if (new-thread.dabr) set_dabr(new-thread.dabr); +#else + if (unlikely(__get_cpu_var(current_dabr) != new-thread.dabr)) + set_dabr(new-thread.dabr); #endif + new_thread = new-thread; old_thread = current-thread; ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH][sata_fsl] Defer non-ncq commands when ncq commands active
On 07/29/2009 12:03 PM, ashish kalra wrote: From: Ashish Kalra ashish.ka...@freescale.com Date: Wed, 29 Jul 2009 21:15:49 +0530 Fix for non-ncq ncq commands causing timeouts when both are issued simultaneously to the same device. Signed-off-by: Ashish Kalra ashish.ka...@freescale.com --- drivers/ata/sata_fsl.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 5a88b44..a33f130 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -1262,6 +1262,7 @@ static struct scsi_host_template sata_fsl_sht = { static struct ata_port_operations sata_fsl_ops = { .inherits = sata_pmp_port_ops, + .qc_defer = ata_std_qc_defer; Applied version with obvious s/;/,/ fix... Jeff ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: Queries regarding I2C and GPIO driver for Freescale MPC5121e in Linux2.6.24 of BSP: MPC512xADS_20090603-ltib.iso
One I2C driver has been included in 0603 bsp, you can refer to it. It has no specific driver for GPIO, but you can find some initializing code for GPIO in arch/powerpc/platforms/512x/mpc5125_ads.c. and mpc512x_pm_test.c. From: linuxppc-dev-bounces+hong-jun.chen=freescale@lists.ozlabs.org [mailto:linuxppc-dev-bounces+hong-jun.chen=freescale@lists.ozlabs.or g] On Behalf Of Uma Kanta Patro Sent: Tuesday, September 08, 2009 6:56 PM To: linuxppc-dev@lists.ozlabs.org Subject: Queries regarding I2C and GPIO driver for Freescale MPC5121e in Linux2.6.24 of BSP: MPC512xADS_20090603-ltib.iso Hi all, I am a newbie to the powerpc linux kernel, but I have worked on some drivers in arm architecture. I am finding powerpc architecture to be fully different than that. I am working on Freescale MPC5121e with the BSP MPC512xADS_20090603-ltib.iso running in it on the ADS512101 Rev4.1 development kit. Can anyone help me in finding some documentation for understanding and working on the powerpc kernel. Any links to the powerpc forums will also be appreciable. - Currently I am going to develop an I2C client driver for one slave microcontroller of our project. I have some knowledge in the I2C client driver making(legacy style and new style). I made a basic I2C client driver to probe for the chip address and for testing I gave it the chip address 0x68(I2C chip address of the M4T162 RTC, present on the board). But while inserting my driver I am getting failure message for the detection of my chip. So I would like to know what other formalities am I lagging in my I2C chip driver. - Also I am in a need for the GPIO driver for my controller ot get interrupt on ht estate change. When I searched in the kernel code I could not find any procedure to do that, also I could not find out the procedure to access either any GPIO pin macros or any register to remap with ioremap(). So please guide me in finding the proper way to do the GPIO accessing and interrupt registration. Will the ioremap() work on powerpc arch? If yes where can I find the memory mapping(register definitions) to use for my GPIO driver making. Thanks for patience in reading my queries. Any help is appreciable. Thanks Regards, Uma ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: AW: PowerPC PCI DMA issues (prefetch/coherency?)
On Tue, 2009-09-08 at 16:00 -0400, Adam Zilkie wrote: We are using pci_alloc_consistent() Then your flush should have no effect since pci_alloc_consistent will return I=1 mapped memory, unless you don't have CONFIG_NOT_COHERENT_CACHE for some reason. Cheers, Ben. Adam On Tue, 2009-09-08 at 12:56 -0700, Prodyut Hazarika wrote: We have found that using flush_dcache_range() after each DMA solves the problem. Ideally, we'd like to be able to allocate the virtual page in cache inhibited memory to avoid the performance loss from all the flush calls. To do this, we'd have to change our TLB sizes and reserve a TLB in memory as cache inhibited (using the 'I' bit). Will update if this works as well. Thanks for your help in this. Aren't you using dma_alloc_coherent to get buffers that are shared between CPU and external devices? Thanks Prodyut On Tue, 2009-09-08 at 11:59 -0700, Prodyut Hazarika wrote: Hi Adam, Yes, I am using the 440EPx (same as the sequoia board). Our ideDriver is DMA'ing blocks of 192-byte data over the PCI bus (using the Sil0680A PCI-IDE bridge). Most of the DMA's (depending on timing) end up being partially corrupted when we try to parse the data in the virtual page. We have confirmed the data is good before the PCI-IDE bridge. We are creating two 8K pages and map them to physical DMA memory using single-entry scatter/gather structs. When a DMA block is corrupted, we see a random portion of it (always a multiple of 16byte cache lines) is overwritten with old data from the last time the buffer was used. This looks like a cache coherency problem. Can you ensure that the TLB entries corresponding to the DMA region has the CacheInhibit bit set. You will need a BDI connected to your system. Also, you will need to invalidate and flush the lines appropriately, since in 440 cores, L1Cache coherency is managed entirely by software. Please look at drivers/net/ibm_newemac/mal.c and core.c for example on how to do it. Thanks Prodyut On Thu, 2009-09-03 at 13:27 -0700, Prodyut Hazarika wrote: Hi Adam, Are you sure there is L2 cache on the 440? It depends on the SoC you are using. SoC like 460EX (Canyonlands board) have L2Cache. It seems you are using a Sequoia board, which has a 440EPx SoC. 440EPx has a 440 cpu core, but no L2Cache. Could you please tell me which SoC you are using? You can also refer to the appropriate dts file to see if there is L2C. For example, in canyonlands.dts (460EX based board), we have the L2C entry. L2C0: l2c { ... } I am seeing this problem with our custom IDE driver which is based on pretty old code. Our driver uses pci_alloc_consistent() to allocate the physical DMA memory and alloc_pages() to allocate a virtual page. It then uses pci_map_sg() to map to a scatter/gather buffer. Perhaps I should convert these to the DMA API calls as you suggest. Could you give more details on the consistency problem? It is a good idea to change to the new DMA APIs, but pci_alloc_consistent() should work too Thanks Prodyut On Thu, 2009-09-03 at 19:57 +1000, Benjamin Herrenschmidt wrote: On Thu, 2009-09-03 at 09:05 +0100, Chris Pringle wrote: Hi Adam, If you have a look in include/asm-ppc/pgtable.h for the following section: #ifdef CONFIG_44x #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_GUARDED) #else #define _PAGE_BASE(_PAGE_PRESENT | _PAGE_ACCESSED) #endif Try adding _PAGE_COHERENT to the appropriate line above and see if that fixes your issue - this causes the 'M' bit to be set on the page which sure enforce cache coherency. If it doesn't, you'll need to check the 'M' bit isn't being masked out in head_44x.S (it was originally masked out on arch/powerpc, but was fixed in later kernels when the cache coherency issues with non-SMP systems were resolved). I have some doubts about the usefulness of doing that for 4xx. AFAIK, the 440 core just ignores M. The problem lies probably elsewhere. Maybe the L2 cache coherency isn't enabled or not working ? The L1 cache on 440 is simply not coherent, so drivers have to make sure they use the appropriate DMA APIs which will do cache flushing when needed. Adam, what driver is causing you that sort of problems ? Cheers, Ben. -- Adam Zilkie Software Designer, International Datacasting Corp. This message and the documents attached hereto are intended only for the addressee and may contain privileged or confidential information. Any
Re: [PATCH] powerpc/85xx: Fix SMP compile error and allow NULL for smp_ops
On Sep 8, 2009, at 4:31 PM, Benjamin Herrenschmidt wrote: On Tue, 2009-09-08 at 14:21 -0500, Kumar Gala wrote: struct smp_ops_t smp_85xx_ops = { + .message_pass = NULL, + .probe = NULL, .kick_cpu = smp_85xx_kick_cpu, + .setup_cpu = NULL, }; Why explicitely setting those to NULL ? Cheers, Ben. couldn't remember if we get NULL for initialized structs or not. - k ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2] powerpc/85xx: Fix SMP compile error and allow NULL for smp_ops
The following commit introduced a compile error since it removed the implementation of smp_85xx_basic_setup: commit 77c0a700c1c292edafa11c1e52821ce4636f81b0 Author: Benjamin Herrenschmidt b...@kernel.crashing.org Date: Fri Aug 28 14:25:04 2009 +1000 powerpc: Properly start decrementer on BookE secondary CPUs Make it so that smp_ops probe() and setup_cpu() can be set to NULL. Signed-off-by: Kumar Gala ga...@kernel.crashing.org --- * Removed explicit setting of NULL in structure arch/powerpc/kernel/smp.c | 10 +++--- arch/powerpc/platforms/85xx/smp.c | 10 -- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 96f107c..d387b39 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -269,7 +269,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus) cpu_callin_map[boot_cpuid] = 1; if (smp_ops) - max_cpus = smp_ops-probe(); + if (smp_ops-probe) + max_cpus = smp_ops-probe(); + else + max_cpus = NR_CPUS; else max_cpus = 1; @@ -493,7 +496,8 @@ int __devinit start_secondary(void *unused) preempt_disable(); cpu_callin_map[cpu] = 1; - smp_ops-setup_cpu(cpu); + if (smp_ops-setup_cpu) + smp_ops-setup_cpu(cpu); if (smp_ops-take_timebase) smp_ops-take_timebase(); @@ -556,7 +560,7 @@ void __init smp_cpus_done(unsigned int max_cpus) old_mask = current-cpus_allowed; set_cpus_allowed(current, cpumask_of_cpu(boot_cpuid)); - if (smp_ops) + if (smp_ops smp_ops-setup_cpu) smp_ops-setup_cpu(boot_cpuid); set_cpus_allowed(current, old_mask); diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 94f901d..04160a4 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -88,25 +88,15 @@ struct smp_ops_t smp_85xx_ops = { .kick_cpu = smp_85xx_kick_cpu, }; -static int __init smp_dummy_probe(void) -{ - return NR_CPUS; -} - void __init mpc85xx_smp_init(void) { struct device_node *np; - smp_85xx_ops.message_pass = NULL; - np = of_find_node_by_type(NULL, open-pic); if (np) { smp_85xx_ops.probe = smp_mpic_probe; smp_85xx_ops.setup_cpu = smp_85xx_setup_cpu; smp_85xx_ops.message_pass = smp_mpic_message_pass; - } else { - smp_85xx_ops.probe = smp_dummy_probe; - smp_85xx_ops.setup_cpu = smp_85xx_basic_setup; } if (cpu_has_feature(CPU_FTR_DBELL)) -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[0/5] Assorted hugepage cleanups
Currently, ordinary pages use one pagetable layout, and each different hugepage size uses a slightly different variant layout. A number of places which need to walk the pagetable must first check the slice map to see what the pagetable layout then handle the various different forms. New hardware, like Book3E is liable to introduce more possible variants. This patch series, therefore, is designed to simplify the matter by limiting knowledge of the pagetable layout to only the allocation path. With this patch, ordinary pages are handled as ever, with a fixed 4 (or 3) level tree. All other variants branch off from some layer of that with a specially marked PGD/PUD/PMD pointer which also contains enough information to interpret the directories below that point. This means that things walking the pagetables (without allocating) don't need to look up the slice map, they can just step down the tree in the usual way, branching off to the non-standard layout path for hugepages, which uses the embdded information to interpret the tree from that point on. This reduces the source size in a number of places, and means that newer variants on the pagetable layout to handle new hardware and new features will need to alter the existing code in less places. In addition we split out the hash / classic MMU specific code into a separate hugetlbpage-hash64.c file. This will make adding support for other MMUs (like 440 and/or Book3E) easier. I've used the libhugetlbfs testsuite to test these patches on a Power5+ machine, but they could certainly do with more testing. In particular, I don't have any suitable hardware to test 16G pages. -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[1/5] Make hpte_need_flush() correctly mask for multiple page sizes
Currently, hpte_need_flush() only correctly flushes the given address for normal pages. Callers for hugepages are required to mask the address themselves. But hpte_need_flush() already looks up the page sizes for its own reasons, so this is a rather silly imposition on the callers. This patch alters it to mask based on the pagesize it has looked up itself, and removes the awkward masking code in the hugepage caller. Signed-off-by: David Gibson d...@au1.ibm.com --- arch/powerpc/mm/hugetlbpage.c |6 +- arch/powerpc/mm/tlb_hash64.c |8 +++- 2 files changed, 4 insertions(+), 10 deletions(-) Index: working-2.6/arch/powerpc/mm/tlb_hash64.c === --- working-2.6.orig/arch/powerpc/mm/tlb_hash64.c 2009-09-04 14:35:30.0 +1000 +++ working-2.6/arch/powerpc/mm/tlb_hash64.c2009-09-04 14:36:12.0 +1000 @@ -53,11 +53,6 @@ void hpte_need_flush(struct mm_struct *m i = batch-index; - /* We mask the address for the base page size. Huge pages will -* have applied their own masking already -*/ - addr = PAGE_MASK; - /* Get page size (maybe move back to caller). * * NOTE: when using special 64K mappings in 4K environment like @@ -75,6 +70,9 @@ void hpte_need_flush(struct mm_struct *m } else psize = pte_pagesize_index(mm, addr, pte); + /* Mask the address for the correct page size */ + addr = ~((1UL mmu_psize_defs[psize].shift) - 1); + /* Build full vaddr */ if (!is_kernel_addr(addr)) { ssize = user_segment_size(addr); Index: working-2.6/arch/powerpc/mm/hugetlbpage.c === --- working-2.6.orig/arch/powerpc/mm/hugetlbpage.c 2009-09-04 14:35:30.0 +1000 +++ working-2.6/arch/powerpc/mm/hugetlbpage.c 2009-09-04 14:36:12.0 +1000 @@ -445,11 +445,7 @@ void set_huge_pte_at(struct mm_struct *m * necessary anymore if we make hpte_need_flush() get the * page size from the slices */ - unsigned int psize = get_slice_psize(mm, addr); - unsigned int shift = mmu_psize_to_shift(psize); - unsigned long sz = ((1UL) shift); - struct hstate *hstate = size_to_hstate(sz); - pte_update(mm, addr hstate-mask, ptep, ~0UL, 1); + pte_update(mm, addr, ptep, ~0UL, 1); } *ptep = __pte(pte_val(pte) ~_PAGE_HPTEFLAGS); } ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev