All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Randy.Dunlap" <randy.dunlap@oracle.com>
To: Om Narasimhan <om.turyx@gmail.com>
Cc: linux-kernel@vger.kernel.org, omanakuttan.potty@sun.com,
	om.nara@gmail.com
Subject: Re: HPET : Adding Legacy Route Replacement option (2nd try)
Date: Tue, 24 Oct 2006 09:37:51 -0700	[thread overview]
Message-ID: <453E415F.30308@oracle.com> (raw)
In-Reply-To: <200610232319.23378.om.turyx@gmail.com>

Om Narasimhan wrote:
> Hi,
> My last mail with patch seems to be messed up. So resending the patch after
> incorporating randy's comments.
> Applies cleanly to 2.6.19-rc2

Yes.  Mostly  :)
Warning: trailing whitespace in line 685 of arch/i386/kernel/acpi/boot.c
Warning: trailing whitespace in lines 304,313,324,332,333 of Documentation/hpet.txt

Thanks for adding the externs to the hpet.h. file.

I didn't see this updated patch on lkml.  Was it dropped by the vger mail server?

You should probably cc: some of the HPET maintainers (search for "HPET"
in the MAINTAINERS file).

The kernel-parameters.txt still needs a little fixup.  See comments below.


> Signed-Off-by : Om Narasimhan <om.turyx@gmail.com>
> 
>  Documentation/hpet.txt              |   56 +++++++++++++++++++++++++++++++++++
>  Documentation/kernel-parameters.txt |    2 +
>  arch/i386/kernel/acpi/boot.c        |   18 +++++++++++
>  arch/i386/kernel/time_hpet.c        |    3 +-
>  arch/x86_64/kernel/time.c           |   16 +++++++---
>  include/asm-x86_64/hpet.h           |    1 +
>  include/linux/acpi.h                |    1 +
>  include/linux/hpet.h                |    7 ++++
>  8 files changed, 98 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/hpet.txt b/Documentation/hpet.txt
> index b7a3dc3..b9daf0d 100644
> --- a/Documentation/hpet.txt
> +++ b/Documentation/hpet.txt
> @@ -298,3 +298,59 @@ members of the hpet_task structure befor
>  hpet_control simply vectors to the hpet_ioctl routine and has the same
>  commands and respective arguments as the user API.  hpet_unregister
>  is used to terminate usage of the HPET timer reserved by hpet_register.
> +
> +		HPET Legacy Replacement Route option (hpet_lrr)
> +
> +HPET is capable of replacing the IRQ0 (connected INT0 PIN) routing for 
> +timer interrupt. The capability register (at offset 0 of HPET
> +base address) has a bit specifying if HPET chip is capbale of doing
> +this. OS can read the bit either from HW or ACPI table. (HPET ACPI
> +description table -> Event Timer block -> bit 15, page 30 of HPET
> +spec).  Ideally (I think so!) BIOS should set the ACPI table than letting
> +the OS read H/W, which gives the BIOS a way to configure either legacy
> +or Legacy replacement modes.
> +
> +Typically the motherboard has BIOS configured / hardwired IRQ0 to INT0 
> +(pin of APIC) connection. Linux assumes IRQ0 connected to INT0 unless it is
> +supplied using an override parameter in the MPTable. Some NVidia chipsets /
> +BIOS initialization code had configured to override IRQ0 -> INT0 connection
> +and later a parameter was introduce (acpi_skip_timer_override) to get IRQ0 ->
> +INT0 connection right.
> +
> +But a number of bioses (both phoenix and AMI) are not working as
> +expected. (I have an AMI BIOS which sets ACPI table bit 15 to 0 and then
> +connect IRQ0 -> INT2 internally, Another bios I have sets the ACPI table bit
> +15 to 0, but does not connect IRQ0 -> INT2. Both would result in a hang in
> +calibrate_delay() since there would not be any timer interrupts So I have 
> +provided a command line parameter which overrides
> +the BIOS ACPI entry. So, irrespctive of the BIOS' HPET ACPI Descriptor
> +table settings, if the parameter hpet_lrr=[0,1] is specified, it takes
> +precedence.
> +
> +* When to use this parameter?
> +
> +Some latest versions CK-804 (e.g),(Actually the code initializes the 
> +CK804 in the BIOS), would correctly set the HPET such that there would not 
> +be any interrupts on INT0. Linux does not handle this situation very well
> +because in linux, if HW is LRR capable, it is enabled from the OS. Still the
> +timer interrupt handler is setup for IRQ0. Under this situation, you can force
> +the parameter hpet_lrr=1, so that IRQ2 is timer interrupts.
> +
> +[root@mophia ~]# cat /proc/interrupts | grep 2:
> + 2:        163          0          0          0          1          7
> +207     955341    IO-APIC-edge  timer
> +
> +[root@mophia ~]# uptime
> + 22:52:38 up 15 min,  2 users,  load average: 0.00, 0.01, 0.02
> +
> +[root@mophia ~]# dmesg | grep -i MP-BIOS
> +
> +For 15 mts (900 sec), around 95k interrupts on timer looks kinda fine.
> +
> +* Known Bugs:
> +I have tested it only with Nvidia CK-804. There seem to be some kind of timing
> +issue between enabling the HPET with LRR set and start of tinerrupts. As a
> +result of which, calibrate_delay() hangs because there are no interrupts. If
> +you run into such a case, pass lpj=<bogomips * 500> as a work around. i.e, if
> +your bogomips is 5000, pass lpj=2500000
> +
> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
> index ff571f9..3066b74 100644
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -365,6 +365,8 @@ and is between 256 and 4096 characters. 
>  
>  	hpet=		[IA-32,HPET] option to disable HPET and use PIT.
>  			Format: disable
> +	hpet_lrr=	[IA32,X86_64,HPET] Option to enable/disable the HPET Legacy
> +			replacement route.

a.  Don't go past column 80 (as in "Legacy").
b.  Blank line before hpet_lrr= line.
c.  Add another line:
		Format: { 1 | 0 }

>  	cm206=		[HW,CD]
>  			Format: { auto | [<io>,][<irq>] }
> diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
> index 92f79cd..2c8a950 100644
> --- a/arch/i386/kernel/acpi/boot.c
> +++ b/arch/i386/kernel/acpi/boot.c
> @@ -82,6 +82,17 @@ EXPORT_SYMBOL(acpi_strict);
>  acpi_interrupt_flags acpi_sci_flags __initdata;
>  int acpi_sci_override_gsi __initdata;
>  int acpi_skip_timer_override __initdata;
> +/* HPET Legacy routing replacement option passed through ACPI Table */
> +int acpi_hpet_lrr;
> +/* cmdline opt. for faulty bioses not setting ACPI HPET entry right */
> +int hpet_lrr_force;
> +
> +static int hpet_lrr_setup (char *str)
> +{
> +	get_option(&str, &hpet_lrr_force);
> +	return 1;
> +}
> +__setup ("hpet_lrr=", hpet_lrr_setup);
>  
>  #ifdef CONFIG_X86_LOCAL_APIC
>  static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
> @@ -669,6 +680,13 @@ #define HPET_RESOURCE_NAME_SIZE 9
>  			 "HPET %u", hpet_tbl->number);
>  		hpet_res->end = (1 * 1024) - 1;
>  	}
> +	acpi_hpet_lrr = (hpet_tbl->id & ACPI_HPET_LRR_CAP) ? 1 : 0;
> +	/* Print a message about the bios HPET ACPI Desc Table passed.
> +	 * LRR bit should not be set in the table unless IRQ0->INT2 is 
> +	 * connected. But BIOS may be faulty ...
> +	 */
> +	printk(KERN_INFO PREFIX "HPET id: %#x. ACPI LRR bit %s SET\n",
> +			hpet_tbl->id, acpi_hpet_lrr ? "": "NOT");
>  
>  #ifdef	CONFIG_X86_64
>  	vxtime.hpet_address = hpet_tbl->addr.addrl |
> diff --git a/arch/i386/kernel/time_hpet.c b/arch/i386/kernel/time_hpet.c
> index 1a2a979..01b2f67 100644
> --- a/arch/i386/kernel/time_hpet.c
> +++ b/arch/i386/kernel/time_hpet.c
> @@ -94,7 +94,8 @@ static int hpet_timer_stop_set_go(unsign
>   	 * Go!
>   	 */
>  	cfg = hpet_readl(HPET_CFG);
> -	if (hpet_use_timer)
> +	/* Ideally the following should be &&(acpi_hpet_lrr || hpet_lrr_force) */
> +	if (hpet_use_timer && hpet_lrr_force)
>  		cfg |= HPET_CFG_LEGACY;
>  	cfg |= HPET_CFG_ENABLE;
>  	hpet_writel(cfg, HPET_CFG);
> diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
> index 1ba5a44..0f5d990 100644
> --- a/arch/x86_64/kernel/time.c
> +++ b/arch/x86_64/kernel/time.c
> @@ -46,9 +46,6 @@ #include <asm/apic.h>
>  #ifdef CONFIG_CPU_FREQ
>  static void cpufreq_delayed_get(void);
>  #endif
> -extern void i8254_timer_resume(void);
> -extern int using_apic_timer;
> -
>  static char *timename = NULL;
>  
>  DEFINE_SPINLOCK(rtc_lock);
> @@ -783,7 +780,10 @@ static int hpet_timer_stop_set_go(unsign
>  		    HPET_TN_32BIT, HPET_T0_CFG);
>  		hpet_writel(hpet_tick, HPET_T0_CMP); /* next interrupt */
>  		hpet_writel(hpet_tick, HPET_T0_CMP); /* period */
> -		cfg |= HPET_CFG_LEGACY;
> +		/* Ideal value (acpi_hpet_lrr || hpet_lrr_force) */
> +		if (hpet_lrr_force)
> +			cfg |= HPET_CFG_LEGACY;
> +
>  	}
>  /*
>   * Go!
> @@ -887,6 +887,7 @@ time_cpu_notifier(struct notifier_block 
>  
>  void __init time_init(void)
>  {
> +	int timer_irq = 0;
>  	if (nohpet)
>  		vxtime.hpet_address = 0;
>  
> @@ -906,6 +907,10 @@ void __init time_init(void)
>  	  	tick_nsec = TICK_NSEC_HPET;
>  		cpu_khz = hpet_calibrate_tsc();
>  		timename = "HPET";
> +		/* Ideal value is (acpi_hpet_lrr || hpet_lrr_force) */
> +		if (hpet_lrr_force)
> +			timer_irq = HPET_TIMER_LRR_IRQ;
> +
>  #ifdef CONFIG_X86_PM_TIMER
>  	} else if (pmtmr_ioport && !vxtime.hpet_address) {
>  		vxtime_hz = PM_TIMER_FREQUENCY;
> @@ -924,7 +929,8 @@ #endif
>  	vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz;
>  	vxtime.last_tsc = get_cycles_sync();
>  	set_cyc2ns_scale(cpu_khz);
> -	setup_irq(0, &irq0);
> +	printk(KERN_WARNING PREFIX "Registering Timer IRQ = %d\n", timer_irq);
> +	setup_irq(timer_irq, &irq0);
>  	hotcpu_notifier(time_cpu_notifier, 0);
>  	time_cpu_notifier(NULL, CPU_ONLINE, (void *)(long)smp_processor_id());
>  
> diff --git a/include/asm-x86_64/hpet.h b/include/asm-x86_64/hpet.h
> index b390984..2d18b39 100644
> --- a/include/asm-x86_64/hpet.h
> +++ b/include/asm-x86_64/hpet.h
> @@ -37,6 +37,7 @@ #define HPET_CFG_ENABLE	0x001
>  #define HPET_CFG_LEGACY	0x002
>  #define	HPET_LEGACY_8254	2
>  #define	HPET_LEGACY_RTC		8
> +#define	HPET_TIMER_LRR_IRQ	2
>  
>  #define HPET_TN_LEVEL		0x0002
>  #define HPET_TN_ENABLE		0x0004
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 88b5dfd..aac4a89 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -220,6 +220,7 @@ enum acpi_interrupt_id {
>  };
>  
>  #define	ACPI_SPACE_MEM		0
> +#define	ACPI_HPET_LRR_CAP	0x8000
>  
>  struct acpi_gen_regaddr {
>  	u8  space_id;
> diff --git a/include/linux/hpet.h b/include/linux/hpet.h
> index 707f7cb..6c31473 100644
> --- a/include/linux/hpet.h
> +++ b/include/linux/hpet.h
> @@ -119,6 +119,13 @@ int hpet_register(struct hpet_task *, in
>  int hpet_unregister(struct hpet_task *);
>  int hpet_control(struct hpet_task *, unsigned int, unsigned long);
>  
> +
> +/* these are used by time.c */
> +extern void i8254_timer_resume(void);
> +extern int using_apic_timer;
> +extern int acpi_hpet_lrr;
> +extern int hpet_lrr_force;
> +
>  #endif /* __KERNEL__ */
>  
>  struct hpet_info {


-- 
~Randy

           reply	other threads:[~2006-10-24 16:37 UTC|newest]

Thread overview: expand[flat|nested]  mbox.gz  Atom feed
 [parent not found: <200610232319.23378.om.turyx@gmail.com>]

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=453E415F.30308@oracle.com \
    --to=randy.dunlap@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=om.nara@gmail.com \
    --cc=om.turyx@gmail.com \
    --cc=omanakuttan.potty@sun.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.