From c414207ab0ae6805769b4a966fef55b7d0742873 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 29 May 2012 03:23:18 +0000 Subject: [PATCH] Compute the master clock frequency, so we no longer need to have it compiled into the kernel. This allows us to boot the same kernel on machines with different master clock frequencies, so long as we can determine the main clock frequency accurately. Cleanup the pmc clock init function so it can be called in early boot so we can use the serial port just after we call cninit. # We have two calls to at91_pmc_clock_init for reasons unknown, that will # be fixed later -- it is harmless for now. --- sys/arm/at91/at91.c | 4 --- sys/arm/at91/at91_machdep.c | 1 + sys/arm/at91/at91_pmc.c | 49 +++++++++++++++++++++++------------ sys/arm/at91/at91rm92reg.h | 4 --- sys/arm/at91/at91sam9260reg.h | 4 --- sys/arm/at91/at91sam9g20reg.h | 4 --- sys/arm/at91/at91var.h | 2 ++ sys/arm/at91/std.ethernut5 | 3 --- sys/arm/at91/std.hl200 | 1 - sys/arm/at91/std.hl201 | 1 - sys/arm/at91/std.kb920x | 1 - sys/arm/at91/std.qila9g20 | 1 - sys/arm/at91/std.sam9g20ek | 5 ---- 13 files changed, 36 insertions(+), 44 deletions(-) diff --git a/sys/arm/at91/at91.c b/sys/arm/at91/at91.c index 842038e132b..e9f27b59d0e 100644 --- a/sys/arm/at91/at91.c +++ b/sys/arm/at91/at91.c @@ -56,11 +56,7 @@ extern const struct pmap_devmap at91_devmap[]; uint32_t at91_chip_id; -#ifdef AT91C_MASTER_CLOCK -uint32_t at91_master_clock = AT91C_MASTER_CLOCK; -#else uint32_t at91_master_clock; -#endif static int at91_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flags, diff --git a/sys/arm/at91/at91_machdep.c b/sys/arm/at91/at91_machdep.c index a7eb5f6f81e..28e691322e9 100644 --- a/sys/arm/at91/at91_machdep.c +++ b/sys/arm/at91/at91_machdep.c @@ -363,6 +363,7 @@ initarm(void *arg, void *arg2) cninit(); + at91_pmc_init_clock(); /* Get chip id so device drivers know about differences */ at91_chip_id = *(volatile uint32_t *) (AT91_BASE + AT91_DBGU_BASE + DBGU_C1R); diff --git a/sys/arm/at91/at91_pmc.c b/sys/arm/at91/at91_pmc.c index cff339699a2..285d7eadff9 100644 --- a/sys/arm/at91/at91_pmc.c +++ b/sys/arm/at91/at91_pmc.c @@ -55,12 +55,15 @@ static struct at91_pmc_softc { bus_space_handle_t sc_sh; struct resource *mem_res; /* Memory resource */ device_t dev; - uint32_t pllb_init; } *pmc_softc; +static uint32_t pllb_init; + MALLOC_DECLARE(M_PMC); MALLOC_DEFINE(M_PMC, "at91_pmc_clocks", "AT91 PMC Clock descriptors"); +#define AT91_PMC_BASE 0xffffc00 + static void at91_pmc_set_pllb_mode(struct at91_pmc_clock *, int); static void at91_pmc_set_sys_mode(struct at91_pmc_clock *, int); static void at91_pmc_set_periph_mode(struct at91_pmc_clock *, int); @@ -150,6 +153,11 @@ static inline uint32_t RD4(struct at91_pmc_softc *sc, bus_size_t off) { + if (sc == NULL) { + uint32_t *p = (uint32_t *)(AT91_BASE + AT91_PMC_BASE + off); + + return *p; + } return (bus_read_4(sc->mem_res, off)); } @@ -157,7 +165,12 @@ static inline void WR4(struct at91_pmc_softc *sc, bus_size_t off, uint32_t val) { - bus_write_4(sc->mem_res, off, val); + if (sc == NULL) { + uint32_t *p = (uint32_t *)(AT91_BASE + AT91_PMC_BASE + off); + + *p = val; + } else + bus_write_4(sc->mem_res, off, val); } void @@ -168,7 +181,7 @@ at91_pmc_set_pllb_mode(struct at91_pmc_clock *clk, int on) if (on) { on = PMC_IER_LOCKB; - value = sc->pllb_init; + value = pllb_init; } else value = 0; @@ -398,15 +411,17 @@ static const unsigned int at91_main_clock_tbl[] = { 16000000, 17344700, 18432000, 20000000 }; #define MAIN_CLOCK_TBL_LEN (sizeof(at91_main_clock_tbl) / sizeof(*at91_main_clock_tbl)) +#endif static unsigned int -at91_pmc_sense_main_clock(struct at91_pmc_softc *sc) +at91_pmc_sense_main_clock(void) { +#if !defined(AT91C_MAIN_CLOCK) unsigned int ckgr_val; unsigned int diff, matchdiff, freq; int i; - ckgr_val = (RD4(sc, CKGR_MCFR) & CKGR_MCFR_MAINF_MASK) << 11; + ckgr_val = (RD4(NULL, CKGR_MCFR) & CKGR_MCFR_MAINF_MASK) << 11; /* * Clocks up to 50MHz can be connected to some models. If @@ -432,21 +447,20 @@ at91_pmc_sense_main_clock(struct at91_pmc_softc *sc) } } return (freq); -} +#else + return (AT91C_MAIN_CLOCK); #endif +} -static void -at91_pmc_init_clock(struct at91_pmc_softc *sc) +void +at91_pmc_init_clock(void) { + struct at91_pmc_softc *sc = NULL; unsigned int main_clock; uint32_t mckr; uint32_t mdiv; -#if !defined(AT91C_MAIN_CLOCK) - main_clock = at91_pmc_sense_main_clock(pmc_softc); -#else - main_clock = AT91C_MAIN_CLOCK; -#endif + main_clock = at91_pmc_sense_main_clock(); if (at91_is_sam9() || at91_is_sam9xe()) { uhpck.pmc_mask = PMC_SCER_UHP_SAM9; @@ -464,8 +478,8 @@ at91_pmc_init_clock(struct at91_pmc_softc *sc) * Initialize the usb clock. This sets up pllb, but disables the * actual clock. */ - sc->pllb_init = at91_pmc_pll_calc(&pllb, 48000000 * 2) | 0x10000000; - at91_pmc_pll_rate(&pllb, sc->pllb_init); + pllb_init = at91_pmc_pll_calc(&pllb, 48000000 * 2) | 0x10000000; + at91_pmc_pll_rate(&pllb, pllb_init); #if 0 /* Turn off USB clocks */ @@ -570,8 +584,11 @@ at91_pmc_attach(device_t dev) /* * Configure main clock frequency. */ - at91_pmc_init_clock(pmc_softc); + at91_pmc_init_clock(); + /* + * Display info about clocks previously computed + */ device_printf(dev, "Primary: %d Hz PLLA: %d MHz CPU: %d MHz MCK: %d MHz\n", main_ck.hz, diff --git a/sys/arm/at91/at91rm92reg.h b/sys/arm/at91/at91rm92reg.h index 8241646a3dd..401d67ca3c0 100644 --- a/sys/arm/at91/at91rm92reg.h +++ b/sys/arm/at91/at91rm92reg.h @@ -403,10 +403,6 @@ #define AT91RM92_CF_PA_BASE 0x51400000 #define AT91RM92_CF_SIZE 0x00100000 -#ifndef AT91C_MASTER_CLOCK -#define AT91C_MASTER_CLOCK 60000000 -#endif - /* SDRAMC */ #define AT91RM92_SDRAMC_BASE 0xfffff90 diff --git a/sys/arm/at91/at91sam9260reg.h b/sys/arm/at91/at91sam9260reg.h index c790c2cf9e4..2f347a474d8 100644 --- a/sys/arm/at91/at91sam9260reg.h +++ b/sys/arm/at91/at91sam9260reg.h @@ -28,10 +28,6 @@ #ifndef AT91SAM9260REG_H_ #define AT91SAM9260REG_H_ -#ifndef AT91SAM9260_MASTER_CLOCK -#define AT91SAM9260_MASTER_CLOCK ((18432000 * 43)/6) -#endif - /* Chip Specific limits */ #define SAM9260_PLL_A_MIN_IN_FREQ 1000000 /* 1 Mhz */ #define SAM9260_PLL_A_MAX_IN_FREQ 32000000 /* 32 Mhz */ diff --git a/sys/arm/at91/at91sam9g20reg.h b/sys/arm/at91/at91sam9g20reg.h index 41c328aa5a6..4ab0353d3f2 100644 --- a/sys/arm/at91/at91sam9g20reg.h +++ b/sys/arm/at91/at91sam9g20reg.h @@ -29,10 +29,6 @@ #ifndef AT91SAM9G20REG_H_ #define AT91SAM9G20REG_H_ -#ifndef AT91SAM9G20_MASTER_CLOCK -#define AT91SAM9G20_MASTER_CLOCK ((18432000 * 43)/6) -#endif - /* Chip Specific limits */ #define SAM9G20_PLL_A_MIN_IN_FREQ 2000000 /* 2 Mhz */ #define SAM9G20_PLL_A_MAX_IN_FREQ 32000000 /* 32 Mhz */ diff --git a/sys/arm/at91/at91var.h b/sys/arm/at91/at91var.h index 9bd0265fc83..be82eeeba45 100644 --- a/sys/arm/at91/at91var.h +++ b/sys/arm/at91/at91var.h @@ -97,4 +97,6 @@ at91_cpu_is(u_int cpu) extern uint32_t at91_irq_system; extern uint32_t at91_master_clock; +void at91_pmc_init_clock(void); + #endif /* _AT91VAR_H_ */ diff --git a/sys/arm/at91/std.ethernut5 b/sys/arm/at91/std.ethernut5 index 684d606d6fd..90b6755e84e 100644 --- a/sys/arm/at91/std.ethernut5 +++ b/sys/arm/at91/std.ethernut5 @@ -7,8 +7,5 @@ makeoptions KERNVIRTADDR=0xc0000000 options KERNPHYSADDR=0x20000000 options KERNVIRTADDR=0xc0000000 -# SAM9XE512 w/ 90.3168 MHz master clock -options AT91C_MASTER_CLOCK=90316800 - device at91_board_ethernut5 nodevice at91sam9g20 diff --git a/sys/arm/at91/std.hl200 b/sys/arm/at91/std.hl200 index 3f99b49be88..f48f7236716 100644 --- a/sys/arm/at91/std.hl200 +++ b/sys/arm/at91/std.hl200 @@ -6,6 +6,5 @@ makeoptions KERNPHYSADDR=0x20100000 options KERNPHYSADDR=0x20100000 makeoptions KERNVIRTADDR=0xc0100000 options KERNVIRTADDR=0xc0100000 -options AT91C_MASTER_CLOCK=45000000 device at91_board_hl200 diff --git a/sys/arm/at91/std.hl201 b/sys/arm/at91/std.hl201 index 2d7d9260506..86022b61137 100644 --- a/sys/arm/at91/std.hl201 +++ b/sys/arm/at91/std.hl201 @@ -6,6 +6,5 @@ makeoptions KERNPHYSADDR=0x20000000 makeoptions KERNVIRTADDR=0xc0000000 options KERNPHYSADDR=0x20000000 options KERNVIRTADDR=0xc0000000 -options AT91C_MASTER_CLOCK=132000000 device at91_board_hl201 diff --git a/sys/arm/at91/std.kb920x b/sys/arm/at91/std.kb920x index 26d0443f28f..85c8d038bf7 100644 --- a/sys/arm/at91/std.kb920x +++ b/sys/arm/at91/std.kb920x @@ -6,6 +6,5 @@ makeoptions KERNPHYSADDR=0x20000000 options KERNPHYSADDR=0x20000000 makeoptions KERNVIRTADDR=0xc0000000 options KERNVIRTADDR=0xc0000000 -options AT91C_MASTER_CLOCK=60000000 device at91_board_kb920x diff --git a/sys/arm/at91/std.qila9g20 b/sys/arm/at91/std.qila9g20 index 007cdf5f8ba..4595d4e4c9a 100644 --- a/sys/arm/at91/std.qila9g20 +++ b/sys/arm/at91/std.qila9g20 @@ -6,6 +6,5 @@ makeoptions KERNPHYSADDR=0x20000000 makeoptions KERNVIRTADDR=0xc0000000 options KERNPHYSADDR=0x20000000 options KERNVIRTADDR=0xc0000000 -options AT91C_MASTER_CLOCK=((12000000*133)/12) device at91_board_qila9g20 diff --git a/sys/arm/at91/std.sam9g20ek b/sys/arm/at91/std.sam9g20ek index c5509c5ced6..f600d9ce94f 100644 --- a/sys/arm/at91/std.sam9g20ek +++ b/sys/arm/at91/std.sam9g20ek @@ -7,9 +7,4 @@ makeoptions KERNVIRTADDR=0xc0000000 options KERNPHYSADDR=0x20000000 options KERNVIRTADDR=0xc0000000 -#SAM9G20 w/ 18.432 Mhz Clock -#options AT91C_MASTER_CLOCK=((18432000*43)/6) -#SAM9260 w/ 18.432 Mhz Clock -#options AT91C_MASTER_CLOCK=((18432000*97)/18) - device at91_board_sam9g20ek