1*e9f96ff4SJustin Hibbits /*- 2*e9f96ff4SJustin Hibbits * Copyright (c) 2018 Justin Hibbits 3*e9f96ff4SJustin Hibbits * All rights reserved. 4*e9f96ff4SJustin Hibbits * 5*e9f96ff4SJustin Hibbits * Redistribution and use in source and binary forms, with or without 6*e9f96ff4SJustin Hibbits * modification, are permitted provided that the following conditions 7*e9f96ff4SJustin Hibbits * are met: 8*e9f96ff4SJustin Hibbits * 1. Redistributions of source code must retain the above copyright 9*e9f96ff4SJustin Hibbits * notice, this list of conditions and the following disclaimer. 10*e9f96ff4SJustin Hibbits * 2. Redistributions in binary form must reproduce the above copyright 11*e9f96ff4SJustin Hibbits * notice, this list of conditions and the following disclaimer in the 12*e9f96ff4SJustin Hibbits * documentation and/or other materials provided with the distribution. 13*e9f96ff4SJustin Hibbits * 14*e9f96ff4SJustin Hibbits * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*e9f96ff4SJustin Hibbits * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*e9f96ff4SJustin Hibbits * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*e9f96ff4SJustin Hibbits * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*e9f96ff4SJustin Hibbits * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*e9f96ff4SJustin Hibbits * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*e9f96ff4SJustin Hibbits * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*e9f96ff4SJustin Hibbits * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*e9f96ff4SJustin Hibbits * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*e9f96ff4SJustin Hibbits * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*e9f96ff4SJustin Hibbits * SUCH DAMAGE. 25*e9f96ff4SJustin Hibbits * 26*e9f96ff4SJustin Hibbits * $FreeBSD$ 27*e9f96ff4SJustin Hibbits */ 28*e9f96ff4SJustin Hibbits 29*e9f96ff4SJustin Hibbits #include <sys/cdefs.h> 30*e9f96ff4SJustin Hibbits __FBSDID("$FreeBSD$"); 31*e9f96ff4SJustin Hibbits 32*e9f96ff4SJustin Hibbits #include <sys/param.h> 33*e9f96ff4SJustin Hibbits #include <sys/systm.h> 34*e9f96ff4SJustin Hibbits #include <sys/conf.h> 35*e9f96ff4SJustin Hibbits #include <sys/bus.h> 36*e9f96ff4SJustin Hibbits #include <sys/kernel.h> 37*e9f96ff4SJustin Hibbits #include <sys/module.h> 38*e9f96ff4SJustin Hibbits #include <sys/lock.h> 39*e9f96ff4SJustin Hibbits #include <sys/mutex.h> 40*e9f96ff4SJustin Hibbits #include <sys/resource.h> 41*e9f96ff4SJustin Hibbits #include <sys/rman.h> 42*e9f96ff4SJustin Hibbits 43*e9f96ff4SJustin Hibbits #include <machine/bus.h> 44*e9f96ff4SJustin Hibbits #include <machine/resource.h> 45*e9f96ff4SJustin Hibbits #include <machine/stdarg.h> 46*e9f96ff4SJustin Hibbits 47*e9f96ff4SJustin Hibbits #include <dev/fdt/fdt_common.h> 48*e9f96ff4SJustin Hibbits #include <dev/ofw/ofw_bus.h> 49*e9f96ff4SJustin Hibbits #include <dev/ofw/ofw_bus_subr.h> 50*e9f96ff4SJustin Hibbits 51*e9f96ff4SJustin Hibbits /* 52*e9f96ff4SJustin Hibbits * From the P1022 manual, sequence for writing to L2CTL is: 53*e9f96ff4SJustin Hibbits * - mbar 54*e9f96ff4SJustin Hibbits * - isync 55*e9f96ff4SJustin Hibbits * - write 56*e9f96ff4SJustin Hibbits * - read 57*e9f96ff4SJustin Hibbits * - mbar 58*e9f96ff4SJustin Hibbits */ 59*e9f96ff4SJustin Hibbits #define L2_CTL 0x0 60*e9f96ff4SJustin Hibbits #define L2CTL_L2E 0x80000000 61*e9f96ff4SJustin Hibbits #define L2CTL_L2I 0x40000000 62*e9f96ff4SJustin Hibbits struct mpc85xx_cache_softc { 63*e9f96ff4SJustin Hibbits struct resource *sc_mem; 64*e9f96ff4SJustin Hibbits }; 65*e9f96ff4SJustin Hibbits 66*e9f96ff4SJustin Hibbits static int 67*e9f96ff4SJustin Hibbits mpc85xx_cache_probe(device_t dev) 68*e9f96ff4SJustin Hibbits { 69*e9f96ff4SJustin Hibbits 70*e9f96ff4SJustin Hibbits if (!ofw_bus_is_compatible(dev, "cache")) 71*e9f96ff4SJustin Hibbits return (ENXIO); 72*e9f96ff4SJustin Hibbits 73*e9f96ff4SJustin Hibbits device_set_desc(dev, "MPC85xx L2 cache"); 74*e9f96ff4SJustin Hibbits return (0); 75*e9f96ff4SJustin Hibbits } 76*e9f96ff4SJustin Hibbits 77*e9f96ff4SJustin Hibbits static int 78*e9f96ff4SJustin Hibbits mpc85xx_cache_attach(device_t dev) 79*e9f96ff4SJustin Hibbits { 80*e9f96ff4SJustin Hibbits struct mpc85xx_cache_softc *sc = device_get_softc(dev); 81*e9f96ff4SJustin Hibbits int rid; 82*e9f96ff4SJustin Hibbits int cache_line_size, cache_size; 83*e9f96ff4SJustin Hibbits 84*e9f96ff4SJustin Hibbits /* Map registers. */ 85*e9f96ff4SJustin Hibbits rid = 0; 86*e9f96ff4SJustin Hibbits sc->sc_mem = bus_alloc_resource_any(dev, 87*e9f96ff4SJustin Hibbits SYS_RES_MEMORY, &rid, RF_ACTIVE); 88*e9f96ff4SJustin Hibbits if (sc->sc_mem == NULL) 89*e9f96ff4SJustin Hibbits return (ENOMEM); 90*e9f96ff4SJustin Hibbits 91*e9f96ff4SJustin Hibbits /* Enable cache and flash invalidate. */ 92*e9f96ff4SJustin Hibbits __asm __volatile ("mbar; isync" ::: "memory"); 93*e9f96ff4SJustin Hibbits bus_write_4(sc->sc_mem, L2_CTL, L2CTL_L2E | L2CTL_L2I); 94*e9f96ff4SJustin Hibbits bus_read_4(sc->sc_mem, L2_CTL); 95*e9f96ff4SJustin Hibbits __asm __volatile ("mbar" ::: "memory"); 96*e9f96ff4SJustin Hibbits 97*e9f96ff4SJustin Hibbits cache_line_size = 0; 98*e9f96ff4SJustin Hibbits cache_size = 0; 99*e9f96ff4SJustin Hibbits OF_getencprop(ofw_bus_get_node(dev), "cache-size", &cache_size, 100*e9f96ff4SJustin Hibbits sizeof(cache_size)); 101*e9f96ff4SJustin Hibbits OF_getencprop(ofw_bus_get_node(dev), "cache-line-size", 102*e9f96ff4SJustin Hibbits &cache_line_size, sizeof(cache_line_size)); 103*e9f96ff4SJustin Hibbits 104*e9f96ff4SJustin Hibbits if (cache_line_size != 0 && cache_size != 0) 105*e9f96ff4SJustin Hibbits device_printf(dev, 106*e9f96ff4SJustin Hibbits "L2 cache size: %dKB, cache line size: %d bytes\n", 107*e9f96ff4SJustin Hibbits cache_size / 1024, cache_line_size); 108*e9f96ff4SJustin Hibbits 109*e9f96ff4SJustin Hibbits return (0); 110*e9f96ff4SJustin Hibbits } 111*e9f96ff4SJustin Hibbits 112*e9f96ff4SJustin Hibbits static device_method_t mpc85xx_cache_methods[] = { 113*e9f96ff4SJustin Hibbits /* device methods */ 114*e9f96ff4SJustin Hibbits DEVMETHOD(device_probe, mpc85xx_cache_probe), 115*e9f96ff4SJustin Hibbits DEVMETHOD(device_attach, mpc85xx_cache_attach), 116*e9f96ff4SJustin Hibbits 117*e9f96ff4SJustin Hibbits DEVMETHOD_END 118*e9f96ff4SJustin Hibbits }; 119*e9f96ff4SJustin Hibbits 120*e9f96ff4SJustin Hibbits static driver_t mpc85xx_cache_driver = { 121*e9f96ff4SJustin Hibbits "cache", 122*e9f96ff4SJustin Hibbits mpc85xx_cache_methods, 123*e9f96ff4SJustin Hibbits sizeof(struct mpc85xx_cache_softc), 124*e9f96ff4SJustin Hibbits }; 125*e9f96ff4SJustin Hibbits static devclass_t mpc85xx_cache_devclass; 126*e9f96ff4SJustin Hibbits 127*e9f96ff4SJustin Hibbits EARLY_DRIVER_MODULE(mpc85xx_cache, simplebus, mpc85xx_cache_driver, 128*e9f96ff4SJustin Hibbits mpc85xx_cache_devclass, NULL, NULL, 129*e9f96ff4SJustin Hibbits BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE); 130