mailweb.openeuler.org
Manage this list

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

Kernel

Threads by month
  • ----- 2025 -----
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2021 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2020 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2019 -----
  • December
kernel@openeuler.org

  • 27 participants
  • 18548 discussions
[PATCH OLK-5.10] xhci: fix issue with resume from system Sx state
by LeoLiuoc 09 Jul '21

09 Jul '21
On Zhaoxin ZX-100 project, xHCI can't work normally after resume from system Sx state. To fix this issue, when resume from system sx state, reinitialize xHCI instead of restore. Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> ---  drivers/usb/host/xhci-pci.c | 3 +++  1 file changed, 3 insertions(+) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 471cf3e96032..44dd77343cc1 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -307,6 +307,9 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)      if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241)          xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_7; +    if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN && pdev->device == 0x9202) +        xhci->quirks |= XHCI_RESET_ON_RESUME; +      if ((pdev->vendor == PCI_VENDOR_ID_BROADCOM ||           pdev->vendor == PCI_VENDOR_ID_CAVIUM) &&           pdev->device == 0x9026) -- 2.20.1
1 0
0 0
[PATCH OLK-5.10] xhci: Adjust the UHCI Controllers bit value
by LeoLiuoc 09 Jul '21

09 Jul '21
Over Current condition is not standardized in the UHCI spec. Zhaoxin UHCI controllers report Over Current active off. Intel controllers report it active on, so we'll adjust the bit value. Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> ---  drivers/usb/host/uhci-pci.c | 3 +++  1 file changed, 3 insertions(+) diff --git a/drivers/usb/host/uhci-pci.c b/drivers/usb/host/uhci-pci.c index 9b88745d247f..d90c391d4899 100644 --- a/drivers/usb/host/uhci-pci.c +++ b/drivers/usb/host/uhci-pci.c @@ -134,6 +134,9 @@ static int uhci_pci_init(struct usb_hcd *hcd)      if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_INTEL)          device_set_wakeup_capable(uhci_dev(uhci), true); +    if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_ZHAOXIN) +        uhci->oc_low = 1; +      /* Set up pointers to PCI-specific functions */      uhci->reset_hc = uhci_pci_reset_hc;      uhci->check_and_reset_hc = uhci_pci_check_and_reset_hc; -- 2.20.1
1 0
0 0
[PATCH OLK-5.10 3/3] ALSA: hda: Add support of Zhaoxin NB HDAC codec
by LeoLiuoc 09 Jul '21

09 Jul '21
Add Zhaoxin NB HDAC codec support. Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> ---  sound/pci/hda/patch_hdmi.c | 26 ++++++++++++++++++++++++++  1 file changed, 26 insertions(+) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 6d2a4dfcfe43..f541aeb4ecca 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -4249,6 +4249,20 @@ static int patch_via_hdmi(struct hda_codec *codec)      return patch_simple_hdmi(codec, VIAHDMI_CVT_NID, VIAHDMI_PIN_NID);  } +/* ZHAOXIN HDMI Implementation */ +static int patch_zx_hdmi(struct hda_codec *codec) +{ +    int err; + +    err = patch_generic_hdmi(codec); +    codec->no_sticky_stream = 1; + +    if (err) +        return err; + +    return 0; +} +  /*   * patch entries   */ @@ -4342,6 +4356,12 @@ HDA_CODEC_ENTRY(0x11069f80, "VX900 HDMI/DP",    patch_via_hdmi),  HDA_CODEC_ENTRY(0x11069f81, "VX900 HDMI/DP",    patch_via_hdmi),  HDA_CODEC_ENTRY(0x11069f84, "VX11 HDMI/DP", patch_generic_hdmi),  HDA_CODEC_ENTRY(0x11069f85, "VX11 HDMI/DP", patch_generic_hdmi), +HDA_CODEC_ENTRY(0x11069f86, "CND001 HDMI/DP", patch_generic_hdmi), +HDA_CODEC_ENTRY(0x11069f87, "CND001 HDMI/DP", patch_generic_hdmi), +HDA_CODEC_ENTRY(0x11069f88, "CHX001 HDMI/DP",    patch_zx_hdmi), +HDA_CODEC_ENTRY(0x11069f89, "CHX001 HDMI/DP",    patch_zx_hdmi), +HDA_CODEC_ENTRY(0x11069f8a, "CHX002 HDMI/DP",    patch_zx_hdmi), +HDA_CODEC_ENTRY(0x11069f8b, "CHX002 HDMI/DP",    patch_zx_hdmi),  HDA_CODEC_ENTRY(0x80860054, "IbexPeak HDMI", patch_i915_cpt_hdmi),  HDA_CODEC_ENTRY(0x80862800, "Geminilake HDMI", patch_i915_glk_hdmi),  HDA_CODEC_ENTRY(0x80862801, "Bearlake HDMI", patch_generic_hdmi), @@ -4369,6 +4389,12 @@ HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI",    patch_generic_hdmi),  HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_i915_byt_hdmi),  HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_i915_byt_hdmi),  HDA_CODEC_ENTRY(0x808629fb, "Crestline HDMI", patch_generic_hdmi), +HDA_CODEC_ENTRY(0x1d179f86, "CND001 HDMI/DP", patch_generic_hdmi), +HDA_CODEC_ENTRY(0x1d179f87, "CND001 HDMI/DP", patch_generic_hdmi), +HDA_CODEC_ENTRY(0x1d179f88, "CHX001 HDMI/DP",    patch_zx_hdmi), +HDA_CODEC_ENTRY(0x1d179f89, "CHX001 HDMI/DP",    patch_zx_hdmi), +HDA_CODEC_ENTRY(0x1d179f8a, "CHX002 HDMI/DP",    patch_zx_hdmi), +HDA_CODEC_ENTRY(0x1d179f8b, "CHX002 HDMI/DP",    patch_zx_hdmi),  /* special ID for generic HDMI */  HDA_CODEC_ENTRY(HDA_CODEC_ID_GENERIC_HDMI, "Generic HDMI", patch_generic_hdmi),  {} /* terminator */ -- 2.20.1
1 0
0 0
[PATCH OLK-5.10 2/3] ALSA: hda: Add support of Zhaoxin NB HDAC
by LeoLiuoc 09 Jul '21

09 Jul '21
Add the new PCI ID 0x1d17 0x9141/0x9142/0x9144 Zhaoxin NB HDAC support. And add some special initialization for Zhaoxin NB HDAC. Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> ---  sound/pci/hda/hda_controller.c | 17 ++++++++++-  sound/pci/hda/hda_controller.h |  2 ++  sound/pci/hda/hda_intel.c      | 53 +++++++++++++++++++++++++++++++++-  3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index b972d59eb1ec..d6de0b1fcb66 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c @@ -1057,6 +1057,16 @@ void azx_stop_chip(struct azx *chip)  }  EXPORT_SYMBOL_GPL(azx_stop_chip); +static void azx_rirb_zxdelay(struct azx *chip, int enable) +{ +    if (chip->remap_diu_addr) { +        if (!enable) +            writel(0x0, (char *)chip->remap_diu_addr + 0x490a8); +        else +            writel(0x1000000, (char *)chip->remap_diu_addr + 0x490a8); +    } +} +  /*   * interrupt handler   */ @@ -1116,9 +1126,14 @@ irqreturn_t azx_interrupt(int irq, void *dev_id)              azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);              active = true;              if (status & RIRB_INT_RESPONSE) { -                if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND) +                if ((chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND) || +                    (chip->driver_caps & AZX_DCAPS_RIRB_PRE_DELAY)) { +                    azx_rirb_zxdelay(chip, 1);                      udelay(80); +                }                  snd_hdac_bus_update_rirb(bus); +                if (chip->driver_caps & AZX_DCAPS_RIRB_PRE_DELAY) +                    azx_rirb_zxdelay(chip, 0);              }          }      } while (active && ++repeat < 10); diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h index 68f9668788ea..543b9f75cf42 100644 --- a/sound/pci/hda/hda_controller.h +++ b/sound/pci/hda/hda_controller.h @@ -45,6 +45,7 @@  #define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28)    /* CORBRP clears itself after reset */  #define AZX_DCAPS_NO_MSI64      (1 << 29)    /* Stick to 32-bit MSIs */  #define AZX_DCAPS_SEPARATE_STREAM_TAG    (1 << 30) /* capture and playback use separate stream tag */ +#define AZX_DCAPS_RIRB_PRE_DELAY  (1 << 31)  enum {      AZX_SNOOP_TYPE_NONE, @@ -147,6 +148,7 @@ struct azx {      /* GTS present */      unsigned int gts_present:1; +    void __iomem *remap_diu_addr;  #ifdef CONFIG_SND_HDA_DSP_LOADER      struct azx_dev saved_azx_dev; diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 8ff7902ec6e6..5ac2e95fd5fa 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -241,7 +241,8 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"               "{VIA, VT8251},"               "{VIA, VT8237A},"               "{ULI, M5461}," -             "{ZX, ZhaoxinHDA}}"); +             "{ZX, ZhaoxinHDA}," +             "{ZX, ZhaoxinHDMI}}");  MODULE_DESCRIPTION("Intel HDA driver");  #if defined(CONFIG_PM) && defined(CONFIG_VGA_SWITCHEROO) @@ -273,6 +274,7 @@ enum {      AZX_DRIVER_CTHDA,      AZX_DRIVER_CMEDIA,      AZX_DRIVER_ZHAOXIN, +    AZX_DRIVER_ZXHDMI,      AZX_DRIVER_GENERIC,      AZX_NUM_DRIVERS, /* keep this as last entry */  }; @@ -390,6 +392,7 @@ static const char * const driver_short_names[] = {      [AZX_DRIVER_CTHDA] = "HDA Creative",      [AZX_DRIVER_CMEDIA] = "HDA C-Media",      [AZX_DRIVER_ZHAOXIN] = "HDA Zhaoxin", +    [AZX_DRIVER_ZXHDMI] = "HDA Zhaoxin GFX",      [AZX_DRIVER_GENERIC] = "HD-Audio Generic",  }; @@ -411,6 +414,29 @@ static void update_pci_byte(struct pci_dev *pci, unsigned int reg,      pci_write_config_byte(pci, reg, data);  } +static int azx_init_chip_zx(struct azx *chip) +{ +    struct snd_card *card = chip->card; +    unsigned int diu_reg; +    struct pci_dev *diu_pci = NULL; + +    diu_pci = pci_get_device(0x1d17, 0x3a03, NULL); +    if (!diu_pci) { +        dev_err(card->dev, "hda no chx001 device.\n"); +        return -ENXIO; +    } +    pci_read_config_dword(diu_pci, PCI_BASE_ADDRESS_0, &diu_reg); +    chip->remap_diu_addr = ioremap(diu_reg, 0x50000); +    dev_info(card->dev, "hda %x %p\n", diu_reg, chip->remap_diu_addr); +    return 0; +} + +static void azx_free_chip_zx(struct azx *chip) +{ +    if (chip->remap_diu_addr) +        iounmap(chip->remap_diu_addr); +} +  static void azx_init_pci(struct azx *chip)  {      int snoop_type = azx_get_snoop_type(chip); @@ -1386,6 +1412,9 @@ static void azx_free(struct azx *chip)      hda->init_failed = 1; /* to be sure */      complete_all(&hda->probe_wait); +    if (chip->driver_type == AZX_DRIVER_ZXHDMI) +        azx_free_chip_zx(chip); +      if (use_vga_switcheroo(hda)) {          if (chip->disabled && hda->probe_continued)              snd_hda_unlock_devices(&chip->bus); @@ -1786,6 +1815,8 @@ static int default_bdl_pos_adj(struct azx *chip)      case AZX_DRIVER_ICH:      case AZX_DRIVER_PCH:          return 1; +    case AZX_DRIVER_ZXHDMI: +        return 128;      default:          return 32;      } @@ -1903,6 +1934,11 @@ static int azx_first_init(struct azx *chip)      }  #endif +    chip->remap_diu_addr = NULL; + +    if (chip->driver_type == AZX_DRIVER_ZXHDMI) +        azx_init_chip_zx(chip); +      err = pci_request_regions(pci, "ICH HD audio");      if (err < 0)          return err; @@ -2011,6 +2047,7 @@ static int azx_first_init(struct azx *chip)              chip->playback_streams = ATIHDMI_NUM_PLAYBACK;              chip->capture_streams = ATIHDMI_NUM_CAPTURE;              break; +        case AZX_DRIVER_ZXHDMI:          case AZX_DRIVER_GENERIC:          default:              chip->playback_streams = ICH6_NUM_PLAYBACK; @@ -2732,6 +2769,13 @@ static const struct pci_device_id azx_ids[] = {      { PCI_DEVICE(0x1106, 0x9170), .driver_data = AZX_DRIVER_GENERIC },      /* VIA GFX VT6122/VX11 */      { PCI_DEVICE(0x1106, 0x9140), .driver_data = AZX_DRIVER_GENERIC }, +    { PCI_DEVICE(0x1106, 0x9141), .driver_data = AZX_DRIVER_GENERIC  }, +    { PCI_DEVICE(0x1106, 0x9142), +      .driver_data = AZX_DRIVER_ZXHDMI | AZX_DCAPS_POSFIX_LPIB | +      AZX_DCAPS_NO_MSI | AZX_DCAPS_RIRB_PRE_DELAY }, +    { PCI_DEVICE(0x1106, 0x9144), +      .driver_data = AZX_DRIVER_ZXHDMI | AZX_DCAPS_POSFIX_LPIB | +      AZX_DCAPS_NO_MSI | AZX_DCAPS_RIRB_PRE_DELAY },      /* SIS966 */      { PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS },      /* ULI M5461 */ @@ -2787,6 +2831,13 @@ static const struct pci_device_id azx_ids[] = {        .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI },      /* Zhaoxin */      { PCI_DEVICE(0x1d17, 0x3288), .driver_data = AZX_DRIVER_ZHAOXIN }, +    { PCI_DEVICE(0x1d17, 0x9141), .driver_data = AZX_DRIVER_GENERIC  }, +    { PCI_DEVICE(0x1d17, 0x9142), +      .driver_data = AZX_DRIVER_ZXHDMI | AZX_DCAPS_POSFIX_LPIB | +      AZX_DCAPS_NO_MSI | AZX_DCAPS_RIRB_PRE_DELAY }, +    { PCI_DEVICE(0x1d17, 0x9144), +      .driver_data = AZX_DRIVER_ZXHDMI | AZX_DCAPS_POSFIX_LPIB | +      AZX_DCAPS_NO_MSI | AZX_DCAPS_RIRB_PRE_DELAY },      { 0, }  };  MODULE_DEVICE_TABLE(pci, azx_ids); -- 2.20.1
1 0
0 0
[PATCH OLK-5.10 1/3] ALSA: hda: Add Zhaoxin SB HDAC non snoop path support
by LeoLiuoc 09 Jul '21

09 Jul '21
Add Zhaoxin SB HDAC non snoop path support. Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> ---  sound/pci/hda/hda_intel.c | 13 +++++++++++--  1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 4c8b281c3992..8ff7902ec6e6 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -240,8 +240,8 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"               "{ATI, RV770},"               "{VIA, VT8251},"               "{VIA, VT8237A}," -             "{SiS, SIS966}," -             "{ULI, M5461}}"); +             "{ULI, M5461}," +             "{ZX, ZhaoxinHDA}}");  MODULE_DESCRIPTION("Intel HDA driver");  #if defined(CONFIG_PM) && defined(CONFIG_VGA_SWITCHEROO) @@ -1744,6 +1744,15 @@ static void azx_check_snoop_available(struct azx *chip)              snoop = false;      } +    if (azx_get_snoop_type(chip) == AZX_SNOOP_TYPE_NONE && +        chip->driver_type == AZX_DRIVER_ZHAOXIN) { +        u8 val1; + +        pci_read_config_byte(chip->pci, 0x42, &val1); +        if (!(val1 & 0x80) && chip->pci->revision == 0x20) +            snoop = false; +    } +      if (chip->driver_caps & AZX_DCAPS_SNOOP_OFF)          snoop = false; -- 2.20.1
1 0
0 0
[PATCH OLK-5.10 0/3] Add support of Zhaoxin HDAC and codec
by LeoLiuoc 09 Jul '21

09 Jul '21
Zhaoxin have new SB & NB HDAC controller. And have new NB HDAC codec. This patch set add support for them. LeoLiu-oc (3):   ALSA: hda: Add Zhaoxin SB HDAC non snoop path support   ALSA: hda: Add support of Zhaoxin NB HDAC   ALSA: hda: Add support of Zhaoxin NB HDAC codec  sound/pci/hda/hda_controller.c | 17 ++++++++-  sound/pci/hda/hda_controller.h |  2 ++  sound/pci/hda/hda_intel.c      | 64 ++++++++++++++++++++++++++++++++--  sound/pci/hda/patch_hdmi.c     | 26 ++++++++++++++  4 files changed, 106 insertions(+), 3 deletions(-) -- 2.20.1
1 0
0 0
[PATCH OLK-5.10] xhci: Show Zhaoxin XHCI root hub speed correctly
by LeoLiuoc 09 Jul '21

09 Jul '21
Some Zhaoxin xHCI controllers follow usb3.1 spec, but only support gen1 speed 5G. While in Linux kernel, if xHCI suspport usb3.1,root hub speed will show on 10G. To fix this issue, read usb speed ID supported by xHCI to determine root hub speed. Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> ---  drivers/usb/host/xhci.c | 19 +++++++++++++++++++  1 file changed, 19 insertions(+) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index a834f3927bee..e9d67ee299d9 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -5186,6 +5186,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)       */      struct device        *dev = hcd->self.sysdev;      unsigned int        minor_rev; +    u8            i, j;      int            retval;      /* Accept arbitrarily long scatter-gather lists */ @@ -5240,6 +5241,24 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)              hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS;              break;          } + +        /* usb3.1 has gen1 and gen2, Some zx's xHCI controller that follow usb3.1 spec +         * but only support gen1 +         */ +        if (xhci->quirks & XHCI_ZHAOXIN_HOST) { +            minor_rev = 0; +            for (j = 0; j < xhci->num_port_caps; j++) { +                for (i = 0; i < xhci->port_caps[j].psi_count; i++) { +                    if (XHCI_EXT_PORT_PSIV(xhci->port_caps[j].psi[i]) >= 5) +                        minor_rev = 1; +                } +                if (minor_rev != 1) { +                    hcd->speed = HCD_USB3; +                    hcd->self.root_hub->speed = USB_SPEED_SUPER; +                } +            } +        } +          xhci_info(xhci, "Host supports USB 3.%x %sSuperSpeed\n",                minor_rev,                minor_rev ? "Enhanced " : ""); -- 2.20.1
1 0
0 0
[PATCH OLK-5.10] xhci: fix issue of cross page boundary in TRB prefetch
by LeoLiuoc 09 Jul '21

09 Jul '21
On some Zhaoxin platforms, xHCI will prefetch TRB for performance improvement. However this TRB prefetch mechanism may cross page boundary, which may access memory not belong to xHCI. In order to fix this issue, using two pages for TRB allocate and only the first page will be used. Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> ---  drivers/usb/host/xhci-mem.c | 10 +++++++++-  drivers/usb/host/xhci-pci.c |  5 +++++  drivers/usb/host/xhci.h     |  1 +  3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 8ce043e6ed87..67329b4188cf 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -2458,8 +2458,16 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)       * and our use of dma addresses in the trb_address_map radix tree needs       * TRB_SEGMENT_SIZE alignment, so we pick the greater alignment need.       */ -    xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, +    /* With xHCI TRB prefetch patch:To fix cross page boundary access issue +     * in IOV environment +     */ +    if (xhci->quirks & XHCI_ZHAOXIN_TRB_FETCH) { +        xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, +            TRB_SEGMENT_SIZE*2, TRB_SEGMENT_SIZE*2, xhci->page_size*2); +    } else { +        xhci->segment_pool = dma_pool_create("xHCI ring segments", dev,              TRB_SEGMENT_SIZE, TRB_SEGMENT_SIZE, xhci->page_size); +    }      /* See Table 46 and Note on Figure 55 */      xhci->device_pool = dma_pool_create("xHCI input/output contexts", dev, diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index e78316ed99d4..471cf3e96032 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -281,6 +281,11 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)      if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483)          xhci->quirks |= XHCI_LPM_SUPPORT; +    if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN && +        (pdev->device == 0x9202 || +         pdev->device == 0x9203)) +        xhci->quirks |= XHCI_ZHAOXIN_TRB_FETCH; +      if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&          pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI)          xhci->quirks |= XHCI_BROKEN_STREAMS; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 576cafb5d873..e215431f927a 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1881,6 +1881,7 @@ struct xhci_hcd {  #define XHCI_SG_TRB_CACHE_SIZE_QUIRK    BIT_ULL(39)  #define XHCI_NO_SOFT_RETRY    BIT_ULL(40)  #define XHCI_ZHAOXIN_HOST    BIT_ULL(41) +#define XHCI_ZHAOXIN_TRB_FETCH    BIT_ULL(42)      unsigned int        num_active_eps;      unsigned int        limit_active_eps; -- 2.20.1
1 0
0 0
[PATCH OLK-5.10] xhci: Add Zhaoxin xHCI LPM U1/U2 feature support
by LeoLiuoc 09 Jul '21

09 Jul '21
Add LPM u1/u2 feature support for xHCI of zhaoxin Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> ---  drivers/usb/host/xhci-pci.c |  4 ++++  drivers/usb/host/xhci.c     | 34 ++++++++++++++++++++++++++++++++--  drivers/usb/host/xhci.h     |  1 +  3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 7bc18cf8042c..e78316ed99d4 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -268,6 +268,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)      }      if (pdev->vendor == PCI_VENDOR_ID_VIA)          xhci->quirks |= XHCI_RESET_ON_RESUME; +    if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) { +        xhci->quirks |= XHCI_LPM_SUPPORT; +        xhci->quirks |= XHCI_ZHAOXIN_HOST; +    }      /* See https://bugzilla.kernel.org/show_bug.cgi?id=79511 */      if (pdev->vendor == PCI_VENDOR_ID_VIA && diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index a8d97e23f601..a834f3927bee 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -4666,7 +4666,7 @@ static u16 xhci_calculate_u1_timeout(struct xhci_hcd *xhci,  {      unsigned long long timeout_ns; -    if (xhci->quirks & XHCI_INTEL_HOST) +    if (xhci->quirks & (XHCI_INTEL_HOST | XHCI_ZHAOXIN_HOST))          timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc);      else          timeout_ns = udev->u1_params.sel; @@ -4730,7 +4730,7 @@ static u16 xhci_calculate_u2_timeout(struct xhci_hcd *xhci,  {      unsigned long long timeout_ns; -    if (xhci->quirks & XHCI_INTEL_HOST) +    if (xhci->quirks & (XHCI_INTEL_HOST | XHCI_ZHAOXIN_HOST))          timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc);      else          timeout_ns = udev->u2_params.sel; @@ -4835,12 +4835,42 @@ static int xhci_check_intel_tier_policy(struct usb_device *udev,      return -E2BIG;  } +static int xhci_check_zhaoxin_tier_policy(struct usb_device *udev, +                            enum usb3_link_state state) +{ +    struct usb_device *parent; +    unsigned int num_hubs; +    char *state_name; + +    if (state == USB3_LPM_U1) +        state_name = "U1"; +    else if (state == USB3_LPM_U2) +        state_name = "U2"; +    else +        state_name = "Unknown"; +    /* Don't enable U1/U2 if the device is on an external hub*/ +    for (parent = udev->parent, num_hubs = 0; parent->parent; +            parent = parent->parent) +            num_hubs++; + +    if (num_hubs < 1) +        return 0; + +    dev_dbg(&udev->dev, "Disabling %s link state for device" +            " below external hub.\n", state_name); +    dev_dbg(&udev->dev, "Plug device into root port " +            "to decrease power consumption.\n"); +    return -E2BIG; +} +  static int xhci_check_tier_policy(struct xhci_hcd *xhci,          struct usb_device *udev,          enum usb3_link_state state)  {      if (xhci->quirks & XHCI_INTEL_HOST)          return xhci_check_intel_tier_policy(udev, state); +    else if (xhci->quirks & XHCI_ZHAOXIN_HOST) +        return xhci_check_zhaoxin_tier_policy(udev, state);      else          return 0;  } diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index d01241f1daf3..576cafb5d873 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1880,6 +1880,7 @@ struct xhci_hcd {  #define XHCI_DISABLE_SPARSE    BIT_ULL(38)  #define XHCI_SG_TRB_CACHE_SIZE_QUIRK    BIT_ULL(39)  #define XHCI_NO_SOFT_RETRY    BIT_ULL(40) +#define XHCI_ZHAOXIN_HOST    BIT_ULL(41)      unsigned int        num_active_eps;      unsigned int        limit_active_eps; -- 2.20.1
1 0
0 0
[PATCH OLK-5.10] ata: sata_zhaoxin: Add support for Zhaoxin Serial ATA
by LeoLiuoc 09 Jul '21

09 Jul '21
Add Zhaoxin Serial ATA support for Zhaoxin CPUs. Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> ---  drivers/ata/Kconfig        |   8 +  drivers/ata/Makefile       |   1 +  drivers/ata/sata_zhaoxin.c | 384 +++++++++++++++++++++++++++++++++++++  3 files changed, 393 insertions(+)  create mode 100644 drivers/ata/sata_zhaoxin.c diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 030cb32da980..5f62dcdc546b 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -552,6 +552,14 @@ config SATA_VITESSE        If unsure, say N. +config SATA_ZHAOXIN +    tristate "ZhaoXin SATA support" +    depends on PCI +    help +      This option enables support for ZhaoXin Serial ATA. + +      If unsure, say N. +  comment "PATA SFF controllers with BMDMA"  config PATA_ALI diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index b8aebfb14e82..9a3ce171d9e8 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_SATA_SVW)        += sata_svw.o  obj-$(CONFIG_SATA_ULI)        += sata_uli.o  obj-$(CONFIG_SATA_VIA)        += sata_via.o  obj-$(CONFIG_SATA_VITESSE)    += sata_vsc.o +obj-$(CONFIG_SATA_ZHAOXIN)        += sata_zhaoxin.o  # SFF PATA w/ BMDMA  obj-$(CONFIG_PATA_ALI)        += pata_ali.o diff --git a/drivers/ata/sata_zhaoxin.c b/drivers/ata/sata_zhaoxin.c new file mode 100644 index 000000000000..8e30a6525f54 --- /dev/null +++ b/drivers/ata/sata_zhaoxin.c @@ -0,0 +1,384 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + *  sata_zhaoxin.c - ZhaoXin Serial ATA controllers + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/blkdev.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <scsi/scsi.h> +#include <scsi/scsi_cmnd.h> +#include <scsi/scsi_host.h> +#include <linux/libata.h> + +#define DRV_NAME    "sata_zx" +#define DRV_VERSION    "2.6.1" + +enum board_ids_enum { +    cnd001, +}; + +enum { +    SATA_CHAN_ENAB        = 0x40, /* SATA channel enable */ +    SATA_INT_GATE        = 0x41, /* SATA interrupt gating */ +    SATA_NATIVE_MODE    = 0x42, /* Native mode enable */ +    PATA_UDMA_TIMING    = 0xB3, /* PATA timing for DMA/ cable detect */ +    PATA_PIO_TIMING        = 0xAB, /* PATA timing register */ + +    PORT0            = (1 << 1), +    PORT1            = (1 << 0), +    ALL_PORTS        = PORT0 | PORT1, + +    NATIVE_MODE_ALL        = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4), + +    SATA_EXT_PHY        = (1 << 6), /* 0==use PATA, 1==ext phy */ +}; + +static int szx_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); +static int cnd001_scr_read(struct ata_link *link, unsigned int scr, u32 *val); +static int cnd001_scr_write(struct ata_link *link, unsigned int scr, u32 val); +static int szx_hardreset(struct ata_link *link, unsigned int *class, +                unsigned long deadline); + +static void szx_tf_load(struct ata_port *ap, const struct ata_taskfile *tf); + +static const struct pci_device_id szx_pci_tbl[] = { +    { PCI_VDEVICE(ZHAOXIN, 0x9002), cnd001 }, +    { PCI_VDEVICE(ZHAOXIN, 0x9003), cnd001 }, + +    { }    /* terminate list */ +}; + +static struct pci_driver szx_pci_driver = { +    .name            = DRV_NAME, +    .id_table        = szx_pci_tbl, +    .probe            = szx_init_one, +#ifdef CONFIG_PM_SLEEP +    .suspend        = ata_pci_device_suspend, +    .resume            = ata_pci_device_resume, +#endif +    .remove            = ata_pci_remove_one, +}; + +static struct scsi_host_template szx_sht = { +    ATA_BMDMA_SHT(DRV_NAME), +}; + +static struct ata_port_operations szx_base_ops = { +    .inherits        = &ata_bmdma_port_ops, +    .sff_tf_load        = szx_tf_load, +}; + +static struct ata_port_operations cnd001_ops = { +    .inherits        = &szx_base_ops, +    .hardreset        = szx_hardreset, +    .scr_read        = cnd001_scr_read, +    .scr_write        = cnd001_scr_write, +}; + +static struct ata_port_info cnd001_port_info = { +    .flags        = ATA_FLAG_SATA | ATA_FLAG_SLAVE_POSS, +    .pio_mask    = ATA_PIO4, +    .mwdma_mask    = ATA_MWDMA2, +    .udma_mask    = ATA_UDMA6, +    .port_ops    = &cnd001_ops, +}; + + +static int szx_hardreset(struct ata_link *link, unsigned int *class, +                unsigned long deadline) +{ +    int rc; + +    rc = sata_std_hardreset(link, class, deadline); +    if (!rc || rc == -EAGAIN) { +        struct ata_port *ap = link->ap; +        int pmp = link->pmp; +        int tmprc; + +        if (pmp) { +            ap->ops->sff_dev_select(ap, pmp); +            tmprc = ata_sff_wait_ready(&ap->link, deadline); +        } else { +            tmprc = ata_sff_wait_ready(link, deadline); +        } +        if (tmprc) +            ata_link_err(link, "COMRESET failed for wait (errno=%d)\n", +                    rc); +        else +            ata_link_err(link, "wait for bsy success\n"); + +        ata_link_err(link, "COMRESET success (errno=%d) ap=%d link %d\n", +                    rc, link->ap->port_no, link->pmp); +    } else { +        ata_link_err(link, "COMRESET failed (errno=%d) ap=%d link %d\n", +                    rc, link->ap->port_no, link->pmp); +    } +    return rc; +} + +static int cnd001_scr_read(struct ata_link *link, unsigned int scr, u32 *val) +{ +    static const u8 ipm_tbl[] = { 1, 2, 6, 0 }; +    struct pci_dev *pdev = to_pci_dev(link->ap->host->dev); +    int slot = 2 * link->ap->port_no + link->pmp; +    u32 v = 0; +    u8 raw; + +    switch (scr) { +    case SCR_STATUS: +        pci_read_config_byte(pdev, 0xA0 + slot, &raw); + +        /* read the DET field, bit0 and 1 of the config byte */ +        v |= raw & 0x03; + +        /* read the SPD field, bit4 of the configure byte */ +        v |= raw & 0x30; + +        /* read the IPM field, bit2 and 3 of the config byte */ +        v |= ((ipm_tbl[(raw >> 2) & 0x3])<<8); +        break; + +    case SCR_ERROR: +        /* devices other than 5287 uses 0xA8 as base */ +        WARN_ON(pdev->device != 0x9002 && pdev->device != 0x9003); +        pci_write_config_byte(pdev, 0x42, slot); +        pci_read_config_dword(pdev, 0xA8, &v); +        break; + +    case SCR_CONTROL: +        pci_read_config_byte(pdev, 0xA4 + slot, &raw); + +        /* read the DET field, bit0 and bit1 */ +        v |= ((raw & 0x02) << 1) | (raw & 0x01); + +        /* read the IPM field, bit2 and bit3 */ +        v |= ((raw >> 2) & 0x03) << 8; + +        break; + +    default: +        return -EINVAL; +    } + +    *val = v; +    return 0; +} + +static int cnd001_scr_write(struct ata_link *link, unsigned int scr, u32 val) +{ +    struct pci_dev *pdev = to_pci_dev(link->ap->host->dev); +    int slot = 2 * link->ap->port_no + link->pmp; +    u32 v = 0; + +    WARN_ON(pdev == NULL); + +    switch (scr) { +    case SCR_ERROR: +        /* devices 0x9002 uses 0xA8 as base */ +        WARN_ON(pdev->device != 0x9002 && pdev->device != 0x9003); +        pci_write_config_byte(pdev, 0x42, slot); +        pci_write_config_dword(pdev, 0xA8, val); +        return 0; + +    case SCR_CONTROL: +        /* set the DET field */ +        v |= ((val & 0x4) >> 1) | (val & 0x1); + +        /* set the IPM field */ +        v |= ((val >> 8) & 0x3) << 2; + + +        pci_write_config_byte(pdev, 0xA4 + slot, v); + + +        return 0; + +    default: +        return -EINVAL; +    } +} + + +/** + *    szx_tf_load - send taskfile registers to host controller + *    @ap: Port to which output is sent + *    @tf: ATA taskfile register set + * + *    Outputs ATA taskfile to standard ATA host controller. + * + *    This is to fix the internal bug of zx chipsets, which will + *    reset the device register after changing the IEN bit on ctl + *    register. + */ +static void szx_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) +{ +    struct ata_taskfile ttf; + +    if (tf->ctl != ap->last_ctl)  { +        ttf = *tf; +        ttf.flags |= ATA_TFLAG_DEVICE; +        tf = &ttf; +    } +    ata_sff_tf_load(ap, tf); +} + +static const unsigned int szx_bar_sizes[] = { +    8, 4, 8, 4, 16, 256 +}; + +static const unsigned int cnd001_bar_sizes0[] = { +    8, 4, 8, 4, 16, 0 +}; + +static const unsigned int cnd001_bar_sizes1[] = { +    8, 4, 0, 0, 16, 0 +}; + +static int cnd001_prepare_host(struct pci_dev *pdev, struct ata_host **r_host) +{ +    const struct ata_port_info *ppi0[] = { +        &cnd001_port_info, NULL +    }; +    const struct ata_port_info *ppi1[] = { +        &cnd001_port_info, &ata_dummy_port_info +    }; +    struct ata_host *host; +    int i, rc; + +    if (pdev->device == 0x9002) +        rc = ata_pci_bmdma_prepare_host(pdev, ppi0, &host); +    else if (pdev->device == 0x9003) +        rc = ata_pci_bmdma_prepare_host(pdev, ppi1, &host); +    else +        rc = -EINVAL; + +    if (rc) +        return rc; + +    *r_host = host; + +    /* cnd001 9002 hosts four sata ports as M/S of the two channels */ +    /* cnd001 9003 hosts two sata ports as M/S of the one channel */ +    for (i = 0; i < host->n_ports; i++) +        ata_slave_link_init(host->ports[i]); + +    return 0; +} + +static void szx_configure(struct pci_dev *pdev, int board_id) +{ +    u8 tmp8; + +    pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tmp8); +    dev_info(&pdev->dev, "routed to hard irq line %d\n", +        (int) (tmp8 & 0xf0) == 0xf0 ? 0 : tmp8 & 0x0f); + +    /* make sure SATA channels are enabled */ +    pci_read_config_byte(pdev, SATA_CHAN_ENAB, &tmp8); +    if ((tmp8 & ALL_PORTS) != ALL_PORTS) { +        dev_dbg(&pdev->dev, "enabling SATA channels (0x%x)\n", +            (int)tmp8); +        tmp8 |= ALL_PORTS; +        pci_write_config_byte(pdev, SATA_CHAN_ENAB, tmp8); +    } + +    /* make sure interrupts for each channel sent to us */ +    pci_read_config_byte(pdev, SATA_INT_GATE, &tmp8); +    if ((tmp8 & ALL_PORTS) != ALL_PORTS) { +        dev_dbg(&pdev->dev, "enabling SATA channel interrupts (0x%x)\n", +            (int) tmp8); +        tmp8 |= ALL_PORTS; +        pci_write_config_byte(pdev, SATA_INT_GATE, tmp8); +    } + +    /* make sure native mode is enabled */ +    pci_read_config_byte(pdev, SATA_NATIVE_MODE, &tmp8); +    if ((tmp8 & NATIVE_MODE_ALL) != NATIVE_MODE_ALL) { +        dev_dbg(&pdev->dev, +            "enabling SATA channel native mode (0x%x)\n", +            (int) tmp8); +        tmp8 |= NATIVE_MODE_ALL; +        pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8); +    } +} + +static int szx_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) +{ +    unsigned int i; +    int rc; +    struct ata_host *host = NULL; +    int board_id = (int) ent->driver_data; +    const unsigned int *bar_sizes; +    int legacy_mode = 0; + +    ata_print_version_once(&pdev->dev, DRV_VERSION); + +    if (pdev->device == 0x9002 || pdev->device == 0x9003) { +        if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { +            u8 tmp8, mask; + +            /* TODO: What if one channel is in native mode ... */ +            pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8); +            mask = (1 << 2) | (1 << 0); +            if ((tmp8 & mask) != mask) +                legacy_mode = 1; +        } +        if (legacy_mode) +            return -EINVAL; +    } + +    rc = pcim_enable_device(pdev); +    if (rc) +        return rc; + +    if (board_id == cnd001 && pdev->device == 0x9002) +        bar_sizes = &cnd001_bar_sizes0[0]; +    else if (board_id == cnd001 && pdev->device == 0x9003) +        bar_sizes = &cnd001_bar_sizes1[0]; +    else +        bar_sizes = &szx_bar_sizes[0]; + +    for (i = 0; i < ARRAY_SIZE(szx_bar_sizes); i++) { +        if ((pci_resource_start(pdev, i) == 0) || +            (pci_resource_len(pdev, i) < bar_sizes[i])) { +            if (bar_sizes[i] == 0) +                continue; + +            dev_err(&pdev->dev, +                "invalid PCI BAR %u (sz 0x%llx, val 0x%llx)\n", +                i, +                (unsigned long long)pci_resource_start(pdev, i), +                (unsigned long long)pci_resource_len(pdev, i)); + +            return -ENODEV; +        } +    } + +    switch (board_id) { +    case cnd001: +        rc = cnd001_prepare_host(pdev, &host); +        break; +    default: +        rc = -EINVAL; +    } +    if (rc) +        return rc; + +    szx_configure(pdev, board_id); + +    pci_set_master(pdev); +    return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, +                IRQF_SHARED, &szx_sht); +} + +module_pci_driver(szx_pci_driver); + +MODULE_AUTHOR("Yanchen:YanchenSun@zhaoxin.com"); +MODULE_DESCRIPTION("SCSI low-level driver for ZX SATA controllers"); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(pci, szx_pci_tbl); +MODULE_VERSION(DRV_VERSION); -- 2.20.1
1 0
0 0
  • ← Newer
  • 1
  • ...
  • 1752
  • 1753
  • 1754
  • 1755
  • 1756
  • 1757
  • 1758
  • ...
  • 1855
  • Older →

HyperKitty Powered by HyperKitty