Index: projects/ci20_mips/sys/mips/conf/CI20 =================================================================== --- projects/ci20_mips/sys/mips/conf/CI20 (nonexistent) +++ projects/ci20_mips/sys/mips/conf/CI20 (revision 283030) @@ -0,0 +1,37 @@ +# $FreeBSD: $ + +machine mips mips +cpu CPU_MIPS74KC +ident CI20 +machine mips mips +makeoptions KERNLOADADDR=0x80050000 +options HZ=1000 + + +files "../ingenic/files.ingenic" + +# Don't build any modules yet. +makeoptions MODULES_OVERRIDE="" + +makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols + +options DDB +options KDB + +options SCHED_4BSD #4BSD scheduler +options INET #InterNETworking +options NFSCL #Network Filesystem Client +options NFS_ROOT #NFS usable as /, requires NFSCL +options PSEUDOFS #Pseudo-filesystem framework +options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions + +# Debugging for use in -current +options DEADLKRES #Enable the deadlock resolver +options INVARIANTS #Enable calls of extra sanity checking +options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS +options WITNESS #Enable checks to detect deadlocks and cycles +options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed + +device loop +device ether +device md Index: projects/ci20_mips/sys/mips/ingenic/apbus.c =================================================================== --- projects/ci20_mips/sys/mips/ingenic/apbus.c (nonexistent) +++ projects/ci20_mips/sys/mips/ingenic/apbus.c (revision 283030) @@ -0,0 +1,275 @@ +/* $NetBSD: apbus.c,v 1.14 2015/05/04 12:23:15 macallan Exp $ */ + +/*- + * Copyright (c) 2014 Michael Lorenz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* catch-all for on-chip peripherals */ + +#include +__KERNEL_RCSID(0, "$NetBSD: apbus.c,v 1.14 2015/05/04 12:23:15 macallan Exp $"); + +#include "locators.h" +#define _MIPS_BUS_DMA_PRIVATE + +#include +#include +#include +#include +#include + +#include +#include + +#include "opt_ingenic.h" + +static int apbus_match(device_t, cfdata_t, void *); +static void apbus_attach(device_t, device_t, void *); +static int apbus_print(void *, const char *); +static void apbus_bus_mem_init(bus_space_tag_t, void *); + +CFATTACH_DECL_NEW(apbus, 0, apbus_match, apbus_attach, NULL, NULL); + +static struct mips_bus_space apbus_mbst; +bus_space_tag_t apbus_memt = NULL; + +struct mips_bus_dma_tag apbus_dmat = { + ._bounce_alloc_hi = 0x10000000, + ._dmamap_ops = _BUS_DMAMAP_OPS_INITIALIZER, + ._dmamem_ops = _BUS_DMAMEM_OPS_INITIALIZER, + ._dmatag_ops = _BUS_DMATAG_OPS_INITIALIZER, +}; + +typedef struct apbus_dev { + const char *name; /* driver name */ + bus_addr_t addr; /* base address */ + uint32_t irq; /* interrupt */ + uint32_t clk0; /* bit(s) in CLKGR0 */ + uint32_t clk1; /* bit(s) in CLKGR1 */ +} apbus_dev_t; + +static const apbus_dev_t apbus_devs[] = { + { "dwctwo", JZ_DWC2_BASE, 21, CLK_OTG0 | CLK_UHC, CLK_OTG1}, + { "ohci", JZ_OHCI_BASE, 5, CLK_UHC, 0}, + { "ehci", JZ_EHCI_BASE, 20, CLK_UHC, 0}, + { "dme", JZ_DME_BASE, -1, 0, 0}, + { "jzgpio", JZ_GPIO_A_BASE, 17, 0, 0}, + { "jzgpio", JZ_GPIO_B_BASE, 16, 0, 0}, + { "jzgpio", JZ_GPIO_C_BASE, 15, 0, 0}, + { "jzgpio", JZ_GPIO_D_BASE, 14, 0, 0}, + { "jzgpio", JZ_GPIO_E_BASE, 13, 0, 0}, + { "jzgpio", JZ_GPIO_F_BASE, 12, 0, 0}, + { "jziic", JZ_SMB0_BASE, 60, CLK_SMB0, 0}, + { "jziic", JZ_SMB1_BASE, 59, CLK_SMB1, 0}, + { "jziic", JZ_SMB2_BASE, 58, CLK_SMB2, 0}, + { "jziic", JZ_SMB3_BASE, 57, 0, CLK_SMB3}, + { "jziic", JZ_SMB4_BASE, 56, 0, CLK_SMB4}, + { "jzmmc", JZ_MSC0_BASE, 37, CLK_MSC0, 0}, + { "jzmmc", JZ_MSC1_BASE, 36, CLK_MSC1, 0}, + { "jzmmc", JZ_MSC2_BASE, 35, CLK_MSC2, 0}, + { "jzfb", JZ_LCDC0_BASE, 31, CLK_LCD, CLK_HDMI}, + { NULL, -1, -1, 0, 0} +}; + +void +apbus_init(void) +{ + static bool done = false; + if (done) + return; + done = true; + + apbus_bus_mem_init(&apbus_mbst, NULL); + apbus_memt = &apbus_mbst; +} + +int +apbus_match(device_t parent, cfdata_t match, void *aux) +{ + struct mainbusdev { + const char *md_name; + } *aa = aux; + if (strcmp(aa->md_name, "apbus") == 0) return 1; + return 0; +} + +void +apbus_attach(device_t parent, device_t self, void *aux) +{ + uint32_t reg, mpll, m, n, p, mclk, pclk, pdiv, cclk, cdiv; + aprint_normal("\n"); + + /* should have been called early on */ + apbus_init(); + +#ifdef INGENIC_DEBUG + printf("core ctrl: %08x\n", MFC0(12, 2)); + printf("core status: %08x\n", MFC0(12, 3)); + printf("REIM: %08x\n", MFC0(12, 4)); + printf("ID: %08x\n", MFC0(15, 1)); +#endif + /* assuming we're using MPLL */ + mpll = readreg(JZ_CPMPCR); + m = (mpll & JZ_PLLM_M) >> JZ_PLLM_S; + n = (mpll & JZ_PLLN_M) >> JZ_PLLN_S; + p = (mpll & JZ_PLLP_M) >> JZ_PLLP_S; + + /* assuming 48MHz EXTCLK */ + mclk = (48000 * (m + 1) / (n + 1)) / (p + 1); + + reg = readreg(JZ_CPCCR); + pdiv = ((reg & JZ_PDIV_M) >> JZ_PDIV_S) + 1; + pclk = mclk / pdiv; + cdiv = (reg & JZ_CDIV_M) + 1; + cclk = mclk / cdiv; + + aprint_debug_dev(self, "mclk %d kHz\n", mclk); + aprint_debug_dev(self, "pclk %d kHz\n", pclk); + aprint_debug_dev(self, "CPU clock %d kHz\n", cclk); + + /* enable clocks */ + reg = readreg(JZ_CLKGR1); + reg &= ~CLK_AHB_MON; /* AHB_MON clock */ + writereg(JZ_CLKGR1, reg); + + /* wake up the USB part */ + reg = readreg(JZ_OPCR); + reg |= OPCR_SPENDN0 | OPCR_SPENDN1; + writereg(JZ_OPCR, reg); + + /* wire up GPIOs */ + /* iic0 */ + gpio_as_dev0(3, 30); + gpio_as_dev0(3, 31); + /* iic1 */ + gpio_as_dev0(4, 30); + gpio_as_dev0(4, 31); + /* iic2 */ + gpio_as_dev2(5, 16); + gpio_as_dev2(5, 17); + /* iic3 */ + gpio_as_dev1(3, 10); + gpio_as_dev1(3, 11); + /* iic4 */ + /* make sure these aren't SMB4 */ + gpio_as_dev3(4, 3); + gpio_as_dev3(4, 4); + /* these are supposed to be connected to the RTC */ + gpio_as_dev1(4, 12); + gpio_as_dev1(4, 13); + /* these can be DDC2 or SMB4, set them to DDC2 */ + gpio_as_dev0(5, 24); + gpio_as_dev0(5, 25); + + /* MSC0 */ + gpio_as_dev1(0, 4); + gpio_as_dev1(0, 5); + gpio_as_dev1(0, 6); + gpio_as_dev1(0, 7); + gpio_as_dev1(0, 18); + gpio_as_dev1(0, 19); + gpio_as_dev1(0, 20); + gpio_as_dev1(0, 21); + gpio_as_dev1(0, 22); + gpio_as_dev1(0, 23); + gpio_as_dev1(0, 24); + gpio_as_intr_level_low(5, 20); /* card detect */ + + /* MSC1, for wifi/bt */ + gpio_as_dev0(3, 20); + gpio_as_dev0(3, 21); + gpio_as_dev0(3, 22); + gpio_as_dev0(3, 23); + gpio_as_dev0(3, 24); + gpio_as_dev0(3, 25); + + /* MSC2, on expansion header */ + gpio_as_dev0(1, 20); + gpio_as_dev0(1, 21); + gpio_as_dev0(1, 28); + gpio_as_dev0(1, 29); + gpio_as_dev0(1, 30); + gpio_as_dev0(1, 31); + +#ifdef INGENIC_DEBUG + printf("JZ_CLKGR0 %08x\n", readreg(JZ_CLKGR0)); + printf("JZ_CLKGR1 %08x\n", readreg(JZ_CLKGR1)); + printf("JZ_SPCR0 %08x\n", readreg(JZ_SPCR0)); + printf("JZ_SPCR1 %08x\n", readreg(JZ_SPCR1)); + printf("JZ_SRBC %08x\n", readreg(JZ_SRBC)); + printf("JZ_OPCR %08x\n", readreg(JZ_OPCR)); + printf("JZ_UHCCDR %08x\n", readreg(JZ_UHCCDR)); +#endif + + for (const apbus_dev_t *adv = apbus_devs; adv->name != NULL; adv++) { + struct apbus_attach_args aa; + aa.aa_name = adv->name; + aa.aa_addr = adv->addr; + aa.aa_irq = adv->irq; + aa.aa_dmat = &apbus_dmat; + aa.aa_bst = apbus_memt; + aa.aa_pclk = pclk; + aa.aa_mclk = mclk; + + /* enable clocks as needed */ + if (adv->clk0 != 0) { + reg = readreg(JZ_CLKGR0); + reg &= ~adv->clk0; + writereg(JZ_CLKGR0, reg); + } + + if (adv->clk1 != 0) { + reg = readreg(JZ_CLKGR1); + reg &= ~adv->clk1; + writereg(JZ_CLKGR1, reg); + } + + (void) config_found_ia(self, "apbus", &aa, apbus_print); + } +} + +int +apbus_print(void *aux, const char *pnp) +{ + struct apbus_attach_args *aa = aux; + + if (pnp) { + aprint_normal("%s at %s", aa->aa_name, pnp); + } + if (aa->aa_addr != -1) + aprint_normal(" addr 0x%" PRIxBUSADDR, aa->aa_addr); + if ((pnp == NULL) && (aa->aa_irq != -1)) + aprint_normal(" irq %d", aa->aa_irq); + return (UNCONF); +} + +#define CHIP apbus +#define CHIP_MEM /* defined */ +#define CHIP_W1_BUS_START(v) 0x10000000UL +#define CHIP_W1_BUS_END(v) 0x20000000UL +#define CHIP_W1_SYS_START(v) 0x10000000UL +#define CHIP_W1_SYS_END(v) 0x20000000UL + +#include Property changes on: projects/ci20_mips/sys/mips/ingenic/apbus.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: projects/ci20_mips/sys/mips/ingenic/files.ingenic =================================================================== --- projects/ci20_mips/sys/mips/ingenic/files.ingenic (nonexistent) +++ projects/ci20_mips/sys/mips/ingenic/files.ingenic (revision 283030) @@ -0,0 +1,15 @@ +# $FreeBSD: $ + +mips/ingenic/apbus.c optional ingenic_abp +mips/ingenic/ingenic_com.c optional uart_ignenic +mips/ingenic/ingenic_dwctwo.c optional test +mips/ingenic/ingenic_ohci.c optional test +mips/ingenic/ingenic_ehci.c optional test +mips/ingenic/ingenic_dme.c optional test +mips/ingenic/jziic.c optional test + +mips/ingenic/ingenic_machdep.c standard +mips/mips/intr_machdep.c standard +mips/mips/tick.c standard + +dev/hwpmc/hwpmc_mips24k.c optional hwpmc_mips24k Index: projects/ci20_mips/sys/mips/ingenic/ingenic_com.c =================================================================== --- projects/ci20_mips/sys/mips/ingenic/ingenic_com.c (nonexistent) +++ projects/ci20_mips/sys/mips/ingenic/ingenic_com.c (revision 283030) @@ -0,0 +1,205 @@ +/* $NetBSD: ingenic_com.c,v 1.4 2015/03/07 15:35:33 macallan Exp $ */ + +/*- + * Copyright (c) 2014 Michael Lorenz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: ingenic_com.c,v 1.4 2015/03/07 15:35:33 macallan Exp $"); + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include + +#include "opt_com.h" + +volatile int32_t *com0addr = (int32_t *)MIPS_PHYS_TO_KSEG1(JZ_UART0); + +void ingenic_putchar_init(void); +void ingenic_puts(const char *); +void ingenic_putchar(char); + +#ifndef CONMODE +# define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) +#endif + + +static struct mips_bus_space ingenic_com_mbst; +static int mbst_valid = 0; +static void ingenic_com_bus_mem_init(bus_space_tag_t, void *); +void ingenic_com_cnattach(void); + +static int ingenic_com_match(device_t, cfdata_t , void *); +static void ingenic_com_attach(device_t, device_t, void *); + +struct ingenic_com_softc { + struct com_softc sc_com; +}; + +CFATTACH_DECL_NEW(com_mainbus, sizeof(struct ingenic_com_softc), + ingenic_com_match, ingenic_com_attach, NULL, NULL); + +bus_space_handle_t regh = 0; + +void +ingenic_putchar_init(void) +{ + /* + * XXX don't screw with the UART's speed until we know what clock + * we're on + */ +#if 0 + int rate; +#endif + extern int comspeed(long, long, int); + + com0addr = (uint32_t *)MIPS_PHYS_TO_KSEG1(JZ_UART0); +#if 0 + if (comcnfreq != -1) { + rate = comspeed(comcnspeed, comcnfreq, COM_TYPE_INGENIC); + if (rate < 0) + return; /* XXX */ +#endif + com0addr[com_ier] = 0; + com0addr[com_lctl] = htole32(LCR_DLAB); +#if 0 + com0addr[com_dlbl] = htole32(rate & 0xff); + com0addr[com_dlbh] = htole32(rate >> 8); +#endif + com0addr[com_lctl] = htole32(LCR_8BITS); /* XXX */ + com0addr[com_mcr] = htole32(MCR_DTR|MCR_RTS); + com0addr[com_fifo] = htole32( + FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | + FIFO_TRIGGER_1 | FIFO_UART_ON); +#if 0 + } +#endif +} + + +void +ingenic_putchar(char c) +{ + int timo = 150000; + + while ((le32toh(com0addr[com_lsr]) & LSR_TXRDY) == 0) + if (--timo == 0) + break; + + com0addr[com_data] = htole32((uint32_t)c); + + while ((le32toh(com0addr[com_lsr]) & LSR_TSRE) == 0) + if (--timo == 0) + break; +} + +void +ingenic_puts(const char *restrict s) +{ + char c; + + while ((c = *s++) != 0) + ingenic_putchar(c); +} + +static void +ingenic_com_bus_init(void) +{ + if (mbst_valid) return; + ingenic_com_bus_mem_init(&ingenic_com_mbst, NULL); + mbst_valid = 1; +} + +void +ingenic_com_cnattach(void) +{ + struct com_regs regs; + + ingenic_com_bus_init(); + bus_space_map(&ingenic_com_mbst, 0, 0x1000, 0, ®h); + + memset(®s, 0, sizeof(regs)); + COM_INIT_REGS(regs, &ingenic_com_mbst, regh, 0); + + /* + * XXX + * UART clock is either 6MHz or 12MHz, the manual is rather unclear + * so we just leave alone whatever u-boot set up + * my uplcom is too tolerant to show any difference + */ + comcnattach1(®s, 115200, 48000000, COM_TYPE_INGENIC, CONMODE); +} + +static int +ingenic_com_match(device_t parent, cfdata_t cfdata, void *args) +{ + struct mainbusdev { + const char *md_name; + } *aa = args; + if (strcmp(aa->md_name, "com") == 0) return 1; + return 0; +} + + +static void +ingenic_com_attach(device_t parent, device_t self, void *args) +{ + struct ingenic_com_softc *isc = device_private(self); + struct com_softc *sc = &isc->sc_com; + + sc->sc_dev = self; + sc->sc_frequency = 48000000; + sc->sc_type = COM_TYPE_INGENIC; + memset(&sc->sc_regs, 0, sizeof(sc->sc_regs)); + COM_INIT_REGS(sc->sc_regs, &ingenic_com_mbst, regh, 0); + com_attach_subr(sc); + printf("\n"); + evbmips_intr_establish(51, comintr, sc); +} + +#define CHIP ingenic_com +#define CHIP_MEM /* defined */ +#define CHIP_W1_BUS_START(v) 0x00000000UL +#define CHIP_W1_BUS_END(v) 0x00010000UL +#define CHIP_W1_SYS_START(v) 0x10030000UL +#define CHIP_W1_SYS_END(v) 0x10035000UL +#define CHIP_ACCESS_SIZE 1 +#define CHIP_ALIGN_STRIDE 2 + +#include Property changes on: projects/ci20_mips/sys/mips/ingenic/ingenic_com.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: projects/ci20_mips/sys/mips/ingenic/ingenic_dme.c =================================================================== --- projects/ci20_mips/sys/mips/ingenic/ingenic_dme.c (nonexistent) +++ projects/ci20_mips/sys/mips/ingenic/ingenic_dme.c (revision 283030) @@ -0,0 +1,165 @@ +/* $NetBSD: ingenic_dme.c,v 1.1 2015/03/10 18:15:47 macallan Exp $ */ + +/*- + * Copyright (c) 2015 Michael Lorenz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: ingenic_dme.c,v 1.1 2015/03/10 18:15:47 macallan Exp $"); + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include "opt_ingenic.h" + +static int ingenic_dme_match(device_t, struct cfdata *, void *); +static void ingenic_dme_attach(device_t, device_t, void *); +static int ingenic_dme_intr(void *); + +CFATTACH_DECL_NEW(ingenic_dme, sizeof(struct dme_softc), + ingenic_dme_match, ingenic_dme_attach, NULL, NULL); + +#define GPIO_DME_INT 19 +#define GPIO_DME_INT_MASK (1 << GPIO_DME_INT) + +/* ARGSUSED */ +static int +ingenic_dme_match(device_t parent, struct cfdata *match, void *aux) +{ + struct apbus_attach_args *aa = aux; + + if (strcmp(aa->aa_name, "dme") != 0) + return 0; + + return 1; +} + +/* ARGSUSED */ +static void +ingenic_dme_attach(device_t parent, device_t self, void *aux) +{ + struct dme_softc *sc = device_private(self); + struct apbus_attach_args *aa = aux; + void *ih; + static uint8_t enaddr[ETHER_ADDR_LEN]; + int error; + + sc->sc_dev = self; + + sc->sc_iot = aa->aa_bst; + sc->dme_io = JZ_DME_IO; + sc->dme_data = JZ_DME_DATA; + sc->sc_phy_initialized = 0; + + if (aa->aa_addr == 0) + aa->aa_addr = JZ_DME_BASE; + + error = bus_space_map(aa->aa_bst, aa->aa_addr, 4, 0, &sc->sc_ioh); + if (error) { + aprint_error_dev(self, + "can't map registers for %s: %d\n", aa->aa_name, error); + return; + } + + aprint_naive(": DM9000 Ethernet controller\n"); + aprint_normal(": DM9000 Ethernet controller\n"); + + + /* make sure the chip is powered up and not in reset */ + gpio_as_output(1, 25); + gpio_set(1, 25, 1); + gpio_as_output(5, 12); + gpio_set(5, 12, 1); + + /* setup pins to talk to the chip */ + gpio_as_dev0(1, 1); + gpio_as_dev0(0, 0); + gpio_as_dev0(0, 1); + gpio_as_dev0(0, 2); + gpio_as_dev0(0, 3); + gpio_as_dev0(0, 4); + gpio_as_dev0(0, 5); + gpio_as_dev0(0, 6); + gpio_as_dev0(0, 7); + + gpio_as_dev0(0, 16); + gpio_as_dev0(0, 17); + gpio_as_dev0(0, 26); + + /* DM9000 interrupt is on GPIO E pin 19 */ + gpio_as_intr_level(4, GPIO_DME_INT); + ih = evbmips_intr_establish(13, ingenic_dme_intr, sc); + + if (ih == NULL) { + aprint_error_dev(self, "failed to establish interrupt %d\n", + 13); + goto fail; + } + + /* + * XXX grab MAC address set by uboot + * I'm not sure uboot will program the MAC address into the chip when + * not netbooting, so this needs to go away + */ + dme_read_c(sc, DM9000_PAB0, enaddr, 6); + dme_attach(sc, enaddr); + return; +fail: + if (ih) { + evbmips_intr_disestablish(ih); + } + bus_space_unmap(sc->sc_iot, sc->sc_ioh, 4); +} + +static int +ingenic_dme_intr(void *arg) +{ + uint32_t reg; + int ret = 0; + + /* see if it's us */ + reg = readreg(JZ_GPIO_E_BASE + JZ_GPIO_FLAG); + if (reg & GPIO_DME_INT_MASK) { + /* yes, it's ours, handle it... */ + ret = dme_intr(arg); + /* ... and clear it */ + writereg(JZ_GPIO_E_BASE + JZ_GPIO_FLAGC, GPIO_DME_INT_MASK); + } + return ret; +} Property changes on: projects/ci20_mips/sys/mips/ingenic/ingenic_dme.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: projects/ci20_mips/sys/mips/ingenic/ingenic_dwctwo.c =================================================================== --- projects/ci20_mips/sys/mips/ingenic/ingenic_dwctwo.c (nonexistent) +++ projects/ci20_mips/sys/mips/ingenic/ingenic_dwctwo.c (revision 283030) @@ -0,0 +1,216 @@ +/* $NetBSD: ingenic_dwctwo.c,v 1.10 2015/04/28 15:07:07 macallan Exp $ */ + +/*- + * Copyright (c) 2014 Michael Lorenz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: ingenic_dwctwo.c,v 1.10 2015/04/28 15:07:07 macallan Exp $"); + +/* + * adapted from bcm2835_dwctwo.c + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include "dwc2_core.h" + +#include "opt_ingenic.h" + +struct ingenic_dwc2_softc { + struct dwc2_softc sc_dwc2; + + void *sc_ih; +}; + +static struct dwc2_core_params ingenic_dwc2_params = { + .otg_cap = -1, /* HNP/SRP capable */ + .otg_ver = -1, /* 1.3 */ + .dma_enable = 1, + .dma_desc_enable = 0, + .speed = -1, /* High Speed */ + .enable_dynamic_fifo = -1, + .en_multiple_tx_fifo = -1, + .host_rx_fifo_size = 1024, /* 1024 DWORDs */ + .host_nperio_tx_fifo_size = 1024, /* 1024 DWORDs */ + .host_perio_tx_fifo_size = 1024, /* 1024 DWORDs */ + .max_transfer_size = -1, + .max_packet_count = -1, + .host_channels = -1, + .phy_type = -1, /* UTMI */ + .phy_utmi_width = -1, /* 16 bits */ + .phy_ulpi_ddr = -1, /* Single */ + .phy_ulpi_ext_vbus = -1, + .i2c_enable = -1, + .ulpi_fs_ls = -1, + .host_support_fs_ls_low_power = -1, + .host_ls_low_power_phy_clk = -1, /* 48 MHz */ + .ts_dline = -1, + .reload_ctl = -1, + .ahbcfg = -1, + .uframe_sched = 0, +}; + +static int ingenic_dwc2_match(device_t, struct cfdata *, void *); +static void ingenic_dwc2_attach(device_t, device_t, void *); +static void ingenic_dwc2_deferred(device_t); + +CFATTACH_DECL_NEW(ingenic_dwctwo, sizeof(struct ingenic_dwc2_softc), + ingenic_dwc2_match, ingenic_dwc2_attach, NULL, NULL); + +/* ARGSUSED */ +static int +ingenic_dwc2_match(device_t parent, struct cfdata *match, void *aux) +{ + struct apbus_attach_args *aa = aux; + + if (strcmp(aa->aa_name, "dwctwo") != 0) + return 0; + + return 1; +} + +/* ARGSUSED */ +static void +ingenic_dwc2_attach(device_t parent, device_t self, void *aux) +{ + struct ingenic_dwc2_softc *sc = device_private(self); + struct apbus_attach_args *aa = aux; + uint32_t reg; + int error; + + sc->sc_dwc2.sc_dev = self; + + sc->sc_dwc2.sc_iot = aa->aa_bst; + sc->sc_dwc2.sc_bus.dmatag = aa->aa_dmat; + sc->sc_dwc2.sc_params = &ingenic_dwc2_params; + + if (aa->aa_addr == 0) + aa->aa_addr = JZ_DWC2_BASE; + + error = bus_space_map(aa->aa_bst, aa->aa_addr, 0x20000, 0, + &sc->sc_dwc2.sc_ioh); + if (error) { + aprint_error_dev(self, + "can't map registers for %s: %d\n", aa->aa_name, error); + return; + } + + aprint_naive(": USB OTG controller\n"); + aprint_normal(": USB OTG controller\n"); + + /* reset PHY, flash LED */ + gpio_set(5, 15, 0); + delay(250000); + gpio_set(5, 15, 1); + + reg = readreg(JZ_USBPCR); + reg |= PCR_VBUSVLDEXTSEL; + reg |= PCR_VBUSVLDEXT; + reg |= PCR_USB_MODE; + reg |= PCR_COMMONONN; + reg &= ~PCR_OTG_DISABLE; + writereg(JZ_USBPCR, reg); +#ifdef INGENIC_DEBUG + printf("JZ_USBPCR %08x\n", reg); +#endif + + reg = readreg(JZ_USBPCR1); + reg |= PCR_SYNOPSYS; + reg |= PCR_REFCLK_CORE; + reg &= ~PCR_CLK_M; + reg |= PCR_CLK_48; + reg |= PCR_WORD_I_F0; + reg |= PCR_WORD_I_F1; + writereg(JZ_USBPCR1, reg); +#ifdef INGENIC_DEBUG + printf("JZ_USBPCR1 %08x\n", reg); + printf("JZ_USBRDT %08x\n", readreg(JZ_USBRDT)); +#endif + + delay(10000); + + reg = readreg(JZ_USBPCR); + reg |= PCR_POR; + writereg(JZ_USBPCR, reg); + delay(1000); + reg &= ~PCR_POR; + writereg(JZ_USBPCR, reg); + + delay(10000); + + sc->sc_ih = evbmips_intr_establish(aa->aa_irq, dwc2_intr, &sc->sc_dwc2); + + if (sc->sc_ih == NULL) { + aprint_error_dev(self, "failed to establish interrupt %d\n", + aa->aa_irq); + goto fail; + } + + config_defer(self, ingenic_dwc2_deferred); + + return; + +fail: + if (sc->sc_ih) { + evbmips_intr_disestablish(sc->sc_ih); + sc->sc_ih = NULL; + } + bus_space_unmap(sc->sc_dwc2.sc_iot, sc->sc_dwc2.sc_ioh, 0x20000); +} + +static void +ingenic_dwc2_deferred(device_t self) +{ + struct ingenic_dwc2_softc *sc = device_private(self); + int error; + + sc->sc_dwc2.sc_id_vendor = USB_VENDOR_INGENIC; + strlcpy(sc->sc_dwc2.sc_vendor, "Ingenic", sizeof(sc->sc_dwc2.sc_vendor)); + error = dwc2_init(&sc->sc_dwc2); + if (error != 0) { + aprint_error_dev(self, "couldn't initialize host, error=%d\n", + error); + return; + } + sc->sc_dwc2.sc_child = config_found(sc->sc_dwc2.sc_dev, + &sc->sc_dwc2.sc_bus, usbctlprint); +} Property changes on: projects/ci20_mips/sys/mips/ingenic/ingenic_dwctwo.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: projects/ci20_mips/sys/mips/ingenic/ingenic_ehci.c =================================================================== --- projects/ci20_mips/sys/mips/ingenic/ingenic_ehci.c (nonexistent) +++ projects/ci20_mips/sys/mips/ingenic/ingenic_ehci.c (revision 283030) @@ -0,0 +1,155 @@ +/* $NetBSD: ingenic_ehci.c,v 1.3 2015/03/17 09:27:09 macallan Exp $ */ + +/*- + * Copyright (c) 2015 Michael Lorenz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: ingenic_ehci.c,v 1.3 2015/03/17 09:27:09 macallan Exp $"); + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include "opt_ingenic.h" +#include "ohci.h" + +static int ingenic_ehci_match(device_t, struct cfdata *, void *); +static void ingenic_ehci_attach(device_t, device_t, void *); + +CFATTACH_DECL_NEW(ingenic_ehci, sizeof(struct ehci_softc), + ingenic_ehci_match, ingenic_ehci_attach, NULL, NULL); + +#if NOHCI > 0 +extern device_t ingenic_ohci; +#endif + +/* ARGSUSED */ +static int +ingenic_ehci_match(device_t parent, struct cfdata *match, void *aux) +{ + struct apbus_attach_args *aa = aux; + + if (strcmp(aa->aa_name, "ehci") != 0) + return 0; + + return 1; +} + +/* ARGSUSED */ +static void +ingenic_ehci_attach(device_t parent, device_t self, void *aux) +{ + struct ehci_softc *sc = device_private(self); + struct apbus_attach_args *aa = aux; + void *ih; + int error, status; + uint32_t reg; + + sc->sc_dev = self; + + sc->iot = aa->aa_bst; + sc->sc_bus.dmatag = aa->aa_dmat; + sc->sc_bus.hci_private = sc; + sc->sc_size = 0x1000; + sc->sc_bus.usbrev = USBREV_2_0; + + if (aa->aa_addr == 0) + aa->aa_addr = JZ_EHCI_BASE; + + error = bus_space_map(aa->aa_bst, aa->aa_addr, 0x1000, 0, &sc->ioh); + if (error) { + aprint_error_dev(self, + "can't map registers for %s: %d\n", aa->aa_name, error); + return; + } + + aprint_naive(": EHCI USB controller\n"); + aprint_normal(": EHCI USB controller\n"); + + /* + * voodoo from the linux driver: + * select utmi data bus width of controller to 16bit + */ + reg = bus_space_read_4(sc->iot, sc->ioh, 0xb0); + reg |= 1 << 6; + bus_space_write_4(sc->iot, sc->ioh, 0xb0, reg); + + /* Disable EHCI interrupts */ + bus_space_write_4(sc->iot, sc->ioh, EHCI_USBINTR, 0); + + ih = evbmips_intr_establish(aa->aa_irq, ehci_intr, sc); + + if (ih == NULL) { + aprint_error_dev(self, "failed to establish interrupt %d\n", + aa->aa_irq); + goto fail; + } + +#if NOHCI > 0 + if (ingenic_ohci != NULL) { + sc->sc_ncomp = 1; + sc->sc_comps[0] = ingenic_ohci; + } else + sc->sc_ncomp = 0; +#else + sc->sc_ncomp = 0; +#endif + sc->sc_id_vendor = USB_VENDOR_INGENIC; + strlcpy(sc->sc_vendor, "Ingenic", sizeof(sc->sc_vendor)); + + status = ehci_init(sc); + if (status != USBD_NORMAL_COMPLETION) { + aprint_error_dev(self, "init failed, error=%d\n", status); + goto fail; + } + + /* Attach USB device */ + sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint); + + return; + +fail: + if (ih) { + evbmips_intr_disestablish(ih); + } + bus_space_unmap(sc->iot, sc->ioh, 0x1000); +} Property changes on: projects/ci20_mips/sys/mips/ingenic/ingenic_ehci.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: projects/ci20_mips/sys/mips/ingenic/ingenic_machdep.c =================================================================== --- projects/ci20_mips/sys/mips/ingenic/ingenic_machdep.c (nonexistent) +++ projects/ci20_mips/sys/mips/ingenic/ingenic_machdep.c (revision 283030) @@ -0,0 +1,188 @@ +/*- + * Copyright (c) 2006 Wojciech A. Koszek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ +#include +__FBSDID("$FreeBSD$"); + +#include "opt_ddb.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +extern int *edata; +extern int *end; + +void ingenic_reset(void); + +/* + * Temporary boot environment used at startup. + */ +static char boot1_env[4096]; + +void +platform_cpu_init() +{ + /* Nothing special */ +} + +static void +mips_init(void) +{ + int i; + + for (i = 0; i < 10; i++) { + phys_avail[i] = 0; + } + + /* phys_avail regions are in bytes */ + phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end); + phys_avail[1] = ctob(realmem); + + dump_avail[0] = phys_avail[0]; + dump_avail[1] = phys_avail[1]; + + physmem = realmem; + + init_param1(); + init_param2(physmem); + mips_cpu_init(); + pmap_bootstrap(); + mips_proc0_init(); + mutex_init(); + kdb_init(); +#ifdef KDB + if (boothowto & RB_KDB) + kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); +#endif +} + +/* + * Perform a board-level soft-reset. + * Note that this is not emulated by gxemul. + */ +void +platform_reset(void) +{ + char *c; + + c = (char *)MIPS_PHYS_TO_KSEG0(0); + *c = 0; +} + +static uint64_t +ingenic_cpu_freq(void) +{ + uint64_t platform_counter_freq = 0; + + if (platform_counter_freq == 0) + platform_counter_freq = MIPS_DEFAULT_HZ; + + return (platform_counter_freq); +} + +void +platform_start(__register_t a0, __register_t a1, __register_t a2, + __register_t a3) +{ + vm_offset_t kernend; + uint64_t platform_counter_freq; + int argc = a0; + int32_t *argv = (int32_t*)a1; + int32_t *envp = (int32_t*)a2; + unsigned int memsize = a3; + int i; + + /* clear the BSS and SBSS segments */ + kernend = (vm_offset_t)&end; + memset(&edata, 0, kernend - (vm_offset_t)(&edata)); + + mips_postboot_fixup(); + + mips_pcpu0_init(); + platform_counter_freq = ingenic_cpu_freq(); + mips_timer_early_init(platform_counter_freq); + init_static_kenv(boot1_env, sizeof(boot1_env)); + + cninit(); + printf("entry: platform_start()\n"); + + bootverbose = 1; + /* + * YAMON uses 32bit pointers to strings so + * convert them to proper type manually + */ + if (bootverbose) { + printf("cmd line: "); + for (i = 0; i < argc; i++) + printf("%s ", (char*)(intptr_t)argv[i]); + printf("\n"); + + printf("envp:\n"); + for (i = 0; envp[i]; i += 2) + printf("\t%s = %s\n", (char*)(intptr_t)envp[i], + (char*)(intptr_t)envp[i+1]); + + printf("memsize = %08x\n", memsize); + } + + realmem = btoc(memsize); + mips_init(); + + mips_timer_init_params(platform_counter_freq, 0); +} Property changes on: projects/ci20_mips/sys/mips/ingenic/ingenic_machdep.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: projects/ci20_mips/sys/mips/ingenic/ingenic_ohci.c =================================================================== --- projects/ci20_mips/sys/mips/ingenic/ingenic_ohci.c (nonexistent) +++ projects/ci20_mips/sys/mips/ingenic/ingenic_ohci.c (revision 283030) @@ -0,0 +1,135 @@ +/* $NetBSD: ingenic_ohci.c,v 1.3 2015/03/17 09:27:09 macallan Exp $ */ + +/*- + * Copyright (c) 2015 Michael Lorenz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: ingenic_ohci.c,v 1.3 2015/03/17 09:27:09 macallan Exp $"); + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "opt_ingenic.h" + +static int ingenic_ohci_match(device_t, struct cfdata *, void *); +static void ingenic_ohci_attach(device_t, device_t, void *); + +CFATTACH_DECL_NEW(ingenic_ohci, sizeof(struct ohci_softc), + ingenic_ohci_match, ingenic_ohci_attach, NULL, NULL); + +device_t ingenic_ohci = NULL; + +/* ARGSUSED */ +static int +ingenic_ohci_match(device_t parent, struct cfdata *match, void *aux) +{ + struct apbus_attach_args *aa = aux; + + if (strcmp(aa->aa_name, "ohci") != 0) + return 0; + + return 1; +} + +/* ARGSUSED */ +static void +ingenic_ohci_attach(device_t parent, device_t self, void *aux) +{ + struct ohci_softc *sc = device_private(self); + struct apbus_attach_args *aa = aux; + void *ih; + int error, status; + + sc->sc_dev = self; + + sc->iot = aa->aa_bst; + sc->sc_bus.dmatag = aa->aa_dmat; + sc->sc_bus.hci_private = sc; + sc->sc_size = 0x1000; + + if (aa->aa_addr == 0) + aa->aa_addr = JZ_OHCI_BASE; + + error = bus_space_map(aa->aa_bst, aa->aa_addr, 0x1000, 0, &sc->ioh); + if (error) { + aprint_error_dev(self, + "can't map registers for %s: %d\n", aa->aa_name, error); + return; + } + + aprint_naive(": OHCI USB controller\n"); + aprint_normal(": OHCI USB controller\n"); + + /* Disable OHCI interrupts */ + bus_space_write_4(sc->iot, sc->ioh, OHCI_INTERRUPT_DISABLE, + OHCI_ALL_INTRS); + + ih = evbmips_intr_establish(aa->aa_irq, ohci_intr, sc); + + if (ih == NULL) { + aprint_error_dev(self, "failed to establish interrupt %d\n", + aa->aa_irq); + goto fail; + } + + sc->sc_endian = OHCI_LITTLE_ENDIAN; + + sc->sc_id_vendor = USB_VENDOR_INGENIC; + strlcpy(sc->sc_vendor, "Ingenic", sizeof(sc->sc_vendor)); + + status = ohci_init(sc); + if (status != USBD_NORMAL_COMPLETION) { + aprint_error_dev(self, "init failed, error=%d\n", status); + goto fail; + } + + /* Attach USB device */ + sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint); + ingenic_ohci = self; + return; + +fail: + if (ih) { + evbmips_intr_disestablish(ih); + } + bus_space_unmap(sc->iot, sc->ioh, 0x1000); +} Property changes on: projects/ci20_mips/sys/mips/ingenic/ingenic_ohci.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: projects/ci20_mips/sys/mips/ingenic/ingenic_regs.h =================================================================== --- projects/ci20_mips/sys/mips/ingenic/ingenic_regs.h (nonexistent) +++ projects/ci20_mips/sys/mips/ingenic/ingenic_regs.h (revision 283030) @@ -0,0 +1,758 @@ +/* $NetBSD: ingenic_regs.h,v 1.17 2015/05/04 12:16:24 macallan Exp $ */ + +/*- + * Copyright (c) 2014 Michael Lorenz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef INGENIC_REGS_H +#define INGENIC_REGS_H + +/* for mips_wbflush() */ +#include + +/* UARTs, mostly 16550 compatible with 32bit spaced registers */ +#define JZ_UART0 0x10030000 +#define JZ_UART1 0x10031000 +#define JZ_UART2 0x10032000 +#define JZ_UART3 0x10033000 +#define JZ_UART4 0x10034000 + +/* LCD controller base addresses, registers are in jzfb_regs.h */ +#define JZ_LCDC0_BASE 0x13050000 +#define JZ_LCDC1_BASE 0x130a0000 + +/* watchdog */ +#define JZ_WDOG_TDR 0x10002000 /* compare */ +#define JZ_WDOG_TCER 0x10002004 + #define TCER_ENABLE 0x01 /* enable counter */ +#define JZ_WDOG_TCNT 0x10002008 /* 16bit up count */ +#define JZ_WDOG_TCSR 0x1000200c + #define TCSR_PCK_EN 0x01 /* PCLK */ + #define TCSR_RTC_EN 0x02 /* RTCCLK - 32.768kHz */ + #define TCSR_EXT_EN 0x04 /* EXTCLK - 48MHz */ + #define TCSR_PRESCALE_M 0x38 + #define TCSR_DIV_1 0x00 + #define TCSR_DIV_4 0x08 + #define TCSR_DIV_16 0x10 + #define TCSR_DIV_64 0x18 + #define TCSR_DIV_256 0x20 + #define TCSR_DIV_1024 0x28 + +/* timers and PWMs */ +#define JZ_TC_TER 0x10002010 /* TC enable reg, ro */ +#define JZ_TC_TESR 0x10002014 /* TC enable set reg. */ + #define TESR_TCST0 0x0001 /* enable counter 0 */ + #define TESR_TCST1 0x0002 /* enable counter 1 */ + #define TESR_TCST2 0x0004 /* enable counter 2 */ + #define TESR_TCST3 0x0008 /* enable counter 3 */ + #define TESR_TCST4 0x0010 /* enable counter 4 */ + #define TESR_TCST5 0x0020 /* enable counter 5 */ + #define TESR_TCST6 0x0040 /* enable counter 6 */ + #define TESR_TCST7 0x0080 /* enable counter 7 */ + #define TESR_OST 0x8000 /* enable OST */ +#define JZ_TC_TECR 0x10002018 /* TC enable clear reg. */ +#define JZ_TC_TFR 0x10002020 + #define TFR_FFLAG0 0x00000001 /* channel 0 */ + #define TFR_FFLAG1 0x00000002 /* channel 1 */ + #define TFR_FFLAG2 0x00000004 /* channel 2 */ + #define TFR_FFLAG3 0x00000008 /* channel 3 */ + #define TFR_FFLAG4 0x00000010 /* channel 4 */ + #define TFR_FFLAG5 0x00000020 /* channel 5 */ + #define TFR_FFLAG6 0x00000040 /* channel 6 */ + #define TFR_FFLAG7 0x00000080 /* channel 7 */ + #define TFR_OSTFLAG 0x00008000 /* OS timer */ +#define JZ_TC_TFSR 0x10002024 /* timer flag set */ +#define JZ_TC_TFCR 0x10002028 /* timer flag clear */ +#define JZ_TC_TMR 0x10002030 /* timer flag mask */ +#define JZ_TC_TMSR 0x10002034 /* timer flag mask set */ +#define JZ_TC_TMCR 0x10002038 /* timer flag mask clear*/ + +#define JZ_TC_TDFR(n) (0x10002040 + (n * 0x10)) /* FULL compare */ +#define JZ_TC_TDHR(n) (0x10002044 + (n * 0x10)) /* HALF compare */ +#define JZ_TC_TCNT(n) (0x10002048 + (n * 0x10)) /* count */ + +#define JZ_TC_TCSR(n) (0x1000204c + (n * 0x10)) +/* same bits as in JZ_WDOG_TCSR */ + +/* operating system timer */ +#define JZ_OST_DATA 0x100020e0 /* compare */ +#define JZ_OST_CNT_LO 0x100020e4 +#define JZ_OST_CNT_HI 0x100020e8 +#define JZ_OST_CTRL 0x100020ec + #define OSTC_PCK_EN 0x0001 /* use PCLK */ + #define OSTC_RTC_EN 0x0002 /* use RTCCLK */ + #define OSTC_EXT_EN 0x0004 /* use EXTCLK */ + #define OSTC_PRESCALE_M 0x0038 + #define OSTC_DIV_1 0x0000 + #define OSTC_DIV_4 0x0008 + #define OSTC_DIV_16 0x0010 + #define OSTC_DIV_64 0x0018 + #define OSTC_DIV_256 0x0020 + #define OSTC_DIV_1024 0x0028 + #define OSTC_SHUTDOWN 0x0200 + #define OSTC_MODE 0x8000 /* 0 - reset to 0 when = OST_DATA */ +#define JZ_OST_CNT_U32 0x100020fc /* copy of CNT_HI when reading CNT_LO */ + +static inline void +writereg(uint32_t reg, uint32_t val) +{ + *(int32_t *)MIPS_PHYS_TO_KSEG1(reg) = val; + mips_wbflush(); +} + +static inline uint32_t +readreg(uint32_t reg) +{ + mips_wbflush(); + return *(int32_t *)MIPS_PHYS_TO_KSEG1(reg); +} + +/* extra CP0 registers */ +static inline uint32_t +MFC0(uint32_t r, uint32_t s) +{ + uint32_t ret = 0x12345678; + + __asm volatile("mfc0 %0, $%1, %2; nop;" : "=r"(ret) : "i"(r), "i"(s)); + return ret; +} + +#define MTC0(v, r, s) __asm volatile("mtc0 %0, $%1, %2; nop;" :: "r"(v), "i"(r), "i"(s)) + +#define CP0_CORE_CTRL 12 /* select 2 */ + #define CC_SW_RST0 1 /* reset core 0 */ + #define CC_SW_RST1 2 /* reset core 1 */ + #define CC_RPC0 0x100 /* dedicater reset entry core 0 */ + #define CC_RPC1 0x200 /* -- || -- core 1 */ + #define CC_SLEEP0M 0x10000 /* mask sleep core 0 */ + #define CC_SLEEP1M 0x20000 /* mask sleep core 1 */ + +/* cores status, 12 select 3 */ +#define CS_MIRQ0_P 0x00001 /* mailbox IRQ for 0 pending */ +#define CS_MIRQ1_P 0x00002 /* || core 1 */ +#define CS_IRQ0_P 0x00100 /* peripheral IRQ for core 0 */ +#define CS_IRQ1_P 0x00200 /* || core 1 */ +#define CS_SLEEP0 0x10000 /* core 0 sleeping */ +#define CS_SLEEP1 0x20000 /* core 1 sleeping */ + +/* cores reset entry & IRQ masks - 12 select 4 */ +#define REIM_MIRQ0_M 0x00001 /* allow mailbox IRQ for core 0 */ +#define REIM_MIRQ1_M 0x00002 /* allow mailbox IRQ for core 1 */ +#define REIM_IRQ0_M 0x00100 /* allow peripheral IRQ for core 0 */ +#define REIM_IRQ1_M 0x00200 /* allow peripheral IRQ for core 1 */ +#define REIM_ENTRY_M 0xffff0000 /* reset exception entry if RPCn=1 */ + +#define CP0_CORE_MBOX 20 /* select 0 for core 0, 1 for 1 */ + +/* power management */ +#define JZ_CPCCR 0x10000000 /* Clock Control Register */ + #define JZ_PDIV_M 0x000f0000 /* PCLK divider mask */ + #define JZ_PDIV_S 16 /* PCLK divider shift */ + #define JZ_CDIV_M 0x0000000f /* CPU clock divider mask */ + #define JZ_CDIV_S 0 /* CPU clock divider shift */ +#define JZ_CPMPCR 0x00000014 /* MPLL */ + #define JZ_PLLM_S 19 /* PLL multiplier shift */ + #define JZ_PLLM_M 0xfff80000 /* PLL multiplier mask */ + #define JZ_PLLN_S 13 /* PLL divider shift */ + #define JZ_PLLN_M 0x0007e000 /* PLL divider mask */ + #define JZ_PLLP_S 9 /* PLL postdivider shift */ + #define JZ_PLLP_M 0x00001700 /* PLL postdivider mask */ + #define JZ_PLLON 0x00000010 /* PLL is on and stable */ + #define JZ_PLLBP 0x00000002 /* PLL bypass */ + #define JZ_PLLEN 0x00000001 /* PLL enable */ +#define JZ_CLKGR0 0x10000020 /* CLocK Gating Registers */ + #define CLK_NEMC (1 << 0) + #define CLK_BCH (1 << 1) + #define CLK_OTG0 (1 << 2) + #define CLK_MSC0 (1 << 3) + #define CLK_SSI0 (1 << 4) + #define CLK_SMB0 (1 << 5) + #define CLK_SMB1 (1 << 6) + #define CLK_SCC (1 << 7) + #define CLK_AIC (1 << 8) + #define CLK_TSSI0 (1 << 9) + #define CLK_OWI (1 << 10) + #define CLK_MSC1 (1 << 11) + #define CLK_MSC2 (1 << 12) + #define CLK_KBC (1 << 13) + #define CLK_SADC (1 << 14) + #define CLK_UART0 (1 << 15) + #define CLK_UART1 (1 << 16) + #define CLK_UART2 (1 << 17) + #define CLK_UART3 (1 << 18) + #define CLK_SSI1 (1 << 19) + #define CLK_SSI2 (1 << 20) + #define CLK_PDMA (1 << 21) + #define CLK_GPS (1 << 22) + #define CLK_MAC (1 << 23) + #define CLK_UHC (1 << 24) + #define CLK_SMB2 (1 << 25) + #define CLK_CIM (1 << 26) + #define CLK_TVE (1 << 27) + #define CLK_LCD (1 << 28) + #define CLK_IPU (1 << 29) + #define CLK_DDR0 (1 << 30) + #define CLK_DDR1 (1 << 31) + +#define JZ_OPCR 0x10000024 /* Oscillator Power Control Reg. */ + #define OPCR_IDLE_DIS 0x80000000 /* don't stop CPU clk on idle */ + #define OPCR_GPU_CLK_ST 0x40000000 /* stop GPU clock */ + #define OPCR_L2CM_M 0x0c000000 + #define OPCR_L2CM_ON 0x00000000 /* L2 stays on in sleep */ + #define OPCR_L2CM_RET 0x04000000 /* L2 retention mode in sleep */ + #define OPCR_L2CM_OFF 0x08000000 /* L2 powers down in sleep */ + #define OPCR_SPENDN0 0x00000080 /* OTG port forced down */ + #define OPCR_SPENDN1 0x00000040 /* UHC port forced down */ + #define OPCR_BUS_MODE 0x00000020 /* 1 - bursts */ + #define OPCR_O1SE 0x00000010 /* EXTCLK on in sleep */ + #define OPCR_PD 0x00000008 /* P0 down in sleep */ + #define OPCR_ERCS 0x00000004 /* 1 RTCCLK, 0 EXTCLK/512 */ + #define OPCR_CPU_MODE 0x00000002 /* 1 access 'accelerated' */ + #define OPCR_OSE 0x00000001 /* disable EXTCLK */ +#define JZ_CLKGR1 0x10000028 /* CLocK Gating Registers */ + #define CLK_SMB3 (1 << 0) + #define CLK_TSSI1 (1 << 1) + #define CLK_VPU (1 << 2) + #define CLK_PCM (1 << 3) + #define CLK_GPU (1 << 4) + #define CLK_COMPRESS (1 << 5) + #define CLK_AIC1 (1 << 6) + #define CLK_GPVLC (1 << 7) + #define CLK_OTG1 (1 << 8) + #define CLK_HDMI (1 << 9) + #define CLK_UART4 (1 << 10) + #define CLK_AHB_MON (1 << 11) + #define CLK_SMB4 (1 << 12) + #define CLK_DES (1 << 13) + #define CLK_X2D (1 << 14) + #define CLK_P1 (1 << 15) + +#define JZ_USBPCR 0x1000003c + #define PCR_USB_MODE 0x80000000 /* 1 - otg */ + #define PCR_AVLD_REG 0x40000000 + #define PCR_IDPULLUP_MASK 0x30000000 + #define PCR_INCR_MASK 0x08000000 + #define PCR_TCRISETUNE 0x04000000 + #define PCR_COMMONONN 0x02000000 + #define PCR_VBUSVLDEXT 0x01000000 + #define PCR_VBUSVLDEXTSEL 0x00800000 + #define PCR_POR 0x00400000 + #define PCR_SIDDQ 0x00200000 + #define PCR_OTG_DISABLE 0x00100000 + #define PCR_COMPDISTN_M 0x000e0000 + #define PCR_OTGTUNE 0x0001c000 + #define PCR_SQRXTUNE 0x00003800 + #define PCR_TXFSLSTUNE 0x00000780 + #define PCR_TXPREEMPHTUNE 0x00000040 + #define PCR_TXHSXVTUNE 0x00000030 + #define PCR_TXVREFTUNE 0x0000000f +#define JZ_USBRDT 0x10000040 /* Reset Detect Timer Register */ +#define JZ_USBPCR1 0x10000048 + #define PCR_SYNOPSYS 0x10000000 /* Mentor mode otherwise */ + #define PCR_REFCLK_CORE 0x0c000000 + #define PCR_REFCLK_XO25 0x04000000 + #define PCR_REFCLK_CO 0x00000000 + #define PCR_CLK_M 0x03000000 /* clock */ + #define PCR_CLK_192 0x03000000 /* 19.2MHz */ + #define PCR_CLK_48 0x02000000 /* 48MHz */ + #define PCR_CLK_24 0x01000000 /* 24MHz */ + #define PCR_CLK_12 0x00000000 /* 12MHz */ + #define PCR_DMPD1 0x00800000 /* pull down D- on port 1 */ + #define PCR_DPPD1 0x00400000 /* pull down D+ on port 1 */ + #define PCR_PORT0_RST 0x00200000 /* port 0 reset */ + #define PCR_PORT1_RST 0x00100000 /* port 1 reset */ + #define PCR_WORD_I_F0 0x00080000 /* 1: 16bit/30M, 8/60 otherw. */ + #define PCR_WORD_I_F1 0x00040000 /* same for port 1 */ + #define PCR_COMPDISTUNE 0x00038000 /* disconnect threshold */ + #define PCR_SQRXTUNE1 0x00007000 /* squelch threshold */ + #define PCR_TXFSLSTUNE1 0x00000f00 /* FS/LS impedance adj. */ + #define PCR_TXPREEMPH 0x00000080 /* HS transm. pre-emphasis */ + #define PCR_TXHSXVTUNE1 0x00000060 /* dp/dm voltage adj. */ + #define PCR_TXVREFTUNE1 0x00000017 /* HS DC voltage adj. */ + #define PCR_TXRISETUNE1 0x00000001 /* rise/fall wave adj. */ + +#define JZ_UHCCDR 0x1000006c /* UHC Clock Divider Register */ + #define UHCCDR_SCLK_A 0x00000000 + #define UHCCDR_MPLL 0x40000000 + #define UHCCDR_EPLL 0x80000000 + #define UHCCDR_OTG_PHY 0xc0000000 + #define UHCCDR_CE 0x20000000 + #define UHCCDR_BUSY 0x10000000 + #define UHCCDR_STOP 0x08000000 + #define UHCCDR_DIV_M 0x000000ff +#define JZ_SPCR0 0x100000b8 /* SRAM Power Control Registers */ +#define JZ_SPCR1 0x100000bc +#define JZ_SRBC 0x100000c4 /* Soft Reset & Bus Control */ + +/* interrupt controller */ +#define JZ_ICSR0 0x10001000 /* raw IRQ line status */ +#define JZ_ICMR0 0x10001004 /* IRQ mask, 1 masks IRQ */ +#define JZ_ICMSR0 0x10001008 /* sets bits in mask register */ +#define JZ_ICMCR0 0x1000100c /* clears bits in mask register */ +#define JZ_ICPR0 0x10001010 /* line status after masking */ + +#define JZ_ICSR1 0x10001020 /* raw IRQ line status */ +#define JZ_ICMR1 0x10001024 /* IRQ mask, 1 masks IRQ */ +#define JZ_ICMSR1 0x10001028 /* sets bits in mask register */ +#define JZ_ICMCR1 0x1000102c /* clears bits in maks register */ +#define JZ_ICPR1 0x10001030 /* line status after masking */ + +#define JZ_DSR0 0x10001034 /* source for PDMA */ +#define JZ_DMR0 0x10001038 /* mask for PDMA */ +#define JZ_DPR0 0x1000103c /* pending for PDMA */ + +#define JZ_DSR1 0x10001040 /* source for PDMA */ +#define JZ_DMR1 0x10001044 /* mask for PDMA */ +#define JZ_DPR1 0x10001048 /* pending for PDMA */ + +/* memory controller */ +#define JZ_DMMAP0 0x13010024 +#define JZ_DMMAP1 0x13010028 + #define DMMAP_BASE 0x0000ff00 /* base PADDR of memory chunk */ + #define DMMAP_MASK 0x000000ff /* mask which bits of PADDR are + * constant */ +/* USB controllers */ +#define JZ_EHCI_BASE 0x13490000 +#define JZ_OHCI_BASE 0x134a0000 +#define JZ_DWC2_BASE 0x13500000 + +/* Ethernet */ +#define JZ_DME_BASE 0x16000000 +#define JZ_DME_IO 0 +#define JZ_DME_DATA 2 + +/* GPIO */ +#define JZ_GPIO_A_BASE 0x10010000 +#define JZ_GPIO_B_BASE 0x10010100 +#define JZ_GPIO_C_BASE 0x10010200 +#define JZ_GPIO_D_BASE 0x10010300 +#define JZ_GPIO_E_BASE 0x10010400 +#define JZ_GPIO_F_BASE 0x10010500 + +/* GPIO registers per port */ +#define JZ_GPIO_PIN 0x00000000 /* pin level register */ +/* 0 - normal gpio, 1 - interrupt */ +#define JZ_GPIO_INT 0x00000010 /* interrupt register */ +#define JZ_GPIO_INTS 0x00000014 /* interrupt set register */ +#define JZ_GPIO_INTC 0x00000018 /* interrupt clear register */ +/* + * INT == 1: 1 disables interrupt + * INT == 0: device select, see below + */ +#define JZ_GPIO_MASK 0x00000020 /* port mask register */ +#define JZ_GPIO_MASKS 0x00000024 /* port mask set register */ +#define JZ_GPIO_MASKC 0x00000028 /* port mask clear register */ +/* + * INT == 1: 0 - level triggered, 1 - edge triggered + * INT == 0: 0 - device select, see below + */ +#define JZ_GPIO_PAT1 0x00000030 /* pattern 1 register */ +#define JZ_GPIO_PAT1S 0x00000034 /* pattern 1 set register */ +#define JZ_GPIO_PAT1C 0x00000038 /* pattern 1 clear register */ +/* + * INT == 1: + * PAT1 == 0: 0 - trigger on low, 1 - trigger on high + * PAT1 == 1: 0 - trigger on falling edge, 1 - trigger on rising edge + * INT == 0: + * MASK == 0: + * PAT1 == 0: 0 - device 0, 1 - device 1 + * PAT1 == 1: 0 - device 2, 1 - device 3 + * MASK == 1: + * PAT1 == 0: set gpio output + * PAT1 == 1: pin is input + */ +#define JZ_GPIO_PAT0 0x00000040 /* pattern 0 register */ +#define JZ_GPIO_PAT0S 0x00000044 /* pattern 0 set register */ +#define JZ_GPIO_PAT0C 0x00000048 /* pattern 0 clear register */ +/* 1 - interrupt happened */ +#define JZ_GPIO_FLAG 0x00000050 /* flag register */ +#define JZ_GPIO_FLAGC 0x00000058 /* flag clear register */ +/* 1 - disable pull up/down resistors */ +#define JZ_GPIO_DPULL 0x00000070 /* pull disable register */ +#define JZ_GPIO_DPULLS 0x00000074 /* pull disable set register */ +#define JZ_GPIO_DPULLC 0x00000078 /* pull disable clear register */ +/* the following are uncommented in the manual */ +#define JZ_GPIO_DRVL 0x00000080 /* drive low register */ +#define JZ_GPIO_DRVLS 0x00000084 /* drive low set register */ +#define JZ_GPIO_DRVLC 0x00000088 /* drive low clear register */ +#define JZ_GPIO_DIR 0x00000090 /* direction register */ +#define JZ_GPIO_DIRS 0x00000094 /* direction register */ +#define JZ_GPIO_DIRC 0x00000098 /* direction register */ +#define JZ_GPIO_DRVH 0x000000a0 /* drive high register */ +#define JZ_GPIO_DRVHS 0x000000a4 /* drive high set register */ +#define JZ_GPIO_DRVHC 0x000000a8 /* drive high clear register */ + +static inline void +gpio_as_output(uint32_t g, int pin) +{ + uint32_t mask = 1 << pin; + uint32_t reg = JZ_GPIO_A_BASE + (g << 8); + + writereg(reg + JZ_GPIO_INTC, mask); /* use as gpio */ + writereg(reg + JZ_GPIO_MASKS, mask); + writereg(reg + JZ_GPIO_PAT1C, mask); /* make output */ +} + +static inline void +gpio_set(uint32_t g, int pin, int level) +{ + uint32_t mask = 1 << pin; + uint32_t reg = JZ_GPIO_A_BASE + (g << 8); + + reg += (level == 0) ? JZ_GPIO_PAT0C : JZ_GPIO_PAT0S; + writereg(reg, mask); +} + +static inline void +gpio_as_dev0(uint32_t g, int pin) +{ + uint32_t mask = 1 << pin; + uint32_t reg = JZ_GPIO_A_BASE + (g << 8); + + writereg(reg + JZ_GPIO_INTC, mask); /* use as gpio */ + writereg(reg + JZ_GPIO_MASKC, mask); /* device mode */ + writereg(reg + JZ_GPIO_PAT1C, mask); /* select 0 */ + writereg(reg + JZ_GPIO_PAT0C, mask); +} + +static inline void +gpio_as_dev1(uint32_t g, int pin) +{ + uint32_t mask = 1 << pin; + uint32_t reg = JZ_GPIO_A_BASE + (g << 8); + + writereg(reg + JZ_GPIO_INTC, mask); /* use as gpio */ + writereg(reg + JZ_GPIO_MASKC, mask); /* device mode */ + writereg(reg + JZ_GPIO_PAT1C, mask); /* select 1 */ + writereg(reg + JZ_GPIO_PAT0S, mask); +} + +static inline void +gpio_as_dev2(uint32_t g, int pin) +{ + uint32_t mask = 1 << pin; + uint32_t reg = JZ_GPIO_A_BASE + (g << 8); + + writereg(reg + JZ_GPIO_INTC, mask); /* use as gpio */ + writereg(reg + JZ_GPIO_MASKC, mask); /* device mode */ + writereg(reg + JZ_GPIO_PAT1S, mask); /* select 2 */ + writereg(reg + JZ_GPIO_PAT0C, mask); +} + +static inline void +gpio_as_dev3(uint32_t g, int pin) +{ + uint32_t mask = 1 << pin; + uint32_t reg = JZ_GPIO_A_BASE + (g << 8); + + writereg(reg + JZ_GPIO_INTC, mask); /* use as gpio */ + writereg(reg + JZ_GPIO_MASKC, mask); /* device mode */ + writereg(reg + JZ_GPIO_PAT1S, mask); /* select 3 */ + writereg(reg + JZ_GPIO_PAT0S, mask); +} + +static inline void +gpio_as_intr_level(uint32_t g, int pin) +{ + uint32_t mask = 1 << pin; + uint32_t reg = JZ_GPIO_A_BASE + (g << 8); + + writereg(reg + JZ_GPIO_MASKS, mask); /* mask it */ + writereg(reg + JZ_GPIO_INTS, mask); /* use as interrupt */ + writereg(reg + JZ_GPIO_PAT1C, mask); /* level trigger */ + writereg(reg + JZ_GPIO_PAT0S, mask); /* trigger on high */ + writereg(reg + JZ_GPIO_FLAGC, mask); /* clear it */ + writereg(reg + JZ_GPIO_MASKC, mask); /* enable it */ +} + +static inline void +gpio_as_intr_level_low(uint32_t g, int pin) +{ + uint32_t mask = 1 << pin; + uint32_t reg = JZ_GPIO_A_BASE + (g << 8); + + writereg(reg + JZ_GPIO_MASKS, mask); /* mask it */ + writereg(reg + JZ_GPIO_INTS, mask); /* use as interrupt */ + writereg(reg + JZ_GPIO_PAT1C, mask); /* level trigger */ + writereg(reg + JZ_GPIO_PAT0C, mask); /* trigger on low */ + writereg(reg + JZ_GPIO_FLAGC, mask); /* clear it */ + writereg(reg + JZ_GPIO_MASKC, mask); /* enable it */ +} + +static inline void +gpio_as_input(uint32_t g, int pin) +{ + uint32_t mask = 1 << pin; + uint32_t reg = JZ_GPIO_A_BASE + (g << 8); + + writereg(reg + JZ_GPIO_MASKS, mask); /* mask it */ + writereg(reg + JZ_GPIO_INTC, mask); /* not an interrupt */ + writereg(reg + JZ_GPIO_PAT1S, mask); /* use as input */ + writereg(reg + JZ_GPIO_FLAGC, mask); /* clear it just in case */ +} + +/* I2C / SMBus */ +#define JZ_SMB0_BASE 0x10050000 +#define JZ_SMB1_BASE 0x10051000 +#define JZ_SMB2_BASE 0x10052000 +#define JZ_SMB3_BASE 0x10053000 +#define JZ_SMB4_BASE 0x10054000 + +/* SMBus register offsets, per port */ +#define JZ_SMBCON 0x00 /* SMB control */ + #define JZ_STPHLD 0x80 /* Stop Hold Enable bit */ + #define JZ_SLVDIS 0x40 /* 1 - slave disabled */ + #define JZ_REST 0x20 /* 1 - allow RESTART */ + #define JZ_MATP 0x10 /* 1 - enable 10bit addr. for master */ + #define JZ_SATP 0x08 /* 1 - enable 10bit addr. for slave */ + #define JZ_SPD_M 0x06 /* bus speed control */ + #define JZ_SPD_100KB 0x02 /* 100kBit/s mode */ + #define JZ_SPD_400KB 0x04 /* 400kBit/s mode */ + #define JZ_MD 0x01 /* enable master */ +#define JZ_SMBTAR 0x04 /* SMB target address */ + #define JZ_SMATP 0x1000 /* enable 10bit master addr */ + #define JZ_SPECIAL 0x0800 /* 1 - special command */ + #define JZ_START 0x0400 /* 1 - send START */ + #define JZ_SMBTAR_M 0x03ff /* target address */ +#define JZ_SMBSAR 0x08 /* SMB slave address */ +#define JZ_SMBDC 0x10 /* SMB data buffer and command */ + #define JZ_CMD 0x100 /* 1 - read, 0 - write */ + #define JZ_DATA 0x0ff +#define JZ_SMBSHCNT 0x14 /* Standard speed SMB SCL high count */ +#define JZ_SMBSLCNT 0x18 /* Standard speed SMB SCL low count */ +#define JZ_SMBFHCNT 0x1C /* Fast speed SMB SCL high count */ +#define JZ_SMBFLCNT 0x20 /* Fast speed SMB SCL low count */ +#define JZ_SMBINTST 0x2C /* SMB Interrupt Status */ + #define JZ_ISTT 0x400 /* START or RESTART occured */ + #define JZ_ISTP 0x200 /* STOP occured */ + #define JZ_TXABT 0x40 /* ABORT occured */ + #define JZ_TXEMP 0x10 /* TX FIFO is low */ + #define JZ_TXOF 0x08 /* TX FIFO is high */ + #define JZ_RXFL 0x04 /* RX FIFO is at JZ_SMBRXTL*/ + #define JZ_RXOF 0x02 /* RX FIFO is high */ + #define JZ_RXUF 0x01 /* RX FIFO underflow */ +#define JZ_SMBINTM 0x30 /* SMB Interrupt Mask */ +#define JZ_SMBRXTL 0x38 /* SMB RxFIFO Threshold */ +#define JZ_SMBTXTL 0x3C /* SMB TxFIFO Threshold */ +#define JZ_SMBCINT 0x40 /* Clear Interrupts */ + #define JZ_CLEARALL 0x01 +#define JZ_SMBCRXUF 0x44 /* Clear RXUF Interrupt */ +#define JZ_SMBCRXOF 0x48 /* Clear RX_OVER Interrupt */ +#define JZ_SMBCTXOF 0x4C /* Clear TX_OVER Interrupt */ +#define JZ_SMBCRXREQ 0x50 /* Clear RDREQ Interrupt */ +#define JZ_SMBCTXABT 0x54 /* Clear TX_ABRT Interrupt */ +#define JZ_SMBCRXDN 0x58 /* Clear RX_DONE Interrupt */ +#define JZ_SMBCACT 0x5c /* Clear ACTIVITY Interrupt */ +#define JZ_SMBCSTP 0x60 /* Clear STOP Interrupt */ +#define JZ_SMBCSTT 0x64 /* Clear START Interrupt */ +#define JZ_SMBCGC 0x68 /* Clear GEN_CALL Interrupt */ +#define JZ_SMBENB 0x6C /* SMB Enable */ + #define JZ_ENABLE 0x01 +#define JZ_SMBST 0x70 /* SMB Status register */ + #define JZ_SLVACT 0x40 /* slave is active */ + #define JZ_MSTACT 0x20 /* master is active */ + #define JZ_RFF 0x10 /* RX FIFO is full */ + #define JZ_RFNE 0x08 /* RX FIFO not empty */ + #define JZ_TFE 0x04 /* TX FIFO is empty */ + #define JZ_TFNF 0x02 /* TX FIFO is not full */ + #define JZ_ACT 0x01 /* JZ_SLVACT | JZ_MSTACT */ +#define JZ_SMBABTSRC 0x80 /* SMB Transmit Abort Status Register */ +#define JZ_SMBDMACR 0x88 /* DMA Control Register */ +#define JZ_SMBDMATDL 0x8c /* DMA Transmit Data Level */ +#define JZ_SMBDMARDL 0x90 /* DMA Receive Data Level */ +#define JZ_SMBSDASU 0x94 /* SMB SDA Setup Register */ +#define JZ_SMBACKGC 0x98 /* SMB ACK General Call Register */ +#define JZ_SMBENBST 0x9C /* SMB Enable Status Register */ +#define JZ_SMBSDAHD 0xD0 /* SMB SDA HolD time Register */ + #define JZ_HDENB 0x100 /* enable hold time */ + +/* SD/MMC hosts */ +#define JZ_MSC0_BASE 0x13450000 +#define JZ_MSC1_BASE 0x13460000 +#define JZ_MSC2_BASE 0x13470000 + +#define JZ_MSC_CTRL 0x00 + #define JZ_SEND_CCSD 0x8000 + #define JZ_SEND_AS_CCSD 0x4000 + #define JZ_EXIT_MULTIPLE 0x0080 + #define JZ_EXIT_TRANSFER 0x0040 + #define JZ_START_READWAIT 0x0020 + #define JZ_STOP_READWAIT 0x0010 + #define JZ_RESET 0x0008 + #define JZ_START_OP 0x0004 + #define JZ_CLOCK_CTRL_M 0x0003 + #define JZ_CLOCK_START 0x0002 + #define JZ_CLOCK_STOP 0x0001 +#define JZ_MSC_STAT 0x04 + #define JZ_AUTO_CMD12_DONE 0x80000000 + #define JZ_AUTO_CMD23_DONE 0x40000000 + #define JZ_SVS 0x20000000 + #define JZ_PIN_LEVEL_M 0x1f000000 + #define JZ_BCE 0x00100000 /* boot CRC error */ + #define JZ_BDE 0x00080000 /* boot data end */ + #define JZ_BAE 0x00040000 /* boot acknowledge error */ + #define JZ_BAR 0x00020000 /* boot ack. received */ + #define JZ_DMAEND 0x00010000 + #define JZ_IS_RESETTING 0x00008000 + #define JZ_SDIO_INT_ACTIVE 0x00004000 + #define JZ_PRG_DONE 0x00002000 + #define JZ_DATA_TRAN_DONE 0x00001000 + #define JZ_END_CMD_RES 0x00000800 + #define JZ_DATA_FIFO_AFULL 0x00000400 + #define JZ_IS_READWAIT 0x00000200 + #define JZ_CLK_EN 0x00000100 + #define JZ_DATA_FIFO_FULL 0x00000080 + #define JZ_DATA_FIFO_EMPTY 0x00000040 + #define JZ_CRC_RES_ERR 0x00000020 + #define JZ_CRC_READ_ERR 0x00000010 + #define JZ_CRC_WRITE_ERR_M 0x0000000c + #define JZ_CRC_WRITE_OK 0x00000000 + #define JZ_CRC_CARD_ERR 0x00000004 + #define JZ_CRC_NO_STATUS 0x00000008 + #define JZ_TIME_OUT_RES 0x00000002 + #define JZ_TIME_OUT_READ 0x00000001 +#define JZ_MSC_CLKRT 0x08 + #define JZ_DEV_CLK 0x0 + #define JZ_DEV_CLK_2 0x1 /* DEV_CLK / 2 */ + #define JZ_DEV_CLK_4 0x2 /* DEV_CLK / 4 */ + #define JZ_DEV_CLK_8 0x3 /* DEV_CLK / 8 */ + #define JZ_DEV_CLK_16 0x4 /* DEV_CLK / 16 */ + #define JZ_DEV_CLK_32 0x5 /* DEV_CLK / 32 */ + #define JZ_DEV_CLK_64 0x6 /* DEV_CLK / 64 */ + #define JZ_DEV_CLK_128 0x7 /* DEV_CLK / 128 */ +#define JZ_MSC_CMDAT 0x0c + #define JZ_CCS_EXPECTED 0x80000000 + #define JZ_READ_CEATA 0x40000000 + #define JZ_DIS_BOOT 0x08000000 + #define JZ_ENA_BOOT 0x04000000 + #define JZ_EXP_BOOT_ACK 0x02000000 + #define JZ_BOOT_MODE 0x01000000 + #define JZ_AUTO_CMD23 0x00040000 + #define JZ_SDIO_PRDT 0x00020000 + #define JZ_AUTO_CMD12 0x00010000 + #define JZ_RTRG_M 0x0000c000 /* receive FIFO trigger */ + #define JZ_RTRG_16 0x00000000 /* >= 16 */ + #define JZ_RTRG_32 0x00004000 /* >= 32 */ + #define JZ_RTRG_64 0x00008000 /* >= 64 */ + #define JZ_RTRG_96 0x0000c000 /* >= 96 */ + #define JZ_TTRG_M 0x00003000 /* transmit FIFO trigger */ + #define JZ_TTRG_16 0x00000000 /* >= 16 */ + #define JZ_TTRG_32 0x00001000 /* >= 32 */ + #define JZ_TTRG_64 0x00002000 /* >= 64 */ + #define JZ_TTRG_96 0x00003000 /* >= 96 */ + #define JZ_IO_ABORT 0x00000800 + #define JZ_BUS_WIDTH_M 0x00000600 + #define JZ_BUS_1BIT 0x00000000 + #define JZ_BUS_4BIT 0x00000200 + #define JZ_BUS_8BIT 0x00000300 + #define JZ_INIT 0x00000080 /* send 80 clk init before cmd */ + #define JZ_BUSY 0x00000040 + #define JZ_STREAM 0x00000020 + #define JZ_WRITE 0x00000010 /* read otherwise */ + #define JZ_DATA_EN 0x00000008 + #define JZ_RESPONSE_M 0x00000007 /* response format */ + #define JZ_RES_NONE 0x00000000 + #define JZ_RES_R1 0x00000001 /* R1 and R1b */ + #define JZ_RES_R2 0x00000002 + #define JZ_RES_R3 0x00000003 + #define JZ_RES_R4 0x00000004 + #define JZ_RES_R5 0x00000005 + #define JZ_RES_R6 0x00000006 + #define JZ_RES_R7 0x00000007 +#define JZ_MSC_RESTO 0x10 /* 16bit response timeout in MSC_CLK */ +#define JZ_MSC_RDTO RW 0x14 /* 32bit read timeout in MSC_CLK */ +#define JZ_MSC_BLKLEN 0x18 /* 16bit block length */ +#define JZ_MSC_NOB RW 0x1c /* 16bit block counter */ +#define JZ_MSC_SNOB 0x20 /* 16bit successful block counter */ +#define JZ_MSC_IMASK 0x24 /* interrupt mask */ + #define JZ_INT_AUTO_CMD23_DONE 0x40000000 + #define JZ_INT_SVS 0x20000000 + #define JZ_INT_PIN_LEVEL_M 0x1f000000 + #define JZ_INT_BCE 0x00100000 + #define JZ_INT_BDE 0x00080000 + #define JZ_INT_BAE 0x00040000 + #define JZ_INT_BAR 0x00020000 + #define JZ_INT_DMAEND 0x00010000 + #define JZ_INT_AUTO_CMD12_DONE 0x00008000 + #define JZ_INT_DATA_FIFO_FULL 0x00004000 + #define JZ_INT_DATA_FIFO_EMPTY 0x00002000 + #define JZ_INT_CRC_RES_ERR 0x00001000 + #define JZ_INT_CRC_READ_ERR 0x00000800 + #define JZ_INT_CRC_WRITE_ERR 0x00000400 + #define JZ_INT_TIMEOUT_RES 0x00000200 + #define JZ_INT_TIMEOUT_READ 0x00000100 + #define JZ_INT_SDIO 0x00000080 + #define JZ_INT_TXFIFO_WR_REQ 0x00000040 + #define JZ_INT_RXFIFO_RD_REQ 0x00000020 + #define JZ_INT_EMD_CMD_RES 0x00000004 + #define JZ_INT_PRG_DONE 0x00000002 + #define JZ_INT_DATA_TRAN_DONE 0x00000001 +#define JZ_MSC_IFLG 0x28 /* interrupt flags */ +#define JZ_MSC_CMD 0x2c /* 6bit CMD index */ +#define JZ_MSC_ARG 0x30 /* 32bit argument */ +#define JZ_MSC_RES 0x34 /* 8x16bit response data FIFO */ +#define JZ_MSC_RXFIFO 0x38 +#define JZ_MSC_TXFIFO 0x3c +#define JZ_MSC_LPM 0x40 + #define JZ_DRV_SEL_M 0xc0000000 + #define JZ_FALLING_EDGE 0x00000000 + #define JZ_RISING_1NS 0x40000000 /* 1ns delay */ + #define JZ_RISING_4 0x80000000 /* 1/4 MSC_CLK delay */ + #define JZ_SMP_SEL 0x20000000 /* 1 - rising edge */ + #define JZ_LPM 0x00000001 /* low power mode */ +#define JZ_MSC_DMAC 0x44 + #define JZ_MODE_SEL 0x80 /* 1 - specify transfer length */ + #define JZ_AOFST_M 0x60 /* address offset in bytes */ + #define JZ_ALIGNEN 0x10 /* allow non-32bit-aligned transfers */ + #define JZ_INCR_M 0x0c /* burst type */ + #define JZ_INCR_16 0x00 + #define JZ_INCR_32 0x04 + #define JZ_INCR_64 0x08 + #define JZ_DMASEL 0x02 /* 1 - SoC DMAC, 0 - MSC built-in */ + #define JZ_DMAEN 0x01 /* enable DMA */ +#define JZ_MSC_DMANDA 0x48 /* next descriptor paddr */ +#define JZ_MSC_DMADA 0x4c /* current descriptor */ +#define JZ_MSC_DMALEN 0x50 /* transfer tength */ +#define JZ_MSC_DMACMD 0x54 + #define JZ_DMA_IDI_M 0xff000000 + #define JZ_DMA_ID_M 0x00ff0000 + #define JZ_DMA_AOFST_M 0x00000600 + #define JZ_DMA_ALIGN 0x00000100 + #define JZ_DMA_ENDI 0x00000002 + #define JZ_DMA_LINK 0x00000001 +#define JZ_MSC_CTRL2 0x58 + #define JZ_PIP 0x1f000000 /* 1 - intr trigger on high */ + #define JZ_RST_EN 0x00800000 + #define JZ_STPRM 0x00000010 + #define JZ_SVC 0x00000008 + #define JZ_SMS_M 0x00000007 + #define JZ_SMS_DEF 0x00000000 /* default speed */ + #define JZ_SMS_HIGH 0x00000001 /* high speed */ + #define JZ_SMS_SDR12 0x00000002 + #define JZ_SMS_SDR25 0x00000003 + #define JZ_SMS_SDR50 0x00000004 +#define JZ_MSC_RTCNT 0x5c /* RT FIFO count */ + +#endif /* INGENIC_REGS_H */ Property changes on: projects/ci20_mips/sys/mips/ingenic/ingenic_regs.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: projects/ci20_mips/sys/mips/ingenic/ingenic_var.h =================================================================== --- projects/ci20_mips/sys/mips/ingenic/ingenic_var.h (nonexistent) +++ projects/ci20_mips/sys/mips/ingenic/ingenic_var.h (revision 283030) @@ -0,0 +1,47 @@ +/* $NetBSD: ingenic_var.h,v 1.4 2015/05/04 12:23:15 macallan Exp $ */ + +/*- + * Copyright (c) 2014 Michael Lorenz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef INGENIC_VAR_H +#define INGENIC_VAR_H + +#include + +struct apbus_attach_args { + const char *aa_name; + bus_space_tag_t aa_bst; + bus_dma_tag_t aa_dmat; + bus_addr_t aa_addr; + uint32_t aa_irq; + uint32_t aa_pclk; /* PCLK in kHz */ + uint32_t aa_mclk; /* MCLK in kHz */ +}; + +extern bus_space_tag_t ingenic_memt; +void apbus_init(void); + +#endif /* INGENIC_VAR_H */ Property changes on: projects/ci20_mips/sys/mips/ingenic/ingenic_var.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: projects/ci20_mips/sys/mips/ingenic/jziic.c =================================================================== --- projects/ci20_mips/sys/mips/ingenic/jziic.c (nonexistent) +++ projects/ci20_mips/sys/mips/ingenic/jziic.c (revision 283030) @@ -0,0 +1,635 @@ +/* $NetBSD: jziic.c,v 1.2 2015/04/21 06:12:41 macallan Exp $ */ + +/*- + * Copyright (c) 2015 Michael Lorenz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: jziic.c,v 1.2 2015/04/21 06:12:41 macallan Exp $"); + +/* + * a preliminary driver for JZ4780's on-chip SMBus controllers + * - needs more error handling and interrupt support + * - transfers can't be more than the chip's FIFO, supposedly 16 bytes per + * direction + * so, good enough for RTCs but not much else yet + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "opt_ingenic.h" + +#ifdef JZIIC_DEBUG +#define DPRINTF aprint_error +#define STATIC /* */ +#else +#define DPRINTF while (0) printf +#define STATIC static +#endif + +STATIC int jziic_match(device_t, struct cfdata *, void *); +STATIC void jziic_attach(device_t, device_t, void *); + +struct jziic_softc { + device_t sc_dev; + bus_space_tag_t sc_memt; + bus_space_handle_t sc_memh; + struct i2c_controller sc_i2c; + kmutex_t sc_buslock, sc_cvlock; + uint32_t sc_pclk; + /* stuff used for interrupt-driven transfers */ + const uint8_t *sc_cmd; + uint8_t *sc_buf; + uint32_t sc_cmdlen, sc_buflen; + uint32_t sc_cmdptr, sc_bufptr, sc_rds; + uint32_t sc_abort; + kcondvar_t sc_ping; + uint8_t sc_txbuf[256]; + boolean_t sc_reading; +}; + +CFATTACH_DECL_NEW(jziic, sizeof(struct jziic_softc), + jziic_match, jziic_attach, NULL, NULL); + +STATIC int jziic_enable(struct jziic_softc *); +STATIC void jziic_disable(struct jziic_softc *); +STATIC int jziic_wait(struct jziic_softc *); +STATIC void jziic_set_speed(struct jziic_softc *); +STATIC int jziic_i2c_acquire_bus(void *, int); +STATIC void jziic_i2c_release_bus(void *, int); +STATIC int jziic_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, size_t, + void *, size_t, int); +STATIC int jziic_i2c_exec_poll(struct jziic_softc *, i2c_op_t, i2c_addr_t, + const void *, size_t, void *, size_t, int); +STATIC int jziic_i2c_exec_intr(struct jziic_softc *, i2c_op_t, i2c_addr_t, + const void *, size_t, void *, size_t, int); + +STATIC int jziic_intr(void *); + + +/* ARGSUSED */ +STATIC int +jziic_match(device_t parent, struct cfdata *match, void *aux) +{ + struct apbus_attach_args *aa = aux; + + if (strcmp(aa->aa_name, "jziic") != 0) + return 0; + + return 1; +} + +/* ARGSUSED */ +STATIC void +jziic_attach(device_t parent, device_t self, void *aux) +{ + struct jziic_softc *sc = device_private(self); + struct apbus_attach_args *aa = aux; + struct i2cbus_attach_args iba; + int error; + void *ih; +#ifdef JZIIC_DEBUG + int i; + uint8_t in[1] = {0}, out[16]; +#endif + + sc->sc_dev = self; + sc->sc_pclk = aa->aa_pclk; + sc->sc_memt = aa->aa_bst; + + error = bus_space_map(aa->aa_bst, aa->aa_addr, 0x100, 0, &sc->sc_memh); + if (error) { + aprint_error_dev(self, + "can't map registers for %s: %d\n", aa->aa_name, error); + return; + } + + mutex_init(&sc->sc_buslock, MUTEX_DEFAULT, IPL_NONE); + mutex_init(&sc->sc_cvlock, MUTEX_DEFAULT, IPL_NONE); + cv_init(&sc->sc_ping, device_xname(self)); + + aprint_naive(": SMBus controller\n"); + aprint_normal(": SMBus controller\n"); + + ih = evbmips_intr_establish(aa->aa_irq, jziic_intr, sc); + + if (ih == NULL) { + aprint_error_dev(self, "failed to establish interrupt %d\n", + aa->aa_irq); + goto fail; + } + +#ifdef JZIIC_DEBUG + if (jziic_i2c_exec(sc, I2C_OP_READ_WITH_STOP, 0x51, in, 1, out, 9, 0) + >= 0) { + for (i = 0; i < 9; i++) + printf(" %02x", out[i]); + printf("\n"); + delay(1000000); + jziic_i2c_exec(sc, I2C_OP_READ_WITH_STOP, + 0x51, in, 1, out, 9, 0); + for (i = 0; i < 9; i++) + printf(" %02x", out[i]); + printf("\n"); + delay(1000000); + jziic_i2c_exec(sc, I2C_OP_READ_WITH_STOP, + 0x51, in, 1, out, 9, 0); + for (i = 0; i < 9; i++) + printf(" %02x", out[i]); + printf("\n"); + } +#endif + + /* fill in the i2c tag */ + sc->sc_i2c.ic_cookie = sc; + sc->sc_i2c.ic_acquire_bus = jziic_i2c_acquire_bus; + sc->sc_i2c.ic_release_bus = jziic_i2c_release_bus; + sc->sc_i2c.ic_send_start = NULL; + sc->sc_i2c.ic_send_stop = NULL; + sc->sc_i2c.ic_initiate_xfer = NULL; + sc->sc_i2c.ic_read_byte = NULL; + sc->sc_i2c.ic_write_byte = NULL; + sc->sc_i2c.ic_exec = jziic_i2c_exec; + + iba.iba_tag = &sc->sc_i2c; + (void) config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print); + + + return; + +fail: + if (ih) { + evbmips_intr_disestablish(ih); + } + bus_space_unmap(sc->sc_memt, sc->sc_memh, 0x100); +} + +STATIC int +jziic_enable(struct jziic_softc *sc) +{ + int bail = 100000; + uint32_t reg; + + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBENB, JZ_ENABLE); + reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, JZ_SMBENBST); + DPRINTF("status: %02x\n", reg); + while ((bail > 0) && (reg == 0)) { + bail--; + reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, JZ_SMBENBST); + } + DPRINTF("bail: %d\n", bail); + return (reg != 0); +} + +STATIC void +jziic_disable(struct jziic_softc *sc) +{ + int bail = 100000; + uint32_t reg; + + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBENB, 0); + reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, JZ_SMBENBST); + DPRINTF("status: %02x\n", reg); + while ((bail > 0) && (reg != 0)) { + bail--; + reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, JZ_SMBENBST); + } + DPRINTF("bail: %d\n", bail); +} + +STATIC int +jziic_i2c_acquire_bus(void *cookie, int flags) +{ + struct jziic_softc *sc = cookie; + + mutex_enter(&sc->sc_buslock); + return 0; +} + +STATIC void +jziic_i2c_release_bus(void *cookie, int flags) +{ + struct jziic_softc *sc = cookie; + + mutex_exit(&sc->sc_buslock); +} + +STATIC int +jziic_wait(struct jziic_softc *sc) +{ + uint32_t reg; + int bail = 10000; + reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, JZ_SMBST); + while ((reg & JZ_MSTACT) && (bail > 0)) { + delay(100); + reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, JZ_SMBST); + bail--; + } + return ((reg & JZ_MSTACT) == 0); +} + +STATIC void +jziic_set_speed(struct jziic_softc *sc) +{ + int ticks, hcnt, lcnt, hold, setup; + + /* PCLK ticks per SMBus cycle */ + ticks = sc->sc_pclk / 100; /* assuming 100kHz for now */ + hcnt = (ticks * 40 / (40 + 47)) - 8; + lcnt = (ticks * 47 / (40 + 47)) - 1; + hold = sc->sc_pclk * 4 / 10000 - 1; /* ... * 400 / 1000000 ... */ + hold = max(1, hold); + hold |= JZ_HDENB; + setup = sc->sc_pclk * 3 / 10000 + 1; /* ... * 300 / 1000000 ... */ + DPRINTF("hcnt %d lcnt %d hold %d\n", hcnt, lcnt, hold); + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBSHCNT, hcnt); + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBSLCNT, lcnt); + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBSDAHD, hold); + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBSDASU, setup); + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBCON, + JZ_SLVDIS | JZ_STPHLD | JZ_REST | JZ_SPD_100KB | JZ_MD); + (void)bus_space_read_4(sc->sc_memt, sc->sc_memh, JZ_SMBCINT); +} + +STATIC int +jziic_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *vcmd, + size_t cmdlen, void *vbuf, size_t buflen, int flags) +{ + struct jziic_softc *sc = cookie; + + if (cold || (flags & I2C_F_POLL)) { + return jziic_i2c_exec_poll(sc, op, addr, vcmd, cmdlen, vbuf, + buflen, flags); + } else { +#ifdef JZIIC_DEBUG + uint8_t *b = vbuf; + int i, ret; + + memset(vbuf, 0, buflen); + jziic_i2c_exec_intr(sc, op, addr, vcmd, cmdlen, vbuf, + buflen, flags); + for (i = 0; i < buflen; i++) { + printf(" %02x", b[i]); + } + printf("\n"); + ret = jziic_i2c_exec_poll(sc, op, addr, vcmd, cmdlen, vbuf, + buflen, flags); + for (i = 0; i < buflen; i++) { + printf(" %02x", b[i]); + } + printf("\n"); + return ret; +#else + return jziic_i2c_exec_intr(sc, op, addr, vcmd, cmdlen, vbuf, + buflen, flags); +#endif + } +} + +STATIC int +jziic_i2c_exec_poll(struct jziic_softc *sc, i2c_op_t op, i2c_addr_t addr, + const void *vcmd, size_t cmdlen, void *vbuf, size_t buflen, int flags) +{ + int i, bail = 10000, ret = 0; + uint32_t abort; + uint8_t *rx, data; + const uint8_t *tx; + + tx = vcmd; + rx = vbuf; + + DPRINTF("%s: 0x%02x %d %d\n", __func__, addr, cmdlen, buflen); + + jziic_disable(sc); + + /* we're polling, so disable interrupts */ + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBINTM, 0); + + jziic_set_speed(sc); + jziic_wait(sc); + /* try to talk... */ + + if (!jziic_enable(sc)) { + ret = -1; + goto bork; + } + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBINTM, 0); + + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBTAR, addr); + jziic_wait(sc); + DPRINTF("st: %02x\n", + bus_space_read_4(sc->sc_memt, sc->sc_memh, JZ_SMBST)); + DPRINTF("wr int: %02x\n", + bus_space_read_4(sc->sc_memt, sc->sc_memh, JZ_SMBINTST)); + abort = bus_space_read_4(sc->sc_memt, sc->sc_memh, JZ_SMBABTSRC); + DPRINTF("abort: %02x\n", abort); + if ((abort != 0)) { + ret = -1; + goto bork; + } + + do { + bail--; + delay(100); + } while (((bus_space_read_4(sc->sc_memt, sc->sc_memh, JZ_SMBST) & + JZ_TFE) == 0) && (bail > 0)); + + if (cmdlen != 0) { + for (i = 0; i < cmdlen; i++) { + bus_space_write_4(sc->sc_memt, sc->sc_memh, + JZ_SMBDC, *tx); + tx++; + } + } + + if (I2C_OP_READ_P(op)) { + /* now read */ + for (i = 0; i < (buflen + 1); i++) { + bus_space_write_4(sc->sc_memt, sc->sc_memh, + JZ_SMBDC, JZ_CMD); + } + wbflush(); + DPRINTF("rd st: %02x\n", + bus_space_read_4(sc->sc_memt, sc->sc_memh, JZ_SMBST)); + DPRINTF("rd int: %02x\n", + bus_space_read_4(sc->sc_memt, sc->sc_memh, JZ_SMBINTST)); + DPRINTF("abort: %02x\n", + bus_space_read_4(sc->sc_memt, sc->sc_memh, JZ_SMBABTSRC)); + for (i = 0; i < buflen; i++) { + bail = 10000; + while (((bus_space_read_4(sc->sc_memt, sc->sc_memh, + JZ_SMBST) & JZ_RFNE) == 0) && (bail > 0)) { + bail--; + delay(100); + } + if (bail == 0) { + ret = -1; + goto bork; + } + data = bus_space_read_4(sc->sc_memt, sc->sc_memh, + JZ_SMBDC); + DPRINTF("rd st: %02x %d\n", + bus_space_read_4(sc->sc_memt, sc->sc_memh, JZ_SMBST), + bail); + DPRINTF("rd int: %02x\n", + bus_space_read_4(sc->sc_memt, sc->sc_memh, + JZ_SMBINTST)); + DPRINTF("abort: %02x\n", abort); + DPRINTF("rd data: %02x\n", data); + *rx = data; + rx++; + } + } else { + tx = vbuf; + for (i = 0; i < buflen; i++) { + DPRINTF("wr data: %02x\n", *tx); + bus_space_write_4(sc->sc_memt, sc->sc_memh, + JZ_SMBDC, *tx); + wbflush(); + tx++; + } + jziic_wait(sc); + abort = bus_space_read_4(sc->sc_memt, sc->sc_memh, + JZ_SMBABTSRC); + DPRINTF("abort: %02x\n", abort); + if ((abort != 0)) { + ret = -1; + goto bork; + } + + DPRINTF("st: %02x %d\n", + bus_space_read_4(sc->sc_memt, sc->sc_memh, JZ_SMBST), bail); + DPRINTF("wr int: %02x\n", + bus_space_read_4(sc->sc_memt, sc->sc_memh, JZ_SMBINTST)); + } + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBCON, + JZ_SLVDIS | JZ_REST | JZ_SPD_100KB | JZ_MD); +bork: + jziic_disable(sc); + return ret; +} + +STATIC int +jziic_i2c_exec_intr(struct jziic_softc *sc, i2c_op_t op, i2c_addr_t addr, + const void *vcmd, size_t cmdlen, void *vbuf, size_t buflen, int flags) +{ + int i, ret = 0, bail; + + DPRINTF("%s: 0x%02x %d %d\n", __func__, addr, cmdlen, buflen); + + jziic_disable(sc); + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBINTM, 0); + + mutex_enter(&sc->sc_cvlock); + + sc->sc_reading = FALSE; + + if (I2C_OP_READ_P(op)) { + sc->sc_cmd = vcmd; + sc->sc_cmdlen = cmdlen; + sc->sc_buf = vbuf; + sc->sc_buflen = buflen; + memset(vbuf, 0, buflen); + } else { + if ((cmdlen + buflen) > 256) + return -1; + memcpy(sc->sc_txbuf, vcmd, cmdlen); + memcpy(sc->sc_txbuf + cmdlen, vbuf, buflen); + sc->sc_cmd = sc->sc_txbuf; + sc->sc_cmdlen = cmdlen + buflen; + sc->sc_buf = NULL; + sc->sc_buflen = 0; + } + sc->sc_cmdptr = 0; + sc->sc_bufptr = 0; + sc->sc_rds = 0; + sc->sc_abort = 0; + + jziic_set_speed(sc); + jziic_wait(sc); + + /* set FIFO levels */ + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBTXTL, 4); + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBRXTL, 0 + /*min(7, max(0, buflen - 2 ))*/); + + /* try to talk... */ + + if (!jziic_enable(sc)) { + ret = -1; + goto bork; + } + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBINTM, 0); + + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBTAR, addr); + jziic_wait(sc); + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBCINT, JZ_CLEARALL); + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBINTM, + JZ_TXABT | JZ_TXEMP); + + bail = 100 * sc->sc_cmdlen; + while ((sc->sc_cmdptr < sc->sc_cmdlen) && (bail > 0)) { + cv_timedwait(&sc->sc_ping, &sc->sc_cvlock, 1); + if (sc->sc_abort) { + /* we received an abort interrupt -> bailout */ + DPRINTF("abort: %x\n", sc->sc_abort); + ret = -1; + goto bork; + } + bail--; + } + + if (sc->sc_cmdptr < sc->sc_cmdlen) { + /* we didn't send everything? */ + DPRINTF("sent %d of %d\n", sc->sc_cmdptr, sc->sc_cmdlen); + ret = -1; + goto bork; + } + + if (I2C_OP_READ_P(op)) { + /* now read */ + sc->sc_reading = TRUE; + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBINTM, + JZ_TXABT | JZ_RXFL | JZ_TXEMP); + + for (i = 0; i < min((buflen + 1), 4); i++) { + bus_space_write_4(sc->sc_memt, sc->sc_memh, + JZ_SMBDC, JZ_CMD); + wbflush(); + } + sc->sc_rds = i; + + bail = 10 * sc->sc_buflen; /* 10 ticks per byte should be ok */ + while ((sc->sc_bufptr < sc->sc_buflen) && (bail > 0)) { + cv_timedwait(&sc->sc_ping, &sc->sc_cvlock, 1); + if (sc->sc_abort) { + /* we received an abort interrupt -> bailout */ + DPRINTF("rx abort: %x\n", sc->sc_abort); + ret = -1; + goto bork; + } + bail--; + } + + if (sc->sc_bufptr < sc->sc_buflen) { + /* we didn't get everything? */ + DPRINTF("rcvd %d of %d\n", sc->sc_bufptr, sc->sc_buflen); + ret = -1; + goto bork; + } + } + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBCON, + JZ_SLVDIS | JZ_REST | JZ_SPD_100KB | JZ_MD); +bork: + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBINTM, 0); + jziic_disable(sc); + mutex_exit(&sc->sc_cvlock); + return ret; +} + +STATIC int +jziic_intr(void *cookie) +{ + struct jziic_softc *sc = cookie; + uint32_t stat, data, rstat; + int i; + + stat = bus_space_read_4(sc->sc_memt, sc->sc_memh, JZ_SMBINTST); + if (stat & JZ_TXEMP) { + if (sc->sc_reading) { + if (sc->sc_rds < (sc->sc_buflen + 1)) { + for (i = 0; + i < min(4, (sc->sc_buflen + 1) - + sc->sc_rds); + i++) { + bus_space_write_4( sc->sc_memt, + sc->sc_memh, + JZ_SMBDC, JZ_CMD); + wbflush(); + } + sc->sc_rds += i; + } else { + /* we're done, so turn TX FIFO interrupt off */ + bus_space_write_4(sc->sc_memt, sc->sc_memh, + JZ_SMBINTM, + JZ_TXABT | JZ_RXFL); + } + } else { + rstat = bus_space_read_4(sc->sc_memt, sc->sc_memh, + JZ_SMBST); + while ((rstat & JZ_TFNF) && + (sc->sc_cmdptr < sc->sc_cmdlen)) { + data = *sc->sc_cmd; + sc->sc_cmd++; + sc->sc_cmdptr++; + bus_space_write_4(sc->sc_memt, sc->sc_memh, + JZ_SMBDC, data & 0xff); + rstat = bus_space_read_4(sc->sc_memt, sc->sc_memh, + JZ_SMBST); + }; + /* no need to clear this one */ + if (sc->sc_cmdptr >= sc->sc_cmdlen) { + cv_signal(&sc->sc_ping); + bus_space_write_4(sc->sc_memt, sc->sc_memh, + JZ_SMBINTM, JZ_TXABT); + } + } + } + if (stat & JZ_RXFL) { + rstat = bus_space_read_4(sc->sc_memt, sc->sc_memh, JZ_SMBST); + while ((rstat & JZ_RFNE) && (sc->sc_bufptr < sc->sc_buflen)) { + data = bus_space_read_4(sc->sc_memt, sc->sc_memh, + JZ_SMBDC); + *sc->sc_buf = (uint8_t)(data & 0xff); + sc->sc_buf++; + sc->sc_bufptr++; + rstat = bus_space_read_4(sc->sc_memt, sc->sc_memh, + JZ_SMBST); + } + if (sc->sc_bufptr >= sc->sc_buflen) + cv_signal(&sc->sc_ping); + } + if (stat & JZ_TXABT) { + sc->sc_abort = bus_space_read_4(sc->sc_memt, sc->sc_memh, + JZ_SMBABTSRC); + cv_signal(&sc->sc_ping); + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBCINT, + JZ_CLEARALL); + bus_space_write_4(sc->sc_memt, sc->sc_memh, JZ_SMBINTM, 0); + } + return 0; +} Property changes on: projects/ci20_mips/sys/mips/ingenic/jziic.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property