All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch] lewisburg map/pcs register handling
@ 2017-11-14 23:55 Peter Chang
  2017-11-27 19:25 ` Tejun Heo
  0 siblings, 1 reply; 2+ messages in thread
From: Peter Chang @ 2017-11-14 23:55 UTC (permalink / raw)
  To: linux-ide

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

mostly, intel made the registers wider so that the offsets aren't
right. it only matters if you don't populate all the ports and aren't
using the first port.

\p

[-- Attachment #2: 0001-ahci-lewisburg-MAP-PCS-register-handling.patch --]
[-- Type: text/x-patch, Size: 5169 bytes --]

From 62ccc6118960204769809a1ea9d162cf2c1c95e1 Mon Sep 17 00:00:00 2001
From: peter chang <dpf@google.com>
Date: Tue, 14 Nov 2017 13:43:15 -0800
Subject: [PATCH] ahci: lewisburg MAP / PCS register handling

registers are now 32-bits and the existing offsets mean that the
wrong registers are being updated.

Change-Id: I992b31bc9e789f9dfbeb29afeb0b7777e325ea71
---
 drivers/ata/ahci.c    | 34 +++++++++++++++++++++++++++-------
 drivers/ata/ahci.h    |  4 ++++
 drivers/ata/libahci.c | 19 +++++++++++++++++++
 3 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 9f78bb03bb76..16b0fac9f0ae 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -71,6 +71,7 @@ enum board_ids {
 
 	/* board IDs for specific chipsets in alphabetical order */
 	board_ahci_avn,
+	board_ahci_lbg,
 	board_ahci_mcp65,
 	board_ahci_mcp77,
 	board_ahci_mcp89,
@@ -174,6 +175,14 @@ static const struct ata_port_info ahci_port_info[] = {
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &ahci_avn_ops,
 	},
+	[board_ahci_lbg] = {
+		AHCI_HFLAGS	(AHCI_HFLAG_32BIT_MAP_PCS |
+				 AHCI_HFLAG_PCI_PORT_MAP),
+		.flags		= AHCI_FLAG_COMMON,
+		.pio_mask	= ATA_PIO4,
+		.udma_mask	= ATA_UDMA6,
+		.port_ops	= &ahci_ops,
+	},
 	[board_ahci_mcp65] = {
 		AHCI_HFLAGS	(AHCI_HFLAG_NO_FPDMA_AA | AHCI_HFLAG_NO_PMP |
 				 AHCI_HFLAG_YES_NCQ),
@@ -374,14 +383,14 @@ static const struct pci_device_id ahci_pci_tbl[] = {
 	{ PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */
 	{ PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */
 	{ PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/
-	{ PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Lewisburg AHCI*/
+	{ PCI_VDEVICE(INTEL, 0x2823), board_ahci_lbg }, /* Lewisburg AHCI*/
 	{ PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* Lewisburg RAID*/
 	{ PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Lewisburg RAID*/
-	{ PCI_VDEVICE(INTEL, 0xa182), board_ahci }, /* Lewisburg AHCI*/
+	{ PCI_VDEVICE(INTEL, 0xa182), board_ahci_lbg }, /* Lewisburg AHCI*/
 	{ PCI_VDEVICE(INTEL, 0xa186), board_ahci }, /* Lewisburg RAID*/
 	{ PCI_VDEVICE(INTEL, 0xa1d2), board_ahci }, /* Lewisburg RAID*/
 	{ PCI_VDEVICE(INTEL, 0xa1d6), board_ahci }, /* Lewisburg RAID*/
-	{ PCI_VDEVICE(INTEL, 0xa202), board_ahci }, /* Lewisburg AHCI*/
+	{ PCI_VDEVICE(INTEL, 0xa202), board_ahci_lbg }, /* Lewisburg AHCI*/
 	{ PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/
 	{ PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/
 	{ PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/
@@ -630,12 +639,23 @@ static int ahci_pci_reset_controller(struct ata_host *host)
 	if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
 		struct ahci_host_priv *hpriv = host->private_data;
 		u16 tmp16;
+		u32 tmp32;
 
 		/* configure PCS */
-		pci_read_config_word(pdev, 0x92, &tmp16);
-		if ((tmp16 & hpriv->port_map) != hpriv->port_map) {
-			tmp16 |= hpriv->port_map;
-			pci_write_config_word(pdev, 0x92, tmp16);
+		if (hpriv->flags & AHCI_HFLAG_32BIT_MAP_PCS)
+			pci_read_config_dword(pdev, 0x94, &tmp32);
+		else {
+			pci_read_config_word(pdev, 0x92, &tmp16);
+			tmp32 = tmp16;
+		}
+		if ((tmp32 & hpriv->port_map) != hpriv->port_map) {
+			tmp32 |= hpriv->port_map;
+			if (hpriv->flags & AHCI_HFLAG_32BIT_MAP_PCS)
+				pci_write_config_dword(pdev, 0x94, tmp32);
+			else {
+				tmp16 = tmp32;
+				pci_write_config_word(pdev, 0x92, tmp16);
+			}
 		}
 	}
 
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index 8b61123d2c3c..a649107027de 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -251,6 +251,10 @@ enum {
 	AHCI_HFLAG_YES_ALPM		= (1 << 23), /* force ALPM cap on */
 	AHCI_HFLAG_NO_WRITE_TO_RO	= (1 << 24), /* don't write to read
 							only registers */
+        AHCI_HFLAG_32BIT_MAP_PCS	= (1 << 25), /* MAP/PCS register
+                                                        32-bits wide */
+        AHCI_HFLAG_PCI_PORT_MAP		= (1 << 26), /* port map in pci
+                                                        config space */
 
 	/* ap->flags bits */
 
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index 3e286d86ab42..e65481d8e362 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -40,6 +40,7 @@
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
 #include <linux/device.h>
+#include <linux/pci.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
 #include <linux/libata.h>
@@ -523,6 +524,24 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
 		port_map &= hpriv->mask_port_map;
 	}
 
+	if (hpriv->flags & AHCI_HFLAG_PCI_PORT_MAP) {
+		struct pci_dev *pdev = to_pci_dev(dev);
+		u16 disabled;
+
+		if (hpriv->flags & AHCI_HFLAG_32BIT_MAP_PCS) {
+			u32 tmp;
+
+			pci_read_config_dword(pdev, 0x90, &tmp);
+			disabled = (tmp >> 16) & 0xffff;
+		} else {
+			pci_read_config_word(pdev, 0x90, &disabled);
+			disabled = (disabled >> 8) & 0xff;
+		}
+
+		dev_info(dev, "port_map:%x disabled:%x\n", port_map, disabled);
+		port_map &= ~disabled;
+	}
+
 	/* cross check port_map and cap.n_ports */
 	if (port_map) {
 		int map_ports = 0;
-- 
2.15.0.448.gf294e3d99a-goog


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

* Re: [patch] lewisburg map/pcs register handling
  2017-11-14 23:55 [patch] lewisburg map/pcs register handling Peter Chang
@ 2017-11-27 19:25 ` Tejun Heo
  0 siblings, 0 replies; 2+ messages in thread
From: Tejun Heo @ 2017-11-27 19:25 UTC (permalink / raw)
  To: Peter Chang; +Cc: linux-ide

Hello, Peter.

On Tue, Nov 14, 2017 at 03:55:12PM -0800, Peter Chang wrote:
> From 62ccc6118960204769809a1ea9d162cf2c1c95e1 Mon Sep 17 00:00:00 2001
> From: peter chang <dpf@google.com>
> Date: Tue, 14 Nov 2017 13:43:15 -0800
> Subject: [PATCH] ahci: lewisburg MAP / PCS register handling
> 
> registers are now 32-bits and the existing offsets mean that the
> wrong registers are being updated.
> 
> Change-Id: I992b31bc9e789f9dfbeb29afeb0b7777e325ea71

Can you please drop Change-Id and add Signed-off-by?  Also, the
earlier part of the email where you explained what's going on was
actually easier to understand.  Maybe put that in the description?

> -		pci_read_config_word(pdev, 0x92, &tmp16);
> -		if ((tmp16 & hpriv->port_map) != hpriv->port_map) {
> -			tmp16 |= hpriv->port_map;
> -			pci_write_config_word(pdev, 0x92, tmp16);
> +		if (hpriv->flags & AHCI_HFLAG_32BIT_MAP_PCS)
> +			pci_read_config_dword(pdev, 0x94, &tmp32);
> +		else {
> +			pci_read_config_word(pdev, 0x92, &tmp16);
> +			tmp32 = tmp16;
> +		}

The coding style says that we always add {} to both if and else bodies.

> +		if ((tmp32 & hpriv->port_map) != hpriv->port_map) {
> +			tmp32 |= hpriv->port_map;
> +			if (hpriv->flags & AHCI_HFLAG_32BIT_MAP_PCS)
> +				pci_write_config_dword(pdev, 0x94, tmp32);
> +			else {
> +				tmp16 = tmp32;
> +				pci_write_config_word(pdev, 0x92, tmp16);
> +			}

@@ -523,6 +524,24 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
>  		port_map &= hpriv->mask_port_map;
>  	}
>  
> +	if (hpriv->flags & AHCI_HFLAG_PCI_PORT_MAP) {
> +		struct pci_dev *pdev = to_pci_dev(dev);
> +		u16 disabled;
> +
> +		if (hpriv->flags & AHCI_HFLAG_32BIT_MAP_PCS) {
> +			u32 tmp;
> +
> +			pci_read_config_dword(pdev, 0x90, &tmp);
> +			disabled = (tmp >> 16) & 0xffff;
> +		} else {
> +			pci_read_config_word(pdev, 0x90, &disabled);
> +			disabled = (disabled >> 8) & 0xff;
> +		}
> +
> +		dev_info(dev, "port_map:%x disabled:%x\n", port_map, disabled);
> +		port_map &= ~disabled;
> +	}

And the patch description doesn't explain the above chunk.  Can you
please explain this part too?

Thanks.

-- 
tejun

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

end of thread, other threads:[~2017-11-27 19:25 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-14 23:55 [patch] lewisburg map/pcs register handling Peter Chang
2017-11-27 19:25 ` Tejun Heo

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.