1254056Sganbold/*- 2266337Sian * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@freebsd.org> 3254056Sganbold * All rights reserved. 4254056Sganbold * 5254056Sganbold * Redistribution and use in source and binary forms, with or without 6254056Sganbold * modification, are permitted provided that the following conditions 7254056Sganbold * are met: 8254056Sganbold * 1. Redistributions of source code must retain the above copyright 9254056Sganbold * notice, this list of conditions and the following disclaimer. 10254056Sganbold * 2. Redistributions in binary form must reproduce the above copyright 11254056Sganbold * notice, this list of conditions and the following disclaimer in the 12254056Sganbold * documentation and/or other materials provided with the distribution. 13254056Sganbold * 14254056Sganbold * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15254056Sganbold * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16254056Sganbold * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17254056Sganbold * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18254056Sganbold * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19254056Sganbold * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20254056Sganbold * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21254056Sganbold * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22254056Sganbold * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23254056Sganbold * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24254056Sganbold * SUCH DAMAGE. 25254056Sganbold */ 26254056Sganbold 27254056Sganbold/* CPU configuration module for Allwinner A20 */ 28254056Sganbold 29254056Sganbold#include <sys/cdefs.h> 30254056Sganbold__FBSDID("$FreeBSD: releng/10.2/sys/arm/allwinner/a20/a20_cpu_cfg.c 266337 2014-05-17 18:53:36Z ian $"); 31254056Sganbold 32254056Sganbold#include <sys/param.h> 33254056Sganbold#include <sys/systm.h> 34254056Sganbold#include <sys/bus.h> 35254056Sganbold#include <sys/kernel.h> 36254056Sganbold#include <sys/module.h> 37254056Sganbold#include <sys/malloc.h> 38254056Sganbold#include <sys/rman.h> 39254056Sganbold#include <sys/timeet.h> 40254056Sganbold#include <sys/timetc.h> 41254056Sganbold#include <sys/watchdog.h> 42254056Sganbold#include <machine/bus.h> 43254056Sganbold#include <machine/cpu.h> 44254056Sganbold#include <machine/intr.h> 45254056Sganbold 46254056Sganbold#include <dev/fdt/fdt_common.h> 47254056Sganbold#include <dev/ofw/openfirm.h> 48254056Sganbold#include <dev/ofw/ofw_bus.h> 49254056Sganbold#include <dev/ofw/ofw_bus_subr.h> 50254056Sganbold 51254056Sganbold#include <machine/bus.h> 52254056Sganbold#include <machine/fdt.h> 53254056Sganbold 54254056Sganbold#include "a20_cpu_cfg.h" 55254056Sganbold 56254056Sganboldstruct a20_cpu_cfg_softc { 57254056Sganbold struct resource *res; 58254056Sganbold bus_space_tag_t bst; 59254056Sganbold bus_space_handle_t bsh; 60254056Sganbold}; 61254056Sganbold 62254056Sganboldstatic struct a20_cpu_cfg_softc *a20_cpu_cfg_sc = NULL; 63254056Sganbold 64254056Sganbold#define cpu_cfg_read_4(sc, reg) \ 65254056Sganbold bus_space_read_4((sc)->bst, (sc)->bsh, (reg)) 66254056Sganbold#define cpu_cfg_write_4(sc, reg, val) \ 67254056Sganbold bus_space_write_4((sc)->bst, (sc)->bsh, (reg), (val)) 68254056Sganbold 69254056Sganboldstatic int 70254056Sganbolda20_cpu_cfg_probe(device_t dev) 71254056Sganbold{ 72254056Sganbold 73266152Sian if (!ofw_bus_status_okay(dev)) 74266152Sian return (ENXIO); 75266152Sian 76254056Sganbold if (ofw_bus_is_compatible(dev, "allwinner,sun7i-cpu-cfg")) { 77254056Sganbold device_set_desc(dev, "A20 CPU Configuration Module"); 78254056Sganbold return(BUS_PROBE_DEFAULT); 79254056Sganbold } 80254056Sganbold 81254056Sganbold return (ENXIO); 82254056Sganbold} 83254056Sganbold 84254056Sganboldstatic int 85254056Sganbolda20_cpu_cfg_attach(device_t dev) 86254056Sganbold{ 87254056Sganbold struct a20_cpu_cfg_softc *sc = device_get_softc(dev); 88254056Sganbold int rid = 0; 89254056Sganbold 90254056Sganbold if (a20_cpu_cfg_sc) 91254056Sganbold return (ENXIO); 92254056Sganbold 93254056Sganbold sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); 94254056Sganbold if (!sc->res) { 95254056Sganbold device_printf(dev, "could not allocate resource\n"); 96254056Sganbold return (ENXIO); 97254056Sganbold } 98254056Sganbold 99254056Sganbold sc->bst = rman_get_bustag(sc->res); 100254056Sganbold sc->bsh = rman_get_bushandle(sc->res); 101254056Sganbold 102254056Sganbold a20_cpu_cfg_sc = sc; 103254056Sganbold 104254056Sganbold return (0); 105254056Sganbold} 106254056Sganbold 107254056Sganboldstatic device_method_t a20_cpu_cfg_methods[] = { 108254056Sganbold DEVMETHOD(device_probe, a20_cpu_cfg_probe), 109254056Sganbold DEVMETHOD(device_attach, a20_cpu_cfg_attach), 110254056Sganbold { 0, 0 } 111254056Sganbold}; 112254056Sganbold 113254056Sganboldstatic driver_t a20_cpu_cfg_driver = { 114254056Sganbold "a20_cpu_cfg", 115254056Sganbold a20_cpu_cfg_methods, 116254056Sganbold sizeof(struct a20_cpu_cfg_softc), 117254056Sganbold}; 118254056Sganbold 119254056Sganboldstatic devclass_t a20_cpu_cfg_devclass; 120254056Sganbold 121254056SganboldDRIVER_MODULE(a20_cpu_cfg, simplebus, a20_cpu_cfg_driver, a20_cpu_cfg_devclass, 0, 0); 122254056Sganbold 123254056Sganbolduint64_t 124254056Sganbolda20_read_counter64(void) 125254056Sganbold{ 126254056Sganbold uint32_t lo, hi; 127254056Sganbold 128254056Sganbold /* Latch counter, wait for it to be ready to read. */ 129254056Sganbold cpu_cfg_write_4(a20_cpu_cfg_sc, OSC24M_CNT64_CTRL_REG, CNT64_RL_EN); 130254056Sganbold while (cpu_cfg_read_4(a20_cpu_cfg_sc, OSC24M_CNT64_CTRL_REG) & CNT64_RL_EN) 131254056Sganbold continue; 132254056Sganbold 133254056Sganbold hi = cpu_cfg_read_4(a20_cpu_cfg_sc, OSC24M_CNT64_HIGH_REG); 134254056Sganbold lo = cpu_cfg_read_4(a20_cpu_cfg_sc, OSC24M_CNT64_LOW_REG); 135254056Sganbold 136254056Sganbold return (((uint64_t)hi << 32) | lo); 137254056Sganbold} 138254056Sganbold 139