* [PATCH v9 0/3] media: nxp: Add CSI Pixel Formatter support
From: Guoniu Zhou @ 2026-05-26 8:57 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Laurent Pinchart, Frank Li, Abel Vesa, Peng Fan,
Michael Turquette, Stephen Boyd
Cc: imx, linux-media, devicetree, linux-arm-kernel, linux-kernel,
linux-clk, Guoniu Zhou, Guoniu Zhou, Frank Li,
Krzysztof Kozlowski
CSI Pixel Formatter is a module found on i.MX95. It could unpack the
pixels received by the formatter and reformat them to meet the pixel
link format requirement.
This patch series adds a new V4L2 driver for CSI Pixel Formatter.
v4l2-compliance 1.28.1-5233, 64 bits, 64-bit time_t
v4l2-compliance SHA: fc15e229d9d3 2024-07-23 19:22:15
Compliance test for device /dev/v4l-subdev9:
Driver Info:
Driver version : 7.1.0
Capabilities : 0x00000002
Streams Support
Client Capabilities: 0x0000000000000003
streams interval-uses-which
Required ioctls:
test VIDIOC_SUDBEV_QUERYCAP: OK
test invalid ioctls: OK
Allow for multiple opens:
test second /dev/v4l-subdev9 open: OK
test VIDIOC_SUBDEV_QUERYCAP: OK
test for unlimited opens: OK
Debug ioctls:
test VIDIOC_LOG_STATUS: OK (Not Supported)
Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 0 Audio Inputs: 0 Tuners: 0
Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0
Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
test VIDIOC_G/S_EDID: OK (Not Supported)
Sub-Device routing ioctls:
test Try VIDIOC_SUBDEV_G_ROUTING/VIDIOC_SUBDEV_S_ROUTING: OK
test Active VIDIOC_SUBDEV_G_ROUTING/VIDIOC_SUBDEV_S_ROUTING: OK
Control ioctls:
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK (Not Supported)
test VIDIOC_QUERYCTRL: OK (Not Supported)
test VIDIOC_G/S_CTRL: OK (Not Supported)
test VIDIOC_G/S/TRY_EXT_CTRLS: OK (Not Supported)
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK (Not Supported)
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 0 Private Controls: 0
Format ioctls:
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK (Not Supported)
test VIDIOC_G/S_PARM: OK (Not Supported)
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK (Not Supported)
test VIDIOC_TRY_FMT: OK (Not Supported)
test VIDIOC_S_FMT: OK (Not Supported)
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK (Not Supported)
test Composing: OK (Not Supported)
test Scaling: OK (Not Supported)
Codec ioctls:
test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)
Buffer ioctls:
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK (Not Supported)
test CREATE_BUFS maximum buffers: OK
test VIDIOC_REMOVE_BUFS: OK
test VIDIOC_EXPBUF: OK (Not Supported)
test Requests: OK (Not Supported)
Total for device /dev/v4l-subdev9: 47, Succeeded: 47, Failed: 0, Warnings: 0
Signed-off-by: Guoniu Zhou <guoniu.zhou@nxp.com>
---
Changes in v9:
- [NEW PATCH] Fix formatter as syscon child node issue
- Link to v8: https://lore.kernel.org/r/20260525-csi_formatter-v8-0-6b646231224b@oss.nxp.com
Changes in v8:
- Rebase to latest media/next
- Use standard port reference instead of video-interfaces.yaml
- Add parent syscon node in example to show device integration
- Remove fmt field and look up format from subdev state instead
- Unify function and structure naming to use csi_formatter_ prefix
- Remove misleading alignment comment from set_fmt function
- Optimize get_frame_desc to call once per start_stream
- Replace V4L2_FRAME_DESC_ENTRY_MAX with CSI_FORMATTER_VC_NUM in loops
- Remove redundant debug message in enable_streams
- Use MEDIA_PAD_FL_MUST_CONNECT flag instead of manual link check
- Link to v7: https://lore.kernel.org/r/20260518-csi_formatter-v7-0-562b750557e3@oss.nxp.com
Changes in v7:
- Change compatible to imx95-csi-formatter as IP is i.MX95 specific per Marco's suggestion
Link: https://lore.kernel.org/linux-media/20260511-csi_formatter-v6-0-01028e312e2b@oss.nxp.com/T/#mcd135b3de179b3cb69daa1fd6e0e8e27c85b3332
- Update references from imx9 to imx95 for consistency with dt-bindings
- Enable PM runtime before async registration
- Link to v6: https://lore.kernel.org/r/20260511-csi_formatter-v6-0-01028e312e2b@oss.nxp.com
Changes in v6:
- Rebase to latest media/next
- Update v4l2-compliace test
- Remove unused header includes
- Unify macro naming: VCx/VCX -> VC and parameter x -> vc
- Remove unused format field from csi_formatter struct
- Use compact initialization for formats array
- Make find_csi_format() return NULL instead of default format
- Use unsigned int for array index in find_csi_format()
- Add err_ prefix to error handling labels
- Add v4l2_subdev_cleanup() and reorder cleanup sequence
- Update enable_streams debug output format
- Rename VC_MAX to VC_NUM and fix boundary check
- Update CSI formatter Kconfig description
- Use v4l2_subdev_get_frame_desc_passthrough() helper
- Fix error paths in async registration and probe
- Add mutex to protect enabled_streams
- Switch to devm_pm_runtime_enable()
- Remove redundant num_routes check in set_routing
- Optimize get_index_by_dt() and add warning for unsupported type
- csi_formatter_start/stop_stream: Process all streams in mask
- Link to v5: https://lore.kernel.org/r/20260123-csi_formatter-v5-0-d5b803f867bf@nxp.com
Changes in v5:
- Remove CSI_FORMATTER_DRV_NAME macro since only use once.
- Remove sd->owner = THIS_MODULE;
- Simplify code by using DEFINE_RUNTIME_DEV_PM_OPS macro.
- Link to v4: https://lore.kernel.org/r/20260122-csi_formatter-v4-0-6f6fcad1c33a@nxp.com
Changes in v4:
- Rebase to latest media/next.
- Add comments to describe the index field in formatter_dt_to_index_map array.
- Link to v3: https://lore.kernel.org/r/20251219-csi_formatter-v3-0-8680d6d87091@nxp.com
Changes in v3:
- Rename nxp,imx9-csi-formatter.yaml to fsl,imx9-csi-formatter.yaml.
- Drop clock-names property.
- Drop macro IMX95_PD_CAMERA definition and use a constant directly.
[PATCH 1/2] media: dt-bindings: Add CSI Pixel Formatter DT bindings
- Remove the assignment driver.owner = THIS_MODULE.
- Assign struct fwnode_handle *ep __free(fwnode_handle) when definition.
- Update yaml file name for csi formatter in MAINTAINERS.
[PATCH 2/2] media: nxp: Add i.MX9 CSI pixel formatter v4l2 driver
- Link to v2: https://lore.kernel.org/r/20251217-csi_formatter-v2-0-62168af80210@nxp.com
Changes in v2:
- Delete "|" for description key.
- Add empty line between child node and property.
- Delete labels for endpoint of child nodes.
[PATCH 1/2] media: dt-bindings: Add CSI Pixel Formatter DT bindings
- Update commit message.
- Use the value defined by bellow macros directly since they are used only once.
#define CSI_FORMATTER_DEF_MBUS_CODE MEDIA_BUS_FMT_UYVY8_1X16
#define CSI_FORMATTER_DEF_PIX_WIDTH 1920U
#define CSI_FORMATTER_DEF_PIX_HEIGHT 1080U
#define CSI_FORMATTER_MAX_PIX_WIDTH 0xffff
#define CSI_FORMATTER_MAX_PIX_HEIGHT 0xffff
- Use macro pm_ptr() to fix build warning when CONFIG_PM is disabled.
- Finish route loop by break statement, instead of goto.
- Return dev_err_probe() when meet errors in probe() function instead of dev_err().
- Remove MODULE_ALIAS().
- Refine .enable(.dsable)_stream callback implementation, include bellow changes:
Add stream checking.
Fix potential pm runtime count unbalance issue.
Add stop stream error handling when enabling remote subdev stream.
- Use __free(fwnode_handle) to drop reference to a device node automatically.
[PATCH 2/2] media: nxp: Add i.MX9 CSI pixel formatter v4l2 driver
- Link to v1: https://lore.kernel.org/r/20251203-csi_formatter-v1-0-eb9e1147b49e@nxp.com
---
Guoniu Zhou (3):
dt-bindings: clock: imx95-blk-ctl: Allow child nodes
media: dt-bindings: Add CSI Pixel Formatter DT bindings
media: nxp: Add i.MX95 CSI pixel formatter v4l2 driver
.../bindings/clock/nxp,imx95-blk-ctl.yaml | 11 +
.../bindings/media/fsl,imx95-csi-formatter.yaml | 96 +++
MAINTAINERS | 8 +
drivers/media/platform/nxp/Kconfig | 14 +
drivers/media/platform/nxp/Makefile | 1 +
drivers/media/platform/nxp/imx95-csi-formatter.c | 758 +++++++++++++++++++++
6 files changed, 888 insertions(+)
---
base-commit: a3d78e74dd3ed04797ea351edb7f0a19b961c063
change-id: 20251125-csi_formatter-e6d29316dce6
Best regards,
--
Guoniu Zhou <guoniu.zhou@oss.nxp.com>
^ permalink raw reply
* [PATCH v5 3/4] PCI: tegra: Add Tegra264 support
From: Thierry Reding @ 2026-05-26 8:53 UTC (permalink / raw)
To: Bjorn Helgaas, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Thierry Reding, Jonathan Hunter, Karthikeyan Mitran,
Hou Zhiqiang, Thomas Petazzoni, Pali Rohár, Michal Simek,
Kevin Xie, Thierry Reding, Aksh Garg
Cc: linux-pci, devicetree, linux-tegra, linux-kernel,
linux-arm-kernel, Thierry Reding, Manikanta Maddireddy
In-Reply-To: <20260526-tegra264-pcie-v5-0-84a813b979d7@nvidia.com>
From: Thierry Reding <treding@nvidia.com>
Add a driver for the PCIe controller found on NVIDIA Tegra264 SoCs. The
driver is very small, with its main purpose being to set up the address
translation registers and then creating a standard PCI host using ECAM.
Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
Changes in v5:
- make PCIE_TEGRA264 symbol tristate
- drop dependency on PCI_MSI
- reorganize tegra264_pcie struct
- use standard wake-gpios property
- rename tegra264_pcie_bpmp_set_rp_state() to tegra264_pcie_power_off()
- use dev_err() instead of dev_info() for some error messages
- add clarifying comment as to why bandwidth requests aren't fatal
- address some compiler warnings on 32-bit physical address platforms
- drop needless comments
- explicitly deinitialize controller on suspend
- use devm_pm_runtime_active_enabled()
- rename "free" label to "free_ecam"
- use dev_err_probe() in more places
- reselect default pin state during resume, not probe
- return early on absence of wake GPIO
- simplify BW value calculation
Changes in v2:
- specify generations applicable for PCI_TEGRA driver to avoid confusion
- drop SPDX-FileCopyrightText tag
- rename link_state to link_up to clarify meaning
- replace memset() by an empty initializer
- sanity-check only enable BAR regions
- bring PCI link out of reset in case firmware didn't
- use common wait times instead of defining our own
- use core helpers to parse and print PCI link speed
- fix multi-line comment
- use dev_err_probe() more ubiquitously
- fix probe sequence and error cleanup
- use DEFINE_NOIRQ_DEV_PM_OPS() to avoid warnings for !PM_SUSPEND
- reuse more standard registers and remove unused register definitions
- use %pe and ERR_PTR() to print symbolic errors
- add signed-off-by from Manikanta as the original author
- add myself as author after significantly modifying the driver
---
drivers/pci/controller/Kconfig | 9 +-
drivers/pci/controller/Makefile | 1 +
drivers/pci/controller/pcie-tegra264.c | 544 +++++++++++++++++++++++++++++++++
3 files changed, 553 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 2247709ef6d6..dde2f59fef7a 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -255,7 +255,14 @@ config PCI_TEGRA
select IRQ_MSI_LIB
help
Say Y here if you want support for the PCIe host controller found
- on NVIDIA Tegra SoCs.
+ on NVIDIA Tegra SoCs (Tegra20 through Tegra186).
+
+config PCIE_TEGRA264
+ tristate "NVIDIA Tegra264 PCIe controller"
+ depends on ARCH_TEGRA || COMPILE_TEST
+ help
+ Say Y here if you want support for the PCIe host controller found
+ on NVIDIA Tegra264 SoCs.
config PCIE_RCAR_HOST
bool "Renesas R-Car PCIe controller (host mode)"
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index ac8db283f0fe..d478743b5142 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_PCI_HYPERV_INTERFACE) += pci-hyperv-intf.o
obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o
obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
+obj-$(CONFIG_PCIE_TEGRA264) += pcie-tegra264.o
obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
obj-$(CONFIG_PCIE_RCAR_HOST) += pcie-rcar.o pcie-rcar-host.o
obj-$(CONFIG_PCIE_RCAR_EP) += pcie-rcar.o pcie-rcar-ep.o
diff --git a/drivers/pci/controller/pcie-tegra264.c b/drivers/pci/controller/pcie-tegra264.c
new file mode 100644
index 000000000000..0b8e0f724e25
--- /dev/null
+++ b/drivers/pci/controller/pcie-tegra264.c
@@ -0,0 +1,544 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * PCIe host controller driver for Tegra264 SoC
+ *
+ * Copyright (c) 2022-2026, NVIDIA CORPORATION. All rights reserved.
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/of_pci.h>
+#include <linux/of_platform.h>
+#include <linux/pci-ecam.h>
+#include <linux/pci.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include <soc/tegra/bpmp.h>
+#include <soc/tegra/bpmp-abi.h>
+#include <soc/tegra/fuse.h>
+
+#include "../pci.h"
+
+/* XAL registers */
+#define XAL_RC_ECAM_BASE_HI 0x00
+#define XAL_RC_ECAM_BASE_LO 0x04
+#define XAL_RC_ECAM_BUSMASK 0x08
+#define XAL_RC_IO_BASE_HI 0x0c
+#define XAL_RC_IO_BASE_LO 0x10
+#define XAL_RC_IO_LIMIT_HI 0x14
+#define XAL_RC_IO_LIMIT_LO 0x18
+#define XAL_RC_MEM_32BIT_BASE_HI 0x1c
+#define XAL_RC_MEM_32BIT_BASE_LO 0x20
+#define XAL_RC_MEM_32BIT_LIMIT_HI 0x24
+#define XAL_RC_MEM_32BIT_LIMIT_LO 0x28
+#define XAL_RC_MEM_64BIT_BASE_HI 0x2c
+#define XAL_RC_MEM_64BIT_BASE_LO 0x30
+#define XAL_RC_MEM_64BIT_LIMIT_HI 0x34
+#define XAL_RC_MEM_64BIT_LIMIT_LO 0x38
+#define XAL_RC_BAR_CNTL_STANDARD 0x40
+#define XAL_RC_BAR_CNTL_STANDARD_IOBAR_EN BIT(0)
+#define XAL_RC_BAR_CNTL_STANDARD_32B_BAR_EN BIT(1)
+#define XAL_RC_BAR_CNTL_STANDARD_64B_BAR_EN BIT(2)
+
+/* XTL registers */
+#define XTL_RC_PCIE_CFG_LINK_STATUS 0x5a
+
+#define XTL_RC_MGMT_PERST_CONTROL 0x218
+#define XTL_RC_MGMT_PERST_CONTROL_PERST_O_N BIT(0)
+
+#define XTL_RC_MGMT_CLOCK_CONTROL 0x47c
+#define XTL_RC_MGMT_CLOCK_CONTROL_PEX_CLKREQ_I_N_PIN_USE_CONV_TO_PRSNT BIT(9)
+
+struct tegra264_pcie {
+ struct device *dev;
+
+ /* I/O memory */
+ void __iomem *xal;
+ void __iomem *xtl;
+ void __iomem *ecam;
+
+ /* bridge configuration */
+ struct pci_config_window *cfg;
+ struct pci_host_bridge *bridge;
+
+ /* wake IRQ */
+ struct gpio_desc *wake_gpio;
+ unsigned int wake_irq;
+
+ /* BPMP and bandwidth management */
+ struct icc_path *icc_path;
+ struct tegra_bpmp *bpmp;
+ u32 ctl_id;
+
+ bool link_up;
+};
+
+static int tegra264_pcie_parse_dt(struct tegra264_pcie *pcie)
+{
+ struct device *dev = pcie->dev;
+ int err;
+
+ pcie->wake_gpio = devm_gpiod_get_optional(dev, "wake", GPIOD_IN);
+ if (IS_ERR(pcie->wake_gpio))
+ return PTR_ERR(pcie->wake_gpio);
+
+ if (!pcie->wake_gpio)
+ return 0;
+
+ device_init_wakeup(dev, true);
+
+ err = gpiod_to_irq(pcie->wake_gpio);
+ if (err < 0)
+ return dev_err_probe(dev, err, "failed to get wake IRQ\n");
+
+ pcie->wake_irq = (unsigned int)err;
+
+ return 0;
+}
+
+static void tegra264_pcie_power_off(struct tegra264_pcie *pcie)
+{
+ struct tegra_bpmp_message msg = {};
+ struct mrq_pcie_request req = {};
+ int err;
+
+ req.cmd = CMD_PCIE_RP_CONTROLLER_OFF;
+ req.rp_ctrlr_off.rp_controller = pcie->ctl_id;
+
+ msg.mrq = MRQ_PCIE;
+ msg.tx.data = &req;
+ msg.tx.size = sizeof(req);
+
+ err = tegra_bpmp_transfer(pcie->bpmp, &msg);
+ if (err)
+ dev_err(pcie->dev, "failed to turn off PCIe #%u: %pe\n",
+ pcie->ctl_id, ERR_PTR(err));
+
+ if (msg.rx.ret)
+ dev_err(pcie->dev, "failed to turn off PCIe #%u: %d\n",
+ pcie->ctl_id, msg.rx.ret);
+}
+
+static void tegra264_pcie_icc_set(struct tegra264_pcie *pcie)
+{
+ u32 value, speed, width;
+ int err;
+
+ value = readw(pcie->ecam + XTL_RC_PCIE_CFG_LINK_STATUS);
+ speed = FIELD_GET(PCI_EXP_LNKSTA_CLS, value);
+ width = FIELD_GET(PCI_EXP_LNKSTA_NLW, value);
+
+ value = Mbps_to_icc(width * PCIE_SPEED2MBS_ENC(speed));
+
+ /*
+ * We don't want to error out here because a boot-critical device
+ * could be connected to this root port. Failure to set the bandwidth
+ * request may have an adverse impact on performance, but it is not
+ * generally fatal, so we opt to continue regardless so that users
+ * get a chance to fix things.
+ */
+ err = icc_set_bw(pcie->icc_path, value, value);
+ if (err < 0)
+ dev_err(pcie->dev,
+ "failed to request bandwidth (%u MBps): %pe\n",
+ value, ERR_PTR(err));
+}
+
+/*
+ * The various memory regions used by the controller (I/O, memory, ECAM) are
+ * set up during early boot and have hardware-level protections in place. If
+ * the DT ranges don't match what's been setup, the controller won't be able
+ * to write the address endpoints properly, so make sure to validate that DT
+ * and firmware programming agree on these ranges.
+ */
+static bool tegra264_pcie_check_ranges(struct platform_device *pdev)
+{
+ struct tegra264_pcie *pcie = platform_get_drvdata(pdev);
+ struct device_node *np = pcie->dev->of_node;
+ struct of_pci_range_parser parser;
+ phys_addr_t phys, limit, hi, lo;
+ struct of_pci_range range;
+ struct resource *res;
+ bool status = true;
+ u32 value;
+ int err;
+
+ err = of_pci_range_parser_init(&parser, np);
+ if (err < 0)
+ return false;
+
+ for_each_of_pci_range(&parser, &range) {
+ unsigned int addr_hi, addr_lo, limit_hi, limit_lo, enable;
+ unsigned long type = range.flags & IORESOURCE_TYPE_BITS;
+ phys_addr_t start, end, mask;
+ const char *region = NULL;
+
+ end = range.cpu_addr + range.size - 1;
+ start = range.cpu_addr;
+
+ switch (type) {
+ case IORESOURCE_IO:
+ addr_hi = XAL_RC_IO_BASE_HI;
+ addr_lo = XAL_RC_IO_BASE_LO;
+ limit_hi = XAL_RC_IO_LIMIT_HI;
+ limit_lo = XAL_RC_IO_LIMIT_LO;
+ enable = XAL_RC_BAR_CNTL_STANDARD_IOBAR_EN;
+ mask = SZ_64K - 1;
+ region = "I/O";
+ break;
+
+ case IORESOURCE_MEM:
+ if (range.flags & IORESOURCE_PREFETCH) {
+ addr_hi = XAL_RC_MEM_64BIT_BASE_HI;
+ addr_lo = XAL_RC_MEM_64BIT_BASE_LO;
+ limit_hi = XAL_RC_MEM_64BIT_LIMIT_HI;
+ limit_lo = XAL_RC_MEM_64BIT_LIMIT_LO;
+ enable = XAL_RC_BAR_CNTL_STANDARD_64B_BAR_EN;
+ region = "prefetchable memory";
+ } else {
+ addr_hi = XAL_RC_MEM_32BIT_BASE_HI;
+ addr_lo = XAL_RC_MEM_32BIT_BASE_LO;
+ limit_hi = XAL_RC_MEM_32BIT_LIMIT_HI;
+ limit_lo = XAL_RC_MEM_32BIT_LIMIT_LO;
+ enable = XAL_RC_BAR_CNTL_STANDARD_32B_BAR_EN;
+ region = "memory";
+ }
+
+ mask = SZ_1M - 1;
+ break;
+ }
+
+ /* not interested in anything that's not I/O or memory */
+ if (!region)
+ continue;
+
+ /* don't check regions that haven't been enabled */
+ value = readl(pcie->xal + XAL_RC_BAR_CNTL_STANDARD);
+ if ((value & enable) == 0)
+ continue;
+
+ hi = readl(pcie->xal + addr_hi);
+ lo = readl(pcie->xal + addr_lo);
+ phys = ((hi << 16) << 16) | lo;
+
+ hi = readl(pcie->xal + limit_hi);
+ lo = readl(pcie->xal + limit_lo);
+ limit = ((hi << 16) << 16) | lo | mask;
+
+ if (phys != start || limit != end) {
+ dev_err(pcie->dev,
+ "%s region mismatch: %pap-%pap -> %pap-%pap\n",
+ region, &phys, &limit, &start, &end);
+ status = false;
+ }
+ }
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ecam");
+ if (!res)
+ return false;
+
+ hi = readl(pcie->xal + XAL_RC_ECAM_BASE_HI);
+ lo = readl(pcie->xal + XAL_RC_ECAM_BASE_LO);
+ phys = ((hi << 16) << 16) | lo;
+
+ value = readl(pcie->xal + XAL_RC_ECAM_BUSMASK);
+ limit = phys + ((value + 1) << 20) - 1;
+
+ if (phys != res->start || limit != res->end) {
+ dev_err(pcie->dev,
+ "ECAM region mismatch: %pap-%pap -> %pap-%pap\n",
+ &phys, &limit, &res->start, &res->end);
+ status = false;
+ }
+
+ return status;
+}
+
+static bool tegra264_pcie_link_up(struct tegra264_pcie *pcie,
+ enum pci_bus_speed *speed)
+{
+ u16 value = readw(pcie->ecam + XTL_RC_PCIE_CFG_LINK_STATUS);
+
+ if (value & PCI_EXP_LNKSTA_DLLLA) {
+ if (speed)
+ *speed = pcie_link_speed[FIELD_GET(PCI_EXP_LNKSTA_CLS,
+ value)];
+
+ return true;
+ }
+
+ return false;
+}
+
+static void tegra264_pcie_init(struct tegra264_pcie *pcie)
+{
+ enum pci_bus_speed speed;
+ unsigned int i;
+ u32 value;
+
+ /* bring the endpoint out of reset */
+ value = readl(pcie->xtl + XTL_RC_MGMT_PERST_CONTROL);
+ value |= XTL_RC_MGMT_PERST_CONTROL_PERST_O_N;
+ writel(value, pcie->xtl + XTL_RC_MGMT_PERST_CONTROL);
+
+ if (!tegra_is_silicon()) {
+ dev_info(pcie->dev,
+ "skipping link state for PCIe #%u in simulation\n",
+ pcie->ctl_id);
+ pcie->link_up = true;
+ return;
+ }
+
+ for (i = 0; i < PCIE_LINK_WAIT_MAX_RETRIES; i++) {
+ if (tegra264_pcie_link_up(pcie, NULL))
+ break;
+
+ usleep_range(PCIE_LINK_WAIT_US_MIN, PCIE_LINK_WAIT_US_MAX);
+ }
+
+ if (tegra264_pcie_link_up(pcie, &speed)) {
+ msleep(PCIE_RESET_CONFIG_WAIT_MS);
+ dev_info(pcie->dev, "PCIe #%u link is up (speed: %s)\n",
+ pcie->ctl_id, pci_speed_string(speed));
+ tegra264_pcie_icc_set(pcie);
+ pcie->link_up = true;
+ } else {
+ dev_info(pcie->dev, "PCIe #%u link is down\n", pcie->ctl_id);
+
+ value = readl(pcie->xtl + XTL_RC_MGMT_CLOCK_CONTROL);
+
+ /*
+ * Set link state only when link fails and no hot-plug feature
+ * is present.
+ */
+ if ((value & XTL_RC_MGMT_CLOCK_CONTROL_PEX_CLKREQ_I_N_PIN_USE_CONV_TO_PRSNT) == 0) {
+ dev_info(pcie->dev,
+ "PCIe #%u link is down and not hotplug-capable, turning off\n",
+ pcie->ctl_id);
+ tegra264_pcie_power_off(pcie);
+ pcie->link_up = false;
+ } else {
+ pcie->link_up = true;
+ }
+ }
+}
+
+static void tegra264_pcie_deinit(struct tegra264_pcie *pcie)
+{
+ u32 value;
+
+ /* take the endpoint into reset */
+ value = readl(pcie->xtl + XTL_RC_MGMT_PERST_CONTROL);
+ value &= ~XTL_RC_MGMT_PERST_CONTROL_PERST_O_N;
+ writel(value, pcie->xtl + XTL_RC_MGMT_PERST_CONTROL);
+}
+
+static int tegra264_pcie_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct pci_host_bridge *bridge;
+ struct tegra264_pcie *pcie;
+ struct resource_entry *bus;
+ struct resource *res;
+ int err;
+
+ bridge = devm_pci_alloc_host_bridge(dev, sizeof(struct tegra264_pcie));
+ if (!bridge)
+ return dev_err_probe(dev, -ENOMEM,
+ "failed to allocate host bridge\n");
+
+ pcie = pci_host_bridge_priv(bridge);
+ platform_set_drvdata(pdev, pcie);
+ pcie->bridge = bridge;
+ pcie->dev = dev;
+
+ err = tegra264_pcie_parse_dt(pcie);
+ if (err < 0)
+ return dev_err_probe(dev, err, "failed to parse device tree\n");
+
+ pcie->xal = devm_platform_ioremap_resource_byname(pdev, "xal");
+ if (IS_ERR(pcie->xal))
+ return dev_err_probe(dev, PTR_ERR(pcie->xal),
+ "failed to map XAL memory\n");
+
+ pcie->xtl = devm_platform_ioremap_resource_byname(pdev, "xtl-pri");
+ if (IS_ERR(pcie->xtl))
+ return dev_err_probe(dev, PTR_ERR(pcie->xtl),
+ "failed to map XTL-PRI memory\n");
+
+ bus = resource_list_first_type(&bridge->windows, IORESOURCE_BUS);
+ if (!bus)
+ return dev_err_probe(dev, -ENODEV,
+ "failed to get bus resources\n");
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ecam");
+ if (!res)
+ return dev_err_probe(dev, -ENXIO,
+ "failed to get ECAM resource\n");
+
+ pcie->icc_path = devm_of_icc_get(dev, "write");
+ if (IS_ERR(pcie->icc_path))
+ return dev_err_probe(dev, PTR_ERR(pcie->icc_path),
+ "failed to get ICC\n");
+
+ /*
+ * Parse BPMP property only for silicon, as interaction with BPMP is
+ * not needed for other platforms.
+ */
+ if (tegra_is_silicon()) {
+ pcie->bpmp = tegra_bpmp_get_with_id(dev, &pcie->ctl_id);
+ if (IS_ERR(pcie->bpmp))
+ return dev_err_probe(dev, PTR_ERR(pcie->bpmp),
+ "failed to get BPMP\n");
+ }
+
+ err = devm_pm_runtime_active_enabled(dev);
+ if (err < 0)
+ return dev_err_probe(dev, "failed to enable runtime PM\n");
+
+ pm_runtime_get_sync(dev);
+
+ /* sanity check that programmed ranges match what's in DT */
+ if (!tegra264_pcie_check_ranges(pdev)) {
+ err = -EINVAL;
+ goto put_pm;
+ }
+
+ pcie->cfg = pci_ecam_create(dev, res, bus->res, &pci_generic_ecam_ops);
+ if (IS_ERR(pcie->cfg)) {
+ err = dev_err_probe(dev, PTR_ERR(pcie->cfg),
+ "failed to create ECAM\n");
+ goto put_pm;
+ }
+
+ bridge->ops = (struct pci_ops *)&pci_generic_ecam_ops.pci_ops;
+ bridge->sysdata = pcie->cfg;
+ pcie->ecam = pcie->cfg->win;
+
+ tegra264_pcie_init(pcie);
+
+ if (!pcie->link_up)
+ goto free_ecam;
+
+ err = pci_host_probe(bridge);
+ if (err < 0) {
+ dev_err_probe(dev, ERR_PTR(err), "failed to register host\n");
+ goto free_ecam;
+ }
+
+ return 0;
+
+free_ecam:
+ pci_ecam_free(pcie->cfg);
+put_pm:
+ pm_runtime_put_sync(dev);
+
+ if (tegra_is_silicon())
+ tegra_bpmp_put(pcie->bpmp);
+
+ return err;
+}
+
+static void tegra264_pcie_remove(struct platform_device *pdev)
+{
+ struct tegra264_pcie *pcie = platform_get_drvdata(pdev);
+
+ /*
+ * If we undo tegra264_pcie_init() then link goes down and need
+ * controller reset to bring up the link again. Remove intention is
+ * to clean up the root bridge and re-enumerate during bind.
+ */
+ pci_lock_rescan_remove();
+ pci_stop_root_bus(pcie->bridge->bus);
+ pci_remove_root_bus(pcie->bridge->bus);
+ pci_unlock_rescan_remove();
+
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+
+ if (tegra_is_silicon())
+ tegra_bpmp_put(pcie->bpmp);
+
+ pci_ecam_free(pcie->cfg);
+}
+
+static int tegra264_pcie_suspend_noirq(struct device *dev)
+{
+ struct tegra264_pcie *pcie = dev_get_drvdata(dev);
+ int err;
+
+ tegra_pcie_deinit(pcie);
+
+ if (pcie->wake_gpio && device_may_wakeup(dev)) {
+ err = enable_irq_wake(pcie->wake_irq);
+ if (err < 0)
+ dev_err(dev, "failed to enable wake IRQ: %pe\n",
+ ERR_PTR(err));
+ }
+
+ return 0;
+}
+
+static int tegra264_pcie_resume_noirq(struct device *dev)
+{
+ struct tegra264_pcie *pcie = dev_get_drvdata(dev);
+ int err;
+
+ err = pinctrl_pm_select_default_state(dev);
+ if (err < 0)
+ dev_err(dev, "failed to configure sideband pins: %pe\n",
+ ERR_PTR(err));
+
+ if (pcie->wake_gpio && device_may_wakeup(dev)) {
+ err = disable_irq_wake(pcie->wake_irq);
+ if (err < 0)
+ dev_err(dev, "failed to disable wake IRQ: %pe\n",
+ ERR_PTR(err));
+ }
+
+ if (pcie->link_up == false)
+ return 0;
+
+ tegra264_pcie_init(pcie);
+
+ return 0;
+}
+
+static DEFINE_NOIRQ_DEV_PM_OPS(tegra264_pcie_pm_ops,
+ tegra264_pcie_suspend_noirq,
+ tegra264_pcie_resume_noirq);
+
+static const struct of_device_id tegra264_pcie_of_match[] = {
+ {
+ .compatible = "nvidia,tegra264-pcie",
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, tegra264_pcie_of_match);
+
+static struct platform_driver tegra264_pcie_driver = {
+ .probe = tegra264_pcie_probe,
+ .remove = tegra264_pcie_remove,
+ .driver = {
+ .name = "tegra264-pcie",
+ .pm = &tegra264_pcie_pm_ops,
+ .of_match_table = tegra264_pcie_of_match,
+ },
+};
+module_platform_driver(tegra264_pcie_driver);
+
+MODULE_AUTHOR("Manikanta Maddireddy <mmaddireddy@nvidia.com>");
+MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
+MODULE_DESCRIPTION("NVIDIA Tegra264 PCIe host controller driver");
+MODULE_LICENSE("GPL");
--
2.52.0
^ permalink raw reply related
* [PATCH v5 4/4] arm64: tegra: Reorder reg and reg-names to match bindings
From: Thierry Reding @ 2026-05-26 8:53 UTC (permalink / raw)
To: Bjorn Helgaas, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Thierry Reding, Jonathan Hunter, Karthikeyan Mitran,
Hou Zhiqiang, Thomas Petazzoni, Pali Rohár, Michal Simek,
Kevin Xie, Thierry Reding, Aksh Garg
Cc: linux-pci, devicetree, linux-tegra, linux-kernel,
linux-arm-kernel, Thierry Reding
In-Reply-To: <20260526-tegra264-pcie-v5-0-84a813b979d7@nvidia.com>
From: Thierry Reding <treding@nvidia.com>
The ECAM region cannot be the first entry in the "reg" property, because
in that case the unit-address wouldn't match the first entry. The order
of the nodes can also not be changed to match the ECAM entry because the
ECAM region is global and outside of any of the control busses.
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
Changes in v5:
- rebase onto v7.1-rc1
Changes in v4:
- revert ECAM "reg" entry order
Changes in v2:
- order ECAM "reg" entry before others
---
arch/arm64/boot/dts/nvidia/tegra264.dtsi | 48 ++++++++++++++++----------------
1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/arch/arm64/boot/dts/nvidia/tegra264.dtsi b/arch/arm64/boot/dts/nvidia/tegra264.dtsi
index 06d8357bdf52..d4f2a4ab03c3 100644
--- a/arch/arm64/boot/dts/nvidia/tegra264.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra264.dtsi
@@ -3556,11 +3556,11 @@ cmdqv4: cmdqv@b200000 {
pci@c000000 {
compatible = "nvidia,tegra264-pcie";
- reg = <0xd0 0xb0000000 0x0 0x10000000>,
- <0x00 0x0c000000 0x0 0x00004000>,
+ reg = <0x00 0x0c000000 0x0 0x00004000>,
<0x00 0x0c004000 0x0 0x00001000>,
- <0x00 0x0c005000 0x0 0x00001000>;
- reg-names = "ecam", "xal", "xtl", "xtl-pri";
+ <0x00 0x0c005000 0x0 0x00001000>,
+ <0xd0 0xb0000000 0x0 0x10000000>;
+ reg-names = "xal", "xtl", "xtl-pri", "ecam";
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
@@ -3892,12 +3892,12 @@ gpio_uphy: gpio@8300000 {
pci@8400000 {
compatible = "nvidia,tegra264-pcie";
- reg = <0xa8 0xb0000000 0x0 0x10000000>,
- <0x00 0x08400000 0x0 0x00004000>,
+ reg = <0x00 0x08400000 0x0 0x00004000>,
<0x00 0x08404000 0x0 0x00001000>,
<0x00 0x08405000 0x0 0x00001000>,
- <0x00 0x08410000 0x0 0x00010000>;
- reg-names = "ecam", "xal", "xtl", "xtl-pri", "xpl";
+ <0x00 0x08410000 0x0 0x00010000>,
+ <0xa8 0xb0000000 0x0 0x10000000>;
+ reg-names = "xal", "xtl", "xtl-pri", "xpl", "ecam";
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
@@ -3924,12 +3924,12 @@ pci@8400000 {
pci@8420000 {
compatible = "nvidia,tegra264-pcie";
- reg = <0xb0 0xb0000000 0x0 0x10000000>,
- <0x00 0x08420000 0x0 0x00004000>,
+ reg = <0x00 0x08420000 0x0 0x00004000>,
<0x00 0x08424000 0x0 0x00001000>,
<0x00 0x08425000 0x0 0x00001000>,
- <0x00 0x08430000 0x0 0x00010000>;
- reg-names = "ecam", "xal", "xtl", "xtl-pri", "xpl";
+ <0x00 0x08430000 0x0 0x00010000>,
+ <0xb0 0xb0000000 0x0 0x10000000>;
+ reg-names = "xal", "xtl", "xtl-pri", "xpl", "ecam";
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
@@ -3956,12 +3956,12 @@ pci@8420000 {
pci@8440000 {
compatible = "nvidia,tegra264-pcie";
- reg = <0xb8 0xb0000000 0x0 0x10000000>,
- <0x00 0x08440000 0x0 0x00004000>,
+ reg = <0x00 0x08440000 0x0 0x00004000>,
<0x00 0x08444000 0x0 0x00001000>,
<0x00 0x08445000 0x0 0x00001000>,
- <0x00 0x08450000 0x0 0x00010000>;
- reg-names = "ecam", "xal", "xtl", "xtl-pri", "xpl";
+ <0x00 0x08450000 0x0 0x00010000>,
+ <0xb8 0xb0000000 0x0 0x10000000>;
+ reg-names = "xal", "xtl", "xtl-pri", "xpl", "ecam";
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
@@ -3988,12 +3988,12 @@ pci@8440000 {
pci@8460000 {
compatible = "nvidia,tegra264-pcie";
- reg = <0xc0 0xb0000000 0x0 0x10000000>,
- <0x00 0x08460000 0x0 0x00004000>,
+ reg = <0x00 0x08460000 0x0 0x00004000>,
<0x00 0x08464000 0x0 0x00001000>,
<0x00 0x08465000 0x0 0x00001000>,
- <0x00 0x08470000 0x0 0x00010000>;
- reg-names = "ecam", "xal", "xtl", "xtl-pri", "xpl";
+ <0x00 0x08470000 0x0 0x00010000>,
+ <0xc0 0xb0000000 0x0 0x10000000>;
+ reg-names = "xal", "xtl", "xtl-pri", "xpl", "ecam";
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
@@ -4020,12 +4020,12 @@ pci@8460000 {
pci@8480000 {
compatible = "nvidia,tegra264-pcie";
- reg = <0xc8 0xb0000000 0x0 0x10000000>,
- <0x00 0x08480000 0x0 0x00004000>,
+ reg = <0x00 0x08480000 0x0 0x00004000>,
<0x00 0x08484000 0x0 0x00001000>,
<0x00 0x08485000 0x0 0x00001000>,
- <0x00 0x08490000 0x0 0x00010000>;
- reg-names = "ecam", "xal", "xtl", "xtl-pri", "xpl";
+ <0x00 0x08490000 0x0 0x00010000>,
+ <0xc8 0xb0000000 0x0 0x10000000>;
+ reg-names = "xal", "xtl", "xtl-pri", "xpl", "ecam";
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
--
2.52.0
^ permalink raw reply related
* [PATCH v5 2/4] PCI: Use standard wait times for PCIe link monitoring
From: Thierry Reding @ 2026-05-26 8:53 UTC (permalink / raw)
To: Bjorn Helgaas, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Thierry Reding, Jonathan Hunter, Karthikeyan Mitran,
Hou Zhiqiang, Thomas Petazzoni, Pali Rohár, Michal Simek,
Kevin Xie, Thierry Reding, Aksh Garg
Cc: linux-pci, devicetree, linux-tegra, linux-kernel,
linux-arm-kernel, Thierry Reding
In-Reply-To: <20260526-tegra264-pcie-v5-0-84a813b979d7@nvidia.com>
From: Thierry Reding <treding@nvidia.com>
Instead of defining the wait values for each driver, use common values
defined in the core pci.h header file. Note that most drivers don't use
the millisecond waits, but rather usleep_range(), so add these commonly
used values to the header so that all drivers can use them.
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
Changes in v2:
- fix build for Cadence
---
drivers/pci/controller/cadence/pcie-cadence-host-common.c | 6 ++++--
drivers/pci/controller/cadence/pcie-cadence-lga-regs.h | 5 -----
drivers/pci/controller/mobiveil/pcie-mobiveil.c | 4 ++--
drivers/pci/controller/mobiveil/pcie-mobiveil.h | 5 -----
drivers/pci/controller/pci-aardvark.c | 7 ++-----
drivers/pci/controller/pcie-xilinx-nwl.c | 9 ++-------
drivers/pci/controller/plda/pcie-starfive.c | 9 ++-------
drivers/pci/pci.h | 2 ++
8 files changed, 14 insertions(+), 33 deletions(-)
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host-common.c b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
index 2b0211870f02..72b36c70f389 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host-common.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host-common.c
@@ -15,6 +15,8 @@
#include "pcie-cadence.h"
#include "pcie-cadence-host-common.h"
+#include "../../pci.h"
+
#define LINK_RETRAIN_TIMEOUT HZ
u64 bar_max_size[] = {
@@ -53,12 +55,12 @@ int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie,
int retries;
/* Check if the link is up or not */
- for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
+ for (retries = 0; retries < PCIE_LINK_WAIT_MAX_RETRIES; retries++) {
if (pcie_link_up(pcie)) {
dev_info(dev, "Link up\n");
return 0;
}
- usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
+ usleep_range(PCIE_LINK_WAIT_US_MIN, PCIE_LINK_WAIT_US_MAX);
}
return -ETIMEDOUT;
diff --git a/drivers/pci/controller/cadence/pcie-cadence-lga-regs.h b/drivers/pci/controller/cadence/pcie-cadence-lga-regs.h
index 857b2140c5d2..15dc4fcaf45d 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-lga-regs.h
+++ b/drivers/pci/controller/cadence/pcie-cadence-lga-regs.h
@@ -10,11 +10,6 @@
#include <linux/bitfield.h>
-/* Parameters for the waiting for link up routine */
-#define LINK_WAIT_MAX_RETRIES 10
-#define LINK_WAIT_USLEEP_MIN 90000
-#define LINK_WAIT_USLEEP_MAX 100000
-
/* Local Management Registers */
#define CDNS_PCIE_LM_BASE 0x00100000
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.c b/drivers/pci/controller/mobiveil/pcie-mobiveil.c
index 62ecbaeb0a60..cc102032c1e6 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil.c
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.c
@@ -218,11 +218,11 @@ int mobiveil_bringup_link(struct mobiveil_pcie *pcie)
int retries;
/* check if the link is up or not */
- for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
+ for (retries = 0; retries < PCIE_LINK_WAIT_MAX_RETRIES; retries++) {
if (mobiveil_pcie_link_up(pcie))
return 0;
- usleep_range(LINK_WAIT_MIN, LINK_WAIT_MAX);
+ usleep_range(PCIE_LINK_WAIT_US_MIN, PCIE_LINK_WAIT_US_MAX);
}
dev_err(&pcie->pdev->dev, "link never came up\n");
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.h b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
index 7246de6a7176..11010a99e27c 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil.h
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
@@ -122,11 +122,6 @@
#define IB_WIN_SIZE ((u64)256 * 1024 * 1024 * 1024)
#define MAX_PIO_WINDOWS 8
-/* Parameters for the waiting for link up routine */
-#define LINK_WAIT_MAX_RETRIES 10
-#define LINK_WAIT_MIN 90000
-#define LINK_WAIT_MAX 100000
-
#define PAGED_ADDR_BNDRY 0xc00
#define OFFSET_TO_PAGE_ADDR(off) \
((off & PAGE_LO_MASK) | PAGED_ADDR_BNDRY)
diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index e34bea1ff0ac..506323a6c72b 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -255,9 +255,6 @@ enum {
#define PIO_RETRY_CNT 750000 /* 1.5 s */
#define PIO_RETRY_DELAY 2 /* 2 us*/
-#define LINK_WAIT_MAX_RETRIES 10
-#define LINK_WAIT_USLEEP_MIN 90000
-#define LINK_WAIT_USLEEP_MAX 100000
#define RETRAIN_WAIT_MAX_RETRIES 10
#define RETRAIN_WAIT_USLEEP_US 2000
@@ -349,11 +346,11 @@ static int advk_pcie_wait_for_link(struct advk_pcie *pcie)
int retries;
/* check if the link is up or not */
- for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
+ for (retries = 0; retries < PCIE_LINK_WAIT_MAX_RETRIES; retries++) {
if (advk_pcie_link_up(pcie))
return 0;
- usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
+ usleep_range(PCIE_LINK_WAIT_US_MIN, PCIE_LINK_WAIT_US_MAX);
}
return -ETIMEDOUT;
diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c
index 7db2c96c6cec..fc65e9fdddb3 100644
--- a/drivers/pci/controller/pcie-xilinx-nwl.c
+++ b/drivers/pci/controller/pcie-xilinx-nwl.c
@@ -140,11 +140,6 @@
#define PCIE_PHY_LINKUP_BIT BIT(0)
#define PHY_RDY_LINKUP_BIT BIT(1)
-/* Parameters for the waiting for link up routine */
-#define LINK_WAIT_MAX_RETRIES 10
-#define LINK_WAIT_USLEEP_MIN 90000
-#define LINK_WAIT_USLEEP_MAX 100000
-
struct nwl_msi { /* MSI information */
DECLARE_BITMAP(bitmap, INT_PCI_MSI_NR);
struct irq_domain *dev_domain;
@@ -203,10 +198,10 @@ static int nwl_wait_for_link(struct nwl_pcie *pcie)
int retries;
/* check if the link is up or not */
- for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
+ for (retries = 0; retries < PCIE_LINK_WAIT_MAX_RETRIES; retries++) {
if (nwl_phy_link_up(pcie))
return 0;
- usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
+ usleep_range(PCIE_LINK_WAIT_US_MIN, PCIE_LINK_WAIT_US_MAX);
}
dev_err(dev, "PHY link never came up\n");
diff --git a/drivers/pci/controller/plda/pcie-starfive.c b/drivers/pci/controller/plda/pcie-starfive.c
index 298036c3e7f9..542a751b6f4d 100644
--- a/drivers/pci/controller/plda/pcie-starfive.c
+++ b/drivers/pci/controller/plda/pcie-starfive.c
@@ -45,11 +45,6 @@
#define STG_SYSCON_LNKSTA_OFFSET 0x170
#define DATA_LINK_ACTIVE BIT(5)
-/* Parameters for the waiting for link up routine */
-#define LINK_WAIT_MAX_RETRIES 10
-#define LINK_WAIT_USLEEP_MIN 90000
-#define LINK_WAIT_USLEEP_MAX 100000
-
struct starfive_jh7110_pcie {
struct plda_pcie_rp plda;
struct reset_control *resets;
@@ -217,12 +212,12 @@ static int starfive_pcie_host_wait_for_link(struct starfive_jh7110_pcie *pcie)
int retries;
/* Check if the link is up or not */
- for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
+ for (retries = 0; retries < PCIE_LINK_WAIT_MAX_RETRIES; retries++) {
if (starfive_pcie_link_up(&pcie->plda)) {
dev_info(pcie->plda.dev, "port link up\n");
return 0;
}
- usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
+ usleep_range(PCIE_LINK_WAIT_US_MIN, PCIE_LINK_WAIT_US_MAX);
}
return -ETIMEDOUT;
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index b36667969ad5..54a9e06e85f8 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -63,6 +63,8 @@ struct pcie_tlp_log;
/* Parameters for the waiting for link up routine */
#define PCIE_LINK_WAIT_MAX_RETRIES 10
#define PCIE_LINK_WAIT_SLEEP_MS 90
+#define PCIE_LINK_WAIT_US_MIN 90000
+#define PCIE_LINK_WAIT_US_MAX 100000
/* Format of TLP; PCIe r7.0, sec 2.2.1 */
#define PCIE_TLP_FMT_3DW_NO_DATA 0x00 /* 3DW header, no data */
--
2.52.0
^ permalink raw reply related
* [PATCH v5 1/4] dt-bindings: pci: Strictly distinguish C0 from C1-C5
From: Thierry Reding @ 2026-05-26 8:53 UTC (permalink / raw)
To: Bjorn Helgaas, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Thierry Reding, Jonathan Hunter, Karthikeyan Mitran,
Hou Zhiqiang, Thomas Petazzoni, Pali Rohár, Michal Simek,
Kevin Xie, Thierry Reding, Aksh Garg
Cc: linux-pci, devicetree, linux-tegra, linux-kernel,
linux-arm-kernel, Thierry Reding
In-Reply-To: <20260526-tegra264-pcie-v5-0-84a813b979d7@nvidia.com>
From: Thierry Reding <treding@nvidia.com>
Instead of using the ECAM registers as the first entry, strictly make a
distinction between C0 and C1-C5. This is needed because otherwise the
unit address doesn't match the first "reg" entry. We also cannot change
the ordering of these nodes to follow the ECAM addresses because that
would put them outside of their "control bus" hierarchy since the ECAM
address space is a global one outside of any of the control busses.
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
Changes in v5:
- rebase on top of v7.1-rc1, make it into a fix
Changes in v4:
- ECAM is outside of the controller's region, so it cannot be the first
reg entry, otherwise we get warnings because it doesn't match the
unit-address, so revert back to oneOf construct
Changes in v2:
- move ECAM region first and unify C0 vs. C1-C5
- move unevaluatedProperties to right before the examples
- add description to clarify the two types of controllers
- add examples for C0 and C1-C5
---
.../bindings/pci/nvidia,tegra264-pcie.yaml | 75 ++++++++++++++--------
1 file changed, 50 insertions(+), 25 deletions(-)
diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra264-pcie.yaml b/Documentation/devicetree/bindings/pci/nvidia,tegra264-pcie.yaml
index dc4f8725c9f5..acb677d477fb 100644
--- a/Documentation/devicetree/bindings/pci/nvidia,tegra264-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/nvidia,tegra264-pcie.yaml
@@ -10,32 +10,23 @@ maintainers:
- Thierry Reding <thierry.reding@gmail.com>
- Jon Hunter <jonathanh@nvidia.com>
+description: |
+ Of the six PCIe controllers found on Tegra264, one (C0) is used for the
+ internal GPU and the other five (C1-C5) are routed to connectors such as
+ PCI or M.2 slots. Therefore the UPHY registers (XPL) exist only for C1
+ through C5, but not for C0.
+
properties:
compatible:
const: nvidia,tegra264-pcie
reg:
- description: |
- Of the six PCIe controllers found on Tegra264, one (C0) is used for the
- internal GPU and the other five (C1-C5) are routed to connectors such as
- PCI or M.2 slots. Therefore the UPHY registers (XPL) exist only for C1
- through C5, but not for C0.
minItems: 4
- items:
- - description: ECAM-compatible configuration space
- - description: application layer registers
- - description: transaction layer registers
- - description: privileged transaction layer registers
- - description: data link/physical layer registers (not available on C0)
+ maxItems: 5
reg-names:
minItems: 4
- items:
- - const: ecam
- - const: xal
- - const: xtl
- - const: xtl-pri
- - const: xpl
+ maxItems: 5
interrupts:
minItems: 1
@@ -70,6 +61,40 @@ required:
allOf:
- $ref: /schemas/pci/pci-host-bridge.yaml#
+ - oneOf:
+ - description: C0 controller (no UPHY)
+ properties:
+ reg:
+ items:
+ - description: application layer registers
+ - description: transaction layer registers
+ - description: privileged transaction layer registers
+ - description: ECAM compatible configuration space
+
+ reg-names:
+ items:
+ - const: xal
+ - const: xtl
+ - const: xtl-pri
+ - const: ecam
+
+ - description: C1-C5 controllers (with UPHY)
+ properties:
+ reg:
+ items:
+ - description: application layer registers
+ - description: transaction layer registers
+ - description: privileged transaction layer registers
+ - description: data link/physical layer registers
+ - description: ECAM compatible configuration space
+
+ reg-names:
+ items:
+ - const: xal
+ - const: xtl
+ - const: xtl-pri
+ - const: xpl
+ - const: ecam
unevaluatedProperties: false
@@ -81,11 +106,11 @@ examples:
pci@c000000 {
compatible = "nvidia,tegra264-pcie";
- reg = <0xd0 0xb0000000 0x0 0x10000000>,
- <0x00 0x0c000000 0x0 0x00004000>,
+ reg = <0x00 0x0c000000 0x0 0x00004000>,
<0x00 0x0c004000 0x0 0x00001000>,
- <0x00 0x0c005000 0x0 0x00001000>;
- reg-names = "ecam", "xal", "xtl", "xtl-pri";
+ <0x00 0x0c005000 0x0 0x00001000>,
+ <0xd0 0xb0000000 0x0 0x10000000>;
+ reg-names = "xal", "xtl", "xtl-pri", "ecam";
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
@@ -118,12 +143,12 @@ examples:
pci@8400000 {
compatible = "nvidia,tegra264-pcie";
- reg = <0xa8 0xb0000000 0x0 0x10000000>,
- <0x00 0x08400000 0x0 0x00004000>,
+ reg = <0x00 0x08400000 0x0 0x00004000>,
<0x00 0x08404000 0x0 0x00001000>,
<0x00 0x08405000 0x0 0x00001000>,
- <0x00 0x08410000 0x0 0x00010000>;
- reg-names = "ecam", "xal", "xtl", "xtl-pri", "xpl";
+ <0x00 0x08410000 0x0 0x00010000>,
+ <0xa8 0xb0000000 0x0 0x10000000>;
+ reg-names = "xal", "xtl", "xtl-pri", "xpl", "ecam";
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
--
2.52.0
^ permalink raw reply related
* [PATCH v5 0/4] PCI: tegra: Add Tegra264 support
From: Thierry Reding @ 2026-05-26 8:53 UTC (permalink / raw)
To: Bjorn Helgaas, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Thierry Reding, Jonathan Hunter, Karthikeyan Mitran,
Hou Zhiqiang, Thomas Petazzoni, Pali Rohár, Michal Simek,
Kevin Xie, Thierry Reding, Aksh Garg
Cc: linux-pci, devicetree, linux-tegra, linux-kernel,
linux-arm-kernel, Thierry Reding, Manikanta Maddireddy
Hi,
this series adds support for the PCIe controllers found on the Tegra264
SoC. There are six instances, one of which is for internal purposes only
and the other five are general purpose.
The first patch tweaks the DT bindings slightly to avoid new DT compiler
warnings that slipped through because they are now disabled by default
(-Wno-unit_address_vs_reg).
Before adding the driver in patch 3, patch 2 introduces some new common
wait times for PCIe and unifies the way that drivers use them. Finally,
patch 4 reorders the reg and reg-names property entries to match the
bindings changes from patch 1.
All of the prerequisites were merged in v7.1-rc1, so this can be applied
to the PCI tree directly. Optionally I can also pick up patch 4 into the
Tegra tree, but there should be no conflicts, so feel free to pick this
up with the rest.
Thanks,
Thierry
Changes in v5:
- address review comments for the PCI driver patch
- Link to v4: https://patch.msgid.link/20260402-tegra264-pcie-v4-0-21e2e19987e8@nvidia.com
Changes in v4:
- strip out dependencies that are going in through the ARM SoC tree
- revert bindings to oneOf construct so that we don't produce new DTC
warnings
- Link to v3: https://patch.msgid.link/20260326135855.2795149-1-thierry.reding@kernel.org
Changes in v3:
- integrate PCI standard wait times patch into the series to maintain
bisectability
- fix review comments from Mikko
- Link to v2: https://patch.msgid.link/20260320225443.2571920-1-thierry.reding@kernel.org
Changes in v2:
- fix an issue with sanity-checking disabled BARs
- address review comments
- Link to v1: https://patch.msgid.link/20260319160110.2131954-1-thierry.reding@kernel.org
Thanks,
Thierry
---
Thierry Reding (4):
dt-bindings: pci: Strictly distinguish C0 from C1-C5
PCI: Use standard wait times for PCIe link monitoring
PCI: tegra: Add Tegra264 support
arm64: tegra: Reorder reg and reg-names to match bindings
.../bindings/pci/nvidia,tegra264-pcie.yaml | 75 ++-
arch/arm64/boot/dts/nvidia/tegra264.dtsi | 48 +-
drivers/pci/controller/Kconfig | 9 +-
drivers/pci/controller/Makefile | 1 +
.../controller/cadence/pcie-cadence-host-common.c | 6 +-
.../pci/controller/cadence/pcie-cadence-lga-regs.h | 5 -
drivers/pci/controller/mobiveil/pcie-mobiveil.c | 4 +-
drivers/pci/controller/mobiveil/pcie-mobiveil.h | 5 -
drivers/pci/controller/pci-aardvark.c | 7 +-
drivers/pci/controller/pcie-tegra264.c | 544 +++++++++++++++++++++
drivers/pci/controller/pcie-xilinx-nwl.c | 9 +-
drivers/pci/controller/plda/pcie-starfive.c | 9 +-
drivers/pci/pci.h | 2 +
13 files changed, 641 insertions(+), 83 deletions(-)
---
base-commit: 550604d6c9b9efc8d068aff94dc301694a7afdee
change-id: 20260402-tegra264-pcie-e30abe23da07
Best regards,
--
Thierry Reding <treding@nvidia.com>
^ permalink raw reply
* Re: [PATCH v4 2/5] arm_mpam: resctrl: Pre-allocate assignable monitors
From: Ben Horgan @ 2026-05-26 8:47 UTC (permalink / raw)
To: Koba Ko
Cc: amitsinght, baisheng.gao, baolin.wang, carl, dave.martin, david,
dfustini, fenghuay, gshan, james.morse, jic23, lcherian,
linux-arm-kernel, linux-kernel, peternewman, punit.agrawal,
quic_jiles, reinette.chatre, rohit.mathew, scott, sdonthineni,
tan.shaopeng, xhao, zengheng4, x86
In-Reply-To: <1aea92be-0e7c-459c-a96c-5a54cea073ff@nvidia.com>
Hi Koba,
On 5/26/26 03:50, Koba Ko wrote:
>
>>
>> +/*
>> + * This must run after all event counters have been picked so that any free
>> + * running counters have already been allocated.
>> + */
>> +static int mpam_resctrl_monitor_init_abmc(struct mpam_resctrl_mon *mon)
>> +{
>> + struct mpam_resctrl_res *res = &mpam_resctrl_controls[RDT_RESOURCE_L3];
>> + size_t num_rmid = resctrl_arch_system_num_rmid_idx();
>> + struct rdt_resource *l3 = &res->resctrl_res;
>> + struct mpam_class *class = mon->class;
>> + u16 num_mbwu_mon;
>> + int *cntrs;
>> +
>> + int *rmid_array __free(kvfree) = kvmalloc_objs(*rmid_array, num_rmid);
>> + if (!rmid_array) {
>> + pr_debug("Failed to allocate RMID array\n");
>> + return -ENOMEM;
>> + }
>> + memset(rmid_array, -1, num_rmid * sizeof(*rmid_array));
>> +
>> + num_mbwu_mon = class->props.num_mbwu_mon;
>> + cntrs = __alloc_mbwu_array(mon->class, num_mbwu_mon);
>
> hi Ben,
> One thing double-checking here.
> The allocation path uses class->props.num_mbwu_mon,
> but teardown frees using l3_num_allocated_mbwu,
> which is the global minimum exposed counter counter.
> If classes can have different num_mbwu_mon values, a class with more
> monitors than the global minimum may leak the tail of assigned_counters during
> teardown.
>
> koba
Thanks for bringing this up. The l3_num_allocated_mbwu is a hangover from when
this code supported both mbm_total_bytes and mbm_local_bytes with a separate
class for each. As we've now decided that mbm_total_bytes is the only bandwidth
counter it makes sense to support we will always have at most single class with
allocated bandwidth counters. Hence, I don't think there is a leak but
l3_num_allocated_mbwu adds unneeeded complication so I'll have a go at removing it.
Thanks,
Ben
>
>> + if (IS_ERR(cntrs))
>> + return PTR_ERR(cntrs);
>> + mon->assigned_counters = cntrs;
>> + mon->mbwu_idx_to_mon = no_free_ptr(rmid_array);
>> +
>> + l3->mon.mbm_cntr_assignable = true;
>> + l3->mon.mbm_assign_on_mkdir = true;
>> + l3->mon.mbm_cntr_configurable = false;
>> + l3->mon.mbm_cntr_assign_fixed = true;
>> +
>> + mpam_resctrl_monitor_sync_abmc_vals(l3);
>> +
>> + return 0;
>> +}
>> +
>> static int mpam_resctrl_monitor_init(struct mpam_resctrl_mon *mon,
>> enum resctrl_event_id type)
>> {
>> @@ -1133,8 +1234,21 @@ static int mpam_resctrl_monitor_init(struct
>> mpam_resctrl_mon *mon,
>> */
>> l3->mon.num_rmid = resctrl_arch_system_num_rmid_idx();
>>
>> - if (resctrl_enable_mon_event(type, false, 0, NULL))
>> - l3->mon_capable = true;
>> + if (type == QOS_L3_MBM_TOTAL_EVENT_ID) {
>> + int err;
>> +
>> + err = mpam_resctrl_monitor_init_abmc(mon);
>> + if (err)
>> + return err;
>> +
>> + static_assert(MAX_EVT_CONFIG_BITS == 0x7f);
>> + l3->mon.mbm_cfg_mask = MAX_EVT_CONFIG_BITS;
>> + }
>> +
>> + if (!resctrl_enable_mon_event(type, false, 0, NULL))
>> + return -EINVAL;
>> +
>> + l3->mon_capable = true;
>>
>> return 0;
>> }
>> @@ -1697,6 +1811,23 @@ void mpam_resctrl_exit(void)
>> resctrl_exit();
>> }
>>
>> +static void mpam_resctrl_teardown_mon(struct mpam_resctrl_mon *mon, struct
>> mpam_class *class)
>> +{
>> + u32 num_mbwu_mon = l3_num_allocated_mbwu;
>> +
>> + if (!mon->mbwu_idx_to_mon)
>> + return;
>> +
>> + if (mon->assigned_counters) {
>> + __free_mbwu_mon(class, mon->assigned_counters, num_mbwu_mon);
>> + kvfree(mon->assigned_counters);
>> + mon->assigned_counters = NULL;
>> + }
>> +
>> + kvfree(mon->mbwu_idx_to_mon);
>> + mon->mbwu_idx_to_mon = NULL;
>> +}
>> +
>> /*
>> * The driver is detaching an MSC from this class, if resctrl was using it,
>> * pull on resctrl_exit().
>> @@ -1719,6 +1850,8 @@ void mpam_resctrl_teardown_class(struct mpam_class *class)
>> for_each_mpam_resctrl_mon(mon, eventid) {
>> if (mon->class == class) {
>> mon->class = NULL;
>> +
>> + mpam_resctrl_teardown_mon(mon, class);
>> break;
>> }
>> }
>> --
>> 2.43.0
>>
^ permalink raw reply
* RE: [PATCH v2] iommu: Allow device driver to use its own PASID space for SVA
From: Joonwon Kang @ 2026-05-26 8:44 UTC (permalink / raw)
To: kevin.tian
Cc: Alexander.Grest, alexander.shishkin, amhetre, baolu.lu, bp,
dave.hansen, easwar.hariharan, hpa, iommu, jacob.jun.pan, jgg,
joonwonkang, joro, jpb, kas, kees, linux-arm-kernel, linux-kernel,
mingo, nicolinc, peterz, praan, robin.murphy, ryasuoka, smostafa,
sohil.mehta, tglx, will, x86, xin
In-Reply-To: <DM6PR11MB3690699A3178F1559D4BE1CA8C0B2@DM6PR11MB3690.namprd11.prod.outlook.com>
> > From: Joonwon Kang <joonwonkang@google.com>
> > Sent: Tuesday, May 26, 2026 2:58 PM
> >
> > > On Mon, May 25, 2026 at 03:29:24PM +0000, Joonwon Kang wrote:
> > >
> > > > Currently, the only known expected user of the new kAPI is our team.
> > Since
> > > > I test if the patch resolves our problem before sending it, I believe it
> > > > should be good enough. Do you mean more than our team by
> > "accompanied
> > > > users"?
> > >
> > > He means you cannot send patches like this that only serve OOT drivers
> > > to the mainline kernel.
> >
> > Hmm, it gets back to the chicken-and-egg problem. So, do you recommend
> > deferring the patch submission until we find a new in-tree user of the
> > new kAPI? I believe we will not make our module in-tree anytime soon.
> > Or, is it like I still can send the patch and get it reviewed although we
> > cannot merge it to the mainline?
> >
>
> It's not chicken-and-egg problem. Just always send them together.
>
> so let's wait until your module is ready for in-tree review...
Alright, thanks. I will wait until any in-tree users show up in the future
and continue working on this then. Please let me know if there is any
request later.
Appreciate all for reviewing the patches from RFC to this point :)
Thanks,
Joonwon Kang
^ permalink raw reply
* Re: [PATCH v4 3/4] PCI: tegra: Add Tegra264 support
From: Thierry Reding @ 2026-05-26 8:42 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: Thierry Reding, Bjorn Helgaas, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Hunter, Karthikeyan Mitran, Hou Zhiqiang,
Thomas Petazzoni, Pali Rohár, Michal Simek, Kevin Xie,
linux-pci, devicetree, linux-tegra, linux-kernel,
linux-arm-kernel, Thierry Reding, Manikanta Maddireddy
In-Reply-To: <ukeelrtmjgxxwlkkzsojygzo6us5ijshis66a4x2a44hg4bw25@hggglahvrajy>
[-- Attachment #1: Type: text/plain, Size: 5189 bytes --]
On Fri, Apr 10, 2026 at 10:04:20PM +0530, Manivannan Sadhasivam wrote:
> On Tue, Apr 07, 2026 at 11:38:28AM +0200, Thierry Reding wrote:
> > On Thu, Apr 02, 2026 at 11:02:02PM +0530, Manivannan Sadhasivam wrote:
> > > On Thu, Apr 02, 2026 at 04:27:37PM +0200, Thierry Reding wrote:
[...]
> > > > + depends on ARCH_TEGRA || COMPILE_TEST
> > > > + depends on PCI_MSI
> > >
> > > Why?
> >
> > I suppose it's not necessary in the sense of it being a build
> > dependency. At runtime, however, the root complex is not useful if PCI
> > MSI is not enabled. We can drop this dependency and rely on .config to
> > have it enabled as needed.
> >
>
> Yes. I think the rationale is to depend on the symbols that the driver needs for
> build dependency.
Done.
[...]
> > > > + GPIOD_IN);
> > > > + if (IS_ERR(pcie->wake_gpio))
> > > > + return PTR_ERR(pcie->wake_gpio);
> > > > +
> > > > + if (pcie->wake_gpio) {
> > >
> > > Since you are bailing out above, you don't need this check.
> >
> > I think we still want to have this check to handle the case of optional
> > wake GPIOs. Not all controllers may have this wired up and
> > devm_gpiod_get_optional() will return NULL (not an ERR_PTR()-encoded
> > error) if the wake-gpios property is missing.
> >
>
> Ok. In that case you can just bail out:
> if (!pcie->wake_gpio)
> return 0;
Done.
[...]
> > > > + bw = width * (PCIE_SPEED2MBS_ENC(speed) / BITS_PER_BYTE);
> > > > + value = MBps_to_icc(bw);
> > >
> > > So this becomes, 'width * (PCIE_SPEED2MBS_ENC(speed) / 8) * 1000 / 8'. But don't
> > > you want, 'width * (PCIE_SPEED2MBS_ENC(speed)) * 1000 / 8'?
> >
> > This is M*B*ps_to_icc(), not M*b*ps_to_icc(), so we do in fact get the
> > latter. I almost fell for this as well because I got confused by some of
> > these macros being all-caps and other times the case actually mattering.
> >
>
> Oops, I was misleaded too. But you can simply do:
> bw = Mbps_to_icc(width * PCIE_SPEED2MBS_ENC(speed));
>
> > > > + err = icc_set_bw(pcie->icc_path, bw, bw);
>
> And here you were setting the MBps, not Kbps.
Done.
> > > > + if (err < 0)
> > > > + dev_err(pcie->dev,
> > > > + "failed to request bandwidth (%u MBps): %pe\n",
> > > > + bw, ERR_PTR(err));
> > >
> > > So you don't want to error out if this fails?
> >
> > No. This is not a fatal error and the system will continue to work,
> > albeit perhaps at suboptimal performance. Given that Ethernet and mass
> > storage are connected to these, a failure to set the bandwidth and
> > erroring out here may leave the system unusable, but continuing on would
> > let the system boot and update firmware, kernel or whatever to recover.
> >
> > I'll add a comment explaining this.
> >
>
> Yeah, that'll help.
Done.
[...]
> > > s/link/controller or endpoint?
> >
> > This controls the PERST# signal, so I guess "endpoint" would be more
> > correct.
> >
>
> Yes!
Done.
[...]
> > > > + if (!pcie->link_up)
> > > > + goto free;
> > >
> > > goto free_ecam;
> >
> > It's not clear to me, but are you suggesting to rename the existing
> > "free" label to "free_ecam"? I can do that.
> >
>
> Yeah, I was just asking for a rename.
Done.
[...]
> > > > +static int tegra264_pcie_resume_noirq(struct device *dev)
> > > > +{
> > > > + struct tegra264_pcie *pcie = dev_get_drvdata(dev);
> > > > + int err;
> > > > +
> > > > + if (pcie->wake_gpio && device_may_wakeup(dev)) {
> > > > + err = disable_irq_wake(pcie->wake_irq);
> > > > + if (err < 0)
> > > > + dev_err(dev, "failed to disable wake IRQ: %pe\n",
> > > > + ERR_PTR(err));
> > > > + }
> > > > +
> > > > + if (pcie->link_up == false)
> > > > + return 0;
> > > > +
> > > > + tegra264_pcie_init(pcie);
> > > > +
> > >
> > > Why do you need init() here without deinit() in tegra264_pcie_suspend_noirq()?
> >
> > That's because when we come out of suspend the link may have gone down
> > again, so we need to take the endpoint out of reset to retrigger the
> > link training. I think we could possibly explicitly clear that PERST_O_N
> > bit in the PERST_CONTROL register in a new tegra264_pcie_deinit() to
> > mirror what tegra264_pcie_init() does, but it's automatically done by
> > firmware anyway, so not needed.
> >
>
> Hmm, so firmware asserts PERST# at the end of suspend? It is not clear to me why
> it is doing so. But for symmetry I'd like to do it in tegra264_pcie_deinit().
Done.
> Also, I'm not certain about the 'pcie->link_up' check here. If it is 'false',
> then probe() should've failed. So why do you need the check here anyway?
>
> Maybe you should get rid of this check and return the link status from
> tegra264_pcie_init() directly?
We specifically don't want to fail the probe for this when the link is
not there because we want to tighly control the power mode when the link
is not up. We also need to keep the link alive for the case where it can
be hotplug capable.
I've added a new tegra264_pcie_deinit() function to clear that PERST_O_N
bit explicitly, but I've kept the link_up flag.
Thanks,
Thierry
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH v2 3/6] gpiolib: of: add quirk for IS31FL319X shutdown line
From: Bartosz Golaszewski @ 2026-05-26 8:40 UTC (permalink / raw)
To: Jun Yan
Cc: Pavel Machek, Krzysztof Kozlowski, Wei Xu, Geert Uytterhoeven,
Peter Rosin, linux-leds, devicetree, linux-kernel, linux-arm-msm,
linux-arm-kernel, linux-gpio, linusw, dmitry.baryshkov, Lee Jones,
Pavel Machek, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, Andrew Lunn, Gregory Clement,
Sebastian Hesselbarth, Bartosz Golaszewski, Vincent Knecht,
Grant Feng, Andre Przywara, Tony Lindgren, Sudeep Holla,
Romain Perier, Jesper Nilsson, Robert Marko
In-Reply-To: <20260525144629.498630-4-jerrysteve1101@gmail.com>
On Mon, 25 May 2026 16:46:09 +0200, Jun Yan <jerrysteve1101@gmail.com> said:
> According to the IS31FL319x datasheet[1], the SDB pin is active‑low.
> However, existing device tree incorrectly configure it as active‑high.
>
> Add a fixup to force the consumer active low for legacy device trees.
>
> [1] https://lumissil.com/assets/pdf/core/IS31FL3196_DS.pdf
>
> Signed-off-by: Jun Yan <jerrysteve1101@gmail.com>
> ---
> drivers/gpio/gpiolib-of.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
> index ef1ac68b94b7..8a79aaadc9ea 100644
> --- a/drivers/gpio/gpiolib-of.c
> +++ b/drivers/gpio/gpiolib-of.c
> @@ -194,6 +194,16 @@ static void of_gpio_try_fixup_polarity(const struct device_node *np,
> { "himax,hx8357", "gpios-reset", false },
> { "himax,hx8369", "gpios-reset", false },
> #endif
> +#if IS_ENABLED(CONFIG_LEDS_IS31FL319X)
> + /*
> + * According to the IS31FL319x datasheet, the SDB pin is active‑low.
> + * However, existing device tree incorrectly configure it
> + * as active‑high.
> + */
> + { "issi,is31fl3199", "shutdown-gpios", false },
> + { "si-en,sn3190", "shutdown-gpios", false },
> + { "si-en,sn3193", "shutdown-gpios", false },
> +#endif
> #if IS_ENABLED(CONFIG_MTD_NAND_JZ4780)
> /*
> * The rb-gpios semantics was undocumented and qi,lb60 (along with
> --
> 2.54.0
>
>
Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
^ permalink raw reply
* [PATCH RFC RESEND v5 2/6] firmware: meson: sm: video firmware loading via secure monitor
From: Zhentao Guo via B4 Relay @ 2026-05-26 8:40 UTC (permalink / raw)
To: Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-kernel, linux-amlogic, linux-kernel, linux-media,
devicetree, Zhentao Guo
In-Reply-To: <20260526-b4-s4-vdec-upstream-v5-0-33bc817f93f4@amlogic.com>
From: Zhentao Guo <zhentao.guo@amlogic.com>
Add SM_LOAD_VIDEO_FW to the secure monitor command enum
to allow decoder drivers to load firmware through the meson_sm
interface.
Signed-off-by: Zhentao Guo <zhentao.guo@amlogic.com>
---
include/linux/firmware/meson/meson_sm.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/linux/firmware/meson/meson_sm.h b/include/linux/firmware/meson/meson_sm.h
index 8eaf8922ab02..f40867a000f1 100644
--- a/include/linux/firmware/meson/meson_sm.h
+++ b/include/linux/firmware/meson/meson_sm.h
@@ -14,6 +14,7 @@ enum {
SM_GET_CHIP_ID,
SM_A1_PWRC_SET,
SM_A1_PWRC_GET,
+ SM_LOAD_VIDEO_FW,
};
struct meson_sm_firmware;
--
2.42.0
^ permalink raw reply related
* [PATCH RFC RESEND v5 6/6] arm64: defconfig: Enable CONFIG_VIDEO_AMLOGIC_VDEC
From: Zhentao Guo via B4 Relay @ 2026-05-26 8:40 UTC (permalink / raw)
To: Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-kernel, linux-amlogic, linux-kernel, linux-media,
devicetree, Zhentao Guo
In-Reply-To: <20260526-b4-s4-vdec-upstream-v5-0-33bc817f93f4@amlogic.com>
From: Zhentao Guo <zhentao.guo@amlogic.com>
Enable the Amlogic V4L2 stateless video decoder driver as a module
in the arm64 defconfig. This driver is needed for stateless video
decoding support on Amlogic SoCs.
Signed-off-by: Zhentao Guo <zhentao.guo@amlogic.com>
---
arch/arm64/configs/defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 4567f4b34f29..14caac24d200 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -913,6 +913,7 @@ CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_SDR_PLATFORM_DRIVERS=y
CONFIG_V4L_MEM2MEM_DRIVERS=y
CONFIG_VIDEO_AMPHION_VPU=m
+CONFIG_VIDEO_AMLOGIC_VDEC=m
CONFIG_VIDEO_CADENCE_CSI2RX=m
CONFIG_VIDEO_WAVE_VPU=m
CONFIG_VIDEO_E5010_JPEG_ENC=m
--
2.42.0
^ permalink raw reply related
* [PATCH RFC RESEND v5 3/6] media: dt-bindings: Add Amlogic V4L2 video decoder
From: Zhentao Guo via B4 Relay @ 2026-05-26 8:40 UTC (permalink / raw)
To: Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-kernel, linux-amlogic, linux-kernel, linux-media,
devicetree, Zhentao Guo
In-Reply-To: <20260526-b4-s4-vdec-upstream-v5-0-33bc817f93f4@amlogic.com>
From: Zhentao Guo <zhentao.guo@amlogic.com>
Describe the initial support for the V4L2 stateless video decoder
driver used with the Amlogic S4 (S805X2) platform.
Signed-off-by: Zhentao Guo <zhentao.guo@amlogic.com>
---
.../devicetree/bindings/media/amlogic,s4-vdec.yaml | 103 +++++++++++++++++++++
1 file changed, 103 insertions(+)
diff --git a/Documentation/devicetree/bindings/media/amlogic,s4-vdec.yaml b/Documentation/devicetree/bindings/media/amlogic,s4-vdec.yaml
new file mode 100644
index 000000000000..a0f33f6c35a1
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/amlogic,s4-vdec.yaml
@@ -0,0 +1,103 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2025 Amlogic, Inc. All rights reserved
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/amlogic,s4-vdec.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic Video Decode Accelerator
+
+maintainers:
+ - Zhentao Guo <zhentao.guo@amlogic.com>
+
+description:
+ The Video Decoder Accelerator present on Amlogic SOCs.
+ It supports stateless h264 decoding.
+
+properties:
+ compatible:
+ const: amlogic,s4-vdec
+
+ reg:
+ maxItems: 2
+
+ reg-names:
+ items:
+ - const: dos
+ - const: dmc
+
+ interrupts:
+ maxItems: 3
+
+ clocks:
+ maxItems: 3
+
+ clock-names:
+ items:
+ - const: dos
+ - const: vdec
+ - const: hevcf
+
+ power-domains:
+ maxItems: 2
+
+ power-domain-names:
+ items:
+ - const: vdec
+ - const: hevc
+
+ resets:
+ maxItems: 1
+
+ amlogic,canvas:
+ description: should point to a canvas provider node
+ $ref: /schemas/types.yaml#/definitions/phandle
+
+ secure-monitor:
+ description: phandle to the secure-monitor node
+ $ref: /schemas/types.yaml#/definitions/phandle
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - interrupts
+ - clocks
+ - clock-names
+ - power-domains
+ - power-domain-names
+ - amlogic,canvas
+ - secure-monitor
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/amlogic,s4-pll-clkc.h>
+ #include <dt-bindings/clock/amlogic,s4-peripherals-clkc.h>
+ #include <dt-bindings/power/meson-s4-power.h>
+ #include <dt-bindings/reset/amlogic,meson-s4-reset.h>
+ video-codec@fe320000 {
+ compatible = "amlogic,s4-vdec";
+ reg = <0xfe320000 0x10000>,
+ <0xfe036000 0x20>;
+ amlogic,canvas = <&canvas>;
+ reg-names = "dos",
+ "dmc";
+ interrupts = <GIC_SPI 91 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 92 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 93 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc_periphs CLKID_DOS>,
+ <&clkc_periphs CLKID_VDEC_SEL>,
+ <&clkc_periphs CLKID_HEVCF_SEL>;
+ clock-names = "dos",
+ "vdec",
+ "hevcf";
+ power-domains = <&pwrc PWRC_S4_DOS_VDEC_ID>,
+ <&pwrc PWRC_S4_DOS_HEVC_ID>;
+ power-domain-names = "vdec",
+ "hevc";
+ resets = <&reset RESET_DOS>;
+ secure-monitor = <&sm>;
+ };
--
2.42.0
^ permalink raw reply related
* [PATCH RFC RESEND v5 1/6] firmware: meson: sm: Add video firmware loading SMC call
From: Zhentao Guo via B4 Relay @ 2026-05-26 8:40 UTC (permalink / raw)
To: Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-kernel, linux-amlogic, linux-kernel, linux-media,
devicetree, Zhentao Guo
In-Reply-To: <20260526-b4-s4-vdec-upstream-v5-0-33bc817f93f4@amlogic.com>
From: Zhentao Guo <zhentao.guo@amlogic.com>
Add SM_LOAD_VIDEO_FW at SMC ID 0xb200000f in the command
table to load video firmware.
Signed-off-by: Zhentao Guo <zhentao.guo@amlogic.com>
---
drivers/firmware/meson/meson_sm.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/firmware/meson/meson_sm.c b/drivers/firmware/meson/meson_sm.c
index 3ab67aaa9e5d..5da6c65d684a 100644
--- a/drivers/firmware/meson/meson_sm.c
+++ b/drivers/firmware/meson/meson_sm.c
@@ -47,6 +47,7 @@ static const struct meson_sm_chip gxbb_chip = {
CMD(SM_GET_CHIP_ID, 0x82000044),
CMD(SM_A1_PWRC_SET, 0x82000093),
CMD(SM_A1_PWRC_GET, 0x82000095),
+ CMD(SM_LOAD_VIDEO_FW, 0xb200000f),
{ /* sentinel */ },
},
};
--
2.42.0
^ permalink raw reply related
* [PATCH RFC RESEND v5 5/6] arm64: dts: amlogic: Add video decoder driver support for S4 SOCs
From: Zhentao Guo via B4 Relay @ 2026-05-26 8:40 UTC (permalink / raw)
To: Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-kernel, linux-amlogic, linux-kernel, linux-media,
devicetree, Zhentao Guo
In-Reply-To: <20260526-b4-s4-vdec-upstream-v5-0-33bc817f93f4@amlogic.com>
From: Zhentao Guo <zhentao.guo@amlogic.com>
Add vdec node to enable Amlogic V4L2 stateless video decoder
support.
Signed-off-by: Zhentao Guo <zhentao.guo@amlogic.com>
---
arch/arm64/boot/dts/amlogic/meson-s4.dtsi | 34 +++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
index 2a6fbd530836..5ad826e4b554 100644
--- a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
@@ -96,6 +96,11 @@ saradc: adc@fe026000 {
status = "disabled";
};
+ optee {
+ compatible = "linaro,optee-tz";
+ method = "smc";
+ };
+
soc {
compatible = "simple-bus";
#address-cells = <2>;
@@ -907,5 +912,34 @@ emmc: mmc@fe08c000 {
assigned-clocks = <&clkc_periphs CLKID_SD_EMMC_C>;
assigned-clock-rates = <24000000>;
};
+
+ canvas: video-lut@fe036048 {
+ compatible = "amlogic,canvas";
+ reg = <0x0 0xfe036048 0x0 0x14>;
+ };
+
+ video-codec@fe320000 {
+ compatible = "amlogic,s4-vdec";
+ reg = <0x0 0xfe320000 0x0 0x10000>,
+ <0x0 0xfe036000 0x0 0x20>;
+ amlogic,canvas = <&canvas>;
+ reg-names = "dos",
+ "dmc";
+ interrupts = <GIC_SPI 91 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 92 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 93 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc_periphs CLKID_DOS>,
+ <&clkc_periphs CLKID_VDEC_SEL>,
+ <&clkc_periphs CLKID_HEVCF_SEL>;
+ clock-names = "dos",
+ "vdec",
+ "hevcf";
+ power-domains = <&pwrc PWRC_S4_DOS_VDEC_ID>,
+ <&pwrc PWRC_S4_DOS_HEVC_ID>;
+ power-domain-names = "vdec",
+ "hevc";
+ resets = <&reset RESET_DOS>;
+ secure-monitor = <&sm>;
+ };
};
};
--
2.42.0
^ permalink raw reply related
* [PATCH RFC RESEND v5 0/6] Add Amlogic stateless H.264 video decoder for S4
From: Zhentao Guo via B4 Relay @ 2026-05-26 8:40 UTC (permalink / raw)
To: Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-kernel, linux-amlogic, linux-kernel, linux-media,
devicetree, Zhentao Guo
Introduce initial driver support for Amlogic's new video acceleration
hardware architecture, designed for video stream decoding.
Compared to the current Amlogic video decoder hardware architecture,
this new implementation eliminates the Esparser hardware component,
enabling direct vb2 buffer input. The driver is designed to support
the V4L2 M2M stateless decoder API. The initial phase includes support
for H.264 decoding on Amlogic S805X2 platform.
The driver needs to work alongside with a signed firmware. The loading process of
the signed fw is as follow.
Stage1: Decypt and decompose the full firmware package when the driver is probed.
+---------------------+ +---------------------+
| Decoder Driver | | TEE Shared Memory |
| (Kernel Space) | | |
| +---------------+ | | +---------------+ |
| | video_ucode | | | | firmware | |
| | .bin | | Copy payload to SHM | | payload | |
| | (from fs) | | ---------------------> | | (Secure RAM) | |
| +---------------+ | | +---------------+ |
+---------------------+ +----------+----------+
|
| PTA Invocation
v
+-------------------------------+
| BL32 |
| +-------------------------+ |
| | Decrypt Firmware | |
| +-----------+-------------+ |
| | |
| v |
| +-------------------------+ |
| | Decompose the full | |
| | firmware pacakge | |
| +-----------+-------------+ |
| | |
| v |
| +-------------------------+ |
| | Store decomposed .bin | |
| | in Secure Memory | |
| +-------------------------+ |
+-------------------------------+
Stage2: When a decode job is scheduled, load decrypted fw via secure monitor.
+---------------------+
| V4L2 M2M Framework |
| +---------------+ |
| | device_run | |
| +------+--------+ |
+---------+-----------+
|
v
+---------------------+ +---------------------+
| Decoder Driver | | Secure Monitor |
| (Kernel Space) | | (bl32) |
| +---------------+ | SMC Call | +---------------+ |
| | Select Codec | | ---------------> | | Select & Load | |
| | Specific FW | | | | firmware.bin | |
| +---------------+ | | | to AMRISC | |
+---------------------+ | +-------+-------+ |
+----------+----------+
|
v
+---------------------+
| AMRISC Core |
| +---------------+ |
| | Running fw on | |
| | AMRISC | |
| +---------------+ |
+---------------------+
The driver is capable of:
- Supporting stateless H.264 decoding up to a resolution 1920x1088(on the S805X2 platform).
- Supporting I/P/B frame handling.
- Supporting vb2 mmap and dma-buf modes.
- Supporting frame-based decode mode. (Note that some H.264 bitstreams require
DPB reordering to generate reference lists, the stateless decoder driver
cannot access reordered reference lists in this mode, requiring the driver
to perform reference list reordering itself)
- Supporting NV12/NV21 output.
- Supporting Annex B start codes.
This driver is tested with Gstreamer.
Example:
gst-launch-1.0 filesrc location=/tmp/video_640x360_mp4_hevc_450kbps_no_b.mp4 !
parsebin ! v4l2slh264dec ! filesink location=/tmp/output.yuv
Retry the compliance test based on kernel 7.1.0:
v4l2-compliance 1.30.1, 64 bits, 64-bit time_t
Compliance test for aml-vdec-drv device /dev/video0:
Driver Info:
Driver name : aml-vdec-drv
Card type : platform:aml-vdec-drv
Bus info : platform:fe320000.video-codec
Driver version : 7.1.0
Capabilities : 0x84204000
Video Memory-to-Memory Multiplanar
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x04204000
Video Memory-to-Memory Multiplanar
Streaming
Extended Pix Format
Detected Stateless Decoder
Media Driver Info:
Driver name : aml-vdec-drv
Model : aml-vdec-drv
Serial :
Bus info : platform:fe320000.video-codec
Media version : 7.1.0
Hardware revision: 0x00000000 (0)
Driver version : 7.1.0
Interface Info:
ID : 0x0300000c
Type : V4L Video
Entity Info:
ID : 0x00000001 (1)
Name : aml_dev_drv-source
Function : V4L2 I/O
Pad 0x01000002 : 0: Source
Link 0x02000008: to remote pad 0x1000004 of entity 'aml_dev_drv-proc' (Video Decoder): Data, Enabled, Immutable
Required ioctls:
test MC information (see 'Media Driver Info' above): OK
test VIDIOC_QUERYCAP: OK
test invalid ioctls: OK
Allow for multiple opens:
test second /dev/video0 open: OK
test VIDIOC_QUERYCAP: OK
test VIDIOC_G/S_PRIORITY: OK
test for unlimited opens: OK
Debug ioctls:
test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
test VIDIOC_LOG_STATUS: OK (Not Supported)
Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 0 Audio Inputs: 0 Tuners: 0
Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0
Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
test VIDIOC_G/S_EDID: OK (Not Supported)
Control ioctls:
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
test VIDIOC_QUERYCTRL: OK
test VIDIOC_G/S_CTRL: OK
test VIDIOC_G/S/TRY_EXT_CTRLS: OK
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 6 Private Controls: 0
Standard Compound Controls: 4 Private Compound Controls: 0
Format ioctls:
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
test VIDIOC_G/S_PARM: OK (Not Supported)
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK
test VIDIOC_TRY_FMT: OK
test VIDIOC_S_FMT: OK
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK (Not Supported)
test Composing: OK (Not Supported)
test Scaling: OK (Not Supported)
Codec ioctls:
test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK
Buffer ioctls:
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
test CREATE_BUFS maximum buffers: OK
test VIDIOC_REMOVE_BUFS: OK
test VIDIOC_EXPBUF: OK
test Requests: OK
test blocking wait: OK
Total for aml-vdec-drv device /dev/video0: 49, Succeeded: 49, Failed: 0, Warnings: 0
Fluster test result of JVT-AVC_V1.
Result:
Ran 77/135 tests successfully
- 52 test vectors failed due to interlaced or mbaff clips: The Amlogic stateless
decoder driver only support bitstreams with frame_mbs_only_flags == 1.
Test Vectors:
cabac_mot_fld0_full
cabac_mot_mbaff0_full
cabac_mot_picaff0_full
CABREF3_Sand_D
CAFI1_SVA_C
CAMA1_Sony_C
CAMA1_TOSHIBA_B
cama1_vtc_c
cama2_vtc_b
CAMA3_Sand_E
cama3_vtc_b
CAMACI3_Sony_C
CAMANL1_TOSHIBA_B
CAMANL2_TOSHIBA_B
CAMANL3_Sand_E
CAMASL3_Sony_B
CAMP_MOT_MBAFF_L30
CAMP_MOT_MBAFF_L31
CANLMA2_Sony_C
CANLMA3_Sony_C
CAPA1_TOSHIBA_B
CAPAMA3_Sand_F
cavlc_mot_fld0_full_B
cavlc_mot_mbaff0_full_B
cavlc_mot_picaff0_full_B
CVCANLMA2_Sony_C
CVFI1_Sony_D
CVFI1_SVA_C
CVFI2_Sony_H
CVFI2_SVA_C
CVMA1_Sony_D
CVMA1_TOSHIBA_B
CVMANL1_TOSHIBA_B
CVMANL2_TOSHIBA_B
CVMAPAQP3_Sony_E
CVMAQP2_Sony_G
CVMAQP3_Sony_D
CVMP_MOT_FLD_L30_B
CVNLFI1_Sony_C
CVNLFI2_Sony_H
CVPA1_TOSHIBA_B
FI1_Sony_E
MR6_BT_B
MR7_BT_B
MR8_BT_B
MR9_BT_B
Sharp_MP_Field_1_B
Sharp_MP_Field_2_B
Sharp_MP_Field_3_B
Sharp_MP_PAFF_1r2
Sharp_MP_PAFF_2r
CVMP_MOT_FRM_L31_B
- 3 test vectors failed due to unsupported bitstream.
num_slice_group_minus1 greater than zero is not supported by the
hardware.
Test Vectors:
FM1_BT_B
FM1_FT_E
FM2_SVA_C
- 2 test vectors failed because SP_SLICE type is not supported by the
hardware.
Test Vectors:
SP1_BT_A
sp2_bt_b
One remain failure is CVFC1_Sony_C, which contains crop information. The md5sum of every decoded YUV indicates that original output from the decoder was correct. The YUV was cropped by gstreamer. The correct cropping method for this bitstream should be to crop 30*2 rows of pixels from both the top and bottom of the image, and 13*2 columns of pixels from both the left and right sides.However, gstreamer cropped 13*4 columns of pixels from the right side and 30*4 rows of pixels from the bottom. We are trying to find out the cause of this. Other failuers mentioned in V1 and V2 were resolved.
Changes in v5:
- Rename the compatible and the clock item accroding to Krzysztof's feedback.
- Use tee & meson_sm helpers to decrypt load the signed decoder firmware. Add the meson_sm describsion and reference to dt-binding and dts.
- Link to v4: https://lore.kernel.org/r/20260213-b4-s4-vdec-upstream-v4-0-c7112d00d662@amlogic.com
Changes in v4:
- Use %pad to print dma_addr_t type instead of using %llx.
- Add initial values to some local variables.
- Link to v3: https://lore.kernel.org/r/20260121-b4-s4-vdec-upstream-v3-0-4496aec3d79e@amlogic.com
Changes in v3:
- Fixed the DT check error:
arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dtb: video-codec@fe320000 (amlogic,s4-vcodec-dec): 'amlogic,canvas' does not match any of the regexes: '^pinctrl-[0-9]+$'
from schema $id: http://devicetree.org/schemas/media/amlogic,vcodec-dec.yaml
- Added DOS reset lines to dtsi and dt-binding.
- Fixed the issue where some B-frames were not decoded correctly(The fluster failures mentioned in patch V1 and V2 were mostly caused by this).
- Fixed the issue where canvas_index leaks occurred during the decoding of some bitstreams.
- Rework the src/dst format storage. Use v4l2_pix_format_mplane to store formats that related to bitstreams into the context. Add the reset format function to reset all the formats to default value.
- Store decoding parameters related to chip platforms, such as maximum width/height and alignment requirement, organized by chip platform.
- Link to v2: https://lore.kernel.org/r/20251124-b4-s4-vdec-upstream-v2-0-bdbbce3f11a6@amlogic.com
Changes in v2:
- Fixed incorrect generation of the reference lists for some B-frames.
- Rename or get rid of some properties in DTS and dt-binding.
- Remove some useless code or helper functions, (eg. clk helper functions, reg I/O macros, and some superfluous print messages) replace these functions with existing ones.
- Replace all the printk messages with dev_err/dev_info/dev_dbg
- Use the helper functions from the existing meson-canvas driver.
- Use clk_bulk_data to map clocks from DTS.
- Retry the V4L2 Compliance test on 6.18-rc6, fix a newly introduced bug.
- Link to v1: https://lore.kernel.org/r/20251027-b4-s4-vdec-upstream-v1-0-620401813b5d@amlogic.com
Signed-off-by: Zhentao Guo <zhentao.guo@amlogic.com>
---
Zhentao Guo (6):
firmware: meson: sm: Add video firmware loading SMC call
firmware: meson: sm: video firmware loading via secure monitor
media: dt-bindings: Add Amlogic V4L2 video decoder
decoder: Add V4L2 stateless H.264 decoder driver
arm64: dts: amlogic: Add video decoder driver support for S4 SOCs
arm64: defconfig: Enable CONFIG_VIDEO_AMLOGIC_VDEC
.../devicetree/bindings/media/amlogic,s4-vdec.yaml | 103 +
MAINTAINERS | 7 +
arch/arm64/boot/dts/amlogic/meson-s4.dtsi | 34 +
arch/arm64/configs/defconfig | 1 +
drivers/firmware/meson/meson_sm.c | 1 +
drivers/media/platform/amlogic/Kconfig | 1 +
drivers/media/platform/amlogic/Makefile | 1 +
drivers/media/platform/amlogic/vdec/Kconfig | 18 +
drivers/media/platform/amlogic/vdec/Makefile | 4 +
drivers/media/platform/amlogic/vdec/TODO | 7 +
drivers/media/platform/amlogic/vdec/aml_vdec.c | 736 +++++++
drivers/media/platform/amlogic/vdec/aml_vdec.h | 33 +
drivers/media/platform/amlogic/vdec/aml_vdec_drv.c | 239 +++
drivers/media/platform/amlogic/vdec/aml_vdec_drv.h | 172 ++
drivers/media/platform/amlogic/vdec/aml_vdec_hw.c | 538 +++++
drivers/media/platform/amlogic/vdec/aml_vdec_hw.h | 159 ++
.../platform/amlogic/vdec/aml_vdec_platform.c | 81 +
.../platform/amlogic/vdec/aml_vdec_platform.h | 46 +
.../media/platform/amlogic/vdec/aml_vdec_tee_fw.c | 240 +++
.../media/platform/amlogic/vdec/aml_vdec_tee_fw.h | 27 +
drivers/media/platform/amlogic/vdec/h264.c | 2128 ++++++++++++++++++++
drivers/media/platform/amlogic/vdec/h264.h | 299 +++
drivers/media/platform/amlogic/vdec/reg_defines.h | 177 ++
include/linux/firmware/meson/meson_sm.h | 1 +
24 files changed, 5053 insertions(+)
---
base-commit: d387b06f7c15b4639244ad66b4b0900c6a02b430
change-id: 20251027-b4-s4-vdec-upstream-0603c1a4c84a
Best regards,
--
Zhentao Guo <zhentao.guo@amlogic.com>
^ permalink raw reply
* Re: [PATCH v2 1/2] gpio: mxc: fix irq_high handling
From: Bartosz Golaszewski @ 2026-05-26 8:34 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Alexander Stein
Cc: Bartosz Golaszewski, linux-gpio, imx, linux-arm-kernel,
linux-kernel
In-Reply-To: <20260526063504.25916-1-alexander.stein@ew.tq-group.com>
On Tue, 26 May 2026 08:35:01 +0200, Alexander Stein wrote:
> If port->irq_high is -1 (fsl,imx21-gpio compatible) and gpio_idx is >= 16
> enable_irq_wake() is called with -1 which is wrong.
>
>
Applied, thanks!
[1/2] gpio: mxc: fix irq_high handling
https://git.kernel.org/brgl/c/dac917ed5aead741004db8d0d5151dd577802df8
[2/2] gpio: mxc: use BIT() macro
https://git.kernel.org/brgl/c/077c421b38ab87f32f7ef4503a6add43ae4cb57a
Best regards,
--
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH 1/2] gfp_types: Introduce a new GFP_ATOMIC_RT gfp flag
From: Sebastian Andrzej Siewior @ 2026-05-26 8:28 UTC (permalink / raw)
To: Michal Hocko
Cc: Waiman Long, Marc Zyngier, Thomas Gleixner, Clark Williams,
Steven Rostedt, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, linux-arm-kernel, linux-kernel, linux-mm,
linux-rt-devel
In-Reply-To: <ahQLVgj8zV4xQRh9@tiehlicka>
On 2026-05-25 10:41:58 [+0200], Michal Hocko wrote:
> Before we go this way we need to really be clear we do want to support
> raw_spinlock (aka RT) contexts. This is a big commitment because it
> dictates internal allocator locking that would have potentially a much
This is only needed for 2/2 of this series and Marc didn't want it.
Sebastian
^ permalink raw reply
* Re: [PATCH 0/7] TQMLX2160A-MBLS2160A DT fixes/updates
From: Alexander Stein @ 2026-05-26 8:23 UTC (permalink / raw)
To: Frank Li, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Shawn Guo
Cc: linux-arm-kernel, linux, devicetree, linux-kernel, Nora Schiffer
In-Reply-To: <20260331141915.2918927-1-alexander.stein@ew.tq-group.com>
Hi Frank,
Am Dienstag, 31. März 2026, 16:19:01 CEST schrieb Alexander Stein:
> Hi,
>
> this series adds small fixes and improvements for TQMLX2160A DTs.
> The DT overlays address specific hardware behaviour when serdes is configured
> differently.
Any feedback here?
Thank and best regards,
Alexander
>
> Best regards,
> Alexander
>
> Alexander Stein (1):
> arm64: dts: fsl-lx2160a-tqmlx2160a: Remove deprecated properties
>
> Nora Schiffer (6):
> arm64: dts: fsl-lx2160a-tqmlx2160a: fix LED polarity
> arm64: dts: fsl-lx2160a-tqmlx2160a-mblx2160a: use DPMAC 17 and 18 for
> SGMII in SERDES2 configs 7 and 11
> arm64: dts: fsl-lx2160a-tqmlx2160a: add aliases for all 18 DPMAC
> instances
> arm64: dts: fsl-lx2160a-tqmlx2160a-mbls2160a: add various GPIO hogs
> arm64: dts: fsl-lx2160a-tqmlx2160a-mbls2160a: enable pcs_mdio17 and
> pcs_mdio18 in appropriate overlays
> arm64: dts: fsl-lx2160a-tqmlx2160a-mbls2160a: specify Ethernet PHY
> reset GPIOs
>
> .../fsl-lx2160a-tqmlx2160a-mblx2160a.dts | 306 +++++++++++++++++-
> ...l-lx2160a-tqmlx2160a-mblx2160a_x_11_x.dtso | 20 ++
> ...sl-lx2160a-tqmlx2160a-mblx2160a_x_7_x.dtso | 20 ++
> .../dts/freescale/fsl-lx2160a-tqmlx2160a.dtsi | 23 +-
> 4 files changed, 357 insertions(+), 12 deletions(-)
>
>
--
TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht München, HRB 105018
Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
http://www.tq-group.com/
^ permalink raw reply
* Re: [PATCH v2 0/2] i2c: imx: fix SMBus block-read of 0 locking the bus
From: Vincent Jardin @ 2026-05-26 8:12 UTC (permalink / raw)
To: Carlos Song (OSS)
Cc: Oleksij Rempel, Pengutronix Kernel Team, Andi Shyti, Frank Li,
Sascha Hauer, Fabio Estevam, Wolfram Sang, Kaushal Butala,
Shawn Guo, Stefan Eichenberger, linux-i2c@vger.kernel.org,
imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
In-Reply-To: <AM0PR04MB6802B906706F0CDE5BA73696E80B2@AM0PR04MB6802.eurprd04.prod.outlook.com>
Hi Carlos,
> Thanks for working on this fix, this looks good to me.
thanks for checking it. It took some times to isolate this issue and
then find a fix.
> SMBus block reads with a length of 0 seem quite uncommon in practice.
> Was this triggered by a specific device behavior, or mainly found
> during boundary / compliance testing?
It is trigger by the usage of a mpq8785 on the i2c bus: when the kernel attaches
on it using its pmsbus/hwmon framework, then the i2c bus get locked on lx2160 !
> Regarding the handling of len == 0,
> I see that the patch sets:
>
> msg->buf[0] = 0;
> msg->len = 2;
>
> It relies on the last-byte STOP handling together with TXAK. It will help I2C-IMX generate NACK + STOP and
> release the bus, right?
Yes, exactly. Reading I2DR for the length byte has already armed the
next byte, so we set TXAK to NACK it and extend msg->len to 2.
Next then i2c_imx_isr_read_continue() at msg_buf_idx == msg->len - 1,
ie the normal last-byte path, which clears MSTA to emit STOP. So NACK + STOP,
and THEN the bus is released. I do not see any other means to handle it.
> len = 0 is a legal behavior, So it go into a successful path.
Yes. count == 0 is legal (SMBus 3.1 6.5.7), so the transfer reaches
STATE_DONE and returns success.
> But len > I2C_SMBUS_BLOCK_MAX is abnormal behavior. So it go into a fail path.
Correct, and it is a protocol error, so it needs to end up with a -EPROTO while
a count of 0 is an ok case.
> Do I understand it right?
yes. I do not see any other means to handle it.
> Also, if possible could you briefly describe how you validated this change
> (e.g. test setup or steps, with and without the fix)?
On a lx2160a board, on its i2c, bind a mpq8785, and enable the Kernel pmbus/hwmon
framework, then the i2c bus becomes un-useable. Using a scope, we can confirm that
the lx21260a i2c cannot recover.
Best regards,
Vincent
^ permalink raw reply
* Re: [PATCH v3 01/17] ACPI: GTDT: Account for GTDTv3 size when walking the platform timer descriptors
From: Sudeep Holla @ 2026-05-26 8:06 UTC (permalink / raw)
To: Marc Zyngier
Cc: linux-arm-kernel, linux-acpi, linux-kernel, devicetree,
Lorenzo Pieralisi, Sudeep Holla, Hanjun Guo, Catalin Marinas,
Will Deacon, Rafael J. Wysocki, Mark Rutland, Daniel Lezcano,
Thomas Gleixner, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Neil Armstrong,
Kevin Hilman, Jerome Brunet, Martin Blumenstingl, Ge Gordon,
BST Linux Kernel Upstream Group, Jesper Nilsson, Lars Persson,
Alim Akhtar, Ivaylo Ivanov, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Dinh Nguyen,
Matthias Brugger, AngeloGioacchino Del Regno, Thierry Reding,
Jonathan Hunter, Bjorn Andersson, Konrad Dybcio,
Andreas Färber, Yu-Chun Lin [林祐君],
Heiko Stuebner, Shawn Lin, Orson Zhai, Baolin Wang, Michal Simek
In-Reply-To: <20260523140242.586031-2-maz@kernel.org>
On Sat, May 23, 2026 at 03:02:26PM +0100, Marc Zyngier wrote:
> Since ARMv8.1, the architecture has grown an EL2-private virtual
> timer. This has been described in ACPI since ACPI v6.3 and revision
> 3 of the GTDT table.
>
> An aditional structure was added in ACPICA, though in a rather
> bizarre way, and merged in v5.1 as 8f5a14d053100 ("ACPICA: ACPI 6.3:
> add GTDT Revision 3 support").
>
> Finally plug the table parsing in GTDT, and correct the parsing of
> the platform timer subtables to account for the expanded size of
> the base table. This also comes with some extra sanitisation of
> the table, in the unlikely case someone got it wrong...
>
> Suggested-by: Sudeep Holla <sudeep.holla@kernel.org>
Reviewed-by: Sudeep Holla <sudeep.holla@kernel.org>
--
Regards,
Sudeep
^ permalink raw reply
* Re: [PATCH] dt-bindings: gpio: meson-axg: Fix whitespace issue
From: Bartosz Golaszewski @ 2026-05-26 8:03 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Kevin Hilman,
Jerome Brunet, Martin Blumenstingl, Jun Yan
Cc: Bartosz Golaszewski, linux-gpio, devicetree, linux-arm-kernel,
linux-amlogic, linux-kernel
In-Reply-To: <20260524154954.385778-1-jerrysteve1101@gmail.com>
On Sun, 24 May 2026 23:49:53 +0800, Jun Yan wrote:
> Clean up whitespace misalignment in meson-axg-gpio.h
>
>
Applied, thanks!
[1/1] dt-bindings: gpio: meson-axg: Fix whitespace issue
https://git.kernel.org/brgl/c/820017813b818a9b6411e481fcc98f5260b6e6c1
Best regards,
--
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH v3 1/6] arm64/hugetlb: Extend batching of multiple CONT_PTE in a single PTE setup
From: Dev Jain @ 2026-05-26 7:56 UTC (permalink / raw)
To: Wen Jiang, linux-mm, linux-arm-kernel, catalin.marinas, will,
akpm, urezki
Cc: baohua, Xueyuan.chen21, rppt, david, ryan.roberts,
anshuman.khandual, ajd, linux-kernel, jiangwen6
In-Reply-To: <20260522053146.83209-2-jiangwenxiaomi@gmail.com>
On 22/05/26 11:01 am, Wen Jiang wrote:
> From: "Barry Song (Xiaomi)" <baohua@kernel.org>
>
> For sizes aligned to CONT_PTE_SIZE and smaller than PMD_SIZE,
> we can batch CONT_PTE settings instead of handling them individually.
Better wording: "we can handle CONT_PTE_SIZE groups together"
>
> Signed-off-by: Barry Song (Xiaomi) <baohua@kernel.org>
> Signed-off-by: Wen Jiang <jiangwen6@xiaomi.com>
> Tested-by: Xueyuan Chen <xueyuan.chen21@gmail.com>
> ---
> arch/arm64/mm/hugetlbpage.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> index a42c05cf56408..c4d8b226126cb 100644
> --- a/arch/arm64/mm/hugetlbpage.c
> +++ b/arch/arm64/mm/hugetlbpage.c
> @@ -110,6 +110,12 @@ static inline int num_contig_ptes(unsigned long size, size_t *pgsize)
> contig_ptes = CONT_PTES;
> break;
> default:
> + if (size > 0 && size < PMD_SIZE &&
> + IS_ALIGNED(size, CONT_PTE_SIZE)) {
> + contig_ptes = size >> PAGE_SHIFT;
> + *pgsize = PAGE_SIZE;
> + break;
> + }
> WARN_ON(!__hugetlb_valid_size(size));
> }
>
> @@ -359,6 +365,10 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags)
> case CONT_PTE_SIZE:
> return pte_mkcont(entry);
> default:
> + if (pagesize > 0 && pagesize < PMD_SIZE &&
> + IS_ALIGNED(pagesize, CONT_PTE_SIZE))
> + return pte_mkcont(entry);
> +
> break;
> }
> pr_warn("%s: unrecognized huge page size 0x%lx\n",
^ permalink raw reply
* Re: [PATCH] irqchip/gic-v4: Harden against bogus command line
From: Mostafa Saleh @ 2026-05-26 7:50 UTC (permalink / raw)
To: Marc Zyngier; +Cc: linux-arm-kernel, linux-kernel, tglx
In-Reply-To: <86zf1qv4do.wl-maz@kernel.org>
On Sat, May 23, 2026 at 10:53:23AM +0100, Marc Zyngier wrote:
> On Thu, 21 May 2026 14:05:03 +0100,
> Mostafa Saleh <smostafa@google.com> wrote:
> >
> > When accidentally setting “kvm-arm.vgic_v4_enable=1” on the wrong
> > setup that has no MSI controller device tree node (it exists but
> > not used) and GICv4, it caused a panic as “gic_domain” is NULL and
> > the kernel attempted to access its ops.
>
> When you say "that has no MSI controller device tree node", does it
> mean that the ITS has not been probed at all?
Yes.
>
> >
> > Originally, I hit this on an older kernel, but was able to reproduce
> > it on upstream with Qemu by hacking this unreasonable setup.
> >
> > [ 33.145536] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000028
> > [ 33.145658] Mem abort info:
> > [ 33.145751] ESR = 0x0000000096000006
> > ...
> > [ 33.154057] CPU: 1 UID: 0 PID: 295 Comm: lkvm-static Not tainted 7.1.0-rc4-ge3f15ad3970e #5 PREEMPT
> > [ 33.156922] Hardware name: linux,dummy-virt (DT)
> > [ 33.158780] pstate: 81402005 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
> > [ 33.160340] pc : __irq_domain_instantiate+0x1d4/0x578
> > [ 33.162602] lr : __irq_domain_instantiate+0x1cc/0x578
> >
> > Add a hardening check to avoid the NULL access, and fail the VM
> > creation in that case.
> >
> > Signed-off-by: Mostafa Saleh <smostafa@google.com>
> > ---
> > drivers/irqchip/irq-gic-v4.c | 3 +++
> > 1 file changed, 3 insertions(+)
> >
> > diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c
> > index 8455b4a5fbb0..7e39f7eae85f 100644
> > --- a/drivers/irqchip/irq-gic-v4.c
> > +++ b/drivers/irqchip/irq-gic-v4.c
> > @@ -159,6 +159,9 @@ int its_alloc_vcpu_irqs(struct its_vm *vm)
> > {
> > int vpe_base_irq, i;
> >
> > + if (!gic_domain)
> > + return -EINVAL;
> > +
> > vm->fwnode = irq_domain_alloc_named_id_fwnode("GICv4-vpe",
> > task_pid_nr(current));
> > if (!vm->fwnode)
>
> I think this check is a good few levels too late. If you want to fix
> this, I'd rather make sure that kvm_vgic_global_state.has_gicv4 is
> reliable and covers this case. Which means making sure that
> gic_kvm_info::has_v4 is itself reliable.
>
> If my above understanding is correct, I'd expect the following
> (untested) hack to help.
Thanks! That also fixes the crash, the VM will launch with a vGIC with
no ITS in that case.
Thanks,
Mostafa
>
> Thanks,
>
> M.
>
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 291d7668cc8da..e6b9fee1b6786 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -5838,6 +5838,7 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
>
> if (list_empty(&its_nodes)) {
> pr_warn("ITS: No ITS available, not enabling LPIs\n");
> + rdists->has_vlpis = false;
> return -ENXIO;
> }
>
>
> --
> Without deviation from the norm, progress is not possible.
^ permalink raw reply
* [PATCH] KVM: arm64: PMU: Preserve AArch32 counter low bits
From: Qiang Ma @ 2026-05-26 7:46 UTC (permalink / raw)
To: maz, oupton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will
Cc: linux-arm-kernel, kvmarm, linux-kernel, Qiang Ma
AArch32 writes to PMU event counters cannot update the top 32 bits,
even when PMUv3p5 makes the counters 64-bit. KVM therefore needs to
preserve the existing high half and only update the low half written by
the guest, unless the caller explicitly forces a full reset through
PMCR.P.
The current code masks @val down to the old high half before taking
lower_32_bits(val), which means the low half is always zero. As a
result, AArch32 writes to event counters discard the guest-provided low
32 bits instead of storing them.
Build the new value from the old high 32 bits and the low 32 bits of
the value supplied by the guest.
Fixes: 26d2d0594d70 ("KVM: arm64: PMU: Do not let AArch32 change the counters' top 32 bits")
Signed-off-by: Qiang Ma <maqianga@uniontech.com>
---
arch/arm64/kvm/pmu-emul.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index e1860acae641..c816db5d6761 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -174,8 +174,8 @@ static void kvm_pmu_set_pmc_value(struct kvm_pmc *pmc, u64 val, bool force)
* action is to use PMCR.P, which will reset them to
* 0 (the only use of the 'force' parameter).
*/
- val = __vcpu_sys_reg(vcpu, reg) & GENMASK(63, 32);
- val |= lower_32_bits(val);
+ val = (__vcpu_sys_reg(vcpu, reg) & GENMASK(63, 32)) |
+ lower_32_bits(val);
}
__vcpu_assign_sys_reg(vcpu, reg, val);
--
2.20.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox