|
| 1 | +From 575f76bdafb41dbe902c335ce246952df6c5cd3d Mon Sep 17 00:00:00 2001 |
| 2 | +From: Yuya Hamamachi <yuya.hamamachi.sx@renesas.com> |
| 3 | +Date: Fri, 29 May 2026 16:49:12 +0900 |
| 4 | +Subject: [PATCH] PCI: rcar-gen4: Limit Max_Read_Request_Size and |
| 5 | + Max_Payload_Size to 256 Bytes |
| 6 | + |
| 7 | +Port of Linux upstream patch 5d329c6aa55a to U-Boot. |
| 8 | + |
| 9 | +R-Car Gen4 PCIe controller has a hardware limitation of 256 Bytes |
| 10 | +Max_Payload_Size (MPS). PCIe specification indicates that the MPS |
| 11 | +must not exceed minimum MPS of any element along the packet path. |
| 12 | + |
| 13 | +R-Car Gen4 Reference Manual, chapter 104.4.8 states that MRRS must |
| 14 | +be set to 128 or 256 bytes. Using 512+ bytes causes transferred data |
| 15 | +to wrap at the 256 Byte boundary, corrupting writes from PCIe devices |
| 16 | +such as non-HMB NVMe SSDs (e.g. Crucial P5 Plus). This is a real |
| 17 | +risk in U-Boot since the MRRS reset default is 512 Bytes. |
| 18 | + |
| 19 | +Add an optional enable_device() hook to struct dm_pci_ops so that |
| 20 | +host controller drivers can apply per-device quirks during PCI |
| 21 | +enumeration. rcar-gen4 implements this hook to clamp both MPS and |
| 22 | +MRRS to 256 Bytes for every device on its bus. Other controllers |
| 23 | +are unaffected (NULL hook is not called). |
| 24 | + |
| 25 | +Upstream-Status: Backport [5d329c6aa55acbd63b26cbf806d3751da73c7806] |
| 26 | +Fixes: 0d0c551011df ("PCI: rcar-gen4: Add R-Car Gen4 PCIe controller support for host mode") |
| 27 | +Signed-off-by: Yuya Hamamachi <yuxia228@gmail.com> |
| 28 | + |
| 29 | +Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
| 30 | +--- |
| 31 | + drivers/pci/pci-rcar-gen4.c | 58 +++++++++++++++++++++++++++++++++++++ |
| 32 | + drivers/pci/pci_auto.c | 9 ++++++ |
| 33 | + include/pci.h | 13 +++++++++ |
| 34 | + 3 files changed, 80 insertions(+) |
| 35 | + |
| 36 | +diff --git a/drivers/pci/pci-rcar-gen4.c b/drivers/pci/pci-rcar-gen4.c |
| 37 | +index e165271f58c..76a195f8406 100644 |
| 38 | +--- a/drivers/pci/pci-rcar-gen4.c |
| 39 | ++++ b/drivers/pci/pci-rcar-gen4.c |
| 40 | +@@ -573,9 +573,67 @@ static int rcar_gen4_pcie_of_to_plat(struct udevice *dev) |
| 41 | + return 0; |
| 42 | + } |
| 43 | + |
| 44 | ++static int rcar_gen4_pcie_enable_device(struct udevice *ctlr, |
| 45 | ++ struct udevice *dev) |
| 46 | ++{ |
| 47 | ++ int pcie_off; |
| 48 | ++ u16 devctl; |
| 49 | ++ |
| 50 | ++ /* Only PCIe-capable devices have the Express capability. */ |
| 51 | ++ pcie_off = dm_pci_find_capability(dev, PCI_CAP_ID_EXP); |
| 52 | ++ if (!pcie_off) |
| 53 | ++ return 0; |
| 54 | ++ |
| 55 | ++ dm_pci_read_config16(dev, pcie_off + PCI_EXP_DEVCTL, &devctl); |
| 56 | ++ |
| 57 | ++ /* |
| 58 | ++ * R-Car Gen4 PCIe controller has a hardware limitation of 256 Bytes |
| 59 | ++ * Max_Payload_Size (MPS). PCIe specification indicates that the MPS |
| 60 | ++ * must not exceed minimum MPS of any element along the packet path. |
| 61 | ++ * Force limit Max_Payload_Size to at most 256 Bytes for each device |
| 62 | ++ * connected to this PCIe controller. |
| 63 | ++ * |
| 64 | ++ * For details, refer to chapter "104.1.1 Features" in either of: |
| 65 | ++ * R-Car S4 R19UH0161EJ0130 Rev.1.30 Jun. 16, 2025 or |
| 66 | ++ * R-Car V4H R19UH0186EJ0130 Rev.1.30 Apr. 21, 2025 or |
| 67 | ++ * R-Car V4M R19UH0217EJ0100 Rev.1.00 Dec. 12, 2025. |
| 68 | ++ */ |
| 69 | ++ if ((devctl & PCI_EXP_DEVCTL_PAYLOAD) > PCI_EXP_DEVCTL_PAYLOAD_256B) { |
| 70 | ++ printf("PCI: Limiting MPS to 256 bytes\n"); |
| 71 | ++ dm_pci_clrset_config16(dev, pcie_off + PCI_EXP_DEVCTL, |
| 72 | ++ PCI_EXP_DEVCTL_PAYLOAD, |
| 73 | ++ PCI_EXP_DEVCTL_PAYLOAD_256B); |
| 74 | ++ } |
| 75 | ++ |
| 76 | ++ /* |
| 77 | ++ * R-Car Gen4 Reference Manual, chapter 104.4.8 Usage notes for |
| 78 | ++ * MRRS (Max Read Request Size) states: |
| 79 | ++ * Please set "Max Read Request Size" to 128 bytes or 256 bytes. |
| 80 | ++ * If "Max Read Request Size" is set to anything other than the |
| 81 | ++ * above, the transferred data will not match the expected value. |
| 82 | ++ * This limitation also seems to apply to devices issuing MRd TLP. |
| 83 | ++ * Force limit Max_Read_Request_Size to at most 256 Bytes for each |
| 84 | ++ * device connected to this PCIe controller. |
| 85 | ++ * |
| 86 | ++ * For details, refer to aforementioned chapter in either of: |
| 87 | ++ * R-Car S4 R19UH0161EJ0130 Rev.1.30 Jun. 16, 2025 or |
| 88 | ++ * R-Car V4H R19UH0186EJ0130 Rev.1.30 Apr. 21, 2025 or |
| 89 | ++ * R-Car V4M R19UH0217EJ0100 Rev.1.00 Dec. 12, 2025. |
| 90 | ++ */ |
| 91 | ++ if ((devctl & PCI_EXP_DEVCTL_READRQ) > PCI_EXP_DEVCTL_READRQ_256B) { |
| 92 | ++ printf("PCI: Limiting MRRS to 256 bytes\n"); |
| 93 | ++ dm_pci_clrset_config16(dev, pcie_off + PCI_EXP_DEVCTL, |
| 94 | ++ PCI_EXP_DEVCTL_READRQ, |
| 95 | ++ PCI_EXP_DEVCTL_READRQ_256B); |
| 96 | ++ } |
| 97 | ++ |
| 98 | ++ return 0; |
| 99 | ++} |
| 100 | ++ |
| 101 | + static const struct dm_pci_ops rcar_gen4_pcie_ops = { |
| 102 | + .read_config = pcie_dw_read_config, |
| 103 | + .write_config = pcie_dw_write_config, |
| 104 | ++ .enable_device = rcar_gen4_pcie_enable_device, |
| 105 | + }; |
| 106 | + |
| 107 | + static const struct udevice_id rcar_gen4_pcie_ids[] = { |
| 108 | +diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c |
| 109 | +index 4a1c782be36..1d632c33acb 100644 |
| 110 | +--- a/drivers/pci/pci_auto.c |
| 111 | ++++ b/drivers/pci/pci_auto.c |
| 112 | +@@ -181,6 +181,15 @@ static void dm_pciauto_setup_device(struct udevice *dev, |
| 113 | + dm_pci_write_config8(dev, PCI_CACHE_LINE_SIZE, |
| 114 | + CFG_SYS_PCI_CACHE_LINE_SIZE); |
| 115 | + dm_pci_write_config8(dev, PCI_LATENCY_TIMER, 0x80); |
| 116 | ++ |
| 117 | ++ /* Call optional host-controller-specific per-device setup hook */ |
| 118 | ++ { |
| 119 | ++ struct udevice *ctlr = pci_get_controller(dev); |
| 120 | ++ const struct dm_pci_ops *ops = pci_get_ops(ctlr); |
| 121 | ++ |
| 122 | ++ if (ops->enable_device) |
| 123 | ++ ops->enable_device(ctlr, dev); |
| 124 | ++ } |
| 125 | + } |
| 126 | + |
| 127 | + /* |
| 128 | +diff --git a/include/pci.h b/include/pci.h |
| 129 | +index 4b0facd6dcf..21d96056339 100644 |
| 130 | +--- a/include/pci.h |
| 131 | ++++ b/include/pci.h |
| 132 | +@@ -901,6 +901,19 @@ struct dm_pci_ops { |
| 133 | + */ |
| 134 | + int (*write_config)(struct udevice *bus, pci_dev_t bdf, uint offset, |
| 135 | + ulong value, enum pci_size_t size); |
| 136 | ++ /** |
| 137 | ++ * enable_device() - Optional per-device setup callback |
| 138 | ++ * |
| 139 | ++ * Called during PCI enumeration after each child device has been |
| 140 | ++ * configured. Allows the host controller driver to apply |
| 141 | ++ * controller-specific quirks (e.g. MPS/MRRS limits) to every |
| 142 | ++ * device on its bus. |
| 143 | ++ * |
| 144 | ++ * @bus: Host controller (root bus) |
| 145 | ++ * @dev: Child device being configured |
| 146 | ++ * @return 0 if OK, -ve on error |
| 147 | ++ */ |
| 148 | ++ int (*enable_device)(struct udevice *bus, struct udevice *dev); |
| 149 | + }; |
| 150 | + |
| 151 | + /* Get access to a PCI bus' operations */ |
| 152 | +-- |
| 153 | +2.34.1 |
| 154 | + |
0 commit comments