* Re: [PATCH 2/2][RFC][v3] pci: fsl: rework PCI driver compatible with Layerscape
From: Lian Minghuan-b31939 @ 2013-09-17 9:23 UTC (permalink / raw)
To: Scott Wood; +Cc: Minghuan Lian, linuxppc-dev, Zang Roy-R61911
In-Reply-To: <1379376308.2536.217.camel@snotra.buserror.net>
Hi Scott,
Thanks for your comments.
please see my replies in line.
On 09/17/2013 08:05 AM, Scott Wood wrote:
> On Thu, 2013-09-12 at 18:07 +0800, Minghuan Lian wrote:
>> The Freescale's Layerscape series processors will use the same PCI
>> controller but change cores from PowerPC to ARM. This patch is to
>> rework FSL PCI driver to support PowerPC and ARM simultaneously.
>> PowerPC uses structure pci_controller to describe PCI controller,
>> but arm uses structure hw_pci and pci_sys_data. They also have
>> different architecture implementation and initialization flow.
>> The architecture-dependent driver will bridge the gap, get the
>> settings from the common driver and initialize the corresponding
>> structure and call the related interface to register PCI controller.
>> The common driver pci-fsl.c removes all the architecture-specific
>> code and provides structure fsl_pci to store all the controller
>> settings and the common functionalities that include reading/writing
>> PCI configuration space, parsing dts node and getting the MEM/IO and
>> bus number ranges, setting ATMU and check link status.
>>
>> Signed-off-by: Minghuan Lian <Minghuan.Lian@freescale.com>
>> ---
>> Based on upstream master
>> The function has been tested on MPC8315ERDB MPC8572DS P5020DS P3041DS
>> and T4240QDS boards
>>
>> Change log:
>> v3:
>> 1. use 'fsl_arch' as function name prefix of all the
>> architecture-specific hooks.
>> 2. Move PCI compatible definitions from arch/powerpc/sysdev/fsl_pci.c
>> to driver/pci/host/pci-fsl.c
>>
>> v2:
>> 1. Use 'pci' instead of 'pcie' in new file name and file contents.
>> 2. Use iowrite32be()/iowrite32() instead of out_be32/le32()
>> 3. Fix ppc_md.dma_set_mask setting
>> 4. Synchronizes host->first_busno and pci->first_busno.
>> 5. Fix PCI IO space settings
>> 6. Some small changes according to Scott's comments.
>>
>>
>> arch/powerpc/Kconfig | 1 +
>> arch/powerpc/sysdev/fsl_pci.c | 150 +++++++++-
>> drivers/edac/mpc85xx_edac.c | 9 -
>> drivers/pci/host/Kconfig | 4 +
>> drivers/pci/host/Makefile | 1 +
>> drivers/pci/host/pci-fsl.c | 656 +++++++++++++++++++++++++++---------------
>> include/linux/fsl/pci.h | 69 +++++
>> 7 files changed, 648 insertions(+), 242 deletions(-)
> The PCI mailing list and maintainer should be included.
[Minghuan] Ok, I will remove 'RFC' and re-send the patch according to
you comments.
>> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
>> index 6b7530f..657d90f 100644
>> --- a/arch/powerpc/Kconfig
>> +++ b/arch/powerpc/Kconfig
>> @@ -691,6 +691,7 @@ config FSL_SOC
>>
>> config FSL_PCI
>> bool
>> + select PCI_FSL if FSL_SOC_BOOKE || PPC_86xx
>> select PPC_INDIRECT_PCI
>> select PCI_QUIRKS
>>
>> diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
>> index a189ff0..4cb12e8 100644
>> --- a/arch/powerpc/sysdev/fsl_pci.c
>> +++ b/arch/powerpc/sysdev/fsl_pci.c
>> @@ -62,7 +62,11 @@ static void quirk_fsl_pcie_header(struct pci_dev *dev)
>> #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
>>
>> #define MAX_PHYS_ADDR_BITS 40
>> -static u64 pci64_dma_offset = 1ull << MAX_PHYS_ADDR_BITS;
>> +
>> +u64 fsl_arch_pci64_dma_offset(void)
>> +{
>> + return 1ull << MAX_PHYS_ADDR_BITS;
>> +}
>>
>> static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
>> {
>> @@ -77,17 +81,43 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
>> if ((dev->bus == &pci_bus_type) &&
>> dma_mask >= DMA_BIT_MASK(MAX_PHYS_ADDR_BITS)) {
>> set_dma_ops(dev, &dma_direct_ops);
>> - set_dma_offset(dev, pci64_dma_offset);
>> + set_dma_offset(dev, fsl_arch_pci64_dma_offset());
>> }
> Is the intent for fsl_arch_pci64_dma_offset() to eventually do something
> that isn't calculable at compile time?
>
[Minghuan] fsl_arch_pci64_dma_offset() is also called by pci-fsl.c to
setup inbound ATMU.
I think different platform or architecture(LS1) may use different dma
offset(maybe I am wrong
they can use the same offset 1ull << MAX_PHYS_ADDR_BITS). I selected
u64 fsl_arch_pci64_dma_offset(void) not extern u64 pci64_dma_offset to
share the global
value between /driver/pci/host/pci-fsl.c and
arch/powerpc/sysdev/fsl_pci.c or / arch/arm/..../fsl_pci.c
'extern' variable will cause the warning when checking patch.
>> *dev->dma_mask = dma_mask;
>> return 0;
>> }
>>
>> +struct fsl_pci *fsl_arch_sys_to_pci(void *sys)
>> +{
>> + struct pci_controller *hose = sys;
>> + struct fsl_pci *pci = hose->private_data;
> If this were just to convert to fsl_pci, that seems like header
> material.
[Minghuan] In arm architecture it will be implemented like this:
struct fsl_pci *fsl_arch_sys_to_pci(void *sys) {
struct pci_sys_data *sys_data = sys;
return sys_data->private_data;
}
driver/pci/host/pci-fsl.c should not include any arch specific header file.
and can not recognize structure pci_controller used in powerpc and
pci_sys_data used in arm.
>> + /* Update the first bus number */
>> + if (pci->first_busno != hose->first_busno)
>> + pci->first_busno = hose->first_busno;
> This isn't part of the interface description in the header...
[Minghuan] Yes. host->first_busno will be reassigned if defined
PCI_REASSIGN_ALL_BUS.
and I can not find a chance to update pci->first_busno. this will cause
we can not
read/write pci configuration space when the hose->first_busno is changed
but pci->first_busno
is not updated synchronously.
the following code to check first_busno when access the configuration space.
if (pci->indirect_type & INDIRECT_TYPE_NO_PCIE_LINK) {
if (bus != pci->first_busno)
return PCIBIOS_DEVICE_NOT_FOUND;
...
}
bus_no = (bus == pci->first_busno) ? pci->self_busno : bus;
So I added the sentences to this function to fix the issue.
>
>> +static int mpc83xx_pcie_check_link(struct pci_controller *hose)
>> +{
>> + u32 val = 0;
>> +
>> +#define PCIE_LTSSM 0x0404 /* PCIE Link Training and Status */
>> +#define PCIE_LTSSM_L0 0x16 /* L0 state */
>> +
>> + early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val);
>> + if (val < PCIE_LTSSM_L0)
>> + return 1;
>> + return 0;
>> +}
> Aren't PCIE_LTSSM and PCIE_LTSSM_L0 defined in include/linux/fsl/pci.h
> at this point?
[Minghuan] Yes. I will remove the duplicate definitions.
>> @@ -260,14 +259,6 @@ int mpc85xx_pci_err_probe(struct platform_device *op)
>> /* we only need the error registers */
>> r.start += 0xe00;
>>
>> - if (!devm_request_mem_region(&op->dev, r.start, resource_size(&r),
>> - pdata->name)) {
>> - printk(KERN_ERR "%s: Error while requesting mem region\n",
>> - __func__);
>> - res = -EBUSY;
>> - goto err;
>> - }
> Why? If the relationship between the edac driver and the main pci
> driver is changing, explain that.
[Minghuan] Ok.
The main pci driver used devm_ioremap_resource() to map regester space.
So PCI EDAC driver would encounter an error when calling
devm_request_mem_region()
EDAC just only need to ioremap the error interrupt registers region and
not need
to call devm_request_mem_region().
>
>> pdata->pci_vbase = devm_ioremap(&op->dev, r.start, resource_size(&r));
>> if (!pdata->pci_vbase) {
>> printk(KERN_ERR "%s: Unable to setup PCI err regs\n", __func__);
>> diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
>> index 3d95048..37d25ae 100644
>> --- a/drivers/pci/host/Kconfig
>> +++ b/drivers/pci/host/Kconfig
>> @@ -19,4 +19,8 @@ config PCI_TEGRA
>> bool "NVIDIA Tegra PCIe controller"
>> depends on ARCH_TEGRA
>>
>> +config PCI_FSL
>> + bool "Freescale PCI/PCIe controller"
>> + depends on FSL_SOC_BOOKE || PPC_86xx
> Needs help text.
>
> Make it clear that this is for 85xx/86xx/QorIQ/Layerscape, not all
> Freescale chips with PCI/PCIe.
[Minghuan] Ok. I will add help text.
>> no_bridge:
>> - iounmap(hose->private_data);
>> - /* unmap cfg_data & cfg_addr separately if not on same page */
>> - if (((unsigned long)hose->cfg_data & PAGE_MASK) !=
>> - ((unsigned long)hose->cfg_addr & PAGE_MASK))
>> - iounmap(hose->cfg_data);
>> - iounmap(hose->cfg_addr);
>> - pcibios_free_controller(hose);
>> - return -ENODEV;
>> + dev_info(&pdev->dev, "It works as EP mode\n");
>> + return -EPERM;
> This is a poorly phrased message. In any case, what does this change
> have to do with making the PCI driver compatible with layerscape?
[Minghuan] I can not quite understand what you mean.
Should I remove the "dev_info(&pdev->dev, "It works as EP mode\n");"
and not change ENODEV to EPERM?
we do not really need this change.
If the controller is in EP mode, we only need to return an error,
because at this time
'hose' has not been created.
> -Scott
>
>
^ permalink raw reply
* [PATCH] powerpc: prom_init exception when updating core value
From: Laurent Dufour @ 2013-09-17 9:52 UTC (permalink / raw)
To: linuxppc-dev; +Cc: tbreeds, benh
Since the CPU is generating an exception when accessing unaligned word, and
as this exception is not yet handled when running prom_init, data should be
copied from the architecture vector byte per byte.
Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
---
arch/powerpc/kernel/prom_init.c | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index edcb6be..50065ee 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -855,7 +855,8 @@ static void __init prom_send_capabilities(void)
{
ihandle root;
prom_arg_t ret;
- __be32 *cores;
+ u32 cores;
+ unsigned char *ptcores;
root = call_prom("open", 1, 1, ADDR("/"));
if (root != 0) {
@@ -865,15 +866,30 @@ static void __init prom_send_capabilities(void)
* (we assume this is the same for all cores) and use it to
* divide NR_CPUS.
*/
- cores = (__be32 *)&ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET];
- if (be32_to_cpup(cores) != NR_CPUS) {
+
+ /* The core value may start at an odd address. If such a word
+ * access is made at a cache line boundary, this leads to an
+ * exception which may not be handled at this time.
+ * Forcing a per byte access to avoid exception.
+ */
+ ptcores = &ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET];
+ cores = 0;
+ cores |= ptcores[0] << 24;
+ cores |= ptcores[1] << 16;
+ cores |= ptcores[2] << 8;
+ cores |= ptcores[3];
+ if (cores != NR_CPUS) {
prom_printf("WARNING ! "
"ibm_architecture_vec structure inconsistent: %lu!\n",
- be32_to_cpup(cores));
+ cores);
} else {
- *cores = cpu_to_be32(DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads()));
+ cores = DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads());
prom_printf("Max number of cores passed to firmware: %lu (NR_CPUS = %lu)\n",
- be32_to_cpup(cores), NR_CPUS);
+ cores, NR_CPUS);
+ ptcores[0] = (cores >> 24) & 0xff;
+ ptcores[1] = (cores >> 16) & 0xff;
+ ptcores[2] = (cores >> 8) & 0xff;
+ ptcores[3] = cores & 0xff;
}
/* try calling the ibm,client-architecture-support method */
^ permalink raw reply related
* RE: [PATCH] powerpc/85xx: DTS - re-organize the SPI partitions property
From: Hu Mingkai-B21284 @ 2013-09-17 11:06 UTC (permalink / raw)
To: Wood Scott-B07421; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <1378948542.12204.490.camel@snotra.buserror.net>
U2NvdHQsDQpTb3JyeSBmb3IgdGhlIGRlbGF5ZWQgcmVzcG9uc2UuDQpQbGVhc2UgZmluZSBteSBj
b21tZW50cy4NClRoYW5rcywNCk1pbmdrYWkNCg0KPiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0t
LQ0KPiBGcm9tOiBXb29kIFNjb3R0LUIwNzQyMQ0KPiBTZW50OiBUaHVyc2RheSwgU2VwdGVtYmVy
IDEyLCAyMDEzIDk6MTYgQU0NCj4gVG86IEh1IE1pbmdrYWktQjIxMjg0DQo+IENjOiBXb29kIFNj
b3R0LUIwNzQyMTsgbGludXhwcGMtZGV2QG96bGFicy5vcmcNCj4gU3ViamVjdDogUmU6IFtQQVRD
SF0gcG93ZXJwYy84NXh4OiBEVFMgLSByZS1vcmdhbml6ZSB0aGUgU1BJIHBhcnRpdGlvbnMNCj4g
cHJvcGVydHkNCj4gDQo+IE9uIFR1ZSwgMjAxMy0wOS0xMCBhdCAyMTowNyAtMDUwMCwgSHUgTWlu
Z2thaS1CMjEyODQgd3JvdGU6DQo+ID4NCj4gPiA+IC0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0t
DQo+ID4gPiBGcm9tOiBXb29kIFNjb3R0LUIwNzQyMQ0KPiA+ID4gU2VudDogV2VkbmVzZGF5LCBT
ZXB0ZW1iZXIgMTEsIDIwMTMgNzozMyBBTQ0KPiA+ID4gVG86IEh1IE1pbmdrYWktQjIxMjg0DQo+
ID4gPiBDYzogbGludXhwcGMtZGV2QG96bGFicy5vcmcNCj4gPiA+IFN1YmplY3Q6IFJlOiBbUEFU
Q0hdIHBvd2VycGMvODV4eDogRFRTIC0gcmUtb3JnYW5pemUgdGhlIFNQSQ0KPiA+ID4gcGFydGl0
aW9ucyBwcm9wZXJ0eQ0KPiA+ID4NCj4gPiA+IFdoYXQgaGFwcGVucyB0byBleHN0aW5nIHVzZXJz
IHdob3NlIGZsYXNoIGlzIGxhaWQgb3V0IHRoZSBleGlzdGluZw0KPiA+ID4gd2F5LCB3aGVuIHRo
ZXkgdXBncmFkZSB0byB0aGVzZSBkZXZpY2UgdHJlZXM/DQo+ID4gPg0KPiA+DQo+ID4gVGhlIFNQ
SSBmbGFzaCBsYXlvdXQgc2hvdWxkIGJlIG1hcHBpbmcgdGhlIG5ldyBkZXZpY2UgdHJlZS4NCj4g
Pg0KPiA+IElmIHRoZSBleGlzdGluZyBkZXZpY2UgdHJlZSBpcyB1c2VkIHRvIGRlcGxveSB0aGUg
U1BJIGZsYXNoLCB0aGUNCj4gPiBmb2xsb3dpbmcgaXNzdWVzIG11c3QgYmUgcnVuIGludG8gYXMg
dGhlIGNvbW1pdCBtZXNzYWdlIGRlc2NyaWJlZDoNCj4gPg0KPiA+IDEuIEtlcm5lbCBpbWFnZXMg
d291bGQgYmUgb3ZlcmxhcHBlZCB3aXRoIFUtQm9vdCBpbWFnZS4NCj4gPiAyLiBLZXJuZWwgaW1h
Z2VzIHdvdWxkIGJlIG92ZXJsYXBwZWQgd2l0aCBGTUFOIHVjb2RlLg0KPiA+IDMuIFNhdmluZyBl
bnZpcm9ubWVudCB2YXJpYWJsZXMgd2lsbCBjcmFzaCB0aGUga2VybmVsIGltYWdlLg0KPiANCj4g
SGFzIHRoZSBTUEkgVS1Cb290IGltYWdlIGFsd2F5cyBiZWVuIGxhcmdlciB0aGFuIDUxMksgZm9y
IGFsbCB0aGVzZQ0KPiBwbGF0Zm9ybXM/ICBXaHksIGdpdmVuIHRoYXQgd2UncmUgdW5kZXIgNTEy
SyBmb3Igb3RoZXIgYm9vdCBtb2Rlcz8NCj4gDQoNCkZvciBEUEFBIHBsYXRmb3JtLCB0aGUgbGQg
c2NyaXB0IHVzZWQgdG8gbGluayB0aGUgdS1ib290IGltYWdlIGlzIA0KIi4vYXJjaC9wb3dlcnBj
L2NwdS9tcGM4NXh4L3UtYm9vdC5sZHMiIHdoaWNoIHdpbGwgZ2VuZXJhdGUgdGhlIDUxMksgdS1i
b290DQpJbWFnZS4gVGhpcyBpbWFnZSB3aWxsIGJlIHNwbGl0IGludG8gNjRieXRlcyBhbmQgYXBw
ZW5kZWQgUEJMIGNvbW1hbmQgZm9yIA0KRWFjaCA2NGJ5dGVzIHBpZWNlcywgc28gdGhlIHNpemUg
b2YgZmluYWwgaW1hZ2UgbXVzdCBiZSBncmVhdGVyIHRoYW4gNTEySy4NCg0KVGhlIHNhbWUgYXBw
bGllcyB0byB0aGUgbm9uLURQQUEgcGxhdGZvcm0gd2hpY2ggZG9lc24ndCBzdXBwb3J0IFRQTC4N
Cg0KRm9yIG5vbi1EUEFBIHBsYXRmb3JtIHdoaWNoIHN1cHBvcnQgVFBMLCB0aGUgaW1hZ2Ugc2l6
ZSBpcyBhbHNvIGdyZWF0ZXIgdGhhbiA1MTJLLg0KDQo+ID4gPiBXZSByZWFsbHkgc2hvdWxkIG5v
dCBiZSBwdXR0aW5nIHBhcnRpdGlvbiBsYXlvdXQgaW5mbyBpbiB0aGUgZGV2aWNlDQo+ID4gPiB0
cmVlIHRvIGJlZ2luIHdpdGguLi4NCj4gPiA+DQo+ID4gT0ssIEkgd2lsbCByZW1vdmUgdGhlIGxh
eW91dCBkaWFncmFtIGluIHRoZSBjb21taXQgbWVzc2FnZS4NCj4gDQo+IFRoYXQncyBub3Qgd2hh
dCBJIG1lYW50LiAgSSBtZWFudCB0aGF0IHRoZSBkdHMgc2hvdWxkIGJlIGRlc2NyaWJpbmcNCj4g
aGFyZHdhcmUsIGFuZCB0aGlzIGlzIHRoZSBzb3J0IG9mIHRyb3VibGUgd2UgcnVuIGludG8gd2hl
biB3ZSBkZXZpYXRlDQo+IGZyb20gdGhhdC4gIEEgYmV0dGVyIHdheSB3b3VsZCBiZSB0byB1c2Ug
dGhlIG10ZHBhcnRzIGNvbW1hbmQgbGluZSBvcHRpb24uDQo+IEV2ZW4gYmV0dGVyIHdvdWxkIGJl
IHNvbWUgc29ydCBvZiBvbi1mbGFzaCBwYXJ0aXRpb24gdGFibGUuDQo+IA0KDQpZb3UncmUgcmln
aHQsIGJ1dCBtYXliZSBzb21lIGN1c3RvbWVyIGhhcyBhbHJlYWR5IHVzZWQgdGhlIGRldmljZSB0
cmVlIHBhcnRpdGlvbiB0YWJsZS4uLg0KDQpUaGFua3MsDQpNaW5na2FpDQoNCg==
^ permalink raw reply
* Re: [PATCH v2 2/6] PCI/MSI: Factor out pci_get_msi_cap() interface
From: Michael Ellerman @ 2013-09-17 14:30 UTC (permalink / raw)
To: Alexander Gordeev
Cc: linuxppc-dev, Joerg Roedel, x86@kernel.org,
linux-kernel@vger.kernel.org, linux-ide@vger.kernel.org,
Jan Beulich, linux-pci@vger.kernel.org, Tejun Heo, Bjorn Helgaas,
Ingo Molnar
In-Reply-To: <20130916102210.GA14102@dhcp-26-207.brq.redhat.com>
On Mon, Sep 16, 2013 at 12:22:11PM +0200, Alexander Gordeev wrote:
> On Mon, Sep 09, 2013 at 05:20:44PM +0200, Alexander Gordeev wrote:
> > On Fri, Sep 06, 2013 at 05:32:05PM -0600, Bjorn Helgaas wrote:
> > > I propose that you rework it that way, and at least find out what
> > > (if anything) would break if we do that. Or maybe we just give up
> > > some optimization; it would be nice to quantify that, too.
> >
> > Hi Bjorn,
> >
> > The series is what it seems a direction to take.
> >
> > Looks like we need PPC folks to agree on the quota check update
> > for pSeries (yes, they do bail out with a positive return value
> > from arch_msi_check_device()):
>
> Hi Ben,
>
> An initiative to simplify MSI/MSI-X allocation interface is brewing.
> It seems pSeries quota thing is an obstacle. If it could be given up
> (patch 2/9).
How about no?
We have a small number of MSIs available, limited by hardware &
firmware, if we don't impose a quota then the first device that probes
will get most/all of the MSIs and other devices miss out.
Anyway I don't see what problem you're trying to solve? I agree the
-ve/0/+ve return value pattern is ugly, but it's hardly the end of the
world.
cheers
^ permalink raw reply
* Re: [PATCH v2] powerpc 8xx: Fixing issue with CONFIG_PIN_TLB
From: leroy christophe @ 2013-09-17 16:40 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev, Paul Mackerras, linux-kernel
In-Reply-To: <1379365336.2536.166.camel@snotra.buserror.net>
Le 16/09/2013 23:02, Scott Wood a écrit :
> On Fri, 2013-09-13 at 07:04 +0200, leroy christophe wrote:
>> Le 12/09/2013 20:44, Scott Wood a écrit :
>>> On Thu, 2013-09-12 at 20:25 +0200, Christophe Leroy wrote:
>>>> This is a reorganisation of the setup of the TLB at kernel startup, in order
>>>> to handle the CONFIG_PIN_TLB case in accordance with chapter 8.10.3 of MPC866
>>>> and MPC885 reference manuals.
>>>>
>>>> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>>>>
>>>> diff -ur linux-3.11.org/arch/powerpc/kernel/head_8xx.S linux-3.11/arch/powerpc/kernel/head_8xx.S
>>>> --- linux-3.11.org/arch/powerpc/kernel/head_8xx.S 2013-09-02 22:46:10.000000000 +0200
>>>> +++ linux-3.11/arch/powerpc/kernel/head_8xx.S 2013-09-09 11:28:54.000000000 +0200
>>>> @@ -785,27 +785,24 @@
>>>> * these mappings is mapped by page tables.
>>>> */
>>>> initial_mmu:
>>>> - tlbia /* Invalidate all TLB entries */
>>>> -/* Always pin the first 8 MB ITLB to prevent ITLB
>>>> - misses while mucking around with SRR0/SRR1 in asm
>>>> -*/
>>>> - lis r8, MI_RSV4I@h
>>>> - ori r8, r8, 0x1c00
>>>> -
>>>> + lis r8, MI_RESETVAL@h
>>>> mtspr SPRN_MI_CTR, r8 /* Set instruction MMU control */
>>>>
>>>> -#ifdef CONFIG_PIN_TLB
>>>> - lis r10, (MD_RSV4I | MD_RESETVAL)@h
>>>> - ori r10, r10, 0x1c00
>>>> - mr r8, r10
>>>> -#else
>>>> lis r10, MD_RESETVAL@h
>>>> -#endif
>>>> #ifndef CONFIG_8xx_COPYBACK
>>>> oris r10, r10, MD_WTDEF@h
>>>> #endif
>>>> mtspr SPRN_MD_CTR, r10 /* Set data TLB control */
>>>>
>>>> + tlbia /* Invalidate all TLB entries */
>>> Is this change to make sure we invalidate everything even if the
>>> bootloader set RSV4I?
>> Most probably. It is step 2 of the process defined in MPC866 and MPC885
>> Reference Manuals:
>>
>> §8.10.3 Loading Locked TLB Entries:
>> The process of loading a single reserved entry in the TLB is as follows:
> To minimize code churn we should just fix actual problems, rather than
> shuffle things around to conform to a suggested sequence. After all,
> we're not just trying to load a single entry.
Ok, I'll try again.
>
>>>> + ori r8, r8, 0x1c00
>>>> + mtspr SPRN_MI_CTR, r8 /* Set instruction MMU control */
>>>> +#ifdef CONFIG_PIN_TLB
>>>> + ori r10, r10, 0x1c00
>>>> + mtspr SPRN_MD_CTR, r10 /* Set data TLB control */
>>>> +#endif
>>> Still 0x1c00?
>> Yes, I kept the same entries in order to limit modifications:
>> * 28 = First 8Mbytes page
>> * 29 = IMMR
>> * 30 = Second 8Mbytes page
>> * 31 = Third 8Mbytes page
> If you actually want to program them in increasing order then it looks
> like you're still missing a write to CTR between the last two 8M entries
> -- thus you'll overwrite the IMMR with the last 8M entry. That was the
> same problem that v1 fixed -- did that change get lost accidentally?
Oops, no, in fact I diffed from the version which was including it
already. My mistake.
>
> The hardware wants to decrement; why fight it?
I see your point.
However it is not clear in the documentation if the decrement is done
really after the update, or at xTLB interrupt. So I propose to still set
the CTR ourself as described in the reference Manual and not assume that
the HW decrements it.
>
>>>> /* Now map the lower 8 Meg into the TLBs. For this quick hack,
>>>> * we can load the instruction and data TLB registers with the
>>>> * same values.
>>>> @@ -825,6 +822,12 @@
>>>> mtspr SPRN_MI_AP, r8
>>>> mtspr SPRN_MD_AP, r8
>>>>
>>>> + /* Always pin the first 8 MB ITLB to prevent ITLB
>>>> + * misses while mucking around with SRR0/SRR1 in asm
>>>> + */
>>>> + lis r8, (MI_RSV4I | MI_RESETVAL)@h
>>>> + mtspr SPRN_MI_CTR, r8 /* Set instruction MMU control */
>>> Entry 0 is not pinnable.
>> Here we are not trying to pin entry 0.
> Sorry, misread the patch.
>
>> We are at step 8, we are setting
>> MI_RSV4I. At the same time, we set MD_CTR to 0 which is off the pinned
>> range, to be sure that we won't overwrite one of the pinned entries.
>>
>> The main difference compared to the previous implementation is that
>> before, we were setting the RSV4I bit before loading the TLB entries.
>> Now, as defined in the Reference Manuals, we are doing it at the end.
> Have you seen any evidence that it matters?
Not really.
Ok, propose a new patch in a few minutes.
Christophe
^ permalink raw reply
* [PATCH v3] powerpc 8xx: Fixing issue with CONFIG_PIN_TLB
From: Christophe Leroy @ 2013-09-17 17:09 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, scottwood
Cc: linuxppc-dev, linux-kernel
Activating CONFIG_PIN_TLB is supposed to pin the IMMR and the first three
8Mbytes pages. But the setting of the MD_CTR was missing so as the index is
decremented every DTLB update, the pinning of the third 8Mbytes page was
overwriting the DTLB entry for IMMR. At the same time, the last entry written
being entry 31, next entries would possibly get overwritten after.
We are now starting from entry 31 and decrementing.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
diff -ur linux-3.11.org/arch/powerpc/kernel/head_8xx.S linux-3.11/arch/powerpc/kernel/head_8xx.S
--- linux-3.11.org/arch/powerpc/kernel/head_8xx.S 2013-09-02 22:46:10.000000000 +0200
+++ linux-3.11/arch/powerpc/kernel/head_8xx.S 2013-09-09 11:28:54.000000000 +0200
@@ -796,8 +796,7 @@
#ifdef CONFIG_PIN_TLB
lis r10, (MD_RSV4I | MD_RESETVAL)@h
- ori r10, r10, 0x1c00
- mr r8, r10
+ ori r10, r10, 0x1f00
#else
lis r10, MD_RESETVAL@h
#endif
@@ -829,7 +828,7 @@
* internal registers (among other things).
*/
#ifdef CONFIG_PIN_TLB
- addi r10, r10, 0x0100
+ addi r10, r10, -0x0100
mtspr SPRN_MD_CTR, r10
#endif
mfspr r9, 638 /* Get current IMMR */
@@ -848,7 +847,7 @@
#ifdef CONFIG_PIN_TLB
/* Map two more 8M kernel data pages.
*/
- addi r10, r10, 0x0100
+ addi r10, r10, -0x0100
mtspr SPRN_MD_CTR, r10
lis r8, KERNELBASE@h /* Create vaddr for TLB */
@@ -862,6 +861,9 @@
addis r11, r11, 0x0080 /* Add 8M */
mtspr SPRN_MD_RPN, r11
+ addi r10, r10, -0x0100
+ mtspr SPRN_MD_CTR, r10
+
addis r8, r8, 0x0080 /* Add 8M */
mtspr SPRN_MD_EPN, r8
mtspr SPRN_MD_TWC, r9
^ permalink raw reply
* RE: [PATCH v3 4/4] powerpc/85xx: add sysfs for pw20 state and altivec idle
From: Wang Dongsheng-B40534 @ 2013-09-18 3:35 UTC (permalink / raw)
To: Wood Scott-B07421; +Cc: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1379365769.2536.169.camel@snotra.buserror.net>
DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogV29vZCBTY290dC1CMDc0
MjENCj4gU2VudDogVHVlc2RheSwgU2VwdGVtYmVyIDE3LCAyMDEzIDU6MDkgQU0NCj4gVG86IFdh
bmcgRG9uZ3NoZW5nLUI0MDUzNA0KPiBDYzogV29vZCBTY290dC1CMDc0MjE7IGdhbGFrQGtlcm5l
bC5jcmFzaGluZy5vcmc7IGxpbnV4cHBjLQ0KPiBkZXZAbGlzdHMub3psYWJzLm9yZw0KPiBTdWJq
ZWN0OiBSZTogW1BBVENIIHYzIDQvNF0gcG93ZXJwYy84NXh4OiBhZGQgc3lzZnMgZm9yIHB3MjAg
c3RhdGUgYW5kDQo+IGFsdGl2ZWMgaWRsZQ0KPiANCj4gT24gVGh1LCAyMDEzLTA5LTEyIGF0IDIx
OjUzIC0wNTAwLCBXYW5nIERvbmdzaGVuZy1CNDA1MzQgd3JvdGU6DQo+ID4NCj4gPiA+IC0tLS0t
T3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+ID4gPiBGcm9tOiBXb29kIFNjb3R0LUIwNzQyMQ0KPiA+
ID4gU2VudDogRnJpZGF5LCBTZXB0ZW1iZXIgMTMsIDIwMTMgMjowNyBBTQ0KPiA+ID4gVG86IFdh
bmcgRG9uZ3NoZW5nLUI0MDUzNA0KPiA+ID4gQ2M6IFdvb2QgU2NvdHQtQjA3NDIxOyBnYWxha0Br
ZXJuZWwuY3Jhc2hpbmcub3JnOyBsaW51eHBwYy0NCj4gPiA+IGRldkBsaXN0cy5vemxhYnMub3Jn
DQo+ID4gPiBTdWJqZWN0OiBSZTogW1BBVENIIHYzIDQvNF0gcG93ZXJwYy84NXh4OiBhZGQgc3lz
ZnMgZm9yIHB3MjAgc3RhdGUNCj4gPiA+IGFuZCBhbHRpdmVjIGlkbGUNCj4gPiA+DQo+ID4gPiBP
biBXZWQsIDIwMTMtMDktMTEgYXQgMjI6NDggLTA1MDAsIFdhbmcgRG9uZ3NoZW5nLUI0MDUzNCB3
cm90ZToNCj4gPiA+ID4NCj4gPiA+ID4gPiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiA+
ID4gPiA+IEZyb206IFdvb2QgU2NvdHQtQjA3NDIxDQo+ID4gPiA+ID4gU2VudDogVGh1cnNkYXks
IFNlcHRlbWJlciAxMiwgMjAxMyA3OjA0IEFNDQo+ID4gPiA+ID4gVG86IFdhbmcgRG9uZ3NoZW5n
LUI0MDUzNA0KPiA+ID4gPiA+IENjOiBnYWxha0BrZXJuZWwuY3Jhc2hpbmcub3JnOyBsaW51eHBw
Yy1kZXZAbGlzdHMub3psYWJzLm9yZw0KPiA+ID4gPiA+IFN1YmplY3Q6IFJlOiBbUEFUQ0ggdjMg
NC80XSBwb3dlcnBjLzg1eHg6IGFkZCBzeXNmcyBmb3IgcHcyMA0KPiA+ID4gPiA+IHN0YXRlIGFu
ZCBhbHRpdmVjIGlkbGUNCj4gPiA+ID4gPg0KPiA+ID4gPiA+IE9uIFdlZCwgMjAxMy0wOS0xMSBh
dCAxMzo1NiArMDgwMCwgRG9uZ3NoZW5nIFdhbmcgd3JvdGU6DQo+ID4gPiA+ID4gPiBGcm9tOiBX
YW5nIERvbmdzaGVuZyA8ZG9uZ3NoZW5nLndhbmdAZnJlZXNjYWxlLmNvbT4NCj4gPiA+ID4gPiA+
DQo+ID4gPiA+ID4gPiBBZGQgYSBzeXMgaW50ZXJmYWNlIHRvIGVuYWJsZS9kaWFibGUgcHcyMCBz
dGF0ZSBvciBhbHRpdmVjDQo+ID4gPiA+ID4gPiBpZGxlLCBhbmQgY29udHJvbCB0aGUgd2FpdCBl
bnRyeSB0aW1lLg0KPiA+ID4gPiA+ID4NCj4gPiA+ID4gPiA+IEVuYWJsZS9EaXNhYmxlIGludGVy
ZmFjZToNCj4gPiA+ID4gPiA+IDAsIGRpc2FibGUuIDEsIGVuYWJsZS4NCj4gPiA+ID4gPiA+IC9z
eXMvZGV2aWNlcy9zeXN0ZW0vY3B1L2NwdVgvcHcyMF9zdGF0ZQ0KPiA+ID4gPiA+ID4gL3N5cy9k
ZXZpY2VzL3N5c3RlbS9jcHUvY3B1WC9hbHRpdmVjX2lkbGUNCj4gPiA+ID4gPiA+DQo+ID4gPiA+
ID4gPiBTZXQgd2FpdCBlbnRyeSBiaXQgaW50ZXJmYWNlOg0KPiA+ID4gPiA+ID4gYml0IHZhbHVl
IHJhbmdlIDB+NjMsIDAgYml0IGlzIE1pbnRpbWUsIDYzIGJpdCBpcyBNYXh0aW1lLg0KPiA+ID4g
PiA+ID4gL3N5cy9kZXZpY2VzL3N5c3RlbS9jcHUvY3B1WC9wdzIwX3dhaXRfZW50cnlfYml0DQo+
ID4gPiA+ID4gPiAvc3lzL2RldmljZXMvc3lzdGVtL2NwdS9jcHVYL2FsdGl2ZWNfaWRsZV93YWl0
X2VudHJ5X2JpdA0KPiA+ID4gPiA+DQo+ID4gPiA+ID4gSSdtIG5vIGZhbiBvZiB0aGUgd2F5IHBv
d2VycGMgZG9lcyBiaXQgbnVtYmVyaW5nLCBidXQgZG9uJ3QgZmxpcA0KPiA+ID4gPiA+IGl0IGFy
b3VuZCBoZXJlIC0tIHlvdSdsbCBqdXN0IGNhdXNlIGNvbmZ1c2lvbi4NCj4gPiA+ID4gPg0KPiA+
ID4gPiBPSy4gMCBiaXQgaXMgbWF4dGltZSwgNjMgYml0IGlzIG1pbnRpbWUuDQo+ID4gPiA+DQo+
ID4gPiA+ID4gQmV0dGVyIHlldCwgdGhpcyBpbnRlcmZhY2Ugc2hvdWxkIHRha2UgcmVhbCB0aW1l
IHVuaXRzIHJhdGhlcg0KPiA+ID4gPiA+IHRoYW4gYSB0aW1lYmFzZSBiaXQuDQo+ID4gPiA+ID4N
Cj4gPiA+ID4gSSB0aGluayB0aGUgcmVhbCB0aW1lIGlzIG5vdCBzdWl0YWJsZSwgYmVjYXVzZSB0
aW1lYmFzZSBiaXQgZG9lcw0KPiA+ID4gPiBub3QgY29ycmVzcG9uZCB3aXRoIHJlYWwgdGltZS4N
Cj4gPiA+DQo+ID4gPiBJdCdzIGEgYml0IHNsb3BweSBkdWUgdG8gaG93IHRoZSBoYXJkd2FyZSB3
b3JrcywgYnV0IHlvdSBjb3VsZA0KPiA+ID4gY29udmVydCBpdCBsaWtlIHlvdSBkaWQgaW4gZWFy
bGllciBwYXRjaGVzLiAgU2VtYW50aWNhbGx5IGl0IHNob3VsZA0KPiA+ID4gcHJvYmFibHkgYmUg
dGhlIG1pbmltdW0gdGltZSB0byB3YWl0IGJlZm9yZSBlbnRlcmluZyB0aGUgbG93IHBvd2VyDQo+
IHN0YXRlLg0KPiA+ID4NCj4gPiBCdXQgdGhlcmUgaGFzIGEgcHJvYmxlbSwgd2UgY2FuJ3QgY29u
dmVydCBiaXQgdG8gdGhlIHJlYWwgdGltZSB3aGVuDQo+IHVzZXIgcmVhZCB0aGlzIHN5c2ZzLg0K
PiA+IExpa2U6DQo+ID4gZWNobyAxMDAwKHVzKSA+IC9zeXMvKi9wdzIwX3dhaXRfZW50cnlfYml0
LCBhZnRlciBjb252ZXJ0IHdlIGdldCBiaXQgaXMNCj4gNDkuDQo+ID4gY2F0IC9zeXMvKi9wdzIw
X3dhaXRfZW50cnlfYml0LCBhZnRlciBjb252ZXJ0IHRoZSB0aW1lIGlzIDE1OTgodXMpLg0KPiA+
DQo+ID4gVGhlIHJlYWQgb3V0IG9mIHRoZSB0aW1lIGlzIG5vdCByZWFsIHRpbWUuIFVubGVzcyB3
ZSBkZWZpbmUgYSB2YXJpYWJsZQ0KPiB0byBzYXZlIHRoZSByZWFsIHRpbWUuDQo+IA0KPiBJdCdz
IG5vdCB0aGUgZW5kIG9mIHRoZSB3b3JsZCBpZiB0aGUgdmFsdWUgaXMgZGlmZmVyZW50IHdoZW4g
cmVhZCBiYWNrLg0KPiBJdCBqdXN0IGdldHMgcm91bmRlZCB1cCB3aGVuIHlvdSB3cml0ZSBpdC4N
Cj4gDQpPaywgbWFrZSBhIHZhcmlhYmxlIHRvIHNhdmUgaXQuDQoNCj4gPiA+ID4gPiBBbHNvLCB5
b3UgZGlzYWJsZSB0aGUgcG93ZXIgc2F2aW5nIG1vZGUgaWYgdGhlIG1heGltdW0gaW50ZXJ2YWwN
Cj4gPiA+ID4gPiBpcyBzZWxlY3RlZCwNCj4gPiA+ID4gSXQncyBub3QgZGlzYWJsZSB0aGUgcHcy
MCBzdGF0ZSBvciBhbHRpdmVjIGlkbGUsIGp1c3QgbWF4LWRlbGF5DQo+ID4gPiA+IGVudHJ5DQo+
ID4gPiB0aW1lLg0KPiA+ID4NCj4gPiA+IE5vLCB0aGUgY29kZSBjaGVja3MgZm9yIHplcm8gdG8g
c2V0IG9yIGNsZWFyIHRoZSBlbmFibGluZyBiaXQgKGUuZy4NCj4gPiA+IFBXMjBfV0FJVCkuDQo+
ID4gPg0KPiA+IFRoZXJlIGhhcyBwdzIwX3N0YXRlL2FsdGl2ZWNfaWRsZSBzeXMgaW50ZXJmYWNl
IHRvIGNvbnRyb2wNCj4gPiAiZW5hYmxlL2Rpc2FibGUiLCBUaGVyZSBpcyBvbmx5IHRvIGNvbnRy
b2wgd2FpdCBiaXQuIERpZCB5b3UgbWVhbg0KPiByZW1vdmUgInB3MjBfc3RhdGUvYWx0aXZlY19p
ZGxlIg0KPiA+IHN5cyBpbnRlcmZhY2UsIGFuZCByZXVzZSAicHcyMF93YWl0X2VudHJ5X2JpdC9h
bHRpdmVjX2lkbGUqIiBzeXMNCj4gaW50ZXJmYWNlPw0KPiA+IFdoZW4gZWNobyB6ZXJvIGludG8g
InB3MjBfd2FpdF9lbnRyeV9iaXQiIHdlIGp1c3QgdG8gZGlzYWJsZSBwdzIwDQo+ID4gc3RhdGUs
IEkgdGhpbmsgdGhhdCBpcyByZWFzb25hYmxlLiA6KQ0KPiANCj4gU29ycnksIEkgbWlzcmVhZCB0
aGUgcGF0Y2ggYW5kIGRpZG4ndCByZWFsaXplIHRoZXNlIHdlcmUgc2VwYXJhdGUNCj4gaW50ZXJm
YWNlcy4NCktlZXAgdGhlICJwdzIwX3N0YXRlL2FsdGl2ZWNfaWRsZSIgaW50ZXJmYWNlcy4NCg0K
LWRvbmdzaGVuZw0K
^ permalink raw reply
* [PATCH v3] powerpc/p1010rdb-pb:make a new dts for p1010rdb-pb
From: Zhao Qiang @ 2013-09-18 4:04 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Zhao Qiang, Shengzhou Liu
P1010RDB-PA and P1010RDB-PB boards use different external PHY
interrupt signals.
So make a new dts for P1010RDB-PB.
Signed-off-by: Shengzhou Liu <Shengzhou.Liu@freescale.com>
Signed-off-by: Zhao Qiang <B45475@freescale.com>
---
Changes for v2:
-Remove phy interrupts for p1010rdb-pb
Changes for v3
-Maintain the phy interrupts p1010rdb-pa and make a new device
tree for p1010rdb-pb
arch/powerpc/boot/dts/p1010rdb-pa.dtsi | 11 ++++++
arch/powerpc/boot/dts/p1010rdb-pb.dts | 67 +++++++++++++++++++++++++++++++++
arch/powerpc/boot/dts/p1010rdb-pb.dtsi | 11 ++++++
arch/powerpc/boot/dts/p1010rdb.dts | 1 +
arch/powerpc/boot/dts/p1010rdb.dtsi | 3 --
arch/powerpc/boot/p1010rdb-pb.dtb | Bin 0 -> 14030 bytes
arch/powerpc/boot/p1010rdb.dtb | Bin 0 -> 14030 bytes
arch/powerpc/platforms/85xx/p1010rdb.c | 29 ++++++++++++++
8 files changed, 119 insertions(+), 3 deletions(-)
create mode 100644 arch/powerpc/boot/dts/p1010rdb-pa.dtsi
create mode 100644 arch/powerpc/boot/dts/p1010rdb-pb.dts
create mode 100644 arch/powerpc/boot/dts/p1010rdb-pb.dtsi
create mode 100644 arch/powerpc/boot/p1010rdb-pb.dtb
create mode 100644 arch/powerpc/boot/p1010rdb.dtb
diff --git a/arch/powerpc/boot/dts/p1010rdb-pa.dtsi b/arch/powerpc/boot/dts/p1010rdb-pa.dtsi
new file mode 100644
index 0000000..122996e
--- /dev/null
+++ b/arch/powerpc/boot/dts/p1010rdb-pa.dtsi
@@ -0,0 +1,11 @@
+&phy0 {
+ interrupts = <3 1 0 0>;
+};
+
+&phy1 {
+ interrupts = <2 1 0 0>;
+};
+
+&phy2 {
+ interrupts = <2 1 0 0>;
+};
diff --git a/arch/powerpc/boot/dts/p1010rdb-pb.dts b/arch/powerpc/boot/dts/p1010rdb-pb.dts
new file mode 100644
index 0000000..0213552
--- /dev/null
+++ b/arch/powerpc/boot/dts/p1010rdb-pb.dts
@@ -0,0 +1,67 @@
+/*
+ * P1010 RDB-PB Device Tree Source
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "fsl/p1010si-pre.dtsi"
+
+/ {
+ model = "fsl,P1010RDB-PB";
+ compatible = "fsl,P1010RDB-PB";
+
+ memory {
+ device_type = "memory";
+ };
+
+ board_ifc: ifc: ifc@ffe1e000 {
+ /* NOR, NAND Flashes and CPLD on board */
+ ranges = <0x0 0x0 0x0 0xee000000 0x02000000
+ 0x1 0x0 0x0 0xff800000 0x00010000
+ 0x3 0x0 0x0 0xffb00000 0x00000020>;
+ reg = <0x0 0xffe1e000 0 0x2000>;
+ };
+
+ board_soc: soc: soc@ffe00000 {
+ ranges = <0x0 0x0 0xffe00000 0x100000>;
+ };
+
+ pci0: pcie@ffe09000 {
+ reg = <0 0xffe09000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@ffe0a000 {
+ reg = <0 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0x80000000
+ 0x2000000 0x0 0x80000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "p1010rdb.dtsi"
+/include/ "p1010rdb-pb.dtsi"
+/include/ "fsl/p1010si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1010rdb-pb.dtsi b/arch/powerpc/boot/dts/p1010rdb-pb.dtsi
new file mode 100644
index 0000000..52cd22e
--- /dev/null
+++ b/arch/powerpc/boot/dts/p1010rdb-pb.dtsi
@@ -0,0 +1,11 @@
+&phy0 {
+ interrupts = <0 1 0 0>;
+};
+
+&phy1 {
+ interrupts = <2 1 0 0>;
+};
+
+&phy2 {
+ interrupts = <1 1 0 0>;
+};
diff --git a/arch/powerpc/boot/dts/p1010rdb.dts b/arch/powerpc/boot/dts/p1010rdb.dts
index b868d22..0980ff0 100644
--- a/arch/powerpc/boot/dts/p1010rdb.dts
+++ b/arch/powerpc/boot/dts/p1010rdb.dts
@@ -63,4 +63,5 @@
};
/include/ "p1010rdb.dtsi"
+/include/ "p1010rdb-pa.dtsi"
/include/ "fsl/p1010si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1010rdb.dtsi b/arch/powerpc/boot/dts/p1010rdb.dtsi
index 7fc3402..2433ae4 100644
--- a/arch/powerpc/boot/dts/p1010rdb.dtsi
+++ b/arch/powerpc/boot/dts/p1010rdb.dtsi
@@ -199,17 +199,14 @@
mdio@24000 {
phy0: ethernet-phy@0 {
- interrupts = <3 1 0 0>;
reg = <0x1>;
};
phy1: ethernet-phy@1 {
- interrupts = <2 1 0 0>;
reg = <0x0>;
};
phy2: ethernet-phy@2 {
- interrupts = <2 1 0 0>;
reg = <0x2>;
};
diff --git a/arch/powerpc/boot/p1010rdb-pb.dtb b/arch/powerpc/boot/p1010rdb-pb.dtb
new file mode 100644
index 0000000000000000000000000000000000000000..3d9865f45acf180ca5154948b43203701a0c247a
GIT binary patch
literal 14030
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
literal 0
HcmV?d00001
diff --git a/arch/powerpc/boot/p1010rdb.dtb b/arch/powerpc/boot/p1010rdb.dtb
new file mode 100644
index 0000000000000000000000000000000000000000..435166cb47f2b3adf04fe9e10376f5737d795962
GIT binary patch
literal 14030
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
PZ<aSB@MZ-5e<Sce9HbcW
literal 0
HcmV?d00001
diff --git a/arch/powerpc/platforms/85xx/p1010rdb.c b/arch/powerpc/platforms/85xx/p1010rdb.c
index 0252961..7d9eab7 100644
--- a/arch/powerpc/platforms/85xx/p1010rdb.c
+++ b/arch/powerpc/platforms/85xx/p1010rdb.c
@@ -82,3 +82,32 @@ define_machine(p1010_rdb) {
.calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
+
+machine_arch_initcall(p1010_rdb_pb, mpc85xx_common_publish_devices);
+machine_arch_initcall(p1010_rdb_pb, swiotlb_setup_bus_notifier);
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init p1010_rdb_pb_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (of_flat_dt_is_compatible(root, "fsl,P1010RDB-PB"))
+ return 1;
+ return 0;
+}
+
+define_machine(p1010_rdb_pb) {
+ .name = "P1010 RDB-PB",
+ .probe = p1010_rdb_pb_probe,
+ .setup_arch = p1010_rdb_setup_arch,
+ .init_IRQ = p1010_rdb_pic_init,
+#ifdef CONFIG_PCI
+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
+#endif
+ .get_irq = mpic_get_irq,
+ .restart = fsl_rstcr_restart,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+};
--
1.8.0
^ permalink raw reply related
* [PATCH v3] powerpc/p1010rdb-pb:make a new dts for p1010rdb-pb
From: Zhao Qiang @ 2013-09-18 4:54 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Zhao Qiang, Shengzhou Liu
P1010RDB-PA and P1010RDB-PB boards use different external PHY
interrupt signals.
So make a new dts for P1010RDB-PB.
Signed-off-by: Shengzhou Liu <Shengzhou.Liu@freescale.com>
Signed-off-by: Zhao Qiang <B45475@freescale.com>
---
Changes for v2:
-Remove phy interrupts for p1010rdb-pb
Changes for v3:
-Maintain the phy interrupts p1010rdb-pa and make a new device
tree for p1010rdb-pb
arch/powerpc/boot/dts/p1010rdb-pa.dtsi | 11 ++++++
arch/powerpc/boot/dts/p1010rdb-pb.dts | 67 ++++++++++++++++++++++++++++++++++
arch/powerpc/boot/dts/p1010rdb-pb.dtsi | 11 ++++++
arch/powerpc/boot/dts/p1010rdb.dts | 1 +
arch/powerpc/boot/dts/p1010rdb.dtsi | 3 --
arch/powerpc/platforms/85xx/p1010rdb.c | 29 +++++++++++++++
6 files changed, 119 insertions(+), 3 deletions(-)
create mode 100644 arch/powerpc/boot/dts/p1010rdb-pa.dtsi
create mode 100644 arch/powerpc/boot/dts/p1010rdb-pb.dts
create mode 100644 arch/powerpc/boot/dts/p1010rdb-pb.dtsi
diff --git a/arch/powerpc/boot/dts/p1010rdb-pa.dtsi b/arch/powerpc/boot/dts/p1010rdb-pa.dtsi
new file mode 100644
index 0000000..122996e
--- /dev/null
+++ b/arch/powerpc/boot/dts/p1010rdb-pa.dtsi
@@ -0,0 +1,11 @@
+&phy0 {
+ interrupts = <3 1 0 0>;
+};
+
+&phy1 {
+ interrupts = <2 1 0 0>;
+};
+
+&phy2 {
+ interrupts = <2 1 0 0>;
+};
diff --git a/arch/powerpc/boot/dts/p1010rdb-pb.dts b/arch/powerpc/boot/dts/p1010rdb-pb.dts
new file mode 100644
index 0000000..0213552
--- /dev/null
+++ b/arch/powerpc/boot/dts/p1010rdb-pb.dts
@@ -0,0 +1,67 @@
+/*
+ * P1010 RDB-PB Device Tree Source
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "fsl/p1010si-pre.dtsi"
+
+/ {
+ model = "fsl,P1010RDB-PB";
+ compatible = "fsl,P1010RDB-PB";
+
+ memory {
+ device_type = "memory";
+ };
+
+ board_ifc: ifc: ifc@ffe1e000 {
+ /* NOR, NAND Flashes and CPLD on board */
+ ranges = <0x0 0x0 0x0 0xee000000 0x02000000
+ 0x1 0x0 0x0 0xff800000 0x00010000
+ 0x3 0x0 0x0 0xffb00000 0x00000020>;
+ reg = <0x0 0xffe1e000 0 0x2000>;
+ };
+
+ board_soc: soc: soc@ffe00000 {
+ ranges = <0x0 0x0 0xffe00000 0x100000>;
+ };
+
+ pci0: pcie@ffe09000 {
+ reg = <0 0xffe09000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@ffe0a000 {
+ reg = <0 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0x80000000
+ 0x2000000 0x0 0x80000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "p1010rdb.dtsi"
+/include/ "p1010rdb-pb.dtsi"
+/include/ "fsl/p1010si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1010rdb-pb.dtsi b/arch/powerpc/boot/dts/p1010rdb-pb.dtsi
new file mode 100644
index 0000000..52cd22e
--- /dev/null
+++ b/arch/powerpc/boot/dts/p1010rdb-pb.dtsi
@@ -0,0 +1,11 @@
+&phy0 {
+ interrupts = <0 1 0 0>;
+};
+
+&phy1 {
+ interrupts = <2 1 0 0>;
+};
+
+&phy2 {
+ interrupts = <1 1 0 0>;
+};
diff --git a/arch/powerpc/boot/dts/p1010rdb.dts b/arch/powerpc/boot/dts/p1010rdb.dts
index b868d22..0980ff0 100644
--- a/arch/powerpc/boot/dts/p1010rdb.dts
+++ b/arch/powerpc/boot/dts/p1010rdb.dts
@@ -63,4 +63,5 @@
};
/include/ "p1010rdb.dtsi"
+/include/ "p1010rdb-pa.dtsi"
/include/ "fsl/p1010si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1010rdb.dtsi b/arch/powerpc/boot/dts/p1010rdb.dtsi
index 7fc3402..2433ae4 100644
--- a/arch/powerpc/boot/dts/p1010rdb.dtsi
+++ b/arch/powerpc/boot/dts/p1010rdb.dtsi
@@ -199,17 +199,14 @@
mdio@24000 {
phy0: ethernet-phy@0 {
- interrupts = <3 1 0 0>;
reg = <0x1>;
};
phy1: ethernet-phy@1 {
- interrupts = <2 1 0 0>;
reg = <0x0>;
};
phy2: ethernet-phy@2 {
- interrupts = <2 1 0 0>;
reg = <0x2>;
};
diff --git a/arch/powerpc/platforms/85xx/p1010rdb.c b/arch/powerpc/platforms/85xx/p1010rdb.c
index 0252961..7d9eab7 100644
--- a/arch/powerpc/platforms/85xx/p1010rdb.c
+++ b/arch/powerpc/platforms/85xx/p1010rdb.c
@@ -82,3 +82,32 @@ define_machine(p1010_rdb) {
.calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
+
+machine_arch_initcall(p1010_rdb_pb, mpc85xx_common_publish_devices);
+machine_arch_initcall(p1010_rdb_pb, swiotlb_setup_bus_notifier);
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init p1010_rdb_pb_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (of_flat_dt_is_compatible(root, "fsl,P1010RDB-PB"))
+ return 1;
+ return 0;
+}
+
+define_machine(p1010_rdb_pb) {
+ .name = "P1010 RDB-PB",
+ .probe = p1010_rdb_pb_probe,
+ .setup_arch = p1010_rdb_setup_arch,
+ .init_IRQ = p1010_rdb_pic_init,
+#ifdef CONFIG_PCI
+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
+#endif
+ .get_irq = mpic_get_irq,
+ .restart = fsl_rstcr_restart,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+};
--
1.8.0
^ permalink raw reply related
* Re: [PATCH 1/8][v4] powerpc/perf: Rename Power8 macros to start with PME
From: Anshuman Khandual @ 2013-09-18 5:24 UTC (permalink / raw)
To: Sukadev Bhattiprolu
Cc: linuxppc-dev, Michael Ellerman, Paul Mackerras, linux-kernel,
Stephane Eranian
In-Reply-To: <1379119755-21025-2-git-send-email-sukadev@linux.vnet.ibm.com>
On 09/14/2013 06:19 AM, Sukadev Bhattiprolu wrote:
> We use helpers like GENERIC_EVENT_ATTR() to list the generic events in
> sysfs. To avoid name collisions, GENERIC_EVENT_ATTR() requires the perf
> event macros to start with PME.
We got all the raw event codes covered for P7 with the help of power7-events-list.h
enumeration.
/*
* Power7 event codes.
*/
#define EVENT(_name, _code) \
PME_##_name = _code,
enum {
#include "power7-events-list.h"
};
#undef EVENT
Just wondering if its a good idea to name change these selected macros to be consumed
by GENERIC_EVENT_ATTR() right here for this purpose or we need to get the comprehensive
list of raw events for P8 first. Just an idea.
Regards
Anshuman
^ permalink raw reply
* RE: [PATCH v3] powerpc/p1010rdb-pb:make a new dts for p1010rdb-pb
From: Liu Shengzhou-B36685 @ 2013-09-18 5:43 UTC (permalink / raw)
To: Zhao Qiang-B45475; +Cc: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1379480097-11698-1-git-send-email-B45475@freescale.com>
> -----Original Message-----
> From: Zhao Qiang-B45475
> Sent: Wednesday, September 18, 2013 12:55 PM
> To: linuxppc-dev@lists.ozlabs.org
> Cc: Zhao Qiang-B45475; Liu Shengzhou-B36685
> Subject: [PATCH v3] powerpc/p1010rdb-pb:make a new dts for p1010rdb-pb
>=20
> P1010RDB-PA and P1010RDB-PB boards use different external PHY interrupt s=
ignals.
> So make a new dts for P1010RDB-PB.
>=20
> Signed-off-by: Shengzhou Liu <Shengzhou.Liu@freescale.com>
> Signed-off-by: Zhao Qiang <B45475@freescale.com>
> ---
> Changes for v2:
> -Remove phy interrupts for p1010rdb-pb
> Changes for v3:
> -Maintain the phy interrupts p1010rdb-pa and make a new device
> tree for p1010rdb-pb
>=20
> arch/powerpc/boot/dts/p1010rdb-pa.dtsi | 11 ++++++
> arch/powerpc/boot/dts/p1010rdb-pb.dts | 67 +++++++++++++++++++++++++++++=
+++++
> arch/powerpc/boot/dts/p1010rdb-pb.dtsi | 11 ++++++
> arch/powerpc/boot/dts/p1010rdb.dts | 1 +
> arch/powerpc/boot/dts/p1010rdb.dtsi | 3 --
> arch/powerpc/platforms/85xx/p1010rdb.c | 29 +++++++++++++++
> 6 files changed, 119 insertions(+), 3 deletions(-) create mode 100644
> arch/powerpc/boot/dts/p1010rdb-pa.dtsi
> create mode 100644 arch/powerpc/boot/dts/p1010rdb-pb.dts
> create mode 100644 arch/powerpc/boot/dts/p1010rdb-pb.dtsi
>=20
Don't touch p1010rdb.c, create two p1010rdb-pa.dts and p1010rdb-pb.dts, whi=
ch include the common p1010rdb.dtsi.
Combine original p1010rdb.dts and p1010rdb.dtsi into new p1010rdb.dtsi with=
removing compatible part.
Place phy node and following part in p1010rdb-pa.dts and p1010rdb-pb.dts.
/ {
model =3D "fsl,P1010RDB-PA";
compatible =3D "fsl,P1010RDB";
}
/ {
model =3D "fsl,P1010RDB-PB";
compatible =3D "fsl,P1010RDB";
}
-Shengzhou
^ permalink raw reply
* Re: [PATCH v2 2/6] PCI/MSI: Factor out pci_get_msi_cap() interface
From: Alexander Gordeev @ 2013-09-18 9:48 UTC (permalink / raw)
To: Michael Ellerman
Cc: linuxppc-dev, Joerg Roedel, x86@kernel.org,
linux-kernel@vger.kernel.org, linux-ide@vger.kernel.org,
Jan Beulich, linux-pci@vger.kernel.org, Tejun Heo, Bjorn Helgaas,
Ingo Molnar
In-Reply-To: <20130917143022.GA7707@concordia>
On Wed, Sep 18, 2013 at 12:30:23AM +1000, Michael Ellerman wrote:
> How about no?
>
> We have a small number of MSIs available, limited by hardware &
> firmware, if we don't impose a quota then the first device that probes
> will get most/all of the MSIs and other devices miss out.
Out of curiosity - how pSeries has had done it without quotas before
448e2ca ("powerpc/pseries: Implement a quota system for MSIs")?
> Anyway I don't see what problem you're trying to solve? I agree the
> -ve/0/+ve return value pattern is ugly, but it's hardly the end of the
> world.
Well, the interface recently has been re-classified from "ugly" to
"unnecessarily complex and actively harmful" in Tejun's words ;)
Indeed, I checked most of the drivers and it is incredible how people
are creative in misusing the interface: from innocent pci_disable_msix()
calls when if pci_enable_msix() failed to assuming MSI-Xs were enabled
if pci_enable_msix() returned a positive value (apparently untested).
Roughly third of the drivers just do not care and bail out once
pci_enable_msix() has not succeeded. Not sure how many of these are
mandated by the hardware.
Another quite common pattern is a call to pci_enable_msix() to figure out
the number of MSI-Xs available and a repeated call of pci_enable_msix()
to enable those MSI-Xs, this time.
The last pattern makes most of sense to me and could be updated with a more
clear sequence - a call to (bit modified) pci_msix_table_size() followed
by a call to pci_enable_msix(). I think this pattern can effectively
supersede the currently recommended "loop" practice.
But as pSeries quota is still required I propose to introduce a new interface
pci_get_msix_limit() that combines pci_msix_table_size() and (also new)
arch_get_msix_limit(). The latter would check the quota thing in case of
pSeries and none in case of all other architectures.
The recommended practice would be:
/*
* Retrieving 'nvec' by means other than pci_msix_table_size()
*/
rc = pci_get_msix_limit(pdev);
if (rc < 0)
return rc;
/*
* nvec = min(rc, nvec);
*/
for (i = 0; i < nvec; i++)
msix_entry[i].entry = i;
rc = pci_enable_msix(pdev, msix_entry, nvec);
if (rc)
return rc;
Thoughts?
> cheers
--
Regards,
Alexander Gordeev
agordeev@redhat.com
^ permalink raw reply
* [PATCH v10 0/3] DMA: Freescale: Add support for 8-channel DMA engine
From: hongbo.zhang @ 2013-09-18 10:15 UTC (permalink / raw)
To: rob.herring, pawel.moll, mark.rutland, swarren, ian.campbell,
vinod.koul, djbw
Cc: Hongbo Zhang, devicetree, linuxppc-dev, linux-kernel
From: Hongbo Zhang <hongbo.zhang@freescale.com>
Hi DMA and DT maintainers, please have a look at these V10 patches.
Freescale QorIQ T4 and B4 introduce new 8-channel DMA engines, this patch set
adds support this DMA engine.
V9->V10 changes:
- update binding description text, mainly about the reg property and also Elo3
DMA controller specification
V8->V9 changes:
- add "Acked-by: Mark Rutland <mark.rutland@arm.com>" into patch [1/3]
- update reg entry <0x100300 0x4 0x100600 0x4> to two seperate ones
<0x100300 0x4>, <0x100600 0x4> in patch [2/3]
- and also use "QorIQ Elo3 DMA" to mention previous "QorIQ DMA" in [2/3]
V7->V8 changes:
- change the word "mapping" to "specifier" for reg and interrupts description
V6->V7 changes:
- only remove unnecessary "CHIP-dma" explanations in [1/3]
V5->V6 changes:
- minor updates of descriptions in binding document and Kconfig
- remove [4/4], that should be another patch in future
V4->V5 changes:
- update description in the dt binding document, to make it more resonable
- add new patch [4/4] to eliminate a compiling warning which already exists
for a long time
V3->V4 changes:
- introduce new patch [1/3] to revise the legacy dma binding document
- and then add new paragraph to describe new dt node binding in [2/3]
- rebase to latest kernel v3.11-rc1
V2->V3 changes:
- edit Documentation/devicetree/bindings/powerpc/fsl/dma.txt
- edit text string in Kconfig and the driver files, using "elo series" to
mention all the current "elo*"
V1->V2 changes:
- removed the codes handling the register dgsr1, since it isn't used currently
- renamed the DMA DT compatible to "fsl,elo3-dma"
- renamed the new dts files to "elo3-dma-<n>.dtsi"
Hongbo Zhang (3):
DMA: Freescale: revise device tree binding document
DMA: Freescale: Add new 8-channel DMA engine device tree nodes
DMA: Freescale: update driver to support 8-channel DMA engine
.../devicetree/bindings/powerpc/fsl/dma.txt | 137 ++++++++++++++------
arch/powerpc/boot/dts/fsl/b4si-post.dtsi | 4 +-
arch/powerpc/boot/dts/fsl/elo3-dma-0.dtsi | 82 ++++++++++++
arch/powerpc/boot/dts/fsl/elo3-dma-1.dtsi | 82 ++++++++++++
arch/powerpc/boot/dts/fsl/t4240si-post.dtsi | 4 +-
drivers/dma/Kconfig | 9 +-
drivers/dma/fsldma.c | 9 +-
drivers/dma/fsldma.h | 2 +-
8 files changed, 280 insertions(+), 49 deletions(-)
create mode 100644 arch/powerpc/boot/dts/fsl/elo3-dma-0.dtsi
create mode 100644 arch/powerpc/boot/dts/fsl/elo3-dma-1.dtsi
--
1.7.9.5
^ permalink raw reply
* [PATCH v10 1/3] DMA: Freescale: revise device tree binding document
From: hongbo.zhang @ 2013-09-18 10:15 UTC (permalink / raw)
To: rob.herring, pawel.moll, mark.rutland, swarren, ian.campbell,
vinod.koul, djbw
Cc: Hongbo Zhang, devicetree, linuxppc-dev, linux-kernel
In-Reply-To: <1379499333-4745-1-git-send-email-hongbo.zhang@freescale.com>
From: Hongbo Zhang <hongbo.zhang@freescale.com>
This patch updates the discription of each type of DMA controller and its
channels, it is preparation for adding another new DMA controller binding, it
also fixes some defects of indent for text alignment at the same time.
Signed-off-by: Hongbo Zhang <hongbo.zhang@freescale.com>
Acked-by: Mark Rutland <mark.rutland@arm.com>
---
.../devicetree/bindings/powerpc/fsl/dma.txt | 68 +++++++++-----------
1 file changed, 31 insertions(+), 37 deletions(-)
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/dma.txt b/Documentation/devicetree/bindings/powerpc/fsl/dma.txt
index 2a4b4bc..0584168 100644
--- a/Documentation/devicetree/bindings/powerpc/fsl/dma.txt
+++ b/Documentation/devicetree/bindings/powerpc/fsl/dma.txt
@@ -1,33 +1,30 @@
-* Freescale 83xx DMA Controller
+* Freescale DMA Controllers
-Freescale PowerPC 83xx have on chip general purpose DMA controllers.
+** Freescale Elo DMA Controller
+ This is a little-endian 4-channel DMA controller, used in Freescale mpc83xx
+ series chips such as mpc8315, mpc8349, mpc8379 etc.
Required properties:
-- compatible : compatible list, contains 2 entries, first is
- "fsl,CHIP-dma", where CHIP is the processor
- (mpc8349, mpc8360, etc.) and the second is
- "fsl,elo-dma"
-- reg : <registers mapping for DMA general status reg>
-- ranges : Should be defined as specified in 1) to describe the
- DMA controller channels.
+- compatible : must include "fsl,elo-dma"
+- reg : DMA General Status Register, i.e. DGSR which contains
+ status for all the 4 DMA channels
+- ranges : describes the mapping between the address space of the
+ DMA channels and the address space of the DMA controller
- cell-index : controller index. 0 for controller @ 0x8100
-- interrupts : <interrupt mapping for DMA IRQ>
+- interrupts : interrupt specifier for DMA IRQ
- interrupt-parent : optional, if needed for interrupt mapping
-
- DMA channel nodes:
- - compatible : compatible list, contains 2 entries, first is
- "fsl,CHIP-dma-channel", where CHIP is the processor
- (mpc8349, mpc8350, etc.) and the second is
- "fsl,elo-dma-channel". However, see note below.
- - reg : <registers mapping for channel>
- - cell-index : dma channel index starts at 0.
+ - compatible : must include "fsl,elo-dma-channel"
+ However, see note below.
+ - reg : DMA channel specific registers
+ - cell-index : DMA channel index starts at 0.
Optional properties:
- - interrupts : <interrupt mapping for DMA channel IRQ>
- (on 83xx this is expected to be identical to
- the interrupts property of the parent node)
+ - interrupts : interrupt specifier for DMA channel IRQ
+ (on 83xx this is expected to be identical to
+ the interrupts property of the parent node)
- interrupt-parent : optional, if needed for interrupt mapping
Example:
@@ -70,30 +67,27 @@ Example:
};
};
-* Freescale 85xx/86xx DMA Controller
-
-Freescale PowerPC 85xx/86xx have on chip general purpose DMA controllers.
+** Freescale EloPlus DMA Controller
+ This is a 4-channel DMA controller with extended addresses and chaining,
+ mainly used in Freescale mpc85xx/86xx, Pxxx and BSC series chips, such as
+ mpc8540, mpc8641 p4080, bsc9131 etc.
Required properties:
-- compatible : compatible list, contains 2 entries, first is
- "fsl,CHIP-dma", where CHIP is the processor
- (mpc8540, mpc8540, etc.) and the second is
- "fsl,eloplus-dma"
-- reg : <registers mapping for DMA general status reg>
+- compatible : must include "fsl,eloplus-dma"
+- reg : DMA General Status Register, i.e. DGSR which contains
+ status for all the 4 DMA channels
- cell-index : controller index. 0 for controller @ 0x21000,
1 for controller @ 0xc000
-- ranges : Should be defined as specified in 1) to describe the
- DMA controller channels.
+- ranges : describes the mapping between the address space of the
+ DMA channels and the address space of the DMA controller
- DMA channel nodes:
- - compatible : compatible list, contains 2 entries, first is
- "fsl,CHIP-dma-channel", where CHIP is the processor
- (mpc8540, mpc8560, etc.) and the second is
- "fsl,eloplus-dma-channel". However, see note below.
- - cell-index : dma channel index starts at 0.
- - reg : <registers mapping for channel>
- - interrupts : <interrupt mapping for DMA channel IRQ>
+ - compatible : must include "fsl,eloplus-dma-channel"
+ However, see note below.
+ - cell-index : DMA channel index starts at 0.
+ - reg : DMA channel specific registers
+ - interrupts : interrupt specifier for DMA channel IRQ
- interrupt-parent : optional, if needed for interrupt mapping
Example:
--
1.7.9.5
^ permalink raw reply related
* [PATCH v10 2/3] DMA: Freescale: Add new 8-channel DMA engine device tree nodes
From: hongbo.zhang @ 2013-09-18 10:15 UTC (permalink / raw)
To: rob.herring, pawel.moll, mark.rutland, swarren, ian.campbell,
vinod.koul, djbw
Cc: Hongbo Zhang, devicetree, linuxppc-dev, linux-kernel
In-Reply-To: <1379499333-4745-1-git-send-email-hongbo.zhang@freescale.com>
From: Hongbo Zhang <hongbo.zhang@freescale.com>
Freescale QorIQ T4 and B4 introduce new 8-channel DMA engines, this patch adds
the device tree nodes for them.
Signed-off-by: Hongbo Zhang <hongbo.zhang@freescale.com>
---
.../devicetree/bindings/powerpc/fsl/dma.txt | 69 ++++++++++++++++
arch/powerpc/boot/dts/fsl/b4si-post.dtsi | 4 +-
arch/powerpc/boot/dts/fsl/elo3-dma-0.dtsi | 82 ++++++++++++++++++++
arch/powerpc/boot/dts/fsl/elo3-dma-1.dtsi | 82 ++++++++++++++++++++
arch/powerpc/boot/dts/fsl/t4240si-post.dtsi | 4 +-
5 files changed, 237 insertions(+), 4 deletions(-)
create mode 100644 arch/powerpc/boot/dts/fsl/elo3-dma-0.dtsi
create mode 100644 arch/powerpc/boot/dts/fsl/elo3-dma-1.dtsi
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/dma.txt b/Documentation/devicetree/bindings/powerpc/fsl/dma.txt
index 0584168..414fe42 100644
--- a/Documentation/devicetree/bindings/powerpc/fsl/dma.txt
+++ b/Documentation/devicetree/bindings/powerpc/fsl/dma.txt
@@ -128,6 +128,75 @@ Example:
};
};
+** Freescale Elo3 DMA Controller
+ DMA controller which has same function as EloPlus except that Elo3 has 8
+ channels while EloPlus has only 4, it is used in Freescale Txxx and Bxxx
+ series chips, such as t1040, t4240, b4860.
+
+Required properties:
+
+- compatible : must include "fsl,elo3-dma"
+- reg : DMA General Status Registers, i.e. DGSR0 which contains
+ status for channel 1~4, and DGSR1 for channel 5~8
+- ranges : describes the mapping between the address space of the
+ DMA channels and the address space of the DMA controller
+
+- DMA channel nodes:
+ - compatible : must include "fsl,eloplus-dma-channel"
+ - reg : DMA channel specific registers
+ - interrupts : interrupt specifier for DMA channel IRQ
+ - interrupt-parent : optional, if needed for interrupt mapping
+
+Example:
+dma@100300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,elo3-dma";
+ reg = <0x100300 0x4>,
+ <0x100600 0x4>;
+ ranges = <0x0 0x100100 0x500>;
+ dma-channel@0 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ interrupts = <28 2 0 0>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ interrupts = <29 2 0 0>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ interrupts = <30 2 0 0>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ interrupts = <31 2 0 0>;
+ };
+ dma-channel@300 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x300 0x80>;
+ interrupts = <76 2 0 0>;
+ };
+ dma-channel@380 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x380 0x80>;
+ interrupts = <77 2 0 0>;
+ };
+ dma-channel@400 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x400 0x80>;
+ interrupts = <78 2 0 0>;
+ };
+ dma-channel@480 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x480 0x80>;
+ interrupts = <79 2 0 0>;
+ };
+};
+
Note on DMA channel compatible properties: The compatible property must say
"fsl,elo-dma-channel" or "fsl,eloplus-dma-channel" to be used by the Elo DMA
driver (fsldma). Any DMA channel used by fsldma cannot be used by another
diff --git a/arch/powerpc/boot/dts/fsl/b4si-post.dtsi b/arch/powerpc/boot/dts/fsl/b4si-post.dtsi
index 7399154..ea53ea1 100644
--- a/arch/powerpc/boot/dts/fsl/b4si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/b4si-post.dtsi
@@ -223,13 +223,13 @@
reg = <0xe2000 0x1000>;
};
-/include/ "qoriq-dma-0.dtsi"
+/include/ "elo3-dma-0.dtsi"
dma@100300 {
fsl,iommu-parent = <&pamu0>;
fsl,liodn-reg = <&guts 0x580>; /* DMA1LIODNR */
};
-/include/ "qoriq-dma-1.dtsi"
+/include/ "elo3-dma-1.dtsi"
dma@101300 {
fsl,iommu-parent = <&pamu0>;
fsl,liodn-reg = <&guts 0x584>; /* DMA2LIODNR */
diff --git a/arch/powerpc/boot/dts/fsl/elo3-dma-0.dtsi b/arch/powerpc/boot/dts/fsl/elo3-dma-0.dtsi
new file mode 100644
index 0000000..3c210e0
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/elo3-dma-0.dtsi
@@ -0,0 +1,82 @@
+/*
+ * QorIQ Elo3 DMA device tree stub [ controller @ offset 0x100000 ]
+ *
+ * Copyright 2013 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+dma0: dma@100300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,elo3-dma";
+ reg = <0x100300 0x4>,
+ <0x100600 0x4>;
+ ranges = <0x0 0x100100 0x500>;
+ dma-channel@0 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ interrupts = <28 2 0 0>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ interrupts = <29 2 0 0>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ interrupts = <30 2 0 0>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ interrupts = <31 2 0 0>;
+ };
+ dma-channel@300 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x300 0x80>;
+ interrupts = <76 2 0 0>;
+ };
+ dma-channel@380 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x380 0x80>;
+ interrupts = <77 2 0 0>;
+ };
+ dma-channel@400 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x400 0x80>;
+ interrupts = <78 2 0 0>;
+ };
+ dma-channel@480 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x480 0x80>;
+ interrupts = <79 2 0 0>;
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/elo3-dma-1.dtsi b/arch/powerpc/boot/dts/fsl/elo3-dma-1.dtsi
new file mode 100644
index 0000000..cccf3bb
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/elo3-dma-1.dtsi
@@ -0,0 +1,82 @@
+/*
+ * QorIQ Elo3 DMA device tree stub [ controller @ offset 0x101000 ]
+ *
+ * Copyright 2013 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+dma1: dma@101300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,elo3-dma";
+ reg = <0x101300 0x4>,
+ <0x101600 0x4>;
+ ranges = <0x0 0x101100 0x500>;
+ dma-channel@0 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ interrupts = <32 2 0 0>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ interrupts = <33 2 0 0>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ interrupts = <34 2 0 0>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ interrupts = <35 2 0 0>;
+ };
+ dma-channel@300 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x300 0x80>;
+ interrupts = <80 2 0 0>;
+ };
+ dma-channel@380 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x380 0x80>;
+ interrupts = <81 2 0 0>;
+ };
+ dma-channel@400 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x400 0x80>;
+ interrupts = <82 2 0 0>;
+ };
+ dma-channel@480 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x480 0x80>;
+ interrupts = <83 2 0 0>;
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
index bd611a9..ec95c60 100644
--- a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
@@ -387,8 +387,8 @@
reg = <0xea000 0x4000>;
};
-/include/ "qoriq-dma-0.dtsi"
-/include/ "qoriq-dma-1.dtsi"
+/include/ "elo3-dma-0.dtsi"
+/include/ "elo3-dma-1.dtsi"
/include/ "qoriq-espi-0.dtsi"
spi@110000 {
--
1.7.9.5
^ permalink raw reply related
* [PATCH v10 3/3] DMA: Freescale: update driver to support 8-channel DMA engine
From: hongbo.zhang @ 2013-09-18 10:15 UTC (permalink / raw)
To: rob.herring, pawel.moll, mark.rutland, swarren, ian.campbell,
vinod.koul, djbw
Cc: Hongbo Zhang, devicetree, linuxppc-dev, linux-kernel
In-Reply-To: <1379499333-4745-1-git-send-email-hongbo.zhang@freescale.com>
From: Hongbo Zhang <hongbo.zhang@freescale.com>
This patch adds support to 8-channel DMA engine, thus the driver works for both
the new 8-channel and the legacy 4-channel DMA engines.
Signed-off-by: Hongbo Zhang <hongbo.zhang@freescale.com>
---
drivers/dma/Kconfig | 9 +++++----
drivers/dma/fsldma.c | 9 ++++++---
drivers/dma/fsldma.h | 2 +-
3 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 6825957..3979c65 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -89,14 +89,15 @@ config AT_HDMAC
Support the Atmel AHB DMA controller.
config FSL_DMA
- tristate "Freescale Elo and Elo Plus DMA support"
+ tristate "Freescale Elo series DMA support"
depends on FSL_SOC
select DMA_ENGINE
select ASYNC_TX_ENABLE_CHANNEL_SWITCH
---help---
- Enable support for the Freescale Elo and Elo Plus DMA controllers.
- The Elo is the DMA controller on some 82xx and 83xx parts, and the
- Elo Plus is the DMA controller on 85xx and 86xx parts.
+ Enable support for the Freescale Elo series DMA controllers.
+ The Elo is the DMA controller on some mpc82xx and mpc83xx parts, the
+ EloPlus is on mpc85xx and mpc86xx and Pxxx parts, and the Elo3 is on
+ some Txxx and Bxxx parts.
config MPC512X_DMA
tristate "Freescale MPC512x built-in DMA engine support"
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 49e8fbd..16a9a48 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -1261,7 +1261,9 @@ static int fsl_dma_chan_probe(struct fsldma_device *fdev,
WARN_ON(fdev->feature != chan->feature);
chan->dev = fdev->dev;
- chan->id = ((res.start - 0x100) & 0xfff) >> 7;
+ chan->id = (res.start & 0xfff) < 0x300 ?
+ ((res.start - 0x100) & 0xfff) >> 7 :
+ ((res.start - 0x200) & 0xfff) >> 7;
if (chan->id >= FSL_DMA_MAX_CHANS_PER_DEVICE) {
dev_err(fdev->dev, "too many channels for device\n");
err = -EINVAL;
@@ -1434,6 +1436,7 @@ static int fsldma_of_remove(struct platform_device *op)
}
static const struct of_device_id fsldma_of_ids[] = {
+ { .compatible = "fsl,elo3-dma", },
{ .compatible = "fsl,eloplus-dma", },
{ .compatible = "fsl,elo-dma", },
{}
@@ -1455,7 +1458,7 @@ static struct platform_driver fsldma_of_driver = {
static __init int fsldma_init(void)
{
- pr_info("Freescale Elo / Elo Plus DMA driver\n");
+ pr_info("Freescale Elo series DMA driver\n");
return platform_driver_register(&fsldma_of_driver);
}
@@ -1467,5 +1470,5 @@ static void __exit fsldma_exit(void)
subsys_initcall(fsldma_init);
module_exit(fsldma_exit);
-MODULE_DESCRIPTION("Freescale Elo / Elo Plus DMA driver");
+MODULE_DESCRIPTION("Freescale Elo series DMA driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h
index f5c3879..1ffc244 100644
--- a/drivers/dma/fsldma.h
+++ b/drivers/dma/fsldma.h
@@ -112,7 +112,7 @@ struct fsldma_chan_regs {
};
struct fsldma_chan;
-#define FSL_DMA_MAX_CHANS_PER_DEVICE 4
+#define FSL_DMA_MAX_CHANS_PER_DEVICE 8
struct fsldma_device {
void __iomem *regs; /* DGSR register base */
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH 8/8][v4] powerpc/perf: Export Power7 memory hierarchy info to user space.
From: Anshuman Khandual @ 2013-09-18 10:47 UTC (permalink / raw)
To: Sukadev Bhattiprolu
Cc: Stephane Eranian, linuxppc-dev, Paul Mackerras, linux-kernel,
Michael Ellerman
In-Reply-To: <1379119755-21025-9-git-send-email-sukadev@linux.vnet.ibm.com>
On 09/14/2013 06:19 AM, Sukadev Bhattiprolu wrote:
> On Power7, the DCACHE_SRC field in MMCRA register identifies the memory
> hierarchy level (eg: L2, L3 etc) from which a data-cache miss for a
> marked instruction was satisfied.
>
> Use the 'perf_mem_data_src' object to export this hierarchy level to user
> space. Some memory hierarchy levels in Power7 don't map into the arch-neutral
> levels. However, since newer generation of the processor (i.e. Power8) uses
> fewer levels than in Power7, we don't really need to define new hierarchy
> levels just for Power7.
>
> We instead, map as many levels as possible and approximate the rest. See
> comments near dcache-src_map[] in the patch.
>
> Usage:
>
> perf record -d -e 'cpu/PM_MRK_GRP_CMPL/' <application>
> perf report -n --mem-mode --sort=mem,sym,dso,symbol_daddr,dso_daddr"
>
> For samples involving load/store instructions, the memory
> hierarchy level is shown as "L1 hit", "Remote RAM hit" etc.
> # or
>
> perf record --data <application>
> perf report -D
>
> Sample records contain a 'data_src' field which encodes the
> memory hierarchy level: Eg: data_src 0x442 indicates
> MEM_OP_LOAD, MEM_LVL_HIT, MEM_LVL_L2 (i.e load hit L2).
Successfully built and boot tested this entire patchset both on a P7 and P8 system.
Running some sample tests with ebizzy micro benchmark. Till now got only 0x142 and
0x0 values for data_src object for the sample records. Will experiment around bit
more on P7 and P8 systems and post the results.
Regards
Anshuman
^ permalink raw reply
* [PATCH 0/2] move of_find_next_cache_node to DT core
From: Sudeep KarkadaNagesha @ 2013-09-18 10:53 UTC (permalink / raw)
To: devicetree, linuxppc-dev; +Cc: Sudeep KarkadaNagesha
From: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
Hi,
The cache bindings are generic and used by many other architectures
apart from PPC. These patches fixes and move the existing definition
of of_find_next_cache_node to DT common code.
Regards,
Sudeep
Sudeep KarkadaNagesha (2):
powerpc: remove big endianness assumption in of_find_next_cache_node
of: move definition of of_find_next_cache_node into common code.
arch/powerpc/include/asm/prom.h | 3 ---
arch/powerpc/kernel/prom.c | 31 -------------------------------
drivers/of/base.c | 31 +++++++++++++++++++++++++++++++
include/linux/of.h | 2 ++
4 files changed, 33 insertions(+), 34 deletions(-)
--
1.8.1.2
^ permalink raw reply
* [PATCH 1/2] powerpc: remove big endianness assumption in of_find_next_cache_node
From: Sudeep KarkadaNagesha @ 2013-09-18 10:53 UTC (permalink / raw)
To: devicetree, linuxppc-dev; +Cc: Sudeep KarkadaNagesha, Rob Herring, Grant Likely
In-Reply-To: <1379501585-12532-1-git-send-email-Sudeep.KarkadaNagesha@arm.com>
From: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
Currently big endianness of the device tree data is assumed in
of_find_next_cache_node for 'handle' when calling of_find_node_by_phandle.
In preparation to move this function to common code, this patch fixes
the endianness using 'be32_to_cpup'
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
---
arch/powerpc/kernel/prom.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index b7634ce..09be275 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -778,7 +778,7 @@ struct device_node *of_find_next_cache_node(struct device_node *np)
handle = of_get_property(np, "next-level-cache", NULL);
if (handle)
- return of_find_node_by_phandle(*handle);
+ return of_find_node_by_phandle(be32_to_cpup(handle));
/* OF on pmac has nodes instead of properties named "l2-cache"
* beneath CPU nodes.
--
1.8.1.2
^ permalink raw reply related
* [PATCH 2/2] of: move definition of of_find_next_cache_node into common code.
From: Sudeep KarkadaNagesha @ 2013-09-18 10:53 UTC (permalink / raw)
To: devicetree, linuxppc-dev; +Cc: Sudeep KarkadaNagesha, Rob Herring, Grant Likely
In-Reply-To: <1379501585-12532-1-git-send-email-Sudeep.KarkadaNagesha@arm.com>
From: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
Since the definition of_find_next_cache_node is architecture independent,
the existing definition in powerpc can be moved to driver/of/base.c
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
---
arch/powerpc/include/asm/prom.h | 3 ---
arch/powerpc/kernel/prom.c | 31 -------------------------------
drivers/of/base.c | 31 +++++++++++++++++++++++++++++++
include/linux/of.h | 2 ++
4 files changed, 33 insertions(+), 34 deletions(-)
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index 7d0c7f3..bf09e5a 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -44,9 +44,6 @@ void of_parse_dma_window(struct device_node *dn, const __be32 *dma_window,
extern void kdump_move_device_tree(void);
-/* cache lookup */
-struct device_node *of_find_next_cache_node(struct device_node *np);
-
#ifdef CONFIG_NUMA
extern int of_node_to_nid(struct device_node *device);
#else
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 09be275..4432fd8 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -761,37 +761,6 @@ void __init early_init_devtree(void *params)
*******/
/**
- * of_find_next_cache_node - Find a node's subsidiary cache
- * @np: node of type "cpu" or "cache"
- *
- * Returns a node pointer with refcount incremented, use
- * of_node_put() on it when done. Caller should hold a reference
- * to np.
- */
-struct device_node *of_find_next_cache_node(struct device_node *np)
-{
- struct device_node *child;
- const phandle *handle;
-
- handle = of_get_property(np, "l2-cache", NULL);
- if (!handle)
- handle = of_get_property(np, "next-level-cache", NULL);
-
- if (handle)
- return of_find_node_by_phandle(be32_to_cpup(handle));
-
- /* OF on pmac has nodes instead of properties named "l2-cache"
- * beneath CPU nodes.
- */
- if (!strcmp(np->type, "cpu"))
- for_each_child_of_node(np, child)
- if (!strcmp(child->type, "cache"))
- return child;
-
- return NULL;
-}
-
-/**
* of_get_ibm_chip_id - Returns the IBM "chip-id" of a device
* @np: device node of the device
*
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 865d3f6..b2cee3d 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1884,3 +1884,34 @@ int of_device_is_stdout_path(struct device_node *dn)
return of_stdout == dn;
}
EXPORT_SYMBOL_GPL(of_device_is_stdout_path);
+
+/**
+ * of_find_next_cache_node - Find a node's subsidiary cache
+ * @np: node of type "cpu" or "cache"
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done. Caller should hold a reference
+ * to np.
+ */
+struct device_node *of_find_next_cache_node(const struct device_node *np)
+{
+ struct device_node *child;
+ const phandle *handle;
+
+ handle = of_get_property(np, "l2-cache", NULL);
+ if (!handle)
+ handle = of_get_property(np, "next-level-cache", NULL);
+
+ if (handle)
+ return of_find_node_by_phandle(be32_to_cpup(handle));
+
+ /* OF on pmac has nodes instead of properties named "l2-cache"
+ * beneath CPU nodes.
+ */
+ if (!strcmp(np->type, "cpu"))
+ for_each_child_of_node(np, child)
+ if (!strcmp(child->type, "cache"))
+ return child;
+
+ return NULL;
+}
diff --git a/include/linux/of.h b/include/linux/of.h
index f95aee3..c08c07e 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -226,6 +226,8 @@ static inline int of_get_child_count(const struct device_node *np)
return num;
}
+/* cache lookup */
+extern struct device_node *of_find_next_cache_node(const struct device_node *);
extern struct device_node *of_find_node_with_property(
struct device_node *from, const char *prop_name);
#define for_each_node_with_property(dn, prop_name) \
--
1.8.1.2
^ permalink raw reply related
* [PATCH 1/2] pci: fsl: derive the common PCI driver to drivers/pci/host
From: Minghuan Lian @ 2013-09-18 11:02 UTC (permalink / raw)
To: linuxppc-dev
Cc: Minghuan Lian, linux-pci, Zang Roy-R61911, Bjorn Helgaas,
Scott Wood
The Freescale's Layerscape series processors will use ARM cores.
The LS1's PCIe controllers is the same as T4240's. So it's better
the PCIe controller driver can support PowerPC and ARM
simultaneously. This patch is for this purpose. It derives
the common functions from arch/powerpc/sysdev/fsl_pci.c to
drivers/pci/host/pci-fsl.c and leaves the architecture-specific
functions which should be implemented in arch related files.
Signed-off-by: Minghuan Lian <Minghuan.Lian@freescale.com>
---
Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/
arch/powerpc/sysdev/fsl_pci.c | 521 +-----------------
arch/powerpc/sysdev/fsl_pci.h | 89 ----
.../sysdev/fsl_pci.c => drivers/pci/host/pci-fsl.c | 591 +--------------------
.../sysdev/fsl_pci.h => include/linux/fsl/pci.h | 45 +-
4 files changed, 7 insertions(+), 1239 deletions(-)
copy arch/powerpc/sysdev/fsl_pci.c => drivers/pci/host/pci-fsl.c (54%)
copy arch/powerpc/sysdev/fsl_pci.h => include/linux/fsl/pci.h (79%)
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index ccfb50d..a189ff0 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -27,6 +27,7 @@
#include <linux/log2.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
+#include <linux/fsl/pci.h>
#include <asm/io.h>
#include <asm/prom.h>
@@ -58,57 +59,8 @@ static void quirk_fsl_pcie_header(struct pci_dev *dev)
return;
}
-static int fsl_indirect_read_config(struct pci_bus *, unsigned int,
- int, int, u32 *);
-
-static int fsl_pcie_check_link(struct pci_controller *hose)
-{
- u32 val = 0;
-
- if (hose->indirect_type & PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK) {
- if (hose->ops->read == fsl_indirect_read_config) {
- struct pci_bus bus;
- bus.number = hose->first_busno;
- bus.sysdata = hose;
- bus.ops = hose->ops;
- indirect_read_config(&bus, 0, PCIE_LTSSM, 4, &val);
- } else
- early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val);
- if (val < PCIE_LTSSM_L0)
- return 1;
- } else {
- struct ccsr_pci __iomem *pci = hose->private_data;
- /* for PCIe IP rev 3.0 or greater use CSR0 for link state */
- val = (in_be32(&pci->pex_csr0) & PEX_CSR0_LTSSM_MASK)
- >> PEX_CSR0_LTSSM_SHIFT;
- if (val != PEX_CSR0_LTSSM_L0)
- return 1;
- }
-
- return 0;
-}
-
-static int fsl_indirect_read_config(struct pci_bus *bus, unsigned int devfn,
- int offset, int len, u32 *val)
-{
- struct pci_controller *hose = pci_bus_to_host(bus);
-
- if (fsl_pcie_check_link(hose))
- hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
- else
- hose->indirect_type &= ~PPC_INDIRECT_TYPE_NO_PCIE_LINK;
-
- return indirect_read_config(bus, devfn, offset, len, val);
-}
-
#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
-static struct pci_ops fsl_indirect_pcie_ops =
-{
- .read = fsl_indirect_read_config,
- .write = indirect_write_config,
-};
-
#define MAX_PHYS_ADDR_BITS 40
static u64 pci64_dma_offset = 1ull << MAX_PHYS_ADDR_BITS;
@@ -132,291 +84,6 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
return 0;
}
-static int setup_one_atmu(struct ccsr_pci __iomem *pci,
- unsigned int index, const struct resource *res,
- resource_size_t offset)
-{
- resource_size_t pci_addr = res->start - offset;
- resource_size_t phys_addr = res->start;
- resource_size_t size = resource_size(res);
- u32 flags = 0x80044000; /* enable & mem R/W */
- unsigned int i;
-
- pr_debug("PCI MEM resource start 0x%016llx, size 0x%016llx.\n",
- (u64)res->start, (u64)size);
-
- if (res->flags & IORESOURCE_PREFETCH)
- flags |= 0x10000000; /* enable relaxed ordering */
-
- for (i = 0; size > 0; i++) {
- unsigned int bits = min(ilog2(size),
- __ffs(pci_addr | phys_addr));
-
- if (index + i >= 5)
- return -1;
-
- out_be32(&pci->pow[index + i].potar, pci_addr >> 12);
- out_be32(&pci->pow[index + i].potear, (u64)pci_addr >> 44);
- out_be32(&pci->pow[index + i].powbar, phys_addr >> 12);
- out_be32(&pci->pow[index + i].powar, flags | (bits - 1));
-
- pci_addr += (resource_size_t)1U << bits;
- phys_addr += (resource_size_t)1U << bits;
- size -= (resource_size_t)1U << bits;
- }
-
- return i;
-}
-
-/* atmu setup for fsl pci/pcie controller */
-static void setup_pci_atmu(struct pci_controller *hose)
-{
- struct ccsr_pci __iomem *pci = hose->private_data;
- int i, j, n, mem_log, win_idx = 3, start_idx = 1, end_idx = 4;
- u64 mem, sz, paddr_hi = 0;
- u64 offset = 0, paddr_lo = ULLONG_MAX;
- u32 pcicsrbar = 0, pcicsrbar_sz;
- u32 piwar = PIWAR_EN | PIWAR_PF | PIWAR_TGI_LOCAL |
- PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP;
- const char *name = hose->dn->full_name;
- const u64 *reg;
- int len;
-
- if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
- if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_2_2) {
- win_idx = 2;
- start_idx = 0;
- end_idx = 3;
- }
- }
-
- /* Disable all windows (except powar0 since it's ignored) */
- for(i = 1; i < 5; i++)
- out_be32(&pci->pow[i].powar, 0);
- for (i = start_idx; i < end_idx; i++)
- out_be32(&pci->piw[i].piwar, 0);
-
- /* Setup outbound MEM window */
- for(i = 0, j = 1; i < 3; i++) {
- if (!(hose->mem_resources[i].flags & IORESOURCE_MEM))
- continue;
-
- paddr_lo = min(paddr_lo, (u64)hose->mem_resources[i].start);
- paddr_hi = max(paddr_hi, (u64)hose->mem_resources[i].end);
-
- /* We assume all memory resources have the same offset */
- offset = hose->mem_offset[i];
- n = setup_one_atmu(pci, j, &hose->mem_resources[i], offset);
-
- if (n < 0 || j >= 5) {
- pr_err("Ran out of outbound PCI ATMUs for resource %d!\n", i);
- hose->mem_resources[i].flags |= IORESOURCE_DISABLED;
- } else
- j += n;
- }
-
- /* Setup outbound IO window */
- if (hose->io_resource.flags & IORESOURCE_IO) {
- if (j >= 5) {
- pr_err("Ran out of outbound PCI ATMUs for IO resource\n");
- } else {
- pr_debug("PCI IO resource start 0x%016llx, size 0x%016llx, "
- "phy base 0x%016llx.\n",
- (u64)hose->io_resource.start,
- (u64)resource_size(&hose->io_resource),
- (u64)hose->io_base_phys);
- out_be32(&pci->pow[j].potar, (hose->io_resource.start >> 12));
- out_be32(&pci->pow[j].potear, 0);
- out_be32(&pci->pow[j].powbar, (hose->io_base_phys >> 12));
- /* Enable, IO R/W */
- out_be32(&pci->pow[j].powar, 0x80088000
- | (ilog2(hose->io_resource.end
- - hose->io_resource.start + 1) - 1));
- }
- }
-
- /* convert to pci address space */
- paddr_hi -= offset;
- paddr_lo -= offset;
-
- if (paddr_hi == paddr_lo) {
- pr_err("%s: No outbound window space\n", name);
- return;
- }
-
- if (paddr_lo == 0) {
- pr_err("%s: No space for inbound window\n", name);
- return;
- }
-
- /* setup PCSRBAR/PEXCSRBAR */
- early_write_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, 0xffffffff);
- early_read_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, &pcicsrbar_sz);
- pcicsrbar_sz = ~pcicsrbar_sz + 1;
-
- if (paddr_hi < (0x100000000ull - pcicsrbar_sz) ||
- (paddr_lo > 0x100000000ull))
- pcicsrbar = 0x100000000ull - pcicsrbar_sz;
- else
- pcicsrbar = (paddr_lo - pcicsrbar_sz) & -pcicsrbar_sz;
- early_write_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, pcicsrbar);
-
- paddr_lo = min(paddr_lo, (u64)pcicsrbar);
-
- pr_info("%s: PCICSRBAR @ 0x%x\n", name, pcicsrbar);
-
- /* Setup inbound mem window */
- mem = memblock_end_of_DRAM();
-
- /*
- * The msi-address-64 property, if it exists, indicates the physical
- * address of the MSIIR register. Normally, this register is located
- * inside CCSR, so the ATMU that covers all of CCSR is used. But if
- * this property exists, then we normally need to create a new ATMU
- * for it. For now, however, we cheat. The only entity that creates
- * this property is the Freescale hypervisor, and the address is
- * specified in the partition configuration. Typically, the address
- * is located in the page immediately after the end of DDR. If so, we
- * can avoid allocating a new ATMU by extending the DDR ATMU by one
- * page.
- */
- reg = of_get_property(hose->dn, "msi-address-64", &len);
- if (reg && (len == sizeof(u64))) {
- u64 address = be64_to_cpup(reg);
-
- if ((address >= mem) && (address < (mem + PAGE_SIZE))) {
- pr_info("%s: extending DDR ATMU to cover MSIIR", name);
- mem += PAGE_SIZE;
- } else {
- /* TODO: Create a new ATMU for MSIIR */
- pr_warn("%s: msi-address-64 address of %llx is "
- "unsupported\n", name, address);
- }
- }
-
- sz = min(mem, paddr_lo);
- mem_log = ilog2(sz);
-
- /* PCIe can overmap inbound & outbound since RX & TX are separated */
- if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
- /* Size window to exact size if power-of-two or one size up */
- if ((1ull << mem_log) != mem) {
- mem_log++;
- if ((1ull << mem_log) > mem)
- pr_info("%s: Setting PCI inbound window "
- "greater than memory size\n", name);
- }
-
- piwar |= ((mem_log - 1) & PIWAR_SZ_MASK);
-
- /* Setup inbound memory window */
- out_be32(&pci->piw[win_idx].pitar, 0x00000000);
- out_be32(&pci->piw[win_idx].piwbar, 0x00000000);
- out_be32(&pci->piw[win_idx].piwar, piwar);
- win_idx--;
-
- hose->dma_window_base_cur = 0x00000000;
- hose->dma_window_size = (resource_size_t)sz;
-
- /*
- * if we have >4G of memory setup second PCI inbound window to
- * let devices that are 64-bit address capable to work w/o
- * SWIOTLB and access the full range of memory
- */
- if (sz != mem) {
- mem_log = ilog2(mem);
-
- /* Size window up if we dont fit in exact power-of-2 */
- if ((1ull << mem_log) != mem)
- mem_log++;
-
- piwar = (piwar & ~PIWAR_SZ_MASK) | (mem_log - 1);
-
- /* Setup inbound memory window */
- out_be32(&pci->piw[win_idx].pitar, 0x00000000);
- out_be32(&pci->piw[win_idx].piwbear,
- pci64_dma_offset >> 44);
- out_be32(&pci->piw[win_idx].piwbar,
- pci64_dma_offset >> 12);
- out_be32(&pci->piw[win_idx].piwar, piwar);
-
- /*
- * install our own dma_set_mask handler to fixup dma_ops
- * and dma_offset
- */
- ppc_md.dma_set_mask = fsl_pci_dma_set_mask;
-
- pr_info("%s: Setup 64-bit PCI DMA window\n", name);
- }
- } else {
- u64 paddr = 0;
-
- /* Setup inbound memory window */
- out_be32(&pci->piw[win_idx].pitar, paddr >> 12);
- out_be32(&pci->piw[win_idx].piwbar, paddr >> 12);
- out_be32(&pci->piw[win_idx].piwar, (piwar | (mem_log - 1)));
- win_idx--;
-
- paddr += 1ull << mem_log;
- sz -= 1ull << mem_log;
-
- if (sz) {
- mem_log = ilog2(sz);
- piwar |= (mem_log - 1);
-
- out_be32(&pci->piw[win_idx].pitar, paddr >> 12);
- out_be32(&pci->piw[win_idx].piwbar, paddr >> 12);
- out_be32(&pci->piw[win_idx].piwar, piwar);
- win_idx--;
-
- paddr += 1ull << mem_log;
- }
-
- hose->dma_window_base_cur = 0x00000000;
- hose->dma_window_size = (resource_size_t)paddr;
- }
-
- if (hose->dma_window_size < mem) {
-#ifdef CONFIG_SWIOTLB
- ppc_swiotlb_enable = 1;
-#else
- pr_err("%s: ERROR: Memory size exceeds PCI ATMU ability to "
- "map - enable CONFIG_SWIOTLB to avoid dma errors.\n",
- name);
-#endif
- /* adjusting outbound windows could reclaim space in mem map */
- if (paddr_hi < 0xffffffffull)
- pr_warning("%s: WARNING: Outbound window cfg leaves "
- "gaps in memory map. Adjusting the memory map "
- "could reduce unnecessary bounce buffering.\n",
- name);
-
- pr_info("%s: DMA window size is 0x%llx\n", name,
- (u64)hose->dma_window_size);
- }
-}
-
-static void __init setup_pci_cmd(struct pci_controller *hose)
-{
- u16 cmd;
- int cap_x;
-
- early_read_config_word(hose, 0, 0, PCI_COMMAND, &cmd);
- cmd |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY
- | PCI_COMMAND_IO;
- early_write_config_word(hose, 0, 0, PCI_COMMAND, cmd);
-
- cap_x = early_find_capability(hose, 0, 0, PCI_CAP_ID_PCIX);
- if (cap_x) {
- int pci_x_cmd = cap_x + PCI_X_CMD;
- cmd = PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ
- | PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E;
- early_write_config_word(hose, 0, 0, pci_x_cmd, cmd);
- } else {
- early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80);
- }
-}
-
void fsl_pcibios_fixup_bus(struct pci_bus *bus)
{
struct pci_controller *hose = pci_bus_to_host(bus);
@@ -454,112 +121,6 @@ void fsl_pcibios_fixup_bus(struct pci_bus *bus)
}
}
-int __init fsl_add_bridge(struct platform_device *pdev, int is_primary)
-{
- int len;
- struct pci_controller *hose;
- struct resource rsrc;
- const int *bus_range;
- u8 hdr_type, progif;
- struct device_node *dev;
- struct ccsr_pci __iomem *pci;
-
- dev = pdev->dev.of_node;
-
- if (!of_device_is_available(dev)) {
- pr_warning("%s: disabled\n", dev->full_name);
- return -ENODEV;
- }
-
- pr_debug("Adding PCI host bridge %s\n", dev->full_name);
-
- /* Fetch host bridge registers address */
- if (of_address_to_resource(dev, 0, &rsrc)) {
- printk(KERN_WARNING "Can't get pci register base!");
- return -ENOMEM;
- }
-
- /* Get bus range if any */
- bus_range = of_get_property(dev, "bus-range", &len);
- if (bus_range == NULL || len < 2 * sizeof(int))
- printk(KERN_WARNING "Can't get bus-range for %s, assume"
- " bus 0\n", dev->full_name);
-
- pci_add_flags(PCI_REASSIGN_ALL_BUS);
- hose = pcibios_alloc_controller(dev);
- if (!hose)
- return -ENOMEM;
-
- /* set platform device as the parent */
- hose->parent = &pdev->dev;
- hose->first_busno = bus_range ? bus_range[0] : 0x0;
- hose->last_busno = bus_range ? bus_range[1] : 0xff;
-
- pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n",
- (u64)rsrc.start, (u64)resource_size(&rsrc));
-
- pci = hose->private_data = ioremap(rsrc.start, resource_size(&rsrc));
- if (!hose->private_data)
- goto no_bridge;
-
- setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
- PPC_INDIRECT_TYPE_BIG_ENDIAN);
-
- if (in_be32(&pci->block_rev1) < PCIE_IP_REV_3_0)
- hose->indirect_type |= PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK;
-
- if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
- /* use fsl_indirect_read_config for PCIe */
- hose->ops = &fsl_indirect_pcie_ops;
- /* For PCIE read HEADER_TYPE to identify controler mode */
- early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type);
- if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
- goto no_bridge;
-
- } else {
- /* For PCI read PROG to identify controller mode */
- early_read_config_byte(hose, 0, 0, PCI_CLASS_PROG, &progif);
- if ((progif & 1) == 1)
- goto no_bridge;
- }
-
- setup_pci_cmd(hose);
-
- /* check PCI express link status */
- if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
- hose->indirect_type |= PPC_INDIRECT_TYPE_EXT_REG |
- PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS;
- if (fsl_pcie_check_link(hose))
- hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
- }
-
- printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. "
- "Firmware bus number: %d->%d\n",
- (unsigned long long)rsrc.start, hose->first_busno,
- hose->last_busno);
-
- pr_debug(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
- hose, hose->cfg_addr, hose->cfg_data);
-
- /* Interpret the "ranges" property */
- /* This also maps the I/O region and sets isa_io/mem_base */
- pci_process_bridge_OF_ranges(hose, dev, is_primary);
-
- /* Setup PEX window registers */
- setup_pci_atmu(hose);
-
- return 0;
-
-no_bridge:
- iounmap(hose->private_data);
- /* unmap cfg_data & cfg_addr separately if not on same page */
- if (((unsigned long)hose->cfg_data & PAGE_MASK) !=
- ((unsigned long)hose->cfg_addr & PAGE_MASK))
- iounmap(hose->cfg_data);
- iounmap(hose->cfg_addr);
- pcibios_free_controller(hose);
- return -ENODEV;
-}
#endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, quirk_fsl_pcie_header);
@@ -1029,26 +590,6 @@ int fsl_pci_mcheck_exception(struct pt_regs *regs)
#endif
#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
-static const struct of_device_id pci_ids[] = {
- { .compatible = "fsl,mpc8540-pci", },
- { .compatible = "fsl,mpc8548-pcie", },
- { .compatible = "fsl,mpc8610-pci", },
- { .compatible = "fsl,mpc8641-pcie", },
- { .compatible = "fsl,qoriq-pcie-v2.1", },
- { .compatible = "fsl,qoriq-pcie-v2.2", },
- { .compatible = "fsl,qoriq-pcie-v2.3", },
- { .compatible = "fsl,qoriq-pcie-v2.4", },
- { .compatible = "fsl,qoriq-pcie-v3.0", },
-
- /*
- * The following entries are for compatibility with older device
- * trees.
- */
- { .compatible = "fsl,p1022-pcie", },
- { .compatible = "fsl,p4080-pcie", },
-
- {},
-};
struct device_node *fsl_pci_primary;
@@ -1083,64 +624,4 @@ void fsl_pci_assign_primary(void)
}
}
}
-
-static int fsl_pci_probe(struct platform_device *pdev)
-{
- int ret;
- struct device_node *node;
-
- node = pdev->dev.of_node;
- ret = fsl_add_bridge(pdev, fsl_pci_primary == node);
-
- mpc85xx_pci_err_probe(pdev);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int fsl_pci_resume(struct device *dev)
-{
- struct pci_controller *hose;
- struct resource pci_rsrc;
-
- hose = pci_find_hose_for_OF_device(dev->of_node);
- if (!hose)
- return -ENODEV;
-
- if (of_address_to_resource(dev->of_node, 0, &pci_rsrc)) {
- dev_err(dev, "Get pci register base failed.");
- return -ENODEV;
- }
-
- setup_pci_atmu(hose);
-
- return 0;
-}
-
-static const struct dev_pm_ops pci_pm_ops = {
- .resume = fsl_pci_resume,
-};
-
-#define PCI_PM_OPS (&pci_pm_ops)
-
-#else
-
-#define PCI_PM_OPS NULL
-
-#endif
-
-static struct platform_driver fsl_pci_driver = {
- .driver = {
- .name = "fsl-pci",
- .pm = PCI_PM_OPS,
- .of_match_table = pci_ids,
- },
- .probe = fsl_pci_probe,
-};
-
-static int __init fsl_pci_init(void)
-{
- return platform_driver_register(&fsl_pci_driver);
-}
-arch_initcall(fsl_pci_init);
#endif
diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h
index 8d455df..ce77aad 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -21,95 +21,6 @@ struct platform_device;
#define PCI_FSL_BRR1 0xbf8
#define PCI_FSL_BRR1_VER 0xffff
-#define PCIE_LTSSM 0x0404 /* PCIE Link Training and Status */
-#define PCIE_LTSSM_L0 0x16 /* L0 state */
-#define PCIE_IP_REV_2_2 0x02080202 /* PCIE IP block version Rev2.2 */
-#define PCIE_IP_REV_3_0 0x02080300 /* PCIE IP block version Rev3.0 */
-#define PIWAR_EN 0x80000000 /* Enable */
-#define PIWAR_PF 0x20000000 /* prefetch */
-#define PIWAR_TGI_LOCAL 0x00f00000 /* target - local memory */
-#define PIWAR_READ_SNOOP 0x00050000
-#define PIWAR_WRITE_SNOOP 0x00005000
-#define PIWAR_SZ_MASK 0x0000003f
-
-/* PCI/PCI Express outbound window reg */
-struct pci_outbound_window_regs {
- __be32 potar; /* 0x.0 - Outbound translation address register */
- __be32 potear; /* 0x.4 - Outbound translation extended address register */
- __be32 powbar; /* 0x.8 - Outbound window base address register */
- u8 res1[4];
- __be32 powar; /* 0x.10 - Outbound window attributes register */
- u8 res2[12];
-};
-
-/* PCI/PCI Express inbound window reg */
-struct pci_inbound_window_regs {
- __be32 pitar; /* 0x.0 - Inbound translation address register */
- u8 res1[4];
- __be32 piwbar; /* 0x.8 - Inbound window base address register */
- __be32 piwbear; /* 0x.c - Inbound window base extended address register */
- __be32 piwar; /* 0x.10 - Inbound window attributes register */
- u8 res2[12];
-};
-
-/* PCI/PCI Express IO block registers for 85xx/86xx */
-struct ccsr_pci {
- __be32 config_addr; /* 0x.000 - PCI/PCIE Configuration Address Register */
- __be32 config_data; /* 0x.004 - PCI/PCIE Configuration Data Register */
- __be32 int_ack; /* 0x.008 - PCI Interrupt Acknowledge Register */
- __be32 pex_otb_cpl_tor; /* 0x.00c - PCIE Outbound completion timeout register */
- __be32 pex_conf_tor; /* 0x.010 - PCIE configuration timeout register */
- __be32 pex_config; /* 0x.014 - PCIE CONFIG Register */
- __be32 pex_int_status; /* 0x.018 - PCIE interrupt status */
- u8 res2[4];
- __be32 pex_pme_mes_dr; /* 0x.020 - PCIE PME and message detect register */
- __be32 pex_pme_mes_disr; /* 0x.024 - PCIE PME and message disable register */
- __be32 pex_pme_mes_ier; /* 0x.028 - PCIE PME and message interrupt enable register */
- __be32 pex_pmcr; /* 0x.02c - PCIE power management command register */
- u8 res3[3016];
- __be32 block_rev1; /* 0x.bf8 - PCIE Block Revision register 1 */
- __be32 block_rev2; /* 0x.bfc - PCIE Block Revision register 2 */
-
-/* PCI/PCI Express outbound window 0-4
- * Window 0 is the default window and is the only window enabled upon reset.
- * The default outbound register set is used when a transaction misses
- * in all of the other outbound windows.
- */
- struct pci_outbound_window_regs pow[5];
- u8 res14[96];
- struct pci_inbound_window_regs pmit; /* 0xd00 - 0xd9c Inbound MSI */
- u8 res6[96];
-/* PCI/PCI Express inbound window 3-0
- * inbound window 1 supports only a 32-bit base address and does not
- * define an inbound window base extended address register.
- */
- struct pci_inbound_window_regs piw[4];
-
- __be32 pex_err_dr; /* 0x.e00 - PCI/PCIE error detect register */
- u8 res21[4];
- __be32 pex_err_en; /* 0x.e08 - PCI/PCIE error interrupt enable register */
- u8 res22[4];
- __be32 pex_err_disr; /* 0x.e10 - PCI/PCIE error disable register */
- u8 res23[12];
- __be32 pex_err_cap_stat; /* 0x.e20 - PCI/PCIE error capture status register */
- u8 res24[4];
- __be32 pex_err_cap_r0; /* 0x.e28 - PCIE error capture register 0 */
- __be32 pex_err_cap_r1; /* 0x.e2c - PCIE error capture register 0 */
- __be32 pex_err_cap_r2; /* 0x.e30 - PCIE error capture register 0 */
- __be32 pex_err_cap_r3; /* 0x.e34 - PCIE error capture register 0 */
- u8 res_e38[200];
- __be32 pdb_stat; /* 0x.f00 - PCIE Debug Status */
- u8 res_f04[16];
- __be32 pex_csr0; /* 0x.f14 - PEX Control/Status register 0*/
-#define PEX_CSR0_LTSSM_MASK 0xFC
-#define PEX_CSR0_LTSSM_SHIFT 2
-#define PEX_CSR0_LTSSM_L0 0x11
- __be32 pex_csr1; /* 0x.f18 - PEX Control/Status register 1*/
- u8 res_f1c[228];
-
-};
-
-extern int fsl_add_bridge(struct platform_device *pdev, int is_primary);
extern void fsl_pcibios_fixup_bus(struct pci_bus *bus);
extern int mpc83xx_add_bridge(struct device_node *dev);
u64 fsl_pci_immrbar_base(struct pci_controller *hose);
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/drivers/pci/host/pci-fsl.c
similarity index 54%
copy from arch/powerpc/sysdev/fsl_pci.c
copy to drivers/pci/host/pci-fsl.c
index ccfb50d..69d338b 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/drivers/pci/host/pci-fsl.c
@@ -1,5 +1,5 @@
/*
- * MPC83xx/85xx/86xx PCI/PCIE support routing.
+ * 85xx/86xx/LS PCI/PCIE support routing.
*
* Copyright 2007-2012 Freescale Semiconductor, Inc.
* Copyright 2008-2009 MontaVista Software, Inc.
@@ -8,9 +8,6 @@
* Recode: ZHANG WEI <wei.zhang@freescale.com>
* Rewrite the routing for Frescale PCI and PCI Express
* Roy Zang <tie-fei.zang@freescale.com>
- * MPC83xx PCI-Express support:
- * Tony Li <tony.li@freescale.com>
- * Anton Vorontsov <avorontsov@ru.mvista.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -38,29 +35,6 @@
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
-static int fsl_pcie_bus_fixup, is_mpc83xx_pci;
-
-static void quirk_fsl_pcie_header(struct pci_dev *dev)
-{
- u8 hdr_type;
-
- /* if we aren't a PCIe don't bother */
- if (!pci_find_capability(dev, PCI_CAP_ID_EXP))
- return;
-
- /* if we aren't in host mode don't bother */
- pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type);
- if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
- return;
-
- dev->class = PCI_CLASS_BRIDGE_PCI << 8;
- fsl_pcie_bus_fixup = 1;
- return;
-}
-
-static int fsl_indirect_read_config(struct pci_bus *, unsigned int,
- int, int, u32 *);
-
static int fsl_pcie_check_link(struct pci_controller *hose)
{
u32 val = 0;
@@ -109,29 +83,6 @@ static struct pci_ops fsl_indirect_pcie_ops =
.write = indirect_write_config,
};
-#define MAX_PHYS_ADDR_BITS 40
-static u64 pci64_dma_offset = 1ull << MAX_PHYS_ADDR_BITS;
-
-static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
-{
- if (!dev->dma_mask || !dma_supported(dev, dma_mask))
- return -EIO;
-
- /*
- * Fixup PCI devices that are able to DMA to above the physical
- * address width of the SoC such that we can address any internal
- * SoC address from across PCI if needed
- */
- if ((dev->bus == &pci_bus_type) &&
- dma_mask >= DMA_BIT_MASK(MAX_PHYS_ADDR_BITS)) {
- set_dma_ops(dev, &dma_direct_ops);
- set_dma_offset(dev, pci64_dma_offset);
- }
-
- *dev->dma_mask = dma_mask;
- return 0;
-}
-
static int setup_one_atmu(struct ccsr_pci __iomem *pci,
unsigned int index, const struct resource *res,
resource_size_t offset)
@@ -417,43 +368,6 @@ static void __init setup_pci_cmd(struct pci_controller *hose)
}
}
-void fsl_pcibios_fixup_bus(struct pci_bus *bus)
-{
- struct pci_controller *hose = pci_bus_to_host(bus);
- int i, is_pcie = 0, no_link;
-
- /* The root complex bridge comes up with bogus resources,
- * we copy the PHB ones in.
- *
- * With the current generic PCI code, the PHB bus no longer
- * has bus->resource[0..4] set, so things are a bit more
- * tricky.
- */
-
- if (fsl_pcie_bus_fixup)
- is_pcie = early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP);
- no_link = !!(hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK);
-
- if (bus->parent == hose->bus && (is_pcie || no_link)) {
- for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; ++i) {
- struct resource *res = bus->resource[i];
- struct resource *par;
-
- if (!res)
- continue;
- if (i == 0)
- par = &hose->io_resource;
- else if (i < 4)
- par = &hose->mem_resources[i-1];
- else par = NULL;
-
- res->start = par ? par->start : 0;
- res->end = par ? par->end : 0;
- res->flags = par ? par->flags : 0;
- }
- }
-}
-
int __init fsl_add_bridge(struct platform_device *pdev, int is_primary)
{
int len;
@@ -560,475 +474,7 @@ no_bridge:
pcibios_free_controller(hose);
return -ENODEV;
}
-#endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */
-
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, quirk_fsl_pcie_header);
-
-#if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x)
-struct mpc83xx_pcie_priv {
- void __iomem *cfg_type0;
- void __iomem *cfg_type1;
- u32 dev_base;
-};
-
-struct pex_inbound_window {
- u32 ar;
- u32 tar;
- u32 barl;
- u32 barh;
-};
-
-/*
- * With the convention of u-boot, the PCIE outbound window 0 serves
- * as configuration transactions outbound.
- */
-#define PEX_OUTWIN0_BAR 0xCA4
-#define PEX_OUTWIN0_TAL 0xCA8
-#define PEX_OUTWIN0_TAH 0xCAC
-#define PEX_RC_INWIN_BASE 0xE60
-#define PEX_RCIWARn_EN 0x1
-
-static int mpc83xx_pcie_exclude_device(struct pci_bus *bus, unsigned int devfn)
-{
- struct pci_controller *hose = pci_bus_to_host(bus);
-
- if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK)
- return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * Workaround for the HW bug: for Type 0 configure transactions the
- * PCI-E controller does not check the device number bits and just
- * assumes that the device number bits are 0.
- */
- if (bus->number == hose->first_busno ||
- bus->primary == hose->first_busno) {
- if (devfn & 0xf8)
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
-
- if (ppc_md.pci_exclude_device) {
- if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static void __iomem *mpc83xx_pcie_remap_cfg(struct pci_bus *bus,
- unsigned int devfn, int offset)
-{
- struct pci_controller *hose = pci_bus_to_host(bus);
- struct mpc83xx_pcie_priv *pcie = hose->dn->data;
- u32 dev_base = bus->number << 24 | devfn << 16;
- int ret;
-
- ret = mpc83xx_pcie_exclude_device(bus, devfn);
- if (ret)
- return NULL;
-
- offset &= 0xfff;
-
- /* Type 0 */
- if (bus->number == hose->first_busno)
- return pcie->cfg_type0 + offset;
-
- if (pcie->dev_base == dev_base)
- goto mapped;
-
- out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAL, dev_base);
-
- pcie->dev_base = dev_base;
-mapped:
- return pcie->cfg_type1 + offset;
-}
-
-static int mpc83xx_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
- int offset, int len, u32 *val)
-{
- void __iomem *cfg_addr;
-
- cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset);
- if (!cfg_addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- switch (len) {
- case 1:
- *val = in_8(cfg_addr);
- break;
- case 2:
- *val = in_le16(cfg_addr);
- break;
- default:
- *val = in_le32(cfg_addr);
- break;
- }
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
- int offset, int len, u32 val)
-{
- struct pci_controller *hose = pci_bus_to_host(bus);
- void __iomem *cfg_addr;
-
- cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset);
- if (!cfg_addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- /* PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS */
- if (offset == PCI_PRIMARY_BUS && bus->number == hose->first_busno)
- val &= 0xffffff00;
-
- switch (len) {
- case 1:
- out_8(cfg_addr, val);
- break;
- case 2:
- out_le16(cfg_addr, val);
- break;
- default:
- out_le32(cfg_addr, val);
- break;
- }
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops mpc83xx_pcie_ops = {
- .read = mpc83xx_pcie_read_config,
- .write = mpc83xx_pcie_write_config,
-};
-
-static int __init mpc83xx_pcie_setup(struct pci_controller *hose,
- struct resource *reg)
-{
- struct mpc83xx_pcie_priv *pcie;
- u32 cfg_bar;
- int ret = -ENOMEM;
-
- pcie = zalloc_maybe_bootmem(sizeof(*pcie), GFP_KERNEL);
- if (!pcie)
- return ret;
-
- pcie->cfg_type0 = ioremap(reg->start, resource_size(reg));
- if (!pcie->cfg_type0)
- goto err0;
-
- cfg_bar = in_le32(pcie->cfg_type0 + PEX_OUTWIN0_BAR);
- if (!cfg_bar) {
- /* PCI-E isn't configured. */
- ret = -ENODEV;
- goto err1;
- }
-
- pcie->cfg_type1 = ioremap(cfg_bar, 0x1000);
- if (!pcie->cfg_type1)
- goto err1;
-
- WARN_ON(hose->dn->data);
- hose->dn->data = pcie;
- hose->ops = &mpc83xx_pcie_ops;
- hose->indirect_type |= PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK;
-
- out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAH, 0);
- out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAL, 0);
-
- if (fsl_pcie_check_link(hose))
- hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
-
- return 0;
-err1:
- iounmap(pcie->cfg_type0);
-err0:
- kfree(pcie);
- return ret;
-
-}
-
-int __init mpc83xx_add_bridge(struct device_node *dev)
-{
- int ret;
- int len;
- struct pci_controller *hose;
- struct resource rsrc_reg;
- struct resource rsrc_cfg;
- const int *bus_range;
- int primary;
-
- is_mpc83xx_pci = 1;
-
- if (!of_device_is_available(dev)) {
- pr_warning("%s: disabled by the firmware.\n",
- dev->full_name);
- return -ENODEV;
- }
- pr_debug("Adding PCI host bridge %s\n", dev->full_name);
-
- /* Fetch host bridge registers address */
- if (of_address_to_resource(dev, 0, &rsrc_reg)) {
- printk(KERN_WARNING "Can't get pci register base!\n");
- return -ENOMEM;
- }
-
- memset(&rsrc_cfg, 0, sizeof(rsrc_cfg));
-
- if (of_address_to_resource(dev, 1, &rsrc_cfg)) {
- printk(KERN_WARNING
- "No pci config register base in dev tree, "
- "using default\n");
- /*
- * MPC83xx supports up to two host controllers
- * one at 0x8500 has config space registers at 0x8300
- * one at 0x8600 has config space registers at 0x8380
- */
- if ((rsrc_reg.start & 0xfffff) == 0x8500)
- rsrc_cfg.start = (rsrc_reg.start & 0xfff00000) + 0x8300;
- else if ((rsrc_reg.start & 0xfffff) == 0x8600)
- rsrc_cfg.start = (rsrc_reg.start & 0xfff00000) + 0x8380;
- }
- /*
- * Controller at offset 0x8500 is primary
- */
- if ((rsrc_reg.start & 0xfffff) == 0x8500)
- primary = 1;
- else
- primary = 0;
-
- /* Get bus range if any */
- bus_range = of_get_property(dev, "bus-range", &len);
- if (bus_range == NULL || len < 2 * sizeof(int)) {
- printk(KERN_WARNING "Can't get bus-range for %s, assume"
- " bus 0\n", dev->full_name);
- }
-
- pci_add_flags(PCI_REASSIGN_ALL_BUS);
- hose = pcibios_alloc_controller(dev);
- if (!hose)
- return -ENOMEM;
-
- hose->first_busno = bus_range ? bus_range[0] : 0;
- hose->last_busno = bus_range ? bus_range[1] : 0xff;
-
- if (of_device_is_compatible(dev, "fsl,mpc8314-pcie")) {
- ret = mpc83xx_pcie_setup(hose, &rsrc_reg);
- if (ret)
- goto err0;
- } else {
- setup_indirect_pci(hose, rsrc_cfg.start,
- rsrc_cfg.start + 4, 0);
- }
-
- printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. "
- "Firmware bus number: %d->%d\n",
- (unsigned long long)rsrc_reg.start, hose->first_busno,
- hose->last_busno);
-
- pr_debug(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
- hose, hose->cfg_addr, hose->cfg_data);
-
- /* Interpret the "ranges" property */
- /* This also maps the I/O region and sets isa_io/mem_base */
- pci_process_bridge_OF_ranges(hose, dev, primary);
-
- return 0;
-err0:
- pcibios_free_controller(hose);
- return ret;
-}
-#endif /* CONFIG_PPC_83xx */
-
-u64 fsl_pci_immrbar_base(struct pci_controller *hose)
-{
-#ifdef CONFIG_PPC_83xx
- if (is_mpc83xx_pci) {
- struct mpc83xx_pcie_priv *pcie = hose->dn->data;
- struct pex_inbound_window *in;
- int i;
-
- /* Walk the Root Complex Inbound windows to match IMMR base */
- in = pcie->cfg_type0 + PEX_RC_INWIN_BASE;
- for (i = 0; i < 4; i++) {
- /* not enabled, skip */
- if (!in_le32(&in[i].ar) & PEX_RCIWARn_EN)
- continue;
-
- if (get_immrbase() == in_le32(&in[i].tar))
- return (u64)in_le32(&in[i].barh) << 32 |
- in_le32(&in[i].barl);
- }
-
- printk(KERN_WARNING "could not find PCI BAR matching IMMR\n");
- }
-#endif
-
-#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
- if (!is_mpc83xx_pci) {
- u32 base;
-
- pci_bus_read_config_dword(hose->bus,
- PCI_DEVFN(0, 0), PCI_BASE_ADDRESS_0, &base);
- return base;
- }
-#endif
-
- return 0;
-}
-#ifdef CONFIG_E500
-static int mcheck_handle_load(struct pt_regs *regs, u32 inst)
-{
- unsigned int rd, ra, rb, d;
-
- rd = get_rt(inst);
- ra = get_ra(inst);
- rb = get_rb(inst);
- d = get_d(inst);
-
- switch (get_op(inst)) {
- case 31:
- switch (get_xop(inst)) {
- case OP_31_XOP_LWZX:
- case OP_31_XOP_LWBRX:
- regs->gpr[rd] = 0xffffffff;
- break;
-
- case OP_31_XOP_LWZUX:
- regs->gpr[rd] = 0xffffffff;
- regs->gpr[ra] += regs->gpr[rb];
- break;
-
- case OP_31_XOP_LBZX:
- regs->gpr[rd] = 0xff;
- break;
-
- case OP_31_XOP_LBZUX:
- regs->gpr[rd] = 0xff;
- regs->gpr[ra] += regs->gpr[rb];
- break;
-
- case OP_31_XOP_LHZX:
- case OP_31_XOP_LHBRX:
- regs->gpr[rd] = 0xffff;
- break;
-
- case OP_31_XOP_LHZUX:
- regs->gpr[rd] = 0xffff;
- regs->gpr[ra] += regs->gpr[rb];
- break;
-
- case OP_31_XOP_LHAX:
- regs->gpr[rd] = ~0UL;
- break;
-
- case OP_31_XOP_LHAUX:
- regs->gpr[rd] = ~0UL;
- regs->gpr[ra] += regs->gpr[rb];
- break;
-
- default:
- return 0;
- }
- break;
-
- case OP_LWZ:
- regs->gpr[rd] = 0xffffffff;
- break;
-
- case OP_LWZU:
- regs->gpr[rd] = 0xffffffff;
- regs->gpr[ra] += (s16)d;
- break;
-
- case OP_LBZ:
- regs->gpr[rd] = 0xff;
- break;
-
- case OP_LBZU:
- regs->gpr[rd] = 0xff;
- regs->gpr[ra] += (s16)d;
- break;
-
- case OP_LHZ:
- regs->gpr[rd] = 0xffff;
- break;
-
- case OP_LHZU:
- regs->gpr[rd] = 0xffff;
- regs->gpr[ra] += (s16)d;
- break;
-
- case OP_LHA:
- regs->gpr[rd] = ~0UL;
- break;
-
- case OP_LHAU:
- regs->gpr[rd] = ~0UL;
- regs->gpr[ra] += (s16)d;
- break;
-
- default:
- return 0;
- }
-
- return 1;
-}
-
-static int is_in_pci_mem_space(phys_addr_t addr)
-{
- struct pci_controller *hose;
- struct resource *res;
- int i;
-
- list_for_each_entry(hose, &hose_list, list_node) {
- if (!(hose->indirect_type & PPC_INDIRECT_TYPE_EXT_REG))
- continue;
-
- for (i = 0; i < 3; i++) {
- res = &hose->mem_resources[i];
- if ((res->flags & IORESOURCE_MEM) &&
- addr >= res->start && addr <= res->end)
- return 1;
- }
- }
- return 0;
-}
-
-int fsl_pci_mcheck_exception(struct pt_regs *regs)
-{
- u32 inst;
- int ret;
- phys_addr_t addr = 0;
-
- /* Let KVM/QEMU deal with the exception */
- if (regs->msr & MSR_GS)
- return 0;
-
-#ifdef CONFIG_PHYS_64BIT
- addr = mfspr(SPRN_MCARU);
- addr <<= 32;
-#endif
- addr += mfspr(SPRN_MCAR);
-
- if (is_in_pci_mem_space(addr)) {
- if (user_mode(regs)) {
- pagefault_disable();
- ret = get_user(regs->nip, &inst);
- pagefault_enable();
- } else {
- ret = probe_kernel_address(regs->nip, inst);
- }
-
- if (mcheck_handle_load(regs, inst)) {
- regs->nip += 4;
- return 1;
- }
- }
-
- return 0;
-}
-#endif
-
-#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
static const struct of_device_id pci_ids[] = {
{ .compatible = "fsl,mpc8540-pci", },
{ .compatible = "fsl,mpc8548-pcie", },
@@ -1050,40 +496,6 @@ static const struct of_device_id pci_ids[] = {
{},
};
-struct device_node *fsl_pci_primary;
-
-void fsl_pci_assign_primary(void)
-{
- struct device_node *np;
-
- /* Callers can specify the primary bus using other means. */
- if (fsl_pci_primary)
- return;
-
- /* If a PCI host bridge contains an ISA node, it's primary. */
- np = of_find_node_by_type(NULL, "isa");
- while ((fsl_pci_primary = of_get_parent(np))) {
- of_node_put(np);
- np = fsl_pci_primary;
-
- if (of_match_node(pci_ids, np) && of_device_is_available(np))
- return;
- }
-
- /*
- * If there's no PCI host bridge with ISA, arbitrarily
- * designate one as primary. This can go away once
- * various bugs with primary-less systems are fixed.
- */
- for_each_matching_node(np, pci_ids) {
- if (of_device_is_available(np)) {
- fsl_pci_primary = np;
- of_node_put(np);
- return;
- }
- }
-}
-
static int fsl_pci_probe(struct platform_device *pdev)
{
int ret;
@@ -1143,4 +555,3 @@ static int __init fsl_pci_init(void)
return platform_driver_register(&fsl_pci_driver);
}
arch_initcall(fsl_pci_init);
-#endif
diff --git a/arch/powerpc/sysdev/fsl_pci.h b/include/linux/fsl/pci.h
similarity index 79%
copy from arch/powerpc/sysdev/fsl_pci.h
copy to include/linux/fsl/pci.h
index 8d455df..bfc241d 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/include/linux/fsl/pci.h
@@ -1,5 +1,5 @@
/*
- * MPC85xx/86xx PCI Express structure define
+ * MPC85xx/86xx/LS PCI Express structure define
*
* Copyright 2007,2011 Freescale Semiconductor, Inc
*
@@ -11,15 +11,8 @@
*/
#ifdef __KERNEL__
-#ifndef __POWERPC_FSL_PCI_H
-#define __POWERPC_FSL_PCI_H
-
-struct platform_device;
-
-
-/* FSL PCI controller BRR1 register */
-#define PCI_FSL_BRR1 0xbf8
-#define PCI_FSL_BRR1_VER 0xffff
+#ifndef __PCI_H
+#define __PCI_H
#define PCIE_LTSSM 0x0404 /* PCIE Link Training and Status */
#define PCIE_LTSSM_L0 0x16 /* L0 state */
@@ -52,7 +45,7 @@ struct pci_inbound_window_regs {
u8 res2[12];
};
-/* PCI/PCI Express IO block registers for 85xx/86xx */
+/* PCI/PCI Express IO block registers for 85xx/86xx/LS */
struct ccsr_pci {
__be32 config_addr; /* 0x.000 - PCI/PCIE Configuration Address Register */
__be32 config_data; /* 0x.004 - PCI/PCIE Configuration Data Register */
@@ -109,33 +102,5 @@ struct ccsr_pci {
};
-extern int fsl_add_bridge(struct platform_device *pdev, int is_primary);
-extern void fsl_pcibios_fixup_bus(struct pci_bus *bus);
-extern int mpc83xx_add_bridge(struct device_node *dev);
-u64 fsl_pci_immrbar_base(struct pci_controller *hose);
-
-extern struct device_node *fsl_pci_primary;
-
-#ifdef CONFIG_PCI
-void fsl_pci_assign_primary(void);
-#else
-static inline void fsl_pci_assign_primary(void) {}
-#endif
-
-#ifdef CONFIG_EDAC_MPC85XX
-int mpc85xx_pci_err_probe(struct platform_device *op);
-#else
-static inline int mpc85xx_pci_err_probe(struct platform_device *op)
-{
- return -ENOTSUPP;
-}
-#endif
-
-#ifdef CONFIG_FSL_PCI
-extern int fsl_pci_mcheck_exception(struct pt_regs *);
-#else
-static inline int fsl_pci_mcheck_exception(struct pt_regs *regs) {return 0; }
-#endif
-
-#endif /* __POWERPC_FSL_PCI_H */
+#endif /* __PCI_H */
#endif /* __KERNEL__ */
--
1.8.1.2
^ permalink raw reply related
* [PATCH 2/2] pci: fsl: rework PCI driver compatible with Layerscape
From: Minghuan Lian @ 2013-09-18 11:02 UTC (permalink / raw)
To: linuxppc-dev
Cc: Minghuan Lian, linux-pci, Zang Roy-R61911, Bjorn Helgaas,
Scott Wood
In-Reply-To: <1379502122-20792-1-git-send-email-Minghuan.Lian@freescale.com>
The Freescale's Layerscape series processors will use the same PCI
controller but change cores from PowerPC to ARM. This patch is to
rework FSL PCI driver to support PowerPC and ARM simultaneously.
PowerPC uses structure pci_controller to describe PCI controller,
but arm uses structure hw_pci and pci_sys_data. They also have
different architecture implementation and initialization flow.
The architecture-dependent driver will bridge the gap, get the
settings from the common driver and initialize the corresponding
structure and call the related interface to register PCI controller.
The common driver pci-fsl.c removes all the architecture-specific
code and provides structure fsl_pci to store all the controller
settings and the common functionalities that include reading/writing
PCI configuration space, parsing dts node and getting the MEM/IO and
bus number ranges, setting ATMU and check link status.
Signed-off-by: Minghuan Lian <Minghuan.Lian@freescale.com>
---
Based on upstream master
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274488/
The function has been tested on MPC8315ERDB MPC8572DS P5020DS P3041DS
and T4240QDS boards
arch/powerpc/Kconfig | 1 +
arch/powerpc/sysdev/fsl_pci.c | 147 +++++++++-
drivers/edac/mpc85xx_edac.c | 16 +-
drivers/pci/host/Kconfig | 7 +
drivers/pci/host/Makefile | 1 +
drivers/pci/host/pci-fsl.c | 653 +++++++++++++++++++++++++++---------------
include/linux/fsl/pci.h | 69 +++++
7 files changed, 653 insertions(+), 241 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 38f3b7e..6fd6348 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -690,6 +690,7 @@ config FSL_SOC
config FSL_PCI
bool
+ select PCI_FSL if FSL_SOC_BOOKE || PPC_86xx
select PPC_INDIRECT_PCI
select PCI_QUIRKS
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index a189ff0..1413257 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -62,7 +62,11 @@ static void quirk_fsl_pcie_header(struct pci_dev *dev)
#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
#define MAX_PHYS_ADDR_BITS 40
-static u64 pci64_dma_offset = 1ull << MAX_PHYS_ADDR_BITS;
+
+u64 fsl_arch_pci64_dma_offset(void)
+{
+ return 1ull << MAX_PHYS_ADDR_BITS;
+}
static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
{
@@ -77,17 +81,43 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
if ((dev->bus == &pci_bus_type) &&
dma_mask >= DMA_BIT_MASK(MAX_PHYS_ADDR_BITS)) {
set_dma_ops(dev, &dma_direct_ops);
- set_dma_offset(dev, pci64_dma_offset);
+ set_dma_offset(dev, fsl_arch_pci64_dma_offset());
}
*dev->dma_mask = dma_mask;
return 0;
}
+struct fsl_pci *fsl_arch_sys_to_pci(void *sys)
+{
+ struct pci_controller *hose = sys;
+ struct fsl_pci *pci = hose->private_data;
+
+ /* Update the first bus number */
+ if (pci->first_busno != hose->first_busno)
+ pci->first_busno = hose->first_busno;
+
+ return pci;
+}
+
+struct pci_bus *fsl_arch_fake_pci_bus(struct fsl_pci *pci, int busnr)
+{
+ static struct pci_bus bus;
+ static struct pci_controller hose;
+
+ bus.number = busnr;
+ bus.sysdata = &hose;
+ hose.private_data = pci;
+ bus.ops = pci->ops;
+
+ return &bus;
+}
+
void fsl_pcibios_fixup_bus(struct pci_bus *bus)
{
struct pci_controller *hose = pci_bus_to_host(bus);
- int i, is_pcie = 0, no_link;
+ int i, is_pcie, no_link;
+ struct fsl_pci *pci = fsl_arch_sys_to_pci(hose);
/* The root complex bridge comes up with bogus resources,
* we copy the PHB ones in.
@@ -97,9 +127,8 @@ void fsl_pcibios_fixup_bus(struct pci_bus *bus)
* tricky.
*/
- if (fsl_pcie_bus_fixup)
- is_pcie = early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP);
- no_link = !!(hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK);
+ is_pcie = pci->is_pcie;
+ no_link = fsl_pci_check_link(pci);
if (bus->parent == hose->bus && (is_pcie || no_link)) {
for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; ++i) {
@@ -121,6 +150,94 @@ void fsl_pcibios_fixup_bus(struct pci_bus *bus)
}
}
+int fsl_arch_pci_exclude_device(struct fsl_pci *pci, u8 bus, u8 devfn)
+{
+ struct pci_controller *hose = pci->sys;
+
+ if (!hose)
+ return PCIBIOS_SUCCESSFUL;
+
+ if (ppc_md.pci_exclude_device)
+ if (ppc_md.pci_exclude_device(hose, bus, devfn))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int fsl_arch_pci_sys_register(struct fsl_pci *pci)
+{
+ struct pci_controller *hose;
+
+ pci_add_flags(PCI_REASSIGN_ALL_BUS);
+ hose = pcibios_alloc_controller(pci->dn);
+ if (!hose)
+ return -ENOMEM;
+
+ /* set platform device as the parent */
+ hose->private_data = pci;
+ hose->parent = pci->dev;
+ hose->first_busno = pci->first_busno;
+ hose->last_busno = pci->last_busno;
+ hose->ops = pci->ops;
+
+#ifdef CONFIG_PPC32
+ /* On 32 bits, limit I/O space to 16MB */
+ if (pci->pci_io_size > 0x01000000)
+ pci->pci_io_size = 0x01000000;
+
+ /* 32 bits needs to map IOs here */
+ hose->io_base_virt = ioremap(pci->io_base_phys + pci->io_resource.start,
+ pci->pci_io_size);
+
+ /* Expect trouble if pci_addr is not 0 */
+ if (fsl_pci_primary == pci->dn)
+ isa_io_base = (unsigned long)hose->io_base_virt;
+#endif /* CONFIG_PPC32 */
+
+ hose->pci_io_size = pci->io_resource.start + pci->pci_io_size;
+ hose->io_base_phys = pci->io_base_phys;
+ hose->io_resource = pci->io_resource;
+
+ memcpy(hose->mem_offset, pci->mem_offset, sizeof(hose->mem_offset));
+ memcpy(hose->mem_resources, pci->mem_resources,
+ sizeof(hose->mem_resources));
+ hose->dma_window_base_cur = pci->dma_window_base_cur;
+ hose->dma_window_size = pci->dma_window_size;
+
+ pci->sys = hose;
+
+ /*
+ * Install our own dma_set_mask handler to fixup dma_ops
+ * and dma_offset when memory is more than dma window size
+ */
+ if (pci->is_pcie && memblock_end_of_DRAM() > hose->dma_window_size)
+ ppc_md.dma_set_mask = fsl_pci_dma_set_mask;
+
+#ifdef CONFIG_SWIOTLB
+ /*
+ * if we couldn't map all of DRAM via the dma windows
+ * we need SWIOTLB to handle buffers located outside of
+ * dma capable memory region
+ */
+ if (memblock_end_of_DRAM() - 1 > hose->dma_window_base_cur +
+ hose->dma_window_size)
+ ppc_swiotlb_enable = 1;
+#endif
+
+ mpc85xx_pci_err_probe(to_platform_device(pci->dev));
+ return 0;
+}
+
+void fsl_arch_pci_sys_remove(struct fsl_pci *pci)
+{
+ struct pci_controller *hose = pci->sys;
+
+ if (!hose)
+ return;
+
+ pcibios_free_controller(hose);
+}
+
#endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, quirk_fsl_pcie_header);
@@ -260,6 +377,16 @@ static struct pci_ops mpc83xx_pcie_ops = {
.write = mpc83xx_pcie_write_config,
};
+static int mpc83xx_pcie_check_link(struct pci_controller *hose)
+{
+ u32 val = 0;
+
+ early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val);
+ if (val < PCIE_LTSSM_L0)
+ return 1;
+ return 0;
+}
+
static int __init mpc83xx_pcie_setup(struct pci_controller *hose,
struct resource *reg)
{
@@ -294,7 +421,7 @@ static int __init mpc83xx_pcie_setup(struct pci_controller *hose,
out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAH, 0);
out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAL, 0);
- if (fsl_pcie_check_link(hose))
+ if (mpc83xx_pcie_check_link(hose))
hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
return 0;
@@ -592,6 +719,7 @@ int fsl_pci_mcheck_exception(struct pt_regs *regs)
#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
struct device_node *fsl_pci_primary;
+extern const struct of_device_id fsl_pci_ids[];
void fsl_pci_assign_primary(void)
{
@@ -607,7 +735,8 @@ void fsl_pci_assign_primary(void)
of_node_put(np);
np = fsl_pci_primary;
- if (of_match_node(pci_ids, np) && of_device_is_available(np))
+ if (of_match_node(fsl_pci_ids, np) &&
+ of_device_is_available(np))
return;
}
@@ -616,7 +745,7 @@ void fsl_pci_assign_primary(void)
* designate one as primary. This can go away once
* various bugs with primary-less systems are fixed.
*/
- for_each_matching_node(np, pci_ids) {
+ for_each_matching_node(np, fsl_pci_ids) {
if (of_device_is_available(np)) {
fsl_pci_primary = np;
of_node_put(np);
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
index 3eb32f6..2e51575 100644
--- a/drivers/edac/mpc85xx_edac.c
+++ b/drivers/edac/mpc85xx_edac.c
@@ -239,7 +239,6 @@ int mpc85xx_pci_err_probe(struct platform_device *op)
pdata = pci->pvt_info;
pdata->name = "mpc85xx_pci_err";
pdata->irq = NO_IRQ;
- dev_set_drvdata(&op->dev, pci);
pci->dev = &op->dev;
pci->mod_name = EDAC_MOD_STR;
pci->ctl_name = pdata->name;
@@ -260,14 +259,13 @@ int mpc85xx_pci_err_probe(struct platform_device *op)
/* we only need the error registers */
r.start += 0xe00;
- if (!devm_request_mem_region(&op->dev, r.start, resource_size(&r),
- pdata->name)) {
- printk(KERN_ERR "%s: Error while requesting mem region\n",
- __func__);
- res = -EBUSY;
- goto err;
- }
-
+ /*
+ * The main pci driver has been changed to call
+ * devm_request_mem_region() to request all PCI controller register
+ * region. PCI EDAC driver can not request error register region
+ * again. so it just only need to call devm_ioremap() to map the error
+ * register region.
+ */
pdata->pci_vbase = devm_ioremap(&op->dev, r.start, resource_size(&r));
if (!pdata->pci_vbase) {
printk(KERN_ERR "%s: Unable to setup PCI err regs\n", __func__);
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 3d95048..e829b18 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -19,4 +19,11 @@ config PCI_TEGRA
bool "NVIDIA Tegra PCIe controller"
depends on ARCH_TEGRA
+config PCI_FSL
+ bool "Freescale PCI/PCIe controller"
+ depends on FSL_SOC_BOOKE || PPC_86xx
+ help
+ Include support for PCI/PCIE controller on Freescale embedded
+ processors 85xx/86xx/QorIQ/Layerscape.
+
endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index c9a997b..3447a27 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
+obj-$(CONFIG_PCI_FSL) += pci-fsl.o
diff --git a/drivers/pci/host/pci-fsl.c b/drivers/pci/host/pci-fsl.c
index 69d338b..0423e72 100644
--- a/drivers/pci/host/pci-fsl.c
+++ b/drivers/pci/host/pci-fsl.c
@@ -22,38 +22,159 @@
#include <linux/bootmem.h>
#include <linux/memblock.h>
#include <linux/log2.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/pci-bridge.h>
-#include <asm/ppc-pci.h>
-#include <asm/machdep.h>
-#include <asm/disassemble.h>
-#include <asm/ppc-opcode.h>
-#include <sysdev/fsl_soc.h>
-#include <sysdev/fsl_pci.h>
-
-static int fsl_pcie_check_link(struct pci_controller *hose)
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_pci.h>
+#include <linux/pci_regs.h>
+#include <linux/platform_device.h>
+#include <linux/resource.h>
+#include <linux/types.h>
+#include <linux/memblock.h>
+#include <linux/fsl/pci.h>
+
+/* Indirect type */
+#define INDIRECT_TYPE_EXT_REG 0x00000002
+#define INDIRECT_TYPE_SURPRESS_PRIMARY_BUS 0x00000004
+#define INDIRECT_TYPE_NO_PCIE_LINK 0x00000008
+#define INDIRECT_TYPE_BIG_ENDIAN 0x00000010
+#define INDIRECT_TYPE_FSL_CFG_REG_LINK 0x00000040
+
+u64 __weak fsl_arch_pci64_dma_offset(void)
+{
+ return 0;
+}
+
+struct fsl_pci * __weak fsl_arch_sys_to_pci(void *sys)
+{
+ return NULL;
+}
+
+struct pci_bus * __weak fsl_arch_fake_pci_bus(struct fsl_pci *pci, int busnr)
+{
+ return NULL;
+}
+
+int __weak fsl_arch_pci_exclude_device(struct fsl_pci *pci, u8 bus, u8 devfn)
+{
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int fsl_pci_read_config(struct fsl_pci *pci, int bus, int devfn,
+ int offset, int len, u32 *val)
+{
+ u32 bus_no, reg, data;
+
+ if (pci->indirect_type & INDIRECT_TYPE_NO_PCIE_LINK) {
+ if (bus != pci->first_busno)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ if (devfn != 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ if (fsl_arch_pci_exclude_device(pci, bus, devfn))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ bus_no = (bus == pci->first_busno) ? pci->self_busno : bus;
+
+ if (pci->indirect_type & INDIRECT_TYPE_EXT_REG)
+ reg = ((offset & 0xf00) << 16) | (offset & 0xfc);
+ else
+ reg = offset & 0xfc;
+
+ if (pci->indirect_type & INDIRECT_TYPE_BIG_ENDIAN)
+ iowrite32be(0x80000000 | (bus_no << 16) | (devfn << 8) | reg,
+ &pci->regs->config_addr);
+ else
+ iowrite32(0x80000000 | (bus_no << 16) | (devfn << 8) | reg,
+ &pci->regs->config_addr);
+
+ /*
+ * Note: the caller has already checked that offset is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ data = ioread32(&pci->regs->config_data);
+ switch (len) {
+ case 1:
+ *val = (data >> (8 * (offset & 3))) & 0xff;
+ break;
+ case 2:
+ *val = (data >> (8 * (offset & 3))) & 0xffff;
+ break;
+ default:
+ *val = data;
+ break;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int fsl_pci_write_config(struct fsl_pci *pci, int bus, int devfn,
+ int offset, int len, u32 val)
+{
+ void __iomem *cfg_data;
+ u32 bus_no, reg;
+
+ if (pci->indirect_type & INDIRECT_TYPE_NO_PCIE_LINK) {
+ if (bus != pci->first_busno)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ if (devfn != 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ if (fsl_arch_pci_exclude_device(pci, bus, devfn))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ bus_no = (bus == pci->first_busno) ?
+ pci->self_busno : bus;
+
+ if (pci->indirect_type & INDIRECT_TYPE_EXT_REG)
+ reg = ((offset & 0xf00) << 16) | (offset & 0xfc);
+ else
+ reg = offset & 0xfc;
+
+ if (pci->indirect_type & INDIRECT_TYPE_BIG_ENDIAN)
+ iowrite32be(0x80000000 | (bus_no << 16) | (devfn << 8) | reg,
+ &pci->regs->config_addr);
+ else
+ iowrite32(0x80000000 | (bus_no << 16) | (devfn << 8) | reg,
+ &pci->regs->config_addr);
+
+ /* suppress setting of PCI_PRIMARY_BUS */
+ if (pci->indirect_type & INDIRECT_TYPE_SURPRESS_PRIMARY_BUS)
+ if ((offset == PCI_PRIMARY_BUS) &&
+ (bus == pci->first_busno))
+ val &= 0xffffff00;
+
+ /*
+ * Note: the caller has already checked that offset is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ cfg_data = ((void *) &(pci->regs->config_data)) + (offset & 3);
+ switch (len) {
+ case 1:
+ iowrite8(val, cfg_data);
+ break;
+ case 2:
+ iowrite16(val, cfg_data);
+ break;
+ default:
+ iowrite32(val, cfg_data);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int fsl_pci_check_link(struct fsl_pci *pci)
{
u32 val = 0;
- if (hose->indirect_type & PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK) {
- if (hose->ops->read == fsl_indirect_read_config) {
- struct pci_bus bus;
- bus.number = hose->first_busno;
- bus.sysdata = hose;
- bus.ops = hose->ops;
- indirect_read_config(&bus, 0, PCIE_LTSSM, 4, &val);
- } else
- early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val);
+ if (pci->indirect_type & INDIRECT_TYPE_FSL_CFG_REG_LINK) {
+ fsl_pci_read_config(pci, 0, 0, PCIE_LTSSM, 4, &val);
if (val < PCIE_LTSSM_L0)
return 1;
} else {
- struct ccsr_pci __iomem *pci = hose->private_data;
/* for PCIe IP rev 3.0 or greater use CSR0 for link state */
- val = (in_be32(&pci->pex_csr0) & PEX_CSR0_LTSSM_MASK)
+ val = (in_be32(&pci->regs->pex_csr0) & PEX_CSR0_LTSSM_MASK)
>> PEX_CSR0_LTSSM_SHIFT;
if (val != PEX_CSR0_LTSSM_L0)
return 1;
@@ -65,27 +186,65 @@ static int fsl_pcie_check_link(struct pci_controller *hose)
static int fsl_indirect_read_config(struct pci_bus *bus, unsigned int devfn,
int offset, int len, u32 *val)
{
- struct pci_controller *hose = pci_bus_to_host(bus);
+ struct fsl_pci *pci = fsl_arch_sys_to_pci(bus->sysdata);
+
+ if (!pci)
+ return PCIBIOS_DEVICE_NOT_FOUND;
- if (fsl_pcie_check_link(hose))
- hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
+ if (fsl_pci_check_link(pci))
+ pci->indirect_type |= INDIRECT_TYPE_NO_PCIE_LINK;
else
- hose->indirect_type &= ~PPC_INDIRECT_TYPE_NO_PCIE_LINK;
+ pci->indirect_type &= ~INDIRECT_TYPE_NO_PCIE_LINK;
- return indirect_read_config(bus, devfn, offset, len, val);
+ return fsl_pci_read_config(pci, bus->number, devfn, offset, len, val);
}
-#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
-
-static struct pci_ops fsl_indirect_pcie_ops =
+static int fsl_indirect_write_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 val)
{
+ struct fsl_pci *pci = fsl_arch_sys_to_pci(bus->sysdata);
+
+ if (!pci)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ return fsl_pci_write_config(pci, bus->number, devfn,
+ offset, len, val);
+}
+
+static struct pci_ops fsl_indirect_pci_ops = {
.read = fsl_indirect_read_config,
- .write = indirect_write_config,
+ .write = fsl_indirect_write_config,
};
+#define EARLY_FSL_PCI_OP(rw, size, type) \
+int early_fsl_##rw##_config_##size(struct fsl_pci *pci, int bus, \
+ int devfn, int offset, type value) \
+{ \
+ return pci_bus_##rw##_config_##size(fsl_arch_fake_pci_bus(pci, bus),\
+ devfn, offset, value); \
+}
+
+EARLY_FSL_PCI_OP(read, byte, u8 *)
+EARLY_FSL_PCI_OP(read, word, u16 *)
+EARLY_FSL_PCI_OP(read, dword, u32 *)
+EARLY_FSL_PCI_OP(write, byte, u8)
+EARLY_FSL_PCI_OP(write, word, u16)
+EARLY_FSL_PCI_OP(write, dword, u32)
+
+static int early_fsl_find_capability(struct fsl_pci *pci,
+ int busnr, int devfn, int cap)
+{
+ struct pci_bus *bus = fsl_arch_fake_pci_bus(pci, busnr);
+
+ if (!bus)
+ return 0;
+
+ return pci_bus_find_capability(bus, devfn, cap);
+}
+
static int setup_one_atmu(struct ccsr_pci __iomem *pci,
- unsigned int index, const struct resource *res,
- resource_size_t offset)
+ unsigned int index, const struct resource *res,
+ resource_size_t offset)
{
resource_size_t pci_addr = res->start - offset;
resource_size_t phys_addr = res->start;
@@ -106,10 +265,10 @@ static int setup_one_atmu(struct ccsr_pci __iomem *pci,
if (index + i >= 5)
return -1;
- out_be32(&pci->pow[index + i].potar, pci_addr >> 12);
- out_be32(&pci->pow[index + i].potear, (u64)pci_addr >> 44);
- out_be32(&pci->pow[index + i].powbar, phys_addr >> 12);
- out_be32(&pci->pow[index + i].powar, flags | (bits - 1));
+ iowrite32be(pci_addr >> 12, &pci->pow[index + i].potar);
+ iowrite32be((u64)pci_addr >> 44, &pci->pow[index + i].potear);
+ iowrite32be(phys_addr >> 12, &pci->pow[index + i].powbar);
+ iowrite32be(flags | (bits - 1), &pci->pow[index + i].powar);
pci_addr += (resource_size_t)1U << bits;
phys_addr += (resource_size_t)1U << bits;
@@ -120,21 +279,19 @@ static int setup_one_atmu(struct ccsr_pci __iomem *pci,
}
/* atmu setup for fsl pci/pcie controller */
-static void setup_pci_atmu(struct pci_controller *hose)
+static void setup_pci_atmu(struct fsl_pci *pci)
{
- struct ccsr_pci __iomem *pci = hose->private_data;
int i, j, n, mem_log, win_idx = 3, start_idx = 1, end_idx = 4;
u64 mem, sz, paddr_hi = 0;
u64 offset = 0, paddr_lo = ULLONG_MAX;
u32 pcicsrbar = 0, pcicsrbar_sz;
u32 piwar = PIWAR_EN | PIWAR_PF | PIWAR_TGI_LOCAL |
PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP;
- const char *name = hose->dn->full_name;
const u64 *reg;
int len;
- if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
- if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_2_2) {
+ if (pci->is_pcie) {
+ if (in_be32(&pci->regs->block_rev1) >= PCIE_IP_REV_2_2) {
win_idx = 2;
start_idx = 0;
end_idx = 3;
@@ -142,47 +299,54 @@ static void setup_pci_atmu(struct pci_controller *hose)
}
/* Disable all windows (except powar0 since it's ignored) */
- for(i = 1; i < 5; i++)
- out_be32(&pci->pow[i].powar, 0);
+ for (i = 1; i < 5; i++)
+ iowrite32be(0, &pci->regs->pow[i].powar);
for (i = start_idx; i < end_idx; i++)
- out_be32(&pci->piw[i].piwar, 0);
+ iowrite32be(0, &pci->regs->piw[i].piwar);
/* Setup outbound MEM window */
- for(i = 0, j = 1; i < 3; i++) {
- if (!(hose->mem_resources[i].flags & IORESOURCE_MEM))
+ for (i = 0, j = 1; i < 3; i++) {
+ if (!(pci->mem_resources[i].flags & IORESOURCE_MEM))
continue;
- paddr_lo = min(paddr_lo, (u64)hose->mem_resources[i].start);
- paddr_hi = max(paddr_hi, (u64)hose->mem_resources[i].end);
+ paddr_lo = min_t(u64, paddr_lo, pci->mem_resources[i].start);
+ paddr_hi = max_t(u64, paddr_hi, pci->mem_resources[i].end);
/* We assume all memory resources have the same offset */
- offset = hose->mem_offset[i];
- n = setup_one_atmu(pci, j, &hose->mem_resources[i], offset);
+ offset = pci->mem_offset[i];
+ n = setup_one_atmu(pci->regs, j, &pci->mem_resources[i],
+ offset);
if (n < 0 || j >= 5) {
- pr_err("Ran out of outbound PCI ATMUs for resource %d!\n", i);
- hose->mem_resources[i].flags |= IORESOURCE_DISABLED;
+ dev_err(pci->dev,
+ "Ran out of outbound PCI ATMUs for resource %d!\n",
+ i);
+ pci->mem_resources[i].flags |= IORESOURCE_DISABLED;
} else
j += n;
}
/* Setup outbound IO window */
- if (hose->io_resource.flags & IORESOURCE_IO) {
- if (j >= 5) {
- pr_err("Ran out of outbound PCI ATMUs for IO resource\n");
- } else {
- pr_debug("PCI IO resource start 0x%016llx, size 0x%016llx, "
- "phy base 0x%016llx.\n",
- (u64)hose->io_resource.start,
- (u64)resource_size(&hose->io_resource),
- (u64)hose->io_base_phys);
- out_be32(&pci->pow[j].potar, (hose->io_resource.start >> 12));
- out_be32(&pci->pow[j].potear, 0);
- out_be32(&pci->pow[j].powbar, (hose->io_base_phys >> 12));
+ if (pci->io_resource.flags & IORESOURCE_IO) {
+ if (j >= 5)
+ dev_err(pci->dev,
+ "Ran out of outbound PCI ATMUs for IO resource\n");
+ else {
+ dev_dbg(pci->dev,
+ "PCI IO resource start 0x%016llx,"
+ "size 0x%016llx, phy base 0x%016llx.\n",
+ (u64)pci->io_resource.start,
+ (u64)resource_size(&pci->io_resource),
+ (u64)pci->io_base_phys);
+ iowrite32be(pci->io_resource.start >> 12,
+ &pci->regs->pow[j].potar);
+ iowrite32be(0, &pci->regs->pow[j].potear);
+ iowrite32be(pci->io_base_phys >> 12,
+ &pci->regs->pow[j].powbar);
/* Enable, IO R/W */
- out_be32(&pci->pow[j].powar, 0x80088000
- | (ilog2(hose->io_resource.end
- - hose->io_resource.start + 1) - 1));
+ iowrite32be(0x80088000 |
+ (ilog2(resource_size(&pci->io_resource)) - 1),
+ &pci->regs->pow[j].powar);
}
}
@@ -191,18 +355,20 @@ static void setup_pci_atmu(struct pci_controller *hose)
paddr_lo -= offset;
if (paddr_hi == paddr_lo) {
- pr_err("%s: No outbound window space\n", name);
+ dev_err(pci->dev, "No outbound window space\n");
return;
}
if (paddr_lo == 0) {
- pr_err("%s: No space for inbound window\n", name);
+ dev_err(pci->dev, "No space for inbound window\n");
return;
}
/* setup PCSRBAR/PEXCSRBAR */
- early_write_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, 0xffffffff);
- early_read_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, &pcicsrbar_sz);
+ early_fsl_write_config_dword(pci, 0, 0, PCI_BASE_ADDRESS_0,
+ 0xffffffff);
+ early_fsl_read_config_dword(pci, 0, 0, PCI_BASE_ADDRESS_0,
+ &pcicsrbar_sz);
pcicsrbar_sz = ~pcicsrbar_sz + 1;
if (paddr_hi < (0x100000000ull - pcicsrbar_sz) ||
@@ -210,11 +376,12 @@ static void setup_pci_atmu(struct pci_controller *hose)
pcicsrbar = 0x100000000ull - pcicsrbar_sz;
else
pcicsrbar = (paddr_lo - pcicsrbar_sz) & -pcicsrbar_sz;
- early_write_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, pcicsrbar);
+ early_fsl_write_config_dword(pci, 0, 0, PCI_BASE_ADDRESS_0,
+ pcicsrbar);
- paddr_lo = min(paddr_lo, (u64)pcicsrbar);
+ paddr_lo = min_t(u64, paddr_lo, pcicsrbar);
- pr_info("%s: PCICSRBAR @ 0x%x\n", name, pcicsrbar);
+ dev_info(pci->dev, "PCICSRBAR @ 0x%x\n", pcicsrbar);
/* Setup inbound mem window */
mem = memblock_end_of_DRAM();
@@ -231,17 +398,19 @@ static void setup_pci_atmu(struct pci_controller *hose)
* can avoid allocating a new ATMU by extending the DDR ATMU by one
* page.
*/
- reg = of_get_property(hose->dn, "msi-address-64", &len);
+ reg = of_get_property(pci->dn, "msi-address-64", &len);
if (reg && (len == sizeof(u64))) {
u64 address = be64_to_cpup(reg);
if ((address >= mem) && (address < (mem + PAGE_SIZE))) {
- pr_info("%s: extending DDR ATMU to cover MSIIR", name);
+ dev_info(pci->dev,
+ "extending DDR ATMU to cover MSIIR\n");
mem += PAGE_SIZE;
} else {
/* TODO: Create a new ATMU for MSIIR */
- pr_warn("%s: msi-address-64 address of %llx is "
- "unsupported\n", name, address);
+ dev_warn(pci->dev,
+ "msi-address-64 address of %llx is "
+ "unsupported\n", address);
}
}
@@ -249,25 +418,26 @@ static void setup_pci_atmu(struct pci_controller *hose)
mem_log = ilog2(sz);
/* PCIe can overmap inbound & outbound since RX & TX are separated */
- if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
+ if (pci->is_pcie) {
/* Size window to exact size if power-of-two or one size up */
if ((1ull << mem_log) != mem) {
mem_log++;
if ((1ull << mem_log) > mem)
- pr_info("%s: Setting PCI inbound window "
- "greater than memory size\n", name);
+ dev_info(pci->dev,
+ "Setting PCI inbound window "
+ "greater than memory size\n");
}
piwar |= ((mem_log - 1) & PIWAR_SZ_MASK);
/* Setup inbound memory window */
- out_be32(&pci->piw[win_idx].pitar, 0x00000000);
- out_be32(&pci->piw[win_idx].piwbar, 0x00000000);
- out_be32(&pci->piw[win_idx].piwar, piwar);
+ iowrite32be(0, &pci->regs->piw[win_idx].pitar);
+ iowrite32be(0, &pci->regs->piw[win_idx].piwbar);
+ iowrite32be(piwar, &pci->regs->piw[win_idx].piwar);
win_idx--;
- hose->dma_window_base_cur = 0x00000000;
- hose->dma_window_size = (resource_size_t)sz;
+ pci->dma_window_base_cur = 0x00000000;
+ pci->dma_window_size = (resource_size_t)sz;
/*
* if we have >4G of memory setup second PCI inbound window to
@@ -284,28 +454,22 @@ static void setup_pci_atmu(struct pci_controller *hose)
piwar = (piwar & ~PIWAR_SZ_MASK) | (mem_log - 1);
/* Setup inbound memory window */
- out_be32(&pci->piw[win_idx].pitar, 0x00000000);
- out_be32(&pci->piw[win_idx].piwbear,
- pci64_dma_offset >> 44);
- out_be32(&pci->piw[win_idx].piwbar,
- pci64_dma_offset >> 12);
- out_be32(&pci->piw[win_idx].piwar, piwar);
-
- /*
- * install our own dma_set_mask handler to fixup dma_ops
- * and dma_offset
- */
- ppc_md.dma_set_mask = fsl_pci_dma_set_mask;
-
- pr_info("%s: Setup 64-bit PCI DMA window\n", name);
+ iowrite32be(0, &pci->regs->piw[win_idx].pitar);
+ iowrite32be(fsl_arch_pci64_dma_offset() >> 44,
+ &pci->regs->piw[win_idx].piwbear);
+ iowrite32be(fsl_arch_pci64_dma_offset() >> 12,
+ &pci->regs->piw[win_idx].piwbar);
+ iowrite32be(piwar,
+ &pci->regs->piw[win_idx].piwar);
}
} else {
u64 paddr = 0;
/* Setup inbound memory window */
- out_be32(&pci->piw[win_idx].pitar, paddr >> 12);
- out_be32(&pci->piw[win_idx].piwbar, paddr >> 12);
- out_be32(&pci->piw[win_idx].piwar, (piwar | (mem_log - 1)));
+ iowrite32be(paddr >> 12, &pci->regs->piw[win_idx].pitar);
+ iowrite32be(paddr >> 12, &pci->regs->piw[win_idx].piwbar);
+ iowrite32be((piwar | (mem_log - 1)),
+ &pci->regs->piw[win_idx].piwar);
win_idx--;
paddr += 1ull << mem_log;
@@ -315,167 +479,181 @@ static void setup_pci_atmu(struct pci_controller *hose)
mem_log = ilog2(sz);
piwar |= (mem_log - 1);
- out_be32(&pci->piw[win_idx].pitar, paddr >> 12);
- out_be32(&pci->piw[win_idx].piwbar, paddr >> 12);
- out_be32(&pci->piw[win_idx].piwar, piwar);
+ iowrite32be(paddr >> 12,
+ &pci->regs->piw[win_idx].pitar);
+ iowrite32be(paddr >> 12,
+ &pci->regs->piw[win_idx].piwbar);
+ iowrite32be(piwar,
+ &pci->regs->piw[win_idx].piwar);
win_idx--;
paddr += 1ull << mem_log;
}
- hose->dma_window_base_cur = 0x00000000;
- hose->dma_window_size = (resource_size_t)paddr;
+ pci->dma_window_base_cur = 0x00000000;
+ pci->dma_window_size = (resource_size_t)paddr;
}
- if (hose->dma_window_size < mem) {
-#ifdef CONFIG_SWIOTLB
- ppc_swiotlb_enable = 1;
-#else
- pr_err("%s: ERROR: Memory size exceeds PCI ATMU ability to "
- "map - enable CONFIG_SWIOTLB to avoid dma errors.\n",
- name);
+ if (pci->dma_window_size < mem) {
+#ifndef CONFIG_SWIOTLB
+ dev_err(pci->dev,
+ "Memory size exceeds PCI ATMU ability to "
+ "map - enable CONFIG_SWIOTLB to avoid dma errors.\n");
#endif
/* adjusting outbound windows could reclaim space in mem map */
if (paddr_hi < 0xffffffffull)
- pr_warning("%s: WARNING: Outbound window cfg leaves "
+ dev_warn(pci->dev,
+ "Outbound window cfg leaves "
"gaps in memory map. Adjusting the memory map "
- "could reduce unnecessary bounce buffering.\n",
- name);
+ "could reduce unnecessary bounce buffering.\n");
- pr_info("%s: DMA window size is 0x%llx\n", name,
- (u64)hose->dma_window_size);
+ dev_info(pci->dev, "DMA window size is 0x%llx\n",
+ (u64)pci->dma_window_size);
}
}
-static void __init setup_pci_cmd(struct pci_controller *hose)
+static void __init setup_pci_cmd(struct fsl_pci *pci)
{
u16 cmd;
int cap_x;
- early_read_config_word(hose, 0, 0, PCI_COMMAND, &cmd);
+ early_fsl_read_config_word(pci, 0, 0, PCI_COMMAND, &cmd);
cmd |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY
| PCI_COMMAND_IO;
- early_write_config_word(hose, 0, 0, PCI_COMMAND, cmd);
+ early_fsl_write_config_word(pci, 0, 0, PCI_COMMAND, cmd);
- cap_x = early_find_capability(hose, 0, 0, PCI_CAP_ID_PCIX);
+ cap_x = early_fsl_find_capability(pci, 0, 0, PCI_CAP_ID_PCIX);
if (cap_x) {
int pci_x_cmd = cap_x + PCI_X_CMD;
cmd = PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ
| PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E;
- early_write_config_word(hose, 0, 0, pci_x_cmd, cmd);
- } else {
- early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80);
- }
+ early_fsl_write_config_word(pci, 0, 0, pci_x_cmd, cmd);
+ } else
+ early_fsl_write_config_byte(pci, 0, 0, PCI_LATENCY_TIMER,
+ 0x80);
}
-int __init fsl_add_bridge(struct platform_device *pdev, int is_primary)
+static int __init
+fsl_pci_setup(struct platform_device *pdev, struct fsl_pci *pci)
{
- int len;
- struct pci_controller *hose;
- struct resource rsrc;
- const int *bus_range;
+ struct resource *rsrc;
u8 hdr_type, progif;
- struct device_node *dev;
- struct ccsr_pci __iomem *pci;
+ struct device_node *dn;
+ struct of_pci_range range;
+ struct of_pci_range_parser parser;
+ int mem = 0;
- dev = pdev->dev.of_node;
+ dn = pdev->dev.of_node;
+ pci->dn = dn;
+ pci->dev = &pdev->dev;
- if (!of_device_is_available(dev)) {
- pr_warning("%s: disabled\n", dev->full_name);
- return -ENODEV;
- }
-
- pr_debug("Adding PCI host bridge %s\n", dev->full_name);
+ dev_info(&pdev->dev, "Find controller %s\n", dn->full_name);
/* Fetch host bridge registers address */
- if (of_address_to_resource(dev, 0, &rsrc)) {
- printk(KERN_WARNING "Can't get pci register base!");
- return -ENOMEM;
+ rsrc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!rsrc) {
+ dev_err(&pdev->dev, "Can't get pci register base!");
+ return -EINVAL;
}
+ dev_info(&pdev->dev, "REG 0x%016llx..0x%016llx\n",
+ (u64)rsrc->start, (u64)rsrc->end);
- /* Get bus range if any */
- bus_range = of_get_property(dev, "bus-range", &len);
- if (bus_range == NULL || len < 2 * sizeof(int))
- printk(KERN_WARNING "Can't get bus-range for %s, assume"
- " bus 0\n", dev->full_name);
-
- pci_add_flags(PCI_REASSIGN_ALL_BUS);
- hose = pcibios_alloc_controller(dev);
- if (!hose)
- return -ENOMEM;
+ /* Parse pci range resources from device tree */
+ if (of_pci_range_parser_init(&parser, dn)) {
+ dev_err(&pdev->dev, "missing ranges property\n");
+ return -EINVAL;
+ }
- /* set platform device as the parent */
- hose->parent = &pdev->dev;
- hose->first_busno = bus_range ? bus_range[0] : 0x0;
- hose->last_busno = bus_range ? bus_range[1] : 0xff;
+ /* Get the I/O and memory ranges from device tree */
+ for_each_of_pci_range(&parser, &range) {
+ unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
+ if (restype == IORESOURCE_IO) {
+ of_pci_range_to_resource(&range, dn,
+ &pci->io_resource);
+ pci->io_resource.name = "I/O";
+ pci->io_resource.start = range.pci_addr;
+ pci->io_resource.end = range.pci_addr + range.size - 1;
+ pci->pci_io_size = range.size;
+ pci->io_base_phys = range.cpu_addr - range.pci_addr;
+ dev_info(&pdev->dev,
+ " IO 0x%016llx..0x%016llx -> 0x%016llx\n",
+ range.cpu_addr,
+ range.cpu_addr + range.size - 1,
+ range.pci_addr);
+ }
+ if (restype == IORESOURCE_MEM) {
+ if (mem >= 3)
+ continue;
+ of_pci_range_to_resource(&range, dn,
+ &pci->mem_resources[mem]);
+ pci->mem_resources[mem].name = "MEM";
+ pci->mem_offset[mem] = range.cpu_addr - range.pci_addr;
+ dev_info(&pdev->dev,
+ "MEM 0x%016llx..0x%016llx -> 0x%016llx\n",
+ (u64)pci->mem_resources[mem].start,
+ (u64)pci->mem_resources[mem].end,
+ range.pci_addr);
+ }
+ }
- pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n",
- (u64)rsrc.start, (u64)resource_size(&rsrc));
+ /* Get bus range */
+ if (of_pci_parse_bus_range(dn, &pci->busn)) {
+ dev_err(&pdev->dev, "failed to parse bus-range property\n");
+ pci->first_busno = 0x0;
+ pci->last_busno = 0xff;
+ } else {
+ pci->first_busno = pci->busn.start;
+ pci->last_busno = pci->busn.end;
+ }
+ dev_info(&pdev->dev, "Firmware bus number %d->%d\n",
+ pci->first_busno, pci->last_busno);
- pci = hose->private_data = ioremap(rsrc.start, resource_size(&rsrc));
- if (!hose->private_data)
- goto no_bridge;
+ pci->regs = devm_ioremap_resource(&pdev->dev, rsrc);
+ if (IS_ERR(pci->regs))
+ return PTR_ERR(pci->regs);
- setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
- PPC_INDIRECT_TYPE_BIG_ENDIAN);
+ pci->ops = &fsl_indirect_pci_ops;
+ pci->indirect_type = INDIRECT_TYPE_BIG_ENDIAN;
- if (in_be32(&pci->block_rev1) < PCIE_IP_REV_3_0)
- hose->indirect_type |= PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK;
+ if (in_be32(&pci->regs->block_rev1) < PCIE_IP_REV_3_0)
+ pci->indirect_type |= INDIRECT_TYPE_FSL_CFG_REG_LINK;
- if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
- /* use fsl_indirect_read_config for PCIe */
- hose->ops = &fsl_indirect_pcie_ops;
- /* For PCIE read HEADER_TYPE to identify controler mode */
- early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type);
- if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
+ pci->is_pcie = early_fsl_find_capability(pci, 0, 0, PCI_CAP_ID_EXP);
+ if (pci->is_pcie) {
+ /* For PCIE read HEADER_TYPE to identify controller mode */
+ early_fsl_read_config_byte(pci, 0, 0, PCI_HEADER_TYPE,
+ &hdr_type);
+ if ((hdr_type & 0x7f) == PCI_HEADER_TYPE_NORMAL)
goto no_bridge;
-
} else {
/* For PCI read PROG to identify controller mode */
- early_read_config_byte(hose, 0, 0, PCI_CLASS_PROG, &progif);
+ early_fsl_read_config_byte(pci, 0, 0, PCI_CLASS_PROG, &progif);
if ((progif & 1) == 1)
goto no_bridge;
}
- setup_pci_cmd(hose);
+ setup_pci_cmd(pci);
/* check PCI express link status */
- if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
- hose->indirect_type |= PPC_INDIRECT_TYPE_EXT_REG |
- PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS;
- if (fsl_pcie_check_link(hose))
- hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
+ if (pci->is_pcie) {
+ pci->indirect_type |= INDIRECT_TYPE_EXT_REG |
+ INDIRECT_TYPE_SURPRESS_PRIMARY_BUS;
+ if (fsl_pci_check_link(pci))
+ pci->indirect_type |= INDIRECT_TYPE_NO_PCIE_LINK;
}
- printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. "
- "Firmware bus number: %d->%d\n",
- (unsigned long long)rsrc.start, hose->first_busno,
- hose->last_busno);
-
- pr_debug(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
- hose, hose->cfg_addr, hose->cfg_data);
-
- /* Interpret the "ranges" property */
- /* This also maps the I/O region and sets isa_io/mem_base */
- pci_process_bridge_OF_ranges(hose, dev, is_primary);
-
/* Setup PEX window registers */
- setup_pci_atmu(hose);
+ setup_pci_atmu(pci);
+
+ platform_set_drvdata(pdev, pci);
return 0;
no_bridge:
- iounmap(hose->private_data);
- /* unmap cfg_data & cfg_addr separately if not on same page */
- if (((unsigned long)hose->cfg_data & PAGE_MASK) !=
- ((unsigned long)hose->cfg_addr & PAGE_MASK))
- iounmap(hose->cfg_data);
- iounmap(hose->cfg_addr);
- pcibios_free_controller(hose);
return -ENODEV;
}
-static const struct of_device_id pci_ids[] = {
+const struct of_device_id fsl_pci_ids[] = {
{ .compatible = "fsl,mpc8540-pci", },
{ .compatible = "fsl,mpc8548-pcie", },
{ .compatible = "fsl,mpc8610-pci", },
@@ -496,35 +674,63 @@ static const struct of_device_id pci_ids[] = {
{},
};
-static int fsl_pci_probe(struct platform_device *pdev)
+static int __init fsl_pci_probe(struct platform_device *pdev)
{
int ret;
- struct device_node *node;
+ struct fsl_pci *pci;
+
+ if (!of_device_is_available(pdev->dev.of_node)) {
+ dev_warn(&pdev->dev, "disabled\n");
+ return -ENODEV;
+ }
+
+ if (!fsl_arch_pci_sys_register) {
+ dev_err(&pdev->dev,
+ "no fsl_arch_pci_sys_register implementation\n");
+ return -EPERM;
+ }
+
+ pci = devm_kzalloc(&pdev->dev, sizeof(*pci), GFP_KERNEL);
+ if (!pci) {
+ dev_err(&pdev->dev, "no memory for fsl_pci\n");
+ return -ENOMEM;
+ }
- node = pdev->dev.of_node;
- ret = fsl_add_bridge(pdev, fsl_pci_primary == node);
+ ret = fsl_pci_setup(pdev, pci);
+ if (ret)
+ return ret;
- mpc85xx_pci_err_probe(pdev);
+ ret = fsl_arch_pci_sys_register(pci);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register pcie to Arch\n");
+ return ret;
+ }
return 0;
}
-#ifdef CONFIG_PM
-static int fsl_pci_resume(struct device *dev)
+static int __exit fsl_pci_remove(struct platform_device *pdev)
{
- struct pci_controller *hose;
- struct resource pci_rsrc;
+ struct fsl_pci *pci = platform_get_drvdata(pdev);
- hose = pci_find_hose_for_OF_device(dev->of_node);
- if (!hose)
+ if (!pci)
return -ENODEV;
- if (of_address_to_resource(dev->of_node, 0, &pci_rsrc)) {
- dev_err(dev, "Get pci register base failed.");
+ if (fsl_arch_pci_sys_remove)
+ fsl_arch_pci_sys_remove(pci);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int fsl_pci_resume(struct device *dev)
+{
+ struct fsl_pci *pci = dev_get_drvdata(dev);
+
+ if (!pci)
return -ENODEV;
- }
- setup_pci_atmu(hose);
+ setup_pci_atmu(pci);
return 0;
}
@@ -545,9 +751,10 @@ static struct platform_driver fsl_pci_driver = {
.driver = {
.name = "fsl-pci",
.pm = PCI_PM_OPS,
- .of_match_table = pci_ids,
+ .of_match_table = fsl_pci_ids,
},
.probe = fsl_pci_probe,
+ .remove = fsl_pci_remove,
};
static int __init fsl_pci_init(void)
diff --git a/include/linux/fsl/pci.h b/include/linux/fsl/pci.h
index bfc241d..500bdbb 100644
--- a/include/linux/fsl/pci.h
+++ b/include/linux/fsl/pci.h
@@ -102,5 +102,74 @@ struct ccsr_pci {
};
+/*
+ * Structure of a PCI controller (host bridge)
+ */
+struct fsl_pci {
+ struct list_head node;
+ int is_pcie;
+ struct device_node *dn;
+ struct device *dev;
+
+ int first_busno;
+ int last_busno;
+ int self_busno;
+ struct resource busn;
+
+ struct pci_ops *ops;
+ struct ccsr_pci __iomem *regs;
+
+ u32 indirect_type;
+
+ struct resource io_resource;
+ resource_size_t io_base_phys;
+ resource_size_t pci_io_size;
+
+ struct resource mem_resources[3];
+ resource_size_t mem_offset[3];
+
+ int global_number; /* PCI domain number */
+
+ resource_size_t dma_window_base_cur;
+ resource_size_t dma_window_size;
+
+ void *sys;
+};
+
+/* Return link status 0-> link, 1-> no link */
+int fsl_pci_check_link(struct fsl_pci *pci);
+
+/*
+ * The fsl_arch_* functions are arch hooks. Those functions are
+ * implemented as weak symbols so that they can be overridden by
+ * architecture specific code if needed.
+ */
+
+/* Return PCI64 DMA offset */
+u64 fsl_arch_pci64_dma_offset(void);
+
+/*
+ * Convert architecture specific pci controller structure to fsl_pci
+ * PowerPC uses structure pci_controller and ARM uses structure pci_sys_data
+ * to describe pci controller.
+ */
+struct fsl_pci *fsl_arch_sys_to_pci(void *sys);
+
+/*
+ * To fake a PCI bus
+ * it is called by early_fsl_*(), at that time the architecture-dependent
+ * pci controller and pci bus have not been created.
+ */
+struct pci_bus *fsl_arch_fake_pci_bus(struct fsl_pci *pci, int busnr);
+
+/* To avoid touching specified devices */
+int fsl_arch_pci_exclude_device(struct fsl_pci *pci, u8 bus, u8 devfn);
+
+/* Register PCI/PCIe controller to architecture system */
+int __weak fsl_arch_pci_sys_register(struct fsl_pci *pci);
+
+/* Remove PCI/PCIe controller from architecture system */
+void __weak fsl_arch_pci_sys_remove(struct fsl_pci *pci);
+
#endif /* __PCI_H */
#endif /* __KERNEL__ */
--
1.8.1.2
^ permalink raw reply related
* [PATCH v2 01/10] of/irq: Rework of_irq_count()
From: Thierry Reding @ 2013-09-18 13:24 UTC (permalink / raw)
To: Rob Herring, Grant Likely, Greg Kroah-Hartman, Thomas Gleixner
Cc: linux-mips, Russell King, devicetree, linux-kernel, Ralf Baechle,
sparclinux, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1379510692-32435-1-git-send-email-treding@nvidia.com>
The of_irq_to_resource() helper that is used to implement of_irq_count()
tries to resolve interrupts and in fact creates a mapping for resolved
interrupts. That's pretty heavy lifting for something that claims to
just return the number of interrupts requested by a given device node.
Instead, use the more lightweight of_irq_map_one(), which, despite the
name, doesn't create an actual mapping. Perhaps a better name would be
of_irq_translate_one().
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
drivers/of/irq.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 1752988..5f44388 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -368,9 +368,10 @@ EXPORT_SYMBOL_GPL(of_irq_to_resource);
*/
int of_irq_count(struct device_node *dev)
{
+ struct of_irq irq;
int nr = 0;
- while (of_irq_to_resource(dev, nr, NULL))
+ while (of_irq_map_one(dev, nr, &irq) == 0)
nr++;
return nr;
--
1.8.4
^ permalink raw reply related
* [PATCH v2 00/10] of/irq: Defer interrupt reference resolution
From: Thierry Reding @ 2013-09-18 13:24 UTC (permalink / raw)
To: Rob Herring, Grant Likely, Greg Kroah-Hartman, Thomas Gleixner
Cc: linux-mips, Russell King, devicetree, linux-kernel, Ralf Baechle,
sparclinux, linuxppc-dev, linux-arm-kernel
Hi,
This small series allows interrupt references from the device tree to be
resolved at driver probe time, rather than at device creation time. The
current implementation resolves such references while devices are added
during the call to of_platform_populate(), which happens very early in
the boot process. This causes probe ordering issues, because all devices
that are an interrupt parent for other devices need to have been probed
by that time. This is worked around for primary interrupt controllers by
initializing them using a device tree specific way (of_irq_init()), but
it doesn't work for something like a GPIO controller that is itself a
platform device and an interrupt parent for other devices at the same
time.
Currently such drivers use explicit initcall ordering to force these
chips to be probed earlier than other devices, but that only fixes a
subset of the problematic cases. It doesn't work if the interrupt user
is itself a platform device on the same bus. There are possibly other
cases where it doesn't work either.
This patch series attempts to fix this by not resolving the interrupt
references at device creation time. Instead, some functionality is added
to the driver core to resolve them for each device immediately before it
is probed. Often this is a lot later than the point at which the device
was created, which gives interrupt parents more time and therefore a
better chance of being probed. More importantly, however, it allows the
driver core to detect when an interrupt parent isn't there yet and cause
the device to be queued for deferred probing. After all, resolving probe
ordering issues is one of the primary reason for the introduction of
deferred probing.
Unfortunately the interrupt core code isn't prepared to handle this very
well, so some preparatory work is required.
Patches 1 and 2 are cleanup. Patch 1 modifies of_irq_count() to not use
the heavyweight of_irq_to_resource(), which will actually try to create
a mapping. While not usually harmful, it causes a warning during boot if
the interrupt parent hasn't registered an IRQ domain yet. Furthermore it
is much more than the stated intention of the function, which is to
return the number of interrupts that a device node uses. Various uses of
the of_irq_to_resource() function are replaced by more simpler versions
using irq_of_parse_and_map() in patch 2.
Patches 3 introduces the __irq_create_mapping() function, equivalent to
its non-__ counterpart except that it returns a negative error code on
failure and therefore allows propagation of a precise error code instead
of 0 for all errors. This is an important prerequisite for subsequent
patches. I would've preferred not to introduce an underscore-prefixed
variant but there are about 114 callers and updating them all would've
been rather messy.
Patch 4 updates irq_create_of_mapping() to return a negative error code
on failure instead of 0. The number of the mapped interrupt is returned
in an output parameter. All callers of this function are updated.
Patch 5 adds an __-prefixed variant of irq_of_parse_and_map() which
returns a negative error code on failure instead of 0. The number of
the mapped interrupt is returned in an output parameter.
Patch 6 modifies of_irq_to_resource() to return a negative error code on
failure (so that error can be propagated) and updates all callers.
Patch 7 propagates errors from of_irq_to_resource() to users of the
of_irq_to_resource_table() function.
Patch 8 adds functionality to the platform driver code to resolve
interrupt references at probe time. It uses the negative error code of
the of_irq_to_resource_table() function to trigger deferred probing.
Patch 9 implements similar functionality for I2C devices.
Patch 10 serves as an example of the kind of cleanup that can be done
after this series. Obviously this will require quite a bit of retesting
of working setups, but I think that in the long run we're better off
without the kind of explicit probe ordering employed by the gpio-tegra
driver and many others.
Note that I've only implemented this for platform and I2C devices, but
the same can be done for SPI and possibly other subsystems as well.
There is another use-case that I'm aware of for which a similar solution
could be implemented. IOMMUs on SoCs generally need to hook themselves
up to new platform devices. This causes a similar issues as interrupt
resolution and should be fixable by extending the of_platform_probe()
function introduced in patch 7 of this series.
Changes in v2:
- use more consistent naming and calling conventions
- use less wrappers, update more callers
- make of_platform_probe() idempotent
The initial version of this patch series can be found here:
https://lkml.org/lkml/2013/9/16/111
Thierry
Thierry Reding (10):
of/irq: Rework of_irq_count()
of/irq: Use irq_of_parse_and_map()
irqdomain: Introduce __irq_create_mapping()
irqdomain: Return errors from irq_create_of_mapping()
of/irq: Introduce __irq_of_parse_and_map()
of/irq: Return errors from of_irq_to_resource()
of/irq: Propagate errors in of_irq_to_resource_table()
of/platform: Resolve interrupt references at probe time
of/i2c: Resolve interrupt references at probe time
gpio: tegra: Use module_platform_driver()
arch/arm/mach-integrator/pci_v3.c | 8 +-
arch/arm/mach-u300/timer.c | 9 +-
arch/microblaze/pci/pci-common.c | 6 +-
arch/mips/lantiq/irq.c | 2 +-
arch/mips/lantiq/xway/gptu.c | 6 +-
arch/mips/pci/fixup-lantiq.c | 12 ++-
arch/mips/pci/pci-rt3883.c | 9 +-
arch/powerpc/kernel/pci-common.c | 7 +-
arch/powerpc/platforms/83xx/mpc832x_rdb.c | 2 +-
arch/powerpc/platforms/cell/celleb_scc_pciex.c | 8 +-
arch/powerpc/platforms/cell/celleb_scc_sio.c | 8 +-
arch/powerpc/platforms/cell/spider-pic.c | 7 +-
arch/powerpc/platforms/cell/spu_manage.c | 6 +-
arch/powerpc/platforms/fsl_uli1575.c | 7 +-
arch/powerpc/platforms/pseries/event_sources.c | 12 +--
arch/powerpc/sysdev/fsl_gtm.c | 9 +-
arch/powerpc/sysdev/mpic_msgr.c | 6 +-
arch/sparc/kernel/of_device_common.c | 12 ++-
arch/x86/kernel/devicetree.c | 11 ++-
drivers/base/platform.c | 4 +
drivers/crypto/caam/ctrl.c | 2 +-
drivers/crypto/caam/jr.c | 2 +-
drivers/crypto/omap-sham.c | 2 +-
drivers/gpio/gpio-tegra.c | 7 +-
drivers/i2c/busses/i2c-cpm.c | 2 +-
drivers/i2c/i2c-core.c | 24 ++++-
drivers/input/serio/xilinx_ps2.c | 7 +-
drivers/net/ethernet/arc/emac_main.c | 10 +--
drivers/net/ethernet/freescale/fs_enet/mac-fcc.c | 2 +-
drivers/net/ethernet/freescale/fs_enet/mac-fec.c | 2 +-
drivers/net/ethernet/freescale/fs_enet/mac-scc.c | 2 +-
drivers/net/ethernet/marvell/mv643xx_eth.c | 5 +-
drivers/of/irq.c | 49 +++++++----
drivers/of/platform.c | 107 +++++++++++++++++++++--
drivers/pci/host/pci-mvebu.c | 9 +-
drivers/spi/spi-fsl-espi.c | 6 +-
drivers/tty/serial/cpm_uart/cpm_uart_core.c | 2 +-
drivers/tty/serial/lantiq.c | 2 +-
include/linux/of_irq.h | 27 ++++--
include/linux/of_platform.h | 7 ++
kernel/irq/irqdomain.c | 87 +++++++++++-------
41 files changed, 353 insertions(+), 161 deletions(-)
--
1.8.4
^ permalink raw reply
* [PATCH v2 02/10] of/irq: Use irq_of_parse_and_map()
From: Thierry Reding @ 2013-09-18 13:24 UTC (permalink / raw)
To: Rob Herring, Grant Likely, Greg Kroah-Hartman, Thomas Gleixner
Cc: linux-mips, Russell King, devicetree, linux-kernel, Ralf Baechle,
sparclinux, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1379510692-32435-1-git-send-email-treding@nvidia.com>
Replace some instances of of_irq_map_one()/irq_create_of_mapping() and
of_irq_to_resource() by the simpler equivalent irq_of_parse_and_map().
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
arch/arm/mach-u300/timer.c | 9 ++++-----
arch/powerpc/platforms/cell/celleb_scc_pciex.c | 8 +++-----
arch/powerpc/platforms/cell/spider-pic.c | 7 ++-----
arch/powerpc/sysdev/fsl_gtm.c | 9 ++++-----
arch/powerpc/sysdev/mpic_msgr.c | 6 ++----
drivers/crypto/caam/ctrl.c | 2 +-
drivers/crypto/caam/jr.c | 2 +-
drivers/crypto/omap-sham.c | 2 +-
drivers/i2c/busses/i2c-cpm.c | 2 +-
drivers/input/serio/xilinx_ps2.c | 7 ++++---
drivers/net/ethernet/arc/emac_main.c | 10 +++++-----
drivers/net/ethernet/freescale/fs_enet/mac-fcc.c | 2 +-
drivers/net/ethernet/freescale/fs_enet/mac-fec.c | 2 +-
drivers/net/ethernet/freescale/fs_enet/mac-scc.c | 2 +-
drivers/spi/spi-fsl-espi.c | 6 +++---
drivers/tty/serial/cpm_uart/cpm_uart_core.c | 2 +-
16 files changed, 35 insertions(+), 43 deletions(-)
diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c
index b5db207..9a5f9fb 100644
--- a/arch/arm/mach-u300/timer.c
+++ b/arch/arm/mach-u300/timer.c
@@ -358,8 +358,7 @@ static struct delay_timer u300_delay_timer;
*/
static void __init u300_timer_init_of(struct device_node *np)
{
- struct resource irq_res;
- int irq;
+ unsigned int irq;
struct clk *clk;
unsigned long rate;
@@ -368,11 +367,11 @@ static void __init u300_timer_init_of(struct device_node *np)
panic("could not ioremap system timer\n");
/* Get the IRQ for the GP1 timer */
- irq = of_irq_to_resource(np, 2, &irq_res);
- if (irq <= 0)
+ irq = irq_of_parse_and_map(np, 2);
+ if (!irq)
panic("no IRQ for system timer\n");
- pr_info("U300 GP1 timer @ base: %p, IRQ: %d\n", u300_timer_base, irq);
+ pr_info("U300 GP1 timer @ base: %p, IRQ: %u\n", u300_timer_base, irq);
/* Clock the interrupt controller */
clk = of_clk_get(np, 0);
diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
index 14be2bd..856ad64 100644
--- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c
+++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
@@ -486,8 +486,7 @@ static __init int celleb_setup_pciex(struct device_node *node,
struct pci_controller *phb)
{
struct resource r;
- struct of_irq oirq;
- int virq;
+ unsigned int virq;
/* SMMIO registers; used inside this file */
if (of_address_to_resource(node, 0, &r)) {
@@ -507,12 +506,11 @@ static __init int celleb_setup_pciex(struct device_node *node,
phb->ops = &scc_pciex_pci_ops;
/* internal interrupt handler */
- if (of_irq_map_one(node, 1, &oirq)) {
+ virq = irq_of_parse_and_map(node, 1);
+ if (!virq) {
pr_err("PCIEXC:Failed to map irq\n");
goto error;
}
- virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
- oirq.size);
if (request_irq(virq, pciex_handle_internal_irq,
0, "pciex", (void *)phb)) {
pr_err("PCIEXC:Failed to request irq\n");
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 8e29944..1f72f4a 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -235,12 +235,9 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
/* First, we check whether we have a real "interrupts" in the device
* tree in case the device-tree is ever fixed
*/
- struct of_irq oirq;
- if (of_irq_map_one(pic->host->of_node, 0, &oirq) == 0) {
- virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
- oirq.size);
+ virq = irq_of_parse_and_map(pic->host->of_node, 0);
+ if (virq)
return virq;
- }
/* Now do the horrible hacks */
tmp = of_get_property(pic->host->of_node, "#interrupt-cells", NULL);
diff --git a/arch/powerpc/sysdev/fsl_gtm.c b/arch/powerpc/sysdev/fsl_gtm.c
index 0eb871c..dd0d5be 100644
--- a/arch/powerpc/sysdev/fsl_gtm.c
+++ b/arch/powerpc/sysdev/fsl_gtm.c
@@ -401,16 +401,15 @@ static int __init fsl_gtm_init(void)
gtm->clock = *clock;
for (i = 0; i < ARRAY_SIZE(gtm->timers); i++) {
- int ret;
- struct resource irq;
+ unsigned int irq;
- ret = of_irq_to_resource(np, i, &irq);
- if (ret == NO_IRQ) {
+ irq = irq_of_parse_and_map(np, i);
+ if (irq == NO_IRQ) {
pr_err("%s: not enough interrupts specified\n",
np->full_name);
goto err;
}
- gtm->timers[i].irq = irq.start;
+ gtm->timers[i].irq = irq;
gtm->timers[i].gtm = gtm;
}
diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c
index c753258..2c9b52a 100644
--- a/arch/powerpc/sysdev/mpic_msgr.c
+++ b/arch/powerpc/sysdev/mpic_msgr.c
@@ -237,15 +237,13 @@ static int mpic_msgr_probe(struct platform_device *dev)
raw_spin_lock_init(&msgr->lock);
if (receive_mask & (1 << i)) {
- struct resource irq;
-
- if (of_irq_to_resource(np, irq_index, &irq) == NO_IRQ) {
+ msgr->irq = irq_of_parse_and_map(np, irq_index);
+ if (msgr->irq == NO_IRQ) {
dev_err(&dev->dev,
"Missing interrupt specifier");
kfree(msgr);
return -EFAULT;
}
- msgr->irq = irq.start;
irq_index += 1;
} else {
msgr->irq = NO_IRQ;
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 26438cd..c8224da 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -419,7 +419,7 @@ static int caam_probe(struct platform_device *pdev)
topregs = (struct caam_full __iomem *)ctrl;
/* Get the IRQ of the controller (for security violations only) */
- ctrlpriv->secvio_irq = of_irq_to_resource(nprop, 0, NULL);
+ ctrlpriv->secvio_irq = irq_of_parse_and_map(nprop, 0);
/*
* Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel,
diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c
index 105ba4d..517a16d 100644
--- a/drivers/crypto/caam/jr.c
+++ b/drivers/crypto/caam/jr.c
@@ -403,7 +403,7 @@ int caam_jr_probe(struct platform_device *pdev, struct device_node *np,
dma_set_mask(jrdev, DMA_BIT_MASK(32));
/* Identify the interrupt */
- jrpriv->irq = of_irq_to_resource(np, 0, NULL);
+ jrpriv->irq = irq_of_parse_and_map(np, 0);
/* Now do the platform independent part */
error = caam_jr_init(jrdev); /* now turn on hardware */
diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index 8bdde57..e28104b 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -1818,7 +1818,7 @@ static int omap_sham_get_res_of(struct omap_sham_dev *dd,
goto err;
}
- dd->irq = of_irq_to_resource(node, 0, NULL);
+ dd->irq = irq_of_parse_and_map(node, 0);
if (!dd->irq) {
dev_err(dev, "can't translate OF irq value\n");
err = -EINVAL;
diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c
index b2b8aa9..3e5ea2c 100644
--- a/drivers/i2c/busses/i2c-cpm.c
+++ b/drivers/i2c/busses/i2c-cpm.c
@@ -447,7 +447,7 @@ static int cpm_i2c_setup(struct cpm_i2c *cpm)
init_waitqueue_head(&cpm->i2c_wait);
- cpm->irq = of_irq_to_resource(ofdev->dev.of_node, 0, NULL);
+ cpm->irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
if (!cpm->irq)
return -EINVAL;
diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c
index 4b7662a..36f7b95 100644
--- a/drivers/input/serio/xilinx_ps2.c
+++ b/drivers/input/serio/xilinx_ps2.c
@@ -235,12 +235,12 @@ static void sxps2_close(struct serio *pserio)
*/
static int xps2_of_probe(struct platform_device *ofdev)
{
- struct resource r_irq; /* Interrupt resources */
struct resource r_mem; /* IO mem resources */
struct xps2data *drvdata;
struct serio *serio;
struct device *dev = &ofdev->dev;
resource_size_t remap_size, phys_addr;
+ unsigned int irq;
int error;
dev_info(dev, "Device Tree Probing \'%s\'\n",
@@ -254,7 +254,8 @@ static int xps2_of_probe(struct platform_device *ofdev)
}
/* Get IRQ for the device */
- if (!of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq)) {
+ irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
+ if (!irq) {
dev_err(dev, "no IRQ found\n");
return -ENODEV;
}
@@ -267,7 +268,7 @@ static int xps2_of_probe(struct platform_device *ofdev)
}
spin_lock_init(&drvdata->lock);
- drvdata->irq = r_irq.start;
+ drvdata->irq = irq;
drvdata->serio = serio;
drvdata->dev = dev;
diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c
index 9e16014..d087852 100644
--- a/drivers/net/ethernet/arc/emac_main.c
+++ b/drivers/net/ethernet/arc/emac_main.c
@@ -628,12 +628,12 @@ static const struct net_device_ops arc_emac_netdev_ops = {
static int arc_emac_probe(struct platform_device *pdev)
{
- struct resource res_regs, res_irq;
+ struct resource res_regs;
struct device_node *phy_node;
struct arc_emac_priv *priv;
struct net_device *ndev;
const char *mac_addr;
- unsigned int id, clock_frequency;
+ unsigned int id, clock_frequency, irq;
int err;
if (!pdev->dev.of_node)
@@ -661,8 +661,8 @@ static int arc_emac_probe(struct platform_device *pdev)
}
/* Get IRQ from device tree */
- err = of_irq_to_resource(pdev->dev.of_node, 0, &res_irq);
- if (!err) {
+ irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+ if (!irq) {
dev_err(&pdev->dev, "failed to retrieve <irq> value from device tree\n");
return -ENODEV;
}
@@ -711,7 +711,7 @@ static int arc_emac_probe(struct platform_device *pdev)
goto out;
}
- ndev->irq = res_irq.start;
+ ndev->irq = irq;
dev_info(&pdev->dev, "IRQ is %d\n", ndev->irq);
/* Register interrupt handler for device */
diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c b/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c
index 7583a95..10f781d 100644
--- a/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c
+++ b/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c
@@ -88,7 +88,7 @@ static int do_pd_setup(struct fs_enet_private *fep)
struct fs_platform_info *fpi = fep->fpi;
int ret = -EINVAL;
- fep->interrupt = of_irq_to_resource(ofdev->dev.of_node, 0, NULL);
+ fep->interrupt = irq_of_parse_and_map(ofdev->dev.of_node, 0);
if (fep->interrupt == NO_IRQ)
goto out;
diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
index 9ae6cdb..53a0c23 100644
--- a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
+++ b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
@@ -98,7 +98,7 @@ static int do_pd_setup(struct fs_enet_private *fep)
{
struct platform_device *ofdev = to_platform_device(fep->dev);
- fep->interrupt = of_irq_to_resource(ofdev->dev.of_node, 0, NULL);
+ fep->interrupt = irq_of_parse_and_map(ofdev->dev.of_node, 0);
if (fep->interrupt == NO_IRQ)
return -EINVAL;
diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-scc.c b/drivers/net/ethernet/freescale/fs_enet/mac-scc.c
index 22a02a7..631f098 100644
--- a/drivers/net/ethernet/freescale/fs_enet/mac-scc.c
+++ b/drivers/net/ethernet/freescale/fs_enet/mac-scc.c
@@ -98,7 +98,7 @@ static int do_pd_setup(struct fs_enet_private *fep)
{
struct platform_device *ofdev = to_platform_device(fep->dev);
- fep->interrupt = of_irq_to_resource(ofdev->dev.of_node, 0, NULL);
+ fep->interrupt = irq_of_parse_and_map(ofdev->dev.of_node, 0);
if (fep->interrupt == NO_IRQ)
return -EINVAL;
diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index b8f1103..3197d55 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -687,7 +687,7 @@ static int of_fsl_espi_probe(struct platform_device *ofdev)
struct device_node *np = ofdev->dev.of_node;
struct spi_master *master;
struct resource mem;
- struct resource irq;
+ unsigned int irq;
int ret = -ENOMEM;
ret = of_mpc8xxx_spi_probe(ofdev);
@@ -702,13 +702,13 @@ static int of_fsl_espi_probe(struct platform_device *ofdev)
if (ret)
goto err;
- ret = of_irq_to_resource(np, 0, &irq);
+ irq = irq_of_parse_and_map(np, 0);
if (!ret) {
ret = -EINVAL;
goto err;
}
- master = fsl_espi_probe(dev, &mem, irq.start);
+ master = fsl_espi_probe(dev, &mem, irq);
if (IS_ERR(master)) {
ret = PTR_ERR(master);
goto err;
diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
index 1a535f7..6957f445 100644
--- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
@@ -1207,7 +1207,7 @@ static int cpm_uart_init_port(struct device_node *np,
pinfo->port.fifosize = pinfo->tx_nrfifos * pinfo->tx_fifosize;
spin_lock_init(&pinfo->port.lock);
- pinfo->port.irq = of_irq_to_resource(np, 0, NULL);
+ pinfo->port.irq = irq_of_parse_and_map(np, 0);
if (pinfo->port.irq == NO_IRQ) {
ret = -EINVAL;
goto out_pram;
--
1.8.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