public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: john stultz <johnstul@us.ibm.com>
To: Mikael Pettersson <mikpe@csd.uu.se>
Cc: lkml <linux-kernel@vger.kernel.org>
Subject: Re: [RFC] bt_ioremap question / cyclone-timer_A1 patch
Date: 09 Jul 2002 19:18:59 -0700	[thread overview]
Message-ID: <1026267539.32190.70.camel@cog> (raw)
In-Reply-To: <200207091103.NAA05525@harpo.it.uu.se>

[-- Attachment #1: Type: text/plain, Size: 1993 bytes --]

On Tue, 2002-07-09 at 04:03, Mikael Pettersson wrote:
> On 08 Jul 2002 19:36:23 -0700, john stultz wrote:
> >Mainly I'm concerned about my usage of bt_ioremap. Early in the boot
> >processes, I need to map in a couple of chipset registers and poke
> >values into them.
> 
> How early? If this is just to get gettimeofday() working, can't it
> wait until the regular initcalls are done?

I guess I might be able to pull it out and do the initialization
somewhere else, but really time_init() seems like the best spot.

> > However one of the registers needs to be kept mapped
> >for the life of the system (look for "cyclone_timer" below). I couldn't
> >find any documentation on whether memory mapped with bt_ioremap can be
> >held across mem_init(). It seems to "just work" but I wanted to find out
> >if I really should be re-mapping the register w/ ioremap once it becomes
> >available. 
> 
> If you look in include/asm-i386/fixmap.h you'll see that the BT ioremap
> pages are temporary, and they do disappear once mem_init() [or whatever]
> is done [pgtable.h sets VMALLOC_END to just below FIXADDR_START, which
> protects the permanent fixmaps but intensionally not the temporary ones].
> If it seemed to work for you then that's just luck, or perhaps it does
> work in highmem kernels?
> 
> For things that must be mapped very early and continue to be mapped as
> long as the kernel is up, you need a permanent fixmap. fixmap.h has a
> number of permanent fixmaps defined #ifdef CONFIG_* and you can easily
> add your own there, under #ifdef CONFIG_X86_IBMEXA.

Thank you for the pointer. I gave it a whirl (see attached) and it seems
to work fine! If anyone notices that I'm still just horribly lucky and
I've done everything wrong, please let me know. :)

Thanks again for the feedback and suggestions!
-john

ps: Again, if anyone feels so inclined to try this patch, do note that
it depends on my tsc-disable patch to apply cleanly. Send me a note and
I'll fwd you my latest version.

[-- Attachment #2: linux-2.4.19-rc1_cyclone-timer_A2.patch --]
[-- Type: text/x-patch, Size: 5057 bytes --]

diff -Nru a/Documentation/Configure.help b/Documentation/Configure.help
--- a/Documentation/Configure.help	Tue Jul  9 18:49:52 2002
+++ b/Documentation/Configure.help	Tue Jul  9 18:49:52 2002
@@ -257,6 +257,11 @@
   You will need a new lynxer.elf file to flash your firmware with - send
   email to Martin.Bligh@us.ibm.com
 
+IBM Enterprise X-Architecture support
+CONFIG_X86_IBMEXA
+  This option makes use of a performance counter on the Cyclone chipset 
+  for calculating do_gettimeofday, greatly improving its performance. 
+
 IO-APIC support on uniprocessors
 CONFIG_X86_UP_IOAPIC
   An IO-APIC (I/O Advanced Programmable Interrupt Controller) is an
diff -Nru a/arch/i386/config.in b/arch/i386/config.in
--- a/arch/i386/config.in	Tue Jul  9 18:49:52 2002
+++ b/arch/i386/config.in	Tue Jul  9 18:49:52 2002
@@ -201,6 +201,7 @@
 	bool 'Multi-node NUMA system support' CONFIG_X86_NUMA
 	if [ "$CONFIG_X86_NUMA" = "y" ]; then
 		bool 'Multiquad (IBM/Sequent) NUMAQ support' CONFIG_MULTIQUAD
+		bool 'IBM Enterprise X-Architecture support' CONFIG_X86_IBMEXA
 	fi
 fi
 
diff -Nru a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
--- a/arch/i386/kernel/time.c	Tue Jul  9 18:49:52 2002
+++ b/arch/i386/kernel/time.c	Tue Jul  9 18:49:52 2002
@@ -253,6 +253,92 @@
 
 static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
 
+
+
+#ifdef CONFIG_X86_IBMEXA
+#define CYCLONE_CBAR_ADDR 0xFEB00CD0
+#define CYCLONE_PMCC_OFFSET 0x51A0
+#define CYCLONE_MPMC_OFFSET 0x51D0
+#define CYCLONE_MPCS_OFFSET 0x51A8
+#define CYCLONE_TIMER_FREQ 100000000
+static u32* cyclone_timer;	/*Cyclone MPMC0 register*/
+static void init_cyclone_clock(void)
+{
+	u32* reg;	
+	u32 base;	/*saved cyclone base address*/
+	u32 pageaddr; /*page that contains cyclone_timer register*/
+	u32 offset;	/*offset from pageaddr to cyclone_timer register*/
+
+	/*find base address*/
+	reg = bt_ioremap(CYCLONE_CBAR_ADDR, 4);
+	if(!reg) return;
+	base = *reg;	
+	bt_iounmap(reg, 4);
+
+	/*setup PMCC*/
+	reg = bt_ioremap(base + CYCLONE_PMCC_OFFSET, 8);
+	if(!reg) return;
+	reg[0] = 0x00000001;
+	bt_iounmap(reg, 8);
+
+	/*setup MPCS*/
+	reg = bt_ioremap(base + CYCLONE_MPCS_OFFSET, 8);
+	if(!reg) return;
+	reg[0] = 0x00000001;
+	bt_iounmap(reg, 8);
+
+	/*map in cyclone_timer w/ set_fixmap*/
+	pageaddr = (base + CYCLONE_MPMC_OFFSET)&PAGE_MASK;
+	offset = (base + CYCLONE_MPMC_OFFSET)&(~PAGE_MASK);
+
+	set_fixmap(FIX_CYCLONE_TIMER, pageaddr);
+	
+	cyclone_timer = fix_to_virt(FIX_CYCLONE_TIMER) + offset;
+}
+
+static u32 last_cyclone_timer;
+
+static inline void mark_timeoffset_cyclone(void)
+{
+	int count;
+	
+	/*quickly read the cyclone timer*/
+	if(cyclone_timer)
+		last_cyclone_timer = cyclone_timer[0];
+	
+	/*calculate delay_at_last_interrupt*/
+	spin_lock(&i8253_lock);
+	outb_p(0x00, 0x43);     /* latch the count ASAP */
+
+	count = inb_p(0x40);    /* read the latched count */
+	count |= inb(0x40) << 8;
+	spin_unlock(&i8253_lock);
+
+	count = ((LATCH-1) - count) * TICK_SIZE;
+	delay_at_last_interrupt = (count + LATCH/2) / LATCH;
+}
+
+static unsigned long do_gettimeoffset_cyclone(void)
+{
+	u32 offset;
+
+	if(!cyclone_timer)
+		return delay_at_last_interrupt;
+
+	/* Read the cyclone timer */
+	offset = cyclone_timer[0];
+		
+	/* .. relative to previous jiffy*/
+	offset = offset - last_cyclone_timer;
+
+	/*convert cyclone ticks to microseconds*/	
+	offset = offset*(1000000/CYCLONE_TIMER_FREQ); 
+
+	/* our adjusted time offset in microseconds */
+	return delay_at_last_interrupt + offset;
+}
+#endif /*CONFIG_X86_IBMEXA*/
+
 #else
 
 #define do_gettimeoffset()	do_fast_gettimeoffset()
@@ -459,6 +545,7 @@
 }
 
 static int use_tsc;
+static int use_cyclone =1; /*XXX should be autodetected*/
 
 /*
  * This is the same as the above, except we _also_ save the current
@@ -506,6 +593,10 @@
 		count = ((LATCH-1) - count) * TICK_SIZE;
 		delay_at_last_interrupt = (count + LATCH/2) / LATCH;
 	}
+#ifdef CONFIG_X86_IBMEXA
+ 	if(use_cyclone)
+		mark_timeoffset_cyclone();
+#endif /*CONFIG_X86_IBMEXA*/
  
 	do_timer_interrupt(irq, NULL, regs);
 
@@ -695,6 +786,14 @@
 			}
 		}
 	}
