Path: blob/master/arch/powerpc/platforms/embedded6xx/mvme5100.c
26489 views
// SPDX-License-Identifier: GPL-2.0-or-later1/*2* Board setup routines for the Motorola/Emerson MVME5100.3*4* Copyright 2013 CSC Australia Pty. Ltd.5*6* Based on earlier code by:7*8* Matt Porter, MontaVista Software Inc.9* Copyright 2001 MontaVista Software Inc.10*11* Author: Stephen Chivers <[email protected]>12*/1314#include <linux/of_irq.h>15#include <linux/of_platform.h>16#include <linux/seq_file.h>1718#include <asm/i8259.h>19#include <asm/pci-bridge.h>20#include <asm/mpic.h>21#include <mm/mmu_decl.h>22#include <asm/udbg.h>2324#define HAWK_MPIC_SIZE 0x00040000U25#define MVME5100_PCI_MEM_OFFSET 0x000000002627/* Board register addresses. */28#define BOARD_STATUS_REG 0xfef8808029#define BOARD_MODFAIL_REG 0xfef8809030#define BOARD_MODRST_REG 0xfef880a031#define BOARD_TBEN_REG 0xfef880c032#define BOARD_SW_READ_REG 0xfef880e033#define BOARD_GEO_ADDR_REG 0xfef880e834#define BOARD_EXT_FEATURE1_REG 0xfef880f035#define BOARD_EXT_FEATURE2_REG 0xfef881003637static phys_addr_t pci_membase;38static u_char *restart;3940static void mvme5100_8259_cascade(struct irq_desc *desc)41{42struct irq_chip *chip = irq_desc_get_chip(desc);43unsigned int cascade_irq = i8259_irq();4445if (cascade_irq)46generic_handle_irq(cascade_irq);4748chip->irq_eoi(&desc->irq_data);49}5051static void __init mvme5100_pic_init(void)52{53struct mpic *mpic;54struct device_node *np;55struct device_node *cp = NULL;56unsigned int cirq;57unsigned long intack = 0;58const u32 *prop = NULL;5960np = of_find_node_by_type(NULL, "open-pic");61if (!np) {62pr_err("Could not find open-pic node\n");63return;64}6566mpic = mpic_alloc(np, pci_membase, 0, 16, 256, " OpenPIC ");6768BUG_ON(mpic == NULL);69of_node_put(np);7071mpic_assign_isu(mpic, 0, pci_membase + 0x10000);7273mpic_init(mpic);7475cp = of_find_compatible_node(NULL, NULL, "chrp,iic");76if (cp == NULL) {77pr_warn("mvme5100_pic_init: couldn't find i8259\n");78return;79}8081cirq = irq_of_parse_and_map(cp, 0);82if (!cirq) {83pr_warn("mvme5100_pic_init: no cascade interrupt?\n");84return;85}8687np = of_find_compatible_node(NULL, "pci", "mpc10x-pci");88if (np) {89prop = of_get_property(np, "8259-interrupt-acknowledge", NULL);9091if (prop)92intack = prop[0];9394of_node_put(np);95}9697if (intack)98pr_debug("mvme5100_pic_init: PCI 8259 intack at 0x%016lx\n",99intack);100101i8259_init(cp, intack);102of_node_put(cp);103irq_set_chained_handler(cirq, mvme5100_8259_cascade);104}105106static int __init mvme5100_add_bridge(struct device_node *dev)107{108const int *bus_range;109int len;110struct pci_controller *hose;111unsigned short devid;112113pr_info("Adding PCI host bridge %pOF\n", dev);114115bus_range = of_get_property(dev, "bus-range", &len);116117hose = pcibios_alloc_controller(dev);118if (hose == NULL)119return -ENOMEM;120121hose->first_busno = bus_range ? bus_range[0] : 0;122hose->last_busno = bus_range ? bus_range[1] : 0xff;123124setup_indirect_pci(hose, 0xfe000cf8, 0xfe000cfc, 0);125126pci_process_bridge_OF_ranges(hose, dev, 1);127128early_read_config_word(hose, 0, 0, PCI_DEVICE_ID, &devid);129130if (devid != PCI_DEVICE_ID_MOTOROLA_HAWK) {131pr_err("HAWK PHB not present?\n");132return 0;133}134135early_read_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_1, &pci_membase);136137if (pci_membase == 0) {138pr_err("HAWK PHB mibar not correctly set?\n");139return 0;140}141142pr_info("mvme5100_pic_init: pci_membase: %x\n", pci_membase);143144return 0;145}146147static const struct of_device_id mvme5100_of_bus_ids[] __initconst = {148{ .compatible = "hawk-bridge", },149{},150};151152/*153* Setup the architecture154*/155static void __init mvme5100_setup_arch(void)156{157if (ppc_md.progress)158ppc_md.progress("mvme5100_setup_arch()", 0);159160restart = ioremap(BOARD_MODRST_REG, 4);161}162163static void __init mvme5100_setup_pci(void)164{165struct device_node *np;166167for_each_compatible_node(np, "pci", "hawk-pci")168mvme5100_add_bridge(np);169}170171static void mvme5100_show_cpuinfo(struct seq_file *m)172{173seq_puts(m, "Vendor\t\t: Motorola/Emerson\n");174seq_puts(m, "Machine\t\t: MVME5100\n");175}176177static void __noreturn mvme5100_restart(char *cmd)178{179180local_irq_disable();181mtmsr(mfmsr() | MSR_IP);182183out_8((u_char *) restart, 0x01);184185while (1)186;187}188189static int __init probe_of_platform_devices(void)190{191192of_platform_bus_probe(NULL, mvme5100_of_bus_ids, NULL);193return 0;194}195196machine_device_initcall(mvme5100, probe_of_platform_devices);197198define_machine(mvme5100) {199.name = "MVME5100",200.compatible = "MVME5100",201.setup_arch = mvme5100_setup_arch,202.discover_phbs = mvme5100_setup_pci,203.init_IRQ = mvme5100_pic_init,204.show_cpuinfo = mvme5100_show_cpuinfo,205.get_irq = mpic_get_irq,206.restart = mvme5100_restart,207.progress = udbg_progress,208};209210211