Module Name: src Committed By: jmcneill Date: Thu Jul 16 11:49:38 UTC 2020
Modified Files: src/sys/arch/evbmips/cavium: machdep.c src/sys/arch/evbmips/conf: OCTEON src/sys/arch/mips/cavium: mainbus.c src/sys/arch/mips/cavium/dev: octeon_pip.c octeon_smi.c src/sys/arch/mips/conf: files.octeon Added Files: src/sys/arch/mips/cavium/dev: octeon_intc.c src/sys/arch/mips/fdt: fdt_dma_machdep.c Log Message: FDT support for Cavium OCTEON MIPS SoCs. WIP. To generate a diff of this commit: cvs rdiff -u -r1.17 -r1.18 src/sys/arch/evbmips/cavium/machdep.c cvs rdiff -u -r1.1 -r1.2 src/sys/arch/evbmips/conf/OCTEON cvs rdiff -u -r1.1 -r1.2 src/sys/arch/mips/cavium/mainbus.c cvs rdiff -u -r0 -r1.1 src/sys/arch/mips/cavium/dev/octeon_intc.c cvs rdiff -u -r1.8 -r1.9 src/sys/arch/mips/cavium/dev/octeon_pip.c cvs rdiff -u -r1.5 -r1.6 src/sys/arch/mips/cavium/dev/octeon_smi.c cvs rdiff -u -r1.9 -r1.10 src/sys/arch/mips/conf/files.octeon cvs rdiff -u -r0 -r1.1 src/sys/arch/mips/fdt/fdt_dma_machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/evbmips/cavium/machdep.c diff -u src/sys/arch/evbmips/cavium/machdep.c:1.17 src/sys/arch/evbmips/cavium/machdep.c:1.18 --- src/sys/arch/evbmips/cavium/machdep.c:1.17 Mon Jul 13 05:20:45 2020 +++ src/sys/arch/evbmips/cavium/machdep.c Thu Jul 16 11:49:37 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.17 2020/07/13 05:20:45 simonb Exp $ */ +/* $NetBSD: machdep.c,v 1.18 2020/07/16 11:49:37 jmcneill Exp $ */ /* * Copyright 2001, 2002 Wasabi Systems, Inc. @@ -114,7 +114,7 @@ #include "opt_multiprocessor.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.17 2020/07/13 05:20:45 simonb Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.18 2020/07/16 11:49:37 jmcneill Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -153,6 +153,8 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v #include <evbmips/cavium/octeon_uboot.h> +#include <dev/fdt/fdtvar.h> + static void mach_init_vector(void); static void mach_init_bus_space(void); static void mach_init_console(void); @@ -192,6 +194,7 @@ void mach_init(uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3) { uint64_t btinfo_paddr; + void *fdt_data; /* clear the BSS segment */ memset(edata, 0, end - edata); @@ -219,6 +222,13 @@ mach_init(uint64_t arg0, uint64_t arg1, cpu_setmodel("Cavium Octeon %s", octeon_cpu_model(mips_options.mips_cpu_id)); + if (octeon_btinfo.obt_minor_version >= 3 && + octeon_btinfo.obt_fdt_addr != 0) { + fdt_data = (void *)MIPS_PHYS_TO_XKPHYS(CCA_CACHEABLE, + octeon_btinfo.obt_fdt_addr); + fdtbus_init(fdt_data); + } + mach_init_vector(); uvm_md_init(); Index: src/sys/arch/evbmips/conf/OCTEON diff -u src/sys/arch/evbmips/conf/OCTEON:1.1 src/sys/arch/evbmips/conf/OCTEON:1.2 --- src/sys/arch/evbmips/conf/OCTEON:1.1 Wed Jul 15 12:15:30 2020 +++ src/sys/arch/evbmips/conf/OCTEON Thu Jul 16 11:49:37 2020 @@ -1,14 +1,16 @@ -# $NetBSD: OCTEON,v 1.1 2020/07/15 12:15:30 simonb Exp $ +# $NetBSD: OCTEON,v 1.2 2020/07/16 11:49:37 jmcneill Exp $ include "arch/mips/conf/std.octeon" include "arch/evbmips/conf/files.octeon" #options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "ERLITE-$Revision: 1.1 $" +#ident "ERLITE-$Revision: 1.2 $" maxusers 32 +options FDT + # Options for necessary to use MD #options MEMORY_DISK_HOOKS #options MEMORY_DISK_IS_ROOT # force root on memory disk @@ -113,11 +115,17 @@ wdog0 at cpunode0 flags 0 # flags 1 wi iobus0 at mainbus? bootbus0 at mainbus? +simplebus* at fdt? pass 0 + +octintc* at fdt? pass 1 com* at iobus? +com* at fdt? octsmi* at iobus? # MDIO controller +octsmi* at fdt? pass 2 octpip* at iobus? # PIP packet processing controller +octpip* at fdt? pass 3 octgmx* at octpip? cnmac* at octgmx? Index: src/sys/arch/mips/cavium/mainbus.c diff -u src/sys/arch/mips/cavium/mainbus.c:1.1 src/sys/arch/mips/cavium/mainbus.c:1.2 --- src/sys/arch/mips/cavium/mainbus.c:1.1 Wed Apr 29 08:32:00 2015 +++ src/sys/arch/mips/cavium/mainbus.c Thu Jul 16 11:49:37 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: mainbus.c,v 1.1 2015/04/29 08:32:00 hikaru Exp $ */ +/* $NetBSD: mainbus.c,v 1.2 2020/07/16 11:49:37 jmcneill Exp $ */ /* * Copyright (c) 2007 @@ -27,22 +27,43 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.1 2015/04/29 08:32:00 hikaru Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.2 2020/07/16 11:49:37 jmcneill Exp $"); + +#define _MIPS_BUS_DMA_PRIVATE #include <sys/param.h> #include <sys/systm.h> #include <sys/device.h> +#include <sys/bus.h> #include <mips/cavium/include/mainbusvar.h> +#include <dev/fdt/fdtvar.h> + static int mainbus_match(device_t, struct cfdata *, void *); static void mainbus_attach(device_t, device_t, void *); +static void mainbus_attach_static(device_t); +static void mainbus_attach_devicetree(device_t); static int mainbus_submatch(device_t, cfdata_t, const int *, void *); static int mainbus_print(void *, const char *); +static void simplebus_bus_io_init(bus_space_tag_t, void *); + CFATTACH_DECL_NEW(mainbus, sizeof(device_t), mainbus_match, mainbus_attach, NULL, NULL); +static struct mips_bus_space simplebus_bus_tag; + +static struct mips_bus_dma_tag simplebus_dma_tag = { + ._cookie = NULL, + ._wbase = 0, + ._bounce_alloc_lo = 0, + ._bounce_alloc_hi = 0, + ._dmamap_ops = _BUS_DMAMAP_OPS_INITIALIZER, + ._dmamem_ops = _BUS_DMAMEM_OPS_INITIALIZER, + ._dmatag_ops = _BUS_DMATAG_OPS_INITIALIZER, +}; + static int mainbus_match(device_t parent, struct cfdata *match, void *aux) { @@ -58,18 +79,55 @@ mainbus_match(device_t parent, struct cf static void mainbus_attach(device_t parent, device_t self, void *aux) { - int i; - struct mainbus_attach_args aa; - aprint_normal("\n"); + if (fdtbus_get_data() != NULL) { + mainbus_attach_devicetree(self); + } else { + mainbus_attach_static(self); + } +} + +static void +mainbus_attach_static(device_t self) +{ + struct mainbus_attach_args aa; + int i; + for (i = 0; i < (int)mainbus_ndevs; i++) { aa.aa_name = mainbus_devs[i]; - (void)config_found_sm_loc(self, "mainbus", NULL, &aa, + config_found_sm_loc(self, "mainbus", NULL, &aa, mainbus_print, mainbus_submatch); } } +extern struct octeon_config octeon_configuration; +extern void octpow_bootstrap(struct octeon_config *); +extern void octfpa_bootstrap(struct octeon_config *); + +static void +mainbus_attach_devicetree(device_t self) +{ + struct mainbus_attach_args aa; + struct fdt_attach_args faa; + + aa.aa_name = "cpunode"; + config_found_sm_loc(self, "mainbus", NULL, &aa, mainbus_print, + mainbus_submatch); + + octpow_bootstrap(&octeon_configuration); + octfpa_bootstrap(&octeon_configuration); + + simplebus_bus_io_init(&simplebus_bus_tag, NULL); + + faa.faa_bst = &simplebus_bus_tag; + faa.faa_a4x_bst = NULL; /* XXX */ + faa.faa_dmat = &simplebus_dma_tag; + faa.faa_name = ""; + faa.faa_phandle = OF_peer(0); + config_found(self, &faa, NULL); +} + static int mainbus_submatch(device_t parent, cfdata_t cf, const int *locs, void *aux) { @@ -94,3 +152,15 @@ mainbus_print(void *aux, const char *pnp return UNCONF; } + +/* ---- bus_space(9) */ +#define CHIP simplebus +#define CHIP_IO +#define CHIP_ACCESS_SIZE 8 + +#define CHIP_W1_BUS_START(v) 0x0000000000000000ULL +#define CHIP_W1_BUS_END(v) 0x7fffffffffffffffULL +#define CHIP_W1_SYS_START(v) 0x8000000000000000ULL +#define CHIP_W1_SYS_END(v) 0xffffffffffffffffULL + +#include <mips/mips/bus_space_alignstride_chipdep.c> Index: src/sys/arch/mips/cavium/dev/octeon_pip.c diff -u src/sys/arch/mips/cavium/dev/octeon_pip.c:1.8 src/sys/arch/mips/cavium/dev/octeon_pip.c:1.9 --- src/sys/arch/mips/cavium/dev/octeon_pip.c:1.8 Tue Jun 23 05:18:02 2020 +++ src/sys/arch/mips/cavium/dev/octeon_pip.c Thu Jul 16 11:49:37 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: octeon_pip.c,v 1.8 2020/06/23 05:18:02 simonb Exp $ */ +/* $NetBSD: octeon_pip.c,v 1.9 2020/07/16 11:49:37 jmcneill Exp $ */ /* * Copyright (c) 2007 Internet Initiative Japan, Inc. @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: octeon_pip.c,v 1.8 2020/06/23 05:18:02 simonb Exp $"); +__KERNEL_RCSID(0, "$NetBSD: octeon_pip.c,v 1.9 2020/07/16 11:49:37 jmcneill Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -44,14 +44,32 @@ __KERNEL_RCSID(0, "$NetBSD: octeon_pip.c #include <mips/cavium/dev/octeon_pipvar.h> #include <mips/cavium/include/iobusvar.h> -static int octpip_match(device_t, struct cfdata *, void *); -static void octpip_attach(device_t, device_t, void *); +#include <dev/fdt/fdtvar.h> -CFATTACH_DECL_NEW(octpip, sizeof(struct octpip_softc), - octpip_match, octpip_attach, NULL, NULL); +static int octpip_iobus_match(device_t, struct cfdata *, void *); +static void octpip_iobus_attach(device_t, device_t, void *); + +static int octpip_fdt_match(device_t, struct cfdata *, void *); +static void octpip_fdt_attach(device_t, device_t, void *); + +CFATTACH_DECL_NEW(octpip_iobus, sizeof(struct octpip_softc), + octpip_iobus_match, octpip_iobus_attach, NULL, NULL); + +CFATTACH_DECL_NEW(octpip_fdt, sizeof(struct octpip_softc), + octpip_fdt_match, octpip_fdt_attach, NULL, NULL); + +static const char * compatible[] = { + "cavium,octeon-3860-pip", + NULL +}; + +static const char * pip_interface_compatible[] = { + "cavium,octeon-3860-pip-interface", + NULL +}; static int -octpip_match(device_t parent, struct cfdata *cf, void *aux) +octpip_iobus_match(device_t parent, struct cfdata *cf, void *aux) { struct iobus_attach_args *aa = aux; @@ -61,7 +79,7 @@ octpip_match(device_t parent, struct cfd } static void -octpip_attach(device_t parent, device_t self, void *aux) +octpip_iobus_attach(device_t parent, device_t self, void *aux) { struct octpip_softc *sc = device_private(self); struct iobus_attach_args *aa = aux; @@ -98,6 +116,60 @@ octpip_attach(device_t parent, device_t } } +static int +octpip_fdt_match(device_t parent, struct cfdata *cf, void *aux) +{ + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +octpip_fdt_attach(device_t parent, device_t self, void *aux) +{ + struct octpip_softc *sc = device_private(self); + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; + struct iobus_attach_args gmxaa; + struct iobus_unit gmxiu; + bus_addr_t intno; + int child; + + sc->sc_dev = self; + + aprint_normal("\n"); + + for (child = OF_child(phandle); child; child = OF_peer(child)) { + if (!of_match_compatible(child, pip_interface_compatible)) + continue; + + if (fdtbus_get_reg(child, 0, &intno, NULL) != 0) { + aprint_error_dev(self, "couldn't get interface number for %s\n", + fdtbus_get_string(child, "name")); + continue; + } + + memset(&gmxaa, 0, sizeof(gmxaa)); + memset(&gmxiu, 0, sizeof(gmxiu)); + + gmxaa.aa_name = "octgmx"; + gmxaa.aa_unitno = (int)intno; + gmxaa.aa_unit = &gmxiu; + gmxaa.aa_bust = faa->faa_bst; + gmxaa.aa_dmat = faa->faa_dmat; + + if (MIPS_PRID_IMPL(mips_options.mips_cpu_id) == MIPS_CN68XX) + gmxiu.addr = GMX_CN68XX_BASE_PORT(intno, 0); + else + gmxiu.addr = GMX_BASE_PORT(intno, 0); + + config_found(self, &gmxaa, NULL); + + /* XXX only one interface supported by octgmx */ + return; + } +} + /* XXX */ void octpip_init(struct octpip_attach_args *aa, struct octpip_softc **rsc) Index: src/sys/arch/mips/cavium/dev/octeon_smi.c diff -u src/sys/arch/mips/cavium/dev/octeon_smi.c:1.5 src/sys/arch/mips/cavium/dev/octeon_smi.c:1.6 --- src/sys/arch/mips/cavium/dev/octeon_smi.c:1.5 Tue Jun 23 05:18:02 2020 +++ src/sys/arch/mips/cavium/dev/octeon_smi.c Thu Jul 16 11:49:37 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: octeon_smi.c,v 1.5 2020/06/23 05:18:02 simonb Exp $ */ +/* $NetBSD: octeon_smi.c,v 1.6 2020/07/16 11:49:37 jmcneill Exp $ */ /* * Copyright (c) 2007 Internet Initiative Japan, Inc. @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: octeon_smi.c,v 1.5 2020/06/23 05:18:02 simonb Exp $"); +__KERNEL_RCSID(0, "$NetBSD: octeon_smi.c,v 1.6 2020/07/16 11:49:37 jmcneill Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -35,6 +35,8 @@ __KERNEL_RCSID(0, "$NetBSD: octeon_smi.c #include <sys/device.h> #include <sys/malloc.h> #include <sys/mbuf.h> +#include <sys/queue.h> +#include <sys/kmem.h> #include <mips/locore.h> #include <mips/cavium/octeonvar.h> @@ -45,6 +47,8 @@ __KERNEL_RCSID(0, "$NetBSD: octeon_smi.c #include <mips/cavium/dev/octeon_smivar.h> #include <mips/cavium/include/iobusvar.h> +#include <dev/fdt/fdtvar.h> + /* * System Management Interface * @@ -67,21 +71,41 @@ __KERNEL_RCSID(0, "$NetBSD: octeon_smi.c * CNF75XX - 2 SMI interfaces */ -static int octsmi_match(device_t, struct cfdata *, void *); -static void octsmi_attach(device_t, device_t, void *); +static int octsmi_iobus_match(device_t, struct cfdata *, void *); +static void octsmi_iobus_attach(device_t, device_t, void *); + +static int octsmi_fdt_match(device_t, struct cfdata *, void *); +static void octsmi_fdt_attach(device_t, device_t, void *); + +static void octsmi_attach_common(struct octsmi_softc *, int); -struct octsmi_softc *smi_list; /* XXX up to 4 SMIs on CN68XX,CN78XX */ +struct octsmi_instance { + struct octsmi_softc * sc; + int phandle; + TAILQ_ENTRY(octsmi_instance) next; +}; + +static TAILQ_HEAD(, octsmi_instance) octsmi_instances = + TAILQ_HEAD_INITIALIZER(octsmi_instances); #define _SMI_RD8(sc, off) \ bus_space_read_8((sc)->sc_regt, (sc)->sc_regh, (off)) #define _SMI_WR8(sc, off, v) \ bus_space_write_8((sc)->sc_regt, (sc)->sc_regh, (off), (v)) -CFATTACH_DECL_NEW(octsmi, sizeof(struct octsmi_softc), - octsmi_match, octsmi_attach, NULL, NULL); +CFATTACH_DECL_NEW(octsmi_iobus, sizeof(struct octsmi_softc), + octsmi_iobus_match, octsmi_iobus_attach, NULL, NULL); + +CFATTACH_DECL_NEW(octsmi_fdt, sizeof(struct octsmi_softc), + octsmi_fdt_match, octsmi_fdt_attach, NULL, NULL); + +static const char * compatible[] = { + "cavium,octeon-3860-mdio", + NULL +}; static int -octsmi_match(device_t parent, struct cfdata *cf, void *aux) +octsmi_iobus_match(device_t parent, struct cfdata *cf, void *aux) { struct iobus_attach_args *aa = aux; @@ -94,7 +118,7 @@ octsmi_match(device_t parent, struct cfd } static void -octsmi_attach(device_t parent, device_t self, void *aux) +octsmi_iobus_attach(device_t parent, device_t self, void *aux) { struct octsmi_softc *sc = device_private(self); struct iobus_attach_args *aa = aux; @@ -112,7 +136,53 @@ octsmi_attach(device_t parent, device_t return; } - smi_list = sc; + octsmi_attach_common(sc, 0); +} + +static int +octsmi_fdt_match(device_t parent, struct cfdata *cf, void *aux) +{ + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +octsmi_fdt_attach(device_t parent, device_t self, void *aux) +{ + struct octsmi_softc *sc = device_private(self); + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; + bus_addr_t addr; + bus_size_t size; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get registers\n"); + return; + } + + sc->sc_dev = self; + sc->sc_regt = faa->faa_bst; + + if (bus_space_map(sc->sc_regt, addr, size, 0, &sc->sc_regh) != 0) { + aprint_error(": couldn't map registers\n"); + return; + } + + aprint_normal("\n"); + + octsmi_attach_common(sc, phandle); +} + +static void +octsmi_attach_common(struct octsmi_softc *sc, int phandle) +{ + struct octsmi_instance *oi; + + oi = kmem_alloc(sizeof(*oi), KM_SLEEP); + oi->sc = sc; + oi->phandle = phandle; + TAILQ_INSERT_TAIL(&octsmi_instances, oi, next); const uint64_t magic_value = SMI_CLK_PREAMBLE | @@ -186,10 +256,17 @@ octsmi_write(struct octsmi_softc *sc, in struct octsmi_softc * octsmi_lookup(int phandle, int port) { - struct octsmi_softc *smi; + struct octsmi_instance *oi; - /* XXX deal with more than one SMI ... */ - smi = smi_list; +#if notyet + TAILQ_FOREACH(oi, &octsmi_instances, list) { + if (oi->phandle == phandle) + return oi->sc; + } - return smi; + return NULL; +#else + oi = TAILQ_FIRST(&octsmi_instances); + return oi == NULL ? NULL : oi->sc; +#endif } Index: src/sys/arch/mips/conf/files.octeon diff -u src/sys/arch/mips/conf/files.octeon:1.9 src/sys/arch/mips/conf/files.octeon:1.10 --- src/sys/arch/mips/conf/files.octeon:1.9 Wed Jun 24 12:43:40 2020 +++ src/sys/arch/mips/conf/files.octeon Thu Jul 16 11:49:38 2020 @@ -1,4 +1,4 @@ -# $NetBSD: files.octeon,v 1.9 2020/06/24 12:43:40 simonb Exp $ +# $NetBSD: files.octeon,v 1.10 2020/07/16 11:49:38 jmcneill Exp $ file arch/mips/mips/locore_octeon.S file arch/mips/mips/bus_dma.c @@ -9,7 +9,9 @@ file arch/mips/cavium/octeon_dma.c file arch/mips/cavium/octeon_intr.c file arch/mips/cavium/octeon_misc.c -device mainbus {} +file arch/mips/fdt/fdt_dma_machdep.c + +device mainbus {}: fdt attach mainbus at root file arch/mips/cavium/mainbus.c mainbus file arch/mips/cavium/mainbus_octeon1p.c mainbus @@ -25,6 +27,11 @@ attach wdog at cpunode with wdog_cpunode file arch/mips/cavium/octeon_cpunode.c cpunode | cpu | wdog needs-flag +# FDT +device octintc +attach octintc at fdt +file arch/mips/cavium/dev/octeon_intc.c octintc + # I/O Bus device iobus {} @@ -70,12 +77,14 @@ attach octciu at iobus file arch/mips/cavium/dev/octeon_ciu.c octciu device octsmi {} -attach octsmi at iobus -file arch/mips/cavium/dev/octeon_smi.c octsmi +attach octsmi at iobus with octsmi_iobus +attach octsmi at fdt with octsmi_fdt +file arch/mips/cavium/dev/octeon_smi.c octsmi_iobus | octsmi_fdt device octpip {} -attach octpip at iobus -file arch/mips/cavium/dev/octeon_pip.c octpip +attach octpip at iobus with octpip_iobus +attach octpip at fdt with octpip_fdt +file arch/mips/cavium/dev/octeon_pip.c octpip_iobus | octpip_fdt device octgmx {} attach octgmx at octpip Added files: Index: src/sys/arch/mips/cavium/dev/octeon_intc.c diff -u /dev/null src/sys/arch/mips/cavium/dev/octeon_intc.c:1.1 --- /dev/null Thu Jul 16 11:49:38 2020 +++ src/sys/arch/mips/cavium/dev/octeon_intc.c Thu Jul 16 11:49:37 2020 @@ -0,0 +1,158 @@ +/* $NetBSD: octeon_intc.c,v 1.1 2020/07/16 11:49:37 jmcneill Exp $ */ + +/*- + * Copyright (c) 2020 Jared D. McNeill <jmcne...@invisible.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: octeon_intc.c,v 1.1 2020/07/16 11:49:37 jmcneill Exp $"); + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/device.h> +#include <sys/intr.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/kmem.h> + +#include <dev/fdt/fdtvar.h> + +#include <arch/mips/cavium/octeonvar.h> + +static int octeon_intc_match(device_t, cfdata_t, void *); +static void octeon_intc_attach(device_t, device_t, void *); + +static void * octeon_intc_establish(device_t, u_int *, int, int, + int (*)(void *), void *); +static void octeon_intc_disestablish(device_t, void *); +static bool octeon_intc_intrstr(device_t, u_int *, char *, size_t); + +struct fdtbus_interrupt_controller_func octeon_intc_funcs = { + .establish = octeon_intc_establish, + .disestablish = octeon_intc_disestablish, + .intrstr = octeon_intc_intrstr +}; + +enum octeon_intc_type { + OCTEON_INTC_CIU, +}; + +struct octeon_intc_softc { + device_t sc_dev; + int sc_phandle; + enum octeon_intc_type sc_type; + const char *sc_descr; +}; + +CFATTACH_DECL_NEW(octintc, sizeof(struct octeon_intc_softc), + octeon_intc_match, octeon_intc_attach, NULL, NULL); + +static const struct of_compat_data compat_data[] = { + { "cavium,octeon-3860-ciu", OCTEON_INTC_CIU }, + { NULL } +}; + +static int +octeon_intc_match(device_t parent, cfdata_t cf, void *aux) +{ + struct fdt_attach_args * const faa = aux; + + return of_match_compat_data(faa->faa_phandle, compat_data); +} + +static void +octeon_intc_attach(device_t parent, device_t self, void *aux) +{ + struct octeon_intc_softc * const sc = device_private(self); + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; + int error; + + sc->sc_dev = self; + sc->sc_phandle = phandle; + sc->sc_type = of_search_compatible(phandle, compat_data)->data; + + switch (sc->sc_type) { + case OCTEON_INTC_CIU: + sc->sc_descr = "CIU"; + break; + } + + error = fdtbus_register_interrupt_controller(self, phandle, + &octeon_intc_funcs); + if (error != 0) { + aprint_error(": couldn't register with fdtbus: %d\n", error); + return; + } + + aprint_naive("\n"); + aprint_normal(": %s\n", sc->sc_descr); +} + +static void * +octeon_intc_establish(device_t dev, u_int *specifier, int ipl, int flags, + int (*func)(void *), void *arg) +{ + struct octeon_intc_softc * const sc = device_private(dev); + + /* 1st cell is the controller register (0 or 1) */ + /* 2nd cell is the bit within the register (0..63) */ + + const u_int reg = be32toh(specifier[0]); + const u_int bit = be32toh(specifier[1]); + const u_int irq = (reg * 64) + bit; + + if (irq >= NIRQS) { + aprint_error_dev(dev, "%s irq %d (%d, %d) out of range\n", + sc->sc_descr, irq, reg, bit); + return NULL; + } + + return octeon_intr_establish(irq, ipl, func, arg); +} + +static void +octeon_intc_disestablish(device_t dev, void *ih) +{ + octeon_intr_disestablish(ih); +} + +static bool +octeon_intc_intrstr(device_t dev, u_int *specifier, char *buf, + size_t buflen) +{ + struct octeon_intc_softc * const sc = device_private(dev); + + /* 1st cell is the controller register (0 or 1) */ + /* 2nd cell is the bit within the register (0..63) */ + + const u_int reg = be32toh(specifier[0]); + const u_int bit = be32toh(specifier[1]); + const u_int irq = (reg * 64) + bit; + + snprintf(buf, buflen, "%s irq %d", sc->sc_descr, irq); + + return true; +} Index: src/sys/arch/mips/fdt/fdt_dma_machdep.c diff -u /dev/null src/sys/arch/mips/fdt/fdt_dma_machdep.c:1.1 --- /dev/null Thu Jul 16 11:49:38 2020 +++ src/sys/arch/mips/fdt/fdt_dma_machdep.c Thu Jul 16 11:49:38 2020 @@ -0,0 +1,71 @@ +/* $NetBSD: fdt_dma_machdep.c,v 1.1 2020/07/16 11:49:38 jmcneill Exp $ */ + +/*- + * Copyright (c) 2020 Jared McNeill <jmcne...@invisible.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: fdt_dma_machdep.c,v 1.1 2020/07/16 11:49:38 jmcneill Exp $"); + +#define _MIPS_BUS_DMA_PRIVATE + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/kmem.h> + +#include <dev/fdt/fdtvar.h> + +static struct mips_bus_dma_tag fdtbus_dma_tag = { + ._cookie = NULL, + ._wbase = 0, + ._bounce_alloc_lo = 0, + ._bounce_alloc_hi = 0, + ._dmamap_ops = _BUS_DMAMAP_OPS_INITIALIZER, + ._dmamem_ops = _BUS_DMAMEM_OPS_INITIALIZER, + ._dmatag_ops = _BUS_DMATAG_OPS_INITIALIZER, +}; + +bus_dma_tag_t +fdtbus_dma_tag_create(int phandle, const struct fdt_dma_range *ranges, + u_int nranges) +{ + bus_dma_tag_t newtag; + bus_addr_t min_addr, max_addr; + int error; + + if (nranges == 0) + return &fdtbus_dma_tag; + + KASSERT(nranges == 1); + KASSERT(ranges[0].dr_sysbase == ranges[0].dr_busbase); + + min_addr = ranges[0].dr_sysbase; + max_addr = min_addr + ranges[0].dr_len - 1; + error = bus_dmatag_subregion(&fdtbus_dma_tag, min_addr, max_addr, + &newtag, 0); + KASSERT(error == 0); + + return newtag; +}