* [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.