From 8fb07c0444c37caa39a8df7c70a694c6211f2f57 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 30 Aug 2010 19:24:18 +0000 Subject: powerpc/dart_iommu: Support for 64-bit iommu bypass window on PCIe The PCI-Express bus off the U4/CPC945 bridge supports direct DMA to all of memory, bypassing the DART iommu, for 64-bit capable devices. This adds support for it on Bimini and Apple Quad G5's in order to improve DMA performances of cards using that slot (the x16 graphics slot). Tested with an Intel ixgbe 10GE card. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/sysdev/dart_iommu.c | 74 ++++++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 10 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index 559db2b846a..17cf15ec38b 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c @@ -70,6 +70,8 @@ static int iommu_table_dart_inited; static int dart_dirty; static int dart_is_u4; +#define DART_U4_BYPASS_BASE 0x8000000000ull + #define DBG(...) static inline void dart_tlb_invalidate_all(void) @@ -292,12 +294,20 @@ static void iommu_table_dart_setup(void) set_bit(iommu_table_dart.it_size - 1, iommu_table_dart.it_map); } -static void pci_dma_dev_setup_dart(struct pci_dev *dev) +static void dma_dev_setup_dart(struct device *dev) { /* We only have one iommu table on the mac for now, which makes * things simple. Setup all PCI devices to point to this table */ - set_iommu_table_base(&dev->dev, &iommu_table_dart); + if (get_dma_ops(dev) == &dma_direct_ops) + set_dma_offset(dev, DART_U4_BYPASS_BASE); + else + set_iommu_table_base(dev, &iommu_table_dart); +} + +static void pci_dma_dev_setup_dart(struct pci_dev *dev) +{ + dma_dev_setup_dart(&dev->dev); } static void pci_dma_bus_setup_dart(struct pci_bus *bus) @@ -315,6 +325,45 @@ static void pci_dma_bus_setup_dart(struct pci_bus *bus) PCI_DN(dn)->iommu_table = &iommu_table_dart; } +static bool dart_device_on_pcie(struct device *dev) +{ + struct device_node *np = of_node_get(dev->of_node); + + while(np) { + if (of_device_is_compatible(np, "U4-pcie") || + of_device_is_compatible(np, "u4-pcie")) { + of_node_put(np); + return true; + } + np = of_get_next_parent(np); + } + return false; +} + +static int dart_dma_set_mask(struct device *dev, u64 dma_mask) +{ + if (!dev->dma_mask || !dma_supported(dev, dma_mask)) + return -EIO; + + /* U4 supports a DART bypass, we use it for 64-bit capable + * devices to improve performances. However, that only works + * for devices connected to U4 own PCIe interface, not bridged + * through hypertransport. We need the device to support at + * least 40 bits of addresses. + */ + if (dart_device_on_pcie(dev) && dma_mask >= DMA_BIT_MASK(40)) { + dev_info(dev, "Using 64-bit DMA iommu bypass\n"); + set_dma_ops(dev, &dma_direct_ops); + } else { + dev_info(dev, "Using 32-bit DMA via iommu\n"); + set_dma_ops(dev, &dma_iommu_ops); + } + dma_dev_setup_dart(dev); + + *dev->dma_mask = dma_mask; + return 0; +} + void __init iommu_init_early_dart(void) { struct device_node *dn; @@ -328,20 +377,25 @@ void __init iommu_init_early_dart(void) dart_is_u4 = 1; } + /* Initialize the DART HW */ + if (dart_init(dn) != 0) + goto bail; + /* Setup low level TCE operations for the core IOMMU code */ ppc_md.tce_build = dart_build; ppc_md.tce_free = dart_free; ppc_md.tce_flush = dart_flush; - /* Initialize the DART HW */ - if (dart_init(dn) == 0) { - ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_dart; - ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_dart; + /* Setup bypass if supported */ + if (dart_is_u4) + ppc_md.dma_set_mask = dart_dma_set_mask; - /* Setup pci_dma ops */ - set_pci_dma_ops(&dma_iommu_ops); - return; - } + ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_dart; + ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_dart; + + /* Setup pci_dma ops */ + set_pci_dma_ops(&dma_iommu_ops); + return; bail: /* If init failed, use direct iommu and null setup functions */ -- cgit v1.2.3-70-g09d2 From 1c9db52534a2c0e9776788cd34ccc193289fc18c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 28 Sep 2010 16:46:51 +0200 Subject: pci: Convert msi to new irq_chip functions Signed-off-by: Thomas Gleixner Reviewed-by: Ingo Molnar Acked-by: Jesse Barnes Cc: Benjamin Herrenschmidt Cc: "David S. Miller" Cc: Tony Luck Cc: Russell King --- arch/arm/mach-iop13xx/msi.c | 8 ++++---- arch/ia64/kernel/msi_ia64.c | 4 ++-- arch/ia64/sn/kernel/msi_sn.c | 4 ++-- arch/powerpc/platforms/cell/axon_msi.c | 6 +++--- arch/powerpc/platforms/pseries/xics.c | 2 +- arch/powerpc/sysdev/fsl_msi.c | 4 ++-- arch/powerpc/sysdev/mpic_pasemi_msi.c | 22 +++++++++++----------- arch/powerpc/sysdev/mpic_u3msi.c | 18 +++++++++--------- arch/sparc/kernel/pci_msi.c | 8 ++++---- arch/x86/kernel/apic/io_apic.c | 8 ++++---- drivers/pci/msi.c | 14 +++++++------- include/linux/msi.h | 5 +++-- 12 files changed, 52 insertions(+), 51 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/arm/mach-iop13xx/msi.c b/arch/arm/mach-iop13xx/msi.c index f34b0ed8063..7149fcc16c8 100644 --- a/arch/arm/mach-iop13xx/msi.c +++ b/arch/arm/mach-iop13xx/msi.c @@ -164,10 +164,10 @@ static void iop13xx_msi_nop(unsigned int irq) static struct irq_chip iop13xx_msi_chip = { .name = "PCI-MSI", .ack = iop13xx_msi_nop, - .enable = unmask_msi_irq, - .disable = mask_msi_irq, - .mask = mask_msi_irq, - .unmask = unmask_msi_irq, + .irq_enable = unmask_msi_irq, + .irq_disable = mask_msi_irq, + .irq_mask = mask_msi_irq, + .irq_unmask = unmask_msi_irq, }; int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c index 4a746ea838f..dbb43424704 100644 --- a/arch/ia64/kernel/msi_ia64.c +++ b/arch/ia64/kernel/msi_ia64.c @@ -104,8 +104,8 @@ static int ia64_msi_retrigger_irq(unsigned int irq) */ static struct irq_chip ia64_msi_chip = { .name = "PCI-MSI", - .mask = mask_msi_irq, - .unmask = unmask_msi_irq, + .irq_mask = mask_msi_irq, + .irq_unmask = unmask_msi_irq, .ack = ia64_ack_msi_irq, #ifdef CONFIG_SMP .set_affinity = ia64_set_msi_irq_affinity, diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c index 0c72dd46383..a5e500f0285 100644 --- a/arch/ia64/sn/kernel/msi_sn.c +++ b/arch/ia64/sn/kernel/msi_sn.c @@ -228,8 +228,8 @@ static int sn_msi_retrigger_irq(unsigned int irq) static struct irq_chip sn_msi_chip = { .name = "PCI-MSI", - .mask = mask_msi_irq, - .unmask = unmask_msi_irq, + .irq_mask = mask_msi_irq, + .irq_unmask = unmask_msi_irq, .ack = sn_ack_msi_irq, #ifdef CONFIG_SMP .set_affinity = sn_set_msi_irq_affinity, diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index 97085530aa6..e3e379c6caa 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -310,9 +310,9 @@ static void axon_msi_teardown_msi_irqs(struct pci_dev *dev) } static struct irq_chip msic_irq_chip = { - .mask = mask_msi_irq, - .unmask = unmask_msi_irq, - .shutdown = unmask_msi_irq, + .irq_mask = mask_msi_irq, + .irq_unmask = unmask_msi_irq, + .irq_shutdown = mask_msi_irq, .name = "AXON-MSI", }; diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index 93834b0d827..67e2c4bdac8 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c @@ -243,7 +243,7 @@ static unsigned int xics_startup(unsigned int virq) * at that level, so we do it here by hand. */ if (irq_to_desc(virq)->msi_desc) - unmask_msi_irq(virq); + unmask_msi_irq(irq_get_irq_data(virq)); /* unmask it */ xics_unmask_irq(virq); diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 87991d3abba..bdbd896c89d 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -51,8 +51,8 @@ static void fsl_msi_end_irq(unsigned int virq) } static struct irq_chip fsl_msi_chip = { - .mask = mask_msi_irq, - .unmask = unmask_msi_irq, + .irq_mask = mask_msi_irq, + .irq_unmask = unmask_msi_irq, .ack = fsl_msi_end_irq, .name = "FSL-MSI", }; diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mpic_pasemi_msi.c index 3b6a9a43718..320ad5a9a25 100644 --- a/arch/powerpc/sysdev/mpic_pasemi_msi.c +++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c @@ -39,24 +39,24 @@ static struct mpic *msi_mpic; -static void mpic_pasemi_msi_mask_irq(unsigned int irq) +static void mpic_pasemi_msi_mask_irq(struct irq_data *data) { - pr_debug("mpic_pasemi_msi_mask_irq %d\n", irq); - mask_msi_irq(irq); - mpic_mask_irq(irq); + pr_debug("mpic_pasemi_msi_mask_irq %d\n", data->irq); + mask_msi_irq(data); + mpic_mask_irq(data->irq); } -static void mpic_pasemi_msi_unmask_irq(unsigned int irq) +static void mpic_pasemi_msi_unmask_irq(struct irq_data *data) { - pr_debug("mpic_pasemi_msi_unmask_irq %d\n", irq); - mpic_unmask_irq(irq); - unmask_msi_irq(irq); + pr_debug("mpic_pasemi_msi_unmask_irq %d\n", data->irq); + mpic_unmask_irq(data->irq); + unmask_msi_irq(data); } static struct irq_chip mpic_pasemi_msi_chip = { - .shutdown = mpic_pasemi_msi_mask_irq, - .mask = mpic_pasemi_msi_mask_irq, - .unmask = mpic_pasemi_msi_unmask_irq, + .irq_shutdown = mpic_pasemi_msi_mask_irq, + .irq_mask = mpic_pasemi_msi_mask_irq, + .irq_unmask = mpic_pasemi_msi_unmask_irq, .eoi = mpic_end_irq, .set_type = mpic_set_irq_type, .set_affinity = mpic_set_affinity, diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c index bcbfe79c704..a2b028b4a20 100644 --- a/arch/powerpc/sysdev/mpic_u3msi.c +++ b/arch/powerpc/sysdev/mpic_u3msi.c @@ -23,22 +23,22 @@ /* A bit ugly, can we get this from the pci_dev somehow? */ static struct mpic *msi_mpic; -static void mpic_u3msi_mask_irq(unsigned int irq) +static void mpic_u3msi_mask_irq(struct irq_data *data) { - mask_msi_irq(irq); - mpic_mask_irq(irq); + mask_msi_irq(data); + mpic_mask_irq(data->irq); } -static void mpic_u3msi_unmask_irq(unsigned int irq) +static void mpic_u3msi_unmask_irq(struct irq_data *data) { - mpic_unmask_irq(irq); - unmask_msi_irq(irq); + mpic_unmask_irq(data->irq); + unmask_msi_irq(data); } static struct irq_chip mpic_u3msi_chip = { - .shutdown = mpic_u3msi_mask_irq, - .mask = mpic_u3msi_mask_irq, - .unmask = mpic_u3msi_unmask_irq, + .irq_shutdown = mpic_u3msi_mask_irq, + .irq_mask = mpic_u3msi_mask_irq, + .irq_unmask = mpic_u3msi_unmask_irq, .eoi = mpic_end_irq, .set_type = mpic_set_irq_type, .set_affinity = mpic_set_affinity, diff --git a/arch/sparc/kernel/pci_msi.c b/arch/sparc/kernel/pci_msi.c index 548b8ca9c21..b210416ace7 100644 --- a/arch/sparc/kernel/pci_msi.c +++ b/arch/sparc/kernel/pci_msi.c @@ -114,10 +114,10 @@ static void free_msi(struct pci_pbm_info *pbm, int msi_num) static struct irq_chip msi_irq = { .name = "PCI-MSI", - .mask = mask_msi_irq, - .unmask = unmask_msi_irq, - .enable = unmask_msi_irq, - .disable = mask_msi_irq, + .irq_mask = mask_msi_irq, + .irq_unmask = unmask_msi_irq, + .irq_enable = unmask_msi_irq, + .irq_disable = mask_msi_irq, /* XXX affinity XXX */ }; diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 7556eb7a1a4..b79938ff9bd 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -3441,8 +3441,8 @@ ir_set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask) */ static struct irq_chip msi_chip = { .name = "PCI-MSI", - .unmask = unmask_msi_irq, - .mask = mask_msi_irq, + .irq_unmask = unmask_msi_irq, + .irq_mask = mask_msi_irq, .ack = ack_apic_edge, #ifdef CONFIG_SMP .set_affinity = set_msi_irq_affinity, @@ -3452,8 +3452,8 @@ static struct irq_chip msi_chip = { static struct irq_chip msi_ir_chip = { .name = "IR-PCI-MSI", - .unmask = unmask_msi_irq, - .mask = mask_msi_irq, + .irq_unmask = unmask_msi_irq, + .irq_mask = mask_msi_irq, #ifdef CONFIG_INTR_REMAP .ack = ir_ack_apic_edge, #ifdef CONFIG_SMP diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 69b7be33b3a..55e0f9378df 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -170,27 +170,27 @@ static void msix_mask_irq(struct msi_desc *desc, u32 flag) desc->masked = __msix_mask_irq(desc, flag); } -static void msi_set_mask_bit(unsigned irq, u32 flag) +static void msi_set_mask_bit(struct irq_data *data, u32 flag) { - struct msi_desc *desc = get_irq_msi(irq); + struct msi_desc *desc = irq_data_get_msi(data); if (desc->msi_attrib.is_msix) { msix_mask_irq(desc, flag); readl(desc->mask_base); /* Flush write to device */ } else { - unsigned offset = irq - desc->dev->irq; + unsigned offset = data->irq - desc->dev->irq; msi_mask_irq(desc, 1 << offset, flag << offset); } } -void mask_msi_irq(unsigned int irq) +void mask_msi_irq(struct irq_data *data) { - msi_set_mask_bit(irq, 1); + msi_set_mask_bit(data, 1); } -void unmask_msi_irq(unsigned int irq) +void unmask_msi_irq(struct irq_data *data) { - msi_set_mask_bit(irq, 0); + msi_set_mask_bit(data, 0); } void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) diff --git a/include/linux/msi.h b/include/linux/msi.h index 91b05c17185..329d17c395a 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -11,8 +11,9 @@ struct msi_msg { /* Helper functions */ struct irq_desc; -extern void mask_msi_irq(unsigned int irq); -extern void unmask_msi_irq(unsigned int irq); +struct irq_data; +extern void mask_msi_irq(struct irq_data *data); +extern void unmask_msi_irq(struct irq_data *data); extern void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg); extern void get_cached_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg); extern void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg); -- cgit v1.2.3-70-g09d2 From 689fd14ae9b2af5c6862ddc11d4791ec9a938cb3 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 11 Sep 2010 19:10:53 +0000 Subject: powerpc: Remove pr_ uses of KERN_ Signed-off-by: Joe Perches Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kvm/emulate.c | 4 ++-- arch/powerpc/sysdev/pmi.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c index 4568ec386c2..b83ba581fd8 100644 --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c @@ -145,7 +145,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) /* this default type might be overwritten by subcategories */ kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS); - pr_debug(KERN_INFO "Emulating opcode %d / %d\n", get_op(inst), get_xop(inst)); + pr_debug("Emulating opcode %d / %d\n", get_op(inst), get_xop(inst)); switch (get_op(inst)) { case OP_TRAP: @@ -275,7 +275,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) { u64 jd = get_tb() - vcpu->arch.dec_jiffies; kvmppc_set_gpr(vcpu, rt, vcpu->arch.dec - jd); - pr_debug(KERN_INFO "mfDEC: %x - %llx = %lx\n", + pr_debug("mfDEC: %x - %llx = %lx\n", vcpu->arch.dec, jd, kvmppc_get_gpr(vcpu, rt)); break; diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c index 24a0bb955b1..4260f368db5 100644 --- a/arch/powerpc/sysdev/pmi.c +++ b/arch/powerpc/sysdev/pmi.c @@ -114,7 +114,7 @@ static void pmi_notify_handlers(struct work_struct *work) spin_lock(&data->handler_spinlock); list_for_each_entry(handler, &data->handler, node) { - pr_debug(KERN_INFO "pmi: notifying handler %p\n", handler); + pr_debug("pmi: notifying handler %p\n", handler); if (handler->type == data->msg.type) handler->handle_pmi_message(data->msg); } -- cgit v1.2.3-70-g09d2 From 4108d9ba9091c55cfb968d42dd7dcae9a098b876 Mon Sep 17 00:00:00 2001 From: matt mooney Date: Wed, 22 Sep 2010 20:51:09 +0000 Subject: powerpc/Makefiles: Change to new flag variables Replace EXTRA_CFLAGS with ccflags-y and EXTRA_AFLAGS with asflags-y. Signed-off-by: matt mooney Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/vdso32/Makefile | 6 +++--- arch/powerpc/kernel/vdso64/Makefile | 6 +++--- arch/powerpc/kvm/Makefile | 2 +- arch/powerpc/lib/Makefile | 4 +--- arch/powerpc/math-emu/Makefile | 2 +- arch/powerpc/mm/Makefile | 4 +--- arch/powerpc/oprofile/Makefile | 4 +--- arch/powerpc/platforms/iseries/Makefile | 2 +- arch/powerpc/platforms/pseries/Makefile | 11 +++-------- arch/powerpc/sysdev/Makefile | 4 +--- arch/powerpc/xmon/Makefile | 4 +--- 11 files changed, 17 insertions(+), 32 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/kernel/vdso32/Makefile b/arch/powerpc/kernel/vdso32/Makefile index 51ead52141b..9a7946c4173 100644 --- a/arch/powerpc/kernel/vdso32/Makefile +++ b/arch/powerpc/kernel/vdso32/Makefile @@ -14,10 +14,10 @@ obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32)) GCOV_PROFILE := n -EXTRA_CFLAGS := -shared -fno-common -fno-builtin -EXTRA_CFLAGS += -nostdlib -Wl,-soname=linux-vdso32.so.1 \ +ccflags-y := -shared -fno-common -fno-builtin +ccflags-y += -nostdlib -Wl,-soname=linux-vdso32.so.1 \ $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) -EXTRA_AFLAGS := -D__VDSO32__ -s +asflags-y := -D__VDSO32__ -s obj-y += vdso32_wrapper.o extra-y += vdso32.lds diff --git a/arch/powerpc/kernel/vdso64/Makefile b/arch/powerpc/kernel/vdso64/Makefile index 79da65d44a2..8c500d8622e 100644 --- a/arch/powerpc/kernel/vdso64/Makefile +++ b/arch/powerpc/kernel/vdso64/Makefile @@ -9,10 +9,10 @@ obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64)) GCOV_PROFILE := n -EXTRA_CFLAGS := -shared -fno-common -fno-builtin -EXTRA_CFLAGS += -nostdlib -Wl,-soname=linux-vdso64.so.1 \ +ccflags-y := -shared -fno-common -fno-builtin +ccflags-y += -nostdlib -Wl,-soname=linux-vdso64.so.1 \ $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) -EXTRA_AFLAGS := -D__VDSO64__ -s +asflags-y := -D__VDSO64__ -s obj-y += vdso64_wrapper.o extra-y += vdso64.lds diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index d45c818a384..4d6863823f6 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile @@ -4,7 +4,7 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror -EXTRA_CFLAGS += -Ivirt/kvm -Iarch/powerpc/kvm +ccflags-y := -Ivirt/kvm -Iarch/powerpc/kvm common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o) diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index ad4a36848f2..889f2bc106d 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -4,9 +4,7 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror -ifeq ($(CONFIG_PPC64),y) -EXTRA_CFLAGS += -mno-minimal-toc -endif +ccflags-$(CONFIG_PPC64) := -mno-minimal-toc CFLAGS_REMOVE_code-patching.o = -pg CFLAGS_REMOVE_feature-fixups.o = -pg diff --git a/arch/powerpc/math-emu/Makefile b/arch/powerpc/math-emu/Makefile index 0c16ab947f1..7d1dba0d57f 100644 --- a/arch/powerpc/math-emu/Makefile +++ b/arch/powerpc/math-emu/Makefile @@ -15,4 +15,4 @@ obj-$(CONFIG_SPE) += math_efp.o CFLAGS_fabs.o = -fno-builtin-fabs CFLAGS_math.o = -fno-builtin-fabs -EXTRA_CFLAGS = -I. -Iinclude/math-emu -w +ccflags-y = -I. -Iinclude/math-emu -w diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile index ce68708bbad..53102f30688 100644 --- a/arch/powerpc/mm/Makefile +++ b/arch/powerpc/mm/Makefile @@ -4,9 +4,7 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror -ifeq ($(CONFIG_PPC64),y) -EXTRA_CFLAGS += -mno-minimal-toc -endif +ccflags-$(CONFIG_PPC64) := -mno-minimal-toc obj-y := fault.o mem.o pgtable.o gup.o \ init_$(CONFIG_WORD_SIZE).o \ diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile index e219ca43962..73456c4cec2 100644 --- a/arch/powerpc/oprofile/Makefile +++ b/arch/powerpc/oprofile/Makefile @@ -1,8 +1,6 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror -ifeq ($(CONFIG_PPC64),y) -EXTRA_CFLAGS += -mno-minimal-toc -endif +ccflags-$(CONFIG_PPC64) := -mno-minimal-toc obj-$(CONFIG_OPROFILE) += oprofile.o diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile index ce014928d46..a7602b11ed9 100644 --- a/arch/powerpc/platforms/iseries/Makefile +++ b/arch/powerpc/platforms/iseries/Makefile @@ -1,4 +1,4 @@ -EXTRA_CFLAGS += -mno-minimal-toc +ccflags-y := -mno-minimal-toc obj-y += exception.o obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt.o mf.o lpevents.o \ diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 93541b39dd1..59eb8bdaa79 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -1,10 +1,5 @@ -ifeq ($(CONFIG_PPC64),y) -EXTRA_CFLAGS += -mno-minimal-toc -endif - -ifeq ($(CONFIG_PPC_PSERIES_DEBUG),y) -EXTRA_CFLAGS += -DDEBUG -endif +ccflags-$(CONFIG_PPC64) := -mno-minimal-toc +ccflags-$(CONFIG_PPC_PSERIES_DEBUG) += -DDEBUG obj-y := lpar.o hvCall.o nvram.o reconfig.o \ setup.o iommu.o event_sources.o ras.o \ @@ -23,7 +18,7 @@ obj-$(CONFIG_MEMORY_HOTPLUG) += hotplug-memory.o obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o obj-$(CONFIG_HVCS) += hvcserver.o obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o -obj-$(CONFIG_PHYP_DUMP) += phyp_dump.o +obj-$(CONFIG_PHYP_DUMP) += phyp_dump.o obj-$(CONFIG_CMM) += cmm.o obj-$(CONFIG_DTL) += dtl.o diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 5642924fb9f..c20ad6de33e 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -1,8 +1,6 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror -ifeq ($(CONFIG_PPC64),y) -EXTRA_CFLAGS += -mno-minimal-toc -endif +ccflags-$(CONFIG_PPC64) := -mno-minimal-toc mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o mpic_pasemi_msi.o obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y) diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile index faa81b6a661..c168c54e3c4 100644 --- a/arch/powerpc/xmon/Makefile +++ b/arch/powerpc/xmon/Makefile @@ -4,9 +4,7 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror GCOV_PROFILE := n -ifdef CONFIG_PPC64 -EXTRA_CFLAGS += -mno-minimal-toc -endif +ccflags-$(CONFIG_PPC64) := -mno-minimal-toc obj-y += xmon.o start.o nonstdio.o -- cgit v1.2.3-70-g09d2 From b8f44ec2c05f9cfe1647173ac60c0cccb1118c91 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 5 Aug 2010 02:45:08 -0500 Subject: powerpc/fsl-pci: Fix MSI support on 83xx platforms The following commit broke 83xx because it assumed the 83xx platforms exposed the "IMMR" address in BAR0 like the 85xx/86xx/QoriQ devices do: commit 3da34aae03d498ee62f75aa7467de93cce3030fd Author: Kumar Gala Date: Tue May 12 15:51:56 2009 -0500 powerpc/fsl: Support unique MSI addresses per PCIe Root Complex However that is not true, so we have to search through the inbound window settings on 83xx to find which one matches the IMMR address to determine its PCI address. Reported-by: Ilya Yanok Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/fsl_msi.c | 9 ++++---- arch/powerpc/sysdev/fsl_pci.c | 52 +++++++++++++++++++++++++++++++++++++++++-- arch/powerpc/sysdev/fsl_pci.h | 1 + 3 files changed, 55 insertions(+), 7 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 87991d3abba..20cdcd2b0ee 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -24,6 +24,7 @@ #include #include #include "fsl_msi.h" +#include "fsl_pci.h" LIST_HEAD(msi_head); @@ -125,13 +126,11 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq, { struct fsl_msi *msi_data = fsl_msi_data; struct pci_controller *hose = pci_bus_to_host(pdev->bus); - u32 base = 0; + u64 base = fsl_pci_immrbar_base(hose); - pci_bus_read_config_dword(hose->bus, - PCI_DEVFN(0, 0), PCI_BASE_ADDRESS_0, &base); + msg->address_lo = msi_data->msi_addr_lo + lower_32_bits(base); + msg->address_hi = msi_data->msi_addr_hi + upper_32_bits(base); - msg->address_lo = msi_data->msi_addr_lo + base; - msg->address_hi = msi_data->msi_addr_hi; msg->data = hwirq; pr_debug("%s: allocated srs: %d, ibs: %d\n", diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 4ae93322525..505c8f0ece9 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -1,7 +1,7 @@ /* * MPC83xx/85xx/86xx PCI/PCIE support routing. * - * Copyright 2007-2009 Freescale Semiconductor, Inc. + * Copyright 2007-2010 Freescale Semiconductor, Inc. * Copyright 2008-2009 MontaVista Software, Inc. * * Initial author: Xianghua Xiao @@ -34,7 +34,7 @@ #include #include -static int fsl_pcie_bus_fixup; +static int fsl_pcie_bus_fixup, is_mpc83xx_pci; static void __init quirk_fsl_pcie_header(struct pci_dev *dev) { @@ -430,6 +430,13 @@ struct mpc83xx_pcie_priv { 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. @@ -437,6 +444,8 @@ struct mpc83xx_pcie_priv { #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) { @@ -604,6 +613,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev) 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); @@ -683,3 +694,40 @@ err0: 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; +} diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h index a9d8bbebed8..8ad72a11f77 100644 --- a/arch/powerpc/sysdev/fsl_pci.h +++ b/arch/powerpc/sysdev/fsl_pci.h @@ -88,6 +88,7 @@ struct ccsr_pci { extern int fsl_add_bridge(struct device_node *dev, 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); #endif /* __POWERPC_FSL_PCI_H */ #endif /* __KERNEL__ */ -- cgit v1.2.3-70-g09d2 From 4ea7c88bec9221031fa57fc7c290fdb5d279748c Mon Sep 17 00:00:00 2001 From: Matthew McClintock Date: Tue, 31 Aug 2010 17:44:51 -0500 Subject: powerpc/fsl_soc: Search all global-utilities nodes for rstccr The first global-utilities node might not contain the rstcr property, so we should search all the nodes Signed-off-by: Matthew McClintock Acked-by: Timur Tabi Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/fsl_soc.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index b91f7acdda6..6c67d9ebf16 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -378,17 +378,23 @@ static __be32 __iomem *rstcr; static int __init setup_rstcr(void) { struct device_node *np; - np = of_find_node_by_name(NULL, "global-utilities"); - if ((np && of_get_property(np, "fsl,has-rstcr", NULL))) { - rstcr = of_iomap(np, 0) + 0xb0; - if (!rstcr) - printk (KERN_EMERG "Error: reset control register " - "not mapped!\n"); - } else if (ppc_md.restart == fsl_rstcr_restart) + + for_each_node_by_name(np, "global-utilities") { + if ((of_get_property(np, "fsl,has-rstcr", NULL))) { + rstcr = of_iomap(np, 0) + 0xb0; + if (!rstcr) + printk (KERN_ERR "Error: reset control " + "register not mapped!\n"); + break; + } + } + + if (!rstcr && ppc_md.restart == fsl_rstcr_restart) printk(KERN_ERR "No RSTCR register, warm reboot won't work\n"); if (np) of_node_put(np); + return 0; } -- cgit v1.2.3-70-g09d2 From da3ed89e7ce272ebcc918487e2a28736ca0dd6bb Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 18 May 2010 07:52:36 -0500 Subject: powerpc/mpc8xxx_gpio: Add support for 'qoriq-gpio' controllers Add 'fsl,qoriq-gpio' compatiable to the list we search for to bind against for mpc8xxx_gpio. This compatiable will be used on P1-P5xxx QorIQ devices like P4080. Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/mpc8xxx_gpio.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c index 2b69084d0f0..c0ea05e87f1 100644 --- a/arch/powerpc/sysdev/mpc8xxx_gpio.c +++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c @@ -330,6 +330,9 @@ static int __init mpc8xxx_add_gpiochips(void) for_each_compatible_node(np, NULL, "fsl,mpc8610-gpio") mpc8xxx_add_controller(np); + for_each_compatible_node(np, NULL, "fsl,qoriq-gpio") + mpc8xxx_add_controller(np); + return 0; } arch_initcall(mpc8xxx_add_gpiochips); -- cgit v1.2.3-70-g09d2 From 4f0e332239e2b5f79757cb8f8f3db16c66f5d220 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 24 Sep 2010 13:34:42 -0500 Subject: powerpc/fsl-booke: Add PCI device ids for P2040/P3041/P5010/P5020 QoirQ chips Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/fsl_pci.c | 8 ++++++++ include/linux/pci_ids.h | 8 ++++++++ 2 files changed, 16 insertions(+) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 505c8f0ece9..818f7c6c8fa 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -407,10 +407,18 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2010E, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2010, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2020E, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2020, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2040E, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2040, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P3041E, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P3041, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4040E, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4040, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4080E, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4080, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P5010E, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P5010, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P5020E, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P5020, quirk_fsl_pcie_header); #endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */ #if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 570fddeb038..f69dfe5e01e 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2315,6 +2315,14 @@ #define PCI_DEVICE_ID_P4080 0x0401 #define PCI_DEVICE_ID_P4040E 0x0408 #define PCI_DEVICE_ID_P4040 0x0409 +#define PCI_DEVICE_ID_P2040E 0x0410 +#define PCI_DEVICE_ID_P2040 0x0411 +#define PCI_DEVICE_ID_P3041E 0x041E +#define PCI_DEVICE_ID_P3041 0x041F +#define PCI_DEVICE_ID_P5020E 0x0420 +#define PCI_DEVICE_ID_P5020 0x0421 +#define PCI_DEVICE_ID_P5010E 0x0428 +#define PCI_DEVICE_ID_P5010 0x0429 #define PCI_DEVICE_ID_MPC8641 0x7010 #define PCI_DEVICE_ID_MPC8641D 0x7011 #define PCI_DEVICE_ID_MPC8610 0x7018 -- cgit v1.2.3-70-g09d2 From 6db92cc9d07db9f713da8554b4bcdfc8e54ad386 Mon Sep 17 00:00:00 2001 From: Harninder Rai Date: Wed, 13 Oct 2010 17:30:56 +0530 Subject: powerpc/85xx: add cache-sram support It adds cache-sram support in P1/P2 QorIQ platforms as under: * A small abstraction over powerpc's remote heap allocator * Exports mpc85xx_cache_sram_alloc()/free() APIs * Supports only one contiguous SRAM window * Drivers can do the following in Kconfig to use these APIs "select FSL_85XX_CACHE_SRAM if MPC85xx" * Required SRAM size and the offset where SRAM should be mapped must be provided at kernel command line as : cache-sram-size= cache-sram-offset= Signed-off-by: Harninder Rai Signed-off-by: Vivek Mahajan Signed-off-by: Kumar Gala --- arch/powerpc/include/asm/fsl_85xx_cache_sram.h | 48 +++++ arch/powerpc/sysdev/Makefile | 1 + arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h | 101 +++++++++++ arch/powerpc/sysdev/fsl_85xx_cache_sram.c | 159 +++++++++++++++++ arch/powerpc/sysdev/fsl_85xx_l2ctlr.c | 231 +++++++++++++++++++++++++ 5 files changed, 540 insertions(+) create mode 100644 arch/powerpc/include/asm/fsl_85xx_cache_sram.h create mode 100644 arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h create mode 100644 arch/powerpc/sysdev/fsl_85xx_cache_sram.c create mode 100644 arch/powerpc/sysdev/fsl_85xx_l2ctlr.c (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/include/asm/fsl_85xx_cache_sram.h b/arch/powerpc/include/asm/fsl_85xx_cache_sram.h new file mode 100644 index 00000000000..2af2bdc37b2 --- /dev/null +++ b/arch/powerpc/include/asm/fsl_85xx_cache_sram.h @@ -0,0 +1,48 @@ +/* + * Copyright 2009 Freescale Semiconductor, Inc. + * + * Cache SRAM handling for QorIQ platform + * + * Author: Vivek Mahajan + + * This file is derived from the original work done + * by Sylvain Munaut for the Bestcomm SRAM allocator. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __ASM_POWERPC_FSL_85XX_CACHE_SRAM_H__ +#define __ASM_POWERPC_FSL_85XX_CACHE_SRAM_H__ + +#include +#include + +/* + * Cache-SRAM + */ + +struct mpc85xx_cache_sram { + phys_addr_t base_phys; + void *base_virt; + unsigned int size; + rh_info_t *rh; + spinlock_t lock; +}; + +extern void mpc85xx_cache_sram_free(void *ptr); +extern void *mpc85xx_cache_sram_alloc(unsigned int size, + phys_addr_t *phys, unsigned int align); + +#endif /* __AMS_POWERPC_FSL_85XX_CACHE_SRAM_H__ */ diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index c20ad6de33e..0bef9dacb64 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_FSL_PMC) += fsl_pmc.o obj-$(CONFIG_FSL_LBC) += fsl_lbc.o obj-$(CONFIG_FSL_GTM) += fsl_gtm.o obj-$(CONFIG_MPC8xxx_GPIO) += mpc8xxx_gpio.o +obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o obj-$(CONFIG_SIMPLE_GPIO) += simple_gpio.o obj-$(CONFIG_RAPIDIO) += fsl_rio.o obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o diff --git a/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h b/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h new file mode 100644 index 00000000000..60c9c0bd5ba --- /dev/null +++ b/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h @@ -0,0 +1,101 @@ +/* + * Copyright 2009-2010 Freescale Semiconductor, Inc + * + * QorIQ based Cache Controller Memory Mapped Registers + * + * Author: Vivek Mahajan + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __FSL_85XX_CACHE_CTLR_H__ +#define __FSL_85XX_CACHE_CTLR_H__ + +#define L2CR_L2FI 0x40000000 /* L2 flash invalidate */ +#define L2CR_L2IO 0x00200000 /* L2 instruction only */ +#define L2CR_SRAM_ZERO 0x00000000 /* L2SRAM zero size */ +#define L2CR_SRAM_FULL 0x00010000 /* L2SRAM full size */ +#define L2CR_SRAM_HALF 0x00020000 /* L2SRAM half size */ +#define L2CR_SRAM_TWO_HALFS 0x00030000 /* L2SRAM two half sizes */ +#define L2CR_SRAM_QUART 0x00040000 /* L2SRAM one quarter size */ +#define L2CR_SRAM_TWO_QUARTS 0x00050000 /* L2SRAM two quarter size */ +#define L2CR_SRAM_EIGHTH 0x00060000 /* L2SRAM one eighth size */ +#define L2CR_SRAM_TWO_EIGHTH 0x00070000 /* L2SRAM two eighth size */ + +#define L2SRAM_OPTIMAL_SZ_SHIFT 0x00000003 /* Optimum size for L2SRAM */ + +#define L2SRAM_BAR_MSK_LO18 0xFFFFC000 /* Lower 18 bits */ +#define L2SRAM_BARE_MSK_HI4 0x0000000F /* Upper 4 bits */ + +enum cache_sram_lock_ways { + LOCK_WAYS_ZERO, + LOCK_WAYS_EIGHTH, + LOCK_WAYS_TWO_EIGHTH, + LOCK_WAYS_HALF = 4, + LOCK_WAYS_FULL = 8, +}; + +struct mpc85xx_l2ctlr { + u32 ctl; /* 0x000 - L2 control */ + u8 res1[0xC]; + u32 ewar0; /* 0x010 - External write address 0 */ + u32 ewarea0; /* 0x014 - External write address extended 0 */ + u32 ewcr0; /* 0x018 - External write ctrl */ + u8 res2[4]; + u32 ewar1; /* 0x020 - External write address 1 */ + u32 ewarea1; /* 0x024 - External write address extended 1 */ + u32 ewcr1; /* 0x028 - External write ctrl 1 */ + u8 res3[4]; + u32 ewar2; /* 0x030 - External write address 2 */ + u32 ewarea2; /* 0x034 - External write address extended 2 */ + u32 ewcr2; /* 0x038 - External write ctrl 2 */ + u8 res4[4]; + u32 ewar3; /* 0x040 - External write address 3 */ + u32 ewarea3; /* 0x044 - External write address extended 3 */ + u32 ewcr3; /* 0x048 - External write ctrl 3 */ + u8 res5[0xB4]; + u32 srbar0; /* 0x100 - SRAM base address 0 */ + u32 srbarea0; /* 0x104 - SRAM base addr reg ext address 0 */ + u32 srbar1; /* 0x108 - SRAM base address 1 */ + u32 srbarea1; /* 0x10C - SRAM base addr reg ext address 1 */ + u8 res6[0xCF0]; + u32 errinjhi; /* 0xE00 - Error injection mask high */ + u32 errinjlo; /* 0xE04 - Error injection mask low */ + u32 errinjctl; /* 0xE08 - Error injection tag/ecc control */ + u8 res7[0x14]; + u32 captdatahi; /* 0xE20 - Error data high capture */ + u32 captdatalo; /* 0xE24 - Error data low capture */ + u32 captecc; /* 0xE28 - Error syndrome */ + u8 res8[0x14]; + u32 errdet; /* 0xE40 - Error detect */ + u32 errdis; /* 0xE44 - Error disable */ + u32 errinten; /* 0xE48 - Error interrupt enable */ + u32 errattr; /* 0xE4c - Error attribute capture */ + u32 erradrrl; /* 0xE50 - Error address capture low */ + u32 erradrrh; /* 0xE54 - Error address capture high */ + u32 errctl; /* 0xE58 - Error control */ + u8 res9[0x1A4]; +}; + +struct sram_parameters { + unsigned int sram_size; + uint64_t sram_offset; +}; + +extern int instantiate_cache_sram(struct platform_device *dev, + struct sram_parameters sram_params); +extern void remove_cache_sram(struct platform_device *dev); + +#endif /* __FSL_85XX_CACHE_CTLR_H__ */ diff --git a/arch/powerpc/sysdev/fsl_85xx_cache_sram.c b/arch/powerpc/sysdev/fsl_85xx_cache_sram.c new file mode 100644 index 00000000000..54fb1922fe3 --- /dev/null +++ b/arch/powerpc/sysdev/fsl_85xx_cache_sram.c @@ -0,0 +1,159 @@ +/* + * Copyright 2009-2010 Freescale Semiconductor, Inc. + * + * Simple memory allocator abstraction for QorIQ (P1/P2) based Cache-SRAM + * + * Author: Vivek Mahajan + * + * This file is derived from the original work done + * by Sylvain Munaut for the Bestcomm SRAM allocator. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include "fsl_85xx_cache_ctlr.h" + +struct mpc85xx_cache_sram *cache_sram; + +void *mpc85xx_cache_sram_alloc(unsigned int size, + phys_addr_t *phys, unsigned int align) +{ + unsigned long offset; + unsigned long flags; + + if (unlikely(cache_sram == NULL)) + return NULL; + + if (!size || (size > cache_sram->size) || (align > cache_sram->size)) { + pr_err("%s(): size(=%x) or align(=%x) zero or too big\n", + __func__, size, align); + return NULL; + } + + if ((align & (align - 1)) || align <= 1) { + pr_err("%s(): align(=%x) must be power of two and >1\n", + __func__, align); + return NULL; + } + + spin_lock_irqsave(&cache_sram->lock, flags); + offset = rh_alloc_align(cache_sram->rh, size, align, NULL); + spin_unlock_irqrestore(&cache_sram->lock, flags); + + if (IS_ERR_VALUE(offset)) + return NULL; + + *phys = cache_sram->base_phys + offset; + + return (unsigned char *)cache_sram->base_virt + offset; +} +EXPORT_SYMBOL(mpc85xx_cache_sram_alloc); + +void mpc85xx_cache_sram_free(void *ptr) +{ + unsigned long flags; + BUG_ON(!ptr); + + spin_lock_irqsave(&cache_sram->lock, flags); + rh_free(cache_sram->rh, ptr - cache_sram->base_virt); + spin_unlock_irqrestore(&cache_sram->lock, flags); +} +EXPORT_SYMBOL(mpc85xx_cache_sram_free); + +int __init instantiate_cache_sram(struct platform_device *dev, + struct sram_parameters sram_params) +{ + int ret = 0; + + if (cache_sram) { + dev_err(&dev->dev, "Already initialized cache-sram\n"); + return -EBUSY; + } + + cache_sram = kzalloc(sizeof(struct mpc85xx_cache_sram), GFP_KERNEL); + if (!cache_sram) { + dev_err(&dev->dev, "Out of memory for cache_sram structure\n"); + return -ENOMEM; + } + + cache_sram->base_phys = sram_params.sram_offset; + cache_sram->size = sram_params.sram_size; + + if (!request_mem_region(cache_sram->base_phys, cache_sram->size, + "fsl_85xx_cache_sram")) { + dev_err(&dev->dev, "%s: request memory failed\n", + dev->dev.of_node->full_name); + ret = -ENXIO; + goto out_free; + } + + cache_sram->base_virt = ioremap_flags(cache_sram->base_phys, + cache_sram->size, _PAGE_COHERENT | PAGE_KERNEL); + if (!cache_sram->base_virt) { + dev_err(&dev->dev, "%s: ioremap_flags failed\n", + dev->dev.of_node->full_name); + ret = -ENOMEM; + goto out_release; + } + + cache_sram->rh = rh_create(sizeof(unsigned int)); + if (IS_ERR(cache_sram->rh)) { + dev_err(&dev->dev, "%s: Unable to create remote heap\n", + dev->dev.of_node->full_name); + ret = PTR_ERR(cache_sram->rh); + goto out_unmap; + } + + rh_attach_region(cache_sram->rh, 0, cache_sram->size); + spin_lock_init(&cache_sram->lock); + + dev_info(&dev->dev, "[base:0x%llx, size:0x%x] configured and loaded\n", + (unsigned long long)cache_sram->base_phys, cache_sram->size); + + return 0; + +out_unmap: + iounmap(cache_sram->base_virt); + +out_release: + release_mem_region(cache_sram->base_phys, cache_sram->size); + +out_free: + kfree(cache_sram); + return ret; +} + +void remove_cache_sram(struct platform_device *dev) +{ + BUG_ON(!cache_sram); + + rh_detach_region(cache_sram->rh, 0, cache_sram->size); + rh_destroy(cache_sram->rh); + + iounmap(cache_sram->base_virt); + release_mem_region(cache_sram->base_phys, cache_sram->size); + + kfree(cache_sram); + cache_sram = NULL; + + dev_info(&dev->dev, "MPC85xx Cache-SRAM driver unloaded\n"); +} diff --git a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c new file mode 100644 index 00000000000..cc8d6556d79 --- /dev/null +++ b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c @@ -0,0 +1,231 @@ +/* + * Copyright 2009-2010 Freescale Semiconductor, Inc. + * + * QorIQ (P1/P2) L2 controller init for Cache-SRAM instantiation + * + * Author: Vivek Mahajan + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +#include "fsl_85xx_cache_ctlr.h" + +static char *sram_size; +static char *sram_offset; +struct mpc85xx_l2ctlr __iomem *l2ctlr; + +static long get_cache_sram_size(void) +{ + unsigned long val; + + if (!sram_size || (strict_strtoul(sram_size, 0, &val) < 0)) + return -EINVAL; + + return val; +} + +static long get_cache_sram_offset(void) +{ + unsigned long val; + + if (!sram_offset || (strict_strtoul(sram_offset, 0, &val) < 0)) + return -EINVAL; + + return val; +} + +static int __init get_size_from_cmdline(char *str) +{ + if (!str) + return 0; + + sram_size = str; + return 1; +} + +static int __init get_offset_from_cmdline(char *str) +{ + if (!str) + return 0; + + sram_offset = str; + return 1; +} + +__setup("cache-sram-size=", get_size_from_cmdline); +__setup("cache-sram-offset=", get_offset_from_cmdline); + +static int __devinit mpc85xx_l2ctlr_of_probe(struct platform_device *dev, + const struct of_device_id *match) +{ + long rval; + unsigned int rem; + unsigned char ways; + const unsigned int *prop; + unsigned int l2cache_size; + struct sram_parameters sram_params; + + if (!dev->dev.of_node) { + dev_err(&dev->dev, "Device's OF-node is NULL\n"); + return -EINVAL; + } + + prop = of_get_property(dev->dev.of_node, "cache-size", NULL); + if (!prop) { + dev_err(&dev->dev, "Missing L2 cache-size\n"); + return -EINVAL; + } + l2cache_size = *prop; + + sram_params.sram_size = get_cache_sram_size(); + if (sram_params.sram_size <= 0) { + dev_err(&dev->dev, + "Entire L2 as cache, Aborting Cache-SRAM stuff\n"); + return -EINVAL; + } + + sram_params.sram_offset = get_cache_sram_offset(); + if (sram_params.sram_offset <= 0) { + dev_err(&dev->dev, + "Entire L2 as cache, provide a valid sram offset\n"); + return -EINVAL; + } + + + rem = l2cache_size % sram_params.sram_size; + ways = LOCK_WAYS_FULL * sram_params.sram_size / l2cache_size; + if (rem || (ways & (ways - 1))) { + dev_err(&dev->dev, "Illegal cache-sram-size in command line\n"); + return -EINVAL; + } + + l2ctlr = of_iomap(dev->dev.of_node, 0); + if (!l2ctlr) { + dev_err(&dev->dev, "Can't map L2 controller\n"); + return -EINVAL; + } + + /* + * Write bits[0-17] to srbar0 + */ + out_be32(&l2ctlr->srbar0, + sram_params.sram_offset & L2SRAM_BAR_MSK_LO18); + + /* + * Write bits[18-21] to srbare0 + */ +#ifdef CONFIG_PHYS_64BIT + out_be32(&l2ctlr->srbarea0, + (sram_params.sram_offset >> 32) & L2SRAM_BARE_MSK_HI4); +#endif + + clrsetbits_be32(&l2ctlr->ctl, L2CR_L2E, L2CR_L2FI); + + switch (ways) { + case LOCK_WAYS_EIGHTH: + setbits32(&l2ctlr->ctl, + L2CR_L2E | L2CR_L2FI | L2CR_SRAM_EIGHTH); + break; + + case LOCK_WAYS_TWO_EIGHTH: + setbits32(&l2ctlr->ctl, + L2CR_L2E | L2CR_L2FI | L2CR_SRAM_QUART); + break; + + case LOCK_WAYS_HALF: + setbits32(&l2ctlr->ctl, + L2CR_L2E | L2CR_L2FI | L2CR_SRAM_HALF); + break; + + case LOCK_WAYS_FULL: + default: + setbits32(&l2ctlr->ctl, + L2CR_L2E | L2CR_L2FI | L2CR_SRAM_FULL); + break; + } + eieio(); + + rval = instantiate_cache_sram(dev, sram_params); + if (rval < 0) { + dev_err(&dev->dev, "Can't instantiate Cache-SRAM\n"); + iounmap(l2ctlr); + return -EINVAL; + } + + return 0; +} + +static int __devexit mpc85xx_l2ctlr_of_remove(struct platform_device *dev) +{ + BUG_ON(!l2ctlr); + + iounmap(l2ctlr); + remove_cache_sram(dev); + dev_info(&dev->dev, "MPC85xx L2 controller unloaded\n"); + + return 0; +} + +static struct of_device_id mpc85xx_l2ctlr_of_match[] = { + { + .compatible = "fsl,p2020-l2-cache-controller", + }, + { + .compatible = "fsl,p2010-l2-cache-controller", + }, + { + .compatible = "fsl,p1020-l2-cache-controller", + }, + { + .compatible = "fsl,p1011-l2-cache-controller", + }, + { + .compatible = "fsl,p1013-l2-cache-controller", + }, + { + .compatible = "fsl,p1022-l2-cache-controller", + }, + {}, +}; + +static struct of_platform_driver mpc85xx_l2ctlr_of_platform_driver = { + .driver = { + .name = "fsl-l2ctlr", + .owner = THIS_MODULE, + .of_match_table = mpc85xx_l2ctlr_of_match, + }, + .probe = mpc85xx_l2ctlr_of_probe, + .remove = __devexit_p(mpc85xx_l2ctlr_of_remove), +}; + +static __init int mpc85xx_l2ctlr_of_init(void) +{ + return of_register_platform_driver(&mpc85xx_l2ctlr_of_platform_driver); +} + +static void __exit mpc85xx_l2ctlr_of_exit(void) +{ + of_unregister_platform_driver(&mpc85xx_l2ctlr_of_platform_driver); +} + +subsys_initcall(mpc85xx_l2ctlr_of_init); +module_exit(mpc85xx_l2ctlr_of_exit); + +MODULE_DESCRIPTION("Freescale MPC85xx L2 controller init"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-70-g09d2 From abd12fe4d1249f6c2c4b34d5ced82f179e6b5d30 Mon Sep 17 00:00:00 2001 From: Shaohui Xie Date: Thu, 14 Oct 2010 10:04:02 +0800 Subject: fsl_rio: Add comments for sRIO registers. Add some comments to make sRIO registers map better readable. Signed-off-by: Shaohui Xie Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/fsl_rio.c | 65 ++++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 25 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 3017532319c..412763672d2 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -117,44 +117,59 @@ struct rio_atmu_regs { }; struct rio_msg_regs { - u32 omr; - u32 osr; + u32 omr; /* 0xD_3000 - Outbound message 0 mode register */ + u32 osr; /* 0xD_3004 - Outbound message 0 status register */ u32 pad1; - u32 odqdpar; + u32 odqdpar; /* 0xD_300C - Outbound message 0 descriptor queue + dequeue pointer address register */ u32 pad2; - u32 osar; - u32 odpr; - u32 odatr; - u32 odcr; + u32 osar; /* 0xD_3014 - Outbound message 0 source address + register */ + u32 odpr; /* 0xD_3018 - Outbound message 0 destination port + register */ + u32 odatr; /* 0xD_301C - Outbound message 0 destination attributes + Register*/ + u32 odcr; /* 0xD_3020 - Outbound message 0 double-word count + register */ u32 pad3; - u32 odqepar; + u32 odqepar; /* 0xD_3028 - Outbound message 0 descriptor queue + enqueue pointer address register */ u32 pad4[13]; - u32 imr; - u32 isr; + u32 imr; /* 0xD_3060 - Inbound message 0 mode register */ + u32 isr; /* 0xD_3064 - Inbound message 0 status register */ u32 pad5; - u32 ifqdpar; + u32 ifqdpar; /* 0xD_306C - Inbound message 0 frame queue dequeue + pointer address register*/ u32 pad6; - u32 ifqepar; + u32 ifqepar; /* 0xD_3074 - Inbound message 0 frame queue enqueue + pointer address register */ u32 pad7[226]; - u32 odmr; - u32 odsr; + u32 odmr; /* 0xD_3400 - Outbound doorbell mode register */ + u32 odsr; /* 0xD_3404 - Outbound doorbell status register */ u32 res0[4]; - u32 oddpr; - u32 oddatr; + u32 oddpr; /* 0xD_3418 - Outbound doorbell destination port + register */ + u32 oddatr; /* 0xD_341c - Outbound doorbell destination attributes + register */ u32 res1[3]; - u32 odretcr; + u32 odretcr; /* 0xD_342C - Outbound doorbell retry error threshold + configuration register */ u32 res2[12]; - u32 dmr; - u32 dsr; + u32 dmr; /* 0xD_3460 - Inbound doorbell mode register */ + u32 dsr; /* 0xD_3464 - Inbound doorbell status register */ u32 pad8; - u32 dqdpar; + u32 dqdpar; /* 0xD_346C - Inbound doorbell queue dequeue Pointer + address register */ u32 pad9; - u32 dqepar; + u32 dqepar; /* 0xD_3474 - Inbound doorbell Queue enqueue pointer + address register */ u32 pad10[26]; - u32 pwmr; - u32 pwsr; - u32 epwqbar; - u32 pwqbar; + u32 pwmr; /* 0xD_34E0 - Inbound port-write mode register */ + u32 pwsr; /* 0xD_34E4 - Inbound port-write status register */ + u32 epwqbar; /* 0xD_34E8 - Extended Port-Write Queue Base Address + register */ + u32 pwqbar; /* 0xD_34EC - Inbound port-write queue base address + register */ }; struct rio_tx_desc { -- cgit v1.2.3-70-g09d2 From 126512e3f274802ca65ebeca8660237f0361ad48 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Tue, 28 Sep 2010 20:55:20 +0200 Subject: USB: add platform glue driver for FSL USB DR controller Replace FSL USB platform code by simple platform driver for creation of FSL USB platform devices. The driver creates platform devices based on the information from USB nodes in the flat device tree. This is the replacement for old arch fsl_soc usb code removed by this patch. The driver uses usual of-style binding, available EHCI-HCD and UDC drivers can be bound to the created devices. The new of-style driver additionaly instantiates USB OTG platform device, as the appropriate USB OTG driver will be added soon. Signed-off-by: Anatolij Gustschin Cc: Kumar Gala Cc: Grant Likely Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/sysdev/fsl_soc.c | 163 ----------------------------- drivers/usb/gadget/Kconfig | 1 + drivers/usb/host/Kconfig | 4 + drivers/usb/host/Makefile | 1 + drivers/usb/host/fsl-mph-dr-of.c | 219 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 225 insertions(+), 163 deletions(-) create mode 100644 drivers/usb/host/fsl-mph-dr-of.c (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index b91f7acdda6..49a51f134c5 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -209,169 +209,6 @@ static int __init of_add_fixed_phys(void) arch_initcall(of_add_fixed_phys); #endif /* CONFIG_FIXED_PHY */ -static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type) -{ - if (!phy_type) - return FSL_USB2_PHY_NONE; - if (!strcasecmp(phy_type, "ulpi")) - return FSL_USB2_PHY_ULPI; - if (!strcasecmp(phy_type, "utmi")) - return FSL_USB2_PHY_UTMI; - if (!strcasecmp(phy_type, "utmi_wide")) - return FSL_USB2_PHY_UTMI_WIDE; - if (!strcasecmp(phy_type, "serial")) - return FSL_USB2_PHY_SERIAL; - - return FSL_USB2_PHY_NONE; -} - -static int __init fsl_usb_of_init(void) -{ - struct device_node *np; - unsigned int i = 0; - struct platform_device *usb_dev_mph = NULL, *usb_dev_dr_host = NULL, - *usb_dev_dr_client = NULL; - int ret; - - for_each_compatible_node(np, NULL, "fsl-usb2-mph") { - struct resource r[2]; - struct fsl_usb2_platform_data usb_data; - const unsigned char *prop = NULL; - - memset(&r, 0, sizeof(r)); - memset(&usb_data, 0, sizeof(usb_data)); - - ret = of_address_to_resource(np, 0, &r[0]); - if (ret) - goto err; - - of_irq_to_resource(np, 0, &r[1]); - - usb_dev_mph = - platform_device_register_simple("fsl-ehci", i, r, 2); - if (IS_ERR(usb_dev_mph)) { - ret = PTR_ERR(usb_dev_mph); - goto err; - } - - usb_dev_mph->dev.coherent_dma_mask = 0xffffffffUL; - usb_dev_mph->dev.dma_mask = &usb_dev_mph->dev.coherent_dma_mask; - - usb_data.operating_mode = FSL_USB2_MPH_HOST; - - prop = of_get_property(np, "port0", NULL); - if (prop) - usb_data.port_enables |= FSL_USB2_PORT0_ENABLED; - - prop = of_get_property(np, "port1", NULL); - if (prop) - usb_data.port_enables |= FSL_USB2_PORT1_ENABLED; - - prop = of_get_property(np, "phy_type", NULL); - usb_data.phy_mode = determine_usb_phy(prop); - - ret = - platform_device_add_data(usb_dev_mph, &usb_data, - sizeof(struct - fsl_usb2_platform_data)); - if (ret) - goto unreg_mph; - i++; - } - - for_each_compatible_node(np, NULL, "fsl-usb2-dr") { - struct resource r[2]; - struct fsl_usb2_platform_data usb_data; - const unsigned char *prop = NULL; - - if (!of_device_is_available(np)) - continue; - - memset(&r, 0, sizeof(r)); - memset(&usb_data, 0, sizeof(usb_data)); - - ret = of_address_to_resource(np, 0, &r[0]); - if (ret) - goto unreg_mph; - - of_irq_to_resource(np, 0, &r[1]); - - prop = of_get_property(np, "dr_mode", NULL); - - if (!prop || !strcmp(prop, "host")) { - usb_data.operating_mode = FSL_USB2_DR_HOST; - usb_dev_dr_host = platform_device_register_simple( - "fsl-ehci", i, r, 2); - if (IS_ERR(usb_dev_dr_host)) { - ret = PTR_ERR(usb_dev_dr_host); - goto err; - } - } else if (prop && !strcmp(prop, "peripheral")) { - usb_data.operating_mode = FSL_USB2_DR_DEVICE; - usb_dev_dr_client = platform_device_register_simple( - "fsl-usb2-udc", i, r, 2); - if (IS_ERR(usb_dev_dr_client)) { - ret = PTR_ERR(usb_dev_dr_client); - goto err; - } - } else if (prop && !strcmp(prop, "otg")) { - usb_data.operating_mode = FSL_USB2_DR_OTG; - usb_dev_dr_host = platform_device_register_simple( - "fsl-ehci", i, r, 2); - if (IS_ERR(usb_dev_dr_host)) { - ret = PTR_ERR(usb_dev_dr_host); - goto err; - } - usb_dev_dr_client = platform_device_register_simple( - "fsl-usb2-udc", i, r, 2); - if (IS_ERR(usb_dev_dr_client)) { - ret = PTR_ERR(usb_dev_dr_client); - goto err; - } - } else { - ret = -EINVAL; - goto err; - } - - prop = of_get_property(np, "phy_type", NULL); - usb_data.phy_mode = determine_usb_phy(prop); - - if (usb_dev_dr_host) { - usb_dev_dr_host->dev.coherent_dma_mask = 0xffffffffUL; - usb_dev_dr_host->dev.dma_mask = &usb_dev_dr_host-> - dev.coherent_dma_mask; - if ((ret = platform_device_add_data(usb_dev_dr_host, - &usb_data, sizeof(struct - fsl_usb2_platform_data)))) - goto unreg_dr; - } - if (usb_dev_dr_client) { - usb_dev_dr_client->dev.coherent_dma_mask = 0xffffffffUL; - usb_dev_dr_client->dev.dma_mask = &usb_dev_dr_client-> - dev.coherent_dma_mask; - if ((ret = platform_device_add_data(usb_dev_dr_client, - &usb_data, sizeof(struct - fsl_usb2_platform_data)))) - goto unreg_dr; - } - i++; - } - return 0; - -unreg_dr: - if (usb_dev_dr_host) - platform_device_unregister(usb_dev_dr_host); - if (usb_dev_dr_client) - platform_device_unregister(usb_dev_dr_client); -unreg_mph: - if (usb_dev_mph) - platform_device_unregister(usb_dev_mph); -err: - return ret; -} - -arch_initcall(fsl_usb_of_init); - #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx) static __be32 __iomem *rstcr; diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index fab765d387b..0fe5bc876fa 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -158,6 +158,7 @@ config USB_GADGET_FSL_USB2 boolean "Freescale Highspeed USB DR Peripheral Controller" depends on FSL_SOC || ARCH_MXC select USB_GADGET_DUALSPEED + select USB_FSL_MPH_DR_OF help Some of Freescale PowerPC processors have a High Speed Dual-Role(DR) USB controller, which supports device mode. diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 2d926cec072..f3a90b0fc42 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -112,10 +112,14 @@ config XPS_USB_HCD_XILINX support both high speed and full speed devices, or high speed devices only. +config USB_FSL_MPH_DR_OF + tristate + config USB_EHCI_FSL bool "Support for Freescale on-chip EHCI USB controller" depends on USB_EHCI_HCD && FSL_SOC select USB_EHCI_ROOT_HUB_TT + select USB_FSL_MPH_DR_OF ---help--- Variation of ARC USB block used in some Freescale chips. diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index f0414429502..19b3a30b1cd 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -31,4 +31,5 @@ obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o +obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c new file mode 100644 index 00000000000..12db5d5cb0b --- /dev/null +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -0,0 +1,219 @@ +/* + * Setup platform devices needed by the Freescale multi-port host + * and/or dual-role USB controller modules based on the description + * in flat device tree. + * + * 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 +#include +#include +#include +#include +#include + +struct fsl_usb2_dev_data { + char *dr_mode; /* controller mode */ + char *drivers[3]; /* drivers to instantiate for this mode */ + enum fsl_usb2_operating_modes op_mode; /* operating mode */ +}; + +struct fsl_usb2_dev_data dr_mode_data[] __devinitdata = { + { + .dr_mode = "host", + .drivers = { "fsl-ehci", NULL, NULL, }, + .op_mode = FSL_USB2_DR_HOST, + }, + { + .dr_mode = "otg", + .drivers = { "fsl-usb2-otg", "fsl-ehci", "fsl-usb2-udc", }, + .op_mode = FSL_USB2_DR_OTG, + }, + { + .dr_mode = "peripheral", + .drivers = { "fsl-usb2-udc", NULL, NULL, }, + .op_mode = FSL_USB2_DR_DEVICE, + }, +}; + +struct fsl_usb2_dev_data * __devinit get_dr_mode_data(struct device_node *np) +{ + const unsigned char *prop; + int i; + + prop = of_get_property(np, "dr_mode", NULL); + if (prop) { + for (i = 0; i < ARRAY_SIZE(dr_mode_data); i++) { + if (!strcmp(prop, dr_mode_data[i].dr_mode)) + return &dr_mode_data[i]; + } + } + pr_warn("%s: Invalid 'dr_mode' property, fallback to host mode\n", + np->full_name); + return &dr_mode_data[0]; /* mode not specified, use host */ +} + +static enum fsl_usb2_phy_modes __devinit determine_usb_phy(const char *phy_type) +{ + if (!phy_type) + return FSL_USB2_PHY_NONE; + if (!strcasecmp(phy_type, "ulpi")) + return FSL_USB2_PHY_ULPI; + if (!strcasecmp(phy_type, "utmi")) + return FSL_USB2_PHY_UTMI; + if (!strcasecmp(phy_type, "utmi_wide")) + return FSL_USB2_PHY_UTMI_WIDE; + if (!strcasecmp(phy_type, "serial")) + return FSL_USB2_PHY_SERIAL; + + return FSL_USB2_PHY_NONE; +} + +struct platform_device * __devinit fsl_usb2_device_register( + struct platform_device *ofdev, + struct fsl_usb2_platform_data *pdata, + const char *name, int id) +{ + struct platform_device *pdev; + const struct resource *res = ofdev->resource; + unsigned int num = ofdev->num_resources; + int retval; + + pdev = platform_device_alloc(name, id); + if (!pdev) { + retval = -ENOMEM; + goto error; + } + + pdev->dev.parent = &ofdev->dev; + + pdev->dev.coherent_dma_mask = ofdev->dev.coherent_dma_mask; + pdev->dev.dma_mask = &pdev->archdata.dma_mask; + *pdev->dev.dma_mask = *ofdev->dev.dma_mask; + + retval = platform_device_add_data(pdev, pdata, sizeof(*pdata)); + if (retval) + goto error; + + if (num) { + retval = platform_device_add_resources(pdev, res, num); + if (retval) + goto error; + } + + retval = platform_device_add(pdev); + if (retval) + goto error; + + return pdev; + +error: + platform_device_put(pdev); + return ERR_PTR(retval); +} + +static const struct of_device_id fsl_usb2_mph_dr_of_match[]; + +static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev) +{ + struct device_node *np = ofdev->dev.of_node; + struct platform_device *usb_dev; + struct fsl_usb2_platform_data data, *pdata; + struct fsl_usb2_dev_data *dev_data; + const struct of_device_id *match; + const unsigned char *prop; + static unsigned int idx; + int i; + + if (!of_device_is_available(np)) + return -ENODEV; + + match = of_match_device(fsl_usb2_mph_dr_of_match, &ofdev->dev); + if (!match) + return -ENODEV; + + pdata = &data; + if (match->data) + memcpy(pdata, match->data, sizeof(data)); + else + memset(pdata, 0, sizeof(data)); + + dev_data = get_dr_mode_data(np); + + if (of_device_is_compatible(np, "fsl-usb2-mph")) { + if (of_get_property(np, "port0", NULL)) + pdata->port_enables |= FSL_USB2_PORT0_ENABLED; + + if (of_get_property(np, "port1", NULL)) + pdata->port_enables |= FSL_USB2_PORT1_ENABLED; + + pdata->operating_mode = FSL_USB2_MPH_HOST; + } else { + /* setup mode selected in the device tree */ + pdata->operating_mode = dev_data->op_mode; + } + + prop = of_get_property(np, "phy_type", NULL); + pdata->phy_mode = determine_usb_phy(prop); + + for (i = 0; i < ARRAY_SIZE(dev_data->drivers); i++) { + if (!dev_data->drivers[i]) + continue; + usb_dev = fsl_usb2_device_register(ofdev, pdata, + dev_data->drivers[i], idx); + if (IS_ERR(usb_dev)) { + dev_err(&ofdev->dev, "Can't register usb device\n"); + return PTR_ERR(usb_dev); + } + } + idx++; + return 0; +} + +static int __devexit __unregister_subdev(struct device *dev, void *d) +{ + platform_device_unregister(to_platform_device(dev)); + return 0; +} + +static int __devexit fsl_usb2_mph_dr_of_remove(struct platform_device *ofdev) +{ + device_for_each_child(&ofdev->dev, NULL, __unregister_subdev); + return 0; +} + +static const struct of_device_id fsl_usb2_mph_dr_of_match[] = { + { .compatible = "fsl-usb2-mph", }, + { .compatible = "fsl-usb2-dr", }, + {}, +}; + +static struct platform_driver fsl_usb2_mph_dr_driver = { + .driver = { + .name = "fsl-usb2-mph-dr", + .owner = THIS_MODULE, + .of_match_table = fsl_usb2_mph_dr_of_match, + }, + .probe = fsl_usb2_mph_dr_of_probe, + .remove = __devexit_p(fsl_usb2_mph_dr_of_remove), +}; + +static int __init fsl_usb2_mph_dr_init(void) +{ + return platform_driver_register(&fsl_usb2_mph_dr_driver); +} +module_init(fsl_usb2_mph_dr_init); + +static void __exit fsl_usb2_mph_dr_exit(void) +{ + platform_driver_unregister(&fsl_usb2_mph_dr_driver); +} +module_exit(fsl_usb2_mph_dr_exit); + +MODULE_DESCRIPTION("FSL MPH DR OF devices driver"); +MODULE_AUTHOR("Anatolij Gustschin "); +MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2