socsvn commit: r237848 - in soc2012/aleek/beaglexm-armv6/sys:
arm/ti arm/ti/am37x boot/fdt/dts
aleek at FreeBSD.org
aleek at FreeBSD.org
Sun Jun 17 20:11:36 UTC 2012
Author: aleek
Date: Sun Jun 17 20:11:33 2012
New Revision: 237848
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=237848
Log:
modified System Control Module (SCM) for omap3. Seems to work, need to test after PRCM is working
Modified:
soc2012/aleek/beaglexm-armv6/sys/arm/ti/am37x/am37x_prcm.c
soc2012/aleek/beaglexm-armv6/sys/arm/ti/am37x/am37x_scm_padconf.c
soc2012/aleek/beaglexm-armv6/sys/arm/ti/ti_machdep.c
soc2012/aleek/beaglexm-armv6/sys/boot/fdt/dts/beagleboardxm.dts
Modified: soc2012/aleek/beaglexm-armv6/sys/arm/ti/am37x/am37x_prcm.c
==============================================================================
--- soc2012/aleek/beaglexm-armv6/sys/arm/ti/am37x/am37x_prcm.c Sun Jun 17 19:16:31 2012 (r237847)
+++ soc2012/aleek/beaglexm-armv6/sys/arm/ti/am37x/am37x_prcm.c Sun Jun 17 20:11:33 2012 (r237848)
@@ -1,6 +1,5 @@
/*-
- * Copyright (c) 2011
- * Ben Gray <ben.r.gray at gmail.com>.
+ * Copyright (c) 2012 Damjan Marion <dmarion at Freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -12,10 +11,10 @@
* 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
+ * 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 AUTHOR OR CONTRIBUTORS BE LIABLE
+ * 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)
@@ -30,171 +29,103 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/bus.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 <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.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/ti/tivar.h>
+#include <arm/ti/ti_scm.h>
#include <arm/ti/ti_prcm.h>
-#include <arm/ti/am37x/am37x_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 ti_clock_dev *clkdev,
- struct resource* mem_res[]);
-
-static int
-omap3_clk_generic_deactivate(const struct ti_clock_dev *clkdev,
- struct resource* mem_res[]);
-
-static int
-omap3_clk_generic_accessible(const struct ti_clock_dev *clkdev,
- struct resource* mem_res[]);
-
-static int
-omap3_clk_generic_set_source(const struct ti_clock_dev *clkdev, clk_src_t clksrc,
- struct resource* mem_res[]);
-
-static int
-omap3_clk_generic_get_source_freq(const struct ti_clock_dev *clkdev,
- unsigned int *freq,
- struct resource* mem_res[]);
-
-
-static int
-omap3_clk_gptimer_get_source_freq(const struct ti_clock_dev *clkdev,
- unsigned int *freq,
- struct resource* mem_res[]);
-static int
-omap3_clk_gptimer_set_source(const struct ti_clock_dev *clkdev,
- clk_src_t clksrc, struct resource* mem_res[]);
-
-
-
-static int
-omap3_clk_alwayson_null_func(const struct ti_clock_dev *clkdev,
- struct resource* mem_res[]);
-
-
-
-static int
-omap3_clk_get_sysclk_freq(const struct ti_clock_dev *clkdev,
- unsigned int *freq, struct resource* mem_res[]);
-
-static int
-omap3_clk_get_arm_fclk_freq(const struct ti_clock_dev *clkdev,
- unsigned int *freq, struct resource* mem_res[]);
-
-
-
-static int
-omap3_clk_hsusbhost_activate(const struct ti_clock_dev *clkdev,
- struct resource* mem_res[]);
-
-static int
-omap3_clk_hsusbhost_deactivate(const struct ti_clock_dev *clkdev,
- struct resource* mem_res[]);
-
-
-
-
-#define FREQ_96MHZ 96000000
-#define FREQ_64MHZ 64000000
-#define FREQ_48MHZ 48000000
-#define FREQ_32KHZ 32000
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <machine/bus.h>
+#include <machine/fdt.h>
-/**
- * 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
-
-
+#define CM_PER 0
+#define CM_PER_L4LS_CLKSTCTRL (CM_PER + 0x000)
+#define CM_PER_L3S_CLKSTCTRL (CM_PER + 0x004)
+#define CM_PER_L3_CLKSTCTRL (CM_PER + 0x00C)
+#define CM_PER_CPGMAC0_CLKCTRL (CM_PER + 0x014)
+#define CM_PER_USB0_CLKCTRL (CM_PER + 0x01C)
+#define CM_PER_TPTC0_CLKCTRL (CM_PER + 0x024)
+#define CM_PER_MMC0_CLKCTRL (CM_PER + 0x03C)
+#define CM_PER_I2C2_CLKCTRL (CM_PER + 0x044)
+#define CM_PER_I2C1_CLKCTRL (CM_PER + 0x048)
+#define CM_PER_TIMER7_CLKCTRL (CM_PER + 0x07C)
+#define CM_PER_TIMER2_CLKCTRL (CM_PER + 0x080)
+#define CM_PER_TIMER3_CLKCTRL (CM_PER + 0x084)
+#define CM_PER_TIMER4_CLKCTRL (CM_PER + 0x088)
+#define CM_PER_GPIO1_CLKCTRL (CM_PER + 0x0AC)
+#define CM_PER_GPIO2_CLKCTRL (CM_PER + 0x0B0)
+#define CM_PER_GPIO3_CLKCTRL (CM_PER + 0x0B4)
+#define CM_PER_TPCC_CLKCTRL (CM_PER + 0x0BC)
+#define CM_PER_L3_INSTR_CLKCTRL (CM_PER + 0x0DC)
+#define CM_PER_L3_CLKCTRL (CM_PER + 0x0E0)
+#define CM_PER_TIMER5_CLKCTRL (CM_PER + 0x0EC)
+#define CM_PER_TIMER6_CLKCTRL (CM_PER + 0x0F0)
+#define CM_PER_MMC1_CLKCTRL (CM_PER + 0x0F4)
+#define CM_PER_MMC2_CLKCTRL (CM_PER + 0x0F8)
+#define CM_PER_TPTC1_CLKCTRL (CM_PER + 0x0FC)
+#define CM_PER_TPTC2_CLKCTRL (CM_PER + 0x100)
+#define CM_PER_OCPWP_L3_CLKSTCTRL (CM_PER + 0x12C)
+#define CM_PER_OCPWP_CLKCTRL (CM_PER + 0x130)
+#define CM_PER_CPSW_CLKSTCTRL (CM_PER + 0x144)
+
+#define CM_WKUP 0x400
+#define CM_WKUP_CLKSTCTRL (CM_WKUP + 0x000)
+#define CM_WKUP_CONTROL_CLKCTRL (CM_WKUP + 0x004)
+#define CM_WKUP_GPIO0_CLKCTRL (CM_WKUP + 0x008)
+#define CM_WKUP_CM_L3_AON_CLKSTCTRL (CM_WKUP + 0x01C)
+#define CM_WKUP_CM_CLKSEL_DPLL_MPU (CM_WKUP + 0x02C)
+#define CM_WKUP_CM_CLKDCOLDO_DPLL_PER (CM_WKUP + 0x07C)
+#define CM_WKUP_I2C0_CLKCTRL (CM_WKUP + 0x0B8)
+
+#define CM_DPLL 0x500
+#define CLKSEL_TIMER7_CLK (CM_DPLL + 0x004)
+#define CLKSEL_TIMER2_CLK (CM_DPLL + 0x008)
+#define CLKSEL_TIMER3_CLK (CM_DPLL + 0x00C)
+#define CLKSEL_TIMER4_CLK (CM_DPLL + 0x010)
+#define CLKSEL_TIMER5_CLK (CM_DPLL + 0x018)
+#define CLKSEL_TIMER6_CLK (CM_DPLL + 0x01C)
+
+#define PRM_DEVICE_OFFSET 0xF00
+#define PRM_RSTCTRL (PRM_DEVICE_OFFSET + 0x00)
+
+struct omap3_prcm_softc {
+ struct resource * res[2];
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+};
+static struct resource_spec omap3_prcm_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { -1, 0 }
+};
+static struct omap3_prcm_softc *omap3_prcm_sc = NULL;
+static int omap3_clk_generic_activate(struct ti_clock_dev *clkdev);
+static int omap3_clk_generic_deactivate(struct ti_clock_dev *clkdev);
+static int omap3_clk_generic_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
+static int omap3_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
+static int omap3_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
+static int omap3_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
+static void omap3_prcm_reset(void);
+static int omap3_clk_cpsw_activate(struct ti_clock_dev *clkdev);
+static int omap3_clk_musb0_activate(struct ti_clock_dev *clkdev);
/**
* omap_clk_devmap - Array of clock devices available on OMAP3xxx devices
@@ -245,9 +176,10 @@
}
-const struct ti_clock_dev omap_clk_devmap[] = {
- /* System clock */
+
+struct ti_clock_dev ti_clk_devmap[] = {
+ /* System clocks */
{ .id = SYS_CLK,
.clk_activate = NULL,
.clk_deactivate = NULL,
@@ -263,934 +195,373 @@
.clk_accessible = NULL,
.clk_get_source_freq = omap3_clk_get_arm_fclk_freq,
},
+ /* CPSW Ethernet Switch core clocks */
+ { .id = CPSW_CLK,
+ .clk_activate = omap3_clk_cpsw_activate,
+ .clk_deactivate = NULL,
+ .clk_set_source = NULL,
+ .clk_accessible = NULL,
+ .clk_get_source_freq = NULL,
+ },
+ /* Mentor USB HS controller core clocks */
+ { .id = MUSB0_CLK,
+ .clk_activate = omap3_clk_musb0_activate,
+ .clk_deactivate = NULL,
+ .clk_set_source = NULL,
+ .clk_accessible = NULL,
+ .clk_get_source_freq = NULL,
+ },
- /* UART device clocks */
- OMAP3_GENERIC_CLOCK_DEV(UART1_CLK),
- OMAP3_GENERIC_CLOCK_DEV(UART2_CLK),
- OMAP3_GENERIC_CLOCK_DEV(UART3_CLK),
- OMAP3_GENERIC_CLOCK_DEV(UART4_CLK),
-
- /* Timer device source clocks */
- OMAP3_GPTIMER_CLOCK_DEV(GPTIMER1_CLK),
- OMAP3_GPTIMER_CLOCK_DEV(GPTIMER2_CLK),
- OMAP3_GPTIMER_CLOCK_DEV(GPTIMER3_CLK),
- OMAP3_GPTIMER_CLOCK_DEV(GPTIMER4_CLK),
- OMAP3_GPTIMER_CLOCK_DEV(GPTIMER5_CLK),
- OMAP3_GPTIMER_CLOCK_DEV(GPTIMER6_CLK),
- OMAP3_GPTIMER_CLOCK_DEV(GPTIMER7_CLK),
- OMAP3_GPTIMER_CLOCK_DEV(GPTIMER8_CLK),
- OMAP3_GPTIMER_CLOCK_DEV(GPTIMER9_CLK),
- OMAP3_GPTIMER_CLOCK_DEV(GPTIMER10_CLK),
- OMAP3_GPTIMER_CLOCK_DEV(GPTIMER11_CLK),
-
- /* MMC device clocks (MMC1 and MMC2 can have different input clocks) */
- OMAP3_GENERIC_CLOCK_DEV(MMC1_CLK),
- OMAP3_GENERIC_CLOCK_DEV(MMC2_CLK),
- OMAP3_GENERIC_CLOCK_DEV(MMC3_CLK),
-
- /* USB HS (high speed TLL, EHCI and OHCI) */
- OMAP3_GENERIC_CLOCK_DEV(USBTLL_CLK),
- OMAP3_HSUSBHOST_CLOCK_DEV(USBHSHOST_CLK),
+ /* DMTimer */
+ AM335X_GENERIC_CLOCK_DEV(DMTIMER2_CLK),
+ AM335X_GENERIC_CLOCK_DEV(DMTIMER3_CLK),
+ AM335X_GENERIC_CLOCK_DEV(DMTIMER4_CLK),
+ AM335X_GENERIC_CLOCK_DEV(DMTIMER5_CLK),
+ AM335X_GENERIC_CLOCK_DEV(DMTIMER6_CLK),
+ AM335X_GENERIC_CLOCK_DEV(DMTIMER7_CLK),
/* GPIO */
- OMAP3_GENERIC_CLOCK_DEV(GPIO1_CLK),
- OMAP3_GENERIC_CLOCK_DEV(GPIO2_CLK),
- OMAP3_GENERIC_CLOCK_DEV(GPIO3_CLK),
- OMAP3_GENERIC_CLOCK_DEV(GPIO4_CLK),
- OMAP3_GENERIC_CLOCK_DEV(GPIO5_CLK),
- OMAP3_GENERIC_CLOCK_DEV(GPIO6_CLK),
-
- /* I2C */
- OMAP3_GENERIC_CLOCK_DEV(I2C1_CLK),
- OMAP3_GENERIC_CLOCK_DEV(I2C2_CLK),
- OMAP3_GENERIC_CLOCK_DEV(I2C3_CLK),
+ AM335X_GENERIC_CLOCK_DEV(GPIO0_CLK),
+ AM335X_GENERIC_CLOCK_DEV(GPIO1_CLK),
+ AM335X_GENERIC_CLOCK_DEV(GPIO2_CLK),
+ AM335X_GENERIC_CLOCK_DEV(GPIO3_CLK),
- /* sDMA */
- OMAP3_ALWAYSON_CLOCK_DEV(SDMA_CLK),
+ /* I2C */
+ AM335X_GENERIC_CLOCK_DEV(I2C0_CLK),
+ AM335X_GENERIC_CLOCK_DEV(I2C1_CLK),
+ AM335X_GENERIC_CLOCK_DEV(I2C2_CLK),
+
+ /* EDMA */
+ AM335X_GENERIC_CLOCK_DEV(EDMA_TPCC_CLK),
+ AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC0_CLK),
+ AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC1_CLK),
+ AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC2_CLK),
+
+ /* MMCHS */
+ AM335X_MMCHS_CLOCK_DEV(MMC0_CLK),
+ AM335X_MMCHS_CLOCK_DEV(MMC1_CLK),
+ AM335X_MMCHS_CLOCK_DEV(MMC2_CLK),
{ INVALID_CLK_IDENT, NULL, NULL, NULL, NULL }
};
-
-
-
-
-
-/**
- * g_omap3_clk_details - Stores details for all the different clocks supported
- *
- * Whenever an operation on a clock is being performed (activated, deactivated,
- * etc) this array is looked up to find the correct register and bit(s) we
- * should be modifying.
- *
- */
-
struct omap3_clk_details {
- clk_ident_t id;
- int32_t src_freq;
-
- /* The register offset from the CM module register region of the registers*/
- uint32_t fclken_offset;
- uint32_t iclken_offset;
- uint32_t idlest_offset;
-
- /* The bit offset for the clock */
- uint32_t bit_offset;
+ clk_ident_t id;
+ uint32_t clkctrl_reg;
+ uint32_t clksel_reg;
};
-#define OMAP3_GENERIC_CLOCK_DETAILS(d, freq, base, fclk, iclk, idlest, bit) \
- { .id = (d), \
- .src_freq = (freq), \
- .fclken_offset = ((base) + (fclk)), \
- .iclken_offset = ((base) + (iclk)), \
- .idlest_offset = ((base) + (idlest)), \
- .bit_offset = (bit), \
+#define _CLK_DETAIL(i, c, s) \
+ { .id = (i), \
+ .clkctrl_reg = (c), \
+ .clksel_reg = (s), \
}
-static const struct omap3_clk_details g_omap3_clk_details[] = {
+static struct omap3_clk_details g_omap3_clk_details[] = {
- /* UART */
- OMAP3_GENERIC_CLOCK_DETAILS(UART1_CLK, FREQ_48MHZ, CORE_CM_OFFSET,
- 0x00, 0x10, 0x20, 13),
- OMAP3_GENERIC_CLOCK_DETAILS(UART2_CLK, FREQ_48MHZ, CORE_CM_OFFSET,
- 0x00, 0x10, 0x20, 14),
- OMAP3_GENERIC_CLOCK_DETAILS(UART3_CLK, FREQ_48MHZ, PER_CM_OFFSET,
- 0x00, 0x10, 0x20, 11),
-
- /* General purpose timers */
- OMAP3_GENERIC_CLOCK_DETAILS(GPTIMER1_CLK, -1, WKUP_CM_OFFSET,
- 0x00, 0x10, 0x20, 3),
- OMAP3_GENERIC_CLOCK_DETAILS(GPTIMER2_CLK, -1, PER_CM_OFFSET,
- 0x00, 0x10, 0x20, 3),
- OMAP3_GENERIC_CLOCK_DETAILS(GPTIMER3_CLK, -1, PER_CM_OFFSET,
- 0x00, 0x10, 0x20, 4),
- OMAP3_GENERIC_CLOCK_DETAILS(GPTIMER4_CLK, -1, PER_CM_OFFSET,
- 0x00, 0x10, 0x20, 5),
- OMAP3_GENERIC_CLOCK_DETAILS(GPTIMER5_CLK, -1, PER_CM_OFFSET,
- 0x00, 0x10, 0x20, 6),
- OMAP3_GENERIC_CLOCK_DETAILS(GPTIMER6_CLK, -1, PER_CM_OFFSET,
- 0x00, 0x10, 0x20, 7),
- OMAP3_GENERIC_CLOCK_DETAILS(GPTIMER7_CLK, -1, PER_CM_OFFSET,
- 0x00, 0x10, 0x20, 8),
- OMAP3_GENERIC_CLOCK_DETAILS(GPTIMER8_CLK, -1, PER_CM_OFFSET,
- 0x00, 0x10, 0x20, 9),
- OMAP3_GENERIC_CLOCK_DETAILS(GPTIMER9_CLK, -1, PER_CM_OFFSET,
- 0x00, 0x10, 0x20, 10),
- OMAP3_GENERIC_CLOCK_DETAILS(GPTIMER10_CLK, -1, CORE_CM_OFFSET,
- 0x00, 0x10, 0x20, 11),
- OMAP3_GENERIC_CLOCK_DETAILS(GPTIMER11_CLK, -1, CORE_CM_OFFSET,
- 0x00, 0x10, 0x20, 12),
-
- /* HSMMC (MMC1 and MMC2 can have different input clocks) */
- OMAP3_GENERIC_CLOCK_DETAILS(MMC1_CLK, FREQ_96MHZ, CORE_CM_OFFSET,
- 0x00, 0x10, 0x20, 24),
- OMAP3_GENERIC_CLOCK_DETAILS(MMC2_CLK, FREQ_96MHZ, CORE_CM_OFFSET,
- 0x00, 0x10, 0x20, 25),
- OMAP3_GENERIC_CLOCK_DETAILS(MMC3_CLK, FREQ_96MHZ, CORE_CM_OFFSET,
- 0x00, 0x10, 0x20, 30),
-
- /* USB HS (high speed TLL, EHCI and OHCI) */
- OMAP3_GENERIC_CLOCK_DETAILS(USBTLL_CLK, -1, CORE_CM_OFFSET,
- 0x08, 0x18, 0x28, 2),
- OMAP3_GENERIC_CLOCK_DETAILS(USBHSHOST_CLK, -1, USBHOST_CM_OFFSET,
- 0x00, 0x10, 0x20, 1),
+ /* DMTimer modules */
+ _CLK_DETAIL(DMTIMER2_CLK, CM_PER_TIMER2_CLKCTRL, CLKSEL_TIMER2_CLK),
+ _CLK_DETAIL(DMTIMER3_CLK, CM_PER_TIMER3_CLKCTRL, CLKSEL_TIMER3_CLK),
+ _CLK_DETAIL(DMTIMER4_CLK, CM_PER_TIMER4_CLKCTRL, CLKSEL_TIMER4_CLK),
+ _CLK_DETAIL(DMTIMER5_CLK, CM_PER_TIMER5_CLKCTRL, CLKSEL_TIMER5_CLK),
+ _CLK_DETAIL(DMTIMER6_CLK, CM_PER_TIMER6_CLKCTRL, CLKSEL_TIMER6_CLK),
+ _CLK_DETAIL(DMTIMER7_CLK, CM_PER_TIMER7_CLKCTRL, CLKSEL_TIMER7_CLK),
/* GPIO modules */
- OMAP3_GENERIC_CLOCK_DETAILS(GPIO1_CLK, -1, WKUP_CM_OFFSET,
- 0x00, 0x10, 0x20, 3),
- OMAP3_GENERIC_CLOCK_DETAILS(GPIO2_CLK, -1, PER_CM_OFFSET,
- 0x00, 0x10, 0x20, 13),
- OMAP3_GENERIC_CLOCK_DETAILS(GPIO3_CLK, -1, PER_CM_OFFSET,
- 0x00, 0x10, 0x20, 14),
- OMAP3_GENERIC_CLOCK_DETAILS(GPIO4_CLK, -1, PER_CM_OFFSET,
- 0x00, 0x10, 0x20, 15),
- OMAP3_GENERIC_CLOCK_DETAILS(GPIO5_CLK, -1, PER_CM_OFFSET,
- 0x00, 0x10, 0x20, 16),
- OMAP3_GENERIC_CLOCK_DETAILS(GPIO6_CLK, -1, PER_CM_OFFSET,
- 0x00, 0x10, 0x20, 17),
-
- /* I2C modules */
- OMAP3_GENERIC_CLOCK_DETAILS(I2C1_CLK, -1, CORE_CM_OFFSET,
- 0x00, 0x10, 0x20, 15),
- OMAP3_GENERIC_CLOCK_DETAILS(I2C2_CLK, -1, CORE_CM_OFFSET,
- 0x00, 0x10, 0x20, 16),
- OMAP3_GENERIC_CLOCK_DETAILS(I2C3_CLK, -1, CORE_CM_OFFSET,
- 0x00, 0x10, 0x20, 17),
+ _CLK_DETAIL(GPIO0_CLK, CM_WKUP_GPIO0_CLKCTRL, 0),
+ _CLK_DETAIL(GPIO1_CLK, CM_PER_GPIO1_CLKCTRL, 0),
+ _CLK_DETAIL(GPIO2_CLK, CM_PER_GPIO2_CLKCTRL, 0),
+ _CLK_DETAIL(GPIO3_CLK, CM_PER_GPIO3_CLKCTRL, 0),
+ /* I2C modules */
+ _CLK_DETAIL(I2C0_CLK, CM_WKUP_I2C0_CLKCTRL, 0),
+ _CLK_DETAIL(I2C1_CLK, CM_PER_I2C1_CLKCTRL, 0),
+ _CLK_DETAIL(I2C2_CLK, CM_PER_I2C2_CLKCTRL, 0),
+
+ /* EDMA modules */
+ _CLK_DETAIL(EDMA_TPCC_CLK, CM_PER_TPCC_CLKCTRL, 0),
+ _CLK_DETAIL(EDMA_TPTC0_CLK, CM_PER_TPTC0_CLKCTRL, 0),
+ _CLK_DETAIL(EDMA_TPTC1_CLK, CM_PER_TPTC1_CLKCTRL, 0),
+ _CLK_DETAIL(EDMA_TPTC2_CLK, CM_PER_TPTC2_CLKCTRL, 0),
+
+ /* MMCHS modules*/
+ _CLK_DETAIL(MMC0_CLK, CM_PER_MMC0_CLKCTRL, 0),
+ _CLK_DETAIL(MMC1_CLK, CM_PER_MMC1_CLKCTRL, 0),
+ _CLK_DETAIL(MMC2_CLK, CM_PER_MMC1_CLKCTRL, 0),
- { INVALID_CLK_IDENT, 0, 0, 0, 0 },
+ { INVALID_CLK_IDENT, 0},
};
+/* Read/Write macros */
+#define prcm_read_4(reg) \
+ bus_space_read_4(omap3_prcm_sc->bst, omap3_prcm_sc->bsh, reg)
+#define prcm_write_4(reg, val) \
+ bus_space_write_4(omap3_prcm_sc->bst, omap3_prcm_sc->bsh, reg, val)
+void omap3_prcm_setup_dmtimer(int);
-
-
-
-/**
- * MAX_MODULE_ENABLE_WAIT - the number of loops to wait for the module to come
- * alive.
- *
- */
-#define MAX_MODULE_ENABLE_WAIT 1000
-
-
-/**
- * ARRAY_SIZE - Macro to return the number of elements in a static const array.
- *
- */
-#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
-
-
-
-
-/**
- * omap3_clk_wait_on_reg - loops for MAX_MODULE_ENABLE_WAIT times or until
- * register bit(s) change.
- * @mem_res: memory resource of the register to read
- * @off: offset of the register within mem_res
- * @mask: the mask to bitwise AND with the register
- * @cmp: if this value matches the register value after the mask is applied
- * the function returns with 0.
- *
- *
- * RETURNS:
- * Returns 0 on success or ETIMEDOUT on failure.
- */
static int
-omap3_clk_wait_on_reg(struct resource* mem_res, bus_size_t off, uint32_t mask,
- uint32_t cmp)
+omap3_prcm_probe(device_t dev)
{
- unsigned int i;
- for (i = 0; i < MAX_MODULE_ENABLE_WAIT; i++) {
- if ((bus_read_4(mem_res, off) & mask) == cmp)
- return (0);
+ if (ofw_bus_is_compatible(dev, "omap3,prcm")) {
+ device_set_desc(dev, "AM335x Power and Clock Management");
+ return(BUS_PROBE_DEFAULT);
}
- return (ETIMEDOUT);
+ return (ENXIO);
}
-
-
-
-
-/**
- * omap3_clk_details - returns a pointer to the generic clock details
- * @id: The ID of the clock to get the details for
- *
- * This function iterates over the g_omap3_clk_details array and returns a
- * pointer to the entry that matches the supplied ID, or NULL if no entry
- * is found.
- *
- * RETURNS:
- * Pointer to clock details or NULL on failure
- */
-static const struct omap3_clk_details*
-omap3_clk_details(clk_ident_t id)
+static int
+omap3_prcm_attach(device_t dev)
{
- const struct omap3_clk_details *walker;
+ struct omap3_prcm_softc *sc = device_get_softc(dev);
+ unsigned int sysclk, fclk;
- for (walker = g_omap3_clk_details; walker->id != INVALID_CLK_IDENT; walker++) {
- if (id == walker->id)
- return (walker);
- }
+ if (omap3_prcm_sc)
+ return (ENXIO);
- return NULL;
-}
+ if (bus_alloc_resources(dev, omap3_prcm_spec, sc->res)) {
+ device_printf(dev, "could not allocate resources\n");
+ return (ENXIO);
+ }
+ sc->bst = rman_get_bustag(sc->res[0]);
+ sc->bsh = rman_get_bushandle(sc->res[0]);
+ omap3_prcm_sc = sc;
+ ti_cpu_reset = omap3_prcm_reset;
+ omap3_clk_get_sysclk_freq(NULL, &sysclk);
+ omap3_clk_get_arm_fclk_freq(NULL, &fclk);
+ device_printf(dev, "Clocks: System %u.%01u MHz, CPU %u MHz\n",
+ sysclk/1000000, (sysclk % 1000000)/100000, fclk/1000000);
-/**
- * omap3_clk_alwayson_null_func - dummy function for always on clocks
- * @clkdev: pointer to the clock device structure (ignored)
- * @mem_res: array of memory resources mapped when PRCM driver attached (ignored)
- *
- *
- *
- * LOCKING:
- * Inherits the locks from the omap_prcm driver, no internal locking.
- *
- * RETURNS:
- * Returns 0 on success or a positive error code on failure.
- */
-static int
-omap3_clk_alwayson_null_func(const struct ti_clock_dev *clkdev,
- struct resource* mem_res[])
-{
return (0);
}
+static device_method_t omap3_prcm_methods[] = {
+ DEVMETHOD(device_probe, omap3_prcm_probe),
+ DEVMETHOD(device_attach, omap3_prcm_attach),
+ { 0, 0 }
+};
+static driver_t omap3_prcm_driver = {
+ "omap3_prcm",
+ omap3_prcm_methods,
+ sizeof(struct omap3_prcm_softc),
+};
+static devclass_t omap3_prcm_devclass;
+DRIVER_MODULE(omap3_prcm, simplebus, omap3_prcm_driver,
+ omap3_prcm_devclass, 0, 0);
+MODULE_DEPEND(omap3_prcm, ti_scm, 1, 1, 1);
-/**
- * omap3_clk_get_sysclk_freq - gets the sysclk frequency
- * @sc: pointer to the clk module/device context
- *
- * Read the clocking information from the power-control/boot-strap registers,
- * and stored in two global variables.
- *
- * RETURNS:
- * nothing, values are saved in global variables
- */
-static int
-omap3_clk_get_sysclk_freq(const struct ti_clock_dev *clkdev,
- unsigned int *freq, struct resource* mem_res[])
+static struct omap3_clk_details*
+omap3_clk_details(clk_ident_t id)
{
- uint32_t clksel;
- uint32_t clknsel;
- unsigned int oscclk;
- unsigned int sysclk;
-
- /* Read the input clock freq from the configuration register */
- clknsel = bus_read_4(mem_res[PRM_INSTANCE_MEM_REGION], CLOCK_CTRL_PRM_OFFSET + 0x40);
- switch (clknsel & 0x7) {
- case 0x0:
- /* 12Mhz */
- oscclk = 12000000;
- break;
- case 0x1:
- /* 13Mhz */
- oscclk = 13000000;
- break;
- case 0x2:
- /* 19.2Mhz */
- oscclk = 19200000;
- break;
- case 0x3:
- /* 26Mhz */
- oscclk = 26000000;
- break;
- case 0x4:
- /* 38.4Mhz */
- oscclk = 38400000;
- break;
- case 0x5:
- /* 16.8Mhz */
- oscclk = 16800000;
- break;
- default:
- panic("%s: Invalid clock freq", __func__);
- }
+ struct omap3_clk_details *walker;
- /* Read the value of the clock divider used for the system clock */
- clksel = bus_read_4(mem_res[PRM_INSTANCE_MEM_REGION], GLOBAL_PRM_OFFSET + 0x70);
- switch (clksel & 0xC0) {
- case 0x40:
- sysclk = oscclk;
- break;
- case 0x80:
- sysclk = oscclk / 2;
- break;
- default:
- panic("%s: Invalid system clock divider", __func__);
+ for (walker = g_omap3_clk_details; walker->id != INVALID_CLK_IDENT; walker++) {
+ if (id == walker->id)
+ return (walker);
}
- /* Return the value */
- if (freq)
- *freq = sysclk;
-
- return (0);
+ return NULL;
}
-
-
-/**
- * omap3_clk_get_arm_fclk_freq - gets the MPU clock frequency
- * @clkdev: ignored
- * @freq: pointer which upon return will contain the freq in hz
- * @mem_res: array of allocated memory resources
- *
- * Reads the frequency setting information registers and returns the value
- * in the freq variable.
- *
- * RETURNS:
- * returns 0 on success, a positive error code on failure.
- */
static int
-omap3_clk_get_arm_fclk_freq(const struct ti_clock_dev *clkdev,
- unsigned int *freq, struct resource* mem_res[])
+omap3_clk_generic_activate(struct ti_clock_dev *clkdev)
{
- unsigned int sysclk;
- unsigned int coreclk;
- unsigned int mpuclk;
- uint32_t clksel;
- uint32_t clkout;
-
-
- /* Get the SYSCLK freq */
- omap3_clk_get_sysclk_freq(clkdev, &sysclk, mem_res);
-
-
- /* First get the freq of the CORE_CLK (feed from DPLL3) */
- clksel = bus_read_4(mem_res[CM_INSTANCE_MEM_REGION], CLOCK_CTRL_CM_OFFSET + 0x40);
- clkout = (sysclk * ((clksel >> 16) & 0x7FF)) / (((clksel >> 8) & 0x7F) + 1);
- coreclk = clkout / (clksel >> 27);
-
-
- /* Next get the freq for the MPU_CLK */
- clksel = bus_read_4(mem_res[CM_INSTANCE_MEM_REGION], MPU_CM_OFFSET + 0x40);
- mpuclk = (coreclk * ((clksel >> 8) & 0x7FF)) / ((clksel & 0x7F) + 1);
-
-
- /* Return the value */
- if (freq)
- *freq = mpuclk;
-
- return (0);
-}
-
-
-
+ struct omap3_prcm_softc *sc = omap3_prcm_sc;
+ struct omap3_clk_details* clk_details;
+ if (sc == NULL)
+ return ENXIO;
-
-
-
-/**
- * omap3_clk_generic_activate - activates a modules iinterface and func clock
- * @clkdev: pointer to the clock device structure.
- * @mem_res: array of memory resources mapped when PRCM driver attached
- *
- *
- *
- * LOCKING:
- * Inherits the locks from the omap_prcm driver, no internal locking.
- *
- * RETURNS:
- * Returns 0 on success or a positive error code on failure.
- */
-static int
-omap3_clk_generic_activate(const struct ti_clock_dev *clkdev,
- struct resource* mem_res[])
-{
- const struct omap3_clk_details* clk_details = omap3_clk_details(clkdev->id);
- struct resource* clk_mem_res = mem_res[CM_INSTANCE_MEM_REGION];
- uint32_t fclken, iclken;
+ clk_details = omap3_clk_details(clkdev->id);
if (clk_details == NULL)
return (ENXIO);
- if (clk_mem_res == NULL)
- return (ENOMEM);
-
-
- /* All the 'generic' clocks have a FCLKEN, ICLKEN and IDLEST register which
- * is for the functional, interface and clock status regsters respectively.
- */
-
- /* Enable the interface clock */
- iclken = bus_read_4(clk_mem_res, clk_details->iclken_offset);
- iclken |= (1UL << clk_details->bit_offset);
- bus_write_4(clk_mem_res, clk_details->iclken_offset, iclken);
-
- /* Read back the value to ensure the write has taken place ... needed ? */
- iclken = bus_read_4(clk_mem_res, clk_details->iclken_offset);
-
-
- /* Enable the functional clock */
- fclken = bus_read_4(clk_mem_res, clk_details->fclken_offset);
- fclken |= (1UL << clk_details->bit_offset);
- bus_write_4(clk_mem_res, clk_details->fclken_offset, fclken);
-
- /* Read back the value to ensure the write has taken place ... needed ? */
- fclken = bus_read_4(clk_mem_res, clk_details->fclken_offset);
-
-
- /* Now poll on the IDLEST register to tell us if the module has come up.
- * TODO: We need to take into account the parent clocks.
- */
-
- /* Try MAX_MODULE_ENABLE_WAIT number of times to check if enabled */
- if (omap3_clk_wait_on_reg(clk_mem_res, clk_details->idlest_offset,
- (1UL << clk_details->bit_offset), 0) != 0) {
- printf("Error: failed to enable module with clock %d\n", clkdev->id);
- return (ETIMEDOUT);
- }
-
- return (0);
-}
+ /* set *_CLKCTRL register MODULEMODE[1:0] to enable(2) */
+ prcm_write_4(clk_details->clkctrl_reg, 2);
+ while ((prcm_read_4(clk_details->clkctrl_reg) & 0x3) != 2)
+ DELAY(10);
-
-/**
- * omap3_clk_generic_deactivate - deactivates a modules clock
- * @clkdev: pointer to the clock device structure.
- * @mem_res: array of memory resources mapped when PRCM driver attached
- *
- *
- *
- * LOCKING:
- * Inherits the locks from the omap_prcm driver, no internal locking.
- *
- * RETURNS:
- * Returns 0 on success or a positive error code on failure.
- */
-static int
-omap3_clk_generic_deactivate(const struct ti_clock_dev *clkdev,
- struct resource* mem_res[])
-{
- const struct omap3_clk_details* clk_details = omap3_clk_details(clkdev->id);
- struct resource* clk_mem_res = mem_res[CM_INSTANCE_MEM_REGION];
- uint32_t fclken, iclken;
-
- if (clk_details == NULL)
- return (ENXIO);
- if (clk_mem_res == NULL)
- return (ENOMEM);
-
-
- /* All the 'generic' clocks have a FCLKEN, ICLKEN and IDLEST register which
- * is for the functional, interface and clock status regsters respectively.
- */
-
- /* Disable the interface clock */
- iclken = bus_read_4(clk_mem_res, clk_details->iclken_offset);
- iclken &= ~(1UL << clk_details->bit_offset);
- bus_write_4(clk_mem_res, clk_details->iclken_offset, iclken);
-
- /* Disable the functional clock */
- fclken = bus_read_4(clk_mem_res, clk_details->fclken_offset);
- fclken &= ~(1UL << clk_details->bit_offset);
- bus_write_4(clk_mem_res, clk_details->fclken_offset, fclken);
-
-
return (0);
}
-
-/**
- * omap3_clk_generic_set_source - checks if a module is accessible
- * @clkdev: pointer to the clock device structure.
- *
- *
- *
- * LOCKING:
- * Inherits the locks from the omap_prcm driver, no internal locking.
- *
- * RETURNS:
- * Returns 0 on success or a positive error code on failure.
- */
static int
-omap3_clk_generic_set_source(const struct ti_clock_dev *clkdev,
- clk_src_t clksrc, struct resource* mem_res[])
+omap3_clk_generic_deactivate(struct ti_clock_dev *clkdev)
{
+ struct omap3_prcm_softc *sc = omap3_prcm_sc;
+ struct omap3_clk_details* clk_details;
+ if (sc == NULL)
+ return ENXIO;
- return (0);
-}
-
-/**
- * omap3_clk_generic_accessible - checks if a module is accessible
- * @clkdev: pointer to the clock device structure.
- *
- *
- *
- * LOCKING:
- * Inherits the locks from the omap_prcm driver, no internal locking.
- *
- * RETURNS:
- * Returns 0 on success or a negative error code on failure.
- */
-static int
-omap3_clk_generic_accessible(const struct ti_clock_dev *clkdev,
- struct resource* mem_res[])
-{
- const struct omap3_clk_details* clk_details = omap3_clk_details(clkdev->id);
- struct resource* clk_mem_res = mem_res[CM_INSTANCE_MEM_REGION];
- uint32_t idlest;
+ clk_details = omap3_clk_details(clkdev->id);
if (clk_details == NULL)
return (ENXIO);
- if (clk_mem_res == NULL)
- return (ENOMEM);
-
- idlest = bus_read_4(clk_mem_res, clk_details->idlest_offset);
-
- /* Check the enabled state */
- if ((idlest & (1UL << clk_details->bit_offset)) == 0)
- return (0);
-
- return (1);
-}
-
-/**
- * omap3_clk_generic_get_source_freq - checks if a module is accessible
- * @clkdev: pointer to the clock device structure.
- *
- *
- *
- * LOCKING:
- * Inherits the locks from the omap_prcm driver, no internal locking.
- *
- * RETURNS:
- * Returns 0 on success or a negative error code on failure.
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-soc-all
mailing list