linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] pata_hpt3x2n: Clean up DPLL stuff
@ 2007-09-26 22:04 Alan Cox
  2007-09-29  6:16 ` Jeff Garzik
  2007-10-01 13:12 ` Sergei Shtylyov
  0 siblings, 2 replies; 5+ messages in thread
From: Alan Cox @ 2007-09-26 22:04 UTC (permalink / raw)
  To: akpm, linux-ide

Nobody commented when I asked for review earlier so it must be ok  8)

Lets stick it in -mm to be sure

Signed-off-by: Alan Cox <alan@redhat.com>

diff -u --new-file --exclude-from /usr/src/exclude --recursive linux.vanilla-2.6.23rc8-mm1/drivers/ata/pata_hpt37x.c linux-2.6.23rc8-mm1/drivers/ata/pata_hpt37x.c
--- linux.vanilla-2.6.23rc8-mm1/drivers/ata/pata_hpt37x.c	2007-09-26 16:46:48.000000000 +0100
+++ linux-2.6.23rc8-mm1/drivers/ata/pata_hpt37x.c	2007-09-18 16:44:32.000000000 +0100
@@ -1,5 +1,5 @@
 /*
- * Libata driver for the highpoint 37x and 30x UDMA66 ATA controllers.
+ * Libata driver for the highpoint 37x and 30x UDMA ATA controllers.
  *
  * This driver is heavily based upon:
  *
@@ -844,6 +844,46 @@
 	/* Never went stable */
 	return 0;
 }
+
+static void *hpt_tune_function(struct pci_dev *dev, int dpll, int clock_slot)
+{
+	static const int MHz[4] = { 33, 40, 50, 66 };
+	/*
+	 *	For non UDMA133 capable devices we should
+	 *	use a 50MHz DPLL by choice
+	 */
+	unsigned int f_low, f_high;
+	int adjust;
+
+	f_low = (MHz[clock_slot] * 48) / MHz[dpll];
+	f_high = f_low + 2;
+	if (clock_slot > 1)
+		f_high += 2;
+	/* Select the DPLL clock. */
+	pci_write_config_byte(dev, 0x5b, 0x21);
+	pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100);
+
+	for(adjust = 0; adjust < 8; adjust++) {
+		if (hpt37x_calibrate_dpll(dev))
+			break;
+		/* See if it'll settle at a fractionally different clock */
+		if (adjust & 1)
+			f_low -= adjust >> 1;
+		else
+			f_high += adjust >> 1;
+		pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100);
+	}
+	if (adjust == 8) {
+		printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n");
+		return NULL;
+	}
+	printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[dpll]);
+	if (dpll == 3)
+		return hpt37x_timings_66;
+	else
+		return hpt37x_timings_50;
+}
+
 /**
  *	hpt37x_init_one		-	Initialise an HPT37X/302
  *	@dev: PCI device
@@ -944,7 +984,7 @@
 	u8 mcr1;
 	u32 freq;
 	int prefer_dpll = 1;
-
+	int hpt374alt = 0;
 	unsigned long iobase = pci_resource_start(dev, 4);
 
 	const struct hpt_chip *chip_table;
@@ -1046,16 +1086,28 @@
 	if (chip_table == &hpt372a)
 		outb(0x0e, iobase + 0x9c);
 
+	/*
+	 * PLL must be done once
+	 */
+	 
+	if (chip_table == &hpt374 && PCI_FUNC(dev->devfn) & 1) {
+		/* The HPT374 secondary devfn is tuned to 50MHz when we find
+		   the primary */
+		port_info = *port;
+		port_info.private_data = hpt37x_timings_50;
+	}	
 	/* Some devices do not let this value be accessed via PCI space
 	   according to the old driver */
