* [PATCH RFC v4 3/7] drm/msm/adreno: rename llc_mmio to cx_misc_mmio
From: Alexander Koskovich @ 2026-04-16 11:05 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Akhil P Oommen,
Bjorn Andersson
Cc: Luca Weiss, linux-arm-msm, dri-devel, freedreno, devicetree,
linux-kernel, Alexander Koskovich, Konrad Dybcio
In-Reply-To: <20260416-adreno-810-v4-0-61676e073f8a@pm.me>
This region is used for more than just LLCC, it also provides access to
software fuse values (raytracing, etc).
Rename relevant symbols from _llc to _cx_misc for use in a follow up
change that decouples this from LLCC.
Reviewed-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Alexander Koskovich <akoskovich@pm.me>
---
drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 8 ++++----
drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 16 ++++++++--------
drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 14 +++++++-------
drivers/gpu/drm/msm/adreno/a8xx_gpu.c | 2 +-
4 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index b7166a883b01..6a369682bb80 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -947,7 +947,7 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
/* Turn on TCM (Tightly Coupled Memory) retention */
if (adreno_is_a7xx(adreno_gpu))
- a6xx_llc_write(a6xx_gpu, REG_A7XX_CX_MISC_TCM_RET_CNTL, 1);
+ a6xx_cx_misc_write(a6xx_gpu, REG_A7XX_CX_MISC_TCM_RET_CNTL, 1);
else if (!adreno_is_a8xx(adreno_gpu))
gmu_write(gmu, REG_A6XX_GMU_GENERAL_7, 1);
@@ -1215,7 +1215,7 @@ static int a6xx_gmu_secure_init(struct a6xx_gpu *a6xx_gpu)
if (!qcom_scm_is_available()) {
dev_warn_once(gpu->dev->dev,
"SCM is not available, poking fuse register\n");
- a6xx_llc_write(a6xx_gpu, REG_A7XX_CX_MISC_SW_FUSE_VALUE,
+ a6xx_cx_misc_write(a6xx_gpu, REG_A7XX_CX_MISC_SW_FUSE_VALUE,
A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
A7XX_CX_MISC_SW_FUSE_VALUE_FASTBLEND |
A7XX_CX_MISC_SW_FUSE_VALUE_LPAC);
@@ -1236,7 +1236,7 @@ static int a6xx_gmu_secure_init(struct a6xx_gpu *a6xx_gpu)
* firmware, find out whether that's the case. The scm call
* above sets the fuse register.
*/
- fuse_val = a6xx_llc_read(a6xx_gpu,
+ fuse_val = a6xx_cx_misc_read(a6xx_gpu,
REG_A7XX_CX_MISC_SW_FUSE_VALUE);
adreno_gpu->has_ray_tracing =
!!(fuse_val & A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING);
@@ -1343,7 +1343,7 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
/* Check to see if we are doing a cold or warm boot */
if (adreno_is_a7xx(adreno_gpu) || adreno_is_a8xx(adreno_gpu)) {
- status = a6xx_llc_read(a6xx_gpu, REG_A7XX_CX_MISC_TCM_RET_CNTL) == 1 ?
+ status = a6xx_cx_misc_read(a6xx_gpu, REG_A7XX_CX_MISC_TCM_RET_CNTL) == 1 ?
GMU_WARM_BOOT : GMU_COLD_BOOT;
} else if (gmu->legacy) {
status = gmu_read(gmu, REG_A6XX_GMU_GENERAL_7) == 1 ?
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index d5aba072f44c..4275c1d726b2 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -2039,7 +2039,7 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu)
struct msm_gpu *gpu = &adreno_gpu->base;
u32 cntl1_regval = 0;
- if (IS_ERR(a6xx_gpu->llc_mmio))
+ if (IS_ERR(a6xx_gpu->cx_misc_mmio))
return;
if (!llcc_slice_activate(a6xx_gpu->llc_slice)) {
@@ -2078,14 +2078,14 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu)
* pagetables
*/
if (!a6xx_gpu->have_mmu500) {
- a6xx_llc_write(a6xx_gpu,
+ a6xx_cx_misc_write(a6xx_gpu,
REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_1, cntl1_regval);
/*
* Program cacheability overrides to not allocate cache
* lines on a write miss
*/
- a6xx_llc_rmw(a6xx_gpu,
+ a6xx_cx_misc_rmw(a6xx_gpu,
REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_0, 0xF, 0x03);
return;
}
@@ -2098,7 +2098,7 @@ static void a7xx_llc_activate(struct a6xx_gpu *a6xx_gpu)
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
struct msm_gpu *gpu = &adreno_gpu->base;
- if (IS_ERR(a6xx_gpu->llc_mmio))
+ if (IS_ERR(a6xx_gpu->cx_misc_mmio))
return;
if (!llcc_slice_activate(a6xx_gpu->llc_slice)) {
@@ -2151,15 +2151,15 @@ static void a6xx_llc_slices_init(struct platform_device *pdev,
of_node_put(phandle);
if (is_a7xx || !a6xx_gpu->have_mmu500)
- a6xx_gpu->llc_mmio = msm_ioremap(pdev, "cx_mem");
+ a6xx_gpu->cx_misc_mmio = msm_ioremap(pdev, "cx_mem");
else
- a6xx_gpu->llc_mmio = NULL;
+ a6xx_gpu->cx_misc_mmio = NULL;
a6xx_gpu->llc_slice = llcc_slice_getd(LLCC_GPU);
a6xx_gpu->htw_llc_slice = llcc_slice_getd(LLCC_GPUHTW);
if (IS_ERR_OR_NULL(a6xx_gpu->llc_slice) && IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice))
- a6xx_gpu->llc_mmio = ERR_PTR(-EINVAL);
+ a6xx_gpu->cx_misc_mmio = ERR_PTR(-EINVAL);
}
#define GBIF_CLIENT_HALT_MASK BIT(0)
@@ -2560,7 +2560,7 @@ static int a6xx_read_speedbin(struct device *dev, struct a6xx_gpu *a6xx_gpu,
return ret;
if (info->quirks & ADRENO_QUIRK_SOFTFUSE) {
- *speedbin = a6xx_llc_read(a6xx_gpu, REG_A8XX_CX_MISC_SW_FUSE_FREQ_LIMIT_STATUS);
+ *speedbin = a6xx_cx_misc_read(a6xx_gpu, REG_A8XX_CX_MISC_SW_FUSE_FREQ_LIMIT_STATUS);
*speedbin = A8XX_CX_MISC_SW_FUSE_FREQ_LIMIT_STATUS_FINALFREQLIMIT(*speedbin);
return 0;
}
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
index eb431e5e00b1..648608c1c98e 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
@@ -102,7 +102,7 @@ struct a6xx_gpu {
bool has_whereami;
- void __iomem *llc_mmio;
+ void __iomem *cx_misc_mmio;
void *llc_slice;
void *htw_llc_slice;
bool have_mmu500;
@@ -240,19 +240,19 @@ static inline bool a6xx_has_gbif(struct adreno_gpu *gpu)
return true;
}
-static inline void a6xx_llc_rmw(struct a6xx_gpu *a6xx_gpu, u32 reg, u32 mask, u32 or)
+static inline void a6xx_cx_misc_rmw(struct a6xx_gpu *a6xx_gpu, u32 reg, u32 mask, u32 or)
{
- return msm_rmw(a6xx_gpu->llc_mmio + (reg << 2), mask, or);
+ return msm_rmw(a6xx_gpu->cx_misc_mmio + (reg << 2), mask, or);
}
-static inline u32 a6xx_llc_read(struct a6xx_gpu *a6xx_gpu, u32 reg)
+static inline u32 a6xx_cx_misc_read(struct a6xx_gpu *a6xx_gpu, u32 reg)
{
- return readl(a6xx_gpu->llc_mmio + (reg << 2));
+ return readl(a6xx_gpu->cx_misc_mmio + (reg << 2));
}
-static inline void a6xx_llc_write(struct a6xx_gpu *a6xx_gpu, u32 reg, u32 value)
+static inline void a6xx_cx_misc_write(struct a6xx_gpu *a6xx_gpu, u32 reg, u32 value)
{
- writel(value, a6xx_gpu->llc_mmio + (reg << 2));
+ writel(value, a6xx_gpu->cx_misc_mmio + (reg << 2));
}
#define shadowptr(_a6xx_gpu, _ring) ((_a6xx_gpu)->shadow_iova + \
diff --git a/drivers/gpu/drm/msm/adreno/a8xx_gpu.c b/drivers/gpu/drm/msm/adreno/a8xx_gpu.c
index 9b99ec5ceeb5..d519a29573a1 100644
--- a/drivers/gpu/drm/msm/adreno/a8xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a8xx_gpu.c
@@ -104,7 +104,7 @@ void a8xx_gpu_get_slice_info(struct msm_gpu *gpu)
return;
}
- slice_mask &= a6xx_llc_read(a6xx_gpu,
+ slice_mask &= a6xx_cx_misc_read(a6xx_gpu,
REG_A8XX_CX_MISC_SLICE_ENABLE_FINAL);
a6xx_gpu->slice_mask = slice_mask;
--
2.53.0
^ permalink raw reply related
* [PATCH RFC v4 4/7] drm/msm/adreno: set cx_misc_mmio regardless of if platform has LLCC
From: Alexander Koskovich @ 2026-04-16 11:05 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Akhil P Oommen,
Bjorn Andersson
Cc: Luca Weiss, linux-arm-msm, dri-devel, freedreno, devicetree,
linux-kernel, Alexander Koskovich, Konrad Dybcio
In-Reply-To: <20260416-adreno-810-v4-0-61676e073f8a@pm.me>
Platforms without a LLCC (e.g. milos) still need to be able to read and
write to the cx_mem region. Previously if LLCC slices were unavailable
the cx_misc_mmio mapping was overwritten with ERR_PTR, causing a crash
when the GMU later accessed cx_mem.
Move the cx_misc_mmio mapping out of a6xx_llc_slices_init() into
a6xx_gpu_init() so that cx_mem mapping is independent of LLCC.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
Signed-off-by: Alexander Koskovich <akoskovich@pm.me>
---
drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 38 ++++++++++++++++-------------------
1 file changed, 17 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 4275c1d726b2..533272e11111 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -2039,7 +2039,7 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu)
struct msm_gpu *gpu = &adreno_gpu->base;
u32 cntl1_regval = 0;
- if (IS_ERR(a6xx_gpu->cx_misc_mmio))
+ if (IS_ERR_OR_NULL(a6xx_gpu->llc_slice) && IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice))
return;
if (!llcc_slice_activate(a6xx_gpu->llc_slice)) {
@@ -2098,7 +2098,7 @@ static void a7xx_llc_activate(struct a6xx_gpu *a6xx_gpu)
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
struct msm_gpu *gpu = &adreno_gpu->base;
- if (IS_ERR(a6xx_gpu->cx_misc_mmio))
+ if (IS_ERR_OR_NULL(a6xx_gpu->llc_slice) && IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice))
return;
if (!llcc_slice_activate(a6xx_gpu->llc_slice)) {
@@ -2135,31 +2135,12 @@ static void a6xx_llc_slices_destroy(struct a6xx_gpu *a6xx_gpu)
static void a6xx_llc_slices_init(struct platform_device *pdev,
struct a6xx_gpu *a6xx_gpu, bool is_a7xx)
{
- struct device_node *phandle;
-
/* No LLCC on non-RPMh (and by extension, non-GMU) SoCs */
if (adreno_has_gmu_wrapper(&a6xx_gpu->base))
return;
- /*
- * There is a different programming path for A6xx targets with an
- * mmu500 attached, so detect if that is the case
- */
- phandle = of_parse_phandle(pdev->dev.of_node, "iommus", 0);
- a6xx_gpu->have_mmu500 = (phandle &&
- of_device_is_compatible(phandle, "arm,mmu-500"));
- of_node_put(phandle);
-
- if (is_a7xx || !a6xx_gpu->have_mmu500)
- a6xx_gpu->cx_misc_mmio = msm_ioremap(pdev, "cx_mem");
- else
- a6xx_gpu->cx_misc_mmio = NULL;
-
a6xx_gpu->llc_slice = llcc_slice_getd(LLCC_GPU);
a6xx_gpu->htw_llc_slice = llcc_slice_getd(LLCC_GPUHTW);
-
- if (IS_ERR_OR_NULL(a6xx_gpu->llc_slice) && IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice))
- a6xx_gpu->cx_misc_mmio = ERR_PTR(-EINVAL);
}
#define GBIF_CLIENT_HALT_MASK BIT(0)
@@ -2621,6 +2602,7 @@ static struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
struct platform_device *pdev = priv->gpu_pdev;
struct adreno_platform_config *config = pdev->dev.platform_data;
const struct adreno_info *info = config->info;
+ struct device_node *phandle;
struct device_node *node;
struct a6xx_gpu *a6xx_gpu;
struct adreno_gpu *adreno_gpu;
@@ -2657,6 +2639,20 @@ static struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
a6xx_llc_slices_init(pdev, a6xx_gpu, is_a7xx);
+ /*
+ * There is a different programming path for A6xx targets with an
+ * mmu500 attached, so detect if that is the case
+ */
+ phandle = of_parse_phandle(pdev->dev.of_node, "iommus", 0);
+ a6xx_gpu->have_mmu500 = (phandle &&
+ of_device_is_compatible(phandle, "arm,mmu-500"));
+ of_node_put(phandle);
+
+ if (is_a7xx || !a6xx_gpu->have_mmu500)
+ a6xx_gpu->cx_misc_mmio = msm_ioremap(pdev, "cx_mem");
+ else
+ a6xx_gpu->cx_misc_mmio = NULL;
+
ret = a6xx_set_supported_hw(&pdev->dev, a6xx_gpu, info);
if (ret) {
a6xx_llc_slices_destroy(a6xx_gpu);
--
2.53.0
^ permalink raw reply related
* [PATCH RFC v4 5/7] drm/msm/a8xx: use pipe protect slot 15 for last-span-unbound feature
From: Alexander Koskovich @ 2026-04-16 11:05 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Akhil P Oommen,
Bjorn Andersson
Cc: Luca Weiss, linux-arm-msm, dri-devel, freedreno, devicetree,
linux-kernel, Alexander Koskovich, Konrad Dybcio
In-Reply-To: <20260416-adreno-810-v4-0-61676e073f8a@pm.me>
A8XX GPUs have two sets of protect registers: 64 global slots and 16
pipe specific slots. The last-span-unbound feature is only available
on pipe protect registers, and should always target pipe slot 15.
This matches the downstream driver which hardcodes pipe slot 15 for
all A8XX GPUs (GRAPHICS.LA.15.0.r1) and resolves protect errors on
A810.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
Signed-off-by: Alexander Koskovich <akoskovich@pm.me>
---
drivers/gpu/drm/msm/adreno/a8xx_gpu.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/a8xx_gpu.c b/drivers/gpu/drm/msm/adreno/a8xx_gpu.c
index d519a29573a1..74802f330ae9 100644
--- a/drivers/gpu/drm/msm/adreno/a8xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a8xx_gpu.c
@@ -265,8 +265,8 @@ static void a8xx_set_cp_protect(struct msm_gpu *gpu)
* Last span feature is only supported on PIPE specific register.
* So update those here
*/
- a8xx_write_pipe(gpu, PIPE_BR, REG_A8XX_CP_PROTECT_PIPE(protect->count_max), final_cfg);
- a8xx_write_pipe(gpu, PIPE_BV, REG_A8XX_CP_PROTECT_PIPE(protect->count_max), final_cfg);
+ a8xx_write_pipe(gpu, PIPE_BR, REG_A8XX_CP_PROTECT_PIPE(15), final_cfg);
+ a8xx_write_pipe(gpu, PIPE_BV, REG_A8XX_CP_PROTECT_PIPE(15), final_cfg);
a8xx_aperture_clear(gpu);
}
--
2.53.0
^ permalink raw reply related
* [PATCH RFC v4 6/7] drm/msm/adreno: add Adreno 810 GPU support
From: Alexander Koskovich @ 2026-04-16 11:05 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Akhil P Oommen,
Bjorn Andersson
Cc: Luca Weiss, linux-arm-msm, dri-devel, freedreno, devicetree,
linux-kernel, Alexander Koskovich
In-Reply-To: <20260416-adreno-810-v4-0-61676e073f8a@pm.me>
Add catalog entry and register configuration for the Adreno 810
found in Qualcomm SM7635 (Milos) based devices.
Signed-off-by: Alexander Koskovich <akoskovich@pm.me>
---
drivers/gpu/drm/msm/adreno/a6xx_catalog.c | 296 ++++++++++++++++++++++++++++++
drivers/gpu/drm/msm/adreno/adreno_gpu.h | 5 +
2 files changed, 301 insertions(+)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
index 550ff3a9b82e..1190804632d6 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
@@ -1799,6 +1799,259 @@ static const struct adreno_reglist_pipe x285_dyn_pwrup_reglist_regs[] = {
};
DECLARE_ADRENO_REGLIST_PIPE_LIST(x285_dyn_pwrup_reglist);
+static const struct adreno_reglist_pipe a810_nonctxt_regs[] = {
+ { REG_A8XX_CP_SMMU_STREAM_ID_LPAC, 0x00000101, BIT(PIPE_NONE) },
+ { REG_A8XX_GRAS_DBG_ECO_CNTL, 0x00f80800, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A6XX_PC_AUTO_VERTEX_STRIDE, 0x00000001, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_PC_VIS_STREAM_CNTL, 0x10010000, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_PC_CONTEXT_SWITCH_STABILIZE_CNTL_1, 0x00000002, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_PC_CHICKEN_BITS_1, 0x00000003, BIT(PIPE_BR) },
+ { REG_A8XX_PC_CHICKEN_BITS_1, 0x00000023, BIT(PIPE_BV) }, /* Avoid partial waves at VFD */
+ { REG_A8XX_PC_CHICKEN_BITS_2, 0x00000200, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_PC_CHICKEN_BITS_3, 0x00500000, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_PC_CHICKEN_BITS_4, 0x00500050, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A7XX_RB_CCU_CNTL, 0x00000068, BIT(PIPE_BR) },
+ { REG_A8XX_RB_RESOLVE_PREFETCH_CNTL, 0x00000007, BIT(PIPE_BR) },
+ { REG_A8XX_RB_CMP_DBG_ECO_CNTL, 0x00004000, BIT(PIPE_BR) },
+ { REG_A8XX_RBBM_NC_MODE_CNTL, 0x00000001, BIT(PIPE_NONE) },
+ { REG_A8XX_RBBM_SLICE_NC_MODE_CNTL, 0x00000001, BIT(PIPE_NONE) },
+ { REG_A8XX_RBBM_WAIT_IDLE_CLOCKS_CNTL, 0x00000030, BIT(PIPE_NONE) },
+ { REG_A8XX_RBBM_WAIT_IDLE_CLOCKS_CNTL2, 0x00000030, BIT(PIPE_NONE) },
+ { REG_A8XX_UCHE_GBIF_GX_CONFIG, 0x010240e0, BIT(PIPE_NONE) },
+ { REG_A8XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x22122212, BIT(PIPE_NONE) },
+ { REG_A8XX_RBBM_CGC_P2S_CNTL, 0x00000040, BIT(PIPE_NONE) },
+ /*
+ * BIT(22): Disable PS out of order retire
+ * BIT(23): Enable half wave mode and MM instruction src&dst is half precision
+ */
+ { REG_A7XX_SP_CHICKEN_BITS_2, BIT(22) | BIT(23), BIT(PIPE_NONE) },
+ { REG_A7XX_SP_CHICKEN_BITS_3, 0x00300000, BIT(PIPE_NONE) },
+ { REG_A6XX_SP_PERFCTR_SHADER_MASK, 0x0000003f, BIT(PIPE_NONE) },
+ { REG_A7XX_SP_HLSQ_TIMEOUT_THRESHOLD_DP, 0x00000080, BIT(PIPE_NONE) },
+ { REG_A7XX_SP_READ_SEL, 0x0001ff00, BIT(PIPE_NONE) },
+ { REG_A6XX_TPL1_DBG_ECO_CNTL, 0x10000000, BIT(PIPE_NONE) },
+ { REG_A6XX_TPL1_DBG_ECO_CNTL1, 0x00000724, BIT(PIPE_NONE) },
+ { REG_A6XX_UCHE_MODE_CNTL, 0x00020000, BIT(PIPE_NONE) },
+ { REG_A8XX_UCHE_CCHE_MODE_CNTL, 0x00001000, BIT(PIPE_NONE) },
+ { REG_A8XX_UCHE_CCHE_CACHE_WAYS, 0x00000800, BIT(PIPE_NONE) },
+ { REG_A8XX_UCHE_CACHE_WAYS, 0x00080000, BIT(PIPE_NONE) },
+ { REG_A8XX_UCHE_VARB_IDLE_TIMEOUT, 0x00000020, BIT(PIPE_NONE) },
+ { REG_A7XX_VFD_DBG_ECO_CNTL, 0x00008000, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_VFD_CB_BV_THRESHOLD, 0x00500050, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_VFD_CB_BR_THRESHOLD, 0x00600060, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_VFD_CB_BUSY_REQ_CNT, 0x00200020, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_VFD_CB_LP_REQ_CNT, 0x00100020, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_VPC_FLATSHADE_MODE_CNTL, 0x00000001, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_VSC_BIN_SIZE, 0x00010001, BIT(PIPE_NONE) },
+ { REG_A8XX_RB_GC_GMEM_PROTECT, 0x00900000, BIT(PIPE_BR) },
+ { },
+};
+
+static const u32 a810_protect_regs[] = {
+ A6XX_PROTECT_RDONLY(0x00000, 0x03a3),
+ A6XX_PROTECT_RDONLY(0x003b4, 0x008b),
+ A6XX_PROTECT_NORDWR(0x00440, 0x001f),
+ A6XX_PROTECT_RDONLY(0x00580, 0x005f),
+ A6XX_PROTECT_NORDWR(0x005e0, 0x011f),
+ A6XX_PROTECT_RDONLY(0x0074a, 0x0005),
+ A6XX_PROTECT_RDONLY(0x00759, 0x0026),
+ A6XX_PROTECT_RDONLY(0x00789, 0x0000),
+ A6XX_PROTECT_RDONLY(0x0078c, 0x0013),
+ A6XX_PROTECT_NORDWR(0x00800, 0x0029),
+ A6XX_PROTECT_NORDWR(0x00837, 0x00af),
+ A6XX_PROTECT_RDONLY(0x008e7, 0x00c9),
+ A6XX_PROTECT_NORDWR(0x008ec, 0x00c3),
+ A6XX_PROTECT_NORDWR(0x009b1, 0x0250),
+ A6XX_PROTECT_RDONLY(0x00ce0, 0x0001),
+ A6XX_PROTECT_RDONLY(0x00df0, 0x0000),
+ A6XX_PROTECT_NORDWR(0x00df1, 0x0000),
+ A6XX_PROTECT_NORDWR(0x00e01, 0x0000),
+ A6XX_PROTECT_NORDWR(0x00e03, 0x1fff),
+ A6XX_PROTECT_NORDWR(0x03c00, 0x00c5),
+ A6XX_PROTECT_RDONLY(0x03cc6, 0x1fff),
+ A6XX_PROTECT_NORDWR(0x08600, 0x01ff),
+ A6XX_PROTECT_NORDWR(0x08e00, 0x00ff),
+ A6XX_PROTECT_RDONLY(0x08f00, 0x0000),
+ A6XX_PROTECT_NORDWR(0x08f01, 0x01be),
+ A6XX_PROTECT_NORDWR(0x09600, 0x01ff),
+ A6XX_PROTECT_RDONLY(0x0981a, 0x02e5),
+ A6XX_PROTECT_NORDWR(0x09e00, 0x01ff),
+ A6XX_PROTECT_NORDWR(0x0a600, 0x01ff),
+ A6XX_PROTECT_NORDWR(0x0ae00, 0x0006),
+ A6XX_PROTECT_NORDWR(0x0ae08, 0x0006),
+ A6XX_PROTECT_NORDWR(0x0ae10, 0x036f),
+ A6XX_PROTECT_NORDWR(0x0b600, 0x1fff),
+ A6XX_PROTECT_NORDWR(0x0dc00, 0x1fff),
+ A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff),
+ A6XX_PROTECT_NORDWR(0x18400, 0x003f),
+ A6XX_PROTECT_RDONLY(0x18440, 0x013f),
+ A6XX_PROTECT_NORDWR(0x18580, 0x1fff),
+ A6XX_PROTECT_NORDWR(0x1b400, 0x1fff),
+ A6XX_PROTECT_NORDWR(0x1f400, 0x0477),
+ A6XX_PROTECT_RDONLY(0x1f878, 0x0787),
+ A6XX_PROTECT_NORDWR(0x1f930, 0x0329),
+ A6XX_PROTECT_NORDWR(0x20000, 0x1fff),
+ A6XX_PROTECT_NORDWR(0x27800, 0x007f),
+ A6XX_PROTECT_RDONLY(0x27880, 0x0381),
+ A6XX_PROTECT_NORDWR(0x27882, 0x0001),
+ A6XX_PROTECT_NORDWR(0x27c02, 0x0000),
+};
+DECLARE_ADRENO_PROTECT(a810_protect, 64);
+
+static const uint32_t a810_pwrup_reglist_regs[] = {
+ REG_A6XX_UCHE_MODE_CNTL,
+ REG_A8XX_UCHE_VARB_IDLE_TIMEOUT,
+ REG_A8XX_UCHE_GBIF_GX_CONFIG,
+ REG_A8XX_UCHE_CACHE_WAYS,
+ REG_A8XX_UCHE_CCHE_MODE_CNTL,
+ REG_A8XX_UCHE_CCHE_CACHE_WAYS,
+ REG_A8XX_UCHE_CCHE_GC_GMEM_RANGE_MIN,
+ REG_A8XX_UCHE_CCHE_GC_GMEM_RANGE_MIN + 1,
+ REG_A8XX_UCHE_CCHE_TRAP_BASE,
+ REG_A8XX_UCHE_CCHE_TRAP_BASE + 1,
+ REG_A8XX_UCHE_CCHE_WRITE_THRU_BASE,
+ REG_A8XX_UCHE_CCHE_WRITE_THRU_BASE + 1,
+ REG_A8XX_UCHE_WRITE_THRU_BASE,
+ REG_A8XX_UCHE_WRITE_THRU_BASE + 1,
+ REG_A8XX_UCHE_TRAP_BASE,
+ REG_A8XX_UCHE_TRAP_BASE + 1,
+ REG_A8XX_UCHE_CLIENT_PF,
+ REG_A8XX_VSC_BIN_SIZE,
+ REG_A8XX_RB_CMP_NC_MODE_CNTL,
+ REG_A7XX_SP_HLSQ_TIMEOUT_THRESHOLD_DP,
+ REG_A8XX_SP_HLSQ_GC_GMEM_RANGE_MIN,
+ REG_A8XX_SP_HLSQ_GC_GMEM_RANGE_MIN + 1,
+ REG_A7XX_SP_READ_SEL,
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(1),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(2),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(3),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(4),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(5),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(6),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(7),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(8),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(9),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(10),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(11),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(12),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(13),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(14),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(15),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(16),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(17),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(18),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(19),
+};
+DECLARE_ADRENO_REGLIST_LIST(a810_pwrup_reglist);
+
+static const u32 a810_ifpc_reglist_regs[] = {
+ REG_A8XX_RBBM_NC_MODE_CNTL,
+ REG_A8XX_RBBM_PERFCTR_CNTL,
+ REG_A8XX_RBBM_SLICE_INTERFACE_HANG_INT_CNTL,
+ REG_A8XX_RBBM_SLICE_NC_MODE_CNTL,
+ REG_A6XX_SP_NC_MODE_CNTL,
+ REG_A7XX_SP_CHICKEN_BITS_2,
+ REG_A7XX_SP_CHICKEN_BITS_3,
+ REG_A6XX_SP_PERFCTR_SHADER_MASK,
+ REG_A6XX_TPL1_NC_MODE_CNTL,
+ REG_A6XX_TPL1_DBG_ECO_CNTL,
+ REG_A6XX_TPL1_DBG_ECO_CNTL1,
+ REG_A8XX_CP_PROTECT_GLOBAL(0),
+ REG_A8XX_CP_PROTECT_GLOBAL(1),
+ REG_A8XX_CP_PROTECT_GLOBAL(2),
+ REG_A8XX_CP_PROTECT_GLOBAL(3),
+ REG_A8XX_CP_PROTECT_GLOBAL(4),
+ REG_A8XX_CP_PROTECT_GLOBAL(5),
+ REG_A8XX_CP_PROTECT_GLOBAL(6),
+ REG_A8XX_CP_PROTECT_GLOBAL(7),
+ REG_A8XX_CP_PROTECT_GLOBAL(8),
+ REG_A8XX_CP_PROTECT_GLOBAL(9),
+ REG_A8XX_CP_PROTECT_GLOBAL(10),
+ REG_A8XX_CP_PROTECT_GLOBAL(11),
+ REG_A8XX_CP_PROTECT_GLOBAL(12),
+ REG_A8XX_CP_PROTECT_GLOBAL(13),
+ REG_A8XX_CP_PROTECT_GLOBAL(14),
+ REG_A8XX_CP_PROTECT_GLOBAL(15),
+ REG_A8XX_CP_PROTECT_GLOBAL(16),
+ REG_A8XX_CP_PROTECT_GLOBAL(17),
+ REG_A8XX_CP_PROTECT_GLOBAL(18),
+ REG_A8XX_CP_PROTECT_GLOBAL(19),
+ REG_A8XX_CP_PROTECT_GLOBAL(20),
+ REG_A8XX_CP_PROTECT_GLOBAL(21),
+ REG_A8XX_CP_PROTECT_GLOBAL(22),
+ REG_A8XX_CP_PROTECT_GLOBAL(23),
+ REG_A8XX_CP_PROTECT_GLOBAL(24),
+ REG_A8XX_CP_PROTECT_GLOBAL(25),
+ REG_A8XX_CP_PROTECT_GLOBAL(26),
+ REG_A8XX_CP_PROTECT_GLOBAL(27),
+ REG_A8XX_CP_PROTECT_GLOBAL(28),
+ REG_A8XX_CP_PROTECT_GLOBAL(29),
+ REG_A8XX_CP_PROTECT_GLOBAL(30),
+ REG_A8XX_CP_PROTECT_GLOBAL(31),
+ REG_A8XX_CP_PROTECT_GLOBAL(32),
+ REG_A8XX_CP_PROTECT_GLOBAL(33),
+ REG_A8XX_CP_PROTECT_GLOBAL(34),
+ REG_A8XX_CP_PROTECT_GLOBAL(35),
+ REG_A8XX_CP_PROTECT_GLOBAL(36),
+ REG_A8XX_CP_PROTECT_GLOBAL(37),
+ REG_A8XX_CP_PROTECT_GLOBAL(38),
+ REG_A8XX_CP_PROTECT_GLOBAL(39),
+ REG_A8XX_CP_PROTECT_GLOBAL(40),
+ REG_A8XX_CP_PROTECT_GLOBAL(41),
+ REG_A8XX_CP_PROTECT_GLOBAL(42),
+ REG_A8XX_CP_PROTECT_GLOBAL(43),
+ REG_A8XX_CP_PROTECT_GLOBAL(44),
+ REG_A8XX_CP_PROTECT_GLOBAL(45),
+ REG_A8XX_CP_PROTECT_GLOBAL(46),
+ REG_A8XX_CP_PROTECT_GLOBAL(47),
+ REG_A8XX_CP_PROTECT_GLOBAL(48),
+ REG_A8XX_CP_PROTECT_GLOBAL(49),
+ REG_A8XX_CP_PROTECT_GLOBAL(50),
+ REG_A8XX_CP_PROTECT_GLOBAL(51),
+ REG_A8XX_CP_PROTECT_GLOBAL(52),
+ REG_A8XX_CP_PROTECT_GLOBAL(53),
+ REG_A8XX_CP_PROTECT_GLOBAL(54),
+ REG_A8XX_CP_PROTECT_GLOBAL(55),
+ REG_A8XX_CP_PROTECT_GLOBAL(56),
+ REG_A8XX_CP_PROTECT_GLOBAL(57),
+ REG_A8XX_CP_PROTECT_GLOBAL(58),
+ REG_A8XX_CP_PROTECT_GLOBAL(59),
+ REG_A8XX_CP_PROTECT_GLOBAL(60),
+ REG_A8XX_CP_PROTECT_GLOBAL(61),
+ REG_A8XX_CP_PROTECT_GLOBAL(62),
+ REG_A8XX_CP_PROTECT_GLOBAL(63),
+};
+DECLARE_ADRENO_REGLIST_LIST(a810_ifpc_reglist);
+
+static const struct adreno_reglist_pipe a810_dyn_pwrup_reglist_regs[] = {
+ { REG_A8XX_CP_PROTECT_CNTL_PIPE, 0, BIT(PIPE_BR) | BIT(PIPE_BV) },
+ { REG_A8XX_CP_PROTECT_PIPE(15), 0, BIT(PIPE_BR) | BIT(PIPE_BV) },
+ { REG_A8XX_GRAS_TSEFE_DBG_ECO_CNTL, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_GRAS_NC_MODE_CNTL, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_GRAS_DBG_ECO_CNTL, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A7XX_RB_CCU_CNTL, 0, BIT(PIPE_BR) },
+ { REG_A8XX_RB_CCU_NC_MODE_CNTL, 0, BIT(PIPE_BR) },
+ { REG_A8XX_RB_CMP_NC_MODE_CNTL, 0, BIT(PIPE_BR) },
+ { REG_A8XX_RB_RESOLVE_PREFETCH_CNTL, 0, BIT(PIPE_BR) },
+ { REG_A8XX_RB_CMP_DBG_ECO_CNTL, 0, BIT(PIPE_BR) },
+ { REG_A8XX_RB_GC_GMEM_PROTECT, 0, BIT(PIPE_BR) },
+ { REG_A6XX_RB_CONTEXT_SWITCH_GMEM_SAVE_RESTORE_ENABLE, 0, BIT(PIPE_BR) },
+ { REG_A8XX_VPC_FLATSHADE_MODE_CNTL, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_PC_CHICKEN_BITS_1, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_PC_CHICKEN_BITS_2, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_PC_CHICKEN_BITS_3, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_PC_CHICKEN_BITS_4, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A6XX_PC_AUTO_VERTEX_STRIDE, 0, BIT(PIPE_BR) | BIT(PIPE_BV) },
+ { REG_A8XX_PC_VIS_STREAM_CNTL, 0, BIT(PIPE_BR) | BIT(PIPE_BV) },
+ { REG_A8XX_PC_CONTEXT_SWITCH_STABILIZE_CNTL_1, 0, BIT(PIPE_BR) | BIT(PIPE_BV) },
+ { REG_A8XX_VFD_CB_BV_THRESHOLD, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_VFD_CB_BR_THRESHOLD, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_VFD_CB_BUSY_REQ_CNT, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_VFD_CB_LP_REQ_CNT, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A7XX_VFD_DBG_ECO_CNTL, 0, BIT(PIPE_BR) | BIT(PIPE_BV) },
+};
+DECLARE_ADRENO_REGLIST_PIPE_LIST(a810_dyn_pwrup_reglist);
+
static const struct adreno_reglist_pipe a840_nonctxt_regs[] = {
{ REG_A8XX_CP_SMMU_STREAM_ID_LPAC, 0x00000101, BIT(PIPE_NONE) },
{ REG_A8XX_GRAS_DBG_ECO_CNTL, 0x00000800, BIT(PIPE_BV) | BIT(PIPE_BR) },
@@ -2193,6 +2446,48 @@ static const struct adreno_info a8xx_gpus[] = {
{ 252, 2 },
{ 221, 3 },
),
+ }, {
+ .chip_ids = ADRENO_CHIP_IDS(0x44010000),
+ .family = ADRENO_8XX_GEN1,
+ .fw = {
+ [ADRENO_FW_SQE] = "gen80300_sqe.fw",
+ [ADRENO_FW_GMU] = "gen80300_gmu.bin",
+ },
+ .gmem = SZ_512K + SZ_64K,
+ .inactive_period = DRM_MSM_INACTIVE_PERIOD,
+ .quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+ ADRENO_QUIRK_HAS_HW_APRIV |
+ ADRENO_QUIRK_PREEMPTION |
+ ADRENO_QUIRK_IFPC,
+ .funcs = &a8xx_gpu_funcs,
+ .zapfw = "gen80300_zap.mbn",
+ .a6xx = &(const struct a6xx_info) {
+ .protect = &a810_protect,
+ .nonctxt_reglist = a810_nonctxt_regs,
+ .pwrup_reglist = &a810_pwrup_reglist,
+ .dyn_pwrup_reglist = &a810_dyn_pwrup_reglist,
+ .ifpc_reglist = &a810_ifpc_reglist,
+ .gbif_cx = a840_gbif,
+ .max_slices = 1,
+ .gmu_chipid = 0x8030000,
+ .bcms = (const struct a6xx_bcm[]) {
+ { .name = "SH0", .buswidth = 16 },
+ { .name = "MC0", .buswidth = 4 },
+ {
+ .name = "ACV",
+ .fixed = true,
+ .perfmode = BIT(2),
+ .perfmode_bw = 10687500,
+ },
+ { /* sentinel */ },
+ },
+ },
+ .preempt_record_size = 4558 * SZ_1K,
+ .speedbins = ADRENO_SPEEDBINS(
+ { 0, 0 },
+ { 242, 1 },
+ { 221, 2 },
+ ),
}
};
@@ -2205,4 +2500,5 @@ static inline __always_unused void __build_asserts(void)
BUILD_BUG_ON(a660_protect.count > a660_protect.count_max);
BUILD_BUG_ON(a690_protect.count > a690_protect.count_max);
BUILD_BUG_ON(a730_protect.count > a730_protect.count_max);
+ BUILD_BUG_ON(a810_protect.count > a810_protect.count_max);
}
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index ec643b84646b..d88eb8ecf417 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -592,6 +592,11 @@ static inline int adreno_is_a8xx(struct adreno_gpu *gpu)
return gpu->info->family >= ADRENO_8XX_GEN1;
}
+static inline int adreno_is_a810(struct adreno_gpu *gpu)
+{
+ return gpu->info->chip_ids[0] == 0x44010000;
+}
+
static inline int adreno_is_x285(struct adreno_gpu *gpu)
{
return gpu->info->chip_ids[0] == 0x44070001;
--
2.53.0
^ permalink raw reply related
* [PATCH RFC v4 7/7] arm64: dts: qcom: milos: Add Adreno 810 GPU and GMU nodes
From: Alexander Koskovich @ 2026-04-16 11:05 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Akhil P Oommen,
Bjorn Andersson
Cc: Luca Weiss, linux-arm-msm, dri-devel, freedreno, devicetree,
linux-kernel, Alexander Koskovich
In-Reply-To: <20260416-adreno-810-v4-0-61676e073f8a@pm.me>
Add GPU and GMU devicetree nodes for the Adreno 810 GPU found on
Qualcomm SM7635 (Milos) based devices.
The qcom,kaanapali-gxclkctl.h header can be reused here because
Milos uses the same driver and the GX_CLKCTL_GX_GDSC definition
is identical.
Signed-off-by: Alexander Koskovich <akoskovich@pm.me>
---
arch/arm64/boot/dts/qcom/milos.dtsi | 166 ++++++++++++++++++++++++++++++++++++
1 file changed, 166 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/milos.dtsi b/arch/arm64/boot/dts/qcom/milos.dtsi
index 0e7cfc12b0d2..4abaef42d7d4 100644
--- a/arch/arm64/boot/dts/qcom/milos.dtsi
+++ b/arch/arm64/boot/dts/qcom/milos.dtsi
@@ -3,6 +3,7 @@
* Copyright (c) 2025, Luca Weiss <luca.weiss@fairphone.com>
*/
+#include <dt-bindings/clock/qcom,kaanapali-gxclkctl.h>
#include <dt-bindings/clock/qcom,milos-camcc.h>
#include <dt-bindings/clock/qcom,milos-dispcc.h>
#include <dt-bindings/clock/qcom,milos-gcc.h>
@@ -1554,6 +1555,171 @@ lpass_ag_noc: interconnect@3c40000 {
qcom,bcm-voters = <&apps_bcm_voter>;
};
+ gpu: gpu@3d00000 {
+ compatible = "qcom,adreno-44010000", "qcom,adreno";
+ reg = <0x0 0x03d00000 0x0 0x40000>,
+ <0x0 0x03d9e000 0x0 0x2000>,
+ <0x0 0x03d61000 0x0 0x800>;
+ reg-names = "kgsl_3d0_reg_memory",
+ "cx_mem",
+ "cx_dbgc";
+
+ interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH 0>;
+
+ iommus = <&adreno_smmu 0 0x0>;
+
+ operating-points-v2 = <&gpu_opp_table>;
+
+ nvmem-cells = <&gpu_speed_bin>;
+ nvmem-cell-names = "speed_bin";
+
+ qcom,gmu = <&gmu>;
+ #cooling-cells = <2>;
+
+ interconnects = <&gem_noc MASTER_GFX3D QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "gfx-mem";
+
+ status = "disabled";
+
+ gpu_zap_shader: zap-shader {
+ memory-region = <&gpu_microcode_mem>;
+ };
+
+ gpu_opp_table: opp-table {
+ compatible = "operating-points-v2-adreno",
+ "operating-points-v2";
+
+ opp-264000000 {
+ opp-hz = /bits/ 64 <264000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;
+ opp-peak-kBps = <2136718>;
+ opp-supported-hw = <0x7>;
+ qcom,opp-acd-level = <0xc8295ffd>;
+ };
+
+ opp-362000000 {
+ opp-hz = /bits/ 64 <362000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+ opp-peak-kBps = <2136718>;
+ opp-supported-hw = <0x7>;
+ qcom,opp-acd-level = <0xc02c5ffd>;
+ };
+
+ opp-510000000 {
+ opp-hz = /bits/ 64 <510000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+ opp-peak-kBps = <3972656>;
+ opp-supported-hw = <0x7>;
+ qcom,opp-acd-level = <0x882b5ffd>;
+ };
+
+ opp-644000000 {
+ opp-hz = /bits/ 64 <644000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+ opp-peak-kBps = <5285156>;
+ opp-supported-hw = <0x7>;
+ qcom,opp-acd-level = <0x882a5ffd>;
+ };
+
+ opp-688000000 {
+ opp-hz = /bits/ 64 <688000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS_L2>;
+ opp-peak-kBps = <6074218>;
+ opp-supported-hw = <0x7>;
+ qcom,opp-acd-level = <0x882a5ffd>;
+ };
+
+ opp-763000000 {
+ opp-hz = /bits/ 64 <763000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
+ opp-peak-kBps = <6671875>;
+ opp-supported-hw = <0x7>;
+ qcom,opp-acd-level = <0xa8295ffd>;
+ };
+
+ opp-895000000 {
+ opp-hz = /bits/ 64 <895000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+ opp-peak-kBps = <8171875>;
+ opp-supported-hw = <0x7>;
+ qcom,opp-acd-level = <0x88295ffd>;
+ };
+
+ opp-960000000 {
+ opp-hz = /bits/ 64 <960000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_TURBO>;
+ opp-peak-kBps = <8171875>;
+ opp-supported-hw = <0x7>;
+ qcom,opp-acd-level = <0xa8285ffd>;
+ };
+
+ opp-1050000000 {
+ opp-hz = /bits/ 64 <1050000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
+ opp-peak-kBps = <18597656>;
+ opp-supported-hw = <0x7>;
+ qcom,opp-acd-level = <0x88285ffd>;
+ };
+
+ opp-1150000000 {
+ opp-hz = /bits/ 64 <1150000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L2>;
+ opp-peak-kBps = <18597656>;
+ opp-supported-hw = <0x3>;
+ qcom,opp-acd-level = <0xa02f5ffd>;
+ };
+ };
+ };
+
+ gmu: gmu@3d37000 {
+ compatible = "qcom,adreno-gmu-810.0", "qcom,adreno-gmu";
+ reg = <0x0 0x03d37000 0x0 0x68000>;
+ reg-names = "gmu";
+
+ interrupts = <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "hfi", "gmu";
+
+ clocks = <&gpucc GPU_CC_AHB_CLK>,
+ <&gpucc GPU_CC_CX_GMU_CLK>,
+ <&gpucc GPU_CC_CXO_CLK>,
+ <&gcc GCC_DDRSS_GPU_AXI_CLK>,
+ <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+ <&gpucc GPU_CC_HUB_CX_INT_CLK>;
+ clock-names = "ahb",
+ "gmu",
+ "cxo",
+ "axi",
+ "memnoc",
+ "hub";
+
+ power-domains = <&gpucc GPU_CC_CX_GDSC>,
+ <&gxclkctl GX_CLKCTL_GX_GDSC>;
+ power-domain-names = "cx",
+ "gx";
+
+ iommus = <&adreno_smmu 5 0x0>;
+
+ qcom,qmp = <&aoss_qmp>;
+
+ operating-points-v2 = <&gmu_opp_table>;
+
+ gmu_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-350000000 {
+ opp-hz = /bits/ 64 <350000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+ };
+
+ opp-650000000 {
+ opp-hz = /bits/ 64 <650000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+ };
+ };
+ };
+
gxclkctl: clock-controller@3d64000 {
compatible = "qcom,milos-gxclkctl";
reg = <0x0 0x03d64000 0x0 0x6000>;
--
2.53.0
^ permalink raw reply related
* [PATCH V13 00/12] pci-imx6: Add support for parsing the reset property in new Root Port binding
From: Sherry Sun @ 2026-04-16 11:14 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
lpieralisi, kwilczynski, mani, bhelgaas, hongxing.zhu, l.stach
Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel
This patch set adds support for parsing the reset property in new Root Port
binding in pci-imx6 driver, similar to the implementation in the qcom pcie
driver[1].
Also introduce generic helper functions to parse Root Port device tree
nodes and extract common properties like reset GPIOs. This allows multiple
PCI host controller drivers to share the same parsing logic.
Define struct pci_host_port to hold common Root Port properties
(currently only reset GPIO descriptor) and add
pci_host_common_parse_ports() to parse Root Port nodes from device tree.
Also add the 'ports' list to struct pci_host_bridge for better maintain
parsed Root Port information.
The plan is to add the wake-gpio property to the root port in subsequent
patches. Also, the vpcie-supply property will be moved to the root port
node later based on the refactoring patch set for the PCI pwrctrl
framework[2].
The initial idea is to adopt the Manivannan’s recent PCIe M.2 KeyE
connector support patch set[3] and PCI power control framework patches[2],
and extend them to the pcie-imx6 driver. Since the new M.2/pwrctrl model is
implemented based on Root Ports and requires the pwrctrl driver to bind to
a Root Port device, we need to introduce a Root Port child node on i.MX
boards that provide an M.2 connector.
To follow a more standardized DT structure, it also makes sense to move
the reset-gpios and wake-gpios properties into the Root Port node. These
signals logically belong to the Root Port rather than the host bridge,
and placing them there aligns with the new M.2/pwrctrl model.
Regarding backward compatibility, as Frank suggested, I will not remove
the old reset-gpio property from existing DTS files to avoid function
break.
For new i.MX platforms — such as the upcoming i.MX952-evk will add
vpcie-supply, reset-gpios, and wake-gpios directly under the Root Port
node.
Therefore, driver updates are needed to support both the legacy
properties and the new standardized Root Port based layout.
[1] https://lore.kernel.org/linux-pci/20250702-perst-v5-0-920b3d1f6ee1@qti.qualcomm.com/
[2] https://lore.kernel.org/linux-pci/20260115-pci-pwrctrl-rework-v5-0-9d26da3ce903@oss.qualcomm.com/
[3] https://lore.kernel.org/linux-pci/20260112-pci-m2-e-v4-0-eff84d2c6d26@oss.qualcomm.com/
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
Changes in V13:
1. Use of_property_present() instead of of_property_read_bool() in patch#2 as
reviewed by sashiko.
2. Add reset Null check in imx_pcie_parse_legacy_binding() to avoid
unconditional deassert delays on boards without reset GPIO as reviewed by
sashiko.
3. Delete the pcie@0,0 port defined in imx6q-utilite-pro.dts and use the new
pcie_port0 label in imx6qdl.dtsi to avoid to defining the conflicting node as
reviewed by sashiko.
Changes in V12:
1. Improve the pci_host_common_parse_port() to correctly handle three scenarios:
PERST# found in Root Port node & PERST# not in Root Port but found in RC node
& PERST# not found in either node.
2. Add documentation noting for pci_host_common_parse_port().
3. Add err_cleanup handle path for pci_host_common_parse_ports() to clean up any
partially parsed Root Port resources.
4. Optimize imx_pcie_assert_perst() to avoid the linearly increasing deassertion
delay if controller has multiple Root Ports.
5. Use mdelay instead of msleep in imx_pcie_assert_perst() for noirq context
safety.
6. Remove early return in imx_pcie_parse_legacy_binding() when reset is NULL to
align with pci_host_common_parse_port(), allowing port creation even without
PERST# GPIO.
Changes in V11:
1. Call pci_host_common_parse_ports() API from pci-imx6 driver instead of dwc
common layer as Mani suggested.
2. Improve the commit message of patch#3 to avoid confusion as Mani suggested.
Changes in V10:
1. Use gpiod_direction_output() instead of gpiod_set_value_cansleep() to
ensure the reset GPIO is properly configured as output before setting
its value in patch#5 as now the reset GPIO is obtained with
GPIOD_ASIS flag.
Changes in V9:
1. Improve the error handling in pci_host_common_parse_ports() as Mani suggested.
2. Move the list_empty check and the comment to imx_pcie_host_init() to make it
clear that imx_pcie_parse_legacy_binding() is a fallback as Mani suggested.
3. Export pci_host_common_delete_ports() so that it can be called by
imx_pcie_parse_legacy_binding().
Changes in V8:
1. Add back the cleanup function pci_host_common_delete_ports() to properly
handles the ports list instead of simply using pci_free_resource_list().
2. Improve the patch#4 commit message.
3. Remove the irrelevant code change in patch#4.
Changes in V7:
1. Change to use GPIOD_ASIS when requesting perst gpio as Mani suggested.
using bridge->dev.
2. Add a seperate patch to move vpcie3v3aux regulator enable from probe to
imx_pcie_host_init() and move imx_pcie_assert_perst() before regulator and
clock enable for pci-imx6.
3. Add device pointer parameter for pci_host_common_parse_port() instead of
Changes in V6:
1. Drop the pre-allocate pci_host_bridge struct changes in dw_pcie_host_init()
and imx_pcie_probe().
2. Parse Root Port nodes in dw_pcie_host_init() as Frank and Mani suggested.
3. Move the imx_pcie_parse_legacy_binding() from imx_pcie_probe() to
imx_pcie_host_init(), so that dw_pcie_host_init() parse Root Port first, if
no Root Port nodes were parsed(indicated by empty ports list), then parse
legacy binding.
4. Add device pointer parameter for pci_host_common_parse_ports().
5. Add NULL pointer check for reset gpio in imx_pcie_parse_legacy_binding().
Changes in V5:
1. Add the Root Port list(pci_host_port) to struct pci_host_bridge for better
maintain parsed Root Port information.
2. Delete the pci_host_common_delete_ports() as now the Root Port list in
pci_host_bridge can be cleared by pci_release_host_bridge_dev().
3. Change the common API pci_host_common_parse_ports() pass down struct
pci_host_bridge *.
4. Modify dw_pcie_host_init() to allow drivers to pre-allocate pci_host_bridge
struct when needed.
5. Allocate bridge early in imx_pcie_probe() to parse Root Ports.
Changes in V4:
1. Add common helpers for parsing Root Port properties in pci-host-common.c in
patch#2.
2. Call common pci_host_common_parse_ports() and pci_host_common_delete_ports()
in pci-imx6 driver.
3. Use PCIE_T_PVPERL_MS and PCIE_RESET_CONFIG_WAIT_MS instead of magic number
100 in patch#3 as Manivannan suggested.
4. Use "PERST#" instead of "PCIe reset" for the reset gpio lable in patch#3.
Changes in V3:
1. Improve the patch#2 commit message as Frank suggested.
2. Add Reviewed-by tag for patch#1.
Changes in V2:
1. Improve the patch#1 commit message as Frank suggested.
2. Also mark the reset-gpio-active-high property as deprecated in
imx6q-pcie DT binding as Rob suggested.
3. The imx_pcie_delete_ports() has been moved up so that the
imx_pcie_parse_ports() can call this helper function in error handling.
4. Keep the old reset-gpio property in the host bridge node for the
existing dts files and add comments to avoid confusion.
---
Sherry Sun (12):
dt-bindings: PCI: fsl,imx6q-pcie: Add reset GPIO in Root Port node
PCI: host-generic: Add common helpers for parsing Root Port properties
PCI: imx6: Assert PERST# before enabling regulators
PCI: imx6: Add support for parsing the reset property in new Root Port
binding
arm: dts: imx6qdl: Add Root Port node and PERST property
arm: dts: imx6sx: Add Root Port node and PERST property
arm: dts: imx7d: Add Root Port node and PERST property
arm64: dts: imx8mm: Add Root Port node and PERST property
arm64: dts: imx8mp: Add Root Port node and PERST property
arm64: dts: imx8mq: Add Root Port node and PERST property
arm64: dts: imx8dxl/qm/qxp: Add Root Port node and PERST property
arm64: dts: imx95: Add Root Port node and PERST property
.../bindings/pci/fsl,imx6q-pcie.yaml | 32 +++++
.../boot/dts/nxp/imx/imx6q-utilite-pro.dts | 17 +--
.../arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi | 5 +
arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi | 11 ++
.../arm/boot/dts/nxp/imx/imx6qp-sabreauto.dts | 5 +
arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi | 5 +
arch/arm/boot/dts/nxp/imx/imx6sx.dtsi | 11 ++
arch/arm/boot/dts/nxp/imx/imx7d-sdb.dts | 5 +
arch/arm/boot/dts/nxp/imx/imx7d.dtsi | 11 ++
.../boot/dts/freescale/imx8-ss-hsio.dtsi | 11 ++
arch/arm64/boot/dts/freescale/imx8dxl-evk.dts | 5 +
arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi | 5 +
arch/arm64/boot/dts/freescale/imx8mm.dtsi | 11 ++
arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 5 +
arch/arm64/boot/dts/freescale/imx8mp.dtsi | 11 ++
arch/arm64/boot/dts/freescale/imx8mq-evk.dts | 10 ++
arch/arm64/boot/dts/freescale/imx8mq.dtsi | 22 ++++
arch/arm64/boot/dts/freescale/imx8qm-mek.dts | 10 ++
.../boot/dts/freescale/imx8qm-ss-hsio.dtsi | 22 ++++
arch/arm64/boot/dts/freescale/imx8qxp-mek.dts | 5 +
.../boot/dts/freescale/imx95-15x15-evk.dts | 5 +
.../boot/dts/freescale/imx95-19x19-evk.dts | 10 ++
arch/arm64/boot/dts/freescale/imx95.dtsi | 22 ++++
drivers/pci/controller/dwc/pci-imx6.c | 120 ++++++++++++++----
drivers/pci/controller/pci-host-common.c | 104 +++++++++++++++
drivers/pci/controller/pci-host-common.h | 16 +++
drivers/pci/probe.c | 1 +
include/linux/pci.h | 1 +
28 files changed, 461 insertions(+), 37 deletions(-)
--
2.37.1
^ permalink raw reply
* [PATCH V13 01/12] dt-bindings: PCI: fsl,imx6q-pcie: Add reset GPIO in Root Port node
From: Sherry Sun @ 2026-04-16 11:14 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
lpieralisi, kwilczynski, mani, bhelgaas, hongxing.zhu, l.stach
Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20260416111422.183860-1-sherry.sun@nxp.com>
Update fsl,imx6q-pcie.yaml to include the standard reset-gpios property
for the Root Port node.
The reset-gpios property is already defined in pci-bus-common.yaml for
PERST#, so use it instead of the local reset-gpio property. Keep the
existing reset-gpio property in the bridge node for backward
compatibility, but mark it as deprecated.
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
---
.../bindings/pci/fsl,imx6q-pcie.yaml | 32 +++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
index 9d1349855b42..e8b8131f5f23 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
@@ -66,16 +66,34 @@ properties:
- const: dma
reset-gpio:
+ deprecated: true
description: Should specify the GPIO for controlling the PCI bus device
reset signal. It's not polarity aware and defaults to active-low reset
sequence (L=reset state, H=operation state) (optional required).
+ This property is deprecated, instead of referencing this property from the
+ host bridge node, use the reset-gpios property from the root port node.
reset-gpio-active-high:
+ deprecated: true
description: If present then the reset sequence using the GPIO
specified in the "reset-gpio" property is reversed (H=reset state,
L=operation state) (optional required).
+ This property is deprecated along with the reset-gpio property above, use
+ the reset-gpios property from the root port node.
type: boolean
+ pcie@0:
+ description:
+ Describe the i.MX6 PCIe Root Port.
+ type: object
+ $ref: /schemas/pci/pci-pci-bridge.yaml#
+
+ properties:
+ reg:
+ maxItems: 1
+
+ unevaluatedProperties: false
+
required:
- compatible
- reg
@@ -236,6 +254,7 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/imx6qdl-clock.h>
+ #include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
pcie: pcie@1ffc000 {
@@ -262,5 +281,18 @@ examples:
<&clks IMX6QDL_CLK_LVDS1_GATE>,
<&clks IMX6QDL_CLK_PCIE_REF_125M>;
clock-names = "pcie", "pcie_bus", "pcie_phy";
+
+ pcie_port0: pcie@0 {
+ compatible = "pciclass,0604";
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+
+ reset-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>;
+ };
};
...
--
2.37.1
^ permalink raw reply related
* [PATCH V13 02/12] PCI: host-generic: Add common helpers for parsing Root Port properties
From: Sherry Sun @ 2026-04-16 11:14 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
lpieralisi, kwilczynski, mani, bhelgaas, hongxing.zhu, l.stach
Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20260416111422.183860-1-sherry.sun@nxp.com>
Introduce generic helper functions to parse Root Port device tree nodes
and extract common properties like reset GPIOs. This allows multiple
PCI host controller drivers to share the same parsing logic.
Define struct pci_host_port to hold common Root Port properties
(currently only reset GPIO descriptor) and add
pci_host_common_parse_ports() to parse Root Port nodes from device tree.
Also add the 'ports' list to struct pci_host_bridge for better maintain
parsed Root Port information.
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
drivers/pci/controller/pci-host-common.c | 104 +++++++++++++++++++++++
drivers/pci/controller/pci-host-common.h | 16 ++++
drivers/pci/probe.c | 1 +
include/linux/pci.h | 1 +
4 files changed, 122 insertions(+)
diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c
index d6258c1cffe5..cb6cd00dc0be 100644
--- a/drivers/pci/controller/pci-host-common.c
+++ b/drivers/pci/controller/pci-host-common.c
@@ -9,6 +9,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/gpio/consumer.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_pci.h>
@@ -17,6 +18,109 @@
#include "pci-host-common.h"
+/**
+ * pci_host_common_delete_ports - Cleanup function for port list
+ * @data: Pointer to the port list head
+ */
+void pci_host_common_delete_ports(void *data)
+{
+ struct list_head *ports = data;
+ struct pci_host_port *port, *tmp;
+
+ list_for_each_entry_safe(port, tmp, ports, list)
+ list_del(&port->list);
+}
+EXPORT_SYMBOL_GPL(pci_host_common_delete_ports);
+
+/**
+ * pci_host_common_parse_port - Parse a single Root Port node
+ * @dev: Device pointer
+ * @bridge: PCI host bridge
+ * @node: Device tree node of the Root Port
+ *
+ * This function parses Root Port properties from the device tree.
+ * Currently it only handles the PERST# GPIO which is optional.
+ *
+ * NOTE: This helper fetches resources (like PERST# GPIO) optionally.
+ * If a controller driver has a hard dependency on certain resources(PHY,
+ * clocks, regulators, etc.), those resources MUST be modeled correctly
+ * in the DT binding and validated in DTS. This helper cannot enforce such
+ * dependencies and the driver may fail to operate if required resources
+ * are missing.
+ *
+ * Returns: 0 on success, -ENOENT if PERST# found in RC node (legacy binding
+ * should be used), Other negative error codes on failure.
+ */
+static int pci_host_common_parse_port(struct device *dev,
+ struct pci_host_bridge *bridge,
+ struct device_node *node)
+{
+ struct pci_host_port *port;
+ struct gpio_desc *reset;
+
+ /* Check if PERST# is present in Root Port node */
+ reset = devm_fwnode_gpiod_get(dev, of_fwnode_handle(node),
+ "reset", GPIOD_ASIS, "PERST#");
+ if (IS_ERR(reset)) {
+ /* If error is not -ENOENT, it's a real error */
+ if (PTR_ERR(reset) != -ENOENT)
+ return PTR_ERR(reset);
+
+ /* PERST# not found in Root Port node, check RC node */
+ if (of_property_present(dev->of_node, "reset-gpios") ||
+ of_property_present(dev->of_node, "reset-gpio"))
+ return -ENOENT;
+
+ /* No PERST# in either node, assume not present in design */
+ reset = NULL;
+ }
+
+ port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
+ if (!port)
+ return -ENOMEM;
+
+ port->reset = reset;
+ INIT_LIST_HEAD(&port->list);
+ list_add_tail(&port->list, &bridge->ports);
+
+ return 0;
+}
+
+/**
+ * pci_host_common_parse_ports - Parse Root Port nodes from device tree
+ * @dev: Device pointer
+ * @bridge: PCI host bridge
+ *
+ * This function iterates through child nodes of the host bridge and parses
+ * Root Port properties (currently only reset GPIO).
+ *
+ * Returns: 0 on success, -ENOENT if no ports found or PERST# found in RC node
+ * (legacy binding should be used), Other negative error codes on failure.
+ */
+int pci_host_common_parse_ports(struct device *dev, struct pci_host_bridge *bridge)
+{
+ int ret = -ENOENT;
+
+ for_each_available_child_of_node_scoped(dev->of_node, of_port) {
+ if (!of_node_is_type(of_port, "pci"))
+ continue;
+ ret = pci_host_common_parse_port(dev, bridge, of_port);
+ if (ret)
+ goto err_cleanup;
+ }
+
+ if (ret)
+ return ret;
+
+ return devm_add_action_or_reset(dev, pci_host_common_delete_ports,
+ &bridge->ports);
+
+err_cleanup:
+ pci_host_common_delete_ports(&bridge->ports);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(pci_host_common_parse_ports);
+
static void gen_pci_unmap_cfg(void *ptr)
{
pci_ecam_free((struct pci_config_window *)ptr);
diff --git a/drivers/pci/controller/pci-host-common.h b/drivers/pci/controller/pci-host-common.h
index b5075d4bd7eb..37714bedb625 100644
--- a/drivers/pci/controller/pci-host-common.h
+++ b/drivers/pci/controller/pci-host-common.h
@@ -12,6 +12,22 @@
struct pci_ecam_ops;
+/**
+ * struct pci_host_port - Generic Root Port properties
+ * @list: List node for linking multiple ports
+ * @reset: GPIO descriptor for PERST# signal
+ *
+ * This structure contains common properties that can be parsed from
+ * Root Port device tree nodes.
+ */
+struct pci_host_port {
+ struct list_head list;
+ struct gpio_desc *reset;
+};
+
+void pci_host_common_delete_ports(void *data);
+int pci_host_common_parse_ports(struct device *dev, struct pci_host_bridge *bridge);
+
int pci_host_common_probe(struct platform_device *pdev);
int pci_host_common_init(struct platform_device *pdev,
struct pci_host_bridge *bridge,
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index b63cd0c310bc..6094b6c1fc90 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -660,6 +660,7 @@ static void pci_init_host_bridge(struct pci_host_bridge *bridge)
{
INIT_LIST_HEAD(&bridge->windows);
INIT_LIST_HEAD(&bridge->dma_ranges);
+ INIT_LIST_HEAD(&bridge->ports);
/*
* We assume we can manage these PCIe features. Some systems may
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 2c4454583c11..cb5f3e7e8e48 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -636,6 +636,7 @@ struct pci_host_bridge {
int domain_nr;
struct list_head windows; /* resource_entry */
struct list_head dma_ranges; /* dma ranges resource list */
+ struct list_head ports; /* Root Port list (pci_host_port) */
#ifdef CONFIG_PCI_IDE
u16 nr_ide_streams; /* Max streams possibly active in @ide_stream_ida */
struct ida ide_stream_ida;
--
2.37.1
^ permalink raw reply related
* [PATCH V13 03/12] PCI: imx6: Assert PERST# before enabling regulators
From: Sherry Sun @ 2026-04-16 11:14 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
lpieralisi, kwilczynski, mani, bhelgaas, hongxing.zhu, l.stach
Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20260416111422.183860-1-sherry.sun@nxp.com>
The PCIe endpoint may start responding or driving signals as soon as
its supply is enabled, even before the reference clock is stable.
Asserting PERST# before enabling the regulator ensures that the
endpoint remains in reset throughout the entire power-up sequence,
until both power and refclk are known to be stable and link
initialization can safely begin.
Currently, the driver enables the vpcie3v3aux regulator in
imx_pcie_probe() before PERST# is asserted in imx_pcie_host_init(),
which may cause PCIe endpoint undefined behavior during early
power-up. However, there is no issue so far because PERST# is
requested as GPIOD_OUT_HIGH in imx_pcie_probe(), which guarantees
that PERST# is asserted before enabling the vpcie3v3aux regulator.
This is prepare for the upcoming changes that will parse the reset
property using the new Root Port binding, which will use GPIOD_ASIS
when requesting the reset GPIO. With GPIOD_ASIS, the GPIO state is not
guaranteed, so explicit sequencing is required.
Fix the power sequencing by:
1. Moving vpcie3v3aux regulator enable from probe to
imx_pcie_host_init(), where it can be properly sequenced with PERST#.
2. Moving imx_pcie_assert_perst() before regulator and clock enable to
ensure correct ordering.
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
drivers/pci/controller/dwc/pci-imx6.c | 49 +++++++++++++++++++++------
1 file changed, 39 insertions(+), 10 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index e35044cc5218..735127ed1455 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -168,6 +168,8 @@ struct imx_pcie {
u32 tx_swing_full;
u32 tx_swing_low;
struct regulator *vpcie;
+ struct regulator *vpcie_aux;
+ bool vpcie_aux_enabled;
struct regulator *vph;
void __iomem *phy_base;
@@ -1222,6 +1224,13 @@ static void imx_pcie_disable_device(struct pci_host_bridge *bridge,
imx_pcie_remove_lut(imx_pcie, pci_dev_id(pdev));
}
+static void imx_pcie_vpcie_aux_disable(void *data)
+{
+ struct regulator *vpcie_aux = data;
+
+ regulator_disable(vpcie_aux);
+}
+
static void imx_pcie_assert_perst(struct imx_pcie *imx_pcie, bool assert)
{
if (assert) {
@@ -1242,6 +1251,24 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
struct imx_pcie *imx_pcie = to_imx_pcie(pci);
int ret;
+ imx_pcie_assert_perst(imx_pcie, true);
+
+ /* Keep 3.3Vaux supply enabled for the entire PCIe controller lifecycle */
+ if (imx_pcie->vpcie_aux && !imx_pcie->vpcie_aux_enabled) {
+ ret = regulator_enable(imx_pcie->vpcie_aux);
+ if (ret) {
+ dev_err(dev, "failed to enable vpcie_aux regulator: %d\n",
+ ret);
+ return ret;
+ }
+ imx_pcie->vpcie_aux_enabled = true;
+
+ ret = devm_add_action_or_reset(dev, imx_pcie_vpcie_aux_disable,
+ imx_pcie->vpcie_aux);
+ if (ret)
+ return ret;
+ }
+
if (imx_pcie->vpcie) {
ret = regulator_enable(imx_pcie->vpcie);
if (ret) {
@@ -1251,25 +1278,24 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
}
}
+ ret = imx_pcie_clk_enable(imx_pcie);
+ if (ret) {
+ dev_err(dev, "unable to enable pcie clocks: %d\n", ret);
+ goto err_reg_disable;
+ }
+
if (pp->bridge && imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_LUT)) {
pp->bridge->enable_device = imx_pcie_enable_device;
pp->bridge->disable_device = imx_pcie_disable_device;
}
imx_pcie_assert_core_reset(imx_pcie);
- imx_pcie_assert_perst(imx_pcie, true);
if (imx_pcie->drvdata->init_phy)
imx_pcie->drvdata->init_phy(imx_pcie);
imx_pcie_configure_type(imx_pcie);
- ret = imx_pcie_clk_enable(imx_pcie);
- if (ret) {
- dev_err(dev, "unable to enable pcie clocks: %d\n", ret);
- goto err_reg_disable;
- }
-
if (imx_pcie->phy) {
ret = phy_init(imx_pcie->phy);
if (ret) {
@@ -1782,9 +1808,12 @@ static int imx_pcie_probe(struct platform_device *pdev)
of_property_read_u32(node, "fsl,max-link-speed", &pci->max_link_speed);
imx_pcie->supports_clkreq = of_property_read_bool(node, "supports-clkreq");
- ret = devm_regulator_get_enable_optional(&pdev->dev, "vpcie3v3aux");
- if (ret < 0 && ret != -ENODEV)
- return dev_err_probe(dev, ret, "failed to enable Vaux supply\n");
+ imx_pcie->vpcie_aux = devm_regulator_get_optional(&pdev->dev, "vpcie3v3aux");
+ if (IS_ERR(imx_pcie->vpcie_aux)) {
+ if (PTR_ERR(imx_pcie->vpcie_aux) != -ENODEV)
+ return PTR_ERR(imx_pcie->vpcie_aux);
+ imx_pcie->vpcie_aux = NULL;
+ }
imx_pcie->vpcie = devm_regulator_get_optional(&pdev->dev, "vpcie");
if (IS_ERR(imx_pcie->vpcie)) {
--
2.37.1
^ permalink raw reply related
* [PATCH V13 04/12] PCI: imx6: Add support for parsing the reset property in new Root Port binding
From: Sherry Sun @ 2026-04-16 11:14 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
lpieralisi, kwilczynski, mani, bhelgaas, hongxing.zhu, l.stach
Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20260416111422.183860-1-sherry.sun@nxp.com>
The current DT binding for pci-imx6 specifies the 'reset-gpios' property
in the host bridge node. However, the PERST# signal logically belongs to
individual Root Ports rather than the host bridge itself. This becomes
important when supporting PCIe KeyE connector and PCI power control
framework for pci-imx6 driver, which requires properties to be specified
in Root Port nodes.
Add support for parsing 'reset-gpios' from Root Port child nodes using
the common helper pci_host_common_parse_ports(), and update the reset
GPIO handling to use the parsed port list from bridge->ports. To
maintain DT backwards compatibility, fallback to the legacy method of
parsing the host bridge node if the reset property is not present in the
Root Port node.
Since now the reset GPIO is obtained with GPIOD_ASIS flag, it may be in
input mode, using gpiod_direction_output() instead of
gpiod_set_value_cansleep() to ensure the reset GPIO is properly
configured as output before setting its value.
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
drivers/pci/controller/dwc/pci-imx6.c | 71 +++++++++++++++++++++------
1 file changed, 57 insertions(+), 14 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 735127ed1455..ec0b1690a41e 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -34,6 +34,7 @@
#include <linux/pm_runtime.h>
#include "../../pci.h"
+#include "../pci-host-common.h"
#include "pcie-designware.h"
#define IMX8MQ_GPR_PCIE_REF_USE_PAD BIT(9)
@@ -152,7 +153,6 @@ struct imx_lut_data {
struct imx_pcie {
struct dw_pcie *pci;
- struct gpio_desc *reset_gpiod;
struct clk_bulk_data *clks;
int num_clks;
bool supports_clkreq;
@@ -1224,6 +1224,32 @@ static void imx_pcie_disable_device(struct pci_host_bridge *bridge,
imx_pcie_remove_lut(imx_pcie, pci_dev_id(pdev));
}
+static int imx_pcie_parse_legacy_binding(struct imx_pcie *pcie)
+{
+ struct device *dev = pcie->pci->dev;
+ struct pci_host_bridge *bridge = pcie->pci->pp.bridge;
+ struct pci_host_port *port;
+ struct gpio_desc *reset;
+
+ reset = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS);
+ if (IS_ERR(reset))
+ return PTR_ERR(reset);
+
+ if (!reset)
+ return 0;
+
+ port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
+ if (!port)
+ return -ENOMEM;
+
+ port->reset = reset;
+ INIT_LIST_HEAD(&port->list);
+ list_add_tail(&port->list, &bridge->ports);
+
+ return devm_add_action_or_reset(dev, pci_host_common_delete_ports,
+ &bridge->ports);
+}
+
static void imx_pcie_vpcie_aux_disable(void *data)
{
struct regulator *vpcie_aux = data;
@@ -1233,14 +1259,21 @@ static void imx_pcie_vpcie_aux_disable(void *data)
static void imx_pcie_assert_perst(struct imx_pcie *imx_pcie, bool assert)
{
+ struct dw_pcie *pci = imx_pcie->pci;
+ struct pci_host_bridge *bridge = pci->pp.bridge;
+ struct pci_host_port *port;
+
+ if (!bridge || list_empty(&bridge->ports))
+ return;
+
if (assert) {
- gpiod_set_value_cansleep(imx_pcie->reset_gpiod, 1);
+ list_for_each_entry(port, &bridge->ports, list)
+ gpiod_direction_output(port->reset, 1);
} else {
- if (imx_pcie->reset_gpiod) {
- msleep(PCIE_T_PVPERL_MS);
- gpiod_set_value_cansleep(imx_pcie->reset_gpiod, 0);
- msleep(PCIE_RESET_CONFIG_WAIT_MS);
- }
+ mdelay(PCIE_T_PVPERL_MS);
+ list_for_each_entry(port, &bridge->ports, list)
+ gpiod_direction_output(port->reset, 0);
+ mdelay(PCIE_RESET_CONFIG_WAIT_MS);
}
}
@@ -1249,8 +1282,25 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct device *dev = pci->dev;
struct imx_pcie *imx_pcie = to_imx_pcie(pci);
+ struct pci_host_bridge *bridge = pp->bridge;
int ret;
+ if (bridge && list_empty(&bridge->ports)) {
+ /* Parse Root Port nodes if present */
+ ret = pci_host_common_parse_ports(dev, bridge);
+ if (ret) {
+ if (ret != -ENOENT) {
+ dev_err(dev, "Failed to parse Root Port nodes: %d\n", ret);
+ return ret;
+ }
+
+ /* Fallback to legacy binding for DT backwards compatibility */
+ ret = imx_pcie_parse_legacy_binding(imx_pcie);
+ if (ret)
+ return ret;
+ }
+ }
+
imx_pcie_assert_perst(imx_pcie, true);
/* Keep 3.3Vaux supply enabled for the entire PCIe controller lifecycle */
@@ -1704,13 +1754,6 @@ static int imx_pcie_probe(struct platform_device *pdev)
return PTR_ERR(imx_pcie->phy_base);
}
- /* Fetch GPIOs */
- imx_pcie->reset_gpiod = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
- if (IS_ERR(imx_pcie->reset_gpiod))
- return dev_err_probe(dev, PTR_ERR(imx_pcie->reset_gpiod),
- "unable to get reset gpio\n");
- gpiod_set_consumer_name(imx_pcie->reset_gpiod, "PCIe reset");
-
/* Fetch clocks */
imx_pcie->num_clks = devm_clk_bulk_get_all(dev, &imx_pcie->clks);
if (imx_pcie->num_clks < 0)
--
2.37.1
^ permalink raw reply related
* [PATCH V13 05/12] arm: dts: imx6qdl: Add Root Port node and PERST property
From: Sherry Sun @ 2026-04-16 11:14 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
lpieralisi, kwilczynski, mani, bhelgaas, hongxing.zhu, l.stach
Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20260416111422.183860-1-sherry.sun@nxp.com>
Since describing the PCIe PERST# property under Host Bridge node is now
deprecated, it is recommended to add it to the Root Port node, so
creating the Root Port node and add the reset-gpios property in Root
Port.
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
arch/arm/boot/dts/nxp/imx/imx6q-utilite-pro.dts | 17 ++++-------------
arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi | 5 +++++
arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi | 11 +++++++++++
arch/arm/boot/dts/nxp/imx/imx6qp-sabreauto.dts | 5 +++++
4 files changed, 25 insertions(+), 13 deletions(-)
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-utilite-pro.dts b/arch/arm/boot/dts/nxp/imx/imx6q-utilite-pro.dts
index c78f101c3cc1..2ddd71f09da3 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6q-utilite-pro.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6q-utilite-pro.dts
@@ -323,19 +323,10 @@ &ipu1_di0_disp0 {
remote-endpoint = <¶llel_display_in>;
};
-&pcie {
- pcie@0,0 {
- reg = <0x000000 0 0 0 0>;
- device_type = "pci";
- #address-cells = <3>;
- #size-cells = <2>;
- bus-range = <0x00 0xff>;
- ranges;
-
- /* non-removable i211 ethernet card */
- eth1: ethernet@0,0 {
- reg = <0x010000 0 0 0 0>;
- };
+&pcie_port0 {
+ /* non-removable i211 ethernet card */
+ eth1: ethernet@0,0 {
+ reg = <0x010000 0 0 0 0>;
};
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi
index ba29720e3f72..fe9046c03ddd 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi
@@ -754,11 +754,16 @@ lvds0_out: endpoint {
&pcie {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pcie>;
+ /* This property is deprecated, use reset-gpios from the Root Port node. */
reset-gpio = <&gpio7 12 GPIO_ACTIVE_LOW>;
vpcie-supply = <®_pcie>;
status = "okay";
};
+&pcie_port0 {
+ reset-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>;
+};
+
&pwm1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
index 4dc2c410cf61..9438862b9927 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
@@ -302,6 +302,17 @@ pcie: pcie@1ffc000 {
<&clks IMX6QDL_CLK_PCIE_REF_125M>;
clock-names = "pcie", "pcie_bus", "pcie_phy";
status = "disabled";
+
+ pcie_port0: pcie@0 {
+ compatible = "pciclass,0604";
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
aips1: bus@2000000 { /* AIPS1 */
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qp-sabreauto.dts b/arch/arm/boot/dts/nxp/imx/imx6qp-sabreauto.dts
index c5b220aeaefd..6b12cab7175f 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qp-sabreauto.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6qp-sabreauto.dts
@@ -45,10 +45,15 @@ MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
};
&pcie {
+ /* This property is deprecated, use reset-gpios from the Root Port node. */
reset-gpio = <&max7310_c 5 GPIO_ACTIVE_LOW>;
status = "okay";
};
+&pcie_port0 {
+ reset-gpios = <&max7310_c 5 GPIO_ACTIVE_LOW>;
+};
+
&sata {
status = "okay";
};
--
2.37.1
^ permalink raw reply related
* [PATCH V13 06/12] arm: dts: imx6sx: Add Root Port node and PERST property
From: Sherry Sun @ 2026-04-16 11:14 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
lpieralisi, kwilczynski, mani, bhelgaas, hongxing.zhu, l.stach
Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20260416111422.183860-1-sherry.sun@nxp.com>
Since describing the PCIe PERST# property under Host Bridge node is now
deprecated, it is recommended to add it to the Root Port node, so
creating the Root Port node and add the reset-gpios property in Root
Port.
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi | 5 +++++
arch/arm/boot/dts/nxp/imx/imx6sx.dtsi | 11 +++++++++++
2 files changed, 16 insertions(+)
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi b/arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi
index 3e238d8118fa..338de4d144b2 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi
@@ -282,11 +282,16 @@ codec: wm8962@1a {
&pcie {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pcie>;
+ /* This property is deprecated, use reset-gpios from the Root Port node. */
reset-gpio = <&gpio2 0 GPIO_ACTIVE_LOW>;
vpcie-supply = <®_pcie_gpio>;
status = "okay";
};
+&pcie_port0 {
+ reset-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+};
+
&lcdif1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lcd>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi b/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
index aefae5a3a6be..5484c398aa37 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
@@ -1470,6 +1470,17 @@ pcie: pcie@8ffc000 {
power-domains = <&pd_disp>, <&pd_pci>;
power-domain-names = "pcie", "pcie_phy";
status = "disabled";
+
+ pcie_port0: pcie@0 {
+ compatible = "pciclass,0604";
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
};
};
--
2.37.1
^ permalink raw reply related
* [PATCH V13 07/12] arm: dts: imx7d: Add Root Port node and PERST property
From: Sherry Sun @ 2026-04-16 11:14 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
lpieralisi, kwilczynski, mani, bhelgaas, hongxing.zhu, l.stach
Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20260416111422.183860-1-sherry.sun@nxp.com>
Since describing the PCIe PERST# property under Host Bridge node is now
deprecated, it is recommended to add it to the Root Port node, so
creating the Root Port node and add the reset-gpios property in Root
Port.
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
arch/arm/boot/dts/nxp/imx/imx7d-sdb.dts | 5 +++++
arch/arm/boot/dts/nxp/imx/imx7d.dtsi | 11 +++++++++++
2 files changed, 16 insertions(+)
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-sdb.dts b/arch/arm/boot/dts/nxp/imx/imx7d-sdb.dts
index a370e868cafe..0046b276b8b9 100644
--- a/arch/arm/boot/dts/nxp/imx/imx7d-sdb.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx7d-sdb.dts
@@ -456,10 +456,15 @@ display_out: endpoint {
};
&pcie {
+ /* This property is deprecated, use reset-gpios from the Root Port node. */
reset-gpio = <&extended_io 1 GPIO_ACTIVE_LOW>;
status = "okay";
};
+&pcie_port0 {
+ reset-gpios = <&extended_io 1 GPIO_ACTIVE_LOW>;
+};
+
®_1p0d {
vin-supply = <&sw2_reg>;
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d.dtsi b/arch/arm/boot/dts/nxp/imx/imx7d.dtsi
index d961c61a93af..3c5c1f2c1460 100644
--- a/arch/arm/boot/dts/nxp/imx/imx7d.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx7d.dtsi
@@ -155,6 +155,17 @@ pcie: pcie@33800000 {
reset-names = "pciephy", "apps", "turnoff";
fsl,imx7d-pcie-phy = <&pcie_phy>;
status = "disabled";
+
+ pcie_port0: pcie@0 {
+ compatible = "pciclass,0604";
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
};
};
--
2.37.1
^ permalink raw reply related
* [PATCH V13 08/12] arm64: dts: imx8mm: Add Root Port node and PERST property
From: Sherry Sun @ 2026-04-16 11:14 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
lpieralisi, kwilczynski, mani, bhelgaas, hongxing.zhu, l.stach
Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20260416111422.183860-1-sherry.sun@nxp.com>
Since describing the PCIe PERST# property under Host Bridge node is now
deprecated, it is recommended to add it to the Root Port node, so
creating the Root Port node and add the reset-gpios property in Root
Port.
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi | 5 +++++
arch/arm64/boot/dts/freescale/imx8mm.dtsi | 11 +++++++++++
2 files changed, 16 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
index 8be44eaf4e1e..e03aba825c18 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
@@ -533,6 +533,7 @@ &pcie_phy {
&pcie0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pcie0>;
+ /* This property is deprecated, use reset-gpios from the Root Port node. */
reset-gpio = <&gpio4 21 GPIO_ACTIVE_LOW>;
clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&pcie0_refclk>,
<&clk IMX8MM_CLK_PCIE1_AUX>;
@@ -559,6 +560,10 @@ &pcie0_ep {
status = "disabled";
};
+&pcie0_port0 {
+ reset-gpios = <&gpio4 21 GPIO_ACTIVE_LOW>;
+};
+
&sai2 {
#sound-dai-cells = <0>;
pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
index 4cc5ad01d0e2..5cf2998d396d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
@@ -1370,6 +1370,17 @@ pcie0: pcie@33800000 {
phys = <&pcie_phy>;
phy-names = "pcie-phy";
status = "disabled";
+
+ pcie0_port0: pcie@0 {
+ compatible = "pciclass,0604";
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie0_ep: pcie-ep@33800000 {
--
2.37.1
^ permalink raw reply related
* [PATCH V13 09/12] arm64: dts: imx8mp: Add Root Port node and PERST property
From: Sherry Sun @ 2026-04-16 11:14 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
lpieralisi, kwilczynski, mani, bhelgaas, hongxing.zhu, l.stach
Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20260416111422.183860-1-sherry.sun@nxp.com>
Since describing the PCIe PERST# property under Host Bridge node is now
deprecated, it is recommended to add it to the Root Port node, so
creating the Root Port node and add the reset-gpios property in Root
Port.
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 5 +++++
arch/arm64/boot/dts/freescale/imx8mp.dtsi | 11 +++++++++++
2 files changed, 16 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
index 2feb5b18645c..a7f3acdc36d1 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
@@ -770,6 +770,7 @@ &pcie_phy {
&pcie0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pcie0>;
+ /* This property is deprecated, use reset-gpios from the Root Port node. */
reset-gpio = <&gpio2 7 GPIO_ACTIVE_LOW>;
vpcie-supply = <®_pcie0>;
vpcie3v3aux-supply = <®_pcie0>;
@@ -783,6 +784,10 @@ &pcie0_ep {
status = "disabled";
};
+&pcie0_port0 {
+ reset-gpios = <&gpio2 7 GPIO_ACTIVE_LOW>;
+};
+
&pwm1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 90d7bb8f5619..5ce2825182fd 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -2265,6 +2265,17 @@ pcie0: pcie: pcie@33800000 {
phys = <&pcie_phy>;
phy-names = "pcie-phy";
status = "disabled";
+
+ pcie0_port0: pcie@0 {
+ compatible = "pciclass,0604";
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie0_ep: pcie_ep: pcie-ep@33800000 {
--
2.37.1
^ permalink raw reply related
* [PATCH V13 10/12] arm64: dts: imx8mq: Add Root Port node and PERST property
From: Sherry Sun @ 2026-04-16 11:14 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
lpieralisi, kwilczynski, mani, bhelgaas, hongxing.zhu, l.stach
Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20260416111422.183860-1-sherry.sun@nxp.com>
Since describing the PCIe PERST# property under Host Bridge node is now
deprecated, it is recommended to add it to the Root Port node, so
creating the Root Port node and add the reset-gpios property in Root
Port.
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
arch/arm64/boot/dts/freescale/imx8mq-evk.dts | 10 +++++++++
arch/arm64/boot/dts/freescale/imx8mq.dtsi | 22 ++++++++++++++++++++
2 files changed, 32 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
index d48f901487d4..e7d87ea81b69 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
@@ -369,6 +369,7 @@ mipi_dsi_out: endpoint {
&pcie0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pcie0>;
+ /* This property is deprecated, use reset-gpios from the Root Port node. */
reset-gpio = <&gpio5 28 GPIO_ACTIVE_LOW>;
clocks = <&clk IMX8MQ_CLK_PCIE1_ROOT>,
<&pcie0_refclk>,
@@ -389,9 +390,14 @@ &pcie0_ep {
status = "disabled";
};
+&pcie0_port0 {
+ reset-gpios = <&gpio5 28 GPIO_ACTIVE_LOW>;
+};
+
&pcie1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pcie1>;
+ /* This property is deprecated, use reset-gpios from the Root Port node. */
reset-gpio = <&gpio5 12 GPIO_ACTIVE_LOW>;
clocks = <&clk IMX8MQ_CLK_PCIE2_ROOT>,
<&pcie0_refclk>,
@@ -414,6 +420,10 @@ &pcie1_ep {
status = "disabled";
};
+&pcie1_port0 {
+ reset-gpios = <&gpio5 12 GPIO_ACTIVE_LOW>;
+};
+
&pgc_gpu {
power-supply = <&sw1a_reg>;
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index 6a25e219832c..e60872aeeb49 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -1768,6 +1768,17 @@ pcie0: pcie@33800000 {
assigned-clock-rates = <250000000>, <100000000>,
<10000000>;
status = "disabled";
+
+ pcie0_port0: pcie@0 {
+ compatible = "pciclass,0604";
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie0_ep: pcie-ep@33800000 {
@@ -1846,6 +1857,17 @@ pcie1: pcie@33c00000 {
assigned-clock-rates = <250000000>, <100000000>,
<10000000>;
status = "disabled";
+
+ pcie1_port0: pcie@0 {
+ compatible = "pciclass,0604";
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie1_ep: pcie-ep@33c00000 {
--
2.37.1
^ permalink raw reply related
* [PATCH V13 11/12] arm64: dts: imx8dxl/qm/qxp: Add Root Port node and PERST property
From: Sherry Sun @ 2026-04-16 11:14 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
lpieralisi, kwilczynski, mani, bhelgaas, hongxing.zhu, l.stach
Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20260416111422.183860-1-sherry.sun@nxp.com>
Since describing the PCIe PERST# property under Host Bridge node is now
deprecated, it is recommended to add it to the Root Port node, so
creating the Root Port node and add the reset-gpios property in Root
Port.
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
.../boot/dts/freescale/imx8-ss-hsio.dtsi | 11 ++++++++++
arch/arm64/boot/dts/freescale/imx8dxl-evk.dts | 5 +++++
arch/arm64/boot/dts/freescale/imx8qm-mek.dts | 10 +++++++++
.../boot/dts/freescale/imx8qm-ss-hsio.dtsi | 22 +++++++++++++++++++
arch/arm64/boot/dts/freescale/imx8qxp-mek.dts | 5 +++++
5 files changed, 53 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-hsio.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-hsio.dtsi
index 469de8b536b5..009990b2e559 100644
--- a/arch/arm64/boot/dts/freescale/imx8-ss-hsio.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-hsio.dtsi
@@ -78,6 +78,17 @@ pcieb: pcie@5f010000 {
power-domains = <&pd IMX_SC_R_PCIE_B>;
fsl,max-link-speed = <3>;
status = "disabled";
+
+ pcieb_port0: pcie@0 {
+ compatible = "pciclass,0604";
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcieb_ep: pcie-ep@5f010000 {
diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts b/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
index bc62ae5ca812..39108a915f96 100644
--- a/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
@@ -675,6 +675,7 @@ &pcie0 {
phy-names = "pcie-phy";
pinctrl-0 = <&pinctrl_pcieb>;
pinctrl-names = "default";
+ /* This property is deprecated, use reset-gpios from the Root Port node. */
reset-gpio = <&lsio_gpio4 0 GPIO_ACTIVE_LOW>;
vpcie-supply = <®_pcieb>;
vpcie3v3aux-supply = <®_pcieb>;
@@ -691,6 +692,10 @@ &pcie0_ep {
status = "disabled";
};
+&pcieb_port0 {
+ reset-gpios = <&lsio_gpio4 0 GPIO_ACTIVE_LOW>;
+};
+
&sai0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai0>;
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
index 011a89d85961..f706c86137c0 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
@@ -810,6 +810,7 @@ &pciea {
phy-names = "pcie-phy";
pinctrl-0 = <&pinctrl_pciea>;
pinctrl-names = "default";
+ /* This property is deprecated, use reset-gpios from the Root Port node. */
reset-gpio = <&lsio_gpio4 29 GPIO_ACTIVE_LOW>;
vpcie-supply = <®_pciea>;
vpcie3v3aux-supply = <®_pciea>;
@@ -817,15 +818,24 @@ &pciea {
status = "okay";
};
+&pciea_port0 {
+ reset-gpios = <&lsio_gpio4 29 GPIO_ACTIVE_LOW>;
+};
+
&pcieb {
phys = <&hsio_phy 1 PHY_TYPE_PCIE 1>;
phy-names = "pcie-phy";
pinctrl-0 = <&pinctrl_pcieb>;
pinctrl-names = "default";
+ /* This property is deprecated, use reset-gpios from the Root Port node. */
reset-gpio = <&lsio_gpio5 0 GPIO_ACTIVE_LOW>;
status = "disabled";
};
+&pcieb_port0 {
+ reset-gpios = <&lsio_gpio5 0 GPIO_ACTIVE_LOW>;
+};
+
&qm_pwm_lvds0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm_lvds0>;
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-ss-hsio.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-ss-hsio.dtsi
index f2c94cdb682b..2e4fbfe0ca16 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-ss-hsio.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qm-ss-hsio.dtsi
@@ -41,6 +41,17 @@ pcie0: pciea: pcie@5f000000 {
power-domains = <&pd IMX_SC_R_PCIE_A>;
fsl,max-link-speed = <3>;
status = "disabled";
+
+ pciea_port0: pcie@0 {
+ compatible = "pciclass,0604";
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie0_ep: pciea_ep: pcie-ep@5f000000 {
@@ -91,6 +102,17 @@ pcie1: pcieb: pcie@5f010000 {
power-domains = <&pd IMX_SC_R_PCIE_B>;
fsl,max-link-speed = <3>;
status = "disabled";
+
+ pcieb_port0: pcie@0 {
+ compatible = "pciclass,0604";
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
sata: sata@5f020000 {
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
index 623169f7ddb5..489e174df4c4 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
@@ -730,6 +730,7 @@ &pcie0 {
phy-names = "pcie-phy";
pinctrl-0 = <&pinctrl_pcieb>;
pinctrl-names = "default";
+ /* This property is deprecated, use reset-gpios from the Root Port node. */
reset-gpios = <&lsio_gpio4 0 GPIO_ACTIVE_LOW>;
vpcie-supply = <®_pcieb>;
vpcie3v3aux-supply = <®_pcieb>;
@@ -746,6 +747,10 @@ &pcie0_ep {
status = "disabled";
};
+&pcieb_port0 {
+ reset-gpios = <&lsio_gpio4 0 GPIO_ACTIVE_LOW>;
+};
+
&scu_key {
status = "okay";
};
--
2.37.1
^ permalink raw reply related
* [PATCH V13 12/12] arm64: dts: imx95: Add Root Port node and PERST property
From: Sherry Sun @ 2026-04-16 11:14 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
lpieralisi, kwilczynski, mani, bhelgaas, hongxing.zhu, l.stach
Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20260416111422.183860-1-sherry.sun@nxp.com>
Since describing the PCIe PERST# property under Host Bridge node is now
deprecated, it is recommended to add it to the Root Port node, so
creating the Root Port node and add the reset-gpios property in Root
Port.
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
.../boot/dts/freescale/imx95-15x15-evk.dts | 5 +++++
.../boot/dts/freescale/imx95-19x19-evk.dts | 10 +++++++++
arch/arm64/boot/dts/freescale/imx95.dtsi | 22 +++++++++++++++++++
3 files changed, 37 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
index e4649d7f9122..7d820a0f80b2 100644
--- a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
@@ -553,6 +553,7 @@ &netcmix_blk_ctrl {
&pcie0 {
pinctrl-0 = <&pinctrl_pcie0>;
pinctrl-names = "default";
+ /* This property is deprecated, use reset-gpios from the Root Port node. */
reset-gpio = <&gpio5 13 GPIO_ACTIVE_LOW>;
vpcie-supply = <®_m2_pwr>;
vpcie3v3aux-supply = <®_m2_pwr>;
@@ -567,6 +568,10 @@ &pcie0_ep {
status = "disabled";
};
+&pcie0_port0 {
+ reset-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
+};
+
&sai1 {
assigned-clocks = <&scmi_clk IMX95_CLK_AUDIOPLL1_VCO>,
<&scmi_clk IMX95_CLK_AUDIOPLL2_VCO>,
diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
index 041fd838fabb..6f193cf04119 100644
--- a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
@@ -540,6 +540,7 @@ &netc_timer {
&pcie0 {
pinctrl-0 = <&pinctrl_pcie0>;
pinctrl-names = "default";
+ /* This property is deprecated, use reset-gpios from the Root Port node. */
reset-gpio = <&i2c7_pcal6524 5 GPIO_ACTIVE_LOW>;
vpcie-supply = <®_pcie0>;
vpcie3v3aux-supply = <®_pcie0>;
@@ -554,9 +555,14 @@ &pcie0_ep {
status = "disabled";
};
+&pcie0_port0 {
+ reset-gpios = <&i2c7_pcal6524 5 GPIO_ACTIVE_LOW>;
+};
+
&pcie1 {
pinctrl-0 = <&pinctrl_pcie1>;
pinctrl-names = "default";
+ /* This property is deprecated, use reset-gpios from the Root Port node. */
reset-gpio = <&i2c7_pcal6524 16 GPIO_ACTIVE_LOW>;
vpcie-supply = <®_slot_pwr>;
vpcie3v3aux-supply = <®_slot_pwr>;
@@ -570,6 +576,10 @@ &pcie1_ep {
status = "disabled";
};
+&pcie1_port0 {
+ reset-gpios = <&i2c7_pcal6524 16 GPIO_ACTIVE_LOW>;
+};
+
&sai1 {
#sound-dai-cells = <0>;
pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi
index 71394871d8dd..0cc6644f98bb 100644
--- a/arch/arm64/boot/dts/freescale/imx95.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
@@ -1890,6 +1890,17 @@ pcie0: pcie@4c300000 {
iommu-map-mask = <0x1ff>;
fsl,max-link-speed = <3>;
status = "disabled";
+
+ pcie0_port0: pcie@0 {
+ compatible = "pciclass,0604";
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie0_ep: pcie-ep@4c300000 {
@@ -1967,6 +1978,17 @@ pcie1: pcie@4c380000 {
iommu-map-mask = <0x1ff>;
fsl,max-link-speed = <3>;
status = "disabled";
+
+ pcie1_port0: pcie@0 {
+ compatible = "pciclass,0604";
+ device_type = "pci";
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ bus-range = <0x01 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ };
};
pcie1_ep: pcie-ep@4c380000 {
--
2.37.1
^ permalink raw reply related
* Re: [PATCH v2 1/2] dt-bindings: rtc: ti,bq32k: Add delay on rtc reads
From: Adriana Nicolae @ 2026-04-16 11:14 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: alexandre.belloni, linux-rtc, devicetree, linux-kernel, robh,
krzk+dt, conor+dt
In-Reply-To: <89bb6063-d473-498e-bca5-0185325608c3@kernel.org>
On Thu, Apr 16, 2026 at 2:00 PM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> On 16/04/2026 11:57, Adriana Stancu wrote:
> > Add a configurable "ti,read-settle-us" property to resolve a limitation
> > where aggressive I2C polling prevents the BQ32000's internal register to
> > update. This ensures the hardware has sufficient idle time to update its
> > buffer, preventing stale data reads on systems where the "interrupts" are
> > not configured.
>
> And why does the value different between each board layouts? Same
> device, different board and you need different value?
>
> Do not attach (thread) your patchsets to some other threads (unrelated
> or older versions). This buries them deep in the mailbox and might
> interfere with applying entire sets. See also:
> https://elixir.bootlin.com/linux/v6.16-rc2/source/Documentation/process/submitting-patches.rst#L830
>
You are right, the delay should be specific to the RTC chip, not the
board layout. I will drop the dt property and send a v3 that
implements a fixed 2ms delay in the driver.
This will be applied only when an interrupt is not present, because
this is when the userspace will use polling.
Best regards,
Adriana
^ permalink raw reply
* [PATCH] arm64: dts: qcom: purwa-iot-evk: Update TSENS thermal zone
From: Gaurav Kohli @ 2026-04-16 11:34 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-msm, devicetree, linux-kernel, manaf.pallikunhi,
Gaurav Kohli
Purwa IOT boards support a different thermal junction temperature
specification compared to the base Purwa platform due to package
level differences.
Update the passive trip thresholds to 105°C to align with the higher
temperature specification.
Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/purwa-iot-evk.dts | 32 ++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/purwa-iot-evk.dts b/arch/arm64/boot/dts/qcom/purwa-iot-evk.dts
index ad503beec1d3..261d1e85651d 100644
--- a/arch/arm64/boot/dts/qcom/purwa-iot-evk.dts
+++ b/arch/arm64/boot/dts/qcom/purwa-iot-evk.dts
@@ -1325,6 +1325,38 @@ right_tweeter: speaker@0,1 {
};
};
+&thermal_gpuss_0 {
+ trips {
+ trip-point0 {
+ temperature = <105000>;
+ };
+ };
+};
+
+&thermal_gpuss_1 {
+ trips {
+ trip-point0 {
+ temperature = <105000>;
+ };
+ };
+};
+
+&thermal_gpuss_2 {
+ trips {
+ trip-point0 {
+ temperature = <105000>;
+ };
+ };
+};
+
+&thermal_gpuss_3 {
+ trips {
+ trip-point0 {
+ temperature = <105000>;
+ };
+ };
+};
+
&tlmm {
edp_reg_en: edp-reg-en-state {
pins = "gpio70";
---
base-commit: 936c21068d7ade00325e40d82bfd2f3f29d9f659
change-id: 20260416-purwa_high_tj-5f87b7ed57c9
Best regards,
--
Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
^ permalink raw reply related
* Re: [PATCH v2 2/2] riscv: dts: spacemit: Add cpu scaling for K1 SoC
From: Anand Moon @ 2026-04-16 11:37 UTC (permalink / raw)
To: Shuwei Wu
Cc: Rafael J. Wysocki, Viresh Kumar, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yixun Lan, linux-pm, linux-kernel, linux-riscv,
spacemit, devicetree
In-Reply-To: <DHUCL24GMX7D.369IWK9DLPZPX@mailbox.org>
Hi Shuwei,
Thanks for sharing the details.
On Thu, 16 Apr 2026 at 11:29, Shuwei Wu <shuwei.wu@mailbox.org> wrote:
>
> On Tue Apr 14, 2026 at 9:25 PM CST, Anand Moon wrote:
> > Hi Shuwei,
> >
> > On Fri, 10 Apr 2026 at 13:30, Shuwei Wu <shuwei.wu@mailbox.org> wrote:
> >>
> >> Add Operating Performance Points (OPP) tables and CPU clock properties
> >> for the two clusters in the SpacemiT K1 SoC.
> >>
> >> Also assign the CPU power supply (cpu-supply) for the Banana Pi BPI-F3
> >> board to fully enable CPU DVFS.
> >>
> >> Signed-off-by: Shuwei Wu <shuwei.wu@mailbox.org>
> >>
> >> ---
> >> Changes in v2:
> >> - Add k1-opp.dtsi with OPP tables for both CPU clusters
> >> - Assign CPU supplies and include OPP table for Banana Pi BPI-F3
> >> ---
> >> arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts | 35 +++++++-
> >> arch/riscv/boot/dts/spacemit/k1-opp.dtsi | 105 ++++++++++++++++++++++++
> >> arch/riscv/boot/dts/spacemit/k1.dtsi | 8 ++
> >> 3 files changed, 147 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
> >> index 444c3b1e6f44..3780593f610d 100644
> >> --- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
> >> +++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
> >> @@ -5,6 +5,7 @@
> >>
> >> #include "k1.dtsi"
> >> #include "k1-pinctrl.dtsi"
> >> +#include "k1-opp.dtsi"
> >>
> >> / {
> >> model = "Banana Pi BPI-F3";
> >> @@ -86,6 +87,38 @@ &combo_phy {
> >> status = "okay";
> >> };
> >>
> >> +&cpu_0 {
> >> + cpu-supply = <&buck1_3v45>;
> >> +};
> >> +
> >> +&cpu_1 {
> >> + cpu-supply = <&buck1_3v45>;
> >> +};
> >> +
> >> +&cpu_2 {
> >> + cpu-supply = <&buck1_3v45>;
> >> +};
> >> +
> >> +&cpu_3 {
> >> + cpu-supply = <&buck1_3v45>;
> >> +};
> >> +
> >> +&cpu_4 {
> >> + cpu-supply = <&buck1_3v45>;
> >> +};
> >> +
> >> +&cpu_5 {
> >> + cpu-supply = <&buck1_3v45>;
> >> +};
> >> +
> >> +&cpu_6 {
> >> + cpu-supply = <&buck1_3v45>;
> >> +};
> >> +
> >> +&cpu_7 {
> >> + cpu-supply = <&buck1_3v45>;
> >> +};
> >> +
> >> &emmc {
> >> bus-width = <8>;
> >> mmc-hs400-1_8v;
> >> @@ -201,7 +234,7 @@ pmic@41 {
> >> dldoin2-supply = <&buck5>;
> >>
> >> regulators {
> >> - buck1 {
> >> + buck1_3v45: buck1 {
> >> regulator-min-microvolt = <500000>;
> >> regulator-max-microvolt = <3450000>;
> >> regulator-ramp-delay = <5000>;
> >> diff --git a/arch/riscv/boot/dts/spacemit/k1-opp.dtsi b/arch/riscv/boot/dts/spacemit/k1-opp.dtsi
> >> new file mode 100644
> >> index 000000000000..768ae390686d
> >> --- /dev/null
> >> +++ b/arch/riscv/boot/dts/spacemit/k1-opp.dtsi
> >> @@ -0,0 +1,105 @@
> >> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> >> +
> >> +/ {
> >> + cluster0_opp_table: opp-table-cluster0 {
> >> + compatible = "operating-points-v2";
> >> + opp-shared;
> >> +
> >> + opp-614400000 {
> >> + opp-hz = /bits/ 64 <614400000>;
> >> + opp-microvolt = <950000>;
> >> + clock-latency-ns = <200000>;
> >> + };
> >> +
> >> + opp-819000000 {
> >> + opp-hz = /bits/ 64 <819000000>;
> >> + opp-microvolt = <950000>;
> >> + clock-latency-ns = <200000>;
> >> + };
> >> +
> >> + opp-1000000000 {
> >> + opp-hz = /bits/ 64 <1000000000>;
> >> + opp-microvolt = <950000>;
> >> + clock-latency-ns = <200000>;
> >> + };
> >> +
> >> + opp-1228800000 {
> >> + opp-hz = /bits/ 64 <1228800000>;
> >> + opp-microvolt = <950000>;
> >> + clock-latency-ns = <200000>;
> >> + };
> >> +
> >> + opp-1600000000 {
> >> + opp-hz = /bits/ 64 <1600000000>;
> >> + opp-microvolt = <1050000>;
> >> + clock-latency-ns = <200000>;
> >> + };
> >> + };
> >> +
> >> + cluster1_opp_table: opp-table-cluster1 {
> >> + compatible = "operating-points-v2";
> >> + opp-shared;
> >> +
> >> + opp-614400000 {
> >> + opp-hz = /bits/ 64 <614400000>;
> >> + opp-microvolt = <950000>;
> >> + clock-latency-ns = <200000>;
> >> + };
> >> +
> >> + opp-819000000 {
> >> + opp-hz = /bits/ 64 <819000000>;
> >> + opp-microvolt = <950000>;
> >> + clock-latency-ns = <200000>;
> >> + };
> >> +
> >> + opp-1000000000 {
> >> + opp-hz = /bits/ 64 <1000000000>;
> >> + opp-microvolt = <950000>;
> >> + clock-latency-ns = <200000>;
> >> + };
> >> +
> >> + opp-1228800000 {
> >> + opp-hz = /bits/ 64 <1228800000>;
> >> + opp-microvolt = <950000>;
> >> + clock-latency-ns = <200000>;
> >> + };
> >> +
> >> + opp-1600000000 {
> >> + opp-hz = /bits/ 64 <1600000000>;
> >> + opp-microvolt = <1050000>;
> >> + clock-latency-ns = <200000>;
> >> + };
> >> + };
> >> +};
> >> +
> >> +&cpu_0 {
> >> + operating-points-v2 = <&cluster0_opp_table>;
> >> +};
> >> +
> >> +&cpu_1 {
> >> + operating-points-v2 = <&cluster0_opp_table>;
> >> +};
> >> +
> >> +&cpu_2 {
> >> + operating-points-v2 = <&cluster0_opp_table>;
> >> +};
> >> +
> >> +&cpu_3 {
> >> + operating-points-v2 = <&cluster0_opp_table>;
> >> +};
> >> +
> >> +&cpu_4 {
> >> + operating-points-v2 = <&cluster1_opp_table>;
> >> +};
> >> +
> >> +&cpu_5 {
> >> + operating-points-v2 = <&cluster1_opp_table>;
> >> +};
> >> +
> >> +&cpu_6 {
> >> + operating-points-v2 = <&cluster1_opp_table>;
> >> +};
> >> +
> >> +&cpu_7 {
> >> + operating-points-v2 = <&cluster1_opp_table>;
> >> +};
> >> diff --git a/arch/riscv/boot/dts/spacemit/k1.dtsi b/arch/riscv/boot/dts/spacemit/k1.dtsi
> >> index 529ec68e9c23..bdd109b81730 100644
> >> --- a/arch/riscv/boot/dts/spacemit/k1.dtsi
> >> +++ b/arch/riscv/boot/dts/spacemit/k1.dtsi
> >> @@ -54,6 +54,7 @@ cpu_0: cpu@0 {
> >> compatible = "spacemit,x60", "riscv";
> >> device_type = "cpu";
> >> reg = <0>;
> >> + clocks = <&syscon_apmu CLK_CPU_C0_CORE>;
> >> riscv,isa = "rv64imafdcbv_zicbom_zicbop_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zba_zbb_zbc_zbs_zkt_zvfh_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt";
> >> riscv,isa-base = "rv64i";
> >> riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "v", "zicbom",
> >> @@ -84,6 +85,7 @@ cpu_1: cpu@1 {
> >> compatible = "spacemit,x60", "riscv";
> >> device_type = "cpu";
> >> reg = <1>;
> >> + clocks = <&syscon_apmu CLK_CPU_C0_CORE>;
> >
> > Based on the Spacemit kernel source, the k1-x_opp_table.dtsi file
> > defines several additional clocks for the Operating Performance Points
> > (OPP) table:
> >
> > clocks = <&ccu CLK_CPU_C0_ACE>, <&ccu CLK_CPU_C1_ACE>, <&ccu CLK_CPU_C0_TCM>,
> > <&ccu CLK_CCI550>, <&ccu CLK_PLL3>, <&ccu
> > CLK_CPU_C0_HI>, <&ccu CLK_CPU_C1_HI>;
> > clock-names = "ace0","ace1","tcm","cci","pll3", "c0hi", "c1hi";
> >
> > These hardware clocks are also explicitly registered in the APMU clock driver
> > via the k1_ccu_apmu_hws array, confirming their availability for frequency
> > and voltage scaling on the K1-X SoC.
> >
> > static struct clk_hw *k1_ccu_apmu_hws[] = {
> > [CLK_CCI550] = &cci550_clk.common.hw,
> > [CLK_CPU_C0_HI] = &cpu_c0_hi_clk.common.hw,
> > [CLK_CPU_C0_CORE] = &cpu_c0_core_clk.common.hw,
> > [CLK_CPU_C0_ACE] = &cpu_c0_ace_clk.common.hw,
> > [CLK_CPU_C0_TCM] = &cpu_c0_tcm_clk.common.hw,
> > [CLK_CPU_C1_HI] = &cpu_c1_hi_clk.common.hw,
> > [CLK_CPU_C1_CORE] = &cpu_c1_core_clk.common.hw,
> > [CLK_CPU_C1_ACE] = &cpu_c1_ace_clk.common.hw,
> >
> > Yes, it is possible to add these clocks for DVFS to work correctly,
> > provided they are managed by the appropriate driver and declared in
> > the Device Tree (DT).
> >
> > Thanks
> > -Anand
>
> Thanks for your review and for pointing this out.
>
> Regarding the clocks you mentioned, I'd like to clarify their roles based on
> the K1 datasheet. Taking Cluster 0 as an example, c0_core_clk is the primary
> clock for the cluster. c0_ace_clk and c0_tcm_clk are children derived from it,
> defaulting to half the frequency of their parent core clock, while c0_hi_clk
> represents the high-speed path selection.
> Cluster 1 follows the same structure.
>
> Based on the official SpacemiT Bianbu OS source, the spacemit-cpufreq.c driver
> mainly performs the following tasks:
> 1. Sets the CCI550 clock frequency to 614MHz.
> 2. Sets the clock frequencies of c0_ace_clk, c1_ace1_clk, and c0_tcm_clk to half
> the frequency of their parent clock.
> 3. For the 1.6GHz OPP, it sets the PLL3 frequency to 3.2GHz and the
> c0_hi_clk/c1_hi_clk frequencies to 1.6GHz.
>
> I booted with the manufacturer's OpenWRT image and used debugfs to confirm that
> the clock states are exactly as described above.
>
> At 1.6GHz:
> Clock Source & Tree Rate (Hz) HW Enable Consumer
> ---------------------------------------------------------------------------
> pll3 3,200,000,000 Y deviceless
> └─ pll3_d2 1,600,000,000 Y deviceless
> ├─ cpu_c1_hi_clk 1,600,000,000 Y deviceless
> │ └─ cpu_c1_pclk 1,600,000,000 Y cpu0
> │ └─ cpu_c1_ace_clk 800,000,000 Y deviceless
> └─ cpu_c0_hi_clk 1,600,000,000 Y deviceless
> └─ cpu_c0_core_clk 1,600,000,000 Y cpu0
> ├─ cpu_c0_tcm_clk 800,000,000 Y deviceless
> └─ cpu_c0_ace_clk 800,000,000 Y deviceless
>
> pll1_2457p6_vco 2,457,600,000 Y deviceless
> └─ pll1_d4 614,400,000 Y deviceless
> └─ pll1_d4_614p4 614,400,000 Y deviceless
> └─ cci550_clk 614,400,000 Y deviceless
>
> At 1.228GHz:
> Clock Source & Tree Rate (Hz) HW Enable Consumer
> ---------------------------------------------------------------------------
> pll1_2457p6_vco 2,457,600,000 Y deviceless
> └─ pll1_d2 1,228,800,000 Y deviceless
> └─ pll1_d2_1228p8 1,228,800,000 Y deviceless
> ├─ cpu_c0_core_clk 1,228,800,000 Y cpu0
> │ ├─ cpu_c0_tcm_clk 614,400,000 Y deviceless
> │ └─ cpu_c0_ace_clk 614,400,000 Y deviceless
> └─ cpu_c1_pclk 1,228,800,000 Y cpu0
> └─ cpu_c1_ace_clk 614,400,000 Y deviceless
> └─ pll1_d4 614,400,000 Y deviceless
> └─ pll1_d4_614p4 614,400,000 Y deviceless
> └─ cci550_clk 614,400,000 Y deviceless
>
> pll3 3,200,000,000 Y deviceless
> └─ pll3_d2 1,600,000,000 Y deviceless
> ├─ cpu_c1_hi_clk 1,600,000,000 Y deviceless
> └─ cpu_c0_hi_clk 1,600,000,000 Y deviceless
> └─ pll3_d3 1,066,666,666 Y deviceless
>
> Regarding the necessity of listing these clocks in the DT, my analysis is as follows:
> 1. For CCI550, I did not find a clear definition of this clock's specific role
> in the SoC datasheet. Although the vendor kernel increases its frequency,
> my benchmarks show that maintaining the mainline default (245.76MHz) has a
> negligible impact on CPU performance.
> 2. For ACE and TCM clocks, they function as synchronous children of the core
> clock with a default divide-by-2 ratio. Since they scale automatically relative
> to c0_core_clk/c1_core_clk and no other peripherals depend on them, they do not
> require manual management in the OPP table.
> 3. For the high-speed path, the underlying clock controller logic already handles
> the parent MUX switching and PLL3 scaling automatically when clk_set_rate()
> is called on the core clock.
>
> I have verified this by checking the hardware state in the mainline kernel.
> The clock tree matches the vendor kernel's configuration:
>
> At 1.6GHz:
> Clock Source & Tree Rate (Hz) HW Enable Consumer
> ---------------------------------------------------------------------------
> pll3 3,200,000,000 Y deviceless
> └─ pll3_d2 1,600,000,000 Y deviceless
> ├─ cpu_c1_hi_clk 1,600,000,000 Y deviceless
> │ └─ cpu_c1_core_clk 1,600,000,000 Y cpu4
> │ └─ cpu_c1_ace_clk 800,000,000 Y deviceless
> └─ cpu_c0_hi_clk 1,600,000,000 Y deviceless
> └─ cpu_c0_core_clk 1,600,000,000 Y cpu0
> ├─ cpu_c0_tcm_clk 800,000,000 Y deviceless
> └─ cpu_c0_ace_clk 800,000,000 Y deviceless
>
> pll1 2,457,600,000 Y deviceless
> └─ pll1_d5 491,520,000 Y deviceless
> └─ pll1_d5_491p52 491,520,000 Y deviceless
> └─ cci550_clk 245,760,000 Y deviceless
>
> At 1.228GHz:
> Clock Source & Tree Rate (Hz) HW Enable Consumer
> ---------------------------------------------------------------------------
> pll1 2,457,600,000 Y deviceless
> ├─ pll1_d5 491,520,000 Y deviceless
> │ └─ pll1_d5_491p52 491,520,000 Y deviceless
> │ └─ cci550_clk 245,760,000 Y deviceless
> └─ pll1_d2 1,228,800,000 Y deviceless
> └─ pll1_d2_1228p8 1,228,800,000 Y deviceless
> └─ cpu_c0_core_clk 1,228,800,000 Y cpu0
> ├─ cpu_c0_tcm_clk 614,400,000 Y deviceless
> └─ cpu_c0_ace_clk 614,400,000 Y deviceless
>
> pll3 3,200,000,000 Y deviceless
> └─ pll3_d2 1,600,000,000 Y deviceless
> └─ cpu_c1_hi_clk 1,600,000,000 Y deviceless
> └─ cpu_c1_core_clk 1,600,000,000 Y cpu4
> └─ cpu_c1_ace_clk 800,000,000 Y deviceless
>
Thanks, I have verified the clocks are set to Y in
/sys/kernel/debug/clk/clk_summary
> Performance benchmarks also confirm that the current configuration is sufficient:
> Benchmark (AWK computation): time awk 'BEGIN{for(i=0;i<10000000;i++) sum+=i}'
> ----------------------------------------------------------------------------
> Frequency | Mainline Linux (s) | OpenWrt (s)
> (kHz) | Real (Total) | User (CPU) | Real (Total) | User (CPU) )
> -------------+---------------+---------------+---------------+--------------
> 1,600,000 | 1.82s | 1.81s | 1.73s | 1.73s
> 1,228,800 | 2.34s | 2.33s | 2.26s | 2.26s
> 1,000,000 | 2.94s | 2.86s | 2.78s | 2.78s
> 819,000 | 3.54s | 3.53s | 3.39s | 3.39s
> 614,400 | 4.73s | 4.71s | 4.51s | 4.51s
> ----------------------------------------------------------------------------
>
> In summary, because the clock controller correctly handles the internal dividers
> and parent switching, declaring only the primary core clock for each CPU node is
> sufficient for functional DVFS.
>
I have just tested this patch against next-20260415
But, I have observed this log on the Banana Pi F3 dev board with the
Banana PI - R4 heat sink and fan.
[ 5.803445][ T1] In-situ OAM (IOAM) with IPv6
[ 5.809605][ T1] NET: Registered PF_PACKET protocol family
[ 5.819098][ T1] Key type dns_resolver registered
[ 5.853430][ C2] cpu2: scalar unaligned word access speed is
1.60x byte access speed (fast)
[ 5.853431][ C3] cpu3: scalar unaligned word access speed is
1.67x byte access speed (fast)
[ 5.853440][ C7] cpu7: scalar unaligned word access speed is
8.10x byte access speed (fast)
[ 5.853432][ C1] cpu1: scalar unaligned word access speed is
3.98x byte access speed (fast)
[ 5.853431][ T1] cpu0: scalar unaligned word access speed is
2.33x byte access speed (fast)
[ 5.853436][ C5] cpu5: scalar unaligned word access speed is
2.29x byte access speed (fast)
[ 5.853436][ C6] cpu6: scalar unaligned word access speed is
2.58x byte access speed (fast)
[ 5.853431][ C4] cpu4: scalar unaligned word access speed is
2.07x byte access speed (fast)
[ 5.936544][ T92] mmcblk0boot0: mmc0:0001 AJTD4R 4.00 MiB
[ 6.003120][ T92] mmcblk0boot1: mmc0:0001 AJTD4R 4.00 MiB
[ 6.070909][ T92] mmcblk0rpmb: mmc0:0001 AJTD4R 4.00 MiB, chardev (244:0)
[ 6.380324][ T1] registered taskstats version 1
[ 6.407337][ T1] Loading compiled-in X.509 certificates
[ 6.594206][ T1] Loaded X.509 cert 'Build time autogenerated
kernel key: 19b81ec48e45e6ee983623417bad5096df8bbcf1'
[ 7.600343][ T1] Demotion targets for Node 0: null
[ 7.608583][ T1] kmemleak: Kernel memory leak detector
initialized (mem pool available: 1309)
[ 7.608646][ T120] kmemleak: Automatic memory scanning thread started
[ 7.624663][ T1] debug_vm_pgtable: [debug_vm_pgtable ]:
Validating architecture page table helpers
[ 7.636721][ T1] page_owner is disabled
[ 8.213648][ T74] debugfs: ':soc:gpio@d4019000-1' already exists
in 'domains'
[ 8.233502][ T74] debugfs: ':soc:gpio@d4019000-1' already exists
in 'domains'
[ 8.254012][ T74] debugfs: ':soc:gpio@d4019000-1' already exists
in 'domains'
[ 8.319431][ T74] printk: legacy console [ttyS0] disabled
[ 8.345811][ T74] d4017000.serial: ttyS0 at MMIO 0xd4017000 (irq
= 16, base_baud = 921600) is a XScale
[ 8.357331][ T74] printk: legacy console [ttyS0] enabled
[ 8.357331][ T74] printk: legacy console [ttyS0] enabled
[ 8.369971][ T74] printk: legacy bootconsole [uart0] disabled
[ 8.369971][ T74] printk: legacy bootconsole [uart0] disabled
[ 8.427040][ T74] /soc/i2c@d401d800/pmic@41: Fixed dependency
cycle(s) with /soc/i2c@d401d800/pmic@41/regulators/buck5
[ 8.634595][ T74] spacemit-p1-rtc spacemit-p1-rtc.1.auto:
registered as rtc0
[ 8.642732][ T74] spacemit-p1-rtc spacemit-p1-rtc.1.auto: setting
system clock to 2026-04-10T00:03:42 UTC (1775779422)
[ 8.766081][ T74] sdhci-spacemit d4280000.mmc: Got CD GPIO
[ 8.801855][ T130] buck1: Restricting voltage, 1050000-950000uV
[ 8.806411][ T129] buck1: Restricting voltage, 1050000-950000uV
[ 8.813413][ T130] buck1: Restricting voltage, 1050000-950000uV
[ 8.818261][ T130] cpu cpu4: _set_opp_voltage: failed to set
voltage (1050000 1050000 1050000 mV): -22
[ 8.818307][ T129] buck1: Restricting voltage, 1050000-950000uV
[ 8.827239][ T129] cpu cpu0: _set_opp_voltage: failed to set
voltage (1050000 1050000 1050000 mV): -22
[ 8.833161][ T130] cpu cpu4: Failed to set regulator voltages: -22
[ 8.842546][ T129] cpu cpu0: Failed to set regulator voltages: -22
[ 8.848941][ T130] cpufreq: __target_index: Failed to change cpu
frequency: -22
[ 8.855273][ T129] cpufreq: __target_index: Failed to change cpu
frequency: -22
[ 8.893720][ T129] buck1: Restricting voltage, 1050000-950000uV
[ 8.904437][ T129] buck1: Restricting voltage, 1050000-950000uV
[ 8.908515][ T129] cpu cpu0: _set_opp_voltage: failed to set
voltage (1050000 1050000 1050000 mV): -22
[ 8.918057][ T129] cpu cpu0: Failed to set regulator voltages: -22
[ 8.924402][ T129] cpufreq: __target_index: Failed to change cpu
frequency: -22
[ 8.945668][ T74] mmc1: SDHCI controller on d4280000.mmc
[d4280000.mmc] using ADMA
[ 8.976207][ T130] buck1: Restricting voltage, 1050000-950000uV
[ 8.980156][ T130] buck1: Restricting voltage, 1050000-950000uV
[ 8.986169][ T130] cpu cpu4: _set_opp_voltage: failed to set
voltage (1050000 1050000 1050000 mV): -22
[ 8.995473][ T130] cpu cpu4: Failed to set regulator voltages: -22
[ 9.001603][ T130] cpufreq: __target_index: Failed to change cpu
frequency: -22
[ 9.020028][ T130] buck1: Restricting voltage, 1050000-950000uV
[ 9.024051][ T129] buck1: Restricting voltage, 1050000-950000uV
[ 9.030122][ T130] buck1: Restricting voltage, 1050000-950000uV
[ 9.036004][ T130] cpu cpu4: _set_opp_voltage: failed to set
voltage (1050000 1050000 1050000 mV): -22
[ 9.036059][ T129] buck1: Restricting voltage, 1050000-950000uV
[ 9.045003][ T130] cpu cpu4: Failed to set regulator voltages: -22
[ 9.045077][ T130] cpufreq: __target_index: Failed to change cpu
frequency: -22
[ 9.058079][ T57] spacemit-k1-pcie ca800000.pcie: host bridge
/soc/pcie-bus/pcie@ca800000 ranges:
[ 9.064716][ T129] cpu cpu0: _set_opp_voltage: failed to set
voltage (1050000 1050000 1050000 mV): -22
[ 9.064745][ T130] buck1: Restricting voltage, 1050000-950000uV
[ 9.064825][ T129] cpu cpu0: Failed to set regulator voltages: -22
[ 9.064889][ T129] cpufreq: __target_index: Failed to change cpu
frequency: -22
[ 9.065762][ T130] buck1: Restricting voltage, 1050000-950000uV
[ 9.069924][ T60] spacemit-k1-pcie ca400000.pcie: host bridge
/soc/pcie-bus/pcie@ca400000 ranges:
[ 9.071122][ T60] spacemit-k1-pcie ca400000.pcie: IO
0x009f002000..0x009f101fff -> 0x0000000000
[ 9.073304][ T60] spacemit-k1-pcie ca400000.pcie: MEM
0x0090000000..0x009effffff -> 0x0090000000
[ 9.081407][ T74] at24 2-0050: 256 byte 24c02 EEPROM, read-only
[ 9.083047][ T130] cpu cpu4: _set_opp_voltage: failed to set
voltage (1050000 1050000 1050000 mV): -22
[ 9.083509][ T129] buck1: Restricting voltage, 1050000-950000uV
[ 9.083614][ T129] buck1: Restricting voltage, 1050000-950000uV
[ 9.083686][ T129] cpu cpu0: _set_opp_voltage: failed to set
voltage (1050000 1050000 1050000 mV): -22
[ 9.083845][ T129] cpu cpu0: Failed to set regulator voltages: -22
[ 9.083885][ T129] cpufreq: __target_index: Failed to change cpu
frequency: -22
[ 9.089945][ T57] spacemit-k1-pcie ca800000.pcie: IO
0x00b7002000..0x00b7101fff -> 0x0000000000
[ 9.092728][ T1] clk: Disabling unused clocks
[ 9.095269][ T130] cpu cpu4: Failed to set regulator voltages: -22
[ 9.096981][ T1] PM: genpd: Disabling unused power domains
[ 9.104949][ T57] spacemit-k1-pcie ca800000.pcie: MEM
0x00a0000000..0x00afffffff -> 0x00a0000000
[ 9.107986][ T129] buck1: Restricting voltage, 1050000-950000uV
[ 9.108166][ T129] buck1: Restricting voltage, 1050000-950000uV
[ 9.108246][ T129] cpu cpu0: _set_opp_voltage: failed to set
voltage (1050000 1050000 1050000 mV): -22
[ 9.108311][ T129] cpu cpu0: Failed to set regulator voltages: -22
[ 9.108356][ T129] cpufreq: __target_index: Failed to change cpu
frequency: -22
[ 9.108582][ T130] cpufreq: __target_index: Failed to change cpu
frequency: -22
[ 9.113366][ T130] buck1: Restricting voltage, 1050000-950000uV
[ 9.118144][ T57] spacemit-k1-pcie ca800000.pcie: MEM
0x00b0000000..0x00b6ffffff -> 0x00b0000000
[ 9.130386][ T130] buck1: Restricting voltage, 1050000-950000uV
[ 9.196246][ T130] cpu cpu4: _set_opp_voltage: failed to set
voltage (1050000 1050000 1050000 mV): -22
[ 9.202562][ T60] spacemit-k1-pcie ca400000.pcie: iATU: unroll T,
8 ob, 8 ib, align 4K, limit 4G
[ 9.206998][ T130] cpu cpu4: Failed to set regulator voltages: -22
[ 9.257180][ T130] cpufreq: __target_index: Failed to change cpu
frequency: -22
After reviewing the Banana Pi F3 schematics, I confirmed that Buck1 and Buck2
Both supply the CORE_0V9 with 0.9V±1% rail. To resolve the restriction errors,
I expanded the voltage range in the DTS to 500,000–950,000 µV.
Additionally, I updated the DTS to map the second CPU cluster (cores 4–7)
to Buck2 to better align with the hardware's power distribution.
[1] https://drive.google.com/file/d/19iLJ5xnCB_oK8VeQjkPGjzAn39WYyylv/view
(page 4)
Can you share your thoughts on the changes below?
$ git diff
diff --git a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
index 7e300cca50d8..be53645ba0c6 100644
--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
+++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
@@ -102,19 +102,19 @@ &cpu_3 {
};
&cpu_4 {
- cpu-supply = <&buck1_3v45>;
+ cpu-supply = <&buck2_3v45>;
};
&cpu_5 {
- cpu-supply = <&buck1_3v45>;
+ cpu-supply = <&buck2_3v45>;
};
&cpu_6 {
- cpu-supply = <&buck1_3v45>;
+ cpu-supply = <&buck2_3v45>;
};
&cpu_7 {
- cpu-supply = <&buck1_3v45>;
+ cpu-supply = <&buck2_3v45>;
};
&emmc {
@@ -234,14 +234,14 @@ pmic@41 {
regulators {
buck1_3v45: buck1 {
regulator-min-microvolt = <500000>;
- regulator-max-microvolt = <3450000>;
+ regulator-max-microvolt = <950000>;
regulator-ramp-delay = <5000>;
regulator-always-on;
};
- buck2 {
+ buck2_3v45: buck2 {
regulator-min-microvolt = <500000>;
- regulator-max-microvolt = <3450000>;
+ regulator-max-microvolt = <950000>;
regulator-ramp-delay = <5000>;
regulator-always-on;
};
> --
> Best regards,
> Shuwei Wu
Thanks
-Anand
^ permalink raw reply related
* Re: [PATCH 1/9] dt-bindings: sound: mt2701-afe-pcm: add HDMI audio path clocks
From: Daniel Golle @ 2026-04-16 11:41 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
Jaroslav Kysela, Takashi Iwai, Cyril Chao, Arnd Bergmann,
Kuninori Morimoto, Nícolas F. R. A. Prado, Eugen Hristev,
linux-sound, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek
In-Reply-To: <20260416-qualified-violet-salmon-4bec7e@quoll>
On Thu, Apr 16, 2026 at 11:38:24AM +0200, Krzysztof Kozlowski wrote:
> On Wed, Apr 15, 2026 at 04:23:27PM +0100, Daniel Golle wrote:
> > Document four additional optional clocks feeding the HDMI audio
> > output path on MT2701 and MT7623N: the HADDS2 PLL (root of the
>
> There is no MT7623N compatible in this file, so that's confusing. Does
> mt7622 have it? If not, then it should be restricted per variant. If
> yet, the model name is confusing.
Only MT7623N (which is apparently identical with MT2701) has all the
multimedia features (ie. HDMI, a Mali-450 GPU, ...). Neither MT7623A
nor any of the other MediaTek router SoCs got any of that. So it
should be restricted to that variant. I'll fix this in v2.
Thanks for the review!
Daniel
^ permalink raw reply
* Re: [PATCH] of: unittest: fix use-after-free in of_unittest_changeset()
From: Rob Herring (Arm) @ 2026-04-16 11:49 UTC (permalink / raw)
To: Wentao Liang; +Cc: saravanak, devicetree, stable, linux-kernel
In-Reply-To: <20260409022233.418103-1-vulab@iscas.ac.cn>
On Thu, 09 Apr 2026 02:22:33 +0000, Wentao Liang wrote:
> The variable 'parent' is assigned the value of 'nchangeset' earlier in the
> function, meaning both point to the same struct device_node. The call to
> of_node_put(nchangeset) can decrement the reference count to zero and
> free the node if there are no other holders. After that, the code still
> uses 'parent' to check for the presence of a property and to read a
> string property, leading to a use-after-free.
>
> Fix this by moving the of_node_put() call after the last access to
> 'parent', avoiding the UAF.
>
> Fixes: 1c668ea65506 ("of: unittest: Use of_property_present()")
> Cc: stable@vger.kernel.org
> Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
> ---
> drivers/of/unittest.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
Applied, thanks!
^ permalink raw reply
* Re: [PATCH] of: unittest: fix use-after-free in testdrv_probe()
From: Rob Herring (Arm) @ 2026-04-16 11:51 UTC (permalink / raw)
To: Wentao Liang; +Cc: linux-kernel, devicetree, stable, saravanak
In-Reply-To: <20260409034859.429071-1-vulab@iscas.ac.cn>
On Thu, 09 Apr 2026 03:48:59 +0000, Wentao Liang wrote:
> The function testdrv_probe() retrieves the device_node from the PCI
> device, applies an overlay, and then immediately calls of_node_put(dn).
> This releases the reference held by the PCI core, potentially freeing
> the node if the reference count drops to zero. Later, the same freed
> pointer 'dn' is passed to of_platform_default_populate(), leading to a
> use-after-free.
>
> The reference to pdev->dev.of_node is owned by the device model and
> should not be released by the driver. Remove the erroneous of_node_put()
> to prevent premature freeing.
>
> Fixes: 26409dd04589 ("of: unittest: Add pci_dt_testdrv pci driver")
> Cc: stable@vger.kernel.org
> Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
> ---
> drivers/of/unittest.c | 1 -
> 1 file changed, 1 deletion(-)
>
Applied, thanks!
^ permalink raw reply
* Re: [PATCH v2 01/13] dt-bindings: i3c: Add mipi-i3c-static-method to support SETAASA
From: Rob Herring @ 2026-04-16 11:59 UTC (permalink / raw)
To: Akhil R
Cc: Alexandre Belloni, Frank Li, Krzysztof Kozlowski, Conor Dooley,
Rafael J . Wysocki, Robert Moore, Len Brown, Guenter Roeck,
Philipp Zabel, Eric Biggers, Sakari Ailus, Wolfram Sang,
Miquel Raynal, linux-i3c, devicetree, linux-kernel, linux-acpi,
acpica-devel, linux-hwmon
In-Reply-To: <20260409105747.48158-2-akhilrajeev@nvidia.com>
On Thu, Apr 09, 2026 at 04:27:31PM +0530, Akhil R wrote:
> Add the 'mipi-i3c-static-method' property mentioned in the MIPI I3C
> Discovery and Configuration Specification [1] to specify which discovery
> method an I3C device supports during bus initialization. The property is
> a bitmap, where a bit value of 1 indicates support for that method, and 0
> indicates lack of support.
> Bit 0: SETDASA CCC (Direct)
> Bit 1: SETAASA CCC (Broadcast)
> Bit 2: Other CCC (vendor / standards extension)
> All other bits are reserved.
>
> It is specifically needed when an I3C device requires SETAASA for the
> address assignment. SETDASA will be supported by default if this property
> is absent, which means for now the property just serves as a flag to
> enable SETAASA, but keep the property as a bitmap to align with the
> specifications.
>
> [1] https://www.mipi.org/mipi-disco-for-i3c-download
>
> Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
> ---
> .../devicetree/bindings/i3c/i3c.yaml | 30 ++++++++++++++++---
> 1 file changed, 26 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/i3c/i3c.yaml b/Documentation/devicetree/bindings/i3c/i3c.yaml
> index e25fa72fd785..1705d90d4d79 100644
> --- a/Documentation/devicetree/bindings/i3c/i3c.yaml
> +++ b/Documentation/devicetree/bindings/i3c/i3c.yaml
> @@ -31,10 +31,12 @@ properties:
> described in the device tree, which in turn means we have to describe
> I3C devices.
>
> - Another use case for describing an I3C device in the device tree is when
> - this I3C device has a static I2C address and we want to assign it a
> - specific I3C dynamic address before the DAA takes place (so that other
> - devices on the bus can't take this dynamic address).
> + Other use-cases for describing an I3C device in the device tree are:
> + - When the I3C device has a static I2C address and we want to assign
> + it a specific I3C dynamic address before the DAA takes place (so
> + that other devices on the bus can't take this dynamic address).
> + - When the I3C device requires SETAASA for its discovery and uses a
> + pre-defined static address.
>
> "#size-cells":
> const: 0
> @@ -147,6 +149,26 @@ patternProperties:
> through SETDASA. If static address is not present, this address is assigned
> through SETNEWDA after assigning a temporary address via ENTDAA.
>
> + mipi-i3c-static-method:
> + $ref: /schemas/types.yaml#/definitions/uint32
> + minimum: 0x1
> + maximum: 0xff
Looks like the max is 0x7 currently.
> + default: 1
> + description: |
> + Bitmap describing which methods of Dynamic Address Assignment from a
> + static address are supported by this I3C Target. A bit value of 1
> + indicates support for that method, and 0 indicates lack of support.
blank line here.
> + Bit 0: SETDASA CCC (Direct)
> + Bit 1: SETAASA CCC (Broadcast)
> + Bit 2: Other CCC (vendor / standards extension)
> + All other bits are reserved.
Indent these by 2 more.
> +
> + This property follows the MIPI I3C specification. The primary use
> + of this property is to indicate support for SETAASA, i.e Bit 1, but
> + will allow all values so that it is aligned with the specifications.
> + SETDASA will remain as the default method even if this property is
> + not present.
> +
> required:
> - reg
>
> --
> 2.50.1
>
^ permalink raw reply
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