From owner-p4-projects@FreeBSD.ORG Wed Mar 31 08:40:03 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 0AADD1065673; Wed, 31 Mar 2010 08:40:03 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C0CB61065680 for ; Wed, 31 Mar 2010 08:40:02 +0000 (UTC) (envelope-from raj@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id A86AC8FC25 for ; Wed, 31 Mar 2010 08:40:02 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id o2V8e2xj011726 for ; Wed, 31 Mar 2010 08:40:02 GMT (envelope-from raj@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id o2V8e2In011724 for perforce@freebsd.org; Wed, 31 Mar 2010 08:40:02 GMT (envelope-from raj@freebsd.org) Date: Wed, 31 Mar 2010 08:40:02 GMT Message-Id: <201003310840.o2V8e2In011724@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to raj@freebsd.org using -f From: Rafal Jaworowski To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 176348 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 31 Mar 2010 08:40:03 -0000 http://p4web.freebsd.org/chv.cgi?CH=176348 Change 176348 by raj@raj_fdt on 2010/03/31 08:39:37 Initial support for PCI / PCI-Express nodes. - Retrieve IMMR data from the DT at very early stage, reduce direct usage of FDT_IMMR_VA. - Improve retrieving CESA SRAM range data. - Rework MV PCI driver to use DT-provided config data and parameters. - Collapse shared (platform) MV code. - Bring a number of other smaller fixes, corrections, renamings and clean-up Tested with PCI-Express network card (em(4)) on DB-88F6281. Affected files ... .. //depot/projects/fdt/sys/arm/include/fdt.h#3 edit .. //depot/projects/fdt/sys/arm/mv/common.c#8 edit .. //depot/projects/fdt/sys/arm/mv/discovery/discovery.c#3 edit .. //depot/projects/fdt/sys/arm/mv/discovery/files.db78xxx#2 edit .. //depot/projects/fdt/sys/arm/mv/gpio.c#4 edit .. //depot/projects/fdt/sys/arm/mv/kirkwood/db88f6xxx.c#4 delete .. //depot/projects/fdt/sys/arm/mv/kirkwood/files.db88f6xxx#2 delete .. //depot/projects/fdt/sys/arm/mv/kirkwood/kirkwood.c#9 edit .. //depot/projects/fdt/sys/arm/mv/kirkwood/sheevaplug.c#3 edit .. //depot/projects/fdt/sys/arm/mv/kirkwood/std.db88f6xxx#2 edit .. //depot/projects/fdt/sys/arm/mv/mv_machdep.c#11 edit .. //depot/projects/fdt/sys/arm/mv/mv_pci.c#2 edit .. //depot/projects/fdt/sys/arm/mv/mvvar.h#6 edit .. //depot/projects/fdt/sys/arm/mv/mvwin.h#4 edit .. //depot/projects/fdt/sys/arm/mv/orion/db88f5xxx.c#3 edit .. //depot/projects/fdt/sys/arm/mv/orion/orion.c#4 edit .. //depot/projects/fdt/sys/conf/files#20 edit .. //depot/projects/fdt/sys/dev/fdt/fdt_arm.c#5 edit .. //depot/projects/fdt/sys/dev/fdt/fdt_common.c#12 edit .. //depot/projects/fdt/sys/dev/fdt/fdt_common.h#10 edit .. //depot/projects/fdt/sys/dev/fdt/fdt_pci.c#1 add .. //depot/projects/fdt/sys/dev/fdt/fdtbus.c#6 edit .. //depot/projects/fdt/sys/dev/fdt/simplebus.c#8 edit .. //depot/projects/fdt/sys/dev/ofw/ofw_bus_subr.c#4 edit .. //depot/projects/fdt/sys/dev/uart/uart_bus_fdt.c#7 edit .. //depot/projects/fdt/sys/powerpc/mpc85xx/lbc.c#6 edit Differences ... ==== //depot/projects/fdt/sys/arm/include/fdt.h#3 (text+ko) ==== @@ -31,6 +31,12 @@ #ifndef _MACHINE_FDT_H_ +#include + +#include +#include + +#include #include #include @@ -50,4 +56,7 @@ */ #define fdtbus_bs_tag obio_tag +int fdt_pci_devmap(phandle_t, struct pmap_devmap *devmap, vm_offset_t, + vm_offset_t); + #endif /* _MACHINE_FDT_H_ */ ==== //depot/projects/fdt/sys/arm/mv/common.c#8 (text+ko) ==== @@ -274,7 +274,7 @@ *rev = bus_space_read_4(fdtbus_bs_tag, MV_PCIE_BASE, 8) & 0xff; } -void +static void soc_identify(void) { uint32_t d, r; @@ -336,6 +336,20 @@ /* TODO add info on currently set endianess */ } +static void +platform_identify(void *dummy) +{ + + soc_identify(); + + /* + * XXX Board identification e.g. read out from FPGA or similar should + * go here + */ +} +SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify, + NULL); + #define MV_USB0_BASE (FDT_IMMR_VA + usb0_base) #define MV_CESA_BASE (FDT_IMMR_VA + cesa_base) #define MV_ETH0_BASE (FDT_IMMR_VA + eth0_base) @@ -1735,7 +1749,7 @@ if (soc_node->base == NULL) continue; - err = fdt_get_regsize(child, soc_node->base, &size); + err = fdt_regsize(child, soc_node->base, &size); if (err != 0) return (err); } @@ -1779,12 +1793,19 @@ /* * Retrieve CESA SRAM data. */ - if ((node = OF_finddevice("/sram")) == 0) + if ((node = OF_finddevice("sram")) != 0) + if (fdt_is_compatible(node, "mrvl,cesa-sram")) + goto moveon; + + if ((node = OF_finddevice("/")) == 0) + return (ENXIO); + + if ((node = fdt_find_compatible(node, "mrvl,cesa-sram", 0)) == 0) /* SRAM block is not always present. */ return (0); - +moveon: sram_base = sram_size = 0; - if (fdt_get_regsize(node, &sram_base, &sram_size) != 0) + if (fdt_regsize(node, &sram_base, &sram_size) != 0) return (EINVAL); cpu_win_tbl[++t].target = MV_WIN_CESA_TARGET; @@ -1792,7 +1813,7 @@ cpu_win_tbl[t].base = sram_base; cpu_win_tbl[t].size = sram_size; cpu_win_tbl[t].remap = -1; - debugf("/sram: base = 0x%0lx size = 0x%0lx\n", sram_base, sram_size); + debugf("sram: base = 0x%0lx size = 0x%0lx\n", sram_base, sram_size); return (0); } ==== //depot/projects/fdt/sys/arm/mv/discovery/discovery.c#3 (text+ko) ==== @@ -53,6 +53,7 @@ #define _MV_PCIE_IO_PHYS(n) (MV_PCIE_IO_PHYS_BASE + ((n) * _MV_PCIE_IO_SIZE)) #define _MV_PCIE_MEM_PHYS(n) (MV_PCIE_MEM_PHYS_BASE + ((n) * _MV_PCIE_MEM_SIZE)) +#if 0 /* * Note the 'pcib' devices are not declared in the obio_devices[]: due to the * much more complex configuration schemes allowed, specifically of the @@ -114,6 +115,7 @@ { 0, 0, 0 } }; +#endif struct resource_spec mv_gpio_res[] = { { SYS_RES_MEMORY, 0, RF_ACTIVE }, ==== //depot/projects/fdt/sys/arm/mv/discovery/files.db78xxx#2 (text+ko) ==== @@ -1,4 +1,3 @@ # $FreeBSD: src/sys/arm/mv/discovery/files.db78xxx,v 1.1 2008/10/13 20:07:13 raj Exp $ arm/mv/discovery/discovery.c standard -arm/mv/discovery/db78xxx.c standard ==== //depot/projects/fdt/sys/arm/mv/gpio.c#4 (text+ko) ==== @@ -566,7 +566,7 @@ tuple_size = gpio_cells * sizeof(pcell_t) + sizeof(phandle_t); tuples = len / tuple_size; - if (fdt_get_regsize(ctrl, &gpio_ctrl, &size)) + if (fdt_regsize(ctrl, &gpio_ctrl, &size)) return (ENXIO); /* * Since to set up GPIO we use the same functions as GPIO driver, and @@ -578,7 +578,7 @@ mv_gpio_softc = ≻ sc.bst = fdtbus_bs_tag; - gpio_ctrl += FDT_IMMR_VA; + gpio_ctrl += fdt_immr_va; if (bus_space_map(sc.bst, gpio_ctrl, size, 0, &sc.bsh) != 0) return (ENXIO); @@ -588,7 +588,7 @@ sc.pin_num = fdt32_to_cpu(pincnt); /* - * Skip controller reference, since contoller's phandle is given + * Skip controller reference, since controller's phandle is given * explicitly (in a function argument). */ inc = sizeof(ihandle_t) / sizeof(pcell_t); ==== //depot/projects/fdt/sys/arm/mv/kirkwood/kirkwood.c#9 (text+ko) ==== @@ -42,17 +42,6 @@ #include #include -const struct obio_pci mv_pci_info[] = { - { MV_TYPE_PCIE, - MV_PCIE_BASE, MV_PCIE_SIZE, - MV_PCIE_IO_BASE, MV_PCIE_IO_SIZE, 4, 0xE0, - MV_PCIE_MEM_BASE, MV_PCIE_MEM_SIZE, 4, 0xE8, - NULL, MV_INT_PEX0 - }, - - { 0, 0, 0 } -}; - struct resource_spec mv_gpio_res[] = { { SYS_RES_MEMORY, 0, RF_ACTIVE }, { SYS_RES_IRQ, 0, RF_ACTIVE }, ==== //depot/projects/fdt/sys/arm/mv/kirkwood/sheevaplug.c#3 (text+ko) ==== @@ -1,8 +1,10 @@ /*- - * Copyright (C) 2008 MARVELL INTERNATIONAL LTD. - * Copyright (C) 2009 Semihalf + * Copyright (c) 2010 The FreeBSD Foundation * All rights reserved. * + * This software was developed by Semihalf under sponsorship from + * the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -11,14 +13,11 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of MARVELL nor the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) @@ -29,80 +28,17 @@ */ #include -__FBSDID("$FreeBSD: src/sys/arm/mv/kirkwood/sheevaplug.c,v 1.1 2009/08/25 10:09:25 raj Exp $"); +__FBSDID("$FreeBSD$"); -#include -#include -#include -#include +#include +#include -#include -#include +#include -#include -#include -#include -#include - -#include -#include -#include - -/* - * Virtual address space layout: - * ----------------------------- - * 0x0000_0000 - 0x7FFF_FFFF : User Process (2 GB) - * 0x8000_0000 - 0xBBFF_FFFF : Unused (960 MB) - * 0xBC00_0000 - 0xBDFF_FFFF : Device Bus: CS1 (32 MB) - * 0xBE00_0000 - 0xBECF_FFFF : Unused (13 MB) - * 0xBED0_0000 - 0xBEDF_FFFF : Device Bus: CS2 (1 MB) - * 0xBEE0_0000 - 0xBEEF_FFFF : Device Bus: CS0 (1 MB) - * 0xBEF0_0000 - 0xBEFF_FFFF : Device Bus: BOOT (1 MB) - * 0xBF00_0000 - 0xBFFF_FFFF : Unused (16 MB) - * 0xC000_0000 - virtual_avail : Kernel Reserved (text, data, page tables, - * : stack etc.) - * virtual-avail - 0xEFFF_FFFF : KVA (virtual_avail is typically < 0xc0a0_0000) - * 0xF000_0000 - 0xF0FF_FFFF : No-Cache allocation area (16 MB) - * 0xF100_0000 - 0xF10F_FFFF : SoC Integrated devices registers range (1 MB) - * 0xF110_0000 - 0xF11F_FFFF : CESA SRAM (1 MB) - * 0xF120_0000 - 0xFFFE_FFFF : Unused (237 MB + 960 kB) - * 0xFFFF_0000 - 0xFFFF_0FFF : 'High' vectors page (4 kB) - * 0xFFFF_1000 - 0xFFFF_1FFF : ARM_TP_ADDRESS/RAS page (4 kB) - * 0xFFFF_2000 - 0xFFFF_FFFF : Unused (56 kB) - */ - -/* Static device mappings. */ -const struct pmap_devmap pmap_devmap[] = { - /* - * Map the on-board devices VA == PA so that we can access them - * with the MMU on or off. - */ - { /* SoC integrated peripherals registers range */ - MV_BASE, - MV_PHYS_BASE, - MV_SIZE, - VM_PROT_READ | VM_PROT_WRITE, - PTE_NOCACHE, - }, - { /* CESA SRAM */ - MV_CESA_SRAM_BASE, - MV_CESA_SRAM_PHYS_BASE, - MV_CESA_SRAM_SIZE, - VM_PROT_READ | VM_PROT_WRITE, - PTE_NOCACHE, - }, - { 0, 0, 0, 0, 0, } -}; - -static void -platform_identify(void *dummy) +int +fdt_pci_devmap(phandle_t node, struct pmap_devmap *devmap, vm_offset_t io_va, + vm_offset_t mem_va) { - soc_identify(); - - /* - * XXX Board identification e.g. read out from FPGA or similar should - * go here - */ + return (0); } -SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify, NULL); ==== //depot/projects/fdt/sys/arm/mv/kirkwood/std.db88f6xxx#2 (text+ko) ==== @@ -2,7 +2,6 @@ include "../mv/std.mv" include "../mv/kirkwood/std.kirkwood" -files "../mv/kirkwood/files.db88f6xxx" - +files "../mv/kirkwood/files.kirkwood" options PHYSMEM_SIZE=0x20000000 ==== //depot/projects/fdt/sys/arm/mv/mv_machdep.c#11 (text+ko) ==== @@ -124,13 +124,10 @@ extern u_int prefetch_abort_handler_address; extern u_int undefined_handler_address; -extern const struct pmap_devmap *pmap_devmap_bootstrap_table; extern vm_offset_t pmap_bootstrap_lastaddr; +extern int *end; struct pv_addr kernel_pt_table[KERNEL_PT_MAX]; - -extern int *end; - struct pcpu __pcpu; struct pcpu *pcpup = &__pcpu; @@ -166,6 +163,7 @@ static void print_bootinfo(void); static void physmap_init(int); +static int platform_devmap_init(void); static int platform_mpp_init(void); static char * @@ -396,12 +394,13 @@ kmdp = preload_search_by_type("elf kernel"); if (kmdp != NULL) { bootinfo = (struct bootinfo *)preload_search_info(kmdp, - MODINFO_METADATA|MODINFOMD_BOOTINFO); + MODINFO_METADATA | MODINFOMD_BOOTINFO); boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *); dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t); - lastaddr = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t); + lastaddr = MD_FETCH(kmdp, MODINFOMD_KERNEND, + vm_offset_t); } /* Initialize memory regions table */ @@ -415,7 +414,8 @@ } availmem_regions_sz = i; } else { - /* Fall back to hardcoded metadata. */ + /* Fall back to hardcoded boothowto flags and metadata. */ + boothowto = RB_VERBOSE | RB_SINGLE; lastaddr = fake_preload_metadata(); /* @@ -447,9 +447,11 @@ if (OF_init((void *)dtbp) != 0) while (1); + if (fdt_immr_addr() != 0) + while (1); + /* Platform-specific initialisation */ - pmap_bootstrap_lastaddr = MV_BASE - ARM_NOCACHE_KVA_SIZE; - pmap_devmap_bootstrap_table = &pmap_devmap[0]; + pmap_bootstrap_lastaddr = fdt_immr_va - ARM_NOCACHE_KVA_SIZE; pcpu_init(pcpup, 0, sizeof(struct pcpu)); PCPU_SET(curthread, &thread0); @@ -564,7 +566,11 @@ pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); + /* Map pmap_devmap[] entries */ + if (platform_devmap_init() != 0) + while (1); pmap_devmap_bootstrap(l1pagetable, pmap_devmap_bootstrap_table); + cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) | DOMAIN_CLIENT); setttb(kernel_l1pt.pv_pa); @@ -688,7 +694,6 @@ { pcell_t pinmap[MPP_PIN_MAX * MPP_PIN_CELLS]; int mpp[MPP_PIN_MAX]; - char buf[64]; uint32_t ctrl_val, ctrl_offset; pcell_t reg[4]; u_long start, size; @@ -702,15 +707,9 @@ /* * Try to access the MPP node directly i.e. through /aliases/mpp. */ - if ((node = OF_finddevice("/aliases")) != 0) - if (OF_getprop(node, "mpp", buf, sizeof(buf)) > 0) { - if ((node = OF_finddevice(buf)) == 0) - return (ENXIO); - if (!fdt_is_compatible(node, "mrvl,mpp")) - return (ENXIO); + if ((node = OF_finddevice("mpp")) != 0) + if (fdt_is_compatible(node, "mrvl,mpp")) goto moveon; - } - /* * Find the node the long way. */ @@ -722,7 +721,6 @@ if ((node = fdt_find_compatible(node, "mrvl,mpp", 0)) == 0) return (ENXIO); - moveon: /* * Process 'reg' prop. @@ -744,7 +742,7 @@ &start, &size); if (rv != 0) return (rv); - start += FDT_IMMR_VA; + start += fdt_immr_va; /* * Process 'pin-count' and 'pin-map' props. @@ -810,6 +808,87 @@ return (0); } +#define FDT_DEVMAP_MAX (1 + 2 + 1 + 1) +static struct pmap_devmap fdt_devmap[FDT_DEVMAP_MAX] = { + { 0, 0, 0, 0, 0, } +}; + +/* + * Construct pmap_devmap[] with DT-derived config data. + */ +static int +platform_devmap_init(void) +{ + phandle_t root, child; + u_long base, size; + int i; + + /* + * IMMR range. + */ + i = 0; + fdt_devmap[i].pd_va = fdt_immr_va; + fdt_devmap[i].pd_pa = fdt_immr_pa; + fdt_devmap[i].pd_size = fdt_immr_size; + fdt_devmap[i].pd_prot = VM_PROT_READ | VM_PROT_WRITE; + fdt_devmap[i].pd_cache = PTE_NOCACHE; + i++; + + /* + * PCI range(s). + */ + if ((root = OF_finddevice("/")) == 0) + return (ENXIO); + + for (child = OF_child(root); child != 0; child = OF_peer(child)) + if (fdt_is_type(child, "pci")) { + /* + * Check space: each PCI node will consume 2 devmap + * entries. + */ + if (i + 1 >= FDT_DEVMAP_MAX) { + return (ENOMEM); + break; + } + + /* + * XXX this should account for PCI and multiple ranges + * of a given kind. + */ + if (fdt_pci_devmap(child, &fdt_devmap[i], + MV_PCIE_IO_BASE, MV_PCIE_MEM_BASE) != 0) + return (ENXIO); + i += 2; + } + + /* + * CESA SRAM range. + */ + if ((child = OF_finddevice("sram")) != 0) + if (fdt_is_compatible(child, "mrvl,cesa-sram")) + goto moveon; + + if ((child = fdt_find_compatible(root, "mrvl,cesa-sram", 0)) == 0) + /* No CESA SRAM node. */ + goto out; +moveon: + if (i >= FDT_DEVMAP_MAX) + return (ENOMEM); + + if (fdt_regsize(child, &base, &size) != 0) + return (EINVAL); + + fdt_devmap[i].pd_va = MV_CESA_SRAM_BASE; /* XXX */ + fdt_devmap[i].pd_pa = base; + fdt_devmap[i].pd_size = size; + fdt_devmap[i].pd_prot = VM_PROT_READ | VM_PROT_WRITE; + fdt_devmap[i].pd_cache = PTE_NOCACHE; + +out: + pmap_devmap_bootstrap_table = &fdt_devmap[0]; + return (0); +} + struct arm32_dma_range * bus_dma_get_range(void) { ==== //depot/projects/fdt/sys/arm/mv/mv_pci.c#2 (text+ko) ==== @@ -1,9 +1,13 @@ /*- - * Copyright (C) 2008 MARVELL INTERNATIONAL LTD. + * Copyright (c) 2008 MARVELL INTERNATIONAL LTD. + * Copyright (c) 2010 The FreeBSD Foundation * All rights reserved. * * Developed by Semihalf. * + * Portions of this software were developed by Semihalf + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -51,10 +55,14 @@ #include #include +#include +#include +#include #include #include #include +#include "ofw_bus_if.h" #include "pcib_if.h" #include @@ -62,6 +70,7 @@ #include #include +#include #define PCI_CFG_ENA (1 << 31) #define PCI_CFG_BUS(bus) (((bus) & 0xff) << 16) @@ -93,18 +102,22 @@ #define PCI_VENDORID_MRVL 0x11AB -struct pcib_mbus_softc { +struct mv_pcib_softc { device_t sc_dev; - struct rman sc_iomem_rman; - bus_addr_t sc_iomem_base; - bus_addr_t sc_iomem_size; - bus_addr_t sc_iomem_alloc; /* Next allocation. */ + struct rman sc_mem_rman; + bus_addr_t sc_mem_base; + bus_addr_t sc_mem_size; + bus_addr_t sc_mem_alloc; /* Next allocation. */ + int sc_mem_win_target; + int sc_mem_win_attr; - struct rman sc_ioport_rman; - bus_addr_t sc_ioport_base; - bus_addr_t sc_ioport_size; - bus_addr_t sc_ioport_alloc; /* Next allocation. */ + struct rman sc_io_rman; + bus_addr_t sc_io_base; + bus_addr_t sc_io_size; + bus_addr_t sc_io_alloc; /* Next allocation. */ + int sc_io_win_target; + int sc_io_win_attr; struct resource *sc_res; bus_space_handle_t sc_bsh; @@ -113,452 +126,208 @@ int sc_busnr; /* Host bridge bus number */ int sc_devnr; /* Host bridge device number */ + int sc_type; - const struct obio_pci *sc_info; + struct fdt_pci_intr sc_intr_info; }; -static void pcib_mbus_identify(driver_t *driver, device_t parent); -static int pcib_mbus_probe(device_t); -static int pcib_mbus_attach(device_t); +/* Local forward prototypes */ +static int mv_pcib_decode_win(phandle_t, struct mv_pcib_softc *); +static void mv_pcib_hw_cfginit(void); +static uint32_t mv_pcib_hw_cfgread(struct mv_pcib_softc *, u_int, u_int, + u_int, u_int, int); +static void mv_pcib_hw_cfgwrite(struct mv_pcib_softc *, u_int, u_int, + u_int, u_int, uint32_t, int); +static int mv_pcib_init(struct mv_pcib_softc *, int, int); +static int mv_pcib_init_all_bars(struct mv_pcib_softc *, int, int, int, int); +static void mv_pcib_init_bridge(struct mv_pcib_softc *, int, int, int); +static int mv_pcib_intr_info(phandle_t, struct mv_pcib_softc *); +static inline void pcib_write_irq_mask(struct mv_pcib_softc *, uint32_t); + + +/* Forward prototypes */ +static int mv_pcib_probe(device_t); +static int mv_pcib_attach(device_t); -static struct resource *pcib_mbus_alloc_resource(device_t, device_t, int, int *, +static struct resource *mv_pcib_alloc_resource(device_t, device_t, int, int *, u_long, u_long, u_long, u_int); -static int pcib_mbus_release_resource(device_t, device_t, int, int, +static int mv_pcib_release_resource(device_t, device_t, int, int, struct resource *); -static int pcib_mbus_read_ivar(device_t, device_t, int, uintptr_t *); -static int pcib_mbus_write_ivar(device_t, device_t, int, uintptr_t); +static int mv_pcib_read_ivar(device_t, device_t, int, uintptr_t *); +static int mv_pcib_write_ivar(device_t, device_t, int, uintptr_t); -static int pcib_mbus_maxslots(device_t); -static uint32_t pcib_mbus_read_config(device_t, u_int, u_int, u_int, u_int, - int); -static void pcib_mbus_write_config(device_t, u_int, u_int, u_int, u_int, +static int mv_pcib_maxslots(device_t); +static uint32_t mv_pcib_read_config(device_t, u_int, u_int, u_int, u_int, int); +static void mv_pcib_write_config(device_t, u_int, u_int, u_int, u_int, uint32_t, int); -static int pcib_mbus_init(struct pcib_mbus_softc *sc, int bus, int maxslot); -static int pcib_mbus_init_bar(struct pcib_mbus_softc *sc, int bus, int slot, - int func, int barno); -static void pcib_mbus_init_bridge(struct pcib_mbus_softc *sc, int bus, int slot, - int func); -static int pcib_mbus_init_resources(struct pcib_mbus_softc *sc, int bus, - int slot, int func, int hdrtype); +static int mv_pcib_route_interrupt(device_t, device_t, int); /* * Bus interface definitions. */ -static device_method_t pcib_mbus_methods[] = { +static device_method_t mv_pcib_methods[] = { /* Device interface */ - DEVMETHOD(device_identify, pcib_mbus_identify), - DEVMETHOD(device_probe, pcib_mbus_probe), - DEVMETHOD(device_attach, pcib_mbus_attach), + DEVMETHOD(device_probe, mv_pcib_probe), + DEVMETHOD(device_attach, mv_pcib_attach), /* Bus interface */ DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_read_ivar, pcib_mbus_read_ivar), - DEVMETHOD(bus_write_ivar, pcib_mbus_write_ivar), - DEVMETHOD(bus_alloc_resource, pcib_mbus_alloc_resource), - DEVMETHOD(bus_release_resource, pcib_mbus_release_resource), + DEVMETHOD(bus_read_ivar, mv_pcib_read_ivar), + DEVMETHOD(bus_write_ivar, mv_pcib_write_ivar), + DEVMETHOD(bus_alloc_resource, mv_pcib_alloc_resource), + DEVMETHOD(bus_release_resource, mv_pcib_release_resource), DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), /* pcib interface */ - DEVMETHOD(pcib_maxslots, pcib_mbus_maxslots), - DEVMETHOD(pcib_read_config, pcib_mbus_read_config), - DEVMETHOD(pcib_write_config, pcib_mbus_write_config), - DEVMETHOD(pcib_route_interrupt, pcib_route_interrupt), + DEVMETHOD(pcib_maxslots, mv_pcib_maxslots), + DEVMETHOD(pcib_read_config, mv_pcib_read_config), + DEVMETHOD(pcib_write_config, mv_pcib_write_config), + DEVMETHOD(pcib_route_interrupt, mv_pcib_route_interrupt), + + /* OFW bus interface */ + DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), + DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), + DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), + DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), + DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), { 0, 0 } }; -static driver_t pcib_mbus_driver = { +static driver_t mv_pcib_driver = { "pcib", - pcib_mbus_methods, - sizeof(struct pcib_mbus_softc), + mv_pcib_methods, + sizeof(struct mv_pcib_softc), }; devclass_t pcib_devclass; -DRIVER_MODULE(pcib, mbus, pcib_mbus_driver, pcib_devclass, 0, 0); +DRIVER_MODULE(pcib, fdtbus, mv_pcib_driver, pcib_devclass, 0, 0); static struct mtx pcicfg_mtx; -static inline void -pcib_write_irq_mask(struct pcib_mbus_softc *sc, uint32_t mask) -{ - - if (!sc->sc_info->op_type != MV_TYPE_PCI) - return; - - bus_space_write_4(sc->sc_bst, sc->sc_bsh, - PCIE_REG_IRQ_MASK, mask); -} - -static void -pcib_mbus_hw_cfginit(void) -{ - static int opened = 0; - - if (opened) - return; - - mtx_init(&pcicfg_mtx, "pcicfg", NULL, MTX_SPIN); - opened = 1; -} - -static uint32_t -pcib_mbus_hw_cfgread(struct pcib_mbus_softc *sc, u_int bus, u_int slot, - u_int func, u_int reg, int bytes) -{ - uint32_t addr, data, ca, cd; - - ca = (sc->sc_info->op_type != MV_TYPE_PCI) ? - PCIE_REG_CFG_ADDR : PCI_REG_CFG_ADDR; - cd = (sc->sc_info->op_type != MV_TYPE_PCI) ? - PCIE_REG_CFG_DATA : PCI_REG_CFG_DATA; - addr = PCI_CFG_ENA | PCI_CFG_BUS(bus) | PCI_CFG_DEV(slot) | - PCI_CFG_FUN(func) | PCI_CFG_PCIE_REG(reg); - - mtx_lock_spin(&pcicfg_mtx); - bus_space_write_4(sc->sc_bst, sc->sc_bsh, ca, addr); - - data = ~0; - switch (bytes) { - case 1: - data = bus_space_read_1(sc->sc_bst, sc->sc_bsh, - cd + (reg & 3)); - break; - case 2: - data = le16toh(bus_space_read_2(sc->sc_bst, sc->sc_bsh, - cd + (reg & 2))); - break; - case 4: - data = le32toh(bus_space_read_4(sc->sc_bst, sc->sc_bsh, - cd)); - break; - } - mtx_unlock_spin(&pcicfg_mtx); - return (data); -} - -static void -pcib_mbus_hw_cfgwrite(struct pcib_mbus_softc *sc, u_int bus, u_int slot, - u_int func, u_int reg, uint32_t data, int bytes) -{ - uint32_t addr, ca, cd; - - ca = (sc->sc_info->op_type != MV_TYPE_PCI) ? - PCIE_REG_CFG_ADDR : PCI_REG_CFG_ADDR; - cd = (sc->sc_info->op_type != MV_TYPE_PCI) ? - PCIE_REG_CFG_DATA : PCI_REG_CFG_DATA; - addr = PCI_CFG_ENA | PCI_CFG_BUS(bus) | PCI_CFG_DEV(slot) | - PCI_CFG_FUN(func) | PCI_CFG_PCIE_REG(reg); - - mtx_lock_spin(&pcicfg_mtx); - bus_space_write_4(sc->sc_bst, sc->sc_bsh, ca, addr); - - switch (bytes) { - case 1: - bus_space_write_1(sc->sc_bst, sc->sc_bsh, - cd + (reg & 3), data); - break; - case 2: - bus_space_write_2(sc->sc_bst, sc->sc_bsh, - cd + (reg & 2), htole16(data)); - break; - case 4: - bus_space_write_4(sc->sc_bst, sc->sc_bsh, - cd, htole32(data)); - break; - } - mtx_unlock_spin(&pcicfg_mtx); -} - static int -pcib_mbus_maxslots(device_t dev) +mv_pcib_probe(device_t self) { - struct pcib_mbus_softc *sc = device_get_softc(dev); + phandle_t parnode; - return ((sc->sc_info->op_type != MV_TYPE_PCI) ? 1 : PCI_SLOTMAX); -} + /* + * The PCI subnode does not have the 'compatible' property, so we need + * to check in the parent PCI node. However the parent is not + * represented by a separate ofw_bus child, and therefore + * ofw_bus_is_compatible() cannot be used, but direct fdt equivalent. + */ + parnode = OF_parent(ofw_bus_get_node(self)); + if (parnode == 0) + return (ENXIO); + if (!(fdt_is_compatible(parnode, "mrvl,pcie") || + fdt_is_compatible(parnode, "mrvl,pci"))) + return (ENXIO); -static uint32_t -pcib_mbus_read_config(device_t dev, u_int bus, u_int slot, u_int func, - u_int reg, int bytes) -{ - struct pcib_mbus_softc *sc = device_get_softc(dev); + device_set_desc(self, "Marvell Integrated PCI/PCI-E Controller"); - /* Skip self */ - if (bus == sc->sc_busnr && slot == sc->sc_devnr) - return (~0U); - - return (pcib_mbus_hw_cfgread(sc, bus, slot, func, reg, bytes)); -} - -static void -pcib_mbus_write_config(device_t dev, u_int bus, u_int slot, u_int func, - u_int reg, uint32_t val, int bytes) -{ - struct pcib_mbus_softc *sc = device_get_softc(dev); - - /* Skip self */ - if (bus == sc->sc_busnr && slot == sc->sc_devnr) - return; - - pcib_mbus_hw_cfgwrite(sc, bus, slot, func, reg, val, bytes); -} - -static void -pcib_mbus_add_child(driver_t *driver, device_t parent, struct pcib_mbus_softc *sc) -{ - device_t child; - int error; - - /* Configure CPU decoding windows */ - error = decode_win_cpu_set(sc->sc_info->op_io_win_target, - sc->sc_info->op_io_win_attr, sc->sc_info->op_io_base, - sc->sc_info->op_io_size, -1); - if (error < 0) { - device_printf(parent, "Could not set up CPU decode " - "window for PCI IO\n"); - return; - } - error = decode_win_cpu_set(sc->sc_info->op_mem_win_target, - sc->sc_info->op_mem_win_attr, sc->sc_info->op_mem_base, - sc->sc_info->op_mem_size, -1); - if (error < 0) { - device_printf(parent, "Could not set up CPU decode " - "windows for PCI MEM\n"); - return; - } - - /* Create driver instance */ - child = BUS_ADD_CHILD(parent, 0, driver->name, -1); - bus_set_resource(child, SYS_RES_MEMORY, 0, - sc->sc_info->op_base, sc->sc_info->op_size); - device_set_softc(child, sc); -} - -static void -pcib_mbus_identify(driver_t *driver, device_t parent) -{ - const struct obio_pci *info = mv_pci_info; - struct pcib_mbus_softc *sc; - uint32_t control; - - while (info->op_base) { - sc = malloc(driver->size, M_DEVBUF, M_NOWAIT | M_ZERO); - if (sc == NULL) { - device_printf(parent, "Could not allocate pcib " - "memory\n"); - break; - } - sc->sc_info = info++; - - /* - * PCI bridge objects are instantiated immediately. PCI-Express - * bridges require more complicated handling depending on - * platform configuration. - */ - if (sc->sc_info->op_type == MV_TYPE_PCI) { - pcib_mbus_add_child(driver, parent, sc); - continue; - } - - /* - * Read link configuration - */ - sc->sc_rid = 0; - sc->sc_res = BUS_ALLOC_RESOURCE(parent, parent, SYS_RES_MEMORY, - &sc->sc_rid, sc->sc_info->op_base, sc->sc_info->op_base + - sc->sc_info->op_size - 1, sc->sc_info->op_size, - RF_ACTIVE); - if (sc->sc_res == NULL) { - device_printf(parent, "Could not map pcib memory\n"); - break; - } - - sc->sc_bst = rman_get_bustag(sc->sc_res); - sc->sc_bsh = rman_get_bushandle(sc->sc_res); - - control = bus_space_read_4(sc->sc_bst, sc->sc_bsh, - PCIE_REG_CONTROL); - - BUS_RELEASE_RESOURCE(parent, parent, SYS_RES_MEMORY, sc->sc_rid, - sc->sc_res); - - /* - * If this PCI-E port (controller) is configured (by the - * underlying firmware) with lane width other than 1x, there - * are auxiliary resources defined for aggregating more width - * on our lane. Skip all such entries as they are not - * standalone ports and must not have a device object - * instantiated. - */ - if ((control & PCIE_CTRL_LINK1X) == 0) - while (info->op_base && - info->op_type == MV_TYPE_PCIE_AGGR_LANE) - info++; - - pcib_mbus_add_child(driver, parent, sc); - } + return (BUS_PROBE_DEFAULT); } static int >>> TRUNCATED FOR MAIL (1000 lines) <<<