1*0aeed3e9SJustin Hibbits /*- 2*0aeed3e9SJustin Hibbits * Copyright (c) 2012 Semihalf. 3*0aeed3e9SJustin Hibbits * All rights reserved. 4*0aeed3e9SJustin Hibbits * 5*0aeed3e9SJustin Hibbits * Redistribution and use in source and binary forms, with or without 6*0aeed3e9SJustin Hibbits * modification, are permitted provided that the following conditions 7*0aeed3e9SJustin Hibbits * are met: 8*0aeed3e9SJustin Hibbits * 1. Redistributions of source code must retain the above copyright 9*0aeed3e9SJustin Hibbits * notice, this list of conditions and the following disclaimer. 10*0aeed3e9SJustin Hibbits * 2. Redistributions in binary form must reproduce the above copyright 11*0aeed3e9SJustin Hibbits * notice, this list of conditions and the following disclaimer in the 12*0aeed3e9SJustin Hibbits * documentation and/or other materials provided with the distribution. 13*0aeed3e9SJustin Hibbits * 14*0aeed3e9SJustin Hibbits * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*0aeed3e9SJustin Hibbits * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*0aeed3e9SJustin Hibbits * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*0aeed3e9SJustin Hibbits * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*0aeed3e9SJustin Hibbits * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*0aeed3e9SJustin Hibbits * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*0aeed3e9SJustin Hibbits * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*0aeed3e9SJustin Hibbits * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*0aeed3e9SJustin Hibbits * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*0aeed3e9SJustin Hibbits * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*0aeed3e9SJustin Hibbits * SUCH DAMAGE. 25*0aeed3e9SJustin Hibbits */ 26*0aeed3e9SJustin Hibbits 27*0aeed3e9SJustin Hibbits #include "opt_platform.h" 28*0aeed3e9SJustin Hibbits #include <sys/cdefs.h> 29*0aeed3e9SJustin Hibbits __FBSDID("$FreeBSD$"); 30*0aeed3e9SJustin Hibbits 31*0aeed3e9SJustin Hibbits #include <sys/param.h> 32*0aeed3e9SJustin Hibbits #include <sys/systm.h> 33*0aeed3e9SJustin Hibbits #include <sys/kernel.h> 34*0aeed3e9SJustin Hibbits #include <sys/bus.h> 35*0aeed3e9SJustin Hibbits #include <sys/proc.h> 36*0aeed3e9SJustin Hibbits #include <sys/pcpu.h> 37*0aeed3e9SJustin Hibbits #include <sys/rman.h> 38*0aeed3e9SJustin Hibbits #include <sys/sched.h> 39*0aeed3e9SJustin Hibbits 40*0aeed3e9SJustin Hibbits #include <vm/vm.h> 41*0aeed3e9SJustin Hibbits #include <vm/pmap.h> 42*0aeed3e9SJustin Hibbits 43*0aeed3e9SJustin Hibbits #include <machine/resource.h> 44*0aeed3e9SJustin Hibbits #include <machine/tlb.h> 45*0aeed3e9SJustin Hibbits 46*0aeed3e9SJustin Hibbits #include <contrib/ncsw/inc/error_ext.h> 47*0aeed3e9SJustin Hibbits #include <contrib/ncsw/inc/xx_ext.h> 48*0aeed3e9SJustin Hibbits 49*0aeed3e9SJustin Hibbits #include "portals.h" 50*0aeed3e9SJustin Hibbits 51*0aeed3e9SJustin Hibbits 52*0aeed3e9SJustin Hibbits int 53*0aeed3e9SJustin Hibbits dpaa_portal_alloc_res(device_t dev, struct dpaa_portals_devinfo *di, int cpu) 54*0aeed3e9SJustin Hibbits { 55*0aeed3e9SJustin Hibbits struct dpaa_portals_softc *sc = device_get_softc(dev); 56*0aeed3e9SJustin Hibbits struct resource_list_entry *rle; 57*0aeed3e9SJustin Hibbits int err; 58*0aeed3e9SJustin Hibbits struct resource_list *res; 59*0aeed3e9SJustin Hibbits 60*0aeed3e9SJustin Hibbits /* Check if MallocSmart allocator is ready */ 61*0aeed3e9SJustin Hibbits if (XX_MallocSmartInit() != E_OK) 62*0aeed3e9SJustin Hibbits return (ENXIO); 63*0aeed3e9SJustin Hibbits 64*0aeed3e9SJustin Hibbits res = &di->di_res; 65*0aeed3e9SJustin Hibbits 66*0aeed3e9SJustin Hibbits /* 67*0aeed3e9SJustin Hibbits * Allocate memory. 68*0aeed3e9SJustin Hibbits * Reserve only one pair of CE/CI virtual memory regions 69*0aeed3e9SJustin Hibbits * for all CPUs, in order to save the space. 70*0aeed3e9SJustin Hibbits */ 71*0aeed3e9SJustin Hibbits if (sc->sc_rres[0] == NULL) { 72*0aeed3e9SJustin Hibbits /* Cache enabled area */ 73*0aeed3e9SJustin Hibbits rle = resource_list_find(res, SYS_RES_MEMORY, 0); 74*0aeed3e9SJustin Hibbits sc->sc_rrid[0] = 0; 75*0aeed3e9SJustin Hibbits sc->sc_rres[0] = bus_alloc_resource(dev, 76*0aeed3e9SJustin Hibbits SYS_RES_MEMORY, &sc->sc_rrid[0], rle->start + sc->sc_dp_pa, 77*0aeed3e9SJustin Hibbits rle->end + sc->sc_dp_pa, rle->count, RF_ACTIVE); 78*0aeed3e9SJustin Hibbits pmap_change_attr((vm_offset_t)rman_get_bushandle(sc->sc_rres[0]), 79*0aeed3e9SJustin Hibbits rle->count, VM_MEMATTR_CACHEABLE); 80*0aeed3e9SJustin Hibbits if (sc->sc_rres[0] == NULL) { 81*0aeed3e9SJustin Hibbits device_printf(dev, "Could not allocate memory.\n"); 82*0aeed3e9SJustin Hibbits return (ENXIO); 83*0aeed3e9SJustin Hibbits } 84*0aeed3e9SJustin Hibbits /* Cache inhibited area */ 85*0aeed3e9SJustin Hibbits rle = resource_list_find(res, SYS_RES_MEMORY, 1); 86*0aeed3e9SJustin Hibbits sc->sc_rrid[1] = 1; 87*0aeed3e9SJustin Hibbits sc->sc_rres[1] = bus_alloc_resource(dev, 88*0aeed3e9SJustin Hibbits SYS_RES_MEMORY, &sc->sc_rrid[1], rle->start + sc->sc_dp_pa, 89*0aeed3e9SJustin Hibbits rle->end + sc->sc_dp_pa, rle->count, RF_ACTIVE); 90*0aeed3e9SJustin Hibbits if (sc->sc_rres[1] == NULL) { 91*0aeed3e9SJustin Hibbits device_printf(dev, "Could not allocate memory.\n"); 92*0aeed3e9SJustin Hibbits bus_release_resource(dev, SYS_RES_MEMORY, 93*0aeed3e9SJustin Hibbits sc->sc_rrid[0], sc->sc_rres[0]); 94*0aeed3e9SJustin Hibbits return (ENXIO); 95*0aeed3e9SJustin Hibbits } 96*0aeed3e9SJustin Hibbits sc->sc_dp[PCPU_GET(cpuid)].dp_regs_mapped = 1; 97*0aeed3e9SJustin Hibbits } 98*0aeed3e9SJustin Hibbits /* Acquire portal's CE_PA and CI_PA */ 99*0aeed3e9SJustin Hibbits rle = resource_list_find(res, SYS_RES_MEMORY, 0); 100*0aeed3e9SJustin Hibbits sc->sc_dp[cpu].dp_ce_pa = rle->start + sc->sc_dp_pa; 101*0aeed3e9SJustin Hibbits sc->sc_dp[cpu].dp_ce_size = rle->count; 102*0aeed3e9SJustin Hibbits rle = resource_list_find(res, SYS_RES_MEMORY, 1); 103*0aeed3e9SJustin Hibbits sc->sc_dp[cpu].dp_ci_pa = rle->start + sc->sc_dp_pa; 104*0aeed3e9SJustin Hibbits sc->sc_dp[cpu].dp_ci_size = rle->count; 105*0aeed3e9SJustin Hibbits 106*0aeed3e9SJustin Hibbits /* Allocate interrupts */ 107*0aeed3e9SJustin Hibbits rle = resource_list_find(res, SYS_RES_IRQ, 0); 108*0aeed3e9SJustin Hibbits sc->sc_dp[cpu].dp_irid = 0; 109*0aeed3e9SJustin Hibbits sc->sc_dp[cpu].dp_ires = bus_alloc_resource(dev, 110*0aeed3e9SJustin Hibbits SYS_RES_IRQ, &sc->sc_dp[cpu].dp_irid, rle->start, rle->end, 111*0aeed3e9SJustin Hibbits rle->count, RF_ACTIVE); 112*0aeed3e9SJustin Hibbits /* Save interrupt number for later use */ 113*0aeed3e9SJustin Hibbits sc->sc_dp[cpu].dp_intr_num = rle->start; 114*0aeed3e9SJustin Hibbits 115*0aeed3e9SJustin Hibbits if (sc->sc_dp[cpu].dp_ires == NULL) { 116*0aeed3e9SJustin Hibbits device_printf(dev, "Could not allocate irq.\n"); 117*0aeed3e9SJustin Hibbits return (ENXIO); 118*0aeed3e9SJustin Hibbits } 119*0aeed3e9SJustin Hibbits 120*0aeed3e9SJustin Hibbits err = XX_PreallocAndBindIntr((int)sc->sc_dp[cpu].dp_ires, cpu); 121*0aeed3e9SJustin Hibbits 122*0aeed3e9SJustin Hibbits if (err != E_OK) { 123*0aeed3e9SJustin Hibbits device_printf(dev, "Could not prealloc and bind interrupt\n"); 124*0aeed3e9SJustin Hibbits bus_release_resource(dev, SYS_RES_IRQ, 125*0aeed3e9SJustin Hibbits sc->sc_dp[cpu].dp_irid, sc->sc_dp[cpu].dp_ires); 126*0aeed3e9SJustin Hibbits sc->sc_dp[cpu].dp_ires = NULL; 127*0aeed3e9SJustin Hibbits return (ENXIO); 128*0aeed3e9SJustin Hibbits } 129*0aeed3e9SJustin Hibbits 130*0aeed3e9SJustin Hibbits #if 0 131*0aeed3e9SJustin Hibbits err = bus_generic_config_intr(dev, rle->start, di->di_intr_trig, 132*0aeed3e9SJustin Hibbits di->di_intr_pol); 133*0aeed3e9SJustin Hibbits if (err != 0) { 134*0aeed3e9SJustin Hibbits device_printf(dev, "Could not configure interrupt\n"); 135*0aeed3e9SJustin Hibbits bus_release_resource(dev, SYS_RES_IRQ, 136*0aeed3e9SJustin Hibbits sc->sc_dp[cpu].dp_irid, sc->sc_dp[cpu].dp_ires); 137*0aeed3e9SJustin Hibbits sc->sc_dp[cpu].dp_ires = NULL; 138*0aeed3e9SJustin Hibbits return (err); 139*0aeed3e9SJustin Hibbits } 140*0aeed3e9SJustin Hibbits #endif 141*0aeed3e9SJustin Hibbits 142*0aeed3e9SJustin Hibbits return (0); 143*0aeed3e9SJustin Hibbits } 144*0aeed3e9SJustin Hibbits 145*0aeed3e9SJustin Hibbits void 146*0aeed3e9SJustin Hibbits dpaa_portal_map_registers(struct dpaa_portals_softc *sc) 147*0aeed3e9SJustin Hibbits { 148*0aeed3e9SJustin Hibbits unsigned int cpu; 149*0aeed3e9SJustin Hibbits 150*0aeed3e9SJustin Hibbits sched_pin(); 151*0aeed3e9SJustin Hibbits cpu = PCPU_GET(cpuid); 152*0aeed3e9SJustin Hibbits if (sc->sc_dp[cpu].dp_regs_mapped) 153*0aeed3e9SJustin Hibbits goto out; 154*0aeed3e9SJustin Hibbits 155*0aeed3e9SJustin Hibbits tlb1_set_entry(rman_get_bushandle(sc->sc_rres[0]), 156*0aeed3e9SJustin Hibbits sc->sc_dp[cpu].dp_ce_pa, sc->sc_dp[cpu].dp_ce_size, 157*0aeed3e9SJustin Hibbits _TLB_ENTRY_MEM); 158*0aeed3e9SJustin Hibbits tlb1_set_entry(rman_get_bushandle(sc->sc_rres[1]), 159*0aeed3e9SJustin Hibbits sc->sc_dp[cpu].dp_ci_pa, sc->sc_dp[cpu].dp_ci_size, 160*0aeed3e9SJustin Hibbits _TLB_ENTRY_IO); 161*0aeed3e9SJustin Hibbits 162*0aeed3e9SJustin Hibbits sc->sc_dp[cpu].dp_regs_mapped = 1; 163*0aeed3e9SJustin Hibbits 164*0aeed3e9SJustin Hibbits out: 165*0aeed3e9SJustin Hibbits sched_unpin(); 166*0aeed3e9SJustin Hibbits } 167