From patchwork Fri Dec 22 09:57:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Christian Zigotzky X-Patchwork-Id: 852288 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3z33th4Xszz9sBZ for ; Fri, 22 Dec 2017 21:01:16 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=xenosoft.de header.i=@xenosoft.de header.b="pPFiikP7"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3z33th1hBbzDqlG for ; Fri, 22 Dec 2017 21:01:16 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=xenosoft.de header.i=@xenosoft.de header.b="pPFiikP7"; dkim-atps=neutral X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (helo) smtp.helo=mo6-p00-ob.smtp.rzone.de (client-ip=2a01:238:20a:202:5300::10; helo=mo6-p00-ob.smtp.rzone.de; envelope-from=chzigotzky@xenosoft.de; receiver=) Authentication-Results: lists.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=xenosoft.de header.i=@xenosoft.de header.b="pPFiikP7"; dkim-atps=neutral Received: from mo6-p00-ob.smtp.rzone.de (mo6-p00-ob.smtp.rzone.de [IPv6:2a01:238:20a:202:5300::10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3z33qW29DHzDsQM for ; Fri, 22 Dec 2017 20:58:30 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1513936706; s=domk; d=xenosoft.de; h=Content-Type:In-Reply-To:Date:Message-ID:References:To:From:Subject: X-RZG-CLASS-ID:X-RZG-AUTH:From:Subject; bh=gJ9D0RU2Iifh/XRl8lKXwg6Ma1pTigope/KE2tHYpRU=; b=pPFiikP7er1HbAgdthLhpB8pM0T8zhJW8D5p4+ps+qapRUAkBG54WplPqRo9na/lzD qPi8+qK20Uf0rnrZlYzMvsFWJGwqI2oaFYOizja/bovEpEh2HoZHWAbhemEg9pBRphtm fViLTVliznKcRvrzKP1I7O6pRc8/EOy7EGukU= X-RZG-AUTH: :L2QefEenb+UdBJSdRCXu93KJ1bmSGnhMdmOod1DhGM4l4Hio94KKxRySf+VvAflxJtIc60wmwNqM X-RZG-CLASS-ID: mo00 Received: from [192.168.1.134] (ppp-188-174-69-151.dynamic.mnet-online.de [188.174.69.151]) by smtp.strato.de (RZmta 42.14 DYNA|AUTH) with ESMTPSA id n02a10tBM9w0IoM (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (curve secp521r1 with 521 ECDH bits, eq. 15360 bits RSA)) (Client did not present a certificate); Fri, 22 Dec 2017 10:58:00 +0100 (CET) Subject: [PATCH] SB600 for the Nemo board has non-zero devices on non-root bus From: Christian Zigotzky To: Bjorn Helgaas , Michael Ellerman , Darren Stevens , "linux-pci@vger.kernel.org" , Bjorn Helgaas , Olof Johansson , linuxppc-dev References: <20171202230052.34y2ivxgpgr3osct@localhost> <4CEE49CE-68F3-457F-B302-54BA8550F36A@xenosoft.de> <1d5276c3-1d29-114a-c868-6f022eee58e7@xenosoft.de> <99f78122-cd53-100f-4f58-be5bf7927d4e@xenosoft.de> <87fu8odnfk.fsf@concordia.ellerman.id.au> <20171206210637.GO23510@bhelgaas-glaptop.roam.corp.google.com> <877etxh1lf.fsf@concordia.ellerman.id.au> <98c7e034-b523-a703-e637-957e2857ab32@xenosoft.de> <20171215202509.GZ30595@bhelgaas-glaptop.roam.corp.google.com> <6326d79e-405b-2ae8-5295-97bf11219b81@xenosoft.de> Message-ID: Date: Fri, 22 Dec 2017 10:57:59 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.5.0 MIME-Version: 1.0 In-Reply-To: <6326d79e-405b-2ae8-5295-97bf11219b81@xenosoft.de> Content-Language: de-DE X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.24 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" Hi Bjorn, Sorry I'm bothering you again. Is this small out of tree init routine in the Nemo patch? I haven't get an answer from Darren yet and I didn't found the small out of tree init routine in the Nemo patch. Please find attached the Nemo patch. Maybe you can find this small out of tree init routine. What do you think of this following code? if (sb600_bus == -1) +       { +               busp = pci_find_bus(0, 0); +               pa_pxp_read_config(busp, PCI_DEVFN(17,0), PCI_SECONDARY_BUS, 1, &val); + +               sb600_bus = val; + +               printk(KERN_CRIT "NEMO SB600 on bus %d.\n",sb600_bus); +       } Thanks, Christian On 04 December 2017 at 12:40PM, Darren Stevens wrote: > Hello Bjorn > > Firstly sorry for not being able to join in this discussion, I have been > moving house and only got my X1000 set up again yesterday.. > > On 30/11/2017, Bjorn Helgaas wrote: >> I *think* something like the patch below should make this work if you >> use the "pci=pcie_scan_all" parameter.  We have some x86 DMI quirks >> that set PCI_SCAN_ALL_PCIE_DEVS automatically.  I don't know how to do >> something similar on powerpc, but maybe you do? > > Actually the root ports on the Nemo's PA6T processor don't respond to the > SB600 unless we turn on a special 'relax pci-e' bit in one of its control > registers. We use a small out of tree init routine to do this, and there > would be the ideal place to put a call to > pci_set_flag(PCI_SCAN_ALL_PCIE_DEVS). > > This patch fixes the last major hurdle to getting the X1000 fully supported in > the linux kernel, so thanks very much for that. > > Regards > Darren > > diff -rupN a/arch/powerpc/platforms/pasemi/pci.c b/arch/powerpc/platforms/pasemi/pci.c --- a/arch/powerpc/platforms/pasemi/pci.c 2017-09-11 17:04:18.257586417 +0200 +++ b/arch/powerpc/platforms/pasemi/pci.c 2017-09-11 17:03:43.040599938 +0200 @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -108,6 +109,69 @@ static int workaround_5945(struct pci_bu return 1; } +#ifdef CONFIG_PPC_PASEMI_NEMO +static int sb600_bus = 5; +static void __iomem *iob_mapbase = NULL; + +static int pa_pxp_read_config(struct pci_bus *bus, unsigned int devfn, + int offset, int len, u32 *val); + +static void sb600_set_flag(int bus) +{ + struct resource res; + struct device_node *dn; + struct pci_bus *busp; + u32 val; + int err; + + if (sb600_bus == -1) + { + busp = pci_find_bus(0, 0); + pa_pxp_read_config(busp, PCI_DEVFN(17,0), PCI_SECONDARY_BUS, 1, &val); + + sb600_bus = val; + + printk(KERN_CRIT "NEMO SB600 on bus %d.\n",sb600_bus); + } + + if (iob_mapbase == NULL) + { + dn = of_find_compatible_node(NULL, "isa", "pasemi,1682m-iob"); + if (!dn) + { + printk(KERN_CRIT "NEMO SB600 missing iob node\n"); + return; + } + + err = of_address_to_resource(dn, 0, &res); + of_node_put(dn); + + if (err) + { + printk(KERN_CRIT "NEMO SB600 missing resource\n"); + return; + } + + printk(KERN_CRIT "NEMO SB600 IOB base %08lx\n",res.start); + + iob_mapbase = ioremap(res.start + 0x100, 0x94); + } + + if (iob_mapbase != NULL) + { + if (bus == sb600_bus) + { + out_le32(iob_mapbase + 4, in_le32(iob_mapbase + 4) | 0x800); + } + else + { + out_le32(iob_mapbase + 4, in_le32(iob_mapbase + 4) & ~0x800); + } + } +} +#endif + + static int pa_pxp_read_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 *val) { @@ -126,6 +190,10 @@ static int pa_pxp_read_config(struct pci addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset); +#ifdef CONFIG_PPC_PASEMI_NEMO + sb600_set_flag(bus->number); +#endif + /* * Note: the caller has already checked that offset is * suitably aligned and that len is 1, 2 or 4. @@ -210,6 +278,9 @@ static int __init pas_add_bridge(struct /* Interpret the "ranges" property */ pci_process_bridge_OF_ranges(hose, dev, 1); + /* Scan for an isa bridge. */ + isa_bridge_find_early(hose); + return 0; } diff -rupN a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c --- a/arch/powerpc/platforms/pasemi/setup.c 2017-09-11 17:04:18.256586450 +0200 +++ b/arch/powerpc/platforms/pasemi/setup.c 2017-09-11 17:03:43.042599888 +0200 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -72,6 +73,17 @@ static void __noreturn pas_restart(char out_le32(reset_reg, 0x6000000); } +#ifdef CONFIG_PPC_PASEMI_NEMO +void pas_shutdown(void) +{ + /* (added by DStevens 19/06/13) + Set the PLD bit that makes the SB600 think the power button is being pressed */ + void __iomem *pld_map = ioremap(0xf5000000,4096); + while (1) + out_8(pld_map+7,0x01); +} +#endif + #ifdef CONFIG_SMP static arch_spinlock_t timebase_lock; static unsigned long timebase; @@ -183,16 +195,30 @@ static int __init pas_setup_mce_regs(voi } machine_device_initcall(pasemi, pas_setup_mce_regs); +#ifdef CONFIG_PPC_PASEMI_NEMO +static void sb600_8259_cascade(struct irq_desc *desc) +{ + struct irq_chip *chip = irq_desc_get_chip(desc); + unsigned int cascade_irq = i8259_irq(); + + if (cascade_irq !=NO_IRQ) + generic_handle_irq(cascade_irq); + + chip->irq_eoi(&desc->irq_data); +} +#endif + static __init void pas_init_IRQ(void) { struct device_node *np; - struct device_node *root, *mpic_node; + struct device_node *root, *mpic_node, *i8259_node; unsigned long openpic_addr; const unsigned int *opprop; int naddr, opplen; int mpic_flags; const unsigned int *nmiprop; struct mpic *mpic; + int gpio_virq; mpic_node = NULL; @@ -244,6 +270,22 @@ static __init void pas_init_IRQ(void) mpic_unmask_irq(irq_get_irq_data(nmi_virq)); } + +#ifdef CONFIG_PPC_PASEMI_NEMO + // Connect legacy i8259 controller in SB600 + i8259_node = of_find_node_by_path("/pxp@0,e0000000"); + printk("Init i8259\n"); + i8259_init(i8259_node, 0); + of_node_put(i8259_node); + + gpio_virq = irq_create_mapping(NULL, 3); + irq_set_irq_type(gpio_virq, IRQ_TYPE_LEVEL_HIGH); + irq_set_chained_handler(gpio_virq, sb600_8259_cascade); + mpic_unmask_irq(irq_get_irq_data(gpio_virq)); + + irq_set_default_host(mpic->irqhost); + +#endif of_node_put(mpic_node); of_node_put(root); } @@ -398,6 +440,18 @@ static const struct of_device_id pasemi_ {}, }; +static struct resource rtc_resource[] = {{ + .name = "rtc", + .start = 0x70, + .end = 0x71, + .flags = IORESOURCE_IO, +}, { + .name = "rtc", + .start = 8, + .end = 8, + .flags = IORESOURCE_IRQ, +}}; + static int __init pasemi_publish_devices(void) { pasemi_pcmcia_init(); @@ -405,6 +459,10 @@ static int __init pasemi_publish_devices /* Publish OF platform devices for SDC and other non-PCI devices */ of_platform_bus_probe(NULL, pasemi_bus_ids, NULL); +#ifdef CONFIG_PPC_PASEMI_NEMO + platform_device_register_simple("rtc_cmos", -1, rtc_resource, 2); +#endif + return 0; } machine_device_initcall(pasemi, pasemi_publish_devices); @@ -421,9 +479,13 @@ static int __init pas_probe(void) iommu_init_early_pasemi(); +#ifdef CONFIG_PPC_PASEMI_NEMO + pm_power_off = pas_shutdown; // Varisys provided a way to turn us off +#endif return 1; } + define_machine(pasemi) { .name = "PA Semi PWRficient", .probe = pas_probe, @@ -435,4 +497,7 @@ define_machine(pasemi) { .calibrate_decr = generic_calibrate_decr, .progress = pas_progress, .machine_check_exception = pas_machine_check_handler, +#if 0 // def CONFIG_PPC_PASEMI_NEMO + .pci_probe_mode = sb600_pci_probe_mode, +#endif }; diff -rupN a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c --- a/drivers/ata/pata_atiixp.c 2017-09-11 17:04:26.591307805 +0200 +++ b/drivers/ata/pata_atiixp.c 2017-09-11 17:03:43.043599863 +0200 @@ -278,6 +278,12 @@ static int atiixp_init_one(struct pci_de }; const struct ata_port_info *ppi[] = { &info, &info }; + /* SB600 on the Nemo board doesn't have secondary port wired */ + #ifdef CONFIG_PPC_PASEMI_NEMO + if((pdev->device == PCI_DEVICE_ID_ATI_IXP600_IDE)) + ppi[1] = &ata_dummy_port_info; + #endif + return ata_pci_bmdma_init_one(pdev, ppi, &atiixp_sht, NULL, ATA_HOST_PARALLEL_SCAN); } diff -rupN a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c --- a/drivers/ata/pata_of_platform.c 2017-09-11 17:04:26.565308689 +0200 +++ b/drivers/ata/pata_of_platform.c 2017-09-11 17:03:43.044599838 +0200 @@ -40,14 +40,36 @@ static int pata_of_platform_probe(struct return -EINVAL; } - ret = of_address_to_resource(dn, 1, &ctl_res); - if (ret) { - dev_err(&ofdev->dev, "can't get CTL address from " - "device tree\n"); - return -EINVAL; + if (of_device_is_compatible(dn, "electra-ide")) { + /* Altstatus is really at offset 0x3f6 from the primary window + * on electra-ide. Adjust ctl_res and io_res accordingly. + */ + ctl_res = io_res; + ctl_res.start = ctl_res.start+0x3f6; + io_res.end = ctl_res.start-1; + +#ifdef CONFIG_PPC_PASEMI_NEMO + } else if (of_device_is_compatible(dn, "electra-cf")) { + /* Task regs are at 0x800, with alt status @ 0x80e in the primary window + * on electra-cf. Adjust ctl_res and io_res accordingly. + */ + ctl_res = io_res; + io_res.start += 0x800; + ctl_res.start = ctl_res.start + 0x80e; + io_res.end = ctl_res.start-1; +#endif + } else { + ret = of_address_to_resource(dn, 1, &ctl_res); + if (ret) { + dev_err(&ofdev->dev, "can't get CTL address from " + "device tree\n"); + return -EINVAL; + } } irq_res = platform_get_resource(ofdev, IORESOURCE_IRQ, 0); + if (irq_res) + irq_res->flags = 0; of_property_read_u32(dn, "reg-shift", ®_shift); @@ -60,6 +82,11 @@ static int pata_of_platform_probe(struct dev_info(&ofdev->dev, "pio-mode unspecified, assuming PIO0\n"); } +#ifdef CONFIG_PPC_PASEMI_NEMO + irq_res = 0; // force irq off (doesn't seem to work) +#endif + + pio_mask = 1 << pio_mode; pio_mask |= (1 << pio_mode) - 1; @@ -69,6 +96,10 @@ static int pata_of_platform_probe(struct static const struct of_device_id pata_of_platform_match[] = { { .compatible = "ata-generic", }, + { .compatible = "electra-ide", }, +#ifdef CONFIG_PPC_PASEMI_NEMO + { .compatible = "electra-cf",}, +#endif { }, }; MODULE_DEVICE_TABLE(of, pata_of_platform_match); diff -rupN a/drivers/i2c/busses/i2c-pasemi.c b/drivers/i2c/busses/i2c-pasemi.c --- a/drivers/i2c/busses/i2c-pasemi.c 2017-09-11 17:04:23.084427043 +0200 +++ b/drivers/i2c/busses/i2c-pasemi.c 2017-09-11 17:03:43.045599813 +0200 @@ -365,7 +365,6 @@ static int pasemi_smb_probe(struct pci_d smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; smbus->adapter.algo = &smbus_algorithm; smbus->adapter.algo_data = smbus; - smbus->adapter.nr = PCI_FUNC(dev->devfn); /* set up the sysfs linkage to our parent device */ smbus->adapter.dev.parent = &dev->dev; @@ -373,7 +372,7 @@ static int pasemi_smb_probe(struct pci_d reg_write(smbus, REG_CTL, (CTL_MTR | CTL_MRR | (CLK_100K_DIV & CTL_CLK_M))); - error = i2c_add_numbered_adapter(&smbus->adapter); + error = i2c_add_adapter(&smbus->adapter); if (error) goto out_release_region; diff -rupN a/drivers/pci/probe.c b/drivers/pci/probe.c --- a/drivers/pci/probe.c 2017-09-11 17:04:23.683406677 +0200 +++ b/drivers/pci/probe.c 2017-09-11 17:03:43.050599688 +0200 @@ -2177,6 +2177,8 @@ static int only_one_child(struct pci_bus if (!parent || !pci_is_pcie(parent)) return 0; + #ifndef CONFIG_PPC_PASEMI_NEMO + // SB600 has non-zero devices on non-root bus. if (pci_pcie_type(parent) == PCI_EXP_TYPE_ROOT_PORT) return 1; @@ -2189,6 +2191,7 @@ static int only_one_child(struct pci_bus if (parent->has_secondary_link && !pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS)) return 1; + #endif return 0; }