imx6_anatop.c revision 266152
1/*- 2 * Copyright (c) 2013 Ian Lepore <ian@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/imx/imx6_anatop.c 266152 2014-05-15 16:11:06Z ian $"); 29 30/* 31 * Analog PLL and power regulator driver for Freescale i.MX6 family of SoCs. 32 * 33 * We don't really do anything with analog PLLs, but the registers for 34 * controlling them belong to the same block as the power regulator registers. 35 * Since the newbus hierarchy makes it hard for anyone other than us to get at 36 * them, we just export a couple public functions to allow the imx6 CCM clock 37 * driver to read and write those registers. 38 * 39 * We also don't do anything about power regulation yet, but when the need 40 * arises, this would be the place for that code to live. 41 * 42 * I have no idea where the "anatop" name comes from. It's in the standard DTS 43 * source describing i.MX6 SoCs, and in the linux and u-boot code which comes 44 * from Freescale, but it's not in the SoC manual. 45 */ 46 47#include <sys/param.h> 48#include <sys/systm.h> 49#include <sys/kernel.h> 50#include <sys/module.h> 51#include <sys/bus.h> 52#include <sys/rman.h> 53 54#include <dev/ofw/ofw_bus.h> 55#include <dev/ofw/ofw_bus_subr.h> 56 57#include <machine/bus.h> 58 59#include <arm/freescale/imx/imx6_anatopreg.h> 60#include <arm/freescale/imx/imx6_anatopvar.h> 61 62struct imx6_anatop_softc { 63 device_t dev; 64 struct resource *mem_res; 65}; 66 67static struct imx6_anatop_softc *imx6_anatop_sc; 68 69uint32_t 70imx6_anatop_read_4(bus_size_t offset) 71{ 72 73 return (bus_read_4(imx6_anatop_sc->mem_res, offset)); 74} 75 76void 77imx6_anatop_write_4(bus_size_t offset, uint32_t value) 78{ 79 80 bus_write_4(imx6_anatop_sc->mem_res, offset, value); 81} 82 83static int 84imx6_anatop_detach(device_t dev) 85{ 86 struct imx6_anatop_softc *sc; 87 88 sc = device_get_softc(dev); 89 90 if (sc->mem_res != NULL) 91 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res); 92 93 return (0); 94} 95 96static int 97imx6_anatop_attach(device_t dev) 98{ 99 struct imx6_anatop_softc *sc; 100 int err, rid; 101 102 sc = device_get_softc(dev); 103 104 /* Allocate bus_space resources. */ 105 rid = 0; 106 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 107 RF_ACTIVE); 108 if (sc->mem_res == NULL) { 109 device_printf(dev, "Cannot allocate memory resources\n"); 110 err = ENXIO; 111 goto out; 112 } 113 114 imx6_anatop_sc = sc; 115 err = 0; 116 117out: 118 119 if (err != 0) 120 imx6_anatop_detach(dev); 121 122 return (err); 123} 124 125static int 126imx6_anatop_probe(device_t dev) 127{ 128 129 if (!ofw_bus_status_okay(dev)) 130 return (ENXIO); 131 132 if (ofw_bus_is_compatible(dev, "fsl,imx6q-anatop") == 0) 133 return (ENXIO); 134 135 device_set_desc(dev, "Freescale i.MX6 Analog PLLs and Power"); 136 137 return (BUS_PROBE_DEFAULT); 138} 139 140static device_method_t imx6_anatop_methods[] = { 141 /* Device interface */ 142 DEVMETHOD(device_probe, imx6_anatop_probe), 143 DEVMETHOD(device_attach, imx6_anatop_attach), 144 DEVMETHOD(device_detach, imx6_anatop_detach), 145 146 DEVMETHOD_END 147}; 148 149static driver_t imx6_anatop_driver = { 150 "imx6_anatop", 151 imx6_anatop_methods, 152 sizeof(struct imx6_anatop_softc) 153}; 154 155static devclass_t imx6_anatop_devclass; 156 157DRIVER_MODULE(imx6_anatop, simplebus, imx6_anatop_driver, imx6_anatop_devclass, 0, 0); 158 159