socsvn commit: r236688 - in soc2012/aleek/beaglexm-armv6: .
sys/arm/ti/omap3
aleek at FreeBSD.org
aleek at FreeBSD.org
Tue May 29 21:47:59 UTC 2012
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 <ben.r.gray at gmail.com>.
+ * 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 <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/module.h>
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <machine/bus.h>
+
+#include <arm/omap/omapvar.h>
+#include <arm/omap/omap3/omap3var.h>
+#include <arm/omap/omap3/omap3_reg.h>
+
+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 <ben.r.gray at gmail.com>.
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <machine/intr.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <arm/omap/omap3/omap3var.h>
+#include <arm/omap/omap3/omap3_reg.h>
+
+
+
+/*
+ * 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 <ben.r.gray at gmail.com>.
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/frame.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+
+#include <arm/omap/omapvar.h>
+#include <arm/omap/omap_prcm.h>
+#include <arm/omap/omap3/omap3_reg.h>
+
+
+
+/*
+ * 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 ***
More information about the svn-soc-all
mailing list