Commit c5d56332fd6c2f0c7cf9d1f65416076f2711ea28

Authored by Zang Roy-r61911
Committed by Paul Mackerras
1 parent 1729dc7833

[POWERPC] Add general support for mpc7448hpc2 (Taiga) platform

Add support for Freescale mpc7448 (Taiga) board support

Signed-off-by: Roy Zang  <tie-fei.zang@freescale.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>

Showing 7 changed files with 397 additions and 3 deletions Side-by-side Diff

arch/powerpc/Kconfig
... ... @@ -336,7 +336,7 @@
336 336  
337 337 config EMBEDDED6xx
338 338 bool "Embedded 6xx/7xx/7xxx-based board"
339   - depends on PPC32 && BROKEN
  339 + depends on PPC32 && (BROKEN||BROKEN_ON_SMP)
340 340  
341 341 config APUS
342 342 bool "Amiga-APUS"
... ... @@ -436,7 +436,8 @@
436 436 default n
437 437  
438 438 config MPIC
439   - depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP
  439 + depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP \
  440 + || MPC7448HPC2
440 441 bool
441 442 default y
442 443  
... ... @@ -821,7 +822,8 @@
821 822 bool
822 823  
823 824 config PCI
824   - bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES)
  825 + bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES) \
  826 + || MPC7448HPC2
825 827 default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx && !PPC_85xx && !PPC_86xx
826 828 default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS
827 829 default PCI_QSPAN if !4xx && !CPM2 && 8xx
arch/powerpc/kernel/legacy_serial.c
... ... @@ -302,6 +302,17 @@
302 302 of_node_put(isa);
303 303 }
304 304  
  305 + /* First fill our array with tsi-bridge ports */
  306 + for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) {
  307 + struct device_node *tsi = of_get_parent(np);
  308 + if (tsi && !strcmp(tsi->type, "tsi-bridge")) {
  309 + index = add_legacy_soc_port(np, np);
  310 + if (index >= 0 && np == stdout)
  311 + legacy_serial_console = index;
  312 + }
  313 + of_node_put(tsi);
  314 + }
  315 +
305 316 #ifdef CONFIG_PCI
306 317 /* Next, try to locate PCI ports */
307 318 for (np = NULL; (np = of_find_all_nodes(np));) {
arch/powerpc/platforms/Makefile
... ... @@ -14,4 +14,5 @@
14 14 obj-$(CONFIG_PPC_ISERIES) += iseries/
15 15 obj-$(CONFIG_PPC_MAPLE) += maple/
16 16 obj-$(CONFIG_PPC_CELL) += cell/
  17 +obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/
arch/powerpc/platforms/embedded6xx/Kconfig
... ... @@ -74,6 +74,16 @@
74 74 Select SANDPOINT if configuring for a Motorola Sandpoint X3
75 75 (any flavor).
76 76  
  77 +config MPC7448HPC2
  78 + bool "Freescale MPC7448HPC2(Taiga)"
  79 + select TSI108_BRIDGE
  80 + select DEFAULT_UIMAGE
  81 + select PPC_UDBG_16550
  82 + select MPIC
  83 + help
  84 + Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga)
  85 + platform
  86 +
77 87 config RADSTONE_PPC7D
78 88 bool "Radstone Technology PPC7D board"
79 89 select PPC_I8259
... ... @@ -219,6 +229,11 @@
219 229 bool
220 230 depends on (GT64260 || MV64360)
221 231 select PPC_INDIRECT_PCI
  232 + default y
  233 +
  234 +config TSI108_BRIDGE
  235 + bool
  236 + depends on MPC7448HPC2
222 237 default y
223 238  
224 239 menu "Set bridge options"
arch/powerpc/platforms/embedded6xx/Makefile
  1 +#
  2 +# Makefile for the 6xx/7xx/7xxxx linux kernel.
  3 +#
  4 +obj-$(CONFIG_MPC7448HPC2) += mpc7448_hpc2.o
arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
  1 +/*
  2 + * mpc7448_hpc2.c
  3 + *
  4 + * Board setup routines for the Freescale Taiga platform
  5 + *
  6 + * Author: Jacob Pan
  7 + * jacob.pan@freescale.com
  8 + * Author: Xianghua Xiao
  9 + * x.xiao@freescale.com
  10 + * Maintainer: Roy Zang <tie-fei.zang@freescale.com>
  11 + * Add Flat Device Tree support fot mpc7448hpc2 board
  12 + *
  13 + * Copyright 2004-2006 Freescale Semiconductor, Inc.
  14 + *
  15 + * This file is licensed under
  16 + * the terms of the GNU General Public License version 2. This program
  17 + * is licensed "as is" without any warranty of any kind, whether express
  18 + * or implied.
  19 + */
  20 +
  21 +#include <linux/config.h>
  22 +#include <linux/stddef.h>
  23 +#include <linux/kernel.h>
  24 +#include <linux/pci.h>
  25 +#include <linux/kdev_t.h>
  26 +#include <linux/console.h>
  27 +#include <linux/delay.h>
  28 +#include <linux/irq.h>
  29 +#include <linux/ide.h>
  30 +#include <linux/seq_file.h>
  31 +#include <linux/root_dev.h>
  32 +#include <linux/serial.h>
  33 +#include <linux/tty.h>
  34 +#include <linux/serial_core.h>
  35 +
  36 +#include <asm/system.h>
  37 +#include <asm/time.h>
  38 +#include <asm/machdep.h>
  39 +#include <asm/prom.h>
  40 +#include <asm/udbg.h>
  41 +#include <asm/tsi108.h>
  42 +#include <asm/pci-bridge.h>
  43 +#include <asm/reg.h>
  44 +#include <mm/mmu_decl.h>
  45 +#include "mpc7448_hpc2.h"
  46 +#include <asm/tsi108_irq.h>
  47 +#include <asm/mpic.h>
  48 +
  49 +#undef DEBUG
  50 +#ifdef DEBUG
  51 +#define DBG(fmt...) do { printk(fmt); } while(0)
  52 +#else
  53 +#define DBG(fmt...) do { } while(0)
  54 +#endif
  55 +
  56 +#ifndef CONFIG_PCI
  57 +isa_io_base = MPC7448_HPC2_ISA_IO_BASE;
  58 +isa_mem_base = MPC7448_HPC2_ISA_MEM_BASE;
  59 +pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET;
  60 +#endif
  61 +
  62 +extern int tsi108_setup_pci(struct device_node *dev);
  63 +extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
  64 +extern void tsi108_pci_int_init(void);
  65 +extern int tsi108_irq_cascade(struct pt_regs *regs, void *unused);
  66 +
  67 +/*
  68 + * Define all of the IRQ senses and polarities. Taken from the
  69 + * mpc7448hpc manual.
  70 + * Note: Likely, this table and the following function should be
  71 + * obtained and derived from the OF Device Tree.
  72 + */
  73 +
  74 +static u_char mpc7448_hpc2_pic_initsenses[] __initdata = {
  75 + /* External on-board sources */
  76 + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[0] XINT0 from FPGA */
  77 + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[1] XINT1 from FPGA */
  78 + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[2] PHY_INT from both GIGE */
  79 + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[3] RESERVED */
  80 + /* Internal Tsi108/109 interrupt sources */
  81 + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */
  82 + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */
  83 + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */
  84 + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */
  85 + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA0 */
  86 + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA1 */
  87 + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA2 */
  88 + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA3 */
  89 + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* UART0 */
  90 + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* UART1 */
  91 + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* I2C */
  92 + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* GPIO */
  93 + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* GIGE0 */
  94 + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* GIGE1 */
  95 + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */
  96 + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* HLP */
  97 + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* SDC */
  98 + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Processor IF */
  99 + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */
  100 + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* PCI/X block */
  101 +};
  102 +
  103 +int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn)
  104 +{
  105 + if (bus == 0 && PCI_SLOT(devfn) == 0)
  106 + return PCIBIOS_DEVICE_NOT_FOUND;
  107 + else
  108 + return PCIBIOS_SUCCESSFUL;
  109 +}
  110 +
  111 +/*
  112 + * find pci slot by devfn in interrupt map of OF tree
  113 + */
  114 +u8 find_slot_by_devfn(unsigned int *interrupt_map, unsigned int devfn)
  115 +{
  116 + int i;
  117 + unsigned int tmp;
  118 + for (i = 0; i < 4; i++){
  119 + tmp = interrupt_map[i*4*7];
  120 + if ((tmp >> 11) == (devfn >> 3))
  121 + return i;
  122 + }
  123 + return i;
  124 +}
  125 +
  126 +/*
  127 + * Scans the interrupt map for pci device
  128 + */
  129 +void mpc7448_hpc2_fixup_irq(struct pci_dev *dev)
  130 +{
  131 + struct pci_controller *hose;
  132 + struct device_node *node;
  133 + unsigned int *interrupt;
  134 + int busnr;
  135 + int len;
  136 + u8 slot;
  137 + u8 pin;
  138 +
  139 + /* Lookup the hose */
  140 + busnr = dev->bus->number;
  141 + hose = pci_bus_to_hose(busnr);
  142 + if (!hose)
  143 + printk(KERN_ERR "No pci hose found\n");
  144 +
  145 + /* Check it has an OF node associated */
  146 + node = (struct device_node *) hose->arch_data;
  147 + if (!node)
  148 + printk(KERN_ERR "No pci node found\n");
  149 +
  150 + interrupt = (unsigned int *) get_property(node, "interrupt-map", &len);
  151 + slot = find_slot_by_devfn(interrupt, dev->devfn);
  152 + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
  153 + if (pin == 0 || pin > 4)
  154 + pin = 1;
  155 + pin--;
  156 + dev->irq = interrupt[slot*4*7 + pin*7 + 5];
  157 + DBG("TSI_PCI: dev->irq = 0x%x\n", dev->irq);
  158 +}
  159 +/* temporary pci irq map fixup*/
  160 +
  161 +void __init mpc7448_hpc2_pcibios_fixup(void)
  162 +{
  163 + struct pci_dev *dev = NULL;
  164 + for_each_pci_dev(dev) {
  165 + mpc7448_hpc2_fixup_irq(dev);
  166 + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
  167 + }
  168 +}
  169 +
  170 +static void __init mpc7448_hpc2_setup_arch(void)
  171 +{
  172 + struct device_node *cpu;
  173 + struct device_node *np;
  174 + if (ppc_md.progress)
  175 + ppc_md.progress("mpc7448_hpc2_setup_arch():set_bridge", 0);
  176 +
  177 + cpu = of_find_node_by_type(NULL, "cpu");
  178 + if (cpu != 0) {
  179 + unsigned int *fp;
  180 +
  181 + fp = (int *)get_property(cpu, "clock-frequency", NULL);
  182 + if (fp != 0)
  183 + loops_per_jiffy = *fp / HZ;
  184 + else
  185 + loops_per_jiffy = 50000000 / HZ;
  186 + of_node_put(cpu);
  187 + }
  188 + tsi108_csr_vir_base = get_vir_csrbase();
  189 +
  190 +#ifdef CONFIG_ROOT_NFS
  191 + ROOT_DEV = Root_NFS;
  192 +#else
  193 + ROOT_DEV = Root_HDA1;
  194 +#endif
  195 +
  196 +#ifdef CONFIG_BLK_DEV_INITRD
  197 + ROOT_DEV = Root_RAM0;
  198 +#endif
  199 +
  200 + /* setup PCI host bridge */
  201 +#ifdef CONFIG_PCI
  202 + for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
  203 + tsi108_setup_pci(np);
  204 +
  205 + ppc_md.pci_exclude_device = mpc7448_hpc2_exclude_device;
  206 + if (ppc_md.progress)
  207 + ppc_md.progress("tsi108: resources set", 0x100);
  208 +#endif
  209 +
  210 + printk(KERN_INFO "MPC7448HPC2 (TAIGA) Platform\n");
  211 + printk(KERN_INFO
  212 + "Jointly ported by Freescale and Tundra Semiconductor\n");
  213 + printk(KERN_INFO
  214 + "Enabling L2 cache then enabling the HID0 prefetch engine.\n");
  215 +}
  216 +
  217 +/*
  218 + * Interrupt setup and service. Interrrupts on the mpc7448_hpc2 come
  219 + * from the four external INT pins, PCI interrupts are routed via
  220 + * PCI interrupt control registers, it generates internal IRQ23
  221 + *
  222 + * Interrupt routing on the Taiga Board:
  223 + * TSI108:PB_INT[0] -> CPU0:INT#
  224 + * TSI108:PB_INT[1] -> CPU0:MCP#
  225 + * TSI108:PB_INT[2] -> N/C
  226 + * TSI108:PB_INT[3] -> N/C
  227 + */
  228 +static void __init mpc7448_hpc2_init_IRQ(void)
  229 +{
  230 + struct mpic *mpic;
  231 + phys_addr_t mpic_paddr = 0;
  232 + struct device_node *tsi_pic;
  233 +
  234 + tsi_pic = of_find_node_by_type(NULL, "open-pic");
  235 + if (tsi_pic) {
  236 + unsigned int size;
  237 + void *prop = get_property(tsi_pic, "reg", &size);
  238 + mpic_paddr = of_translate_address(tsi_pic, prop);
  239 + }
  240 +
  241 + if (mpic_paddr == 0) {
  242 + printk("%s: No tsi108 PIC found !\n", __FUNCTION__);
  243 + return;
  244 + }
  245 +
  246 + DBG("%s: tsi108pic phys_addr = 0x%x\n", __FUNCTION__,
  247 + (u32) mpic_paddr);
  248 +
  249 + mpic = mpic_alloc(mpic_paddr,
  250 + MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET |
  251 + MPIC_SPV_EOI | MPIC_MOD_ID(MPIC_ID_TSI108),
  252 + 0, /* num_sources used */
  253 + TSI108_IRQ_BASE,
  254 + 0, /* num_sources used */
  255 + NR_IRQS - 4 /* XXXX */,
  256 + mpc7448_hpc2_pic_initsenses,
  257 + sizeof(mpc7448_hpc2_pic_initsenses), "Tsi108_PIC");
  258 +
  259 + BUG_ON(mpic == NULL); /* XXXX */
  260 +
  261 + mpic_init(mpic);
  262 + mpic_setup_cascade(IRQ_TSI108_PCI, tsi108_irq_cascade, mpic);
  263 + tsi108_pci_int_init();
  264 +
  265 + /* Configure MPIC outputs to CPU0 */
  266 + tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0);
  267 +}
  268 +
  269 +void mpc7448_hpc2_show_cpuinfo(struct seq_file *m)
  270 +{
  271 + seq_printf(m, "vendor\t\t: Freescale Semiconductor\n");
  272 + seq_printf(m, "machine\t\t: MPC7448hpc2\n");
  273 +}
  274 +
  275 +void mpc7448_hpc2_restart(char *cmd)
  276 +{
  277 + local_irq_disable();
  278 +
  279 + /* Set exception prefix high - to the firmware */
  280 + _nmask_and_or_msr(0, MSR_IP);
  281 +
  282 + for (;;) ; /* Spin until reset happens */
  283 +}
  284 +
  285 +void mpc7448_hpc2_power_off(void)
  286 +{
  287 + local_irq_disable();
  288 + for (;;) ; /* No way to shut power off with software */
  289 +}
  290 +
  291 +void mpc7448_hpc2_halt(void)
  292 +{
  293 + mpc7448_hpc2_power_off();
  294 +}
  295 +
  296 +/*
  297 + * Called very early, device-tree isn't unflattened
  298 + */
  299 +static int __init mpc7448_hpc2_probe(void)
  300 +{
  301 + unsigned long root = of_get_flat_dt_root();
  302 +
  303 + if (!of_flat_dt_is_compatible(root, "mpc74xx"))
  304 + return 0;
  305 + return 1;
  306 +}
  307 +
  308 +static int mpc7448_machine_check_exception(struct pt_regs *regs)
  309 +{
  310 + extern void tsi108_clear_pci_cfg_error(void);
  311 + const struct exception_table_entry *entry;
  312 +
  313 + /* Are we prepared to handle this fault */
  314 + if ((entry = search_exception_tables(regs->nip)) != NULL) {
  315 + tsi108_clear_pci_cfg_error();
  316 + regs->msr |= MSR_RI;
  317 + regs->nip = entry->fixup;
  318 + return 1;
  319 + }
  320 + return 0;
  321 +
  322 +}
  323 +define_machine(mpc7448_hpc2){
  324 + .name = "MPC7448 HPC2",
  325 + .probe = mpc7448_hpc2_probe,
  326 + .setup_arch = mpc7448_hpc2_setup_arch,
  327 + .init_IRQ = mpc7448_hpc2_init_IRQ,
  328 + .show_cpuinfo = mpc7448_hpc2_show_cpuinfo,
  329 + .get_irq = mpic_get_irq,
  330 + .pcibios_fixup = mpc7448_hpc2_pcibios_fixup,
  331 + .restart = mpc7448_hpc2_restart,
  332 + .calibrate_decr = generic_calibrate_decr,
  333 + .machine_check_exception= mpc7448_machine_check_exception,
  334 + .progress = udbg_progress,
  335 +};
arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h
  1 +/*
  2 + * mpc7448_hpc2.h
  3 + *
  4 + * Definitions for Freescale MPC7448_HPC2 platform
  5 + *
  6 + * Author: Jacob Pan
  7 + * jacob.pan@freescale.com
  8 + * Maintainer: Roy Zang <roy.zang@freescale.com>
  9 + *
  10 + * 2006 (c) Freescale Semiconductor, Inc. This file is licensed under
  11 + * the terms of the GNU General Public License version 2. This program
  12 + * is licensed "as is" without any warranty of any kind, whether express
  13 + * or implied.
  14 + */
  15 +
  16 +#ifndef __PPC_PLATFORMS_MPC7448_HPC2_H
  17 +#define __PPC_PLATFORMS_MPC7448_HPC2_H
  18 +
  19 +#include <asm/ppcboot.h>
  20 +
  21 +/* Base Addresses for the PCI bus
  22 + */
  23 +#define MPC7448_HPC2_PCI_MEM_OFFSET (0x00000000)
  24 +#define MPC7448_HPC2_ISA_IO_BASE (0x00000000)
  25 +#define MPC7448_HPC2_ISA_MEM_BASE (0x00000000)
  26 +#endif /* __PPC_PLATFORMS_MPC7448_HPC2_H */