a20_cpu_cfg.c revision 266152
1203954Srdivacky/*- 2203954Srdivacky * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@gmail.com> 3203954Srdivacky * All rights reserved. 4203954Srdivacky * 5203954Srdivacky * Redistribution and use in source and binary forms, with or without 6203954Srdivacky * modification, are permitted provided that the following conditions 7203954Srdivacky * are met: 8203954Srdivacky * 1. Redistributions of source code must retain the above copyright 9203954Srdivacky * notice, this list of conditions and the following disclaimer. 10203954Srdivacky * 2. Redistributions in binary form must reproduce the above copyright 11203954Srdivacky * notice, this list of conditions and the following disclaimer in the 12203954Srdivacky * documentation and/or other materials provided with the distribution. 13203954Srdivacky * 14203954Srdivacky * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15203954Srdivacky * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16249423Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17249423Sdim * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18203954Srdivacky * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19203954Srdivacky * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20203954Srdivacky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21249423Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22203954Srdivacky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23280031Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24203954Srdivacky * SUCH DAMAGE. 25203954Srdivacky */ 26276479Sdim 27276479Sdim/* CPU configuration module for Allwinner A20 */ 28203954Srdivacky 29203954Srdivacky#include <sys/cdefs.h> 30203954Srdivacky__FBSDID("$FreeBSD: stable/10/sys/arm/allwinner/a20/a20_cpu_cfg.c 266152 2014-05-15 16:11:06Z ian $"); 31203954Srdivacky 32203954Srdivacky#include <sys/param.h> 33203954Srdivacky#include <sys/systm.h> 34203954Srdivacky#include <sys/bus.h> 35203954Srdivacky#include <sys/kernel.h> 36203954Srdivacky#include <sys/module.h> 37203954Srdivacky#include <sys/malloc.h> 38218893Sdim#include <sys/rman.h> 39218893Sdim#include <sys/timeet.h> 40218893Sdim#include <sys/timetc.h> 41203954Srdivacky#include <sys/watchdog.h> 42276479Sdim#include <machine/bus.h> 43203954Srdivacky#include <machine/cpu.h> 44276479Sdim#include <machine/intr.h> 45203954Srdivacky 46203954Srdivacky#include <dev/fdt/fdt_common.h> 47203954Srdivacky#include <dev/ofw/openfirm.h> 48203954Srdivacky#include <dev/ofw/ofw_bus.h> 49203954Srdivacky#include <dev/ofw/ofw_bus_subr.h> 50203954Srdivacky 51203954Srdivacky#include <machine/bus.h> 52203954Srdivacky#include <machine/fdt.h> 53203954Srdivacky 54203954Srdivacky#include "a20_cpu_cfg.h" 55203954Srdivacky 56203954Srdivackystruct a20_cpu_cfg_softc { 57203954Srdivacky struct resource *res; 58203954Srdivacky bus_space_tag_t bst; 59203954Srdivacky bus_space_handle_t bsh; 60203954Srdivacky}; 61234353Sdim 62212904Sdimstatic struct a20_cpu_cfg_softc *a20_cpu_cfg_sc = NULL; 63218893Sdim 64203954Srdivacky#define cpu_cfg_read_4(sc, reg) \ 65203954Srdivacky bus_space_read_4((sc)->bst, (sc)->bsh, (reg)) 66276479Sdim#define cpu_cfg_write_4(sc, reg, val) \ 67276479Sdim bus_space_write_4((sc)->bst, (sc)->bsh, (reg), (val)) 68276479Sdim 69203954Srdivackystatic int 70280031Sdima20_cpu_cfg_probe(device_t dev) 71203954Srdivacky{ 72203954Srdivacky 73203954Srdivacky if (!ofw_bus_status_okay(dev)) 74203954Srdivacky return (ENXIO); 75203954Srdivacky 76203954Srdivacky if (ofw_bus_is_compatible(dev, "allwinner,sun7i-cpu-cfg")) { 77203954Srdivacky device_set_desc(dev, "A20 CPU Configuration Module"); 78203954Srdivacky return(BUS_PROBE_DEFAULT); 79203954Srdivacky } 80203954Srdivacky 81203954Srdivacky return (ENXIO); 82203954Srdivacky} 83203954Srdivacky 84203954Srdivackystatic int 85203954Srdivackya20_cpu_cfg_attach(device_t dev) 86203954Srdivacky{ 87203954Srdivacky struct a20_cpu_cfg_softc *sc = device_get_softc(dev); 88203954Srdivacky int rid = 0; 89203954Srdivacky 90203954Srdivacky if (a20_cpu_cfg_sc) 91203954Srdivacky return (ENXIO); 92203954Srdivacky 93203954Srdivacky sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); 94203954Srdivacky if (!sc->res) { 95280031Sdim device_printf(dev, "could not allocate resource\n"); 96203954Srdivacky return (ENXIO); 97203954Srdivacky } 98203954Srdivacky 99203954Srdivacky sc->bst = rman_get_bustag(sc->res); 100203954Srdivacky sc->bsh = rman_get_bushandle(sc->res); 101203954Srdivacky 102203954Srdivacky a20_cpu_cfg_sc = sc; 103203954Srdivacky 104203954Srdivacky return (0); 105203954Srdivacky} 106203954Srdivacky 107203954Srdivackystatic device_method_t a20_cpu_cfg_methods[] = { 108203954Srdivacky DEVMETHOD(device_probe, a20_cpu_cfg_probe), 109203954Srdivacky DEVMETHOD(device_attach, a20_cpu_cfg_attach), 110212904Sdim { 0, 0 } 111212904Sdim}; 112212904Sdim 113212904Sdimstatic driver_t a20_cpu_cfg_driver = { 114210299Sed "a20_cpu_cfg", 115203954Srdivacky a20_cpu_cfg_methods, 116203954Srdivacky sizeof(struct a20_cpu_cfg_softc), 117203954Srdivacky}; 118203954Srdivacky 119203954Srdivackystatic devclass_t a20_cpu_cfg_devclass; 120203954Srdivacky 121203954SrdivackyDRIVER_MODULE(a20_cpu_cfg, simplebus, a20_cpu_cfg_driver, a20_cpu_cfg_devclass, 0, 0); 122203954Srdivacky 123203954Srdivackyuint64_t 124203954Srdivackya20_read_counter64(void) 125203954Srdivacky{ 126203954Srdivacky uint32_t lo, hi; 127203954Srdivacky 128203954Srdivacky /* Latch counter, wait for it to be ready to read. */ 129203954Srdivacky cpu_cfg_write_4(a20_cpu_cfg_sc, OSC24M_CNT64_CTRL_REG, CNT64_RL_EN); 130203954Srdivacky while (cpu_cfg_read_4(a20_cpu_cfg_sc, OSC24M_CNT64_CTRL_REG) & CNT64_RL_EN) 131203954Srdivacky continue; 132203954Srdivacky 133203954Srdivacky hi = cpu_cfg_read_4(a20_cpu_cfg_sc, OSC24M_CNT64_HIGH_REG); 134203954Srdivacky lo = cpu_cfg_read_4(a20_cpu_cfg_sc, OSC24M_CNT64_LOW_REG); 135203954Srdivacky 136203954Srdivacky return (((uint64_t)hi << 32) | lo); 137203954Srdivacky} 138203954Srdivacky 139203954Srdivacky