1296177Sjhibbits/*- 2296177Sjhibbits * Copyright (c) 2012 Semihalf. 3296177Sjhibbits * All rights reserved. 4296177Sjhibbits * 5296177Sjhibbits * Redistribution and use in source and binary forms, with or without 6296177Sjhibbits * modification, are permitted provided that the following conditions 7296177Sjhibbits * are met: 8296177Sjhibbits * 1. Redistributions of source code must retain the above copyright 9296177Sjhibbits * notice, this list of conditions and the following disclaimer. 10296177Sjhibbits * 2. Redistributions in binary form must reproduce the above copyright 11296177Sjhibbits * notice, this list of conditions and the following disclaimer in the 12296177Sjhibbits * documentation and/or other materials provided with the distribution. 13296177Sjhibbits * 14296177Sjhibbits * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15296177Sjhibbits * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16296177Sjhibbits * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17296177Sjhibbits * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18296177Sjhibbits * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19296177Sjhibbits * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20296177Sjhibbits * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21296177Sjhibbits * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22296177Sjhibbits * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23296177Sjhibbits * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24296177Sjhibbits * SUCH DAMAGE. 25296177Sjhibbits */ 26296177Sjhibbits 27296177Sjhibbits#include "opt_platform.h" 28296177Sjhibbits#include <sys/cdefs.h> 29296177Sjhibbits__FBSDID("$FreeBSD$"); 30296177Sjhibbits 31296177Sjhibbits#include <sys/param.h> 32296177Sjhibbits#include <sys/systm.h> 33296177Sjhibbits#include <sys/kernel.h> 34296177Sjhibbits#include <sys/bus.h> 35296177Sjhibbits#include <sys/proc.h> 36296177Sjhibbits#include <sys/pcpu.h> 37296177Sjhibbits#include <sys/rman.h> 38296177Sjhibbits#include <sys/sched.h> 39296177Sjhibbits 40296177Sjhibbits#include <vm/vm.h> 41296177Sjhibbits#include <vm/pmap.h> 42296177Sjhibbits 43296177Sjhibbits#include <machine/resource.h> 44296177Sjhibbits#include <machine/tlb.h> 45296177Sjhibbits 46296177Sjhibbits#include <contrib/ncsw/inc/error_ext.h> 47296177Sjhibbits#include <contrib/ncsw/inc/xx_ext.h> 48296177Sjhibbits 49296177Sjhibbits#include "portals.h" 50296177Sjhibbits 51296177Sjhibbits 52296177Sjhibbitsint 53296177Sjhibbitsdpaa_portal_alloc_res(device_t dev, struct dpaa_portals_devinfo *di, int cpu) 54296177Sjhibbits{ 55296177Sjhibbits struct dpaa_portals_softc *sc = device_get_softc(dev); 56296177Sjhibbits struct resource_list_entry *rle; 57296177Sjhibbits int err; 58296177Sjhibbits struct resource_list *res; 59296177Sjhibbits 60296177Sjhibbits /* Check if MallocSmart allocator is ready */ 61296177Sjhibbits if (XX_MallocSmartInit() != E_OK) 62296177Sjhibbits return (ENXIO); 63296177Sjhibbits 64296177Sjhibbits res = &di->di_res; 65296177Sjhibbits 66296177Sjhibbits /* 67296177Sjhibbits * Allocate memory. 68296177Sjhibbits * Reserve only one pair of CE/CI virtual memory regions 69296177Sjhibbits * for all CPUs, in order to save the space. 70296177Sjhibbits */ 71296177Sjhibbits if (sc->sc_rres[0] == NULL) { 72296177Sjhibbits /* Cache enabled area */ 73296177Sjhibbits rle = resource_list_find(res, SYS_RES_MEMORY, 0); 74296177Sjhibbits sc->sc_rrid[0] = 0; 75296177Sjhibbits sc->sc_rres[0] = bus_alloc_resource(dev, 76296177Sjhibbits SYS_RES_MEMORY, &sc->sc_rrid[0], rle->start + sc->sc_dp_pa, 77296177Sjhibbits rle->end + sc->sc_dp_pa, rle->count, RF_ACTIVE); 78296177Sjhibbits if (sc->sc_rres[0] == NULL) { 79300637Sjhibbits device_printf(dev, 80300637Sjhibbits "Could not allocate cache enabled memory.\n"); 81296177Sjhibbits return (ENXIO); 82296177Sjhibbits } 83300637Sjhibbits tlb1_set_entry(rman_get_bushandle(sc->sc_rres[0]), 84300637Sjhibbits rle->start + sc->sc_dp_pa, rle->count, _TLB_ENTRY_MEM); 85296177Sjhibbits /* Cache inhibited area */ 86296177Sjhibbits rle = resource_list_find(res, SYS_RES_MEMORY, 1); 87296177Sjhibbits sc->sc_rrid[1] = 1; 88296177Sjhibbits sc->sc_rres[1] = bus_alloc_resource(dev, 89296177Sjhibbits SYS_RES_MEMORY, &sc->sc_rrid[1], rle->start + sc->sc_dp_pa, 90296177Sjhibbits rle->end + sc->sc_dp_pa, rle->count, RF_ACTIVE); 91296177Sjhibbits if (sc->sc_rres[1] == NULL) { 92300637Sjhibbits device_printf(dev, 93300637Sjhibbits "Could not allocate cache inhibited memory.\n"); 94296177Sjhibbits bus_release_resource(dev, SYS_RES_MEMORY, 95296177Sjhibbits sc->sc_rrid[0], sc->sc_rres[0]); 96296177Sjhibbits return (ENXIO); 97296177Sjhibbits } 98300637Sjhibbits tlb1_set_entry(rman_get_bushandle(sc->sc_rres[1]), 99300637Sjhibbits rle->start + sc->sc_dp_pa, rle->count, _TLB_ENTRY_IO); 100300637Sjhibbits sc->sc_dp[cpu].dp_regs_mapped = 1; 101296177Sjhibbits } 102296177Sjhibbits /* Acquire portal's CE_PA and CI_PA */ 103296177Sjhibbits rle = resource_list_find(res, SYS_RES_MEMORY, 0); 104296177Sjhibbits sc->sc_dp[cpu].dp_ce_pa = rle->start + sc->sc_dp_pa; 105296177Sjhibbits sc->sc_dp[cpu].dp_ce_size = rle->count; 106296177Sjhibbits rle = resource_list_find(res, SYS_RES_MEMORY, 1); 107296177Sjhibbits sc->sc_dp[cpu].dp_ci_pa = rle->start + sc->sc_dp_pa; 108296177Sjhibbits sc->sc_dp[cpu].dp_ci_size = rle->count; 109296177Sjhibbits 110296177Sjhibbits /* Allocate interrupts */ 111296177Sjhibbits rle = resource_list_find(res, SYS_RES_IRQ, 0); 112296177Sjhibbits sc->sc_dp[cpu].dp_irid = 0; 113296177Sjhibbits sc->sc_dp[cpu].dp_ires = bus_alloc_resource(dev, 114296177Sjhibbits SYS_RES_IRQ, &sc->sc_dp[cpu].dp_irid, rle->start, rle->end, 115296177Sjhibbits rle->count, RF_ACTIVE); 116296177Sjhibbits /* Save interrupt number for later use */ 117296177Sjhibbits sc->sc_dp[cpu].dp_intr_num = rle->start; 118296177Sjhibbits 119296177Sjhibbits if (sc->sc_dp[cpu].dp_ires == NULL) { 120296177Sjhibbits device_printf(dev, "Could not allocate irq.\n"); 121296177Sjhibbits return (ENXIO); 122296177Sjhibbits } 123296177Sjhibbits 124296177Sjhibbits err = XX_PreallocAndBindIntr((int)sc->sc_dp[cpu].dp_ires, cpu); 125296177Sjhibbits 126296177Sjhibbits if (err != E_OK) { 127296177Sjhibbits device_printf(dev, "Could not prealloc and bind interrupt\n"); 128296177Sjhibbits bus_release_resource(dev, SYS_RES_IRQ, 129296177Sjhibbits sc->sc_dp[cpu].dp_irid, sc->sc_dp[cpu].dp_ires); 130296177Sjhibbits sc->sc_dp[cpu].dp_ires = NULL; 131296177Sjhibbits return (ENXIO); 132296177Sjhibbits } 133296177Sjhibbits 134296177Sjhibbits#if 0 135296177Sjhibbits err = bus_generic_config_intr(dev, rle->start, di->di_intr_trig, 136296177Sjhibbits di->di_intr_pol); 137296177Sjhibbits if (err != 0) { 138296177Sjhibbits device_printf(dev, "Could not configure interrupt\n"); 139296177Sjhibbits bus_release_resource(dev, SYS_RES_IRQ, 140296177Sjhibbits sc->sc_dp[cpu].dp_irid, sc->sc_dp[cpu].dp_ires); 141296177Sjhibbits sc->sc_dp[cpu].dp_ires = NULL; 142296177Sjhibbits return (err); 143296177Sjhibbits } 144296177Sjhibbits#endif 145296177Sjhibbits 146296177Sjhibbits return (0); 147296177Sjhibbits} 148296177Sjhibbits 149296177Sjhibbitsvoid 150296177Sjhibbitsdpaa_portal_map_registers(struct dpaa_portals_softc *sc) 151296177Sjhibbits{ 152296177Sjhibbits unsigned int cpu; 153296177Sjhibbits 154296177Sjhibbits sched_pin(); 155296177Sjhibbits cpu = PCPU_GET(cpuid); 156296177Sjhibbits if (sc->sc_dp[cpu].dp_regs_mapped) 157296177Sjhibbits goto out; 158296177Sjhibbits 159296177Sjhibbits tlb1_set_entry(rman_get_bushandle(sc->sc_rres[0]), 160296177Sjhibbits sc->sc_dp[cpu].dp_ce_pa, sc->sc_dp[cpu].dp_ce_size, 161296177Sjhibbits _TLB_ENTRY_MEM); 162296177Sjhibbits tlb1_set_entry(rman_get_bushandle(sc->sc_rres[1]), 163296177Sjhibbits sc->sc_dp[cpu].dp_ci_pa, sc->sc_dp[cpu].dp_ci_size, 164296177Sjhibbits _TLB_ENTRY_IO); 165296177Sjhibbits 166296177Sjhibbits sc->sc_dp[cpu].dp_regs_mapped = 1; 167296177Sjhibbits 168296177Sjhibbitsout: 169296177Sjhibbits sched_unpin(); 170296177Sjhibbits} 171