1239281Sgonzo/* 2239281Sgonzo * Copyright (c) 2010 3239281Sgonzo * Ben Gray <ben.r.gray@gmail.com>. 4239281Sgonzo * All rights reserved. 5239281Sgonzo * 6239281Sgonzo * Redistribution and use in source and binary forms, with or without 7239281Sgonzo * modification, are permitted provided that the following conditions 8239281Sgonzo * are met: 9239281Sgonzo * 1. Redistributions of source code must retain the above copyright 10239281Sgonzo * notice, this list of conditions and the following disclaimer. 11239281Sgonzo * 2. Redistributions in binary form must reproduce the above copyright 12239281Sgonzo * notice, this list of conditions and the following disclaimer in the 13239281Sgonzo * documentation and/or other materials provided with the distribution. 14239281Sgonzo * 3. All advertising materials mentioning features or use of this software 15239281Sgonzo * must display the following acknowledgement: 16239281Sgonzo * This product includes software developed by Ben Gray. 17239281Sgonzo * 4. The name of the company nor the name of the author may be used to 18239281Sgonzo * endorse or promote products derived from this software without specific 19239281Sgonzo * prior written permission. 20239281Sgonzo * 21239281Sgonzo * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``AS IS'' AND ANY EXPRESS OR 22239281Sgonzo * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23239281Sgonzo * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24239281Sgonzo * IN NO EVENT SHALL BEN GRAY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25239281Sgonzo * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26239281Sgonzo * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27239281Sgonzo * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28239281Sgonzo * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29239281Sgonzo * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 30239281Sgonzo * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31239281Sgonzo */ 32239281Sgonzo 33239281Sgonzo/** 34239281Sgonzo * SCM - System Control Module 35239281Sgonzo * 36239281Sgonzo * Hopefully in the end this module will contain a bunch of utility functions 37239281Sgonzo * for configuring and querying the general system control registers, but for 38239281Sgonzo * now it only does pin(pad) multiplexing. 39239281Sgonzo * 40239281Sgonzo * This is different from the GPIO module in that it is used to configure the 41239281Sgonzo * pins between modules not just GPIO input/output. 42239281Sgonzo * 43239281Sgonzo * This file contains the generic top level driver, however it relies on chip 44239281Sgonzo * specific settings and therefore expects an array of ti_scm_padconf structs 45239281Sgonzo * call ti_padconf_devmap to be located somewhere in the kernel. 46239281Sgonzo * 47239281Sgonzo */ 48239281Sgonzo#include <sys/cdefs.h> 49239281Sgonzo__FBSDID("$FreeBSD: releng/11.0/sys/arm/ti/ti_scm.c 299069 2016-05-04 15:48:59Z pfg $"); 50239281Sgonzo 51239281Sgonzo#include <sys/param.h> 52239281Sgonzo#include <sys/systm.h> 53239281Sgonzo#include <sys/kernel.h> 54239281Sgonzo#include <sys/module.h> 55239281Sgonzo#include <sys/bus.h> 56239281Sgonzo#include <sys/resource.h> 57239281Sgonzo#include <sys/rman.h> 58239281Sgonzo#include <sys/lock.h> 59239281Sgonzo#include <sys/mutex.h> 60239281Sgonzo 61239281Sgonzo#include <machine/bus.h> 62239281Sgonzo#include <machine/cpu.h> 63239281Sgonzo#include <machine/cpufunc.h> 64239281Sgonzo#include <machine/resource.h> 65239281Sgonzo 66239281Sgonzo#include <dev/fdt/fdt_common.h> 67283276Sgonzo#include <dev/fdt/fdt_pinctrl.h> 68239281Sgonzo#include <dev/ofw/openfirm.h> 69239281Sgonzo#include <dev/ofw/ofw_bus.h> 70239281Sgonzo#include <dev/ofw/ofw_bus_subr.h> 71239281Sgonzo 72239281Sgonzo#include "ti_scm.h" 73239281Sgonzo 74239281Sgonzostatic struct resource_spec ti_scm_res_spec[] = { 75239281Sgonzo { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Control memory window */ 76239281Sgonzo { -1, 0 } 77239281Sgonzo}; 78239281Sgonzo 79239281Sgonzostatic struct ti_scm_softc *ti_scm_sc; 80239281Sgonzo 81239281Sgonzo#define ti_scm_read_4(sc, reg) \ 82239281Sgonzo bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) 83239281Sgonzo#define ti_scm_write_4(sc, reg, val) \ 84239281Sgonzo bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 85239281Sgonzo 86239281Sgonzo/* 87239281Sgonzo * Device part of OMAP SCM driver 88239281Sgonzo */ 89239281Sgonzostatic int 90239281Sgonzoti_scm_probe(device_t dev) 91239281Sgonzo{ 92261410Sian if (!ofw_bus_status_okay(dev)) 93261410Sian return (ENXIO); 94261410Sian 95283276Sgonzo if (!ofw_bus_is_compatible(dev, "syscon")) 96239281Sgonzo return (ENXIO); 97239281Sgonzo 98283276Sgonzo if (ti_scm_sc) { 99283276Sgonzo return (EEXIST); 100283276Sgonzo } 101283276Sgonzo 102239281Sgonzo device_set_desc(dev, "TI Control Module"); 103239281Sgonzo return (BUS_PROBE_DEFAULT); 104239281Sgonzo} 105239281Sgonzo 106239281Sgonzo/** 107239281Sgonzo * ti_scm_attach - attaches the timer to the simplebus 108239281Sgonzo * @dev: new device 109239281Sgonzo * 110239281Sgonzo * Reserves memory and interrupt resources, stores the softc structure 111239281Sgonzo * globally and registers both the timecount and eventtimer objects. 112239281Sgonzo * 113239281Sgonzo * RETURNS 114299069Spfg * Zero on success or ENXIO if an error occuried. 115239281Sgonzo */ 116239281Sgonzostatic int 117239281Sgonzoti_scm_attach(device_t dev) 118239281Sgonzo{ 119239281Sgonzo struct ti_scm_softc *sc = device_get_softc(dev); 120239281Sgonzo 121239281Sgonzo sc->sc_dev = dev; 122239281Sgonzo 123239281Sgonzo if (bus_alloc_resources(dev, ti_scm_res_spec, sc->sc_res)) { 124239281Sgonzo device_printf(dev, "could not allocate resources\n"); 125239281Sgonzo return (ENXIO); 126239281Sgonzo } 127239281Sgonzo 128239281Sgonzo /* Global timer interface */ 129239281Sgonzo sc->sc_bst = rman_get_bustag(sc->sc_res[0]); 130239281Sgonzo sc->sc_bsh = rman_get_bushandle(sc->sc_res[0]); 131239281Sgonzo 132239281Sgonzo ti_scm_sc = sc; 133239281Sgonzo 134239281Sgonzo return (0); 135239281Sgonzo} 136239281Sgonzo 137239281Sgonzoint 138239281Sgonzoti_scm_reg_read_4(uint32_t reg, uint32_t *val) 139239281Sgonzo{ 140239281Sgonzo if (!ti_scm_sc) 141239281Sgonzo return (ENXIO); 142239281Sgonzo 143239281Sgonzo *val = ti_scm_read_4(ti_scm_sc, reg); 144239281Sgonzo return (0); 145239281Sgonzo} 146239281Sgonzo 147239281Sgonzoint 148239281Sgonzoti_scm_reg_write_4(uint32_t reg, uint32_t val) 149239281Sgonzo{ 150239281Sgonzo if (!ti_scm_sc) 151239281Sgonzo return (ENXIO); 152239281Sgonzo 153239281Sgonzo ti_scm_write_4(ti_scm_sc, reg, val); 154239281Sgonzo return (0); 155239281Sgonzo} 156239281Sgonzo 157239281Sgonzo 158239281Sgonzostatic device_method_t ti_scm_methods[] = { 159239281Sgonzo DEVMETHOD(device_probe, ti_scm_probe), 160239281Sgonzo DEVMETHOD(device_attach, ti_scm_attach), 161283276Sgonzo 162239281Sgonzo { 0, 0 } 163239281Sgonzo}; 164239281Sgonzo 165239281Sgonzostatic driver_t ti_scm_driver = { 166239281Sgonzo "ti_scm", 167239281Sgonzo ti_scm_methods, 168239281Sgonzo sizeof(struct ti_scm_softc), 169239281Sgonzo}; 170239281Sgonzo 171239281Sgonzostatic devclass_t ti_scm_devclass; 172239281Sgonzo 173295660SskraEARLY_DRIVER_MODULE(ti_scm, simplebus, ti_scm_driver, ti_scm_devclass, 0, 0, 174295660Sskra BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); 175