-
 	freq = inl(iobase + 0x90);
 	if ((freq >> 12) != 0xABCDE) {
 		int i;
 		u8 sr;
 		u32 total = 0;
-
+		
 		printk(KERN_WARNING "pata_hpt37x: BIOS has not set timing clocks.\n");
+		if (hpt374alt == 1)
+			printk(KERN_ERR "pata_hpt37x: No saved frequency on primary function.\n");
+
 
 		/* This is the process the HPT371 BIOS is reported to use */
 		for(i = 0; i < 128; i++) {
@@ -1074,48 +1126,19 @@
 
 	clock_slot = hpt37x_clock_slot(freq, chip_table->base);
 	if (chip_table->clocks[clock_slot] == NULL || prefer_dpll) {
-		/*
-		 *	We need to try PLL mode instead
-		 *
-		 *	For non UDMA133 capable devices we should
-		 *	use a 50MHz DPLL by choice
-		 */
-		unsigned int f_low, f_high;
-		int dpll, adjust;
-
 		/* Compute DPLL */
-		dpll = (port->udma_mask & 0xC0) ? 3 : 2;
-
-		f_low = (MHz[clock_slot] * 48) / MHz[dpll];
-		f_high = f_low + 2;
-		if (clock_slot > 1)
-			f_high += 2;
-
-		/* Select the DPLL clock. */
-		pci_write_config_byte(dev, 0x5b, 0x21);
-		pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100);
-
-		for(adjust = 0; adjust < 8; adjust++) {
-			if (hpt37x_calibrate_dpll(dev))
-				break;
-			/* See if it'll settle at a fractionally different clock */
-			if (adjust & 1)
-				f_low -= adjust >> 1;
-			else
-				f_high += adjust >> 1;
-			pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100);
-		}
-		if (adjust == 8) {
-			printk(KERN_ERR "pata_hpt37x: DPLL did not stabilize!\n");
-			return -ENODEV;
+		int dpll = 2;
+		if (port->udma_mask & 0xC0)
+  			dpll = 3;
+		private_data = hpt_tune_function(dev, dpll, clock_slot);
+		/* For the HPT374 tune both channels together from fn 0 */
+		if (chip_table == &hpt374 && !(PCI_FUNC(dev->devfn) & 1)) {
+			struct pci_dev *pair = pci_get_slot(dev->bus, dev->devfn + 1);
+			if (pair != NULL) {
+				hpt_tune_function(pair, dpll, clock_slot);
+				pci_dev_put(pair);
+			}
 		}
-		if (dpll == 3)
-			private_data = (void *)hpt37x_timings_66;
-		else
-			private_data = (void *)hpt37x_timings_50;
-
-		printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using %dMHz DPLL.\n",
-		       MHz[clock_slot], MHz[dpll]);
 	} else {
 		private_data = (void *)chip_table->clocks[clock_slot];
 		/*

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] pata_hpt3x2n: Clean up DPLL stuff
  2007-09-26 22:04 [PATCH] pata_hpt3x2n: Clean up DPLL stuff Alan Cox
@ 2007-09-29  6:16 ` Jeff Garzik
  2007-10-01 13:12 ` Sergei Shtylyov
  1 sibling, 0 replies; 5+ messages in thread
From: Jeff Garzik @ 2007-09-29  6:16 UTC (permalink / raw)
  To: Alan Cox; +Cc: akpm, linux-ide

Alan Cox wrote:
> Nobody commented when I asked for review earlier so it must be ok  8)
> 
> Lets stick it in -mm to be sure
> 
> Signed-off-by: Alan Cox <alan@redhat.com>

applied to libata-dev.git#for-testing



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] pata_hpt3x2n: Clean up DPLL stuff
  2007-09-26 22:04 [PATCH] pata_hpt3x2n: Clean up DPLL stuff Alan Cox
  2007-09-29  6:16 ` Jeff Garzik
@ 2007-10-01 13:12 ` Sergei Shtylyov
  2007-10-02 14:16   ` Alan Cox
  1 sibling, 1 reply; 5+ messages in thread
From: Sergei Shtylyov @ 2007-10-01 13:12 UTC (permalink / raw)
  To: Alan Cox; +Cc: akpm, linux-ide

Hello.

Alan Cox wrote:

> Nobody commented when I asked for review earlier so it must be ok  8)

    It's not that I've seen this before

 > so it must be ok  8)

    Not by me at least, so let me NAK it. 8-)

> Lets stick it in -mm to be sure

    Now let's unstick it. :-)

> Signed-off-by: Alan Cox <alan@redhat.com>
> 
> diff -u --new-file --exclude-from /usr/src/exclude --recursive linux.vanilla-2.6.23rc8-mm1/drivers/ata/pata_hpt37x.c linux-2.6.23rc8-mm1/drivers/ata/pata_hpt37x.c
> --- linux.vanilla-2.6.23rc8-mm1/drivers/ata/pata_hpt37x.c	2007-09-26 16:46:48.000000000 +0100
> +++ linux-2.6.23rc8-mm1/drivers/ata/pata_hpt37x.c	2007-09-18 16:44:32.000000000 +0100

    Wait, I thought you're patching pata_hpt3x2n!

> @@ -844,6 +844,46 @@
>  	/* Never went stable */
>  	return 0;
>  }
> +
> +static void *hpt_tune_function(struct pci_dev *dev, int dpll, int clock_slot)
> +{
> +	static const int MHz[4] = { 33, 40, 50, 66 };
> +	/*
> +	 *	For non UDMA133 capable devices we should
> +	 *	use a 50MHz DPLL by choice
> +	 */
> +	unsigned int f_low, f_high;
> +	int adjust;
> +
> +	f_low = (MHz[clock_slot] * 48) / MHz[dpll];
> +	f_high = f_low + 2;
> +	if (clock_slot > 1)
> +		f_high += 2;
> +	/* Select the DPLL clock. */
> +	pci_write_config_byte(dev, 0x5b, 0x21);
> +	pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100);

    Could move the f_low/high writes to hpt37x_calibrate_dpll()...

