From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from nommos.sslcatacombnetworking.com (nommos.sslcatacombnetworking.com [67.18.224.114]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTP id 0DF7ADDEA2 for ; Thu, 8 Mar 2007 15:36:53 +1100 (EST) In-Reply-To: <1173302058.23776.183.camel@ld0161-tx32> References: <1173302058.23776.183.camel@ld0161-tx32> Mime-Version: 1.0 (Apple Message framework v752.2) Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed Message-Id: From: Kumar Gala Subject: Re: [RFC 1/3] MPC8544DS Basic Port Date: Wed, 7 Mar 2007 22:35:54 -0600 To: Jon Loeliger Cc: "linuxppc-dev@ozlabs.org" List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , On Mar 7, 2007, at 3:14 PM, Jon Loeliger wrote: > arch/powerpc/platforms/85xx/Kconfig | 18 + > arch/powerpc/platforms/85xx/Makefile | 1 > arch/powerpc/platforms/85xx/mpc8544_ds.c | 424 +++++++++++++++++++ > +++++++++++ > 3 files changed, 442 insertions(+), 1 deletions(-) > > > > diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/ > platforms/85xx/Kconfig > index eb661cc..5221664 100644 > --- a/arch/powerpc/platforms/85xx/Kconfig > +++ b/arch/powerpc/platforms/85xx/Kconfig > @@ -20,6 +20,8 @@ config MPC8560_ADS > config MPC85xx_CDS > bool "Freescale MPC85xx CDS" > select DEFAULT_UIMAGE > + select FSL_PCIE > + select PPC_I8259 > help > This option enables support for the MPC85xx CDS board CDS changes in ds patch :) > > @@ -30,6 +32,14 @@ config MPC85xx_MDS > help > This option enables support for the MPC85xx MDS board > > +config MPC8544_DS > + bool "Freescale MPC8544/MPC8533 DS" > + select PPC_I8259 > + select DEFAULT_UIMAGE > + select FSL_PCIE > + help > + This option enables support for the MPC8544/MPC8533 DS board > + > endchoice > > config MPC8540 > @@ -43,11 +53,17 @@ config MPC8560 > select PPC_INDIRECT_PCI > default y if MPC8560_ADS > > +config MPC8544 > + bool > + select SERIAL_8250_SHARE_IRQ hmm, seems like we need this for all 85xx. > + default y if MPC8544_DS > + > config MPC85xx > bool > select PPC_UDBG_16550 > select PPC_INDIRECT_PCI > - default y if MPC8540_ADS || MPC85xx_CDS || MPC8560_ADS || > MPC85xx_MDS > + default y if MPC8540_ADS || MPC85xx_CDS || MPC8560_ADS \ > + || MPC85xx_MDS || MPC8544_DS > > config PPC_INDIRECT_PCI_BE > bool > diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/ > platforms/85xx/Makefile > index 4e63917..4e02cbb 100644 > --- a/arch/powerpc/platforms/85xx/Makefile > +++ b/arch/powerpc/platforms/85xx/Makefile > @@ -5,4 +5,5 @@ obj-$(CONFIG_PPC_85xx) += misc.o pci.o > obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o > obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o > obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o > +obj-$(CONFIG_MPC8544_DS) += mpc8544_ds.o > obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o > diff --git a/arch/powerpc/platforms/85xx/mpc8544_ds.c b/arch/ > powerpc/platforms/85xx/mpc8544_ds.c > new file mode 100644 > index 0000000..035a762 > --- /dev/null > +++ b/arch/powerpc/platforms/85xx/mpc8544_ds.c > @@ -0,0 +1,424 @@ > +/* > + * MPC8544 DS Board Setup > + * > + * Author Xianghua Xiao (x.xiao@freescale.com) > + * Copyright 2007 Freescale Semiconductor Inc. > + * > + * This program is free software; you can redistribute it and/or > modify it > + * under the terms of the GNU General Public License as > published by the > + * Free Software Foundation; either version 2 of the License, or > (at your > + * option) any later version. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include "mpc85xx.h" > + > +#undef DEBUG > + > +#ifdef DEBUG > +#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, > __FUNCTION__, ## args) > +#else > +#define DBG(fmt, args...) > +#endif > + > +#ifndef CONFIG_PCI > +unsigned long isa_io_base = 0; > +unsigned long isa_mem_base = 0; > +unsigned long pci_dram_offset = 0; > +#endif > + > +#ifdef CONFIG_PCI > +int mpc85xx_exclude_device(u_char bus, u_char devfn) > +{ > + if (bus == 2 && PCI_SLOT(devfn) == 0x1d) > + return PCIBIOS_DEVICE_NOT_FOUND; > + else > + return PCIBIOS_SUCCESSFUL; > +} > + > +static void mpc8544_8259_cascade(unsigned int irq, struct irq_desc > *desc) > +{ > + unsigned int cascade_irq = i8259_irq(); > + if (cascade_irq != NO_IRQ) > + generic_handle_irq(cascade_irq); > + desc->chip->eoi(irq); > +} > +#endif /* CONFIG_PCI */ > + > +void __init mpc8544_ds_pic_init(void) > +{ > + struct mpic *mpic; > + struct resource r; > + struct device_node *np = NULL; > +#ifdef CONFIG_PPC_I8259 > + struct device_node *cascade_node = NULL; > + int cascade_irq; > +#endif > + > + np = of_find_node_by_type(np, "open-pic"); > + > + if (np == NULL) { > + printk(KERN_ERR "Could not find open-pic node\n"); > + return; > + } > + > + if (of_address_to_resource(np, 0, &r)) { > + printk(KERN_ERR "Failed to map mpic register space\n"); > + of_node_put(np); > + return; > + } > + > + /* Alloc mpic structure and per isu has 16 INT entries. */ > + mpic = mpic_alloc(np, r.start, > + MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, > + 16, NR_IRQS - 10, " OPENPIC "); Should we must make this 64 instead of NR_IRQS - 10. > + BUG_ON(mpic == NULL); > + > + /* Return the mpic node */ > + > + mpic_assign_isu(mpic, 0, r.start + 0x10000); > + > + /* 48 Internal Interrupts */ > + mpic_assign_isu(mpic, 1, r.start + 0x10200); > + mpic_assign_isu(mpic, 2, r.start + 0x10400); > + mpic_assign_isu(mpic, 3, r.start + 0x10600); > + > + /* 16 External interrupts > + * Moving them from [0 - 15] to [64 - 79] > + */ > + mpic_assign_isu(mpic, 4, r.start + 0x10000); > + FYI, I'm going to rework the irq numbering so we stop doing this reordering. > + mpic_init(mpic); > + > +#ifdef CONFIG_PPC_I8259 > + /* Initialize the i8259 controller */ > + for_each_node_by_type(np, "interrupt-controller") > + if (device_is_compatible(np, "chrp,iic")) { > + cascade_node = np; > + break; > + } > + > + if (cascade_node == NULL) { > + printk(KERN_DEBUG "Could not find i8259 PIC\n"); > + return; > + } > + > + cascade_irq = irq_of_parse_and_map(cascade_node, 0); > + if (cascade_irq == NO_IRQ) { > + printk(KERN_ERR "Failed to map cascade interrupt\n"); > + return; > + } > + > + DBG("mpc8544ds: cascade mapped to irq %d\n", cascade_irq); > + > + i8259_init(cascade_node, 0); > + of_node_put(cascade_node); > + > + set_irq_chained_handler(cascade_irq, mpc8544_8259_cascade); > +#endif /* CONFIG_PPC_I8259 */ > +} > + > +#ifdef CONFIG_PCI > +enum pirq { PIRQA = 8, PIRQB, PIRQC, PIRQD, PIRQE, PIRQF, PIRQG, > PIRQH }; > +const unsigned char uli1575_irq_route_table[16] = { > +/* Value in table -- IRQ number */ > + 0, /* 0: Reserved */ > + 0x8, /* 1: 0b1000 */ > + 0, /* 2: Reserved */ > + 0x2, /* 3: 0b0010 */ > + 0x4, /* 4: 0b0100 */ > + 0x5, /* 5: 0b0101 */ > + 0x7, /* 6: 0b0111 */ > + 0x6, /* 7: 0b0110 */ > + 0, /* 8: Reserved */ > + 0x1, /* 9: 0b0001 */ > + 0x3, /* 10: 0b0011 */ > + 0x9, /* 11: 0b1001 */ > + 0xb, /* 12: 0b1011 */ > + 0, /* 13: Reserved */ > + 0xd, /* 14, 0b1101 */ > + 0xf, /* 15, 0b1111 */ > +}; > + The comments seem a bit silly for numbers in binary. > +static int __devinit > +get_pci_irq_from_of(struct pci_controller *hose, int slot, int pin) > +{ > + struct of_irq oirq; > + u32 laddr[3]; > + struct device_node *hosenode = hose ? hose->arch_data : NULL; > + > + if (!hosenode) > + return -EINVAL; > + > + laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(slot, 0) << 8); > + laddr[1] = laddr[2] = 0; > + of_irq_map_raw(hosenode, &pin, 1, laddr, &oirq); > + DBG("mpc8544_ds: pci irq addr %x, slot %d, pin %d, irq %d\n", > + laddr[0], slot, pin, oirq.specifier[0]); > + return oirq.specifier[0]; > +} > + > +/*8259*/ > +static void __devinit quirk_uli1575(struct pci_dev *dev) > +{ > + unsigned short temp; > + struct pci_controller *hose = pci_bus_to_host(dev->bus); > + unsigned char irq2pin[16]; > + unsigned long pirq_map_word = 0; > + u32 irq; > + int i; > + > + /* > + * ULI1575 interrupts route setup > + */ > + memset(irq2pin, 0, 16); /* Initialize default value 0 */ > + > + /* > + * PIRQE -> PIRQF mapping set manually > + * > + * IRQ pin IRQ# > + * PIRQE ---- 9 > + * PIRQF ---- 10 > + * PIRQG ---- 11 > + * PIRQH ---- 12 > + */ > + for (i = 0; i < 4; i++) > + irq2pin[i + 9] = PIRQE + i; > + > + /* Set IRQ-PIRQ Mapping to ULI1575 */ > + for (i = 0; i < 16; i++) > + if (irq2pin[i]) > + pirq_map_word |= (uli1575_irq_route_table[i] & 0xf) > + << ((irq2pin[i] - PIRQA) * 4); > + > + /* ULI1575 IRQ mapping conf register default value is 0xb9317542 */ > + DBG("Setup ULI1575 IRQ mapping configuration register value = 0x%x > \n", > + pirq_map_word); > + pci_write_config_dword(dev, 0x48, pirq_map_word); > + > +#define ULI1575_SET_DEV_IRQ(slot, pin, > reg) \ > + do { \ > + int irq; \ > + irq = get_pci_irq_from_of(hose, slot, pin); \ > + if (irq > 0 && irq < 16) { \ > + pci_write_config_byte(dev, reg, irq2pin[irq]); \ > + } \ > + else \ > + printk(KERN_WARNING "ULI1575 device" \ > + "(slot %d, pin %d) irq %d is invalid.\n", \ > + slot, pin, irq); \ > + } while(0) > + > + /* USB 1.1 OHCI controller 1, slot 28, pin 1 */ > + ULI1575_SET_DEV_IRQ(28, 1, 0x86); > + > + /* USB 1.1 OHCI controller 2, slot 28, pin 2 */ > + ULI1575_SET_DEV_IRQ(28, 2, 0x87); > + > + /* USB 1.1 OHCI controller 3, slot 28, pin 3 */ > + ULI1575_SET_DEV_IRQ(28, 3, 0x88); > + > + /* USB 2.0 controller, slot 28, pin 4 */ > + irq = get_pci_irq_from_of(hose, 28, 4); > + if (irq >= 0 && irq <= 15) > + pci_write_config_dword(dev, 0x74, uli1575_irq_route_table[irq]); > + > + /* Audio controller, slot 29, pin 1 */ > + ULI1575_SET_DEV_IRQ(29, 1, 0x8a); > + > + /* Modem controller, slot 29, pin 2 */ > + ULI1575_SET_DEV_IRQ(29, 2, 0x8b); > + > + /* HD audio controller, slot 29, pin 3 */ > + ULI1575_SET_DEV_IRQ(29, 3, 0x8c); > + > + /* SMB interrupt: slot 30, pin 1 */ > + ULI1575_SET_DEV_IRQ(30, 1, 0x8e); > + > + /* PMU ACPI SCI interrupt: slot 30, pin 2 */ > + ULI1575_SET_DEV_IRQ(30, 2, 0x8f); > + > + /* Serial ATA interrupt: slot 31, pin 1 */ > + ULI1575_SET_DEV_IRQ(31, 1, 0x8d); > + > + /* Primary PATA IDE IRQ: 14 > + * Secondary PATA IDE IRQ: 15 > + */ > + pci_write_config_byte(dev, 0x44, 0x30 | uli1575_irq_route_table > [14]); > + pci_write_config_byte(dev, 0x75, uli1575_irq_route_table[15]); > + > + /* Set IRQ14 and IRQ15 to legacy IRQs */ > + pci_read_config_word(dev, 0x46, &temp); > + temp |= 0xc000; > + pci_write_config_word(dev, 0x46, temp); > + > + /* Set i8259 interrupt trigger > + * IRQ 3: Level > + * IRQ 4: Level > + * IRQ 5: Level > + * IRQ 6: Level > + * IRQ 7: Level > + * IRQ 9: Level > + * IRQ 10: Level > + * IRQ 11: Level > + * IRQ 12: Level > + * IRQ 14: Edge > + * IRQ 15: Edge > + */ > + outb(0xfa, 0x4d0); > + outb(0x1e, 0x4d1); > + > +#undef ULI1575_SET_DEV_IRQ > +} > + > +/* SATA */ > +static void __devinit quirk_uli5288(struct pci_dev *dev) > +{ > + unsigned char c; > + > + pci_read_config_byte(dev, 0x83, &c); > + c |= 0x80; /* read/write lock */ > + pci_write_config_byte(dev, 0x83, c); > + > + pci_write_config_byte(dev, 0x09, 0x01); /* Base class code: > storage */ > + pci_write_config_byte(dev, 0x0a, 0x06); /* IDE disk */ > + > + pci_read_config_byte(dev, 0x83, &c); > + c &= 0x7f; > + pci_write_config_byte(dev, 0x83, c); > + > + pci_read_config_byte(dev, 0x84, &c); > + c |= 0x01; /* emulated PATA mode enabled */ > + pci_write_config_byte(dev, 0x84, c); > +} > + > +/* PATA */ > +static void __devinit quirk_uli5229(struct pci_dev *dev) > +{ > + unsigned short temp; > + pci_write_config_word(dev, 0x04, 0x0405); /* MEM IO MSI */ > + pci_write_config_byte(dev, 0x09, 0x8a); > + dev->class &= ~0x5; > + pci_read_config_word(dev, 0x4a, &temp); > + temp |= 0x1000; /* Enable Native IRQ 14/15 */ > + pci_write_config_word(dev, 0x4a, temp); > +} > + > +/*Bridge*/ > +static void __devinit early_uli5249(struct pci_dev *dev) > +{ > + unsigned char temp; > + pci_write_config_word(dev, 0x04, 0x0007); /* mem access */ > + pci_read_config_byte(dev, 0x7c, &temp); > + pci_write_config_byte(dev, 0x7c, 0x80); /* R/W lock control */ > + pci_write_config_byte(dev, 0x09, 0x01); /* set as pci-pci bridge */ > + pci_write_config_byte(dev, 0x7c, temp); /* restore pci bus debug > control */ > + dev->class |= 0x1; > +} > + > +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_uli1575); > +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); > +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); > +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249); > +#endif /* CONFIG_PCI */ > + > +/* > + * Setup the architecture > + */ > +static void __init mpc8544_ds_setup_arch(void) > +{ > +#ifdef CONFIG_PCI > + struct device_node *np; > +#endif > + > + if (ppc_md.progress) > + ppc_md.progress("mpc8544_ds_setup_arch()", 0); > + > +#ifdef CONFIG_PCI > + for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) > + add_bridge(np); > + ppc_md.pci_exclude_device = mpc85xx_exclude_device; > +#endif > + > + printk("MPC8544 DS board from Freescale Semiconductor\n"); > +} > + > +void __init mpc8544_ds_pcibios_fixup_bus(struct pci_bus *bus) > +{ > + if (bus->self && bus->self->vendor == 0x10b9 > + && bus->self->device == 0x5249) { > + bus->parent->resource[0]->end = bus->parent->resource[0]->start > + + 0xffff; > + if (bus->resource[1] && bus->parent->resource[1]) > + bus->parent->resource[1]->end += > + bus->resource[1]->end + 1 + 0x100000 > + - bus->resource[1]->start; > + } > +} > + > +void mpc8544_ds_show_cpuinfo(struct seq_file *m) > +{ > + struct device_node *root; > + uint memsize = total_memory; > + const char *model = ""; > + uint svid = mfspr(SPRN_SVR); > + > + seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); > + > + root = of_find_node_by_path("/"); > + if (root) > + model = get_property(root, "model", NULL); > + seq_printf(m, "Machine\t\t: %s\n", model); > + of_node_put(root); > + > + seq_printf(m, "SVR\t\t: 0x%x\n", svid); > + seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); > +} Is this providing any info we really need? Been removing other cpuinfo since they aren't too terrible useful. > + > +/* > + * Called very early, device-tree isn't unflattened > + */ > +static int __init mpc8544_ds_probe(void) > +{ > + char *model = of_get_flat_dt_prop(of_get_flat_dt_root(), > + "model", NULL); > + if (model == NULL) > + return 0; > + if (strcmp(model, "MPC8544DS")) > + return 0; > + > + DBG("MPC8544DS found\n"); > + should use of_flat_dt_is_compatible() see other 85xx boards. > + return 1; > +} > + > +define_machine(mpc8544_ds) { > + .name = "MPC8544 DS", > + .probe = mpc8544_ds_probe, > + .setup_arch = mpc8544_ds_setup_arch, > + .init_IRQ = mpc8544_ds_pic_init, > + .show_cpuinfo = mpc8544_ds_show_cpuinfo, > + .pcibios_fixup_bus = mpc8544_ds_pcibios_fixup_bus, > + .get_irq = mpic_get_irq, > + .restart = mpc85xx_restart, > + .calibrate_decr = generic_calibrate_decr, > + .progress = udbg_progress, > +}; > > > _______________________________________________ > Linuxppc-dev mailing list > Linuxppc-dev@ozlabs.org > https://ozlabs.org/mailman/listinfo/linuxppc-dev