diff options
author | Jasper Lievisse Adriaanse <jasper@cvs.openbsd.org> | 2011-03-14 15:16:47 +0000 |
---|---|---|
committer | Jasper Lievisse Adriaanse <jasper@cvs.openbsd.org> | 2011-03-14 15:16:47 +0000 |
commit | b33ab19ac337857f8d07e39d5854e08e80aa9f0a (patch) | |
tree | 348d9bad50c1650f4e978518e5847e8317779bda /sys/arch | |
parent | 05c5064fde2a319b6f4b74f8226fd0dc8b619711 (diff) |
use DPLL5 as a 120MHz reference clock to be used by the usb subsystem which
previously had no clue and would crash.
feedback/ok drahn@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/beagle/dev/prcm.c | 69 |
1 files changed, 64 insertions, 5 deletions
diff --git a/sys/arch/beagle/dev/prcm.c b/sys/arch/beagle/dev/prcm.c index 04fd63c7cf9..6fb56f36487 100644 --- a/sys/arch/beagle/dev/prcm.c +++ b/sys/arch/beagle/dev/prcm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: prcm.c,v 1.4 2010/08/07 03:50:01 krw Exp $ */ +/* $OpenBSD: prcm.c,v 1.5 2011/03/14 15:16:46 jasper Exp $ */ /* * Copyright (c) 2007,2009 Dale Rahn <drahn@openbsd.org> * @@ -15,6 +15,10 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/* + * Driver for the Power, Reset and Clock Management Module (PRCM). + */ + #include <sys/types.h> #include <sys/param.h> #include <sys/systm.h> @@ -106,10 +110,15 @@ #define PM_WKEN_WKUP 0x0cA0 #define PM_WKST_WKUP 0x0cB0 #define CM_CLKEN_PLL 0x0d00 +#define CM_CLKEN2_PLL 0x0d04 #define CM_IDLEST_CKGEN 0x0d20 #define CM_AUTOIDLE_PLL 0x0d30 +#define CM_AUTOIDLE2_PLL 0x0d34 #define CM_CLKSEL1_PLL 0x0d40 #define CM_CLKSEL2_PLL 0x0d44 +#define CM_CLKSEL3_PLL 0x0d48 +#define CM_CLKSEL4_PLL 0x0d4C +#define CM_CLKSEL5_PLL 0x0d50 #define CM_FCLKEN_PER 0x1000 #define CM_ICLKEN_PER 0x1010 #define CM_IDLEST_PER 0x1020 @@ -147,14 +156,15 @@ uint32_t prcm_fmask_addr[PRCM_REG_MAX]; #define PRCM_SIZE 0x2000 -bus_space_tag_t prcm_iot; -bus_space_handle_t prcm_ioh; +#define SYS_CLK 13 /* SYS_CLK speed in MHz */ + +bus_space_tag_t prcm_iot; +bus_space_handle_t prcm_ioh; int prcm_attached; int prcm_match(struct device *, void *, void *); void prcm_attach(struct device *, struct device *, void *); - - +int prcm_setup_dpll5(void); struct cfattach prcm_ca = { sizeof (struct device), prcm_match, prcm_attach @@ -188,6 +198,9 @@ prcm_attach(struct device *parent, struct device *self, void *args) prcm_attached = 1; + /* Setup the 120MHZ DPLL5 clock, to be used by USB. */ + prcm_setup_dpll5(); + /* XXX */ #if 1 printf("CM_FCLKEN1_CORE %x\n", bus_space_read_4(prcm_iot, prcm_ioh, CM_FCLKEN1_CORE)); @@ -296,3 +309,49 @@ prcm_enableclock(int bit) } printf ("\n"); } + +/* + * OMAP35xx Power, Reset, and Clock Management Reference Guide + * (sprufa5.pdf) and AM/DM37x Multimedia Device Technical Reference + * Manual (sprugn4h.pdf) note that DPLL5 provides a 120MHz clock for + * peripheral domain modules (page 107 and page 302). + * The reference clock for DPLL5 is DPLL5_ALWON_FCLK which is + * SYS_CLK, running at 13MHz. + */ +int +prcm_setup_dpll5(void) +{ + uint32_t val; + + /* + * We need to set the multiplier and divider values for PLL. + * To end up with 120MHz we take SYS_CLK, divide by it and multiply + * with 120 (sprugn4h.pdf, 13.4.11.4.1 SSC Configuration) + */ + val = ((120 & 0x7ff) << 8) | ((SYS_CLK - 1) & 0x7f); + bus_space_write_4(prcm_iot, prcm_ioh, CM_CLKSEL4_PLL, val); + + /* Clock divider from the PLL to the 120MHz clock. */ + bus_space_write_4(prcm_iot, prcm_ioh, CM_CLKSEL5_PLL, val); + + /* + * spruf98o.pdf, page 2319: + * PERIPH2_DPLL_FREQSEL is 0x7 1.75MHz to 2.1MHz + * EN_PERIPH2_DPLL is 0x7 + */ + val = (7 << 4) | (7 << 0); + bus_space_write_4(prcm_iot, prcm_ioh, CM_CLKEN2_PLL, val); + + /* Disable the interconnect clock auto-idle. */ + bus_space_write_4(prcm_iot, prcm_ioh, CM_AUTOIDLE2_PLL, 0x0); + + /* Wait until DPLL5 is locked and there's clock activity. */ + while ((val = bus_space_read_4(prcm_iot, prcm_ioh, + CM_IDLEST_CKGEN) & 0x01) == 0x00) { +#ifdef DIAGNOSTIC + printf("CM_IDLEST_PLL = 0x&08x\n", val); +#endif + } + + return 0; +} |