1220297Sadrian/*- 2220297Sadrian * Copyright (c) 2010 Aleksandr Rybalko. 3220297Sadrian * All rights reserved. 4220297Sadrian * 5220297Sadrian * Redistribution and use in source and binary forms, with or without 6220297Sadrian * modification, are permitted provided that the following conditions 7220297Sadrian * are met: 8220297Sadrian * 1. Redistributions of source code must retain the above copyright 9220297Sadrian * notice, this list of conditions and the following disclaimer. 10220297Sadrian * 2. Redistributions in binary form must reproduce the above copyright 11220297Sadrian * notice, this list of conditions and the following disclaimer in the 12220297Sadrian * documentation and/or other materials provided with the distribution. 13220297Sadrian * 14220297Sadrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15220297Sadrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16220297Sadrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17220297Sadrian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18220297Sadrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19220297Sadrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20220297Sadrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21220297Sadrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22220297Sadrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23220297Sadrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24220297Sadrian * SUCH DAMAGE. 25220297Sadrian */ 26220297Sadrian 27220297Sadrian#include <sys/cdefs.h> 28220297Sadrian__FBSDID("$FreeBSD$"); 29220297Sadrian 30220297Sadrian#include <sys/param.h> 31220297Sadrian#include <sys/systm.h> 32220297Sadrian#include <sys/bus.h> 33220297Sadrian#include <sys/interrupt.h> 34220297Sadrian#include <sys/kernel.h> 35220297Sadrian#include <sys/module.h> 36220297Sadrian#include <sys/rman.h> 37220297Sadrian#include <sys/malloc.h> 38220297Sadrian 39220297Sadrian#include <machine/bus.h> 40220297Sadrian 41220297Sadrian#include <mips/rt305x/rt305xreg.h> 42220297Sadrian#include <mips/rt305x/rt305x_sysctlvar.h> 43220297Sadrian 44220297Sadrian 45220297Sadrianstatic int rt305x_sysctl_probe(device_t); 46220297Sadrianstatic int rt305x_sysctl_attach(device_t); 47220297Sadrianstatic int rt305x_sysctl_detach(device_t); 48220297Sadrian 49220297Sadrian 50220297Sadrianstatic struct rt305x_sysctl_softc *rt305x_sysctl_softc = NULL; 51220297Sadrian 52220297Sadrianstatic void 53220297Sadrianrt305x_sysctl_dump_config(device_t dev) 54220297Sadrian{ 55220297Sadrian uint32_t val; 56220297Sadrian#define DUMPREG(r) \ 57220297Sadrian val = rt305x_sysctl_get(r); printf(" " #r "=%#08x\n", val) 58220297Sadrian 59220297Sadrian val = rt305x_sysctl_get(SYSCTL_CHIPID0_3); 60220297Sadrian printf("\tChip ID: \"%c%c%c%c", 61220297Sadrian (val >> 0 ) & 0xff, 62220297Sadrian (val >> 8 ) & 0xff, 63220297Sadrian (val >> 16) & 0xff, 64220297Sadrian (val >> 24) & 0xff); 65220297Sadrian val = rt305x_sysctl_get(SYSCTL_CHIPID4_7); 66220297Sadrian printf("%c%c%c%c\"\n", 67220297Sadrian (val >> 0 ) & 0xff, 68220297Sadrian (val >> 8 ) & 0xff, 69220297Sadrian (val >> 16) & 0xff, 70220297Sadrian (val >> 24) & 0xff); 71220297Sadrian 72220297Sadrian DUMPREG(SYSCTL_SYSCFG); 73220297Sadrian if ( val & SYSCTL_SYSCFG_INIC_EE_SDRAM) 74220297Sadrian printf("\tGet SDRAM config from EEPROM\n"); 75220297Sadrian if ( val & SYSCTL_SYSCFG_INIC_8MB_SDRAM) 76220297Sadrian printf("\tBootstrap flag is set\n"); 77220297Sadrian printf("\tGE0 mode %u\n", 78220297Sadrian ((val & SYSCTL_SYSCFG_GE0_MODE_MASK) >> 79220297Sadrian SYSCTL_SYSCFG_GE0_MODE_SHIFT)); 80220297Sadrian if ( val & SYSCTL_SYSCFG_BOOT_ADDR_1F00) 81220297Sadrian printf("\tBoot from 0x1f000000\n"); 82220297Sadrian if ( val & SYSCTL_SYSCFG_BYPASS_PLL) 83220297Sadrian printf("\tBypass PLL\n"); 84220297Sadrian if ( val & SYSCTL_SYSCFG_BIG_ENDIAN) 85220297Sadrian printf("\tBig Endian\n"); 86220297Sadrian if ( val & SYSCTL_SYSCFG_CPU_CLK_SEL_384MHZ) 87232250Sgavin printf("\tClock is 384MHz\n"); 88220297Sadrian printf("\tBoot from %u\n", 89220297Sadrian ((val & SYSCTL_SYSCFG_BOOT_FROM_MASK) >> 90220297Sadrian SYSCTL_SYSCFG_BOOT_FROM_SHIFT)); 91220297Sadrian printf("\tBootstrap test code %u\n", 92220297Sadrian ((val & SYSCTL_SYSCFG_TEST_CODE_MASK) >> 93220297Sadrian SYSCTL_SYSCFG_TEST_CODE_SHIFT)); 94220297Sadrian printf("\tSRAM_CS mode %u\n", 95220297Sadrian ((val & SYSCTL_SYSCFG_SRAM_CS_MODE_MASK) >> 96220297Sadrian SYSCTL_SYSCFG_SRAM_CS_MODE_SHIFT)); 97220297Sadrian printf("\t%umA SDRAM_CLK driving\n", 98220297Sadrian (val & SYSCTL_SYSCFG_SDRAM_CLK_DRV)?12:8); 99220297Sadrian 100220297Sadrian DUMPREG(SYSCTL_CLKCFG0); 101220297Sadrian printf("\tSDRAM_CLK_SKEW %uns\n", (val >> 30) & 0x03); 102220297Sadrian 103220297Sadrian DUMPREG(SYSCTL_CLKCFG1); 104220297Sadrian if ( val & SYSCTL_CLKCFG1_PBUS_DIV_CLK_BY2) 105220297Sadrian printf("\tPbus clock is 1/2 of System clock\n"); 106220297Sadrian if ( val & SYSCTL_CLKCFG1_OTG_CLK_EN) 107220297Sadrian printf("\tUSB OTG clock is enabled\n"); 108220297Sadrian if ( val & SYSCTL_CLKCFG1_I2S_CLK_EN) 109220297Sadrian printf("\tI2S clock is enabled\n"); 110220297Sadrian printf("\tI2S clock is %s\n", 111220297Sadrian (val & SYSCTL_CLKCFG1_I2S_CLK_SEL_EXT)? 112232250Sgavin "external":"internal 15.625MHz"); 113220297Sadrian printf("\tI2S clock divider %u\n", 114220297Sadrian ((val & SYSCTL_CLKCFG1_I2S_CLK_DIV_MASK) >> 115220297Sadrian SYSCTL_CLKCFG1_I2S_CLK_DIV_SHIFT)); 116220297Sadrian if ( val & SYSCTL_CLKCFG1_PCM_CLK_EN) 117220297Sadrian printf("\tPCM clock is enabled\n"); 118220297Sadrian 119220297Sadrian printf("\tPCM clock is %s\n", 120220297Sadrian (val & SYSCTL_CLKCFG1_PCM_CLK_SEL_EXT)? 121232250Sgavin "external":"internal 15.625MHz"); 122220297Sadrian printf("\tPCM clock divider %u\n", 123220297Sadrian ((val & SYSCTL_CLKCFG1_PCM_CLK_DIV_MASK) >> 124220297Sadrian SYSCTL_CLKCFG1_PCM_CLK_DIV_SHIFT)); 125220297Sadrian DUMPREG(SYSCTL_GPIOMODE); 126220297Sadrian#undef DUMPREG 127220297Sadrian 128220297Sadrian return; 129220297Sadrian} 130220297Sadrian 131220297Sadrianstatic int 132220297Sadrianrt305x_sysctl_probe(device_t dev) 133220297Sadrian{ 134220297Sadrian device_set_desc(dev, "RT305X System Control driver"); 135220297Sadrian return (0); 136220297Sadrian} 137220297Sadrian 138220297Sadrianstatic int 139220297Sadrianrt305x_sysctl_attach(device_t dev) 140220297Sadrian{ 141220297Sadrian struct rt305x_sysctl_softc *sc = device_get_softc(dev); 142220297Sadrian int error = 0; 143220297Sadrian 144220297Sadrian KASSERT((device_get_unit(dev) == 0), 145220297Sadrian ("rt305x_sysctl: Only one sysctl module supported")); 146220297Sadrian 147220297Sadrian if (rt305x_sysctl_softc != NULL) 148220297Sadrian return (ENXIO); 149220297Sadrian rt305x_sysctl_softc = sc; 150220297Sadrian 151220297Sadrian 152220297Sadrian /* Map control/status registers. */ 153220297Sadrian sc->mem_rid = 0; 154220297Sadrian sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 155220297Sadrian &sc->mem_rid, RF_ACTIVE); 156220297Sadrian 157220297Sadrian if (sc->mem_res == NULL) { 158220297Sadrian device_printf(dev, "couldn't map memory\n"); 159220297Sadrian error = ENXIO; 160220297Sadrian rt305x_sysctl_detach(dev); 161220297Sadrian return(error); 162220297Sadrian } 163220297Sadrian#ifdef notyet 164220297Sadrian sc->irq_rid = 0; 165220297Sadrian if ((sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, 166220297Sadrian &sc->irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) { 167220297Sadrian device_printf(dev, "unable to allocate IRQ resource\n"); 168220297Sadrian return (ENXIO); 169220297Sadrian } 170220297Sadrian 171220297Sadrian if ((bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC, 172220297Sadrian rt305x_sysctl_intr, NULL, sc, &sc->sysctl_ih))) { 173220297Sadrian device_printf(dev, 174220297Sadrian "WARNING: unable to register interrupt handler\n"); 175220297Sadrian return (ENXIO); 176220297Sadrian } 177220297Sadrian#endif 178220297Sadrian rt305x_sysctl_dump_config(dev); 179220297Sadrian 180220297Sadrian return (bus_generic_attach(dev)); 181220297Sadrian} 182220297Sadrian 183220297Sadrianstatic int 184220297Sadrianrt305x_sysctl_detach(device_t dev) 185220297Sadrian{ 186220297Sadrian struct rt305x_sysctl_softc *sc = device_get_softc(dev); 187220297Sadrian 188220297Sadrian bus_generic_detach(dev); 189220297Sadrian 190220297Sadrian if (sc->mem_res) 191220297Sadrian bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, 192220297Sadrian sc->mem_res); 193220297Sadrian#ifdef notyet 194220297Sadrian if (sc->irq_res) 195220297Sadrian bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, 196220297Sadrian sc->irq_res); 197220297Sadrian#endif 198220297Sadrian return(0); 199220297Sadrian} 200220297Sadrian 201220297Sadrian#ifdef notyet 202220297Sadrianstatic int 203220297Sadrianrt305x_sysctl_intr(void *arg) 204220297Sadrian{ 205220297Sadrian return (FILTER_HANDLED); 206220297Sadrian} 207220297Sadrian#endif 208220297Sadrian 209220297Sadrianuint32_t 210220297Sadrianrt305x_sysctl_get(uint32_t reg) 211220297Sadrian{ 212220297Sadrian struct rt305x_sysctl_softc *sc = rt305x_sysctl_softc; 213220297Sadrian return (bus_read_4(sc->mem_res, reg)); 214220297Sadrian} 215220297Sadrian 216220297Sadrianvoid 217220297Sadrianrt305x_sysctl_set(uint32_t reg, uint32_t val) 218220297Sadrian{ 219220297Sadrian struct rt305x_sysctl_softc *sc = rt305x_sysctl_softc; 220220297Sadrian bus_write_4(sc->mem_res, reg, val); 221220297Sadrian return; 222220297Sadrian} 223220297Sadrian 224220297Sadrian 225220297Sadrianstatic device_method_t rt305x_sysctl_methods[] = { 226220297Sadrian DEVMETHOD(device_probe, rt305x_sysctl_probe), 227220297Sadrian DEVMETHOD(device_attach, rt305x_sysctl_attach), 228220297Sadrian DEVMETHOD(device_detach, rt305x_sysctl_detach), 229220297Sadrian 230220297Sadrian {0, 0}, 231220297Sadrian}; 232220297Sadrian 233220297Sadrianstatic driver_t rt305x_sysctl_driver = { 234220297Sadrian "rt305x_sysctl", 235220297Sadrian rt305x_sysctl_methods, 236220297Sadrian sizeof(struct rt305x_sysctl_softc), 237220297Sadrian}; 238220297Sadrianstatic devclass_t rt305x_sysctl_devclass; 239220297Sadrian 240220297SadrianDRIVER_MODULE(rt305x_sysctl, obio, rt305x_sysctl_driver, rt305x_sysctl_devclass, 0, 0); 241