> +	for(adjust = 0; adjust < 8; adjust++) {
> +		if (hpt37x_calibrate_dpll(dev))
> +			break;
> +		/* See if it'll settle at a fractionally different clock */
> +		if (adjust & 1)
> +			f_low -= adjust >> 1;
> +		else
> +			f_high += adjust >> 1;
> +		pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100);
> +	}
> +	if (adjust == 8) {
> +		printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n");

    Deserves KERN_ERR. Wait, I remember to have changed it to KERN_ERR.

> +		return NULL;
> +	}
> +	printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[dpll]);

    That won't do -- it reintroduces the DPLL clock ISO bus clock reporting 
bug (that I've fixed just recently)!

> @@ -944,7 +984,7 @@
>  	u8 mcr1;
>  	u32 freq;
>  	int prefer_dpll = 1;
> -
> +	int hpt374alt = 0;
>  	unsigned long iobase = pci_resource_start(dev, 4);
>  
>  	const struct hpt_chip *chip_table;
> @@ -1046,16 +1086,28 @@
>  	if (chip_table == &hpt372a)
>  		outb(0x0e, iobase + 0x9c);
>  
> +	/*
> +	 * PLL must be done once
> +	 */
> +	 
> +	if (chip_table == &hpt374 && PCI_FUNC(dev->devfn) & 1) {
> +		/* The HPT374 secondary devfn is tuned to 50MHz when we find
> +		   the primary */

    Nah, the reason for that is completely different -- BIOS saves no clock 
data for function 1 but calibrates it for 50 MHz anyway, thus making the 
driver read already distorted f_CNT...
Not actually dangerous as the value yields 33 MHz PCI clock after clamping but 
WTF...

> +		port_info = *port;
> +		port_info.private_data = hpt37x_timings_50;
> +	}

    No, this does not seem correct -- the function 1 should be tuned (for the 
x86 case where there was no BIOS available to tune it beforehand). I don't see 
where the manual tells that the DPLL circuitry is shared. Contrarywise, I'm 
seeing it say on p. 3-22:

2. Each function has its own DPLL module, so you need set DPLL clock on every
    function

>  	/* Some devices do not let this value be accessed via PCI space
>  	   according to the old driver */
> -
>  	freq = inl(iobase + 0x90);
>  	if ((freq >> 12) != 0xABCDE) {
>  		int i;
>  		u8 sr;
>  		u32 total = 0;
> -
> +		
>  		printk(KERN_WARNING "pata_hpt37x: BIOS has not set timing clocks.\n");
> +		if (hpt374alt == 1)
> +			printk(KERN_ERR "pata_hpt37x: No saved frequency on primary function.\n");

    What's so erratic about this? And where hpt374alt is set to 1?

> +		private_data = hpt_tune_function(dev, dpll, clock_slot);
> +		/* For the HPT374 tune both channels together from fn 0 */
> +		if (chip_table == &hpt374 && !(PCI_FUNC(dev->devfn) & 1)) {
> +			struct pci_dev *pair = pci_get_slot(dev->bus, dev->devfn + 1);
> +			if (pair != NULL) {
> +				hpt_tune_function(pair, dpll, clock_slot);
> +				pci_dev_put(pair);
> +			}

    Ah, I see it now: you've decided to tune 2 functions of HPT374 at once...

>  		}
> -		if (dpll == 3)
> -			private_data = (void *)hpt37x_timings_66;
> -		else
> -			private_data = (void *)hpt37x_timings_50;
> -
> -		printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using %dMHz DPLL.\n",
> -		       MHz[clock_slot], MHz[dpll]);

    There was no need to undo that.

>  	} else {
>  		private_data = (void *)chip_table->clocks[clock_slot];
>  		/*

MBR, Sergei

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] pata_hpt3x2n: Clean up DPLL stuff
  2007-10-01 13:12 ` Sergei Shtylyov
@ 2007-10-02 14:16   ` Alan Cox
  2007-10-02 14:21     ` Jeff Garzik
  0 siblings, 1 reply; 5+ messages in thread
From: Alan Cox @ 2007-10-02 14:16 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: akpm, linux-ide

On Mon, 01 Oct 2007 17:12:03 +0400
Sergei Shtylyov <sshtylyov@ru.mvista.com> wrote:

> Hello.
> 
> Alan Cox wrote:
> 
> > Nobody commented when I asked for review earlier so it must be ok  8)
> 
>     It's not that I've seen this before
> 
>  > so it must be ok  8)
> 
>     Not by me at least, so let me NAK it. 8-)
> 
> > Lets stick it in -mm to be sure
> 
>     Now let's unstick it. :-)

Ok I shall revisit that. Andrew please drop

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] pata_hpt3x2n: Clean up DPLL stuff
  2007-10-02 14:16   ` Alan Cox
@ 2007-10-02 14:21     ` Jeff Garzik
  0 siblings, 0 replies; 5+ messages in thread
From: Jeff Garzik @ 2007-10-02 14:21 UTC (permalink / raw)
  To: Alan Cox; +Cc: Sergei Shtylyov, akpm, linux-ide

Alan Cox wrote:
> On Mon, 01 Oct 2007 17:12:03 +0400
> Sergei Shtylyov <sshtylyov@ru.mvista.com> wrote:
> 
>> Hello.
>>
>> Alan Cox wrote:
>>
>>> Nobody commented when I asked for review earlier so it must be ok  8)
>>     It's not that I've seen this before
>>
>>  > so it must be ok  8)
>>
>>     Not by me at least, so let me NAK it. 8-)
>>
>>> Lets stick it in -mm to be sure
>>     Now let's unstick it. :-)
> 
> Ok I shall revisit that. Andrew please drop

As I noted at the time of posting, this is in libata-dev.git#for-testing 
(and thus propagated to -mm via that route).  Consider it dropped, from 
my end.

	Jeff




^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2007-10-02 14:22 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-09-26 22:04 [PATCH] pata_hpt3x2n: Clean up DPLL stuff Alan Cox
2007-09-29  6:16 ` Jeff Garzik
2007-10-01 13:12 ` Sergei Shtylyov
2007-10-02 14:16   ` Alan Cox
2007-10-02 14:21     ` Jeff Garzik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).