From owner-svn-soc-all@FreeBSD.ORG Tue May 29 21:47:59 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id 44460106564A for ; Tue, 29 May 2012 21:47:57 +0000 (UTC) (envelope-from aleek@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Tue, 29 May 2012 21:47:57 +0000 Date: Tue, 29 May 2012 21:47:57 +0000 From: aleek@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120529214757.44460106564A@hub.freebsd.org> Cc: Subject: socsvn commit: r236688 - in soc2012/aleek/beaglexm-armv6: . sys/arm/ti/omap3 X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 May 2012 21:47:59 -0000 Author: aleek Date: Tue May 29 21:47:56 2012 New Revision: 236688 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=236688 Log: merging omap3 branch to armv6 part 1 Added: soc2012/aleek/beaglexm-armv6/sys/arm/ti/omap3/files.omap35xx soc2012/aleek/beaglexm-armv6/sys/arm/ti/omap3/omap35xx.c soc2012/aleek/beaglexm-armv6/sys/arm/ti/omap3/omap3_intr.c soc2012/aleek/beaglexm-armv6/sys/arm/ti/omap3/omap3_prcm_clks.c soc2012/aleek/beaglexm-armv6/sys/arm/ti/omap3/omap3_scm_padconf.c soc2012/aleek/beaglexm-armv6/sys/arm/ti/omap3/omap3_timer.c soc2012/aleek/beaglexm-armv6/sys/arm/ti/omap3/omap3var.h soc2012/aleek/beaglexm-armv6/sys/arm/ti/omap3/std.omap35xx soc2012/aleek/beaglexm-armv6/sys/arm/ti/omap3/uart_bus_omap3.c soc2012/aleek/beaglexm-armv6/sys/arm/ti/omap3/uart_cpu_omap3.c Modified: soc2012/aleek/beaglexm-armv6/ (props changed) Added: soc2012/aleek/beaglexm-armv6/sys/arm/ti/omap3/files.omap35xx ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/aleek/beaglexm-armv6/sys/arm/ti/omap3/files.omap35xx Tue May 29 21:47:56 2012 (r236688) @@ -0,0 +1,27 @@ +#$FreeBSD$ + +arm/ti/omap.c standard +arm/ti/omap_cpuid.c standard +arm/ti/omap_dma.c standard +arm/ti/omap_prcm.c standard +arm/ti/omap_scm.c standard +arm/ti/omap_gpio.c optional gpio +arm/ti/omap_gptimer.c standard +arm/ti/omap_mmc.c optional mmc +arm/ti/omap_space_asm.S standard +arm/ti/omap_i2c.c optional iic + +arm/ti/omap3/omap35xx.c standard +arm/ti/omap3/omap3_intr.c standard +arm/ti/omap3/omap3_prcm_clks.c standard +arm/ti/omap3/omap3_scm_padconf.c standard +arm/ti/omap3/omap3_timer.c standard + +arm/ti/omap3/uart_cpu_omap3.c optional uart +#arm/ti/omap3/uart_bus_omap3.c optional uart + +dev/uart/uart_dev_ns8250.c optional uart + +# USB Host controller +arm/ti/omap_ehci.c optional ehci usb + Added: soc2012/aleek/beaglexm-armv6/sys/arm/ti/omap3/omap35xx.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/aleek/beaglexm-armv6/sys/arm/ti/omap3/omap35xx.c Tue May 29 21:47:56 2012 (r236688) @@ -0,0 +1,491 @@ +/*- + * Copyright (c) 2011 + * Ben Gray . + * 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 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#define _ARM32_BUS_DMA_PRIVATE +#include + +#include +#include +#include + +struct omap3_softc *g_omap3_softc = NULL; + + +/* + * Standard priority levels for the system - 0 has the highest priority and 63 + * is the lowest. + * + * Currently these are all set to the same standard value. + */ +static const int omap35xx_irq_prio[96] = +{ + 0, /* MPU emulation(2) */ + 0, /* MPU emulation(2) */ + 0, /* MPU emulation(2) */ + 0, /* MPU emulation(2) */ + 0, /* Sidetone MCBSP2 overflow */ + 0, /* Sidetone MCBSP3 overflow */ + 0, /* MPU subsystem secure state-machine abort (2) */ + 0, /* External source (active low) */ + 0, /* RESERVED */ + 0, /* SMX error for debug */ + 0, /* SMX error for application */ + 0, /* PRCM module IRQ */ + 0, /* System DMA request 0(3) */ + 0, /* System DMA request 1(3) */ + 0, /* System DMA request 2 */ + 0, /* System DMA request 3 */ + 0, /* McBSP module 1 IRQ (3) */ + 0, /* McBSP module 2 IRQ (3) */ + 0, /* SmartReflex™ 1 */ + 0, /* SmartReflex™ 2 */ + 0, /* General-purpose memory controller module */ + 0, /* 2D/3D graphics module */ + 0, /* McBSP module 3(3) */ + 0, /* McBSP module 4(3) */ + 0, /* Camera interface request 0 */ + 0, /* Display subsystem module(3) */ + 0, /* Mailbox user 0 request */ + 0, /* McBSP module 5 (3) */ + 0, /* IVA2 MMU */ + 0, /* GPIO module 1(3) */ + 0, /* GPIO module 2(3) */ + 0, /* GPIO module 3(3) */ + 0, /* GPIO module 4(3) */ + 0, /* GPIO module 5(3) */ + 0, /* GPIO module 6(3) */ + 0, /* USIM interrupt (HS devices only) (4) */ + 0, /* Watchdog timer module 3 overflow */ + 0, /* General-purpose timer module 1 */ + 0, /* General-purpose timer module 2 */ + 0, /* General-purpose timer module 3 */ + 0, /* General-purpose timer module 4 */ + 0, /* General-purpose timer module 5(3) */ + 0, /* General-purpose timer module 6(3) */ + 0, /* General-purpose timer module 7(3) */ + 0, /* General-purpose timer module 8(3) */ + 0, /* General-purpose timer module 9 */ + 0, /* General-purpose timer module 10 */ + 0, /* General-purpose timer module 11 */ + 0, /* McSPI module 4 */ + 0, /* SHA-1/MD5 crypto-accelerator 2 (HS devices only)(4) */ + 0, /* PKA crypto-accelerator (HS devices only) (4) */ + 0, /* SHA-2/MD5 crypto-accelerator 1 (HS devices only) (4) */ + 0, /* RNG module (HS devices only) (4) */ + 0, /* MG function (3) */ + 0, /* McBSP module 4 transmit(3) */ + 0, /* McBSP module 4 receive(3) */ + 0, /* I2C module 1 */ + 0, /* I2C module 2 */ + 0, /* HDQ / One-wire */ + 0, /* McBSP module 1 transmit(3) */ + 0, /* McBSP module 1 receive(3) */ + 0, /* I2C module 3 */ + 0, /* McBSP module 2 transmit(3) */ + 0, /* McBSP module 2 receive(3) */ + 0, /* PKA crypto-accelerator (HS devices only) (4) */ + 0, /* McSPI module 1 */ + 0, /* McSPI module 2 */ + 0, /* RESERVED */ + 0, /* RESERVED */ + 0, /* RESERVED */ + 0, /* RESERVED */ + 0, /* RESERVED */ + 0, /* UART module 1 */ + 0, /* UART module 2 */ + 0, /* UART module 3 (also infrared)(3) */ + 0, /* Merged interrupt for PBIASlite1 and 2 */ + 0, /* OHCI controller HSUSB MP Host Interrupt */ + 0, /* EHCI controller HSUSB MP Host Interrupt */ + 0, /* HSUSB MP TLL Interrupt */ + 0, /* SHA2/MD5 crypto-accelerator 1 (HS devices only) (4) */ + 0, /* Reserved */ + 0, /* McBSP module 5 transmit(3) */ + 0, /* McBSP module 5 receive(3) */ + 0, /* MMC/SD module 1 */ + 0, /* MS-PRO™ module */ + 0, /* Reserved */ + 0, /* MMC/SD module 2 */ + 0, /* MPU ICR */ + 0, /* RESERVED */ + 0, /* McBSP module 3 transmit(3) */ + 0, /* McBSP module 3 receive(3) */ + 0, /* McSPI module 3 */ + 0, /* High-Speed USB OTG controller */ + 0, /* High-Speed USB OTG DMA controller */ + 0, /* MMC/SD module 3 */ + 0, /* General-purpose timer module 12 */ +}; + + +static const struct omap_cpu_dev omap35xx_devs[] = +{ + /** + * OMAP35xx - General Purpose Timers + * This module provides interfaces to the general purpose timers. + */ + { .name = "omap_gptimer", + .unit = 0, + .mem = { { OMAP35XX_GPTIMER1_HWBASE, OMAP35XX_GPTIMER_SIZE }, + { OMAP35XX_GPTIMER2_HWBASE, OMAP35XX_GPTIMER_SIZE }, + { OMAP35XX_GPTIMER3_HWBASE, OMAP35XX_GPTIMER_SIZE }, + { OMAP35XX_GPTIMER4_HWBASE, OMAP35XX_GPTIMER_SIZE }, + { OMAP35XX_GPTIMER5_HWBASE, OMAP35XX_GPTIMER_SIZE }, + { OMAP35XX_GPTIMER6_HWBASE, OMAP35XX_GPTIMER_SIZE }, + { OMAP35XX_GPTIMER7_HWBASE, OMAP35XX_GPTIMER_SIZE }, + { OMAP35XX_GPTIMER8_HWBASE, OMAP35XX_GPTIMER_SIZE }, + { OMAP35XX_GPTIMER9_HWBASE, OMAP35XX_GPTIMER_SIZE }, + { OMAP35XX_GPTIMER10_HWBASE, OMAP35XX_GPTIMER_SIZE }, + { OMAP35XX_GPTIMER11_HWBASE, OMAP35XX_GPTIMER_SIZE }, + { 0, 0 } + }, + .irqs = { OMAP35XX_IRQ_GPT1, + OMAP35XX_IRQ_GPT2, + OMAP35XX_IRQ_GPT3, + OMAP35XX_IRQ_GPT4, + OMAP35XX_IRQ_GPT5, + OMAP35XX_IRQ_GPT6, + OMAP35XX_IRQ_GPT7, + OMAP35XX_IRQ_GPT8, + OMAP35XX_IRQ_GPT9, + OMAP35XX_IRQ_GPT10, + OMAP35XX_IRQ_GPT11, + -1, + }, + }, + + /** + * OMAP35xx - DMA + * This module provides interfaces to the direct memory access controller + */ + { .name = "omap_dma", + .unit = 0, + .mem = { { OMAP35XX_SDMA_HWBASE, OMAP35XX_SDMA_SIZE }, + { 0, 0 } + }, + .irqs = { OMAP35XX_IRQ_SDMA0, + OMAP35XX_IRQ_SDMA1, + OMAP35XX_IRQ_SDMA2, + OMAP35XX_IRQ_SDMA3, + -1, + }, + }, + + /** + * OMAP35xx - I2C + * This module provides interfaces to the I2C controller + * Note: generally this should be the first function sub-device because + * it's used for the TWL power control device. + */ + { .name = "omap_i2c", + .unit = 0, + .mem = { { OMAP35XX_I2C1_HWBASE, OMAP35XX_I2C1_SIZE }, + { 0, 0 } + }, + .irqs = { OMAP35XX_IRQ_I2C1, + -1, + }, + }, + + /** + * OMAP35xx - GPIO + * There are 6 GPIO register sets, with each set representing 32 GPIO + * pins. + */ + { .name = "gpio", + .unit = 0, + .mem = { { OMAP35XX_GPIO1_HWBASE, OMAP35XX_GPIO1_SIZE }, + { OMAP35XX_GPIO2_HWBASE, OMAP35XX_GPIO2_SIZE }, + { OMAP35XX_GPIO3_HWBASE, OMAP35XX_GPIO3_SIZE }, + { OMAP35XX_GPIO4_HWBASE, OMAP35XX_GPIO4_SIZE }, + { OMAP35XX_GPIO5_HWBASE, OMAP35XX_GPIO5_SIZE }, + { OMAP35XX_GPIO6_HWBASE, OMAP35XX_GPIO6_SIZE }, + { 0, 0 } + }, + .irqs = { OMAP35XX_IRQ_GPIO1_MPU, + OMAP35XX_IRQ_GPIO2_MPU, + OMAP35XX_IRQ_GPIO3_MPU, + OMAP35XX_IRQ_GPIO4_MPU, + OMAP35XX_IRQ_GPIO5_MPU, + OMAP35XX_IRQ_GPIO6_MPU, + -1, + }, + }, + + /** + * OMAP35xx - MMC/SDIO + * There are a total of 3 MMC modules on OMAP3 + */ + { .name = "omap_mmc", + .unit = 0, + .mem = { { OMAP35XX_MMCHS1_HWBASE, OMAP35XX_MMCHS_SIZE }, + { 0, 0 } + }, + .irqs = { OMAP35XX_IRQ_MMC1, + -1, + }, + }, + + /** + * OMAP35xx - USB EHCI + * The OMAP EHCI driver expects three different register sets, one for + * the actual EHCI registers and the other two control the interface. + */ + { .name = "ehci", + .unit = 0, + .mem = { { OMAP35XX_USB_EHCI_HWBASE, OMAP35XX_USB_EHCI_SIZE }, + { OMAP35XX_USB_UHH_HWBASE, OMAP35XX_USB_UHH_SIZE }, + { OMAP35XX_USB_TLL_HWBASE, OMAP35XX_USB_TLL_SIZE }, + { 0, 0 } + }, + .irqs = { OMAP35XX_IRQ_EHCI, + -1, + }, + }, + + { 0, 0, { { 0, 0 } }, { -1 } } +}; + + + +/** + * omap_sdram_size - called from machdep to get the total memory size + * + * Since this function is called very early in the boot, there is none of the + * bus handling code setup. However the boot device map will be setup, so + * we can directly access registers already mapped. + * + * This is a bit ugly, but since we need this information early on and the + * only way to get it (appart from hardcoding it or via kernel args) is to read + * from the EMIF_SRAM registers. + * + * RETURNS: + * The size of memory in bytes. + */ +unsigned int +omap_sdram_size(void) +{ + uint32_t size; + uint32_t sdrc_mcfg_0, sdrc_mcfg_1; + + sdrc_mcfg_0 = *((volatile uint32_t *)(OMAP35XX_SDRC_MCFG(0))); + sdrc_mcfg_1 = *((volatile uint32_t *)(OMAP35XX_SDRC_MCFG(1))); + + /* The size is given in bits 17:8 in 2MB chunk sizes */ + size = ((sdrc_mcfg_0 >> 8) & 0x3FF) * (2 * 1024 * 1024); + size += ((sdrc_mcfg_1 >> 8) & 0x3FF) * (2 * 1024 * 1024); + +printf("[BRG] omap_sdram_size : size = %u\n", size); + + return (size); +} + + + + +/** + * omap35xx_add_child - add a child item to the root omap device + * @dev: the parent device + * @order: defines roughly the order with which to add the child to the parent + * @name: the name to give to the child item + * @unit: the unit number for the device + * @addr: the base address of the register set for device + * @size: the number of a bytes in register set + * @irq: the IRQ number(s) for the device + * + * Adds a child to the omap base device. + * + */ +static void +omap35xx_add_child(device_t dev, int prio, const char *name, int unit, + const struct omap_mem_range mem[], const int irqs[]) +{ + device_t kid; + struct omap_ivar *ivar; + unsigned int i; + + /* Start by adding the actual child to the parent (us) */ + kid = device_add_child_ordered(dev, prio, name, unit); + if (kid == NULL) { + printf("Can't add child %s%d ordered\n", name, unit); + return; + } + + /* Allocate some memory for the omap_ivar structure */ + ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO); + if (ivar == NULL) { + device_delete_child(dev, kid); + printf("Can't add alloc ivar\n"); + return; + } + + /* Assign the ivars to the child item and populate with the device resources */ + device_set_ivars(kid, ivar); + + /* Assign the IRQ(s) in the resource list */ + resource_list_init(&ivar->resources); + if (irqs) { + for (i = 0; *irqs != -1; i++, irqs++) { + bus_set_resource(kid, SYS_RES_IRQ, i, *irqs, 1); + } + } + + /* Assign the memory region to the resource list */ + if (mem) { + for (i = 0; mem->base != 0; i++, mem++) { + bus_set_resource(kid, SYS_RES_MEMORY, i, mem->base, mem->size); + } + } +} + + +/** + * omap35xx_cpu_add_builtin_children - adds the SoC child components + * @dev: this device, the one we are adding to + * + * Adds child devices from the omap35xx_devs list. + * + */ +static void +omap35xx_cpu_add_builtin_children(device_t dev) +{ + int i; + const struct omap_cpu_dev *walker; + + /* Setup all the clock devices - this is not the tick timers, rather it's + * the individual functional and interface clocks for the SoC modules. + */ + omap3_clk_init(dev, 1); + + /* Setup the system control module driver, which basically is just the + * padconf (pinmux) for the OMAP35xx devices. + */ + omap3_padconf_init(dev, 1); + + /* Add the rest of the children from the array above */ + for (i = 5, walker = omap35xx_devs; walker->name; i++, walker++) { + omap35xx_add_child(dev, i, walker->name, walker->unit, + walker->mem, walker->irqs); + } +} + + +/** + * omap35xx_identify - adds the SoC child components + * @dev: this device, the one we are adding to + * + * Adds a child to the omap3 base device. + * + */ +static void +omap35xx_identify(driver_t *drv, device_t parent) +{ + /* Add the resources for this "omap35xx" device */ + omap35xx_add_child(parent, 0, "omap35xx", 0, NULL, NULL); + + /* Add the other SOC components */ + omap35xx_cpu_add_builtin_children(parent); +} + +/** + * omap35xx_probe - called when the device is probed + * @dev: the new device + * + * All we do in this routine is set the description of this device + * + */ +static int +omap35xx_probe(device_t dev) +{ + device_set_desc(dev, "TI OMAP35XX"); + return (0); +} + +/** + * omap35xx_attach - called when the device is attached + * @dev: the new device + * + * All we do in this routine is set the description of this device + * + */ +static int +omap35xx_attach(device_t dev) +{ + struct omap_softc *omapsc = device_get_softc(device_get_parent(dev)); + struct omap3_softc *sc = device_get_softc(dev); + + sc->sc_iotag = omapsc->sc_iotag; + sc->sc_dev = dev; + + + /* Map in the interrupt controller register set */ + if (bus_space_map(sc->sc_iotag, OMAP35XX_INTCPS_HWBASE, + OMAP35XX_INTCPS_SIZE, 0, &sc->sc_intcps_ioh)) { + panic("%s: Cannot map registers", device_get_name(dev)); + } + + + /* Save the device structure globally for the IRQ handling */ + g_omap3_softc = sc; + + /* TODO: Revisit - Install an interrupt post filter */ + arm_post_filter = omap3_post_filter_intr; + + /* Setup the OMAP3 interrupt controller */ + omap3_setup_intr_controller(g_omap3_softc, omap35xx_irq_prio); + + return (0); +} + + + +static device_method_t omap35xx_methods[] = { + DEVMETHOD(device_probe, omap35xx_probe), + DEVMETHOD(device_attach, omap35xx_attach), + DEVMETHOD(device_identify, omap35xx_identify), + {0, 0}, +}; + +static driver_t omap35xx_driver = { + "omap35xx", + omap35xx_methods, + sizeof(struct omap3_softc), +}; + +static devclass_t omap35xx_devclass; + +DRIVER_MODULE(omap35xx, omap, omap35xx_driver, omap35xx_devclass, 0, 0); Added: soc2012/aleek/beaglexm-armv6/sys/arm/ti/omap3/omap3_intr.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/aleek/beaglexm-armv6/sys/arm/ti/omap3/omap3_intr.c Tue May 29 21:47:56 2012 (r236688) @@ -0,0 +1,233 @@ +/*- + * Copyright (c) 2011 + * Ben Gray . + * 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 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + +#include +#include + + + +/* + * There are a number of ways that interrupt handling is implemented in + * the various ARM platforms, the PXA has the neatest way, it creates another + * device driver that handles everything. However IMO this is rather heavy- + * weight for playing with IRQs which should be quite fast ... so I've + * gone for something similar to the IXP425, which just directly plays with + * registers. This assumes that the interrupt control registers are already + * mapped in virtual memory at a fixed virtual address ... simplies. + * + * The intcps (OMAP3 interrupt controller) has some nice registers, were + * you write a bit to clear or set the mask register ... I think in theory + * that means that you don't need to disable interrupts while doing this, + * because it is an atomic operation. + * + * TODO: check this. + * + */ + + + +#define INTCPS_SYSCONFIG 0x10 +#define INTCPS_SYSSTATUS 0x14 +#define INTCPS_SIR_IRQ 0x40 +#define INTCPS_SIR_FIQ 0x44 +#define INTCPS_CONTROL 0x48 +#define INTCPS_PROTECTION 0x4C +#define INTCPS_IDLE 0x50 +#define INTCPS_IRQ_PRIORITY 0x60 +#define INTCPS_FIQ_PRIORITY 0x64 +#define INTCPS_THRESHOLD 0x68 +#define INTCPS_ITR(n) (0x80 + (0x20 * (n))) +#define INTCPS_MIR(n) (0x84 + (0x20 * (n))) +#define INTCPS_MIR_CLEAR(n) (0x88 + (0x20 * (n))) +#define INTCPS_MIR_SET(n) (0x8C + (0x20 * (n))) +#define INTCPS_ISR_SET(n) (0x90 + (0x20 * (n))) +#define INTCPS_ISR_CLEAR(n) (0x94 + (0x20 * (n))) +#define INTCPS_PENDING_IRQ(n) (0x98 + (0x20 * (n))) +#define INTCPS_PENDING_FIQ(n) (0x9C + (0x20 * (n))) +#define INTCPS_ILR(m) (0x100 + (0x4 * (m))) + + + + +/** + * omap3_post_filter_intr - called after the IRQ has been filtered + * @arg: the IRQ number + * + * Called after the interrupt handler has done it's stuff, can be used to + * clean up interrupts that haven't been handled properly. + * + * + * RETURNS: + * nothing + */ +void +omap3_post_filter_intr(void *arg) +{ + /* uintptr_t irq = (uintptr_t) arg; */ + + /* data synchronization barrier */ + cpu_drain_writebuf(); +} + + + + + +/** + * arm_mask_irq - masks an IRQ (disables it) + * @nb: the number of the IRQ to mask (disable) + * + * Disables the interrupt at the HW level. + * + * + * RETURNS: + * nothing + */ +void +arm_mask_irq(uintptr_t nb) +{ + bus_space_write_4(g_omap3_softc->sc_iotag, g_omap3_softc->sc_intcps_ioh, + INTCPS_MIR_SET(nb >> 5), 1UL << (nb & 0x1F)); +} + + +/** + * arm_unmask_irq - unmasks an IRQ (enables it) + * @nb: the number of the IRQ to unmask (enable) + * + * Enables the interrupt at the HW level. + * + * + * RETURNS: + * nothing + */ +void +arm_unmask_irq(uintptr_t nb) +{ + // printf("[BRG] unmasking IRQ %d (off %d, bit %d)\n", nb, (nb >> 5), (nb & 0x1F)); + + bus_space_write_4(g_omap3_softc->sc_iotag, g_omap3_softc->sc_intcps_ioh, + INTCPS_MIR_CLEAR(nb >> 5), 1UL << (nb & 0x1F)); +} + + + +/** + * arm_get_next_irq - gets the next tripped interrupt + * @last_irq: the number of the last IRQ processed + * + * Enables the interrupt at the HW level. + * + * + * RETURNS: + * nothing + */ +int +arm_get_next_irq(int last_irq) +{ + uint32_t active_irq; + + /* clean-up the last IRQ */ + if (last_irq != -1) { + + /* clear the interrupt status flag */ + bus_space_write_4(g_omap3_softc->sc_iotag, g_omap3_softc->sc_intcps_ioh, + INTCPS_ISR_CLEAR(last_irq >> 5), + 1UL << (last_irq & 0x1F)); + + /* tell the interrupt logic we've dealt with the interrupt */ + bus_space_write_4(g_omap3_softc->sc_iotag, g_omap3_softc->sc_intcps_ioh, + INTCPS_CONTROL, 1); + } + + /* Get the next active interrupt */ + active_irq = bus_space_read_4(g_omap3_softc->sc_iotag, + g_omap3_softc->sc_intcps_ioh, INTCPS_SIR_IRQ); + + /* Check for spurious interrupt */ + if ((active_irq & 0xffffff80) == 0xffffff80) { + device_printf(g_omap3_softc->sc_dev, "Spurious interrupt detected " + "(0x%08x)\n", active_irq); + return -1; + } + + /* Just get the active IRQ part */ + active_irq &= 0x7F; + + /* Return the new IRQ if it is different from the previous */ + if (active_irq != last_irq) + return active_irq; + else + return -1; +} + + +/** + * omap3_setup_intr_controller - configures and enables the OMAP3 interrupt + * controller (INTCPS) + * + * + * + * RETURNS: + * nothing + */ +int +omap3_setup_intr_controller(struct omap3_softc *sc, const const int *irqs) +{ + uint32_t syscfg; + uint32_t i; + + if (sc != g_omap3_softc) + panic("Invalid omap3 soft context\n"); + + + /* Reset the interrupt controller */ + bus_space_write_4(g_omap3_softc->sc_iotag, g_omap3_softc->sc_intcps_ioh, + INTCPS_SYSCONFIG, 0x2); + + /* Loop a number of times to check if the INTCPS has come out of reset */ + for (i = 0; i < 10000; i++) { + syscfg = bus_space_read_4(g_omap3_softc->sc_iotag, + g_omap3_softc->sc_intcps_ioh, INTCPS_SYSCONFIG); + if (syscfg & 0x1UL) + break; + } + + + + return 0; +} + Added: soc2012/aleek/beaglexm-armv6/sys/arm/ti/omap3/omap3_prcm_clks.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/aleek/beaglexm-armv6/sys/arm/ti/omap3/omap3_prcm_clks.c Tue May 29 21:47:56 2012 (r236688) @@ -0,0 +1,1196 @@ +/*- + * Copyright (c) 2011 + * Ben Gray . + * 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 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + + +/* + * This file defines the clock configuration for the OMAP3xxx series of + * devices. + * + * How This is Suppose to Work + * =========================== + * - There is a top level omap_prcm module that defines all OMAP SoC drivers + * should use to enable/disable the system clocks regardless of the version + * of OMAP device they are running on. This top level PRCM module is just + * a thin shim to chip specific functions that perform the donkey work of + * configuring the clock - this file is the 'donkey' for OMAP35xx devices. + * + * - The key bit in this file is the omap_clk_devmap array, it's + * used by the omap_prcm driver to determine what clocks are valid and which + * functions to call to manipulate them. + * + * - In essence you just need to define some callbacks for each of the + * clocks and then you're done. + * + * - The other thing worth noting is that when the omap_prcm device + * is registered you typically pass in some memory ranges which are the + * SYS_MEMORY resources. These resources are in turn allocated using + * bus_allocate_resources(...) and the resource handles are passed to all + * individual clock callback handlers. + * + * + * + * + */ + + +void +omap3_clk_init(device_t dev, int prio); + +static int +omap3_clk_generic_activate(const struct omap_clock_dev *clkdev, + struct resource* mem_res[]); + +static int +omap3_clk_generic_deactivate(const struct omap_clock_dev *clkdev, + struct resource* mem_res[]); + +static int +omap3_clk_generic_accessible(const struct omap_clock_dev *clkdev, + struct resource* mem_res[]); + +static int +omap3_clk_generic_set_source(const struct omap_clock_dev *clkdev, clk_src_t clksrc, + struct resource* mem_res[]); + +static int +omap3_clk_generic_get_source_freq(const struct omap_clock_dev *clkdev, + unsigned int *freq, + struct resource* mem_res[]); + + +static int +omap3_clk_gptimer_get_source_freq(const struct omap_clock_dev *clkdev, + unsigned int *freq, + struct resource* mem_res[]); +static int +omap3_clk_gptimer_set_source(const struct omap_clock_dev *clkdev, + clk_src_t clksrc, struct resource* mem_res[]); + + + +static int +omap3_clk_alwayson_null_func(const struct omap_clock_dev *clkdev, + struct resource* mem_res[]); + + + +static int +omap3_clk_get_sysclk_freq(const struct omap_clock_dev *clkdev, + unsigned int *freq, struct resource* mem_res[]); + +static int +omap3_clk_get_arm_fclk_freq(const struct omap_clock_dev *clkdev, + unsigned int *freq, struct resource* mem_res[]); + + + +static int +omap3_clk_hsusbhost_activate(const struct omap_clock_dev *clkdev, + struct resource* mem_res[]); + +static int +omap3_clk_hsusbhost_deactivate(const struct omap_clock_dev *clkdev, + struct resource* mem_res[]); + + + + +#define FREQ_96MHZ 96000000 +#define FREQ_64MHZ 64000000 +#define FREQ_48MHZ 48000000 +#define FREQ_32KHZ 32000 + + + +/** + * Only one memory regions is needed for OMAP35xx clock control (unlike OMAP4) + * + * CM Instance - 0x4800 4000 : 0x4800 5500 + * PRM Instance - 0x4830 6000 : 0x4830 8000 + * + */ +#define CM_INSTANCE_MEM_REGION 0 +#define PRM_INSTANCE_MEM_REGION 1 + +#define IVA2_CM_OFFSET 0x0000 +#define OCP_SYSTEM_CM_OFFSET 0x0800 +#define MPU_CM_OFFSET 0x0900 +#define CORE_CM_OFFSET 0x0A00 +#define SGX_CM_OFFSET 0x0B00 +#define WKUP_CM_OFFSET 0x0C00 +#define CLOCK_CTRL_CM_OFFSET 0x0D00 +#define DSS_CM_OFFSET 0x0E00 +#define CAM_CM_OFFSET 0x0F00 +#define PER_CM_OFFSET 0x1000 +#define EMU_CM_OFFSET 0x1100 +#define GLOBAL_CM_OFFSET 0x1200 +#define NEON_CM_OFFSET 0x1300 +#define USBHOST_CM_OFFSET 0x1400 + +#define IVA2_PRM_OFFSET 0x0000 +#define OCP_SYSTEM_PRM_OFFSET 0x0800 +#define MPU_PRM_OFFSET 0x0900 +#define CORE_PRM_OFFSET 0x0A00 +#define SGX_PRM_OFFSET 0x0B00 +#define WKUP_PRM_OFFSET 0x0C00 +#define CLOCK_CTRL_PRM_OFFSET 0x0D00 +#define DSS_PRM_OFFSET 0x0E00 +#define CAM_PRM_OFFSET 0x0F00 +#define PER_PRM_OFFSET 0x1000 +#define EMU_PRM_OFFSET 0x1100 +#define GLOBAL_PRM_OFFSET 0x1200 +#define NEON_PRM_OFFSET 0x1300 +#define USBHOST_PRM_OFFSET 0x1400 + + + + + + +/** + * omap_clk_devmap - Array of clock devices available on OMAP3xxx devices + * + * This map only defines which clocks are valid and the callback functions + * for clock activate, deactivate, etc. It is used by the top level omap_prcm + * driver. + * + * The actual details of the clocks (config registers, bit fields, sources, + * etc) are in the private g_omap3_clk_details array below. + * + */ + +#define OMAP3_GENERIC_CLOCK_DEV(i) \ + { .id = (i), \ + .clk_activate = omap3_clk_generic_activate, \ + .clk_deactivate = omap3_clk_generic_deactivate, \ + .clk_set_source = omap3_clk_generic_set_source, \ + .clk_accessible = omap3_clk_generic_accessible, \ + .clk_get_source_freq = omap3_clk_generic_get_source_freq \ + } + +#define OMAP3_GPTIMER_CLOCK_DEV(i) \ + { .id = (i), \ + .clk_activate = omap3_clk_generic_activate, \ + .clk_deactivate = omap3_clk_generic_deactivate, \ + .clk_set_source = omap3_clk_gptimer_set_source, \ + .clk_accessible = omap3_clk_generic_accessible, \ + .clk_get_source_freq = omap3_clk_gptimer_get_source_freq \ + } + +#define OMAP3_ALWAYSON_CLOCK_DEV(i) \ + { .id = (i), \ + .clk_activate = omap3_clk_alwayson_null_func, \ + .clk_deactivate = omap3_clk_alwayson_null_func, \ + .clk_set_source = NULL, \ + .clk_accessible = omap3_clk_alwayson_null_func, \ + .clk_get_source_freq = NULL \ + } + *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***