From bkoenig@alpha-tierchen.de  Tue Nov 18 12:03:40 2008
Return-Path: <bkoenig@alpha-tierchen.de>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 11F661065670
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 18 Nov 2008 12:03:40 +0000 (UTC)
	(envelope-from bkoenig@alpha-tierchen.de)
Received: from mail.liberty-hosting.de (mail.smartterra.de [195.225.132.203])
	by mx1.freebsd.org (Postfix) with ESMTP id CB7868FC17
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 18 Nov 2008 12:03:39 +0000 (UTC)
	(envelope-from bkoenig@alpha-tierchen.de)
Received: from home.alpha-tierchen.de (port-87-234-81-35.dynamic.qsc.de [87.234.81.35])
	by mail.liberty-hosting.de (Postfix) with ESMTP id 63A4F3E9D1F
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 18 Nov 2008 12:57:17 +0100 (CET)
Received: by home.alpha-tierchen.de (Postfix, from userid 2000)
	id 363CE28A19; Tue, 18 Nov 2008 13:03:35 +0100 (CET)
Message-Id: <20081118120335.363CE28A19@home.alpha-tierchen.de>
Date: Tue, 18 Nov 2008 13:03:35 +0100 (CET)
From: Bjrn Knig <bkoenig@alpha-tierchen.de>
Reply-To: Bjrn Knig <bkoenig@alpha-tierchen.de>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [patch] Detect main clock frequency of AT91 controller.
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         128961
>Category:       arm
>Synopsis:       [patch] Detect main clock frequency of AT91 controller.
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    stas
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue Nov 18 12:10:06 UTC 2008
>Closed-Date:    Sun Nov 30 22:33:42 UTC 2008
>Last-Modified:  Sun Nov 30 22:33:42 UTC 2008
>Originator:     Bjrn Knig
>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:
Responsible-Changed-From-To: freebsd-arm->stas 
Responsible-Changed-By: stas 
Responsible-Changed-When: Tue Nov 18 12:31:17 UTC 2008 
Responsible-Changed-Why:  
I'll take it. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=128961 
State-Changed-From-To: open->closed 
State-Changed-By: stas 
State-Changed-When: Sun Nov 30 22:33:41 UTC 2008 
State-Changed-Why:  
Committed. Thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=128961 
>Unformatted:
