On Wed, 8 Dec 2021 at 01:09, Rajat Jain <rajatja@xxxxxxxxxx> wrote: > > This particular SD controller from O2 / Bayhub only allows dword > accesses to its LTR max latency registers: > https://github.com/rajatxjain/public_shared/blob/main/OZ711LV2_appnote.pdf > > Thus add a quirk that saves and restores these registers > manually using dword acesses: > LTR Max Snoop Latency Register > LTR Max No-Snoop Latency Register > > Signed-off-by: Rajat Jain <rajatja@xxxxxxxxxx> Acked-by: Ulf Hansson <ulf.hansson@xxxxxxxxxx> Kind regards Uffe > --- > drivers/mmc/host/sdhci-pci.h | 1 - > drivers/pci/quirks.c | 39 ++++++++++++++++++++++++++++++++++++ > include/linux/pci_ids.h | 1 + > 3 files changed, 40 insertions(+), 1 deletion(-) > > diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h > index 5e3193278ff9..d47cc0ba7ca4 100644 > --- a/drivers/mmc/host/sdhci-pci.h > +++ b/drivers/mmc/host/sdhci-pci.h > @@ -10,7 +10,6 @@ > #define PCI_DEVICE_ID_O2_SDS1 0x8421 > #define PCI_DEVICE_ID_O2_FUJIN2 0x8520 > #define PCI_DEVICE_ID_O2_SEABIRD0 0x8620 > -#define PCI_DEVICE_ID_O2_SEABIRD1 0x8621 > > #define PCI_DEVICE_ID_INTEL_PCH_SDIO0 0x8809 > #define PCI_DEVICE_ID_INTEL_PCH_SDIO1 0x880a > diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c > index 003950c738d2..b7bd19802744 100644 > --- a/drivers/pci/quirks.c > +++ b/drivers/pci/quirks.c > @@ -5857,3 +5857,42 @@ static void nvidia_ion_ahci_fixup(struct pci_dev *pdev) > pdev->dev_flags |= PCI_DEV_FLAGS_HAS_MSI_MASKING; > } > DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0ab8, nvidia_ion_ahci_fixup); > + > +/* > + * Bayhub OZ711LV2 SD controller has an errata that only allows DWORD accesses > + * to the LTR max latency registers. Thus need to save and restore these > + * registers manually. > + */ > +static void o2_seabird1_save_ltr(struct pci_dev *dev) > +{ > + struct pci_cap_saved_state *save_state; > + u32 *reg32; > + > + save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_LTR); > + if (save_state) { > + reg32 = &save_state->cap.data[0]; > + /* Preserve PCI_LTR_MAX_SNOOP_LAT & PCI_LTR_MAX_NOSNOOP_LAT */ > + pci_read_config_dword(dev, 0x234, reg32); > + } else { > + pci_err(dev, "quirk can't save LTR snoop latency\n"); > + } > +} > + > +static void o2_seabird1_restore_ltr(struct pci_dev *dev) > +{ > + struct pci_cap_saved_state *save_state; > + u32 *reg32; > + > + save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_LTR); > + if (save_state) { > + reg32 = &save_state->cap.data[0]; > + /* Restore PCI_LTR_MAX_SNOOP_LAT & PCI_LTR_MAX_NOSNOOP_LAT */ > + pci_write_config_dword(dev, 0x234, *reg32); > + } else { > + pci_err(dev, "quirk can't restore LTR snoop latency\n"); > + } > +} > +DECLARE_PCI_FIXUP_SUSPEND_LATE(PCI_VENDOR_ID_O2, PCI_DEVICE_ID_O2_SEABIRD1, > + o2_seabird1_save_ltr); > +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_O2, PCI_DEVICE_ID_O2_SEABIRD1, > + o2_seabird1_restore_ltr); > diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h > index 011f2f1ea5bb..6ed16aa38196 100644 > --- a/include/linux/pci_ids.h > +++ b/include/linux/pci_ids.h > @@ -1717,6 +1717,7 @@ > #define PCI_DEVICE_ID_O2_8221 0x8221 > #define PCI_DEVICE_ID_O2_8320 0x8320 > #define PCI_DEVICE_ID_O2_8321 0x8321 > +#define PCI_DEVICE_ID_O2_SEABIRD1 0x8621 > > #define PCI_VENDOR_ID_3DFX 0x121a > #define PCI_DEVICE_ID_3DFX_VOODOO 0x0001 > -- > 2.34.1.400.ga245620fadb-goog >