PERFORCE change 176348 for review
Rafal Jaworowski
raj at FreeBSD.org
Wed Mar 31 08:40:03 UTC 2010
http://p4web.freebsd.org/chv.cgi?CH=176348
Change 176348 by raj at 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 <dev/ofw/openfirm.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/pmap.h>
#include <machine/intr.h>
#include <arm/mv/mvvar.h>
@@ -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 <arm/mv/mvvar.h>
#include <arm/mv/mvwin.h>
-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 <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/arm/mv/kirkwood/sheevaplug.c,v 1.1 2009/08/25 10:09:25 raj Exp $");
+__FBSDID("$FreeBSD$");
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
-#include <vm/vm.h>
-#include <vm/pmap.h>
+#include <machine/fdt.h>
-#include <machine/bus.h>
-#include <machine/pte.h>
-#include <machine/pmap.h>
-#include <machine/vmparam.h>
-
-#include <arm/mv/mvreg.h>
-#include <arm/mv/mvvar.h>
-#include <arm/mv/mvwin.h>
-
-/*
- * 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 <vm/vm.h>
#include <vm/pmap.h>
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcib_private.h>
+#include "ofw_bus_if.h"
#include "pcib_if.h"
#include <machine/resource.h>
@@ -62,6 +70,7 @@
#include <arm/mv/mvreg.h>
#include <arm/mv/mvvar.h>
+#include <arm/mv/mvwin.h>
#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) <<<
More information about the p4-projects
mailing list