Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * PowerPC 476FPE board specific routines
0004  *
0005  * Copyright © 2013 Tony Breeds IBM Corporation
0006  * Copyright © 2013 Alistair Popple IBM Corporation
0007  *
0008  * Based on earlier code:
0009  *    Matt Porter <mporter@kernel.crashing.org>
0010  *    Copyright 2002-2005 MontaVista Software Inc.
0011  *
0012  *    Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
0013  *    Copyright (c) 2003-2005 Zultys Technologies
0014  *
0015  *    Rewritten and ported to the merged powerpc tree:
0016  *    Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation.
0017  *    Copyright © 2011 David Kliekamp IBM Corporation
0018  */
0019 
0020 #include <linux/init.h>
0021 #include <linux/of.h>
0022 #include <linux/of_address.h>
0023 #include <linux/of_platform.h>
0024 #include <linux/rtc.h>
0025 
0026 #include <asm/machdep.h>
0027 #include <asm/udbg.h>
0028 #include <asm/time.h>
0029 #include <asm/uic.h>
0030 #include <asm/ppc4xx.h>
0031 #include <asm/mpic.h>
0032 #include <asm/mmu.h>
0033 #include <asm/swiotlb.h>
0034 
0035 #include <linux/pci.h>
0036 #include <linux/i2c.h>
0037 
0038 static const struct of_device_id ppc47x_of_bus[] __initconst = {
0039     { .compatible = "ibm,plb4", },
0040     { .compatible = "ibm,plb6", },
0041     { .compatible = "ibm,opb", },
0042     { .compatible = "ibm,ebc", },
0043     {},
0044 };
0045 
0046 /* The EEPROM is missing and the default values are bogus.  This forces USB in
0047  * to EHCI mode */
0048 static void quirk_ppc_currituck_usb_fixup(struct pci_dev *dev)
0049 {
0050     if (of_machine_is_compatible("ibm,currituck")) {
0051         pci_write_config_dword(dev, 0xe0, 0x0114231f);
0052         pci_write_config_dword(dev, 0xe4, 0x00006c40);
0053     }
0054 }
0055 DECLARE_PCI_FIXUP_HEADER(0x1033, 0x0035, quirk_ppc_currituck_usb_fixup);
0056 
0057 /* Akebono has an AVR microcontroller attached to the I2C bus
0058  * which is used to power off/reset the system. */
0059 
0060 /* AVR I2C Commands */
0061 #define AVR_PWRCTL_CMD (0x26)
0062 
0063 /* Flags for the power control I2C commands */
0064 #define AVR_PWRCTL_PWROFF (0x01)
0065 #define AVR_PWRCTL_RESET (0x02)
0066 
0067 static struct i2c_client *avr_i2c_client;
0068 static void __noreturn avr_halt_system(int pwrctl_flags)
0069 {
0070     /* Request the AVR to reset the system */
0071     i2c_smbus_write_byte_data(avr_i2c_client,
0072                   AVR_PWRCTL_CMD, pwrctl_flags);
0073 
0074     /* Wait for system to be reset */
0075     while (1)
0076         ;
0077 }
0078 
0079 static void avr_power_off_system(void)
0080 {
0081     avr_halt_system(AVR_PWRCTL_PWROFF);
0082 }
0083 
0084 static void __noreturn avr_reset_system(char *cmd)
0085 {
0086     avr_halt_system(AVR_PWRCTL_RESET);
0087 }
0088 
0089 static int avr_probe(struct i2c_client *client)
0090 {
0091     avr_i2c_client = client;
0092     ppc_md.restart = avr_reset_system;
0093     pm_power_off = avr_power_off_system;
0094     return 0;
0095 }
0096 
0097 static const struct i2c_device_id avr_id[] = {
0098     { "akebono-avr", 0 },
0099     { }
0100 };
0101 
0102 static struct i2c_driver avr_driver = {
0103     .driver = {
0104         .name = "akebono-avr",
0105     },
0106     .probe_new = avr_probe,
0107     .id_table = avr_id,
0108 };
0109 
0110 static int __init ppc47x_device_probe(void)
0111 {
0112     i2c_add_driver(&avr_driver);
0113     of_platform_bus_probe(NULL, ppc47x_of_bus, NULL);
0114 
0115     return 0;
0116 }
0117 machine_device_initcall(ppc47x, ppc47x_device_probe);
0118 
0119 static void __init ppc47x_init_irq(void)
0120 {
0121     struct device_node *np;
0122 
0123     /* Find top level interrupt controller */
0124     for_each_node_with_property(np, "interrupt-controller") {
0125         if (of_get_property(np, "interrupts", NULL) == NULL)
0126             break;
0127     }
0128     if (np == NULL)
0129         panic("Can't find top level interrupt controller");
0130 
0131     /* Check type and do appropriate initialization */
0132     if (of_device_is_compatible(np, "chrp,open-pic")) {
0133         /* The MPIC driver will get everything it needs from the
0134          * device-tree, just pass 0 to all arguments
0135          */
0136         struct mpic *mpic =
0137             mpic_alloc(np, 0, MPIC_NO_RESET, 0, 0, " MPIC     ");
0138         BUG_ON(mpic == NULL);
0139         mpic_init(mpic);
0140         ppc_md.get_irq = mpic_get_irq;
0141     } else
0142         panic("Unrecognized top level interrupt controller");
0143 }
0144 
0145 #ifdef CONFIG_SMP
0146 static void smp_ppc47x_setup_cpu(int cpu)
0147 {
0148     mpic_setup_this_cpu();
0149 }
0150 
0151 static int smp_ppc47x_kick_cpu(int cpu)
0152 {
0153     struct device_node *cpunode = of_get_cpu_node(cpu, NULL);
0154     const u64 *spin_table_addr_prop;
0155     u32 *spin_table;
0156     extern void start_secondary_47x(void);
0157 
0158     BUG_ON(cpunode == NULL);
0159 
0160     /* Assume spin table. We could test for the enable-method in
0161      * the device-tree but currently there's little point as it's
0162      * our only supported method
0163      */
0164     spin_table_addr_prop =
0165         of_get_property(cpunode, "cpu-release-addr", NULL);
0166 
0167     if (spin_table_addr_prop == NULL) {
0168         pr_err("CPU%d: Can't start, missing cpu-release-addr !\n",
0169                cpu);
0170         return 1;
0171     }
0172 
0173     /* Assume it's mapped as part of the linear mapping. This is a bit
0174      * fishy but will work fine for now
0175      *
0176      * XXX: Is there any reason to assume differently?
0177      */
0178     spin_table = (u32 *)__va(*spin_table_addr_prop);
0179     pr_debug("CPU%d: Spin table mapped at %p\n", cpu, spin_table);
0180 
0181     spin_table[3] = cpu;
0182     smp_wmb();
0183     spin_table[1] = __pa(start_secondary_47x);
0184     mb();
0185 
0186     return 0;
0187 }
0188 
0189 static struct smp_ops_t ppc47x_smp_ops = {
0190     .probe      = smp_mpic_probe,
0191     .message_pass   = smp_mpic_message_pass,
0192     .setup_cpu  = smp_ppc47x_setup_cpu,
0193     .kick_cpu   = smp_ppc47x_kick_cpu,
0194     .give_timebase  = smp_generic_give_timebase,
0195     .take_timebase  = smp_generic_take_timebase,
0196 };
0197 
0198 static void __init ppc47x_smp_init(void)
0199 {
0200     if (mmu_has_feature(MMU_FTR_TYPE_47x))
0201         smp_ops = &ppc47x_smp_ops;
0202 }
0203 
0204 #else /* CONFIG_SMP */
0205 static void __init ppc47x_smp_init(void) { }
0206 #endif /* CONFIG_SMP */
0207 
0208 static void __init ppc47x_setup_arch(void)
0209 {
0210 
0211     /* No need to check the DMA config as we /know/ our windows are all of
0212      * RAM.  Lets hope that doesn't change */
0213     swiotlb_detect_4g();
0214 
0215     ppc47x_smp_init();
0216 }
0217 
0218 static int board_rev = -1;
0219 static int __init ppc47x_get_board_rev(void)
0220 {
0221     int reg;
0222     u8 __iomem *fpga;
0223     struct device_node *np = NULL;
0224 
0225     if (of_machine_is_compatible("ibm,currituck")) {
0226         np = of_find_compatible_node(NULL, NULL, "ibm,currituck-fpga");
0227         reg = 0;
0228     } else if (of_machine_is_compatible("ibm,akebono")) {
0229         np = of_find_compatible_node(NULL, NULL, "ibm,akebono-fpga");
0230         reg = 2;
0231     }
0232 
0233     if (!np)
0234         goto fail;
0235 
0236     fpga = of_iomap(np, 0);
0237     of_node_put(np);
0238     if (!fpga)
0239         goto fail;
0240 
0241     board_rev = ioread8(fpga + reg) & 0x03;
0242     pr_info("%s: Found board revision %d\n", __func__, board_rev);
0243     iounmap(fpga);
0244     return 0;
0245 
0246 fail:
0247     pr_info("%s: Unable to find board revision\n", __func__);
0248     return 0;
0249 }
0250 machine_arch_initcall(ppc47x, ppc47x_get_board_rev);
0251 
0252 /* Use USB controller should have been hardware swizzled but it wasn't :( */
0253 static void ppc47x_pci_irq_fixup(struct pci_dev *dev)
0254 {
0255     if (dev->vendor == 0x1033 && (dev->device == 0x0035 ||
0256                       dev->device == 0x00e0)) {
0257         if (board_rev == 0) {
0258             dev->irq = irq_create_mapping(NULL, 47);
0259             pr_info("%s: Mapping irq %d\n", __func__, dev->irq);
0260         } else if (board_rev == 2) {
0261             dev->irq = irq_create_mapping(NULL, 49);
0262             pr_info("%s: Mapping irq %d\n", __func__, dev->irq);
0263         } else {
0264             pr_alert("%s: Unknown board revision\n", __func__);
0265         }
0266     }
0267 }
0268 
0269 /*
0270  * Called very early, MMU is off, device-tree isn't unflattened
0271  */
0272 static int __init ppc47x_probe(void)
0273 {
0274     if (of_machine_is_compatible("ibm,akebono"))
0275         return 1;
0276 
0277     if (of_machine_is_compatible("ibm,currituck")) {
0278         ppc_md.pci_irq_fixup = ppc47x_pci_irq_fixup;
0279         return 1;
0280     }
0281 
0282     return 0;
0283 }
0284 
0285 define_machine(ppc47x) {
0286     .name           = "PowerPC 47x",
0287     .probe          = ppc47x_probe,
0288     .progress       = udbg_progress,
0289     .init_IRQ       = ppc47x_init_irq,
0290     .setup_arch     = ppc47x_setup_arch,
0291     .restart        = ppc4xx_reset_system,
0292     .calibrate_decr     = generic_calibrate_decr,
0293 };