+
+#ifdef CONFIG_X86_IBMEXA
+ 	if((!use_tsc) && use_cyclone){
+		printk("IBM EXA: Starting Cyclone Clock.\n");
+		do_gettimeoffset = do_gettimeoffset_cyclone;
+		init_cyclone_clock();
+	}
+#endif /*CONFIG_X86_IBMEXA*/
 
 #ifdef CONFIG_VISWS
 	printk("Starting Cobalt Timer system clock\n");
diff -Nru a/include/asm-i386/fixmap.h b/include/asm-i386/fixmap.h
--- a/include/asm-i386/fixmap.h	Tue Jul  9 18:49:52 2002
+++ b/include/asm-i386/fixmap.h	Tue Jul  9 18:49:52 2002
@@ -61,6 +61,9 @@
 	FIX_LI_PCIA,	/* Lithium PCI Bridge A */
 	FIX_LI_PCIB,	/* Lithium PCI Bridge B */
 #endif
+#ifdef CONFIG_X86_IBMEXA
+	FIX_CYCLONE_TIMER, /*cyclone timer register*/
+#endif 
 #ifdef CONFIG_HIGHMEM
 	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
 	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,

  reply	other threads:[~2002-07-10  2:26 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-07-09 11:03 [RFC] bt_ioremap question / cyclone-timer_A1 patch Mikael Pettersson
2002-07-10  2:18 ` john stultz [this message]
  -- strict thread matches above, loose matches on Subject: below --
2002-07-09  2:36 john stultz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1026267539.32190.70.camel@cog \
    --to=johnstul@us.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mikpe@csd.uu.se \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox