Date: Sun, 30 Nov 2008 22:33:03 +0000 (UTC) From: Stanislav Sedov <stas@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r185491 - in head/sys: arm/at91 conf Message-ID: <200811302233.mAUMX3UZ003941@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: stas Date: Sun Nov 30 22:33:03 2008 New Revision: 185491 URL: http://svn.freebsd.org/changeset/base/185491 Log: - Obtain main clock frequency dynamically based on CKGR_MCFR register contents. - It is possible to override the dynamic configuration by using AT91C_MAIN_CLOCK option in kernel config. PR: arm/128961 (based on) Submitted by: Bjorn Konig <bkoenig@alpha-tierchen.de> Reviewed by: imp Approved by: kib (mentor, implicit) Modified: head/sys/arm/at91/at91_pmc.c head/sys/conf/options.arm Modified: head/sys/arm/at91/at91_pmc.c ============================================================================== --- head/sys/arm/at91/at91_pmc.c Sun Nov 30 21:59:44 2008 (r185490) +++ head/sys/arm/at91/at91_pmc.c Sun Nov 30 22:33:03 2008 (r185491) @@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> +#include <sys/limits.h> #include <sys/module.h> #include <sys/time.h> #include <sys/bus.h> @@ -54,7 +55,7 @@ static struct at91_pmc_softc { bus_space_handle_t sc_sh; struct resource *mem_res; /* Memory resource */ device_t dev; - int main_clock_hz; + unsigned int main_clock_hz; uint32_t pllb_init; } *pmc_softc; @@ -145,6 +146,18 @@ static struct at91_pmc_clock *const cloc &ohci_clk }; +#if !defined(AT91C_MAIN_CLOCK) +static const unsigned int at91_mainf_tbl[] = { + 3000000, 3276800, 3686400, 3840000, 4000000, + 4433619, 4915200, 5000000, 5242880, 6000000, + 6144000, 6400000, 6553600, 7159090, 7372800, + 7864320, 8000000, 9830400, 10000000, 11059200, + 12000000, 12288000, 13560000, 14318180, 14745600, + 16000000, 17344700, 18432000, 20000000 +}; +#define MAINF_TBL_LEN (sizeof(at91_mainf_tbl) / sizeof(*at91_mainf_tbl)) +#endif + static inline uint32_t RD4(struct at91_pmc_softc *sc, bus_size_t off) { @@ -301,7 +314,7 @@ fail: } static void -at91_pmc_init_clock(struct at91_pmc_softc *sc, int main_clock) +at91_pmc_init_clock(struct at91_pmc_softc *sc, unsigned int main_clock) { uint32_t mckr; int freq; @@ -384,21 +397,52 @@ at91_pmc_probe(device_t dev) return (0); } +#if !defined(AT91C_MAIN_CLOCK) +static unsigned int +at91_pmc_sense_mainf(struct at91_pmc_softc *sc) +{ + unsigned int ckgr_val; + unsigned int diff, matchdiff; + int i, match; + + ckgr_val = (RD4(sc, CKGR_MCFR) & CKGR_MCFR_MAINF_MASK) << 11; + + /* + * Try to find the standard frequency that match best. + */ + match = 0; + matchdiff = abs(ckgr_val - at91_mainf_tbl[0]); + for (i = 1; i < MAINF_TBL_LEN; i++) { + diff = abs(ckgr_val - at91_mainf_tbl[i]); + if (diff < matchdiff) { + match = i; + matchdiff = diff; + } + } + return (at91_mainf_tbl[match]); +} +#endif + static int at91_pmc_attach(device_t dev) { + unsigned int mainf; int err; pmc_softc = device_get_softc(dev); pmc_softc->dev = dev; if ((err = at91_pmc_activate(dev)) != 0) return err; -#if defined(AT91_TSC) | defined (AT91_BWCT) - at91_pmc_init_clock(pmc_softc, 16000000); + + /* + * Configure main clock frequency. + */ +#if !defined(AT91C_MAIN_CLOCK) + mainf = at91_pmc_sense_mainf(pmc_softc); #else - at91_pmc_init_clock(pmc_softc, 10000000); + mainf = AT91C_MAIN_CLOCK; #endif - + at91_pmc_init_clock(pmc_softc, mainf); return (0); } Modified: head/sys/conf/options.arm ============================================================================== --- head/sys/conf/options.arm Sun Nov 30 21:59:44 2008 (r185490) +++ head/sys/conf/options.arm Sun Nov 30 22:33:03 2008 (r185491) @@ -5,6 +5,7 @@ ARMFPE opt_global.h ARM_KERN_DIRECTMAP opt_vm.h ARM_USE_SMALL_ALLOC opt_global.h AT91C_MASTER_CLOCK opt_global.h +AT91C_MAIN_CLOCK opt_at91.h COUNTS_PER_SEC opt_timer.h CPU_SA1100 opt_global.h CPU_SA1110 opt_global.h
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200811302233.mAUMX3UZ003941>