Author: ray Date: Wed Mar 20 15:39:27 2013 New Revision: 248557 URL: http://svnweb.freebsd.org/changeset/base/248557
Log: Integrate Efika MX project back to home. Sponsored by: The FreeBSD Foundation Added: head/sys/arm/conf/EFIKA_MX (contents, props changed) head/sys/arm/freescale/ head/sys/arm/freescale/imx/ head/sys/arm/freescale/imx/bus_space.c (contents, props changed) head/sys/arm/freescale/imx/common.c (contents, props changed) head/sys/arm/freescale/imx/console.c (contents, props changed) head/sys/arm/freescale/imx/i2c.c (contents, props changed) head/sys/arm/freescale/imx/imx.files (contents, props changed) head/sys/arm/freescale/imx/imx51_ccm.c (contents, props changed) head/sys/arm/freescale/imx/imx51_ccmreg.h (contents, props changed) head/sys/arm/freescale/imx/imx51_ccmvar.h (contents, props changed) head/sys/arm/freescale/imx/imx51_dpllreg.h (contents, props changed) head/sys/arm/freescale/imx/imx51_gpio.c (contents, props changed) head/sys/arm/freescale/imx/imx51_iomux.c (contents, props changed) head/sys/arm/freescale/imx/imx51_iomuxreg.h (contents, props changed) head/sys/arm/freescale/imx/imx51_iomuxvar.h (contents, props changed) head/sys/arm/freescale/imx/imx51_ipuv3.c (contents, props changed) head/sys/arm/freescale/imx/imx51_ipuv3reg.h (contents, props changed) head/sys/arm/freescale/imx/imx51_sdmareg.h (contents, props changed) head/sys/arm/freescale/imx/imx51_ssireg.h (contents, props changed) head/sys/arm/freescale/imx/imx51_tzicreg.h (contents, props changed) head/sys/arm/freescale/imx/imx_gpt.c (contents, props changed) head/sys/arm/freescale/imx/imx_gptreg.h (contents, props changed) head/sys/arm/freescale/imx/imx_gptvar.h (contents, props changed) head/sys/arm/freescale/imx/imx_machdep.c (contents, props changed) head/sys/arm/freescale/imx/imx_wdog.c (contents, props changed) head/sys/arm/freescale/imx/imx_wdogreg.h (contents, props changed) head/sys/arm/freescale/imx/std.imx (contents, props changed) head/sys/arm/freescale/imx/tzic.c (contents, props changed) head/sys/boot/fdt/dts/efikamx.dts (contents, props changed) head/sys/boot/fdt/dts/imx51x.dtsi (contents, props changed) head/sys/dev/ata/chipsets/ata-fsl.c (contents, props changed) head/sys/dev/uart/uart_dev_imx.c (contents, props changed) head/sys/dev/uart/uart_dev_imx5xx.h (contents, props changed) head/sys/dev/usb/controller/ehci_imx.c (contents, props changed) Modified: head/sys/dev/uart/uart.h head/sys/dev/uart/uart_bus_fdt.c Added: head/sys/arm/conf/EFIKA_MX ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/conf/EFIKA_MX Wed Mar 20 15:39:27 2013 (r248557) @@ -0,0 +1,177 @@ +# Kernel configuration for Efika MX Smarttop/Smartbook boards +# +# 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 EFIKA_MX + +include "../freescale/imx/std.imx" + +makeoptions WITHOUT_MODULES="ahc" + +makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols +#options DEBUG + +options SCHED_4BSD # 4BSD scheduler +#options PREEMPTION # Enable kernel thread preemption +options INET # InterNETworking +#options INET6 # IPv6 communications protocols +#options SCTP # Stream Control Transmission Protocol +options FFS # Berkeley Fast Filesystem +options SOFTUPDATES # Enable FFS soft updates support +options UFS_ACL # Support for access control lists +options UFS_DIRHASH # Improve performance on big directories +options UFS_GJOURNAL # Enable gjournal-based UFS journaling +#options MD_ROOT # MD is a potential root device +options NFSCL # New Network Filesystem Client +#options NFSD # New Network Filesystem Server +options NFSLOCKD # Network Lock Manager +options NFS_ROOT # NFS usable as /, requires NFSCL +options MSDOSFS # MSDOS Filesystem +options CD9660 # ISO 9660 Filesystem +#options PROCFS # Process filesystem (requires PSEUDOFS) +options PSEUDOFS # Pseudo-filesystem framework +options TMPFS # TMP Memory Filesystem +options GEOM_PART_GPT # GUID Partition Tables. +options GEOM_LABEL # Provides labelization +#options COMPAT_FREEBSD5 # Compatible with FreeBSD5 +#options COMPAT_FREEBSD6 # Compatible with FreeBSD6 +#options COMPAT_FREEBSD7 # Compatible with FreeBSD7 +options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI +options KTRACE # ktrace(1) support +options SYSVSHM # SYSV-style shared memory +options SYSVMSG # SYSV-style message queues +options SYSVSEM # SYSV-style semaphores +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions +options INCLUDE_CONFIG_FILE # Include this file in kernel + +# required for netbooting +#options BOOTP +#options BOOTP_COMPAT +#options BOOTP_NFSROOT +#options BOOTP_NFSV3 +#options BOOTP_WIRED_TO=ue0 +# +options ROOTDEVNAME=\"ufs:ada0s2a\" + + +# kernel/memory size reduction +#options MUTEX_NOINLINE +#options NO_FFS_SNAPSHOT +#options NO_SWAPPING +#options NO_SYSCTL_DESCR +#options RWLOCK_NOINLINE + +# Debugging support. Always need this: +options KDB # Enable kernel debugger support. +# For minimum debugger support (stable branch) use: +#options KDB_TRACE # Print a stack trace for a panic. +# For full debugger support use this instead: +options DDB # Support DDB. +#options GDB # Support remote GDB. +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 + +# The `bpf' device enables the Berkeley Packet Filter. +# Be aware of the administrative consequences of enabling this! +# Note that 'bpf' is required for DHCP. +device bpf # Berkeley packet filter + +# Pseudo devices. +device loop # Network loopback +device random # Entropy device +device ether # Ethernet support +#device vlan # 802.1Q VLAN support +#device tun # Packet tunnel. +#device md # Memory "disks" +#device gif # IPv6 and IPv4 tunneling +#device faith # IPv6-to-IPv4 relaying (translation) +#device firmware # firmware assist module + +# Serial (COM) ports +device uart # Multi-uart driver +options ALT_BREAK_TO_DEBUGGER + +device ata +device atapci # Only for helper functions +device imxata +options ATA_CAM +options ATA_STATIC_ID # Static device numbering + +device iomux # IO Multiplexor + +device gpio +device gpioled + +device fsliic +device iic +device iicbus + +# SCSI peripherals +device scbus # SCSI bus (required for SCSI) +device da # Direct Access (disks) +device cd # CD +device pass # Passthrough device (direct SCSI access) + +# USB support +#options USB_DEBUG # enable debug msgs +device ehci # OHCI USB interface +device usb # USB Bus (required) +device umass # Disks/Mass storage - Requires scbus and da +device uhid # "Human Interface Devices" +device u3g + +# USB Ethernet, requires miibus +device miibus +device aue # ADMtek USB Ethernet +device axe # ASIX Electronics USB Ethernet +device cdce # Generic USB over Ethernet +device cue # CATC USB Ethernet +device kue # Kawasaki LSI USB Ethernet +device rue # RealTek RTL8150 USB Ethernet +device udav # Davicom DM9601E USB + +# USB Wireless +device rum # Ralink Technology RT2501USB wireless NICs + +# Watchdog timer. +# WARNING: can't be disabled!!! +device imxwdt # Watchdog + +# Wireless NIC cards +device wlan # 802.11 support +device wlan_wep # 802.11 WEP support +device wlan_ccmp # 802.11 CCMP support +device wlan_tkip # 802.11 TKIP support +device wlan_amrr # AMRR transmit rate control algorithm + +# Flattened Device Tree +options FDT +options FDT_DTB_STATIC +makeoptions FDT_DTS_FILE=efikamx.dts + +# NOTE: serial console will be disabled if syscons enabled +# Uncomment following lines for framebuffer/syscons support +device sc +device kbdmux +options SC_DFLT_FONT # compile font in +makeoptions SC_DFLT_FONT=cp437 +device ukbd # Allow keyboard like HIDs to control console + +device ums Added: head/sys/arm/freescale/imx/bus_space.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/freescale/imx/bus_space.c Wed Mar 20 15:39:27 2013 (r248557) @@ -0,0 +1,130 @@ +/*- + * Copyright (C) 2012 FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Oleksandr Tymoshenko under sponsorship + * from the FreeBSD Foundation. + * Portions of this software were developed by Oleksandr Rybalko + * under sponsorship from the FreeBSD Foundation. + * + * 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. + * 3. Neither the name of MARVELL nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY 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 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> +#include <sys/kernel.h> +#include <sys/malloc.h> + +#include <machine/bus.h> + +/* Prototypes for all the bus_space structure functions */ +bs_protos(generic); +bs_protos(generic_armv4); + +struct bus_space _base_tag = { + /* cookie */ + .bs_cookie = (void *) 0, + + /* mapping/unmapping */ + .bs_map = generic_bs_map, + .bs_unmap = generic_bs_unmap, + .bs_subregion = generic_bs_subregion, + + /* allocation/deallocation */ + .bs_alloc = generic_bs_alloc, + .bs_free = generic_bs_free, + + /* barrier */ + .bs_barrier = generic_bs_barrier, + + /* read (single) */ + .bs_r_1 = generic_bs_r_1, + .bs_r_2 = generic_armv4_bs_r_2, + .bs_r_4 = generic_bs_r_4, + .bs_r_8 = NULL, + + /* read multiple */ + .bs_rm_1 = generic_bs_rm_1, + .bs_rm_2 = generic_armv4_bs_rm_2, + .bs_rm_4 = generic_bs_rm_4, + .bs_rm_8 = NULL, + + /* read region */ + .bs_rr_1 = generic_bs_rr_1, + .bs_rr_2 = generic_armv4_bs_rr_2, + .bs_rr_4 = generic_bs_rr_4, + .bs_rr_8 = NULL, + + /* write (single) */ + .bs_w_1 = generic_bs_w_1, + .bs_w_2 = generic_armv4_bs_w_2, + .bs_w_4 = generic_bs_w_4, + .bs_w_8 = NULL, + + /* write multiple */ + .bs_wm_1 = generic_bs_wm_1, + .bs_wm_2 = generic_armv4_bs_wm_2, + .bs_wm_4 = generic_bs_wm_4, + .bs_wm_8 = NULL, + + /* write region */ + .bs_wr_1 = generic_bs_wr_1, + .bs_wr_2 = generic_armv4_bs_wr_2, + .bs_wr_4 = generic_bs_wr_4, + .bs_wr_8 = NULL, + + /* read multiple stream */ + .bs_rm_1_s = generic_bs_rm_1, + .bs_rm_2_s = generic_armv4_bs_rm_2, + .bs_rm_4_s = generic_bs_rm_4, + .bs_rm_8_s = NULL, + + /* write multiple stream */ + .bs_wm_1_s = generic_bs_wm_1, + .bs_wm_2_s = generic_armv4_bs_wm_2, + .bs_wm_4_s = generic_bs_wm_4, + .bs_wm_8_s = NULL, + + /* set multiple */ + /* XXX not implemented */ + + /* set region */ + .bs_sr_1 = NULL, + .bs_sr_2 = generic_armv4_bs_sr_2, + .bs_sr_4 = generic_bs_sr_4, + .bs_sr_8 = NULL, + + /* copy */ + .bs_c_1 = NULL, + .bs_c_2 = generic_armv4_bs_c_2, + .bs_c_4 = NULL, + .bs_c_8 = NULL, +}; + +bus_space_tag_t fdtbus_bs_tag = &_base_tag; Added: head/sys/arm/freescale/imx/common.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/freescale/imx/common.c Wed Mar 20 15:39:27 2013 (r248557) @@ -0,0 +1,75 @@ +/*- + * Copyright (C) 2008-2011 MARVELL INTERNATIONAL LTD. + * Copyright (c) 2012 The FreeBSD Foundation + * All rights reserved. + * + * Developed by Semihalf. + * + * Portions of this software were developed by Oleksandr Rybalko + * under sponsorship from the FreeBSD Foundation. + * + * 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. + * 3. Neither the name of MARVELL nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY 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 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. + */ + +#include "opt_global.h" + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/kdb.h> +#include <sys/reboot.h> + +#include <dev/fdt/fdt_common.h> +#include <dev/ofw/openfirm.h> + +#include <machine/bus.h> +#include <machine/fdt.h> +#include <machine/vmparam.h> + +struct fdt_fixup_entry fdt_fixup_table[] = { + { NULL, NULL } +}; + +static int +fdt_intc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig, + int *pol) +{ + + *interrupt = fdt32_to_cpu(intr[0]); + *trig = INTR_TRIGGER_CONFORM; + *pol = INTR_POLARITY_CONFORM; + + return (0); +} + +fdt_pic_decode_t fdt_pic_table[] = { + &fdt_intc_decode_ic, + NULL +}; Added: head/sys/arm/freescale/imx/console.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/freescale/imx/console.c Wed Mar 20 15:39:27 2013 (r248557) @@ -0,0 +1,164 @@ +/*- + * Copyright (c) 2012 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Oleksandr Rybalko under sponsorship + * from the FreeBSD Foundation. + * + * 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. + */ + +/* Simple UART console driver for Freescale i.MX515 */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/cons.h> +#include <sys/consio.h> +#include <sys/kernel.h> + +/* Allow it to be predefined, to be able to use another UART for console */ +#ifndef IMX_UART_BASE +#define IMX_UART_BASE 0xe3fbc000 /* UART1 */ +#endif + +#define IMX_RXD (u_int32_t *)(IMX_UART_BASE + 0x00) +#define IMX_TXD (u_int32_t *)(IMX_UART_BASE + 0x40) + +#define IMX_UFCR (u_int32_t *)(IMX_UART_BASE + 0x90) +#define IMX_USR1 (u_int32_t *)(IMX_UART_BASE + 0x94) +#define IMX_USR1_TRDY (1 << 13) + +#define IMX_USR2 (u_int32_t *)(IMX_UART_BASE + 0x98) +#define IMX_USR2_RDR (1 << 0) +#define IMX_USR2_TXFE (1 << 14) +#define IMX_USR2_TXDC (1 << 3) + +#define IMX_UTS (u_int32_t *)(IMX_UART_BASE + 0xb4) +#define IMX_UTS_TXFULL (1 << 4) + +/* + * uart related funcs + */ +static u_int32_t +uart_getreg(u_int32_t *bas) +{ + + return *((volatile u_int32_t *)(bas)) & 0xff; +} + +static void +uart_setreg(u_int32_t *bas, u_int32_t val) +{ + + *((volatile u_int32_t *)(bas)) = (u_int32_t)val; +} + +static int +ub_tstc(void) +{ + + return ((uart_getreg(IMX_USR2) & IMX_USR2_RDR) ? 1 : 0); +} + +static int +ub_getc(void) +{ + + while (!ub_tstc()); + __asm __volatile("nop"); + + return (uart_getreg(IMX_RXD) & 0xff); +} + +static void +ub_putc(unsigned char c) +{ + + if (c == '\n') + ub_putc('\r'); + + while (uart_getreg(IMX_UTS) & IMX_UTS_TXFULL) + __asm __volatile("nop"); + + uart_setreg(IMX_TXD, c); +} + +static cn_probe_t uart_cnprobe; +static cn_init_t uart_cninit; +static cn_term_t uart_cnterm; +static cn_getc_t uart_cngetc; +static cn_putc_t uart_cnputc; +static cn_grab_t uart_cngrab; +static cn_ungrab_t uart_cnungrab; + +static void +uart_cngrab(struct consdev *cp) +{ + +} + +static void +uart_cnungrab(struct consdev *cp) +{ + +} + + +static void +uart_cnprobe(struct consdev *cp) +{ + + sprintf(cp->cn_name, "uart"); + cp->cn_pri = CN_NORMAL; +} + +static void +uart_cninit(struct consdev *cp) +{ + uart_setreg(IMX_UFCR, 0x00004210); +} + +void +uart_cnputc(struct consdev *cp, int c) +{ + + ub_putc(c); +} + +int +uart_cngetc(struct consdev * cp) +{ + + return ub_getc(); +} + +static void +uart_cnterm(struct consdev * cp) +{ + +} + +CONSOLE_DRIVER(uart); Added: head/sys/arm/freescale/imx/i2c.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/freescale/imx/i2c.c Wed Mar 20 15:39:27 2013 (r248557) @@ -0,0 +1,492 @@ +/*- + * Copyright (C) 2008-2009 Semihalf, Michal Hajduk + * Copyright (c) 2012 The FreeBSD Foundation + * All rights reserved. + * + * Portions of this software were developed by Oleksandr Rybalko + * under sponsorship from the FreeBSD Foundation. + * + * 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 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 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> +#include <sys/kernel.h> +#include <sys/module.h> +#include <sys/resource.h> + +#include <machine/bus.h> +#include <machine/resource.h> +#include <sys/rman.h> + +#include <sys/lock.h> +#include <sys/mutex.h> + +#include <dev/iicbus/iiconf.h> +#include <dev/iicbus/iicbus.h> +#include "iicbus_if.h" + +#include <dev/fdt/fdt_common.h> +#include <dev/ofw/openfirm.h> +#include <dev/ofw/ofw_bus.h> +#include <dev/ofw/ofw_bus_subr.h> + +#define I2C_ADDR_REG 0x00 /* I2C slave address register */ +#define I2C_FDR_REG 0x04 /* I2C frequency divider register */ +#define I2C_CONTROL_REG 0x08 /* I2C control register */ +#define I2C_STATUS_REG 0x0C /* I2C status register */ +#define I2C_DATA_REG 0x10 /* I2C data register */ +#define I2C_DFSRR_REG 0x14 /* I2C Digital Filter Sampling rate */ + +#define I2CCR_MEN (1 << 7) /* Module enable */ +#define I2CCR_MSTA (1 << 5) /* Master/slave mode */ +#define I2CCR_MTX (1 << 4) /* Transmit/receive mode */ +#define I2CCR_TXAK (1 << 3) /* Transfer acknowledge */ +#define I2CCR_RSTA (1 << 2) /* Repeated START */ + +#define I2CSR_MCF (1 << 7) /* Data transfer */ +#define I2CSR_MASS (1 << 6) /* Addressed as a slave */ +#define I2CSR_MBB (1 << 5) /* Bus busy */ +#define I2CSR_MAL (1 << 4) /* Arbitration lost */ +#define I2CSR_SRW (1 << 2) /* Slave read/write */ +#define I2CSR_MIF (1 << 1) /* Module interrupt */ +#define I2CSR_RXAK (1 << 0) /* Received acknowledge */ + +#define I2C_BAUD_RATE_FAST 0x31 +#define I2C_BAUD_RATE_DEF 0x3F +#define I2C_DFSSR_DIV 0x10 + +#ifdef DEBUG +#define debugf(fmt, args...) do { printf("%s(): ", __func__); \ + printf(fmt,##args); } while (0) +#else +#define debugf(fmt, args...) +#endif + +struct i2c_softc { + device_t dev; + device_t iicbus; + struct resource *res; + struct mtx mutex; + int rid; + bus_space_handle_t bsh; + bus_space_tag_t bst; +}; + +static phandle_t i2c_get_node(device_t, device_t); +static int i2c_probe(device_t); +static int i2c_attach(device_t); + +static int i2c_repeated_start(device_t, u_char, int); +static int i2c_start(device_t, u_char, int); +static int i2c_stop(device_t); +static int i2c_reset(device_t, u_char, u_char, u_char *); +static int i2c_read(device_t, char *, int, int *, int, int); +static int i2c_write(device_t, const char *, int, int *, int); + +static device_method_t i2c_methods[] = { + DEVMETHOD(device_probe, i2c_probe), + DEVMETHOD(device_attach, i2c_attach), + + /* OFW methods */ + DEVMETHOD(ofw_bus_get_node, i2c_get_node), + + DEVMETHOD(iicbus_callback, iicbus_null_callback), + DEVMETHOD(iicbus_repeated_start, i2c_repeated_start), + DEVMETHOD(iicbus_start, i2c_start), + DEVMETHOD(iicbus_stop, i2c_stop), + DEVMETHOD(iicbus_reset, i2c_reset), + DEVMETHOD(iicbus_read, i2c_read), + DEVMETHOD(iicbus_write, i2c_write), + DEVMETHOD(iicbus_transfer, iicbus_transfer_gen), + + { 0, 0 } +}; + +static driver_t i2c_driver = { + "iichb", + i2c_methods, + sizeof(struct i2c_softc), +}; +static devclass_t i2c_devclass; + +DRIVER_MODULE(i2c, simplebus, i2c_driver, i2c_devclass, 0, 0); +DRIVER_MODULE(iicbus, i2c, iicbus_driver, iicbus_devclass, 0, 0); + +static phandle_t +i2c_get_node(device_t bus, device_t dev) +{ + /* + * Share controller node with iicbus device + */ + return ofw_bus_get_node(bus); +} + +static __inline void +i2c_write_reg(struct i2c_softc *sc, bus_size_t off, uint8_t val) +{ + + bus_space_write_1(sc->bst, sc->bsh, off, val); +} + +static __inline uint8_t +i2c_read_reg(struct i2c_softc *sc, bus_size_t off) +{ + + return (bus_space_read_1(sc->bst, sc->bsh, off)); +} + +static __inline void +i2c_flag_set(struct i2c_softc *sc, bus_size_t off, uint8_t mask) +{ + uint8_t status; + + status = i2c_read_reg(sc, off); + status |= mask; + i2c_write_reg(sc, off, status); +} + +/* Wait for transfer interrupt flag */ +static int +wait_for_iif(struct i2c_softc *sc) +{ + int retry; + + retry = 1000; + while (retry --) { + if (i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MIF) + return (IIC_NOERR); + DELAY(10); + } + + return (IIC_ETIMEOUT); +} + +/* Wait for free bus */ +static int +wait_for_nibb(struct i2c_softc *sc) +{ + int retry; + + retry = 1000; + while (retry --) { + if ((i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MBB) == 0) + return (IIC_NOERR); + DELAY(10); + } + + return (IIC_ETIMEOUT); +} + +/* Wait for transfer complete+interrupt flag */ +static int +wait_for_icf(struct i2c_softc *sc) +{ + int retry; + + retry = 1000; + while (retry --) { + + if ((i2c_read_reg(sc, I2C_STATUS_REG) & + (I2CSR_MCF|I2CSR_MIF)) == (I2CSR_MCF|I2CSR_MIF)) + return (IIC_NOERR); + DELAY(10); + } + + return (IIC_ETIMEOUT); +} + +static int +i2c_probe(device_t dev) +{ + struct i2c_softc *sc; + + if (!ofw_bus_is_compatible(dev, "fsl,imx-i2c")) + return (ENXIO); + + sc = device_get_softc(dev); + sc->rid = 0; + + sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid, + RF_ACTIVE); + if (sc->res == NULL) { + device_printf(dev, "could not allocate resources\n"); + return (ENXIO); + } + + sc->bst = rman_get_bustag(sc->res); + sc->bsh = rman_get_bushandle(sc->res); + + /* Enable I2C */ + i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN); + bus_release_resource(dev, SYS_RES_MEMORY, sc->rid, sc->res); + device_set_desc(dev, "I2C bus controller"); + + return (BUS_PROBE_DEFAULT); +} + +static int +i2c_attach(device_t dev) +{ + struct i2c_softc *sc; + + sc = device_get_softc(dev); + sc->dev = dev; + sc->rid = 0; + + mtx_init(&sc->mutex, device_get_nameunit(dev), "I2C", MTX_DEF); + + sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid, + RF_ACTIVE); + if (sc->res == NULL) { + device_printf(dev, "could not allocate resources"); + mtx_destroy(&sc->mutex); + return (ENXIO); + } + + sc->bst = rman_get_bustag(sc->res); + sc->bsh = rman_get_bushandle(sc->res); + + sc->iicbus = device_add_child(dev, "iicbus", -1); + if (sc->iicbus == NULL) { + device_printf(dev, "could not add iicbus child"); + mtx_destroy(&sc->mutex); + return (ENXIO); + } + + bus_generic_attach(dev); + return (IIC_NOERR); +} + +static int +i2c_repeated_start(device_t dev, u_char slave, int timeout) +{ + struct i2c_softc *sc; + int error; + + sc = device_get_softc(dev); + + mtx_lock(&sc->mutex); + + i2c_write_reg(sc, I2C_ADDR_REG, slave); + if ((i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MBB) == 0) { + mtx_unlock(&sc->mutex); + return (IIC_EBUSBSY); + } + + /* Set repeated start condition */ + DELAY(10); + i2c_flag_set(sc, I2C_CONTROL_REG, I2CCR_RSTA); + DELAY(10); + /* Clear status */ + i2c_write_reg(sc, I2C_STATUS_REG, 0x0); + /* Write target address - LSB is R/W bit */ + i2c_write_reg(sc, I2C_DATA_REG, slave); + + error = wait_for_iif(sc); + + /* Clear status */ + i2c_write_reg(sc, I2C_STATUS_REG, 0x0); + + mtx_unlock(&sc->mutex); + + if (error) + return (error); + + return (IIC_NOERR); +} + +static int +i2c_start(device_t dev, u_char slave, int timeout) +{ + struct i2c_softc *sc; + int error; + + sc = device_get_softc(dev); + + mtx_lock(&sc->mutex); + i2c_write_reg(sc, I2C_ADDR_REG, slave); + if (i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MBB) { + mtx_unlock(&sc->mutex); + return (IIC_EBUSBSY); + } + + /* Set start condition */ + i2c_write_reg(sc, I2C_CONTROL_REG, + I2CCR_MEN | I2CCR_MSTA | I2CCR_TXAK); + DELAY(100); + i2c_write_reg(sc, I2C_CONTROL_REG, + I2CCR_MEN | I2CCR_MSTA | I2CCR_MTX | I2CCR_TXAK); + /* Clear status */ + i2c_write_reg(sc, I2C_STATUS_REG, 0x0); + /* Write target address - LSB is R/W bit */ + i2c_write_reg(sc, I2C_DATA_REG, slave); + + error = wait_for_iif(sc); + + mtx_unlock(&sc->mutex); + if (error) + return (error); + + return (IIC_NOERR); +} + + +static int +i2c_stop(device_t dev) +{ + struct i2c_softc *sc; + + sc = device_get_softc(dev); + mtx_lock(&sc->mutex); + i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_TXAK); + DELAY(100); + /* Reset controller if bus still busy after STOP */ + if (wait_for_nibb(sc) == IIC_ETIMEOUT) { + i2c_write_reg(sc, I2C_CONTROL_REG, 0); + DELAY(1000); + i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_TXAK); + + i2c_write_reg(sc, I2C_STATUS_REG, 0x0); + } + mtx_unlock(&sc->mutex); + + return (IIC_NOERR); +} + +static int +i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr) +{ + struct i2c_softc *sc; + uint8_t baud_rate; + + sc = device_get_softc(dev); + + switch (speed) { + case IIC_FAST: + baud_rate = I2C_BAUD_RATE_FAST; + break; + case IIC_SLOW: + case IIC_UNKNOWN: + case IIC_FASTEST: + default: + baud_rate = I2C_BAUD_RATE_DEF; + break; + } + + mtx_lock(&sc->mutex); + i2c_write_reg(sc, I2C_CONTROL_REG, 0x0); + i2c_write_reg(sc, I2C_STATUS_REG, 0x0); + DELAY(1000); + + i2c_write_reg(sc, I2C_FDR_REG, 20); + i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN); + DELAY(1000); + i2c_write_reg(sc, I2C_STATUS_REG, 0x0); + mtx_unlock(&sc->mutex); + + return (IIC_NOERR); +} + +static int +i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay) +{ + struct i2c_softc *sc; + int error, reg; + + sc = device_get_softc(dev); + *read = 0; + + mtx_lock(&sc->mutex); + + if (len) { + if (len == 1) + i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | + I2CCR_MSTA | I2CCR_TXAK); + + else + i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | + I2CCR_MSTA); + + /* dummy read */ + i2c_read_reg(sc, I2C_DATA_REG); + DELAY(1000); + } + + while (*read < len) { *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"