Date: Tue, 18 Nov 2008 13:03:35 +0100 (CET) From: Björn König <bkoenig@alpha-tierchen.de> To: FreeBSD-gnats-submit@FreeBSD.org Subject: arm/128961: [patch] Detect main clock frequency of AT91 controller. Message-ID: <20081118120335.363CE28A19@home.alpha-tierchen.de> Resent-Message-ID: <200811181210.mAICA6sl043677@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 128961 >Category: arm >Synopsis: [patch] Detect main clock frequency of AT91 controller. >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-arm >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Tue Nov 18 12:10:06 UTC 2008 >Closed-Date: >Last-Modified: >Originator: Björn König >Release: >Organization: >Environment: >Description: The PMC of the AT91 controller provides a register where you can find an estimation of the main clock frequency. The patch below uses this register to sense the frequency of the oscillating crystal. Alternatively you can set the frequency explicitely in the kernel configuration file with options AT91C_MAIN_CLOCK=16000000 for example. >How-To-Repeat: >Fix: --- src-sys-arm-at91.diff begins here --- diff --git src/sys/arm/at91/at91_pmc.c src/sys/arm/at91/at91_pmc.c index 061e2bc..c2a97ab 100644 --- src/sys/arm/at91/at91_pmc.c +++ src/sys/arm/at91/at91_pmc.c @@ -144,6 +144,17 @@ static struct at91_pmc_clock *const clock_list[] = { &ohci_clk }; +#if !defined(AT91C_MAIN_CLOCK) +static const 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, 0 +}; +#endif + static inline uint32_t RD4(struct at91_pmc_softc *sc, bus_size_t off) { @@ -383,6 +394,26 @@ at91_pmc_probe(device_t dev) return (0); } +#if !defined(AT91C_MAIN_CLOCK) +static int +at91_pmc_sense_mainf(struct at91_pmc_softc *sc) +{ + int ret = 0; + const int *p; + int mainf = (RD4(sc, CKGR_MCFR) & CKGR_MCFR_MAINF_MASK) << 11; + unsigned diff = (unsigned)-1; + + for (p = at91_mainf_tbl; *p != 0; p++) + if (abs(mainf - *p) < diff) + { + diff = abs(mainf - *p); + ret = *p; + } + + return (ret); +} +#endif + static int at91_pmc_attach(device_t dev) { @@ -392,10 +423,10 @@ at91_pmc_attach(device_t 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); +#if defined(AT91C_MAIN_CLOCK) + at91_pmc_init_clock(pmc_softc, AT91C_MAIN_CLOCK); #else - at91_pmc_init_clock(pmc_softc, 10000000); + at91_pmc_init_clock(pmc_softc, at91_pmc_sense_mainf(pmc_softc)); #endif return (0); diff --git src/sys/conf/options.arm src/sys/conf/options.arm index 66b2575..56791a8 100644 --- src/sys/conf/options.arm +++ src/sys/conf/options.arm @@ -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 --- src-sys-arm-at91.diff ends here --- >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20081118120335.363CE28A19>