Index: head/sys/arm/allwinner/aw_p2wi.c =================================================================== --- head/sys/arm/allwinner/aw_p2wi.c (nonexistent) +++ head/sys/arm/allwinner/aw_p2wi.c (revision 307822) @@ -0,0 +1,277 @@ +/*- + * Copyright (c) 2016 Emmanuel Vadot + * 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 ``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 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$ + */ + +/* + * Allwinner P2WI (Push-Pull Two Wire Interface) + * P2WI is a iic-like interface used on sun6i hardware + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include + +#include "iicbus_if.h" + +static struct ofw_compat_data compat_data[] = { + { "allwinner,sun6i-a31-p2wi", 1 }, + { NULL, 0 } +}; + +static struct resource_spec p2wi_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, + { -1, 0 } +}; + +struct p2wi_softc { + struct resource *res; + struct mtx mtx; + clk_t clk; + hwreset_t rst; + device_t iicbus; +}; + +#define P2WI_LOCK(sc) mtx_lock(&(sc)->mtx) +#define P2WI_UNLOCK(sc) mtx_unlock(&(sc)->mtx) +#define P2WI_READ(sc, reg) bus_read_4((sc)->res, (reg)) +#define P2WI_WRITE(sc, reg, val) bus_write_4((sc)->res, (reg), (val)) + +#define P2WI_RETRY 1000 + +static phandle_t +p2wi_get_node(device_t bus, device_t dev) +{ + return (ofw_bus_get_node(bus)); +} + +static int +p2wi_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) +{ + struct p2wi_softc *sc; + int retry; + + sc = device_get_softc(dev); + + P2WI_LOCK(sc); + + P2WI_WRITE(sc, P2WI_CTRL, P2WI_CTRL_SOFT_RESET); + for (retry = P2WI_RETRY; retry > 0; retry--) + if ((P2WI_READ(sc, P2WI_CTRL) & P2WI_CTRL_SOFT_RESET) == 0) + break; + + P2WI_UNLOCK(sc); + + if (retry == 0) { + device_printf(dev, "soft reset timeout\n"); + return (ETIMEDOUT); + } + + return (IIC_ENOADDR); +} + +static int +p2wi_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) +{ + struct p2wi_softc *sc; + int retry, error; + uint8_t data_len; + + sc = device_get_softc(dev); + + /* + * Since P2WI is only used for AXP22x PMIC we only support + * two messages of one byte length + */ + if (nmsgs != 2 || (msgs[0].flags & IIC_M_RD) == IIC_M_RD || + msgs[0].len != 1 || msgs[1].len != 1) + return (EINVAL); + + P2WI_LOCK(sc); + + /* Write address */ + P2WI_WRITE(sc, P2WI_DADDR0, msgs[0].buf[0]); + + /* Write Data length/Direction */ + data_len = P2WI_DLEN_LEN(msgs[1].len); + if ((msgs[1].flags & IIC_M_RD) == 0) + P2WI_WRITE(sc, P2WI_DATA0, msgs[1].buf[0]); + else + data_len |= P2WI_DLEN_READ; + P2WI_WRITE(sc, P2WI_DLEN, data_len); + + /* Start transfer */ + P2WI_WRITE(sc, P2WI_CTRL, P2WI_CTRL_START_TRANS); + + /* Wait for transfer to complete */ + for (retry = P2WI_RETRY; retry > 0; retry--) + if ((P2WI_READ(sc, P2WI_CTRL) & P2WI_CTRL_START_TRANS) == 0) + break; + + if (retry == 0) { + error = ETIMEDOUT; + goto done; + } + + /* Read data if needed */ + if ((msgs[1].flags & IIC_M_RD) == IIC_M_RD) { + msgs[1].buf[0] = P2WI_READ(sc, P2WI_DATA0) & 0xff; + msgs[1].len = 1; + } + + error = 0; + +done: + P2WI_UNLOCK(sc); + + return (error); +} + +static int +p2wi_probe(device_t dev) +{ + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + return (ENXIO); + + device_set_desc(dev, "Allwinner P2WI"); + return (BUS_PROBE_DEFAULT); +} + +static int +p2wi_attach(device_t dev) +{ + struct p2wi_softc *sc; + int error; + + sc = device_get_softc(dev); + mtx_init(&sc->mtx, device_get_nameunit(dev), "p2wi", MTX_DEF); + + if (clk_get_by_ofw_index(dev, 0, 0, &sc->clk) == 0) { + error = clk_enable(sc->clk); + if (error != 0) { + device_printf(dev, "cannot enable clock\n"); + goto fail; + } + } + if (hwreset_get_by_ofw_idx(dev, 0, 0, &sc->rst) == 0) { + error = hwreset_deassert(sc->rst); + if (error != 0) { + device_printf(dev, "cannot de-assert reset\n"); + goto fail; + } + } + + if (bus_alloc_resources(dev, p2wi_spec, &sc->res) != 0) { + device_printf(dev, "cannot allocate resources for device\n"); + error = ENXIO; + goto fail; + } + + sc->iicbus = device_add_child(dev, "iicbus", -1); + if (sc->iicbus == NULL) { + device_printf(dev, "cannot add iicbus child device\n"); + error = ENXIO; + goto fail; + } + + /* Disable interrupts */ + P2WI_WRITE(sc, P2WI_INTE, 0x0); + + bus_generic_attach(dev); + + return (0); + +fail: + bus_release_resources(dev, p2wi_spec, &sc->res); + if (sc->rst != NULL) + hwreset_release(sc->rst); + if (sc->clk != NULL) + clk_release(sc->clk); + mtx_destroy(&sc->mtx); + return (error); +} + +static device_method_t p2wi_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, p2wi_probe), + DEVMETHOD(device_attach, p2wi_attach), + + /* Bus interface */ + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), + DEVMETHOD(bus_release_resource, bus_generic_release_resource), + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), + DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), + DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), + + /* OFW methods */ + DEVMETHOD(ofw_bus_get_node, p2wi_get_node), + + /* iicbus interface */ + DEVMETHOD(iicbus_callback, iicbus_null_callback), + DEVMETHOD(iicbus_reset, p2wi_reset), + DEVMETHOD(iicbus_transfer, p2wi_transfer), + + DEVMETHOD_END +}; + +static driver_t p2wi_driver = { + "iichb", + p2wi_methods, + sizeof(struct p2wi_softc), +}; + +static devclass_t p2wi_devclass; + +EARLY_DRIVER_MODULE(iicbus, p2wi, iicbus_driver, iicbus_devclass, 0, 0, + BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE); +EARLY_DRIVER_MODULE(p2wi, simplebus, p2wi_driver, p2wi_devclass, 0, 0, + BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE); +MODULE_VERSION(p2wi, 1); Property changes on: head/sys/arm/allwinner/aw_p2wi.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: head/sys/arm/allwinner/aw_p2wi.h =================================================================== --- head/sys/arm/allwinner/aw_p2wi.h (nonexistent) +++ head/sys/arm/allwinner/aw_p2wi.h (revision 307822) @@ -0,0 +1,79 @@ +/*- + * Copyright (c) 2016 Emmanuel Vadot + * 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 ``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 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$ + */ + +#ifndef __AW_P2WI_H__ +#define __AW_P2WI_H__ + +#define P2WI_CTRL 0x00 +#define P2WI_CTRL_SOFT_RESET (1 << 0) +#define P2WI_CTRL_GLOBAL_INT_ENB (1 << 1) +#define P2WI_CTRL_ABORT_TRANS (1 << 6) +#define P2WI_CTRL_START_TRANS (1 << 7) + +#define P2WI_CCR 0x04 +#define P2WI_CCR_CLK_DIV_SHIFT 0 +#define P2WI_CCR_CLK_DIV_MASK 0xFF +#define P2WI_CCR_SDA_ODLY_SHIFT 7 +#define P2WI_CCR_SDA_ODLY_MASK 0x700 + +#define P2WI_INTE 0x08 +#define P2WI_INTE_TRANS_OVER_ENB +#define P2WI_INTE_TRANS_ERR_ENB +#define P2WI_INTE_LOAD_BSY_ENB + +#define P2WI_STAT 0x0C +#define P2WI_STAT_TRANS_OVER (1 << 0) +#define P2WI_STAT_TRANS_ERR (1 << 1) +#define P2WI_STAT_LOAD_BSY (1 << 2) +#define P2WI_STAT_TRANS_ERR_ID_SHIFT 7 +#define P2WI_STAT_TRANS_ERR_ID_MASK 0xFF00 + +#define P2WI_DADDR0 0x10 + +#define P2WI_DADDR1 0x14 + +#define P2WI_DLEN 0x18 +#define P2WI_DLEN_LEN(x) ((x - 1) & 0x7) +#define P2WI_DLEN_READ (1 << 4) + +#define P2WI_DATA0 0x1C + +#define P2WI_DATA1 0x20 + +#define P2WI_LCR 0x24 +#define P2WI_LCR_SDA_CTL_EN (1 << 0) +#define P2WI_LCR_SDA_CTL (1 << 1) +#define P2WI_LCR_SCL_CTL_EN (1 << 2) +#define P2WI_LCR_SCL_CTL (1 << 3) +#define P2WI_LCR_SDA_STATE (1 << 4) +#define P2WI_LCR_SCL_STATE (1 << 5) + + +#define P2WI_PMCR 0x28 + +#endif /* __AW_P2WI_H__ */ Property changes on: head/sys/arm/allwinner/aw_p2wi.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: head/sys/arm/allwinner/files.allwinner =================================================================== --- head/sys/arm/allwinner/files.allwinner (revision 307821) +++ head/sys/arm/allwinner/files.allwinner (revision 307822) @@ -1,57 +1,58 @@ # $FreeBSD$ kern/kern_clocksource.c standard arm/allwinner/a10_ahci.c optional ahci arm/allwinner/a10_codec.c optional sound arm/allwinner/a10_common.c standard arm/allwinner/a10_dmac.c standard arm/allwinner/a10_ehci.c optional ehci arm/allwinner/aw_usbphy.c optional ehci arm/allwinner/a10_gpio.c optional gpio arm/allwinner/a10_mmc.c optional mmc arm/allwinner/a10_sramc.c standard arm/allwinner/aw_nmi.c optional intrng arm/allwinner/aw_if_dwc.c optional dwc +arm/allwinner/aw_p2wi.c optional p2wi arm/allwinner/aw_rsb.c optional rsb arm/allwinner/aw_rtc.c standard arm/allwinner/aw_ts.c standard arm/allwinner/aw_wdog.c standard arm/allwinner/aw_machdep.c standard arm/allwinner/aw_mp.c optional smp arm/allwinner/axp209.c optional axp209 arm/allwinner/axp81x.c optional axp81x arm/allwinner/if_awg.c optional awg arm/allwinner/if_emac.c optional emac arm/allwinner/sunxi_dma_if.m standard dev/iicbus/twsi/a10_twsi.c optional twsi dev/usb/controller/generic_ohci.c optional ohci dev/usb/controller/generic_usb_if.m optional ohci arm/allwinner/aw_sid.c standard arm/allwinner/aw_thermal.c standard dev/iicbus/sy8106a.c optional sy8106a #arm/allwinner/console.c standard arm/allwinner/a10_fb.c optional vt arm/allwinner/a10_hdmi.c optional hdmi arm/allwinner/a10_hdmiaudio.c optional hdmi sound arm/arm/hdmi_if.m optional hdmi arm/allwinner/aw_reset.c standard arm/allwinner/aw_ccu.c standard arm/allwinner/clk/aw_ahbclk.c standard arm/allwinner/clk/aw_apbclk.c standard arm/allwinner/clk/aw_axiclk.c standard arm/allwinner/clk/aw_codecclk.c standard arm/allwinner/clk/aw_cpuclk.c standard arm/allwinner/clk/aw_cpusclk.c standard arm/allwinner/clk/aw_debeclk.c standard arm/allwinner/clk/aw_gate.c standard arm/allwinner/clk/aw_gmacclk.c standard arm/allwinner/clk/aw_hdmiclk.c standard arm/allwinner/clk/aw_lcdclk.c standard arm/allwinner/clk/aw_modclk.c standard arm/allwinner/clk/aw_mmcclk.c standard arm/allwinner/clk/aw_oscclk.c standard arm/allwinner/clk/aw_pll.c standard arm/allwinner/clk/aw_thsclk.c standard arm/allwinner/clk/aw_usbclk.c standard Index: head/sys/arm/conf/GENERIC =================================================================== --- head/sys/arm/conf/GENERIC (revision 307821) +++ head/sys/arm/conf/GENERIC (revision 307822) @@ -1,173 +1,174 @@ # # GENERICV6 -- Generic(ish) kernel config. # # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # # http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the # FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the # device lines is also present in the ../../conf/NOTES and NOTES files. # If you are in doubt as to the purpose or necessity of a line, check first # in NOTES. # # $FreeBSD$ ident GENERIC cpu CPU_CORTEXA_MP machine arm armv6 makeoptions CONF_CFLAGS="-march=armv7a" makeoptions KERNVIRTADDR=0xc0000000 options KERNVIRTADDR=0xc0000000 include "std.armv6" files "../allwinner/files.allwinner" files "../allwinner/a20/files.a20" files "../allwinner/a31/files.a31" files "../allwinner/a83t/files.a83t" files "../allwinner/h3/files.h3" files "../broadcom/bcm2835/files.bcm2836" files "../broadcom/bcm2835/files.bcm283x" files "../nvidia/tegra124/files.tegra124" files "../qemu/files.qemu" options SOC_ALLWINNER_A20 options SOC_ALLWINNER_A31 options SOC_ALLWINNER_A31S options SOC_ALLWINNER_A83T options SOC_ALLWINNER_H3 options SOC_BCM2836 options SCHED_ULE # ULE scheduler options SMP # Enable multiple cores options PLATFORM options PLATFORM_SMP options MULTIDELAY options LINUX_BOOT_ABI # EXT_RESOURCES pseudo devices options EXT_RESOURCES device clk device phy device hwreset device regulator # Interrupt controller options INTRNG device gic # ARM Generic Timer device generic_timer # MMC/SD/SDIO Card slot support device sdhci # SD controller device mmc # mmc/sd bus device mmcsd # mmc/sd flash cards # ATA controllers device ahci # AHCI-compatible SATA controllers #device ata # Legacy ATA/SATA controllers # PCI options NEW_PCIB device pci # PCI NICs device re # RealTek 8139C+/8169/8169S/8110S # VirtIO device virtio device virtio_mmio device virtio_blk device vtnet # Console and misc device uart device uart_ns8250 device uart_snps device pl011 device pty device snp device md # Memory "disks" device random # Entropy device device psci # I2C support device iicbus device iic device twsi device rsb +device p2wi # Allwinner Push-Pull Two Wire interface device axp209 # AXP209 Power Management Unit device axp81x # AXP813/818 Power Management Unit device bcm2835_bsc device icee # GPIO device gpio device gpioled device gpioregulator # SPI device spibus device bcm2835_spi device scbus # SCSI bus (required for ATA/SCSI) device da # Direct Access (disks) device cd # CD device pass # Passthrough device (direct ATA/SCSI access) # USB support options USB_HOST_ALIGN=64 # Align usb buffers to cache line size. device usb #device uhci device ohci device ehci device dwcotg # DWC OTG controller device umass # Disks/Mass storage - Requires scbus and da device uhid # "Human Interface Devices" device ukbd # Allow keyboard like HIDs to control console # Ethernet device loop device ether device vlan # 802.1Q VLAN support device mii device bpf #device emac # 10/100 integrated EMAC controller device dwc # 10/100/1000 integrated GMAC controller device awg # 10/100/1000 integrated EMAC controller # USB ethernet support, requires miibus device smcphy device smsc device miibus # Sound support device sound # Framebuffer support device vt device kbdmux device ums device videomode device hdmi device vchiq # Pinmux device fdt_pinctrl # Extensible Firmware Interface options EFI # Flattened Device Tree options FDT # Configure using FDT/DTB data makeoptions MODULES_EXTRA="dtb/allwinner dtb/nvidia dtb/rpi"