diff options
Diffstat (limited to 'arch/powerpc/platforms/86xx')
| -rw-r--r-- | arch/powerpc/platforms/86xx/Kconfig | 7 | ||||
| -rw-r--r-- | arch/powerpc/platforms/86xx/Makefile | 7 | ||||
| -rw-r--r-- | arch/powerpc/platforms/86xx/gef_gpio.c | 170 | ||||
| -rw-r--r-- | arch/powerpc/platforms/86xx/gef_pic.c | 252 | ||||
| -rw-r--r-- | arch/powerpc/platforms/86xx/gef_pic.h | 11 | ||||
| -rw-r--r-- | arch/powerpc/platforms/86xx/gef_ppc9a.c | 17 | ||||
| -rw-r--r-- | arch/powerpc/platforms/86xx/gef_sbc310.c | 18 | ||||
| -rw-r--r-- | arch/powerpc/platforms/86xx/gef_sbc610.c | 17 | ||||
| -rw-r--r-- | arch/powerpc/platforms/86xx/mpc8610_hpcd.c | 184 | ||||
| -rw-r--r-- | arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | 45 | ||||
| -rw-r--r-- | arch/powerpc/platforms/86xx/pic.c | 17 | ||||
| -rw-r--r-- | arch/powerpc/platforms/86xx/sbc8641d.c | 15 |
12 files changed, 119 insertions, 641 deletions
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig index a0b5638c5dc..1afd1e4a2dd 100644 --- a/arch/powerpc/platforms/86xx/Kconfig +++ b/arch/powerpc/platforms/86xx/Kconfig @@ -4,6 +4,7 @@ menuconfig PPC_86xx depends on 6xx select FSL_SOC select ALTIVEC + select ARCH_WANT_OPTIONAL_GPIOLIB help The Freescale E600 SoCs have 74xx cores. @@ -36,8 +37,8 @@ config GEF_PPC9A bool "GE PPC9A" select DEFAULT_UIMAGE select MMIO_NVRAM - select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB + select GE_FPGA help This option enables support for the GE PPC9A. @@ -45,8 +46,8 @@ config GEF_SBC310 bool "GE SBC310" select DEFAULT_UIMAGE select MMIO_NVRAM - select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB + select GE_FPGA help This option enables support for the GE SBC310. @@ -54,8 +55,8 @@ config GEF_SBC610 bool "GE SBC610" select DEFAULT_UIMAGE select MMIO_NVRAM - select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB + select GE_FPGA select HAS_RAPIDIO help This option enables support for the GE SBC610. diff --git a/arch/powerpc/platforms/86xx/Makefile b/arch/powerpc/platforms/86xx/Makefile index 4b0d7b1aa00..ede815d6489 100644 --- a/arch/powerpc/platforms/86xx/Makefile +++ b/arch/powerpc/platforms/86xx/Makefile @@ -7,7 +7,6 @@ obj-$(CONFIG_SMP) += mpc86xx_smp.o obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o obj-$(CONFIG_SBC8641D) += sbc8641d.o obj-$(CONFIG_MPC8610_HPCD) += mpc8610_hpcd.o -gef-gpio-$(CONFIG_GPIOLIB) += gef_gpio.o -obj-$(CONFIG_GEF_SBC610) += gef_sbc610.o gef_pic.o $(gef-gpio-y) -obj-$(CONFIG_GEF_SBC310) += gef_sbc310.o gef_pic.o $(gef-gpio-y) -obj-$(CONFIG_GEF_PPC9A) += gef_ppc9a.o gef_pic.o $(gef-gpio-y) +obj-$(CONFIG_GEF_SBC610) += gef_sbc610.o +obj-$(CONFIG_GEF_SBC310) += gef_sbc310.o +obj-$(CONFIG_GEF_PPC9A) += gef_ppc9a.o diff --git a/arch/powerpc/platforms/86xx/gef_gpio.c b/arch/powerpc/platforms/86xx/gef_gpio.c deleted file mode 100644 index 4ff7b1e7bba..00000000000 --- a/arch/powerpc/platforms/86xx/gef_gpio.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Driver for GE FPGA based GPIO - * - * Author: Martyn Welch <martyn.welch@ge.com> - * - * 2008 (c) GE Intelligent Platforms Embedded Systems, Inc. - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -/* TODO - * - * Configuration of output modes (totem-pole/open-drain) - * Interrupt configuration - interrupts are always generated the FPGA relies on - * the I/O interrupt controllers mask to stop them propergating - */ - -#include <linux/kernel.h> -#include <linux/compiler.h> -#include <linux/init.h> -#include <linux/io.h> -#include <linux/of.h> -#include <linux/of_device.h> -#include <linux/of_platform.h> -#include <linux/of_gpio.h> -#include <linux/gpio.h> -#include <linux/slab.h> - -#define GEF_GPIO_DIRECT 0x00 -#define GEF_GPIO_IN 0x04 -#define GEF_GPIO_OUT 0x08 -#define GEF_GPIO_TRIG 0x0C -#define GEF_GPIO_POLAR_A 0x10 -#define GEF_GPIO_POLAR_B 0x14 -#define GEF_GPIO_INT_STAT 0x18 -#define GEF_GPIO_OVERRUN 0x1C -#define GEF_GPIO_MODE 0x20 - -static void _gef_gpio_set(void __iomem *reg, unsigned int offset, int value) -{ - unsigned int data; - - data = ioread32be(reg); - /* value: 0=low; 1=high */ - if (value & 0x1) - data = data | (0x1 << offset); - else - data = data & ~(0x1 << offset); - - iowrite32be(data, reg); -} - - -static int gef_gpio_dir_in(struct gpio_chip *chip, unsigned offset) -{ - unsigned int data; - struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip); - - data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT); - data = data | (0x1 << offset); - iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT); - - return 0; -} - -static int gef_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int value) -{ - unsigned int data; - struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip); - - /* Set direction before switching to input */ - _gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value); - - data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT); - data = data & ~(0x1 << offset); - iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT); - - return 0; -} - -static int gef_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - unsigned int data; - int state = 0; - struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip); - - data = ioread32be(mmchip->regs + GEF_GPIO_IN); - state = (int)((data >> offset) & 0x1); - - return state; -} - -static void gef_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip); - - _gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value); -} - -static int __init gef_gpio_init(void) -{ - struct device_node *np; - int retval; - struct of_mm_gpio_chip *gef_gpio_chip; - - for_each_compatible_node(np, NULL, "gef,sbc610-gpio") { - - pr_debug("%s: Initialising GEF GPIO\n", np->full_name); - - /* Allocate chip structure */ - gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL); - if (!gef_gpio_chip) { - pr_err("%s: Unable to allocate structure\n", - np->full_name); - continue; - } - - /* Setup pointers to chip functions */ - gef_gpio_chip->gc.of_gpio_n_cells = 2; - gef_gpio_chip->gc.ngpio = 19; - gef_gpio_chip->gc.direction_input = gef_gpio_dir_in; - gef_gpio_chip->gc.direction_output = gef_gpio_dir_out; - gef_gpio_chip->gc.get = gef_gpio_get; - gef_gpio_chip->gc.set = gef_gpio_set; - - /* This function adds a memory mapped GPIO chip */ - retval = of_mm_gpiochip_add(np, gef_gpio_chip); - if (retval) { - kfree(gef_gpio_chip); - pr_err("%s: Unable to add GPIO\n", np->full_name); - } - } - - for_each_compatible_node(np, NULL, "gef,sbc310-gpio") { - - pr_debug("%s: Initialising GEF GPIO\n", np->full_name); - - /* Allocate chip structure */ - gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL); - if (!gef_gpio_chip) { - pr_err("%s: Unable to allocate structure\n", - np->full_name); - continue; - } - - /* Setup pointers to chip functions */ - gef_gpio_chip->gc.of_gpio_n_cells = 2; - gef_gpio_chip->gc.ngpio = 6; - gef_gpio_chip->gc.direction_input = gef_gpio_dir_in; - gef_gpio_chip->gc.direction_output = gef_gpio_dir_out; - gef_gpio_chip->gc.get = gef_gpio_get; - gef_gpio_chip->gc.set = gef_gpio_set; - - /* This function adds a memory mapped GPIO chip */ - retval = of_mm_gpiochip_add(np, gef_gpio_chip); - if (retval) { - kfree(gef_gpio_chip); - pr_err("%s: Unable to add GPIO\n", np->full_name); - } - } - - return 0; -}; -arch_initcall(gef_gpio_init); - -MODULE_DESCRIPTION("GE I/O FPGA GPIO driver"); -MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com"); -MODULE_LICENSE("GPL"); diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c deleted file mode 100644 index 94594e58594..00000000000 --- a/arch/powerpc/platforms/86xx/gef_pic.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Interrupt handling for GE FPGA based PIC - * - * Author: Martyn Welch <martyn.welch@ge.com> - * - * 2008 (c) GE Intelligent Platforms Embedded Systems, Inc. - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#include <linux/stddef.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/irq.h> -#include <linux/interrupt.h> -#include <linux/spinlock.h> - -#include <asm/byteorder.h> -#include <asm/io.h> -#include <asm/prom.h> -#include <asm/irq.h> - -#include "gef_pic.h" - -#define DEBUG -#undef DEBUG - -#ifdef DEBUG -#define DBG(fmt...) do { printk(KERN_DEBUG "gef_pic: " fmt); } while (0) -#else -#define DBG(fmt...) do { } while (0) -#endif - -#define GEF_PIC_NUM_IRQS 32 - -/* Interrupt Controller Interface Registers */ -#define GEF_PIC_INTR_STATUS 0x0000 - -#define GEF_PIC_INTR_MASK(cpu) (0x0010 + (0x4 * cpu)) -#define GEF_PIC_CPU0_INTR_MASK GEF_PIC_INTR_MASK(0) -#define GEF_PIC_CPU1_INTR_MASK GEF_PIC_INTR_MASK(1) - -#define GEF_PIC_MCP_MASK(cpu) (0x0018 + (0x4 * cpu)) -#define GEF_PIC_CPU0_MCP_MASK GEF_PIC_MCP_MASK(0) -#define GEF_PIC_CPU1_MCP_MASK GEF_PIC_MCP_MASK(1) - - -static DEFINE_RAW_SPINLOCK(gef_pic_lock); - -static void __iomem *gef_pic_irq_reg_base; -static struct irq_host *gef_pic_irq_host; -static int gef_pic_cascade_irq; - -/* - * Interrupt Controller Handling - * - * The interrupt controller handles interrupts for most on board interrupts, - * apart from PCI interrupts. For example on SBC610: - * - * 17:31 RO Reserved - * 16 RO PCI Express Doorbell 3 Status - * 15 RO PCI Express Doorbell 2 Status - * 14 RO PCI Express Doorbell 1 Status - * 13 RO PCI Express Doorbell 0 Status - * 12 RO Real Time Clock Interrupt Status - * 11 RO Temperature Interrupt Status - * 10 RO Temperature Critical Interrupt Status - * 9 RO Ethernet PHY1 Interrupt Status - * 8 RO Ethernet PHY3 Interrupt Status - * 7 RO PEX8548 Interrupt Status - * 6 RO Reserved - * 5 RO Watchdog 0 Interrupt Status - * 4 RO Watchdog 1 Interrupt Status - * 3 RO AXIS Message FIFO A Interrupt Status - * 2 RO AXIS Message FIFO B Interrupt Status - * 1 RO AXIS Message FIFO C Interrupt Status - * 0 RO AXIS Message FIFO D Interrupt Status - * - * Interrupts can be forwarded to one of two output lines. Nothing - * clever is done, so if the masks are incorrectly set, a single input - * interrupt could generate interrupts on both output lines! - * - * The dual lines are there to allow the chained interrupts to be easily - * passed into two different cores. We currently do not use this functionality - * in this driver. - * - * Controller can also be configured to generate Machine checks (MCP), again on - * two lines, to be attached to two different cores. It is suggested that these - * should be masked out. - */ - -void gef_pic_cascade(unsigned int irq, struct irq_desc *desc) -{ - struct irq_chip *chip = irq_desc_get_chip(desc); - unsigned int cascade_irq; - - /* - * See if we actually have an interrupt, call generic handling code if - * we do. - */ - cascade_irq = gef_pic_get_irq(); - - if (cascade_irq != NO_IRQ) - generic_handle_irq(cascade_irq); - - chip->irq_eoi(&desc->irq_data); -} - -static void gef_pic_mask(struct irq_data *d) -{ - unsigned long flags; - unsigned int hwirq = irqd_to_hwirq(d); - u32 mask; - - raw_spin_lock_irqsave(&gef_pic_lock, flags); - mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0)); - mask &= ~(1 << hwirq); - out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask); - raw_spin_unlock_irqrestore(&gef_pic_lock, flags); -} - -static void gef_pic_mask_ack(struct irq_data *d) -{ - /* Don't think we actually have to do anything to ack an interrupt, - * we just need to clear down the devices interrupt and it will go away - */ - gef_pic_mask(d); -} - -static void gef_pic_unmask(struct irq_data *d) -{ - unsigned long flags; - unsigned int hwirq = irqd_to_hwirq(d); - u32 mask; - - raw_spin_lock_irqsave(&gef_pic_lock, flags); - mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0)); - mask |= (1 << hwirq); - out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask); - raw_spin_unlock_irqrestore(&gef_pic_lock, flags); -} - -static struct irq_chip gef_pic_chip = { - .name = "gefp", - .irq_mask = gef_pic_mask, - .irq_mask_ack = gef_pic_mask_ack, - .irq_unmask = gef_pic_unmask, -}; - - -/* When an interrupt is being configured, this call allows some flexibilty - * in deciding which irq_chip structure is used - */ -static int gef_pic_host_map(struct irq_host *h, unsigned int virq, - irq_hw_number_t hwirq) -{ - /* All interrupts are LEVEL sensitive */ - irq_set_status_flags(virq, IRQ_LEVEL); - irq_set_chip_and_handler(virq, &gef_pic_chip, handle_level_irq); - - return 0; -} - -static int gef_pic_host_xlate(struct irq_host *h, struct device_node *ct, - const u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, unsigned int *out_flags) -{ - - *out_hwirq = intspec[0]; - if (intsize > 1) - *out_flags = intspec[1]; - else - *out_flags = IRQ_TYPE_LEVEL_HIGH; - - return 0; -} - -static struct irq_host_ops gef_pic_host_ops = { - .map = gef_pic_host_map, - .xlate = gef_pic_host_xlate, -}; - - -/* - * Initialisation of PIC, this should be called in BSP - */ -void __init gef_pic_init(struct device_node *np) -{ - unsigned long flags; - - /* Map the devices registers into memory */ - gef_pic_irq_reg_base = of_iomap(np, 0); - - raw_spin_lock_irqsave(&gef_pic_lock, flags); - - /* Initialise everything as masked. */ - out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_INTR_MASK, 0); - out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU1_INTR_MASK, 0); - - out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_MCP_MASK, 0); - out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU1_MCP_MASK, 0); - - raw_spin_unlock_irqrestore(&gef_pic_lock, flags); - - /* Map controller */ - gef_pic_cascade_irq = irq_of_parse_and_map(np, 0); - if (gef_pic_cascade_irq == NO_IRQ) { - printk(KERN_ERR "SBC610: failed to map cascade interrupt"); - return; - } - - /* Setup an irq_host structure */ - gef_pic_irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, - GEF_PIC_NUM_IRQS, - &gef_pic_host_ops, NO_IRQ); - if (gef_pic_irq_host == NULL) - return; - - /* Chain with parent controller */ - irq_set_chained_handler(gef_pic_cascade_irq, gef_pic_cascade); -} - -/* - * This is called when we receive an interrupt with apparently comes from this - * chip - check, returning the highest interrupt generated or return NO_IRQ - */ -unsigned int gef_pic_get_irq(void) -{ - u32 cause, mask, active; - unsigned int virq = NO_IRQ; - int hwirq; - - cause = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_STATUS); - - mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0)); - - active = cause & mask; - - if (active) { - for (hwirq = GEF_PIC_NUM_IRQS - 1; hwirq > -1; hwirq--) { - if (active & (0x1 << hwirq)) - break; - } - virq = irq_linear_revmap(gef_pic_irq_host, - (irq_hw_number_t)hwirq); - } - - return virq; -} - diff --git a/arch/powerpc/platforms/86xx/gef_pic.h b/arch/powerpc/platforms/86xx/gef_pic.h deleted file mode 100644 index 6149916da3f..00000000000 --- a/arch/powerpc/platforms/86xx/gef_pic.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __GEF_PIC_H__ -#define __GEF_PIC_H__ - -#include <linux/init.h> - -void gef_pic_cascade(unsigned int, struct irq_desc *); -unsigned int gef_pic_get_irq(void); -void gef_pic_init(struct device_node *); - -#endif /* __GEF_PIC_H__ */ - diff --git a/arch/powerpc/platforms/86xx/gef_ppc9a.c b/arch/powerpc/platforms/86xx/gef_ppc9a.c index 60ce07e3910..c23f3443880 100644 --- a/arch/powerpc/platforms/86xx/gef_ppc9a.c +++ b/arch/powerpc/platforms/86xx/gef_ppc9a.c @@ -24,7 +24,6 @@ #include <linux/seq_file.h> #include <linux/of_platform.h> -#include <asm/system.h> #include <asm/time.h> #include <asm/machdep.h> #include <asm/pci-bridge.h> @@ -37,9 +36,9 @@ #include <sysdev/fsl_pci.h> #include <sysdev/fsl_soc.h> +#include <sysdev/ge/ge_pic.h> #include "mpc86xx.h" -#include "gef_pic.h" #undef DEBUG @@ -74,13 +73,6 @@ static void __init gef_ppc9a_init_irq(void) static void __init gef_ppc9a_setup_arch(void) { struct device_node *regs; -#ifdef CONFIG_PCI - struct device_node *np; - - for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") { - fsl_add_bridge(np, 1); - } -#endif printk(KERN_INFO "GE Intelligent Platforms PPC9A 6U VME SBC\n"); @@ -88,6 +80,8 @@ static void __init gef_ppc9a_setup_arch(void) mpc86xx_smp_init(); #endif + fsl_pci_assign_primary(); + /* Remap basic board registers */ regs = of_find_compatible_node(NULL, NULL, "gef,ppc9a-fpga-regs"); if (regs) { @@ -165,7 +159,7 @@ static void gef_ppc9a_show_cpuinfo(struct seq_file *m) gef_ppc9a_get_vme_is_syscon() ? "yes" : "no"); } -static void __init gef_ppc9a_nec_fixup(struct pci_dev *pdev) +static void gef_ppc9a_nec_fixup(struct pci_dev *pdev) { unsigned int val; @@ -222,6 +216,7 @@ static long __init mpc86xx_time_init(void) static __initdata struct of_device_id of_bus_ids[] = { { .compatible = "simple-bus", }, { .compatible = "gianfar", }, + { .compatible = "fsl,mpc8641-pcie", }, {}, }; @@ -232,7 +227,7 @@ static int __init declare_of_platform_devices(void) return 0; } -machine_device_initcall(gef_ppc9a, declare_of_platform_devices); +machine_arch_initcall(gef_ppc9a, declare_of_platform_devices); define_machine(gef_ppc9a) { .name = "GE PPC9A", diff --git a/arch/powerpc/platforms/86xx/gef_sbc310.c b/arch/powerpc/platforms/86xx/gef_sbc310.c index 3ecee25bf3e..8a6ac20686e 100644 --- a/arch/powerpc/platforms/86xx/gef_sbc310.c +++ b/arch/powerpc/platforms/86xx/gef_sbc310.c @@ -24,7 +24,6 @@ #include <linux/seq_file.h> #include <linux/of_platform.h> -#include <asm/system.h> #include <asm/time.h> #include <asm/machdep.h> #include <asm/pci-bridge.h> @@ -37,9 +36,9 @@ #include <sysdev/fsl_pci.h> #include <sysdev/fsl_soc.h> +#include <sysdev/ge/ge_pic.h> #include "mpc86xx.h" -#include "gef_pic.h" #undef DEBUG @@ -74,20 +73,14 @@ static void __init gef_sbc310_init_irq(void) static void __init gef_sbc310_setup_arch(void) { struct device_node *regs; -#ifdef CONFIG_PCI - struct device_node *np; - - for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") { - fsl_add_bridge(np, 1); - } -#endif - printk(KERN_INFO "GE Intelligent Platforms SBC310 6U VPX SBC\n"); #ifdef CONFIG_SMP mpc86xx_smp_init(); #endif + fsl_pci_assign_primary(); + /* Remap basic board registers */ regs = of_find_compatible_node(NULL, NULL, "gef,fpga-regs"); if (regs) { @@ -153,7 +146,7 @@ static void gef_sbc310_show_cpuinfo(struct seq_file *m) } -static void __init gef_sbc310_nec_fixup(struct pci_dev *pdev) +static void gef_sbc310_nec_fixup(struct pci_dev *pdev) { unsigned int val; @@ -210,6 +203,7 @@ static long __init mpc86xx_time_init(void) static __initdata struct of_device_id of_bus_ids[] = { { .compatible = "simple-bus", }, { .compatible = "gianfar", }, + { .compatible = "fsl,mpc8641-pcie", }, {}, }; @@ -220,7 +214,7 @@ static int __init declare_of_platform_devices(void) return 0; } -machine_device_initcall(gef_sbc310, declare_of_platform_devices); +machine_arch_initcall(gef_sbc310, declare_of_platform_devices); define_machine(gef_sbc310) { .name = "GE SBC310", diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c index 5090d608d9e..06c72636f29 100644 --- a/arch/powerpc/platforms/86xx/gef_sbc610.c +++ b/arch/powerpc/platforms/86xx/gef_sbc610.c @@ -24,7 +24,6 @@ #include <linux/seq_file.h> #include <linux/of_platform.h> -#include <asm/system.h> #include <asm/time.h> #include <asm/machdep.h> #include <asm/pci-bridge.h> @@ -37,9 +36,9 @@ #include <sysdev/fsl_pci.h> #include <sysdev/fsl_soc.h> +#include <sysdev/ge/ge_pic.h> #include "mpc86xx.h" -#include "gef_pic.h" #undef DEBUG @@ -74,13 +73,6 @@ static void __init gef_sbc610_init_irq(void) static void __init gef_sbc610_setup_arch(void) { struct device_node *regs; -#ifdef CONFIG_PCI - struct device_node *np; - - for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") { - fsl_add_bridge(np, 1); - } -#endif printk(KERN_INFO "GE Intelligent Platforms SBC610 6U VPX SBC\n"); @@ -88,6 +80,8 @@ static void __init gef_sbc610_setup_arch(void) mpc86xx_smp_init(); #endif + fsl_pci_assign_primary(); + /* Remap basic board registers */ regs = of_find_compatible_node(NULL, NULL, "gef,fpga-regs"); if (regs) { @@ -142,7 +136,7 @@ static void gef_sbc610_show_cpuinfo(struct seq_file *m) seq_printf(m, "SVR\t\t: 0x%x\n", svid); } -static void __init gef_sbc610_nec_fixup(struct pci_dev *pdev) +static void gef_sbc610_nec_fixup(struct pci_dev *pdev) { unsigned int val; @@ -199,6 +193,7 @@ static long __init mpc86xx_time_init(void) static __initdata struct of_device_id of_bus_ids[] = { { .compatible = "simple-bus", }, { .compatible = "gianfar", }, + { .compatible = "fsl,mpc8641-pcie", }, {}, }; @@ -209,7 +204,7 @@ static int __init declare_of_platform_devices(void) return 0; } -machine_device_initcall(gef_sbc610, declare_of_platform_devices); +machine_arch_initcall(gef_sbc610, declare_of_platform_devices); define_machine(gef_sbc610) { .name = "GE SBC610", diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c index a896511690c..d479d68fbb2 100644 --- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c +++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c @@ -25,7 +25,6 @@ #include <linux/seq_file.h> #include <linux/of.h> -#include <asm/system.h> #include <asm/time.h> #include <asm/machdep.h> #include <asm/pci-bridge.h> @@ -39,12 +38,19 @@ #include <sysdev/fsl_pci.h> #include <sysdev/fsl_soc.h> #include <sysdev/simple_gpio.h> +#include <asm/fsl_guts.h> #include "mpc86xx.h" static struct device_node *pixis_node; static unsigned char *pixis_bdcfg0, *pixis_arch; +/* DIU Pixel Clock bits of the CLKDVDR Global Utilities register */ +#define CLKDVDR_PXCKEN 0x80000000 +#define CLKDVDR_PXCKINV 0x10000000 +#define CLKDVDR_PXCKDLY 0x06000000 +#define CLKDVDR_PXCLK_MASK 0x001F0000 + #ifdef CONFIG_SUSPEND static irqreturn_t mpc8610_sw9_irq(int irq, void *data) { @@ -85,6 +91,9 @@ static struct of_device_id __initdata mpc8610_ids[] = { { .compatible = "simple-bus", }, /* So that the DMA channel nodes can be probed individually: */ { .compatible = "fsl,eloplus-dma", }, + /* PCI controllers */ + { .compatible = "fsl,mpc8610-pci", }, + { .compatible = "fsl,mpc8641-pcie", }, {} }; @@ -101,7 +110,7 @@ static int __init mpc8610_declare_of_platform_devices(void) return 0; } -machine_device_initcall(mpc86xx_hpcd, mpc8610_declare_of_platform_devices); +machine_arch_initcall(mpc86xx_hpcd, mpc8610_declare_of_platform_devices); #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) @@ -145,10 +154,10 @@ machine_device_initcall(mpc86xx_hpcd, mpc8610_declare_of_platform_devices); (c2 << AD_COMP_2_SHIFT) | (c1 << AD_COMP_1_SHIFT) | \ (c0 << AD_COMP_0_SHIFT) | (size << AD_PIXEL_S_SHIFT)) -unsigned int mpc8610hpcd_get_pixel_format(unsigned int bits_per_pixel, - int monitor_port) +u32 mpc8610hpcd_get_pixel_format(enum fsl_diu_monitor_port port, + unsigned int bits_per_pixel) { - static const unsigned long pixelformat[][3] = { + static const u32 pixelformat[][3] = { { MAKE_AD(3, 0, 2, 1, 3, 8, 8, 8, 8), MAKE_AD(4, 2, 0, 1, 2, 8, 8, 8, 0), @@ -163,7 +172,8 @@ unsigned int mpc8610hpcd_get_pixel_format(unsigned int bits_per_pixel, unsigned int arch_monitor; /* The DVI port is mis-wired on revision 1 of this board. */ - arch_monitor = ((*pixis_arch == 0x01) && (monitor_port == 0))? 0 : 1; + arch_monitor = + ((*pixis_arch == 0x01) && (port == FSL_DIU_PORT_DVI)) ? 0 : 1; switch (bits_per_pixel) { case 32: @@ -178,10 +188,11 @@ unsigned int mpc8610hpcd_get_pixel_format(unsigned int bits_per_pixel, } } -void mpc8610hpcd_set_gamma_table(int monitor_port, char *gamma_table_base) +void mpc8610hpcd_set_gamma_table(enum fsl_diu_monitor_port port, + char *gamma_table_base) { int i; - if (monitor_port == 2) { /* dual link LVDS */ + if (port == FSL_DIU_PORT_DLVDS) { for (i = 0; i < 256*3; i++) gamma_table_base[i] = (gamma_table_base[i] << 2) | ((gamma_table_base[i] >> 6) & 0x03); @@ -192,101 +203,77 @@ void mpc8610hpcd_set_gamma_table(int monitor_port, char *gamma_table_base) #define PX_BRDCFG0_DLINK (1 << 4) #define PX_BRDCFG0_DIU_MASK (PX_BRDCFG0_DVISEL | PX_BRDCFG0_DLINK) -void mpc8610hpcd_set_monitor_port(int monitor_port) +void mpc8610hpcd_set_monitor_port(enum fsl_diu_monitor_port port) { - static const u8 bdcfg[] = { - PX_BRDCFG0_DVISEL | PX_BRDCFG0_DLINK, - PX_BRDCFG0_DLINK, - 0, - }; - - if (monitor_port < 3) + switch (port) { + case FSL_DIU_PORT_DVI: clrsetbits_8(pixis_bdcfg0, PX_BRDCFG0_DIU_MASK, - bdcfg[monitor_port]); + PX_BRDCFG0_DVISEL | PX_BRDCFG0_DLINK); + break; + case FSL_DIU_PORT_LVDS: + clrsetbits_8(pixis_bdcfg0, PX_BRDCFG0_DIU_MASK, + PX_BRDCFG0_DLINK); + break; + case FSL_DIU_PORT_DLVDS: + clrbits8(pixis_bdcfg0, PX_BRDCFG0_DIU_MASK); + break; + } } +/** + * mpc8610hpcd_set_pixel_clock: program the DIU's clock + * + * @pixclock: the wavelength, in picoseconds, of the clock + */ void mpc8610hpcd_set_pixel_clock(unsigned int pixclock) { - u32 __iomem *clkdvdr; - u32 temp; - /* variables for pixel clock calcs */ - ulong bestval, bestfreq, speed_ccb, minpixclock, maxpixclock; - ulong pixval; - long err; - int i; - - clkdvdr = ioremap(get_immrbase() + 0xe0800, sizeof(u32)); - if (!clkdvdr) { - printk(KERN_ERR "Err: can't map clock divider register!\n"); + struct device_node *guts_np = NULL; + struct ccsr_guts __iomem *guts; + unsigned long freq; + u64 temp; + u32 pxclk; + + /* Map the global utilities registers. */ + guts_np = of_find_compatible_node(NULL, NULL, "fsl,mpc8610-guts"); + if (!guts_np) { + pr_err("mpc8610hpcd: missing global utilities device node\n"); return; } - /* Pixel Clock configuration */ - speed_ccb = fsl_get_sys_freq(); - - /* Calculate the pixel clock with the smallest error */ - /* calculate the following in steps to avoid overflow */ - pr_debug("DIU pixclock in ps - %d\n", pixclock); - temp = 1000000000/pixclock; - temp *= 1000; - pixclock = temp; - pr_debug("DIU pixclock freq - %u\n", pixclock); - - temp = pixclock * 5 / 100; - pr_debug("deviation = %d\n", temp); - minpixclock = pixclock - temp; - maxpixclock = pixclock + temp; - pr_debug("DIU minpixclock - %lu\n", minpixclock); - pr_debug("DIU maxpixclock - %lu\n", maxpixclock); - pixval = speed_ccb/pixclock; - pr_debug("DIU pixval = %lu\n", pixval); - - err = 100000000; - bestval = pixval; - pr_debug("DIU bestval = %lu\n", bestval); - - bestfreq = 0; - for (i = -1; i <= 1; i++) { - temp = speed_ccb / ((pixval+i) + 1); - pr_debug("DIU test pixval i= %d, pixval=%lu, temp freq. = %u\n", - i, pixval, temp); - if ((temp < minpixclock) || (temp > maxpixclock)) - pr_debug("DIU exceeds monitor range (%lu to %lu)\n", - minpixclock, maxpixclock); - else if (abs(temp - pixclock) < err) { - pr_debug("Entered the else if block %d\n", i); - err = abs(temp - pixclock); - bestval = pixval+i; - bestfreq = temp; - } + guts = of_iomap(guts_np, 0); + of_node_put(guts_np); + if (!guts) { + pr_err("mpc8610hpcd: could not map global utilities device\n"); + return; } - pr_debug("DIU chose = %lx\n", bestval); - pr_debug("DIU error = %ld\n NomPixClk ", err); - pr_debug("DIU: Best Freq = %lx\n", bestfreq); - /* Modify PXCLK in GUTS CLKDVDR */ - pr_debug("DIU: Current value of CLKDVDR = 0x%08x\n", (*clkdvdr)); - temp = (*clkdvdr) & 0x2000FFFF; - *clkdvdr = temp; /* turn off clock */ - *clkdvdr = temp | 0x80000000 | (((bestval) & 0x1F) << 16); - pr_debug("DIU: Modified value of CLKDVDR = 0x%08x\n", (*clkdvdr)); - iounmap(clkdvdr); -} + /* Convert pixclock from a wavelength to a frequency */ + temp = 1000000000000ULL; + do_div(temp, pixclock); + freq = temp; -ssize_t mpc8610hpcd_show_monitor_port(int monitor_port, char *buf) -{ - return snprintf(buf, PAGE_SIZE, - "%c0 - DVI\n" - "%c1 - Single link LVDS\n" - "%c2 - Dual link LVDS\n", - monitor_port == 0 ? '*' : ' ', - monitor_port == 1 ? '*' : ' ', - monitor_port == 2 ? '*' : ' '); + /* + * 'pxclk' is the ratio of the platform clock to the pixel clock. + * On the MPC8610, the value programmed into CLKDVDR is the ratio + * minus one. The valid range of values is 2-31. + */ + pxclk = DIV_ROUND_CLOSEST(fsl_get_sys_freq(), freq) - 1; + pxclk = clamp_t(u32, pxclk, 2, 31); + + /* Disable the pixel clock, and set it to non-inverted and no delay */ + clrbits32(&guts->clkdvdr, + CLKDVDR_PXCKEN | CLKDVDR_PXCKDLY | CLKDVDR_PXCLK_MASK); + + /* Enable the clock and set the pxclk */ + setbits32(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16)); + + iounmap(guts); } -int mpc8610hpcd_set_sysfs_monitor_port(int val) +enum fsl_diu_monitor_port +mpc8610hpcd_valid_monitor_port(enum fsl_diu_monitor_port port) { - return val < 3 ? val : 0; + return port; } #endif @@ -294,32 +281,19 @@ int mpc8610hpcd_set_sysfs_monitor_port(int val) static void __init mpc86xx_hpcd_setup_arch(void) { struct resource r; - struct device_node *np; unsigned char *pixis; if (ppc_md.progress) ppc_md.progress("mpc86xx_hpcd_setup_arch()", 0); -#ifdef CONFIG_PCI - for_each_node_by_type(np, "pci") { - if (of_device_is_compatible(np, "fsl,mpc8610-pci") - || of_device_is_compatible(np, "fsl,mpc8641-pcie")) { - struct resource rsrc; - of_address_to_resource(np, 0, &rsrc); - if ((rsrc.start & 0xfffff) == 0xa000) - fsl_add_bridge(np, 1); - else - fsl_add_bridge(np, 0); - } - } -#endif + fsl_pci_assign_primary(); + #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) diu_ops.get_pixel_format = mpc8610hpcd_get_pixel_format; diu_ops.set_gamma_table = mpc8610hpcd_set_gamma_table; diu_ops.set_monitor_port = mpc8610hpcd_set_monitor_port; diu_ops.set_pixel_clock = mpc8610hpcd_set_pixel_clock; - diu_ops.show_monitor_port = mpc8610hpcd_show_monitor_port; - diu_ops.set_sysfs_monitor_port = mpc8610hpcd_set_sysfs_monitor_port; + diu_ops.valid_monitor_port = mpc8610hpcd_valid_monitor_port; #endif pixis_node = of_find_compatible_node(NULL, NULL, "fsl,fpga-pixis"); @@ -379,5 +353,7 @@ define_machine(mpc86xx_hpcd) { .time_init = mpc86xx_time_init, .calibrate_decr = generic_calibrate_decr, .progress = udbg_progress, +#ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, +#endif }; diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index b11c3535f35..e8bf3fae560 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c @@ -19,9 +19,7 @@ #include <linux/delay.h> #include <linux/seq_file.h> #include <linux/of_platform.h> -#include <linux/memblock.h> -#include <asm/system.h> #include <asm/time.h> #include <asm/machdep.h> #include <asm/pci-bridge.h> @@ -52,15 +50,8 @@ extern int uli_exclude_device(struct pci_controller *hose, static int mpc86xx_exclude_device(struct pci_controller *hose, u_char bus, u_char devfn) { - struct device_node* node; - struct resource rsrc; - - node = hose->dn; - of_address_to_resource(node, 0, &rsrc); - - if ((rsrc.start & 0xfffff) == 0x8000) { + if (hose->dn == fsl_pci_primary) return uli_exclude_device(hose, bus, devfn); - } return PCIBIOS_SUCCESSFUL; } @@ -70,30 +61,11 @@ static int mpc86xx_exclude_device(struct pci_controller *hose, static void __init mpc86xx_hpcn_setup_arch(void) { -#ifdef CONFIG_PCI - struct device_node *np; - struct pci_controller *hose; -#endif - dma_addr_t max = 0xffffffff; - if (ppc_md.progress) ppc_md.progress("mpc86xx_hpcn_setup_arch()", 0); #ifdef CONFIG_PCI - for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") { - struct resource rsrc; - of_address_to_resource(np, 0, &rsrc); - if ((rsrc.start & 0xfffff) == 0x8000) - fsl_add_bridge(np, 1); - else - fsl_add_bridge(np, 0); - hose = pci_find_hose_for_OF_device(np); - max = min(max, hose->dma_window_base_cur + - hose->dma_window_size); - } - ppc_md.pci_exclude_device = mpc86xx_exclude_device; - #endif printk("MPC86xx HPCN board from Freescale Semiconductor\n"); @@ -102,13 +74,9 @@ mpc86xx_hpcn_setup_arch(void) mpc86xx_smp_init(); #endif -#ifdef CONFIG_SWIOTLB - if (memblock_end_of_DRAM() > max) { - ppc_swiotlb_enable = 1; - set_pci_dma_ops(&swiotlb_dma_ops); - ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; - } -#endif + fsl_pci_assign_primary(); + + swiotlb_detect_4g(); } @@ -161,8 +129,9 @@ mpc86xx_time_init(void) static __initdata struct of_device_id of_bus_ids[] = { { .compatible = "simple-bus", }, - { .compatible = "fsl,rapidio-delta", }, + { .compatible = "fsl,srio", }, { .compatible = "gianfar", }, + { .compatible = "fsl,mpc8641-pcie", }, {}, }; @@ -172,7 +141,7 @@ static int __init declare_of_platform_devices(void) return 0; } -machine_device_initcall(mpc86xx_hpcn, declare_of_platform_devices); +machine_arch_initcall(mpc86xx_hpcn, declare_of_platform_devices); machine_arch_initcall(mpc86xx_hpcn, swiotlb_setup_bus_notifier); define_machine(mpc86xx_hpcn) { diff --git a/arch/powerpc/platforms/86xx/pic.c b/arch/powerpc/platforms/86xx/pic.c index 8ef8960abda..d5b98c0f958 100644 --- a/arch/powerpc/platforms/86xx/pic.c +++ b/arch/powerpc/platforms/86xx/pic.c @@ -10,9 +10,9 @@ #include <linux/stddef.h> #include <linux/kernel.h> #include <linux/interrupt.h> +#include <linux/of_irq.h> #include <linux/of_platform.h> -#include <asm/system.h> #include <asm/mpic.h> #include <asm/i8259.h> @@ -31,26 +31,15 @@ static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc) void __init mpc86xx_init_irq(void) { - struct mpic *mpic; - struct device_node *np; - struct resource res; #ifdef CONFIG_PPC_I8259 + struct device_node *np; struct device_node *cascade_node = NULL; int cascade_irq; #endif - /* Determine PIC address. */ - np = of_find_node_by_type(NULL, "open-pic"); - if (np == NULL) - return; - of_address_to_resource(np, 0, &res); - - mpic = mpic_alloc(np, res.start, - MPIC_PRIMARY | MPIC_WANTS_RESET | - MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | + struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU, 0, 256, " MPIC "); - of_node_put(np); BUG_ON(mpic == NULL); mpic_init(mpic); diff --git a/arch/powerpc/platforms/86xx/sbc8641d.c b/arch/powerpc/platforms/86xx/sbc8641d.c index 51c8f331b67..b47a8fd0f3d 100644 --- a/arch/powerpc/platforms/86xx/sbc8641d.c +++ b/arch/powerpc/platforms/86xx/sbc8641d.c @@ -21,7 +21,6 @@ #include <linux/seq_file.h> #include <linux/of_platform.h> -#include <asm/system.h> #include <asm/time.h> #include <asm/machdep.h> #include <asm/pci-bridge.h> @@ -39,23 +38,16 @@ static void __init sbc8641_setup_arch(void) { -#ifdef CONFIG_PCI - struct device_node *np; -#endif - if (ppc_md.progress) ppc_md.progress("sbc8641_setup_arch()", 0); -#ifdef CONFIG_PCI - for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") - fsl_add_bridge(np, 0); -#endif - printk("SBC8641 board from Wind River\n"); #ifdef CONFIG_SMP mpc86xx_smp_init(); #endif + + fsl_pci_assign_primary(); } @@ -103,6 +95,7 @@ mpc86xx_time_init(void) static __initdata struct of_device_id of_bus_ids[] = { { .compatible = "simple-bus", }, { .compatible = "gianfar", }, + { .compatible = "fsl,mpc8641-pcie", }, {}, }; @@ -112,7 +105,7 @@ static int __init declare_of_platform_devices(void) return 0; } -machine_device_initcall(sbc8641, declare_of_platform_devices); +machine_arch_initcall(sbc8641, declare_of_platform_devices); define_machine(sbc8641) { .name = "SBC8641D", |
