* [PATCH v2 phy-next 7/8] soc: fsl: guts: implement the RCW override procedure
From: Vladimir Oltean @ 2026-06-12 21:08 UTC (permalink / raw)
To: linux-phy
Cc: devicetree, linuxppc-dev, linux-arm-kernel, Ioana Ciornei,
Vinod Koul, Neil Armstrong, Tanjeff Moos,
Christophe Leroy (CS GROUP), Michael Walle, Shawn Guo, Frank Li,
linux-kernel
In-Reply-To: <20260612210859.266759-1-vladimir.oltean@nxp.com>
From: Ioana Ciornei <ioana.ciornei@nxp.com>
Add support for the RCW override procedure which enables runtime
reconfiguration of the protocol running on a SerDes lane. The procedure
is done through the DCFG DCSR space which now can be defined as the
second memory region of the guts DT node.
Support is added on the following SoCs: LS1046A, LS1088A, LS2088A.
The procedure is exported to the "client" driver - the Lynx10G SerDes
PHY driver - through the following functions:
- fsl_guts_lane_init() used to notify the initial / boot time lane mode
running on a SerDes lane.
- fsl_guts_lane_validate() used to validate that changing the protocol
on a specific lane is supported.
- fsl_guts_lane_set_mode() which can be used to request the RCW
procedure be executed for a specific lane.
Since the RCW override procedure is different depending on the SoC, the
private fsl_soc_data structure is updated with two new per SoC callbacks
(.serdes_get_rcw_override() and .serdes_init_rcwcr()) which get used
from the generic fsl_guts_lane_set_mode() function. These two callbacks
hide all the SoC specific register offsets, masks and values so that the
_set_mode() procedure is straightforward.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
v1->v2:
- drop DT maintainers from explicit CC
- keep devicetree@vger.kernel.org CCed on entire series
- include missing <linux/bitfield.h>
- namespace SRDS_PRTCL values for LS1046A and LS1088A, even if they are
the same. For LS1028A (not covered here) they are not.
- prefix SRDS_CLK_SEL_{GMII,XGMII} with LS2088A_
- reorder alphanumerically (LS1046A should come before LS1088A)
---
drivers/soc/fsl/guts.c | 285 ++++++++++++++++++++++++++++++++++++++-
include/linux/fsl/guts.h | 20 ++-
2 files changed, 298 insertions(+), 7 deletions(-)
diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
index 9f2aff07a274..0fa2bd99d3c1 100644
--- a/drivers/soc/fsl/guts.c
+++ b/drivers/soc/fsl/guts.c
@@ -5,6 +5,7 @@
* Copyright (C) 2016 Freescale Semiconductor, Inc.
*/
+#include <linux/bitfield.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/module.h>
@@ -15,6 +16,28 @@
#include <linux/fsl/guts.h>
#define DCFG_CCSR 0
+#define DCFG_DCSR 1
+
+#define MAX_NUM_LANES 8
+#define MAX_NUM_SERDES 2
+
+#define LS1046A_RCWSR5_SRDS_PRTCL_S1(lane) \
+ GENMASK(19 + 4 * (lane), 16 + 4 * (lane))
+#define LS1046A_SRDS_PRTCL_XFI 1
+#define LS1046A_SRDS_PRTCL_100BASEX_SGMII 3
+
+#define LS1088A_RCWSR29_SRDS_PRTCL_S1_LNn(lane) \
+ GENMASK(19 + 4 * (3 - lane), 16 + 4 * (3 - lane))
+#define LS1088A_RCWSR30_SRDS_PRTCL_S2_LNn(lane) \
+ GENMASK(3 + 4 * (3 - lane), 4 * (3 - lane))
+#define LS1088A_SRDS_PRTCL_XFI 1
+#define LS1088A_SRDS_PRTCL_100BASEX_SGMII 3
+
+#define LS2088A_RCWSR30_SRDS_CLK_EN_SEL_XGMII_S1 BIT(14)
+#define LS2088A_RCWSR30_SRDS_CLK_SEL_XGMII_Ln_S1(lane) BIT(6 + (7 - (lane)))
+#define LS2088A_RCWSR30_SRDS_CLK_SEL_MSK GENMASK(13, 6)
+#define LS2088A_SRDS_CLK_SEL_XGMII 1
+#define LS2088A_SRDS_CLK_SEL_GMII 0
struct fsl_soc_die_attr {
char *die;
@@ -22,9 +45,19 @@ struct fsl_soc_die_attr {
u32 mask;
};
+struct fsl_soc_serdes_rcw_override {
+ int offset;
+ int mask;
+ int val;
+};
+
struct fsl_soc_data {
const char *sfp_compat;
u32 uid_offset;
+ int (*serdes_get_rcw_override)(int index, int lane,
+ enum lynx_lane_mode lane_mode,
+ struct fsl_soc_serdes_rcw_override *override);
+ void (*serdes_init_rcwcr)(int index);
};
enum qoriq_die {
@@ -138,9 +171,13 @@ static const struct fsl_soc_die_attr fsl_soc_die[] = {
static struct fsl_soc_guts {
struct ccsr_guts __iomem *dcfg_ccsr;
+ struct ccsr_guts __iomem *dcfg_dcsr;
const struct fsl_soc_data *data;
bool little_endian;
u32 svr;
+ enum lynx_lane_mode lane_mode[MAX_NUM_SERDES][MAX_NUM_LANES];
+ bool rcwcr_init_done;
+ spinlock_t rcwcr_lock; /* serializes concurrent writes to the RCWCR */
} soc;
static unsigned int fsl_guts_read(const void __iomem *reg)
@@ -151,6 +188,28 @@ static unsigned int fsl_guts_read(const void __iomem *reg)
return ioread32be(reg);
}
+static void fsl_guts_write(void __iomem *reg, u32 val)
+{
+ if (soc.little_endian)
+ iowrite32(val, reg);
+ else
+ iowrite32be(val, reg);
+}
+
+/* Some fields of the Reset Configuration Word (RCW) can be overridden at
+ * runtime by writing to the RCWCRn registers contained within the DCSR space
+ * of the Device Configuration (DCFG) block. The layout of the RCWCRn registers
+ * is identical with the read-only RCWSRn from the CCSR space.
+ */
+static void fsl_guts_rmw(int offset, u32 val, u32 mask)
+{
+ u32 tmp = fsl_guts_read(&soc.dcfg_ccsr->rcwsr[offset]);
+
+ tmp &= ~mask;
+ tmp |= val;
+ fsl_guts_write(&soc.dcfg_dcsr->rcwcr[offset], tmp);
+}
+
static bool fsl_soc_die_match_one(u32 svr, const struct fsl_soc_die_attr *match)
{
return match->svr == (svr & match->mask);
@@ -167,6 +226,97 @@ static const struct fsl_soc_die_attr *fsl_soc_die_match(
return NULL;
}
+static int
+fsl_guts_serdes_get_rcw_override(int serdes_idx, int lane,
+ enum lynx_lane_mode lane_mode,
+ struct fsl_soc_serdes_rcw_override *override)
+{
+ if ((!fsl_soc_die_match_one(soc.svr, &fsl_soc_die[DIE_LS1088A]) &&
+ !fsl_soc_die_match_one(soc.svr, &fsl_soc_die[DIE_LS2088A]) &&
+ !fsl_soc_die_match_one(soc.svr, &fsl_soc_die[DIE_LS1046A])) ||
+ !soc.data || !soc.data->serdes_get_rcw_override) {
+ pr_debug("RCW override not implemented for SoC\n");
+ return -EINVAL;
+ }
+
+ if (!soc.dcfg_dcsr) {
+ pr_debug("Device tree does not define DCFG_DCSR region necessary for RCW override\n");
+ return -EINVAL;
+ }
+
+ return soc.data->serdes_get_rcw_override(serdes_idx, lane, lane_mode,
+ override);
+}
+
+/**
+ * fsl_guts_lane_init() - Notify guts module of SerDes lane configuration
+ * @serdes_idx: zero-based SerDes block index
+ * @lane: zero-based lane index within SerDes
+ * @lane_mode: initial / boot time SerDes protocol for lane
+ *
+ * On the LS208xA SoC, the RCW override procedure needs to be aware of all link
+ * modes which are configured on a SerDes block.
+ */
+void fsl_guts_lane_init(int serdes_idx, int lane, enum lynx_lane_mode lane_mode)
+{
+ soc.lane_mode[serdes_idx - 1][lane] = lane_mode;
+}
+EXPORT_SYMBOL_NS_GPL(fsl_guts_lane_init, "FSL_GUTS");
+
+/**
+ * fsl_guts_lane_validate() - Validate that SerDes protocol is implemented and
+ * supported on current SoC
+ * @serdes_idx: zero-based SerDes block index
+ * @lane: zero-based lane index within SerDes
+ * @lane_mode: requested SerDes protocol
+ *
+ * Should be called before actually requesting the RCW override procedure to be
+ * applied using %fsl_guts_lane_set_mode()
+ *
+ * Return: 0 if RCW override to protocol is possible, negative error otherwise
+ */
+int fsl_guts_lane_validate(int serdes_idx, int lane, enum lynx_lane_mode lane_mode)
+{
+ struct fsl_soc_serdes_rcw_override override;
+
+ return fsl_guts_serdes_get_rcw_override(serdes_idx, lane, lane_mode,
+ &override);
+}
+EXPORT_SYMBOL_NS_GPL(fsl_guts_lane_validate, "FSL_GUTS");
+
+/**
+ * fsl_guts_lane_set_mode() - apply RCW override procedure for SerDes lane
+ * @serdes_idx: zero-based SerDes block index
+ * @lane: zero-based lane index within SerDes
+ * @lane_mode: requested SerDes protocol
+ *
+ * Return: 0 on success, negative error otherwise
+ */
+int fsl_guts_lane_set_mode(int serdes_idx, int lane, enum lynx_lane_mode lane_mode)
+{
+ struct fsl_soc_serdes_rcw_override override;
+ int err;
+
+ err = fsl_guts_serdes_get_rcw_override(serdes_idx, lane, lane_mode,
+ &override);
+ if (err)
+ return err;
+
+ spin_lock(&soc.rcwcr_lock);
+
+ if (soc.data->serdes_init_rcwcr)
+ soc.data->serdes_init_rcwcr(serdes_idx);
+
+ fsl_guts_rmw(override.offset, override.val << __bf_shf(override.mask),
+ override.mask);
+ soc.lane_mode[serdes_idx - 1][lane] = lane_mode;
+
+ spin_unlock(&soc.rcwcr_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(fsl_guts_lane_set_mode, "FSL_GUTS");
+
static u64 fsl_guts_get_soc_uid(const char *compat, unsigned int offset)
{
struct device_node *np;
@@ -193,6 +343,128 @@ static u64 fsl_guts_get_soc_uid(const char *compat, unsigned int offset)
return uid;
}
+static int ls1046a_serdes_get_rcw_override(int index, int lane,
+ enum lynx_lane_mode lane_mode,
+ struct fsl_soc_serdes_rcw_override *override)
+{
+ /* The RCW override procedure has to write to different registers
+ * depending on the SerDes block index.
+ */
+ switch (index) {
+ case 1:
+ override->offset = 4;
+ override->mask = LS1046A_RCWSR5_SRDS_PRTCL_S1(lane);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (lynx_lane_mode_uses_xgmii_mac(lane_mode))
+ override->val = LS1046A_SRDS_PRTCL_XFI;
+ else if (lynx_lane_mode_uses_gmii_mac(lane_mode))
+ override->val = LS1046A_SRDS_PRTCL_100BASEX_SGMII;
+ else
+ return -EINVAL;
+
+ return 0;
+}
+
+static int ls1088a_serdes_get_rcw_override(int index, int lane,
+ enum lynx_lane_mode lane_mode,
+ struct fsl_soc_serdes_rcw_override *override)
+{
+ /* The RCW override procedure has to write to different registers
+ * depending on the SerDes block index.
+ */
+ switch (index) {
+ case 1:
+ override->offset = 28;
+ override->mask = LS1088A_RCWSR29_SRDS_PRTCL_S1_LNn(lane);
+ break;
+ case 2:
+ override->offset = 29;
+ override->mask = LS1088A_RCWSR30_SRDS_PRTCL_S2_LNn(lane);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (lynx_lane_mode_uses_xgmii_mac(lane_mode))
+ override->val = LS1088A_SRDS_PRTCL_XFI;
+ else if (lynx_lane_mode_uses_gmii_mac(lane_mode))
+ override->val = LS1088A_SRDS_PRTCL_100BASEX_SGMII;
+ else
+ return -EINVAL;
+
+ return 0;
+}
+
+static int ls2088a_serdes_get_rcw_override(int index, int lane,
+ enum lynx_lane_mode lane_mode,
+ struct fsl_soc_serdes_rcw_override *override)
+{
+ switch (index) {
+ case 1:
+ override->offset = 29;
+ override->mask = LS2088A_RCWSR30_SRDS_CLK_SEL_XGMII_Ln_S1(lane);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (lynx_lane_mode_uses_xgmii_mac(lane_mode))
+ override->val = LS2088A_SRDS_CLK_SEL_XGMII;
+ else if (lynx_lane_mode_uses_gmii_mac(lane_mode))
+ override->val = LS2088A_SRDS_CLK_SEL_GMII;
+ else
+ return -EINVAL;
+
+ return 0;
+}
+
+static void ls2088a_serdes_init_rcwcr(int serdes_idx)
+{
+ u32 reg;
+ int i;
+
+ if (serdes_idx != 1)
+ return;
+ if (soc.rcwcr_init_done)
+ return;
+
+ /* SRDS_CLK_EN_SEL_XGMII_S1: SerDes Clock Enable Select XGMII Serdes 1:
+ * Enables to select GMII/XGMII clock according to
+ * SRDS_CLK_SEL_XGMII_Ln_S1
+ */
+ reg = LS2088A_RCWSR30_SRDS_CLK_EN_SEL_XGMII_S1;
+
+ /* We need to configure the initial state of all lanes for
+ * the SerDes block #1
+ */
+ for (i = 0; i < MAX_NUM_LANES; i++)
+ if (lynx_lane_mode_uses_xgmii_mac(soc.lane_mode[serdes_idx - 1][i]))
+ reg |= LS2088A_RCWSR30_SRDS_CLK_SEL_XGMII_Ln_S1(i);
+
+ fsl_guts_rmw(29, reg,
+ LS2088A_RCWSR30_SRDS_CLK_EN_SEL_XGMII_S1 |
+ LS2088A_RCWSR30_SRDS_CLK_SEL_MSK);
+
+ soc.rcwcr_init_done = true;
+}
+
+static const struct fsl_soc_data ls1088a_data = {
+ .serdes_get_rcw_override = ls1088a_serdes_get_rcw_override,
+};
+
+static const struct fsl_soc_data ls1046a_data = {
+ .serdes_get_rcw_override = ls1046a_serdes_get_rcw_override,
+};
+
+static const struct fsl_soc_data ls2088a_data = {
+ .serdes_get_rcw_override = ls2088a_serdes_get_rcw_override,
+ .serdes_init_rcwcr = ls2088a_serdes_init_rcwcr,
+};
+
static const struct fsl_soc_data ls1028a_data = {
.sfp_compat = "fsl,ls1028a-sfp",
.uid_offset = 0x21c,
@@ -221,10 +493,10 @@ static const struct of_device_id fsl_guts_of_match[] = {
{ .compatible = "fsl,mpc8572-guts", },
{ .compatible = "fsl,ls1021a-dcfg", },
{ .compatible = "fsl,ls1043a-dcfg", },
- { .compatible = "fsl,ls2080a-dcfg", },
- { .compatible = "fsl,ls1088a-dcfg", },
+ { .compatible = "fsl,ls2080a-dcfg", .data = &ls2088a_data},
+ { .compatible = "fsl,ls1088a-dcfg", .data = &ls1088a_data},
{ .compatible = "fsl,ls1012a-dcfg", },
- { .compatible = "fsl,ls1046a-dcfg", },
+ { .compatible = "fsl,ls1046a-dcfg", .data = &ls1046a_data},
{ .compatible = "fsl,lx2160a-dcfg", },
{ .compatible = "fsl,ls1028a-dcfg", .data = &ls1028a_data},
{}
@@ -250,6 +522,8 @@ static int __init fsl_guts_init(void)
of_node_put(np);
return -ENOMEM;
}
+ /* DCFG_DCSR is optional */
+ soc.dcfg_dcsr = of_iomap(np, DCFG_DCSR);
soc.little_endian = of_property_read_bool(np, "little-endian");
soc.svr = fsl_guts_read(&soc.dcfg_ccsr->svr);
@@ -296,6 +570,8 @@ static int __init fsl_guts_init(void)
goto err;
}
+ spin_lock_init(&soc.rcwcr_lock);
+
pr_info("Machine: %s\n", soc_dev_attr->machine);
pr_info("SoC family: %s\n", soc_dev_attr->family);
pr_info("SoC ID: %s, Revision: %s\n",
@@ -305,7 +581,8 @@ static int __init fsl_guts_init(void)
err_nomem:
ret = -ENOMEM;
-
+ if (soc.dcfg_dcsr)
+ iounmap(soc.dcfg_dcsr);
iounmap(soc.dcfg_ccsr);
err:
kfree(soc_dev_attr->family);
diff --git a/include/linux/fsl/guts.h b/include/linux/fsl/guts.h
index fdb55ca47a4f..176842531241 100644
--- a/include/linux/fsl/guts.h
+++ b/include/linux/fsl/guts.h
@@ -13,6 +13,7 @@
#include <linux/types.h>
#include <linux/io.h>
+#include <soc/fsl/phy-fsl-lynx.h>
/*
* Global Utility Registers.
@@ -91,9 +92,15 @@ struct ccsr_guts {
u32 iovselsr; /* 0x.00c0 - I/O voltage select status register
Called 'elbcvselcr' on 86xx SOCs */
u8 res0c4[0x100 - 0xc4];
- u32 rcwsr[16]; /* 0x.0100 - Reset Control Word Status registers
- There are 16 registers */
- u8 res140[0x224 - 0x140];
+ /* 0x.0100 - read-only Reset Configuration Word Status registers in
+ * CCSR, or write-only Reset Configuration Word Control registers in
+ * DCSR. In both cases there are 32 registers.
+ */
+ union {
+ u32 rcwsr[32];
+ u32 rcwcr[32];
+ };
+ u8 res180[0x224 - 0x180];
u32 iodelay1; /* 0x.0224 - IO delay control register 1 */
u32 iodelay2; /* 0x.0228 - IO delay control register 2 */
u8 res22c[0x604 - 0x22c];
@@ -131,6 +138,13 @@ struct ccsr_guts {
u32 srds2cr1; /* 0x.0f44 - SerDes2 Control Register 0 */
} __attribute__ ((packed));
+void fsl_guts_lane_init(int serdes_idx, int lane,
+ enum lynx_lane_mode lane_mode);
+int fsl_guts_lane_validate(int serdes_idx, int lane,
+ enum lynx_lane_mode lane_mode);
+int fsl_guts_lane_set_mode(int serdes_idx, int lane,
+ enum lynx_lane_mode lane_mode);
+
/* Alternate function signal multiplex control */
#define MPC85xx_PMUXCR_QE(x) (0x8000 >> (x))
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v2 phy-next 6/8] dt-bindings: fsl: layerscape-dcfg: define DCFG_DCSR region
From: Vladimir Oltean @ 2026-06-12 21:08 UTC (permalink / raw)
To: linux-phy
Cc: devicetree, linuxppc-dev, linux-arm-kernel, Ioana Ciornei,
Vinod Koul, Neil Armstrong, Tanjeff Moos,
Christophe Leroy (CS GROUP), Michael Walle, Shawn Guo, Frank Li,
linux-kernel, Conor Dooley, Conor Dooley, Krzysztof Kozlowski,
Rob Herring
In-Reply-To: <20260612210859.266759-1-vladimir.oltean@nxp.com>
In Layerscape (Arm) and QorIQ (PowerPC) devices, hardware peripherals
are accessed by the CPU through a portion of the SoC address space
called CCSR ("Configuration, Control, and Status Registers"). All
hardware IP blocks have their registers mapped here, and the Device
Configuration block makes no exception.
However, there exists a secondary range of the address space named DCSR
("Debug Control and Status Registers") which, like CCSR, also holds
registers of hardware IP blocks, except the DCSR contents is hidden in
all public reference manuals.
The intention of the CCSR/DCSR split, to the best of my knowledge, was
to place the functionality that is too low level for normal use, and
which is necessary only for debug, in a completely separate address
space which can be hidden.
A use case has appeared where networking SerDes lanes need to be
reconfigured at runtime for a different protocol (example: 10GBase-R to
SGMII), and the architecture of the SoCs does not normally permit that.
The Reset Configuration Word (RCW) is a data structure read by the SoC
preboot loader (PBL) which contains stuff like pinmuxing and SerDes
protocol mapping for each lane.
The RCW that the PBL has loaded is visible in the DCFG block's normal
status registers (from CCSR), as read only. Turns out, the RCW is also
mapped in the DCFG's shadow register map (in DCSR), in a write-only
form. Writing to the RCW registers from the DCFG's DCSR space to change
what the PBL has loaded is called "RCW override".
It has been validated that the RCW override procedure is necessary to
reconfigure the networking data path when a SerDes lane performs a major
protocol change. It changes some internal muxes which connect the PCS to
either the 10G MAC or to the 1G MAC.
Defining the DCSR area of the DCFG as a secondary 'reg' array element
allows operating systems to perform RCW overrides. Since it is
introduced late in the binding's lifetime, it is optional. It can be
identified by name, but also by index (first 'reg' is CCSR).
Note that while all SoCs should have a DCFG register block in DCSR, we
only need to expose it for the SoCs where the RCW override procedure is
known to be needed and has been validated.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
---
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Rob Herring <robh@kernel.org>
v1->v2:
- add Conor's review tag
- update email addresses of DT maintainers
---
.../bindings/soc/fsl/fsl,layerscape-dcfg.yaml | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/soc/fsl/fsl,layerscape-dcfg.yaml b/Documentation/devicetree/bindings/soc/fsl/fsl,layerscape-dcfg.yaml
index 3fb0534ea597..fc14fd0bf84b 100644
--- a/Documentation/devicetree/bindings/soc/fsl/fsl,layerscape-dcfg.yaml
+++ b/Documentation/devicetree/bindings/soc/fsl/fsl,layerscape-dcfg.yaml
@@ -36,7 +36,20 @@ properties:
- const: simple-mfd
reg:
- maxItems: 1
+ minItems: 1
+ items:
+ - description:
+ Customer-visible DCFG register map from CCSR address space
+ (Configuration, Control and Status Registers)
+ - description:
+ Customer-hidden DCFG register map from DCSR address space
+ (Debug Control and Status Registers)
+
+ reg-names:
+ minItems: 1
+ items:
+ - const: dcfg_ccsr
+ - const: dcfg_dcsr
little-endian: true
big-endian: true
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v2 phy-next 5/8] soc: fsl: guts: make fsl_soc_data available after fsl_guts_init()
From: Vladimir Oltean @ 2026-06-12 21:08 UTC (permalink / raw)
To: linux-phy
Cc: devicetree, linuxppc-dev, linux-arm-kernel, Ioana Ciornei,
Vinod Koul, Neil Armstrong, Tanjeff Moos,
Christophe Leroy (CS GROUP), Michael Walle, Shawn Guo, Frank Li,
linux-kernel
In-Reply-To: <20260612210859.266759-1-vladimir.oltean@nxp.com>
In a future change, struct fsl_soc_data will be extended with methods
for performing RCW override.
Since this will be performed from a calling context outside
fsl_guts_init(), we need to keep track of the soc_data that we determine
at fsl_guts_init() time, so we can reference it later.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
v1->v2: none
---
drivers/soc/fsl/guts.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
index 1494b545bbb4..9f2aff07a274 100644
--- a/drivers/soc/fsl/guts.c
+++ b/drivers/soc/fsl/guts.c
@@ -138,6 +138,7 @@ static const struct fsl_soc_die_attr fsl_soc_die[] = {
static struct fsl_soc_guts {
struct ccsr_guts __iomem *dcfg_ccsr;
+ const struct fsl_soc_data *data;
bool little_endian;
u32 svr;
} soc;
@@ -234,7 +235,6 @@ static int __init fsl_guts_init(void)
struct soc_device_attribute *soc_dev_attr;
static struct soc_device *soc_dev;
const struct fsl_soc_die_attr *soc_die;
- const struct fsl_soc_data *soc_data;
const struct of_device_id *match;
struct device_node *np;
u64 soc_uid = 0;
@@ -243,7 +243,7 @@ static int __init fsl_guts_init(void)
np = of_find_matching_node_and_match(NULL, fsl_guts_of_match, &match);
if (!np)
return 0;
- soc_data = match->data;
+ soc.data = match->data;
soc.dcfg_ccsr = of_iomap(np, DCFG_CCSR);
if (!soc.dcfg_ccsr) {
@@ -283,9 +283,9 @@ static int __init fsl_guts_init(void)
if (!soc_dev_attr->revision)
goto err_nomem;
- if (soc_data)
- soc_uid = fsl_guts_get_soc_uid(soc_data->sfp_compat,
- soc_data->uid_offset);
+ if (soc.data)
+ soc_uid = fsl_guts_get_soc_uid(soc.data->sfp_compat,
+ soc.data->uid_offset);
if (soc_uid)
soc_dev_attr->serial_number = kasprintf(GFP_KERNEL, "%016llX",
soc_uid);
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v2 phy-next 4/8] soc: fsl: guts: make it easier to determine on which SoC we are running
From: Vladimir Oltean @ 2026-06-12 21:08 UTC (permalink / raw)
To: linux-phy
Cc: devicetree, linuxppc-dev, linux-arm-kernel, Ioana Ciornei,
Vinod Koul, Neil Armstrong, Tanjeff Moos,
Christophe Leroy (CS GROUP), Michael Walle, Shawn Guo, Frank Li,
linux-kernel
In-Reply-To: <20260612210859.266759-1-vladimir.oltean@nxp.com>
From: Ioana Ciornei <ioana.ciornei@nxp.com>
The guts driver will need to easily determine on which SoC it's running
when it will need to perform RCW override at runtime. The guts driver
knows this already because fsl_guts_init() reads the QorIQ/Layerscape
architectural System Version Register (SVR), but it doesn't save this
for later lookups.
Add a new qoriq_die enum to be used as an index in the fsl_soc_die
array. A new fsl_soc_die_match_one() function is also added so that we
can directly determine if the SVR is a match with a specific die.
The SVR value read from the DCFG CCSR is also kept in the global soc
structure so that it can be accessed when needed.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
v1->v2: none
---
drivers/soc/fsl/guts.c | 47 ++++++++++++++++++++++++++++++++++++------
1 file changed, 41 insertions(+), 6 deletions(-)
diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
index dc1a42cd9544..1494b545bbb4 100644
--- a/drivers/soc/fsl/guts.c
+++ b/drivers/soc/fsl/guts.c
@@ -27,6 +27,23 @@ struct fsl_soc_data {
u32 uid_offset;
};
+enum qoriq_die {
+ DIE_T4240,
+ DIE_T1040,
+ DIE_T2080,
+ DIE_T1024,
+ DIE_LS1043A,
+ DIE_LS2080A,
+ DIE_LS1088A,
+ DIE_LS1012A,
+ DIE_LS1046A,
+ DIE_LS2088A,
+ DIE_LS1021A,
+ DIE_LX2160A,
+ DIE_LS1028A,
+ DIE_MAX,
+};
+
/* SoC die attribute definition for QorIQ platform */
static const struct fsl_soc_die_attr fsl_soc_die[] = {
/*
@@ -34,21 +51,25 @@ static const struct fsl_soc_die_attr fsl_soc_die[] = {
*/
/* Die: T4240, SoC: T4240/T4160/T4080 */
+ [DIE_T4240] =
{ .die = "T4240",
.svr = 0x82400000,
.mask = 0xfff00000,
},
/* Die: T1040, SoC: T1040/T1020/T1042/T1022 */
+ [DIE_T1040] =
{ .die = "T1040",
.svr = 0x85200000,
.mask = 0xfff00000,
},
/* Die: T2080, SoC: T2080/T2081 */
+ [DIE_T2080] =
{ .die = "T2080",
.svr = 0x85300000,
.mask = 0xfff00000,
},
/* Die: T1024, SoC: T1024/T1014/T1023/T1013 */
+ [DIE_T1024] =
{ .die = "T1024",
.svr = 0x85400000,
.mask = 0xfff00000,
@@ -59,46 +80,55 @@ static const struct fsl_soc_die_attr fsl_soc_die[] = {
*/
/* Die: LS1043A, SoC: LS1043A/LS1023A */
+ [DIE_LS1043A] =
{ .die = "LS1043A",
.svr = 0x87920000,
.mask = 0xffff0000,
},
/* Die: LS2080A, SoC: LS2080A/LS2040A/LS2085A */
+ [DIE_LS2080A] =
{ .die = "LS2080A",
.svr = 0x87010000,
.mask = 0xff3f0000,
},
/* Die: LS1088A, SoC: LS1088A/LS1048A/LS1084A/LS1044A */
+ [DIE_LS1088A] =
{ .die = "LS1088A",
.svr = 0x87030000,
.mask = 0xff3f0000,
},
/* Die: LS1012A, SoC: LS1012A */
+ [DIE_LS1012A] =
{ .die = "LS1012A",
.svr = 0x87040000,
.mask = 0xffff0000,
},
/* Die: LS1046A, SoC: LS1046A/LS1026A */
+ [DIE_LS1046A] =
{ .die = "LS1046A",
.svr = 0x87070000,
.mask = 0xffff0000,
},
/* Die: LS2088A, SoC: LS2088A/LS2048A/LS2084A/LS2044A */
+ [DIE_LS2088A] =
{ .die = "LS2088A",
.svr = 0x87090000,
.mask = 0xff3f0000,
},
/* Die: LS1021A, SoC: LS1021A/LS1020A/LS1022A */
+ [DIE_LS1021A] =
{ .die = "LS1021A",
.svr = 0x87000000,
.mask = 0xfff70000,
},
/* Die: LX2160A, SoC: LX2160A/LX2120A/LX2080A */
+ [DIE_LX2160A] =
{ .die = "LX2160A",
.svr = 0x87360000,
.mask = 0xff3f0000,
},
/* Die: LS1028A, SoC: LS1028A */
+ [DIE_LS1028A] =
{ .die = "LS1028A",
.svr = 0x870b0000,
.mask = 0xff3f0000,
@@ -109,6 +139,7 @@ static const struct fsl_soc_die_attr fsl_soc_die[] = {
static struct fsl_soc_guts {
struct ccsr_guts __iomem *dcfg_ccsr;
bool little_endian;
+ u32 svr;
} soc;
static unsigned int fsl_guts_read(const void __iomem *reg)
@@ -119,11 +150,16 @@ static unsigned int fsl_guts_read(const void __iomem *reg)
return ioread32be(reg);
}
+static bool fsl_soc_die_match_one(u32 svr, const struct fsl_soc_die_attr *match)
+{
+ return match->svr == (svr & match->mask);
+}
+
static const struct fsl_soc_die_attr *fsl_soc_die_match(
u32 svr, const struct fsl_soc_die_attr *matches)
{
while (matches->svr) {
- if (matches->svr == (svr & matches->mask))
+ if (fsl_soc_die_match_one(svr, matches))
return matches;
matches++;
}
@@ -202,7 +238,6 @@ static int __init fsl_guts_init(void)
const struct of_device_id *match;
struct device_node *np;
u64 soc_uid = 0;
- u32 svr;
int ret;
np = of_find_matching_node_and_match(NULL, fsl_guts_of_match, &match);
@@ -217,7 +252,7 @@ static int __init fsl_guts_init(void)
}
soc.little_endian = of_property_read_bool(np, "little-endian");
- svr = fsl_guts_read(&soc.dcfg_ccsr->svr);
+ soc.svr = fsl_guts_read(&soc.dcfg_ccsr->svr);
of_node_put(np);
/* Register soc device */
@@ -229,7 +264,7 @@ static int __init fsl_guts_init(void)
if (ret)
of_machine_read_compatible(&soc_dev_attr->machine, 0);
- soc_die = fsl_soc_die_match(svr, fsl_soc_die);
+ soc_die = fsl_soc_die_match(soc.svr, fsl_soc_die);
if (soc_die) {
soc_dev_attr->family = kasprintf(GFP_KERNEL, "QorIQ %s",
soc_die->die);
@@ -239,12 +274,12 @@ static int __init fsl_guts_init(void)
if (!soc_dev_attr->family)
goto err_nomem;
- soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "svr:0x%08x", svr);
+ soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "svr:0x%08x", soc.svr);
if (!soc_dev_attr->soc_id)
goto err_nomem;
soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d.%d",
- (svr >> 4) & 0xf, svr & 0xf);
+ (soc.svr >> 4) & 0xf, soc.svr & 0xf);
if (!soc_dev_attr->revision)
goto err_nomem;
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v2 phy-next 3/8] soc: fsl: guts: add a central fsl_guts_read() function
From: Vladimir Oltean @ 2026-06-12 21:08 UTC (permalink / raw)
To: linux-phy
Cc: devicetree, linuxppc-dev, linux-arm-kernel, Ioana Ciornei,
Vinod Koul, Neil Armstrong, Tanjeff Moos,
Christophe Leroy (CS GROUP), Michael Walle, Shawn Guo, Frank Li,
linux-kernel
In-Reply-To: <20260612210859.266759-1-vladimir.oltean@nxp.com>
From: Ioana Ciornei <ioana.ciornei@nxp.com>
Add a central fsl_guts_read() function which will take into account the
endianness that was already determined. No point is duplicating the
if-else statement each time we need to read a DCFG register.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
v1->v2: none
---
drivers/soc/fsl/guts.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
index a0a52a5603a5..dc1a42cd9544 100644
--- a/drivers/soc/fsl/guts.c
+++ b/drivers/soc/fsl/guts.c
@@ -111,6 +111,14 @@ static struct fsl_soc_guts {
bool little_endian;
} soc;
+static unsigned int fsl_guts_read(const void __iomem *reg)
+{
+ if (soc.little_endian)
+ return ioread32(reg);
+
+ return ioread32be(reg);
+}
+
static const struct fsl_soc_die_attr *fsl_soc_die_match(
u32 svr, const struct fsl_soc_die_attr *matches)
{
@@ -209,10 +217,7 @@ static int __init fsl_guts_init(void)
}
soc.little_endian = of_property_read_bool(np, "little-endian");
- if (soc.little_endian)
- svr = ioread32(&soc.dcfg_ccsr->svr);
- else
- svr = ioread32be(&soc.dcfg_ccsr->svr);
+ svr = fsl_guts_read(&soc.dcfg_ccsr->svr);
of_node_put(np);
/* Register soc device */
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v2 phy-next 2/8] soc: fsl: guts: add a global structure to hold state
From: Vladimir Oltean @ 2026-06-12 21:08 UTC (permalink / raw)
To: linux-phy
Cc: devicetree, linuxppc-dev, linux-arm-kernel, Ioana Ciornei,
Vinod Koul, Neil Armstrong, Tanjeff Moos,
Christophe Leroy (CS GROUP), Michael Walle, Shawn Guo, Frank Li,
linux-kernel
In-Reply-To: <20260612210859.266759-1-vladimir.oltean@nxp.com>
From: Ioana Ciornei <ioana.ciornei@nxp.com>
Add the fsl_soc_guts structure in order to pass information like base
addresses, endianness etc between the init time and the runtime
operations (RCW override) which will get added in future patches.
There is no point in mapping and unmapping the DCFG CCSR space every
time we need to make a read, just map it once and keep its reference in
this new global struture.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
v1->v2: none
---
drivers/soc/fsl/guts.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
index f87ee47c1503..a0a52a5603a5 100644
--- a/drivers/soc/fsl/guts.c
+++ b/drivers/soc/fsl/guts.c
@@ -106,6 +106,11 @@ static const struct fsl_soc_die_attr fsl_soc_die[] = {
{ },
};
+static struct fsl_soc_guts {
+ struct ccsr_guts __iomem *dcfg_ccsr;
+ bool little_endian;
+} soc;
+
static const struct fsl_soc_die_attr *fsl_soc_die_match(
u32 svr, const struct fsl_soc_die_attr *matches)
{
@@ -187,9 +192,7 @@ static int __init fsl_guts_init(void)
const struct fsl_soc_die_attr *soc_die;
const struct fsl_soc_data *soc_data;
const struct of_device_id *match;
- struct ccsr_guts __iomem *regs;
struct device_node *np;
- bool little_endian;
u64 soc_uid = 0;
u32 svr;
int ret;
@@ -199,18 +202,17 @@ static int __init fsl_guts_init(void)
return 0;
soc_data = match->data;
- regs = of_iomap(np, DCFG_CCSR);
- if (!regs) {
+ soc.dcfg_ccsr = of_iomap(np, DCFG_CCSR);
+ if (!soc.dcfg_ccsr) {
of_node_put(np);
return -ENOMEM;
}
- little_endian = of_property_read_bool(np, "little-endian");
- if (little_endian)
- svr = ioread32(®s->svr);
+ soc.little_endian = of_property_read_bool(np, "little-endian");
+ if (soc.little_endian)
+ svr = ioread32(&soc.dcfg_ccsr->svr);
else
- svr = ioread32be(®s->svr);
- iounmap(regs);
+ svr = ioread32be(&soc.dcfg_ccsr->svr);
of_node_put(np);
/* Register soc device */
@@ -263,6 +265,8 @@ static int __init fsl_guts_init(void)
err_nomem:
ret = -ENOMEM;
+
+ iounmap(soc.dcfg_ccsr);
err:
kfree(soc_dev_attr->family);
kfree(soc_dev_attr->soc_id);
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v2 phy-next 0/8] RCW override for 10G Lynx dynamic protocol reconfiguration
From: Vladimir Oltean @ 2026-06-12 21:08 UTC (permalink / raw)
To: linux-phy
Cc: devicetree, linuxppc-dev, linux-arm-kernel, Ioana Ciornei,
Vinod Koul, Neil Armstrong, Tanjeff Moos,
Christophe Leroy (CS GROUP), Michael Walle, Shawn Guo, Frank Li,
linux-kernel, Conor Dooley, Krzysztof Kozlowski, Rob Herring
Previous set "New Generic PHY driver for Lynx 10G SerDes":
https://lore.kernel.org/linux-phy/20260610151952.2141019-1-vladimir.oltean@nxp.com/
introduced the 10G Lynx SerDes driver with a reduced functionality set.
Namely, only minor protocol changes are supported (1GbE <-> 2.5GbE).
The major protocol changes need a procedure named RCW override,
explained in more detail in commits 6/8 and 7/8.
This series adds kernel and device tree binding support for RCW
override, completing the SerDes PHY driver functionality.
Two components are involved:
- drivers/soc/fsl/guts.c (binding is fsl,layerscape-dcfg.yaml) - Device
Configuration Unit, this is API provider for the SerDes driver to
request RCW override depending on SoC
- drivers/phy/freescale/phy-fsl-lynx-10g.c - SerDes PHY driver, this is
API consumer
The guts driver probes on DCFG blocks from multiple Freescale SoC
generations:
- MPC85xx, BSC and QorIQ (PowerPC) are all covered by the
Documentation/devicetree/bindings/soc/fsl/guts.txt schema
- Layerscape (Arm) is covered by
Documentation/devicetree/bindings/soc/fsl/fsl,layerscape-dcfg.yaml
It is ultimately the same hardware block, just that (from what I can
tell) the Layerscape nodes are also compatible with syscon, and PowerPC
aren't.
RCW override has only been validated on select Layerscape SoCs, so
converting guts.txt to a PowerPC schema is out of scope for this
series - we don't even touch that (just in case it gets asked).
Using syscon to map the DCFG_DCSR register block in the Lynx SerDes
driver instead of creating this guts <-> lynx API was considered, but
because the RCW procedure is SoC-specific, it was ruled out for
polluting the SerDes driver. The guts driver is all about SoC awareness
anyway, and it offers some abstraction of all the gory details.
Resending because Sashiko didn't run on v1 (it runs on linux-phy/master
instead of linux-phy/next, and linux-next, used as fallback when
applying to linux-phy/master fails, wasn't regenerated to include the
Lynx 10G base patches at the time v1 was sent). There was a build
failure on most arches except arm64 anyway, so it's good to have that
fixed.
Changes since v1:
- add Conor's review tag on 6/8
- update email addresses of DT maintainers
- drop DT maintainers from explicit CC on patch 7/8
- keep devicetree@vger.kernel.org CCed on entire series
- include missing <linux/bitfield.h> in patch 7/8
- namespace SRDS_PRTCL values for LS1046A and LS1088A, even if they are
the same. For LS1028A (not covered here) they are not.
- prefix SRDS_CLK_SEL_{GMII,XGMII} with LS2088A_
- reorder alphanumerically (LS1046A should come before LS1088A)
Change log also in individual patches.
v1 at:
https://lore.kernel.org/linux-phy/20260611193940.44416-1-vladimir.oltean@nxp.com/
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Rob Herring <robh@kernel.org>
Ioana Ciornei (5):
soc: fsl: guts: use a macro to encode the DCFG CCSR space
soc: fsl: guts: add a global structure to hold state
soc: fsl: guts: add a central fsl_guts_read() function
soc: fsl: guts: make it easier to determine on which SoC we are
running
soc: fsl: guts: implement the RCW override procedure
Vladimir Oltean (3):
soc: fsl: guts: make fsl_soc_data available after fsl_guts_init()
dt-bindings: fsl: layerscape-dcfg: define DCFG_DCSR region
phy: lynx-10g: use RCW override procedure for dynamic protocol change
.../bindings/soc/fsl/fsl,layerscape-dcfg.yaml | 15 +-
drivers/phy/freescale/Kconfig | 1 +
drivers/phy/freescale/phy-fsl-lynx-10g.c | 24 +-
drivers/soc/fsl/guts.c | 369 ++++++++++++++++--
include/linux/fsl/guts.h | 20 +-
5 files changed, 393 insertions(+), 36 deletions(-)
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v2 phy-next 1/8] soc: fsl: guts: use a macro to encode the DCFG CCSR space
From: Vladimir Oltean @ 2026-06-12 21:08 UTC (permalink / raw)
To: linux-phy
Cc: devicetree, linuxppc-dev, linux-arm-kernel, Ioana Ciornei,
Vinod Koul, Neil Armstrong, Tanjeff Moos,
Christophe Leroy (CS GROUP), Michael Walle, Shawn Guo, Frank Li,
linux-kernel
In-Reply-To: <20260612210859.266759-1-vladimir.oltean@nxp.com>
From: Ioana Ciornei <ioana.ciornei@nxp.com>
Instead of using a hardcoded value when iomapping the DCFG CCSR space,
add a new macro for it. The code will be easier to follow this way,
especially when we add support for the DCFG DCSR space as well.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
v1->v2: none
---
drivers/soc/fsl/guts.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
index 9bee7baec2b9..f87ee47c1503 100644
--- a/drivers/soc/fsl/guts.c
+++ b/drivers/soc/fsl/guts.c
@@ -14,6 +14,8 @@
#include <linux/platform_device.h>
#include <linux/fsl/guts.h>
+#define DCFG_CCSR 0
+
struct fsl_soc_die_attr {
char *die;
u32 svr;
@@ -197,7 +199,7 @@ static int __init fsl_guts_init(void)
return 0;
soc_data = match->data;
- regs = of_iomap(np, 0);
+ regs = of_iomap(np, DCFG_CCSR);
if (!regs) {
of_node_put(np);
return -ENOMEM;
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* Re: [PATCH v1 phy-next 7/8] soc: fsl: guts: implement the RCW override procedure
From: Vladimir Oltean @ 2026-06-12 20:25 UTC (permalink / raw)
To: Conor Dooley
Cc: linux-phy, devicetree, linuxppc-dev, linux-arm-kernel,
Ioana Ciornei, Vinod Koul, Neil Armstrong, Tanjeff Moos,
Christophe Leroy (CS GROUP), Michael Walle, Shawn Guo, Frank Li,
linux-kernel, Krzysztof Kozlowski, Rob Herring
In-Reply-To: <20260612-twenty-diary-4aab5327f9c2@spud>
On Fri, Jun 12, 2026 at 04:44:30PM +0100, Conor Dooley wrote:
> On Thu, Jun 11, 2026 at 10:39:39PM +0300, Vladimir Oltean wrote:
> > From: Ioana Ciornei <ioana.ciornei@nxp.com>
> >
> > Add support for the RCW override procedure which enables runtime
> > reconfiguration of the protocol running on a SerDes lane. The procedure
> > is done through the DCFG DCSR space which now can be defined as the
> > second memory region of the guts DT node.
> > Support is added on the following SoCs: LS1046A, LS1088A, LS2088A.
> >
> > The procedure is exported to the "client" driver - the Lynx10G SerDes
> > PHY driver - through the following functions:
> > - fsl_guts_lane_init() used to notify the initial / boot time lane mode
> > running on a SerDes lane.
> > - fsl_guts_lane_validate() used to validate that changing the protocol
> > on a specific lane is supported.
> > - fsl_guts_lane_set_mode() which can be used to request the RCW
> > procedure be executed for a specific lane.
> >
> > Since the RCW override procedure is different depending on the SoC, the
> > private fsl_soc_data structure is updated with two new per SoC callbacks
> > (.serdes_get_rcw_override() and .serdes_init_rcwcr()) which get used
> > from the generic fsl_guts_lane_set_mode() function. These two callbacks
> > hide all the SoC specific register offsets, masks and values so that the
> > _set_mode() procedure is straightforward.
> >
> > Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
> > Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
> > ---
> > Cc: Conor Dooley <conor@kernel.org>
> > Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
> > Cc: Rob Herring <robh@kernel.org>
> > Cc: devicetree@vger.kernel.org
>
> Wrong CC list for this specific patch?
No, it was intentional. Provided for context, so DT reviewers can check
that extra properties not defined in the schema aren't being used.
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v1 phy-next 6/8] dt-bindings: fsl: layerscape-dcfg: define DCFG_DCSR region
From: Vladimir Oltean @ 2026-06-12 20:23 UTC (permalink / raw)
To: Conor Dooley
Cc: linux-phy, devicetree, linuxppc-dev, linux-arm-kernel,
Ioana Ciornei, Vinod Koul, Neil Armstrong, Tanjeff Moos,
Christophe Leroy (CS GROUP), Michael Walle, Shawn Guo, Frank Li,
linux-kernel, Krzysztof Kozlowski, Rob Herring
In-Reply-To: <20260612-graveyard-hacked-c65d54a1ece8@spud>
On Fri, Jun 12, 2026 at 04:44:00PM +0100, Conor Dooley wrote:
> On Thu, Jun 11, 2026 at 10:39:38PM +0300, Vladimir Oltean wrote:
> > In Layerscape (Arm) and QorIQ (PowerPC) devices, hardware peripherals
> > are accessed by the CPU through a portion of the SoC address space
> > called CCSR ("Configuration, Control, and Status Registers"). All
> > hardware IP blocks have their registers mapped here, and the Device
> > Configuration block makes no exception.
> >
> > However, there exists a secondary range of the address space named DCSR
> > ("Debug Control and Status Registers") which, like CCSR, also holds
> > registers of hardware IP blocks, except the DCSR contents is hidden in
> > all public reference manuals.
> >
> > The intention of the CCSR/DCSR split, to the best of my knowledge, was
> > to place the functionality that is too low level for normal use, and
> > which is necessary only for debug, in a completely separate address
> > space which can be hidden.
> >
> > A use case has appeared where networking SerDes lanes need to be
> > reconfigured at runtime for a different protocol (example: 10GBase-R to
> > SGMII), and the architecture of the SoCs does not normally permit that.
> > The Reset Configuration Word (RCW) is a data structure read by the SoC
> > preboot loader (PBL) which contains stuff like pinmuxing and SerDes
> > protocol mapping for each lane.
> >
> > The RCW that the PBL has loaded is visible in the DCFG block's normal
> > status registers (from CCSR), as read only. Turns out, the RCW is also
> > mapped in the DCFG's shadow register map (in DCSR), in a write-only
> > form. Writing to the RCW registers from the DCFG's DCSR space to change
> > what the PBL has loaded is called "RCW override".
> >
> > It has been validated that the RCW override procedure is necessary to
> > reconfigure the networking data path when a SerDes lane performs a major
> > protocol change. It changes some internal muxes which connect the PCS to
> > either the 10G MAC or to the 1G MAC.
> >
> > Defining the DCSR area of the DCFG as a secondary 'reg' array element
> > allows operating systems to perform RCW overrides. Since it is
> > introduced late in the binding's lifetime, it is optional. It can be
> > identified by name, but also by index (first 'reg' is CCSR).
> >
> > Note that while all SoCs should have a DCFG register block in DCSR, we
> > only need to expose it for the SoCs where the RCW override procedure is
> > known to be needed and has been validated.
> >
> > Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
> > ---
> > Cc: Conor Dooley <conor@kernel.org>
>
> Where did this email come from btw? get_maintainer.pl result should have
> +dt in it.
Historical data. I am keeping all sorts of commands (here git send-email)
in *.txt files and that's where I got the stale email addresses from.
Krzysztof's is also bouncing. Will fix for v2.
> Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
> pw-bot: not-applicable
Thanks for the review!
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v6 5/5] arm64: dts: qcom: Add Shikra EVK boards
From: sashiko-bot @ 2026-06-12 17:36 UTC (permalink / raw)
To: Komal Bajaj
Cc: robh, vkoul, linux-phy, devicetree, neil.armstrong, conor+dt,
olteanv
In-Reply-To: <20260612-shikra-dt-v6-5-6b6cb58db477@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] `shikra-cqs-evk.dts` incorrectly includes `shikra-cqm-som.dtsi` instead of a CQS-specific SoM file.
--
commit 0c4f6d07dd3b32da53231a5dcf3de036bb58f76f
Author: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
arm64: dts: qcom: Add Shikra EVK boards
This commit adds device trees for the Shikra EVK platform, introducing
three board variants paired with a common carrier board. It includes
configurations for retail and industrial SoMs, both with and without
modems.
[ ... ]
> diff --git a/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts b/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts
> new file mode 100644
> index 0000000000000..b3f19a64d7aed
> --- /dev/null
> +++ b/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts
> @@ -0,0 +1,40 @@
> +// SPDX-License-Identifier: BSD-3-Clause
> +/*
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +
> +/dts-v1/;
> +
> +#include "shikra-cqm-som.dtsi"
[Severity: Medium]
Is this the intended include for the CQS board?
The commit message indicates the CQS board pairs with the CQ2390S SoM
(without modem), but this includes the CQM (with modem) SoM definition.
If modem-specific nodes are later added to shikra-cqm-som.dtsi, wouldn't
they inadvertently be applied to this modem-less CQS variant?
> +#include "shikra-evk.dtsi"
> +
> +/ {
> + model = "Qualcomm Technologies, Inc. Shikra CQS EVK";
> + compatible = "qcom,shikra-cqs-evk", "qcom,shikra-cqs-som", "qcom,shikra";
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260612-shikra-dt-v6-0-6b6cb58db477@oss.qualcomm.com?part=5
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v6 5/5] arm64: dts: qcom: Add Shikra EVK boards
From: Komal Bajaj @ 2026-06-12 17:27 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vinod Koul, Neil Armstrong, Wesley Cheng,
Ulf Hansson
Cc: linux-arm-msm, devicetree, linux-kernel, linux-phy, linux-mmc,
monish.chunara, Komal Bajaj, Imran Shaik, Monish Chunara,
Rakesh Kota, Raviteja Laggyshetty, Sneh Mankad, Vishnu Santhosh,
Xueyao An, Konrad Dybcio
In-Reply-To: <20260612-shikra-dt-v6-0-6b6cb58db477@oss.qualcomm.com>
Add device trees for the Shikra EVK platform, which combines each
of Shikra SoM variant with a common carrier board.
Three EVK boards are introduced:
- shikra-cqm-evk.dts: pairs with CQ2390M SoM (retail, with modem)
- shikra-cqs-evk.dts: pairs with CQ2390S SoM (retail, without modem)
- shikra-iqs-evk.dts: pairs with IQ2390S SoM (industrial, without modem)
Also add shikra-evk.dtsi, it represents the common carrier-board and
daughter-card configuration shared across all Shikra EVK variants.
Co-developed-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
Co-developed-by: Monish Chunara <quic_mchunara@quicinc.com>
Signed-off-by: Monish Chunara <quic_mchunara@quicinc.com>
Co-developed-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>
Signed-off-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>
Co-developed-by: Raviteja Laggyshetty <raviteja.laggyshetty@oss.qualcomm.com>
Signed-off-by: Raviteja Laggyshetty <raviteja.laggyshetty@oss.qualcomm.com>
Co-developed-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
Signed-off-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
Co-developed-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
Signed-off-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
Co-developed-by: Xueyao An <xueyao.an@oss.qualcomm.com>
Signed-off-by: Xueyao An <xueyao.an@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/Makefile | 3 +++
arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts | 40 +++++++++++++++++++++++++++++
arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts | 40 +++++++++++++++++++++++++++++
arch/arm64/boot/dts/qcom/shikra-evk.dtsi | 15 +++++++++++
arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts | 40 +++++++++++++++++++++++++++++
5 files changed, 138 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 6f33c4e2f09c..a9e9d829fb96 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -334,6 +334,9 @@ dtb-$(CONFIG_ARCH_QCOM) += sdm850-huawei-matebook-e-2019.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdm850-lenovo-yoga-c630.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdm850-samsung-w737.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdx75-idp.dtb
+dtb-$(CONFIG_ARCH_QCOM) += shikra-cqm-evk.dtb
+dtb-$(CONFIG_ARCH_QCOM) += shikra-cqs-evk.dtb
+dtb-$(CONFIG_ARCH_QCOM) += shikra-iqs-evk.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm4250-oneplus-billie2.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm4450-qrd.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm6115-fxtec-pro1x.dtb
diff --git a/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts b/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts
new file mode 100644
index 000000000000..0a52ab9b7a4c
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+/dts-v1/;
+
+#include "shikra-cqm-som.dtsi"
+#include "shikra-evk.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. Shikra CQM EVK";
+ compatible = "qcom,shikra-cqm-evk", "qcom,shikra-cqm-som", "qcom,shikra";
+ chassis-type = "embedded";
+
+ aliases {
+ mmc0 = &sdhc_1;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&sdhc_1 {
+ vmmc-supply = <&pm4125_l20>;
+ vqmmc-supply = <&pm4125_l14>;
+
+ pinctrl-0 = <&sdc1_state_on>;
+ pinctrl-1 = <&sdc1_state_off>;
+ pinctrl-names = "default", "sleep";
+
+ non-removable;
+ supports-cqe;
+ no-sdio;
+ no-sd;
+
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts b/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts
new file mode 100644
index 000000000000..b3f19a64d7ae
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+/dts-v1/;
+
+#include "shikra-cqm-som.dtsi"
+#include "shikra-evk.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. Shikra CQS EVK";
+ compatible = "qcom,shikra-cqs-evk", "qcom,shikra-cqs-som", "qcom,shikra";
+ chassis-type = "embedded";
+
+ aliases {
+ mmc0 = &sdhc_1;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&sdhc_1 {
+ vmmc-supply = <&pm4125_l20>;
+ vqmmc-supply = <&pm4125_l14>;
+
+ pinctrl-0 = <&sdc1_state_on>;
+ pinctrl-1 = <&sdc1_state_off>;
+ pinctrl-names = "default", "sleep";
+
+ non-removable;
+ supports-cqe;
+ no-sdio;
+ no-sd;
+
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/shikra-evk.dtsi b/arch/arm64/boot/dts/qcom/shikra-evk.dtsi
new file mode 100644
index 000000000000..d0c48bad704c
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/shikra-evk.dtsi
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+&qupv3_0 {
+ firmware-name = "qcom/shikra/qupv3fw.elf";
+
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
diff --git a/arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts b/arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts
new file mode 100644
index 000000000000..3003a47bd759
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+/dts-v1/;
+
+#include "shikra-iqs-som.dtsi"
+#include "shikra-evk.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. Shikra IQS EVK";
+ compatible = "qcom,shikra-iqs-evk", "qcom,shikra-iqs-som", "qcom,shikra";
+ chassis-type = "embedded";
+
+ aliases {
+ mmc0 = &sdhc_1;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&sdhc_1 {
+ vmmc-supply = <&pm8150_l17>;
+ vqmmc-supply = <&pm8150_s4>;
+
+ pinctrl-0 = <&sdc1_state_on>;
+ pinctrl-1 = <&sdc1_state_off>;
+ pinctrl-names = "default", "sleep";
+
+ non-removable;
+ supports-cqe;
+ no-sdio;
+ no-sd;
+
+ status = "okay";
+};
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v6 4/5] arm64: dts: qcom: Add Shikra IQ2390S SoM platform
From: Komal Bajaj @ 2026-06-12 17:27 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vinod Koul, Neil Armstrong, Wesley Cheng,
Ulf Hansson
Cc: linux-arm-msm, devicetree, linux-kernel, linux-phy, linux-mmc,
monish.chunara, Komal Bajaj, Dmitry Baryshkov
In-Reply-To: <20260612-shikra-dt-v6-0-6b6cb58db477@oss.qualcomm.com>
Add device tree include for the IQ2390S variant of the Shikra
System-on-Module, an industrial compute module integrating the Shikra
SoC and PMIC for industrial IoT applications, designed to mount on
carrier boards.
- shikra-iqs-som.dtsi: Industrial SoM without modem (PM8150 PMIC)
The DTSI includes the common shikra.dtsi and adds PM8150 PMIC regulator
definitions specific to this variant.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/shikra-iqs-som.dtsi | 170 +++++++++++++++++++++++++++
1 file changed, 170 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/shikra-iqs-som.dtsi b/arch/arm64/boot/dts/qcom/shikra-iqs-som.dtsi
new file mode 100644
index 000000000000..73945bf42112
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/shikra-iqs-som.dtsi
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+
+#include "shikra.dtsi"
+#include "pm8150.dtsi"
+
+/ {
+ gpio-key {
+ compatible = "gpio-keys";
+ label = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&vol_up_n>;
+
+ key-volume-up {
+ label = "Volume Up";
+ gpios = <&pm8150_gpios 6 GPIO_ACTIVE_LOW>;
+ linux,input-type = <1>;
+ linux,code = <KEY_VOLUMEUP>;
+ wakeup-source;
+ debounce-interval = <15>;
+ linux,can-disable;
+ };
+ };
+};
+
+&pm8150_gpios {
+ vol_up_n: vol-up-n-state {
+ pins = "gpio6";
+ function = PMIC_GPIO_FUNC_NORMAL;
+ input-enable;
+ bias-pull-up;
+ power-source = <0>;
+ };
+
+};
+
+&pon_pwrkey {
+ status = "okay";
+};
+
+&pon_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ status = "okay";
+};
+
+&rpm_requests {
+ regulators {
+ compatible = "qcom,rpm-pm8150-regulators";
+
+ pm8150_s4: s4 {
+ regulator-min-microvolt = <1080000>;
+ regulator-max-microvolt = <2040000>;
+ };
+
+ pm8150_s5: s5 {
+ regulator-min-microvolt = <1574000>;
+ regulator-max-microvolt = <2040000>;
+ };
+
+ pm8150_s6: s6 {
+ regulator-min-microvolt = <382000>;
+ regulator-max-microvolt = <1352000>;
+ };
+
+ pm8150_s7: s7 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm8150_s8: s8 {
+ regulator-min-microvolt = <570000>;
+ regulator-max-microvolt = <650000>;
+ };
+
+ pm8150_l1: l1 {
+ regulator-min-microvolt = <312000>;
+ regulator-max-microvolt = <1304000>;
+ };
+
+ pm8150_l2: l2 {
+ regulator-min-microvolt = <1650000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ pm8150_l3: l3 {
+ regulator-min-microvolt = <312000>;
+ regulator-max-microvolt = <1304000>;
+ };
+
+ pm8150_l4: l4 {
+ regulator-min-microvolt = <875000>;
+ regulator-max-microvolt = <975000>;
+ };
+
+ pm8150_l5: l5 {
+ regulator-min-microvolt = <788000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ pm8150_l6: l6 {
+ regulator-min-microvolt = <875000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ pm8150_l7: l7 {
+ regulator-min-microvolt = <1504000>;
+ regulator-max-microvolt = <2000000>;
+ };
+
+ pm8150_l8: l8 {
+ regulator-min-microvolt = <1150000>;
+ regulator-max-microvolt = <1304000>;
+ };
+
+ pm8150_l9: l9 {
+ regulator-min-microvolt = <875000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ pm8150_l10: l10 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3544000>;
+ };
+
+ pm8150_l11: l11 {
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1304000>;
+ };
+
+ pm8150_l12: l12 {
+ regulator-min-microvolt = <1650000>;
+ regulator-max-microvolt = <1950000>;
+ };
+
+ pm8150_l13: l13 {
+ regulator-min-microvolt = <2921000>;
+ regulator-max-microvolt = <3230000>;
+ };
+
+ pm8150_l14: l14 {
+ regulator-min-microvolt = <1700000>;
+ regulator-max-microvolt = <1910000>;
+ };
+
+ pm8150_l15: l15 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1900000>;
+ };
+
+ pm8150_l16: l16 {
+ regulator-min-microvolt = <1504000>;
+ regulator-max-microvolt = <3544000>;
+ };
+
+ pm8150_l17: l17 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3544000>;
+ };
+
+ pm8150_l18: l18 {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <728000>;
+ };
+ };
+};
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v6 3/5] arm64: dts: qcom: Add Shikra CQ2390M SoM platform
From: Komal Bajaj @ 2026-06-12 17:27 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vinod Koul, Neil Armstrong, Wesley Cheng,
Ulf Hansson
Cc: linux-arm-msm, devicetree, linux-kernel, linux-phy, linux-mmc,
monish.chunara, Komal Bajaj, Rakesh Kota, Dmitry Baryshkov
In-Reply-To: <20260612-shikra-dt-v6-0-6b6cb58db477@oss.qualcomm.com>
Add device tree include for the CQ2390M variant of the Shikra
System-on-Module, a compact compute module integrating the Shikra SoC
and PMIC for IoT applications, designed to mount on carrier boards.
- shikra-cqm-som.dtsi: Retail SoM with modem (PM4125 and PM8005 PMIC)
The DTSI includes the common shikra.dtsi, adds PM4125 and PM8005 PMIC
peripheral definitions specific to this variant. Since PM8005 regulators
are controlled by rpmpd, so disabling the pm8005 regulators.
Co-developed-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>
Signed-off-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi | 156 +++++++++++++++++++++++++++
1 file changed, 156 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi b/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi
new file mode 100644
index 000000000000..dc3861489f64
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+
+#include "shikra.dtsi"
+#include "pm4125.dtsi"
+#include "pm8005.dtsi"
+
+/ {
+ gpio-keys {
+ compatible = "gpio-keys";
+ label = "gpio-keys";
+ pinctrl-0 = <&vol_up_n>;
+ pinctrl-names = "default";
+
+ key-volume-up {
+ label = "Volume Up";
+ gpios = <&pm4125_gpios 9 GPIO_ACTIVE_LOW>;
+ linux,input-type = <1>;
+ linux,code = <KEY_VOLUMEUP>;
+ wakeup-source;
+ debounce-interval = <15>;
+ linux,can-disable;
+ };
+ };
+};
+
+&pm4125_gpios {
+ vol_up_n: vol-up-n-state {
+ pins = "gpio9";
+ function = PMIC_GPIO_FUNC_NORMAL;
+ input-enable;
+ bias-pull-up;
+ power-source = <0>;
+ };
+};
+
+&pm4125_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+
+ status = "okay";
+};
+
+&pm8005_regulators {
+ status = "disabled";
+};
+
+&rpm_requests {
+ regulators {
+ compatible = "qcom,rpm-pm2250-regulators";
+
+ pm4125_s2: s2 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm4125_l3: l3 {
+ regulator-min-microvolt = <624000>;
+ regulator-max-microvolt = <650000>;
+ };
+
+ pm4125_l4: l4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2960000>;
+ };
+
+ pm4125_l5: l5 {
+ regulator-min-microvolt = <1232000>;
+ regulator-max-microvolt = <1304000>;
+ };
+
+ pm4125_l6: l6 {
+ regulator-min-microvolt = <788000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ pm4125_l7: l7 {
+ regulator-min-microvolt = <664000>;
+ regulator-max-microvolt = <664000>;
+ };
+
+ pm4125_l8: l8 {
+ regulator-min-microvolt = <928000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ pm4125_l9: l9 {
+ regulator-min-microvolt = <875000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ pm4125_l10: l10 {
+ regulator-min-microvolt = <1304000>;
+ regulator-max-microvolt = <1304000>;
+ };
+
+ pm4125_l12: l12 {
+ regulator-min-microvolt = <928000>;
+ regulator-max-microvolt = <975000>;
+ };
+
+ pm4125_l13: l13 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm4125_l14: l14 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm4125_l15: l15 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm4125_l16: l16 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm4125_l17: l17 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3544000>;
+ };
+
+ pm4125_l18: l18 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2960000>;
+ };
+
+ pm4125_l19: l19 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2960000>;
+ };
+
+ pm4125_l20: l20 {
+ regulator-min-microvolt = <2952000>;
+ regulator-max-microvolt = <2952000>;
+ };
+
+ pm4125_l21: l21 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3056000>;
+ };
+
+ pm4125_l22: l22 {
+ regulator-min-microvolt = <3304000>;
+ regulator-max-microvolt = <3304000>;
+ };
+ };
+};
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v6 2/5] arm64: dts: qcom: Introduce Shikra SoC base dtsi
From: Komal Bajaj @ 2026-06-12 17:27 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vinod Koul, Neil Armstrong, Wesley Cheng,
Ulf Hansson
Cc: linux-arm-msm, devicetree, linux-kernel, linux-phy, linux-mmc,
monish.chunara, Komal Bajaj, Imran Shaik, Monish Chunara,
Rakesh Kota, Raviteja Laggyshetty, Sneh Mankad, Vishnu Santhosh,
Xueyao An, Konrad Dybcio
In-Reply-To: <20260612-shikra-dt-v6-0-6b6cb58db477@oss.qualcomm.com>
Add initial device tree support for the Qualcomm Shikra SoC,
an IoT-focused platform built around a heterogeneous CPU cluster
(Cortex-A55 + Cortex-A78C) with RPM-based power and clock management.
Enable support for the following peripherals:
- CPU nodes
- Global Clock Controller (GCC)
- RPM-based clock controller (RPMCC) and power domains (RPMPD)
- Interrupt controller
- Top Level Mode Multiplexer (TLMM)
- Debug UART
- eMMC host controller
- System timer and watchdog
Co-developed-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
Co-developed-by: Monish Chunara <quic_mchunara@quicinc.com>
Signed-off-by: Monish Chunara <quic_mchunara@quicinc.com>
Co-developed-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>
Signed-off-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>
Co-developed-by: Raviteja Laggyshetty <raviteja.laggyshetty@oss.qualcomm.com>
Signed-off-by: Raviteja Laggyshetty <raviteja.laggyshetty@oss.qualcomm.com>
Co-developed-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
Signed-off-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
Co-developed-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
Signed-off-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
Co-developed-by: Xueyao An <xueyao.an@oss.qualcomm.com>
Signed-off-by: Xueyao An <xueyao.an@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/shikra.dtsi | 842 +++++++++++++++++++++++++++++++++++
1 file changed, 842 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/shikra.dtsi b/arch/arm64/boot/dts/qcom/shikra.dtsi
new file mode 100644
index 000000000000..4e5bc9e17c8e
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/shikra.dtsi
@@ -0,0 +1,842 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <dt-bindings/clock/qcom,rpmcc.h>
+#include <dt-bindings/clock/qcom,shikra-gcc.h>
+#include <dt-bindings/interconnect/qcom,icc.h>
+#include <dt-bindings/interconnect/qcom,rpm-icc.h>
+#include <dt-bindings/interconnect/qcom,shikra.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+
+/ {
+ interrupt-parent = <&intc>;
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ clocks {
+ xo_board: xo-board {
+ compatible = "fixed-clock";
+ clock-frequency = <38400000>;
+ #clock-cells = <0>;
+ };
+
+ sleep_clk: sleep-clk {
+ compatible = "fixed-clock";
+ clock-frequency = <32764>;
+ #clock-cells = <0>;
+ };
+ };
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ next-level-cache = <&l3>;
+ capacity-dmips-mhz = <1024>;
+ dynamic-power-coefficient = <100>;
+ };
+
+ cpu1: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x0 0x100>;
+ enable-method = "psci";
+ next-level-cache = <&l3>;
+ capacity-dmips-mhz = <1024>;
+ dynamic-power-coefficient = <100>;
+ };
+
+ cpu2: cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x0 0x200>;
+ enable-method = "psci";
+ next-level-cache = <&l3>;
+ capacity-dmips-mhz = <1024>;
+ dynamic-power-coefficient = <100>;
+ };
+
+ cpu3: cpu@300 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a78c";
+ reg = <0x0 0x300>;
+ enable-method = "psci";
+ next-level-cache = <&l2_3>;
+ capacity-dmips-mhz = <1946>;
+ dynamic-power-coefficient = <489>;
+
+ l2_3: l2-cache {
+ compatible = "cache";
+ cache-level = <2>;
+ cache-unified;
+ next-level-cache = <&l3>;
+ cache-size = <0x40000>;
+ };
+ };
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&cpu0>;
+ };
+
+ core1 {
+ cpu = <&cpu1>;
+ };
+
+ core2 {
+ cpu = <&cpu2>;
+ };
+ };
+
+ cluster1 {
+ core0 {
+ cpu = <&cpu3>;
+ };
+ };
+ };
+
+ l3: l3-cache {
+ compatible = "cache";
+ cache-level = <3>;
+ cache-unified;
+ cache-size = <0x80000>;
+ };
+ };
+
+ firmware {
+ scm {
+ compatible = "qcom,scm-shikra", "qcom,scm";
+ clocks = <&rpmcc RPM_SMD_CE1_CLK>;
+ clock-names = "core";
+ qcom,dload-mode = <&tcsr_regs 0x13000>;
+ #reset-cells = <1>;
+ interconnects = <&system_noc MASTER_CRYPTO_CORE0 RPM_ALWAYS_TAG
+ &mc_virt SLAVE_EBI_CH0 RPM_ALWAYS_TAG>;
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ /* We expect the bootloader to fill in the size */
+ reg = <0x0 0x80000000 0x0 0x0>;
+ };
+
+ pmu-a55 {
+ compatible = "arm,cortex-a55-pmu";
+ interrupts = <GIC_PPI 5 IRQ_TYPE_LEVEL_HIGH &ppi_cluster0>;
+ };
+
+ pmu-a78c {
+ compatible = "arm,cortex-a78-pmu";
+ interrupts = <GIC_PPI 5 IRQ_TYPE_LEVEL_HIGH &ppi_cluster1>;
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ rpm: remoteproc {
+ compatible = "qcom,shikra-rpm-proc", "qcom,rpm-proc";
+
+ glink-edge {
+ compatible = "qcom,glink-rpm";
+ interrupts = <GIC_SPI 194 IRQ_TYPE_EDGE_RISING 0>;
+ qcom,rpm-msg-ram = <&rpm_msg_ram>;
+ mboxes = <&apcs_glb 0>;
+
+ rpm_requests: rpm-requests {
+ compatible = "qcom,rpm-shikra", "qcom,glink-smd-rpm";
+ qcom,glink-channels = "rpm_requests";
+
+ rpmcc: clock-controller {
+ compatible = "qcom,rpmcc-shikra", "qcom,rpmcc-qcm2290", "qcom,rpmcc";
+ clocks = <&xo_board>;
+ clock-names = "xo";
+ #clock-cells = <1>;
+ };
+
+ rpmpd: power-controller {
+ compatible = "qcom,shikra-rpmpd";
+ #power-domain-cells = <1>;
+ operating-points-v2 = <&rpmpd_opp_table>;
+
+ rpmpd_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ rpmpd_opp_min_svs: opp1 {
+ opp-level = <RPM_SMD_LEVEL_MIN_SVS>;
+ };
+
+ rpmpd_opp_low_svs: opp2 {
+ opp-level = <RPM_SMD_LEVEL_LOW_SVS>;
+ };
+
+ rpmpd_opp_svs: opp3 {
+ opp-level = <RPM_SMD_LEVEL_SVS>;
+ };
+
+ rpmpd_opp_svs_plus: opp4 {
+ opp-level = <RPM_SMD_LEVEL_SVS_PLUS>;
+ };
+
+ rpmpd_opp_nom: opp5 {
+ opp-level = <RPM_SMD_LEVEL_NOM>;
+ };
+
+ rpmpd_opp_nom_plus: opp6 {
+ opp-level = <RPM_SMD_LEVEL_NOM_PLUS>;
+ };
+
+ rpmpd_opp_turbo: opp7 {
+ opp-level = <RPM_SMD_LEVEL_TURBO>;
+ };
+
+ rpmpd_opp_turbo_plus: opp8 {
+ opp-level = <RPM_SMD_LEVEL_TURBO_NO_CPR>;
+ };
+ };
+ };
+ };
+ };
+
+ mpm: interrupt-controller {
+ compatible = "qcom,mpm";
+ qcom,rpm-msg-ram = <&apss_mpm>;
+ interrupts = <GIC_SPI 197 IRQ_TYPE_EDGE_RISING 0>;
+ mboxes = <&apcs_glb 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ #power-domain-cells = <0>;
+ interrupt-parent = <&intc>;
+ qcom,mpm-pin-count = <96>;
+ qcom,mpm-pin-map = <2 275>, /* TSENS0 uplow */
+ <12 422>, /* DWC3 ss_phy_irq */
+ <58 272>, /* QUSB2_PHY dmse_hv_vddmx */
+ <59 273>, /* QUSB2_PHY dpse_hv_vddmx */
+ <86 183>, /* MPM wake, SPMI */
+ <90 157>, /* QUSB2_PHY DM */
+ <91 158>; /* QUSB2_PHY DP */
+ };
+ };
+
+ reserved_memory: reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ hyp_mem: hyp@80000000 {
+ reg = <0x0 0x80000000 0x0 0x1600000>;
+ no-map;
+ };
+
+ xblboot_mem: xblboot@85e00000 {
+ reg = <0x0 0x85e00000 0x0 0x100000>;
+ no-map;
+ };
+
+ secdata_apss_mem: secdata-apss@85fff000 {
+ reg = <0x0 0x85fff000 0x0 0x1000>;
+ no-map;
+ };
+
+ smem_mem: smem@86000000 {
+ compatible = "qcom,smem";
+ reg = <0x0 0x86000000 0x0 0x200000>;
+ no-map;
+
+ hwlocks = <&tcsr_mutex 3>;
+ };
+
+ audio_heap_mem: audio-heap@86200000 {
+ reg = <0x0 0x86200000 0x0 0x100000>;
+ no-map;
+ };
+
+ tz_stat_mem: tz-stat@a0000000 {
+ reg = <0x0 0xa0000000 0x0 0x100000>;
+ no-map;
+ };
+
+ qtee_mem: qtee@a1300000 {
+ reg = <0x0 0xa1300000 0x0 0x500000>;
+ no-map;
+ };
+
+ tz_apps_mem: tz-apps@a1800000 {
+ reg = <0x0 0xa1800000 0x0 0x2100000>;
+ no-map;
+ };
+
+ mpss_wlan_mem: mpss-wlan@ab000000 {
+ reg = <0x0 0xab000000 0x0 0x6e00000>;
+ no-map;
+ };
+
+ wlan_mem: wlan@b2300000 {
+ reg = <0x0 0xb2300000 0x0 0x100000>;
+ no-map;
+ };
+
+ cdsp_mem: cdsp@b2400000 {
+ reg = <0x0 0xb2400000 0x0 0x1900000>;
+ no-map;
+ };
+
+ gpu_micro_code_mem: gpu-micro-code@b3d00000 {
+ reg = <0x0 0xb3d00000 0x0 0x2000>;
+ no-map;
+ };
+
+ video_mem: video@b3d02000 {
+ reg = <0x0 0xb3d02000 0x0 0x700000>;
+ no-map;
+ };
+
+ lmcu_mem: lmcu@b4402000 {
+ reg = <0x0 0xb4402000 0x0 0x300000>;
+ no-map;
+ };
+
+ lmcu_dtb_mem: lmcu-dtb@b4702000 {
+ reg = <0x0 0xb4702000 0x0 0x40000>;
+ no-map;
+ };
+ };
+
+ soc: soc@0 {
+ compatible = "simple-bus";
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dma-ranges = <0x0 0x0 0x0 0x0 0x10 0x0>;
+ ranges = <0x0 0x0 0x0 0x0 0x10 0x0>;
+
+ tcsr_mutex: syscon@340000 {
+ compatible = "qcom,tcsr-mutex";
+ reg = <0x0 0x00340000 0x0 0x20000>;
+ #hwlock-cells = <1>;
+ };
+
+ tcsr_regs: syscon@3c0000 {
+ compatible = "qcom,shikra-tcsr", "syscon";
+ reg = <0x0 0x003c0000 0x0 0x40000>;
+ };
+
+ tlmm: pinctrl@500000 {
+ compatible = "qcom,shikra-tlmm";
+ reg = <0x0 0x00500000 0x0 0x700000>;
+
+ interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH 0>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ gpio-ranges = <&tlmm 0 0 165>;
+ wakeup-parent = <&mpm>;
+
+ qup_uart0_default: qup-uart0-default-state {
+ pins = "gpio0", "gpio1";
+ function = "qup0_se0";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sdc1_state_on: sdc1-on-state {
+ clk-pins {
+ pins = "sdc1_clk";
+ drive-strength = <6>;
+ bias-disable;
+ };
+
+ cmd-pins {
+ pins = "sdc1_cmd";
+ drive-strength = <6>;
+ bias-pull-up;
+ };
+
+ data-pins {
+ pins = "sdc1_data";
+ drive-strength = <6>;
+ bias-pull-up;
+ };
+
+ rclk-pins {
+ pins = "sdc1_rclk";
+ bias-pull-down;
+ };
+ };
+
+ sdc1_state_off: sdc1-off-state {
+ clk-pins {
+ pins = "sdc1_clk";
+ drive-strength = <2>;
+ bias-bus-hold;
+ };
+
+ cmd-pins {
+ pins = "sdc1_cmd";
+ drive-strength = <2>;
+ bias-bus-hold;
+ };
+
+ data-pins {
+ pins = "sdc1_data";
+ drive-strength = <2>;
+ bias-bus-hold;
+ };
+
+ rclk-pins {
+ pins = "sdc1_rclk";
+ bias-bus-hold;
+ };
+ };
+ };
+
+ mem_noc: interconnect@d00000 {
+ compatible = "qcom,shikra-mem-noc-core";
+ reg = <0x0 0x00d00000 0x0 0x43080>;
+ clocks = <&gcc GCC_DDRSS_GPU_AXI_CLK>;
+ clock-names = "gpu_axi";
+ #interconnect-cells = <2>;
+ };
+
+ llcc: system-cache-controller@e00000 {
+ compatible = "qcom,shikra-llcc";
+ reg = <0x0 0x00e00000 0x0 0x80000>,
+ <0x0 0x00f00000 0x0 0x80000>,
+ <0x0 0x01000000 0x0 0x80000>;
+ reg-names = "llcc0_base",
+ "llcc1_base",
+ "llcc_broadcast_base";
+ interrupts = <GIC_SPI 539 IRQ_TYPE_LEVEL_HIGH 0>;
+ };
+
+ gcc: clock-controller@1400000 {
+ compatible = "qcom,shikra-gcc";
+ reg = <0x0 0x01400000 0x0 0x1f0000>;
+ clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
+ <&sleep_clk>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>;
+ power-domains = <&rpmpd RPMPD_VDDCX>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ #power-domain-cells = <1>;
+ };
+
+ system_noc: interconnect@1880000 {
+ compatible = "qcom,shikra-sys-noc";
+ reg = <0x0 0x01880000 0x0 0x6a080>;
+ clocks = <&gcc GCC_EMAC0_AXI_SYS_NOC_CLK>,
+ <&gcc GCC_EMAC1_AXI_SYS_NOC_CLK>,
+ <&gcc GCC_SYS_NOC_USB2_PRIM_AXI_CLK>,
+ <&gcc GCC_SYS_NOC_USB3_PRIM_AXI_CLK>;
+ clock-names = "emac0_axi",
+ "emac1_axi",
+ "usb2_axi",
+ "usb3_axi";
+ #interconnect-cells = <2>;
+
+ clk_virt: interconnect-clk {
+ compatible = "qcom,shikra-clk-virt";
+ #interconnect-cells = <2>;
+ };
+
+ mc_virt: interconnect-mc {
+ compatible = "qcom,shikra-mc-virt";
+ #interconnect-cells = <2>;
+ };
+
+ mmrt_virt: interconnect-mmrt {
+ compatible = "qcom,shikra-mmrt-virt";
+ #interconnect-cells = <2>;
+ };
+
+ mmnrt_virt: interconnect-mmnrt {
+ compatible = "qcom,shikra-mmnrt-virt";
+ #interconnect-cells = <2>;
+ };
+ };
+
+ config_noc: interconnect@1900000 {
+ compatible = "qcom,shikra-config-noc";
+ reg = <0x0 0x01900000 0x0 0x8080>;
+ #interconnect-cells = <2>;
+ };
+
+ qfprom: efuse@1b44000 {
+ compatible = "qcom,shikra-qfprom", "qcom,qfprom";
+ reg = <0x0 0x01b44000 0x0 0x3000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ qusb2_hstx_trim_1: hstx-trim@25b {
+ reg = <0x25b 0x1>;
+ bits = <1 4>;
+ };
+
+ gpu_speed_bin: gpu-speed-bin@2006 {
+ reg = <0x2006 0x2>;
+ bits = <5 8>;
+ };
+ };
+
+ spmi_bus: spmi@1c40000 {
+ compatible = "qcom,spmi-pmic-arb";
+ reg = <0x0 0x01c40000 0x0 0x1100>,
+ <0x0 0x01e00000 0x0 0x2000000>,
+ <0x0 0x03e00000 0x0 0x100000>,
+ <0x0 0x03f00000 0x0 0xa0000>,
+ <0x0 0x01c0a000 0x0 0x26000>;
+ reg-names = "core",
+ "chnls",
+ "obsrvr",
+ "intr",
+ "cnfg";
+ interrupts-extended = <&mpm 86 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "periph_irq";
+ interrupt-controller;
+ #interrupt-cells = <4>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+ qcom,channel = <0>;
+ qcom,ee = <0>;
+ };
+
+ rpm_msg_ram: sram@45f0000 {
+ compatible = "qcom,rpm-msg-ram", "mmio-sram";
+ reg = <0x0 0x045f0000 0x0 0x7000>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x0 0x045f0000 0x7000>;
+
+ apss_mpm: sram@1b8 {
+ reg = <0x1b8 0x48>;
+ };
+ };
+
+ sram@4690000 {
+ compatible = "qcom,rpm-stats";
+ reg = <0x0 0x04690000 0x0 0x14000>;
+ };
+
+ sdhc_1: mmc@4744000 {
+ compatible = "qcom,shikra-sdhci", "qcom,sdhci-msm-v5";
+
+ reg = <0x0 0x04744000 0x0 0x1000>,
+ <0x0 0x04745000 0x0 0x1000>;
+ reg-names = "hc",
+ "cqhci";
+
+ iommus = <&apps_smmu 0xc0 0x0>;
+
+ interrupts = <GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "hc_irq",
+ "pwr_irq";
+
+ clocks = <&gcc GCC_SDCC1_AHB_CLK>,
+ <&gcc GCC_SDCC1_APPS_CLK>,
+ <&rpmcc RPM_SMD_XO_CLK_SRC>;
+ clock-names = "iface",
+ "core",
+ "xo";
+
+ interconnects = <&system_noc MASTER_SDCC_1 RPM_ALWAYS_TAG
+ &mc_virt SLAVE_EBI_CH0 RPM_ALWAYS_TAG>,
+ <&mem_noc MASTER_AMPSS_M0 RPM_ACTIVE_TAG
+ &config_noc SLAVE_SDCC_1 RPM_ACTIVE_TAG>;
+ interconnect-names = "sdhc-ddr",
+ "cpu-sdhc";
+
+ power-domains = <&rpmpd RPMPD_VDDCX>;
+ operating-points-v2 = <&sdhc1_opp_table>;
+
+ qcom,dll-config = <0x000f642c>;
+ qcom,ddr-config = <0x80040868>;
+
+ bus-width = <8>;
+
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
+
+ resets = <&gcc GCC_SDCC1_BCR>;
+
+ status = "disabled";
+
+ sdhc1_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-100000000 {
+ opp-hz = /bits/ 64 <100000000>;
+ required-opps = <&rpmpd_opp_low_svs>;
+ opp-peak-kBps = <250000 133320>;
+ opp-avg-kBps = <104000 0>;
+ };
+
+ opp-384000000 {
+ opp-hz = /bits/ 64 <384000000>;
+ required-opps = <&rpmpd_opp_nom>;
+ opp-peak-kBps = <800000 300000>;
+ opp-avg-kBps = <400000 0>;
+ };
+ };
+ };
+
+ qupv3_0: geniqup@4ac0000 {
+ compatible = "qcom,geni-se-qup";
+ reg = <0x0 0x04ac0000 0x0 0x2000>;
+
+ clocks = <&gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>,
+ <&gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>;
+ clock-names = "m-ahb",
+ "s-ahb";
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ uart0: serial@4a80000 {
+ compatible = "qcom,geni-debug-uart";
+ reg = <0x0 0x04a80000 0x0 0x4000>;
+
+ interrupts = <GIC_SPI 527 IRQ_TYPE_LEVEL_HIGH 0>;
+
+ clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>;
+ clock-names = "se";
+
+ interconnects = <&clk_virt MASTER_QUP_CORE_0 RPM_ALWAYS_TAG
+ &clk_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>,
+ <&mem_noc MASTER_AMPSS_M0 RPM_ALWAYS_TAG
+ &config_noc SLAVE_QUP_0 RPM_ALWAYS_TAG>;
+ interconnect-names = "qup-core",
+ "qup-config";
+
+ pinctrl-0 = <&qup_uart0_default>;
+ pinctrl-names = "default";
+
+ status = "disabled";
+ };
+ };
+
+ sram@c11e000 {
+ compatible = "qcom,shikra-imem", "mmio-sram";
+ reg = <0x0 0x0c11e000 0x0 0x1000>;
+ ranges = <0x0 0x0 0x0c11e000 0x1000>;
+
+ no-memory-wc;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ pil-sram@94c {
+ compatible = "qcom,pil-reloc-info";
+ reg = <0x94c 0xc8>;
+ };
+ };
+
+ apps_smmu: iommu@c600000 {
+ compatible = "qcom,shikra-smmu-500", "qcom,smmu-500", "arm,mmu-500";
+ reg = <0x0 0x0c600000 0x0 0x80000>;
+ #iommu-cells = <2>;
+ #global-interrupts = <1>;
+
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH 0>;
+ };
+
+ intc: interrupt-controller@f200000 {
+ compatible = "arm,gic-v3";
+ reg = <0x0 0xf200000 0x0 0x10000>,
+ <0x0 0xf240000 0x0 0x80000>;
+
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>;
+
+ #interrupt-cells = <4>;
+ interrupt-controller;
+
+ #redistributor-regions = <1>;
+ redistributor-stride = <0x0 0x20000>;
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ ppi-partitions {
+ ppi_cluster0: interrupt-partition-0 {
+ affinity = <&cpu0 &cpu1 &cpu2>;
+ };
+
+ ppi_cluster1: interrupt-partition-1 {
+ affinity = <&cpu3>;
+ };
+ };
+ };
+
+ apcs_glb: mailbox@f400000 {
+ compatible = "qcom,shikra-apss-shared", "qcom,sdm845-apss-shared";
+ reg = <0x0 0x0f400000 0x0 0x1000>;
+ #mbox-cells = <1>;
+ };
+
+ watchdog@f410000 {
+ compatible = "qcom,apss-wdt-shikra", "qcom,kpss-wdt";
+ reg = <0x0 0x0f410000 0x0 0x1000>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&sleep_clk>;
+ };
+
+ timer@f420000 {
+ compatible = "arm,armv7-timer-mem";
+ reg = <0x0 0x0f420000 0x0 0x1000>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x0 0x0 0x10000000>;
+
+ frame@f421000 {
+ reg = <0x0f421000 0x1000>,
+ <0x0f422000 0x1000>;
+ frame-number = <0>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH 0>;
+ };
+
+ frame@f423000 {
+ reg = <0x0f423000 0x1000>;
+ frame-number = <1>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH 0>;
+ status = "disabled";
+ };
+
+ frame@f425000 {
+ reg = <0x0f425000 0x1000>;
+ frame-number = <2>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH 0>;
+ status = "disabled";
+ };
+
+ frame@f427000 {
+ reg = <0x0f427000 0x1000>;
+ frame-number = <3>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH 0>;
+ status = "disabled";
+ };
+
+ frame@f429000 {
+ reg = <0x0f429000 0x1000>;
+ frame-number = <4>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH 0>;
+ status = "disabled";
+ };
+
+ frame@f42b000 {
+ reg = <0x0f42b000 0x1000>;
+ frame-number = <5>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH 0>;
+ status = "disabled";
+ };
+
+ frame@f42d000 {
+ reg = <0x0f42d000 0x1000>;
+ frame-number = <6>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH 0>;
+ status = "disabled";
+ };
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+
+ interrupts = <GIC_PPI 1 IRQ_TYPE_LEVEL_LOW 0>,
+ <GIC_PPI 2 IRQ_TYPE_LEVEL_LOW 0>,
+ <GIC_PPI 3 IRQ_TYPE_LEVEL_LOW 0>,
+ <GIC_PPI 0 IRQ_TYPE_LEVEL_LOW 0>;
+ };
+};
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v6 1/5] dt-bindings: arm: qcom: Document Shikra and its EVK boards
From: Komal Bajaj @ 2026-06-12 17:27 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vinod Koul, Neil Armstrong, Wesley Cheng,
Ulf Hansson
Cc: linux-arm-msm, devicetree, linux-kernel, linux-phy, linux-mmc,
monish.chunara, Komal Bajaj, Krzysztof Kozlowski
In-Reply-To: <20260612-shikra-dt-v6-0-6b6cb58db477@oss.qualcomm.com>
Shikra is a Qualcomm IoT SoC available in a System-on-Module (SoM)
form factor. The SoM integrates the Shikra SoC, PMICs, and essential
passives, and is designed to be mounted on carrier boards.
Three eSoM variant are introduced:
- CQM: retail variant with integrated modem (PM4125 and PM8005 PMIC)
- CQS: retail variant without modem (PM4125 and PM8005 PMIC)
- IQS: industrial-grade variant without modem (PM8150 PMIC)
Each SoM variant pairs with a common EVK carrier board provides debug
UART, USB, and other peripheral interfaces.
Add compatible strings for the CQ2390M, CQ2390S, IQ2390S SoM variant and
its corresponding EVK boards.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
---
Documentation/devicetree/bindings/arm/qcom.yaml | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
index 50cc18a6ec5e..cf7d241f8107 100644
--- a/Documentation/devicetree/bindings/arm/qcom.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom.yaml
@@ -989,6 +989,24 @@ properties:
- xiaomi,polaris
- const: qcom,sdm845
+ - items:
+ - enum:
+ - qcom,shikra-cqm-evk
+ - const: qcom,shikra-cqm-som
+ - const: qcom,shikra
+
+ - items:
+ - enum:
+ - qcom,shikra-cqs-evk
+ - const: qcom,shikra-cqs-som
+ - const: qcom,shikra
+
+ - items:
+ - enum:
+ - qcom,shikra-iqs-evk
+ - const: qcom,shikra-iqs-som
+ - const: qcom,shikra
+
- items:
- enum:
- oneplus,billie2
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v6 0/5] arm64: dts: qcom: Add initial device tree support for Shikra
From: Komal Bajaj @ 2026-06-12 17:27 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vinod Koul, Neil Armstrong, Wesley Cheng,
Ulf Hansson
Cc: linux-arm-msm, devicetree, linux-kernel, linux-phy, linux-mmc,
monish.chunara, Komal Bajaj, Krzysztof Kozlowski, Imran Shaik,
Monish Chunara, Rakesh Kota, Raviteja Laggyshetty, Sneh Mankad,
Vishnu Santhosh, Xueyao An, Konrad Dybcio, Dmitry Baryshkov
Add initial device tree support for the Qualcomm Shikra SoC.
Shikra ships in a SoM form factor; this series covers the CQ2390M,
CQ2390S and IQ2390S SoM variants and their EVK boards.
The series adds:
- dt-bindings for the Shikra SoC, CQ2390M/CQ2390S/IQ2390S EVK boards
- SoC base DTSI
- CQ2390M SoM DTSI with PM4125 and PM8005 PMIC regulator definitions
- IQ2390S SoM DTSI with PM8150 PMIC regulator definitions
- EVK DTS files enabling UART and eMMC on the carrier board
Note: USB support is intentionally dropped from this series. It will be
sent separately once the USB driver changes for Shikra are concluded.
Signed-off-by: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
---
Changes in v6:
- Collect Reviewed-by tags (Krzysztof, Dmitry)
- Fix ranges value and interconnects alignment in sdhc node in shikra.dtsi (Dmitry)
- Link to v5: https://lore.kernel.org/r/20260611-shikra-dt-v5-0-103ed26a8529@oss.qualcomm.com
Changes in v5:
- Add qcom,rpmcc-qcm2290 fallback compatible to rpmcc node in shikra.dtsi
- Link to v4: https://lore.kernel.org/r/20260527-shikra-dt-v4-0-b5ca1fa0b392@oss.qualcomm.com
Changes in v4:
- Updated commit message for 1/5 and 3/5 (Krzysztof, Konrad)
- Incorporated Konrad's comment
- Collected Reviewed-By tags
- Link to v3: https://lore.kernel.org/r/20260522-shikra-dt-v3-0-80ffde8a3dc4@oss.qualcomm.com
Changes in v3:
- Drop USB nodes from this series; will be sent separately pending
conclusion of USB driver changes for Shikra
- Fix memory base (0xa0000000 -> 0x80000000) (sashiko-bot)
- Fix power-domain macro: QCM2290_VDDCX -> RPMPD_VDDCX for sdhc (sashiko-bot)
- Fix INTC GIC_PPI number from 8 to GIC_PPI 9 (sashiko-bot)
- Rename SoM variant CQ7790M to CQ2390M (Konrad)
- Add PMIC DTSI includes to CQ2390M and IQ2390S SoM
- Link to v2: https://lore.kernel.org/r/20260519-shikra-dt-v2-0-c01b90fb4395@oss.qualcomm.com
Changes in v2:
- Update SoM/EVK combination bindings (Krzysztof)
- Add per-CPU-type PMU nodes with PPI partitions for the heterogeneous
cluster (Cortex-A55 + Cortex-A78C) (Konrad)
- Use full product names CQ2390M/CQ2390S in commit messages (Krzysztof)
- Update RPM interconnect tags and power-domain to RPMPD for sdhc (sashiko-bot)
- Update to use MPM for ss_phy_irq instead of direct GIC for usb (sashiko-bot)
- Add IQ2390S SoM (PM8150 PMIC) and IQS EVK board support
- Link to v1: https://lore.kernel.org/r/20260512-shikra-dt-v1-0-716438330dd0@oss.qualcomm.com
---
Komal Bajaj (5):
dt-bindings: arm: qcom: Document Shikra and its EVK boards
arm64: dts: qcom: Introduce Shikra SoC base dtsi
arm64: dts: qcom: Add Shikra CQ2390M SoM platform
arm64: dts: qcom: Add Shikra IQ2390S SoM platform
arm64: dts: qcom: Add Shikra EVK boards
Documentation/devicetree/bindings/arm/qcom.yaml | 18 +
arch/arm64/boot/dts/qcom/Makefile | 3 +
arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts | 40 ++
arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi | 156 +++++
arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts | 40 ++
arch/arm64/boot/dts/qcom/shikra-evk.dtsi | 15 +
arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts | 40 ++
arch/arm64/boot/dts/qcom/shikra-iqs-som.dtsi | 170 +++++
arch/arm64/boot/dts/qcom/shikra.dtsi | 842 ++++++++++++++++++++++++
9 files changed, 1324 insertions(+)
---
base-commit: ec039126b7fac4e3af35ebccaa7c6f9b6875ba81
change-id: 20260511-shikra-dt-d75d97454646
prerequisite-change-id: 20260429-shikra-gcc-rpmcc-clks-2094edfff3b0:v5
prerequisite-patch-id: 59bb0a7828e41f546f734f127d81da83c0adcda9
prerequisite-patch-id: 197da6bcb15cadc47869dba88c8020987b25c335
prerequisite-patch-id: 8ec9c1eb03f052ae232ed54117abed38672c23f6
prerequisite-patch-id: 350db4f4bcdfc0fad9ed57cd5b1723f85ad44f5d
prerequisite-message-id: 20260508-shikra_mailbox_and_rpm_changes-v3-1-698f8e5fb339@oss.qualcomm.com
prerequisite-patch-id: e80ea7940b9817449cec21afa6e9e443e007166f
prerequisite-patch-id: 2526e0507d3b5c065eafd75a657d7f903af8488f
prerequisite-patch-id: c3b7e18cd60d1f779b88ace2fae1227d3d37d83e
prerequisite-change-id: 20260430-shikra-imem-binding-a7bb9d2f16d2:v1
prerequisite-patch-id: 80d8ab865b7b0663c5b2878b45b55e2e4fde9c19
prerequisite-change-id: 20260501-shikra-scm-binding-a7ff5fabd0f2:v1
prerequisite-patch-id: 8e645e1c6ad6182de4813a726c293654324de1df
prerequisite-change-id: 20260501-shikra-tcsr-binding-fff1689e4097:v1
prerequisite-patch-id: f6781d2cf0829ccb32f1400623c95739972f2ee2
Best regards,
--
Komal Bajaj <komal.bajaj@oss.qualcomm.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v5 2/5] arm64: dts: qcom: Introduce Shikra SoC base dtsi
From: Komal Bajaj @ 2026-06-12 17:19 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vinod Koul, Neil Armstrong, Wesley Cheng,
Ulf Hansson, linux-arm-msm, devicetree, linux-kernel, linux-phy,
linux-mmc, monish.chunara, Imran Shaik, Monish Chunara,
Rakesh Kota, Raviteja Laggyshetty, Sneh Mankad, Vishnu Santhosh,
Xueyao An, Konrad Dybcio
In-Reply-To: <zzveallrfaeaclkes4dvexcxacyyew6mjgar5ctmhevh6ld4c5@caxx3gdr6g6v>
On 6/12/2026 1:46 AM, Dmitry Baryshkov wrote:
> On Thu, Jun 11, 2026 at 03:40:09PM +0530, Komal Bajaj wrote:
>> Add initial device tree support for the Qualcomm Shikra SoC,
>> an IoT-focused platform built around a heterogeneous CPU cluster
>> (Cortex-A55 + Cortex-A78C) with RPM-based power and clock management.
>>
>> Enable support for the following peripherals:
>> - CPU nodes
>> - Global Clock Controller (GCC)
>> - RPM-based clock controller (RPMCC) and power domains (RPMPD)
>> - Interrupt controller
>> - Top Level Mode Multiplexer (TLMM)
>> - Debug UART
>> - eMMC host controller
>> - System timer and watchdog
>>
>> Co-developed-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
>> Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
>> Co-developed-by: Monish Chunara <quic_mchunara@quicinc.com>
>> Signed-off-by: Monish Chunara <quic_mchunara@quicinc.com>
>> Co-developed-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>
>> Signed-off-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>
>> Co-developed-by: Raviteja Laggyshetty <raviteja.laggyshetty@oss.qualcomm.com>
>> Signed-off-by: Raviteja Laggyshetty <raviteja.laggyshetty@oss.qualcomm.com>
>> Co-developed-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
>> Signed-off-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
>> Co-developed-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
>> Signed-off-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
>> Co-developed-by: Xueyao An <xueyao.an@oss.qualcomm.com>
>> Signed-off-by: Xueyao An <xueyao.an@oss.qualcomm.com>
>> Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
>> Signed-off-by: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
>> ---
>> arch/arm64/boot/dts/qcom/shikra.dtsi | 842 +++++++++++++++++++++++++++++++++++
>> 1 file changed, 842 insertions(+)
>>
>> +
>> + rpm_msg_ram: sram@45f0000 {
>> + compatible = "qcom,rpm-msg-ram", "mmio-sram";
>> + reg = <0x0 0x045f0000 0x0 0x7000>;
>> +
>> + #address-cells = <1>;
>> + #size-cells = <1>;
>> + ranges = <0 0x0 0x045f0000 0x7000>;
> 0x0
ACK
>
>> +
>> + apss_mpm: sram@1b8 {
>> + reg = <0x1b8 0x48>;
>> + };
>> + };
>> +
>> + sram@4690000 {
>> + compatible = "qcom,rpm-stats";
>> + reg = <0x0 0x04690000 0x0 0x14000>;
>> + };
>> +
>> + sdhc_1: mmc@4744000 {
>> + compatible = "qcom,shikra-sdhci", "qcom,sdhci-msm-v5";
>> +
>> + reg = <0x0 0x04744000 0x0 0x1000>,
>> + <0x0 0x04745000 0x0 0x1000>;
>> + reg-names = "hc",
>> + "cqhci";
>> +
>> + iommus = <&apps_smmu 0xc0 0x0>;
>> +
>> + interrupts = <GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH 0>,
>> + <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH 0>;
>> + interrupt-names = "hc_irq",
>> + "pwr_irq";
>> +
>> + clocks = <&gcc GCC_SDCC1_AHB_CLK>,
>> + <&gcc GCC_SDCC1_APPS_CLK>,
>> + <&rpmcc RPM_SMD_XO_CLK_SRC>;
>> + clock-names = "iface",
>> + "core",
>> + "xo";
>> +
>> + interconnects = <&system_noc MASTER_SDCC_1 RPM_ALWAYS_TAG
>> + &mc_virt SLAVE_EBI_CH0 RPM_ALWAYS_TAG>,
> Please align on '&'.
ACK
Thanks
Komal
>
>> + <&mem_noc MASTER_AMPSS_M0 RPM_ACTIVE_TAG
>> + &config_noc SLAVE_SDCC_1 RPM_ACTIVE_TAG>;
>> + interconnect-names = "sdhc-ddr",
>> + "cpu-sdhc";
>> +
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v5 1/5] dt-bindings: arm: qcom: Document Shikra and its EVK boards
From: Komal Bajaj @ 2026-06-12 17:18 UTC (permalink / raw)
To: Rob Herring
Cc: Bjorn Andersson, Konrad Dybcio, Krzysztof Kozlowski, Conor Dooley,
Vinod Koul, Neil Armstrong, Wesley Cheng, Ulf Hansson,
linux-arm-msm, devicetree, linux-kernel, linux-phy, linux-mmc,
monish.chunara
In-Reply-To: <20260611181841.GA3163205-robh@kernel.org>
On 6/11/2026 11:48 PM, Rob Herring wrote:
> On Thu, Jun 11, 2026 at 03:40:08PM +0530, Komal Bajaj wrote:
>> Shikra is a Qualcomm IoT SoC available in a System-on-Module (SoM)
>> form factor. The SoM integrates the Shikra SoC, PMICs, and essential
>> passives, and is designed to be mounted on carrier boards.
>>
>> Three eSoM variant are introduced:
>> - CQM: retail variant with integrated modem (PM4125 and PM8005 PMIC)
>> - CQS: retail variant without modem (PM4125 and PM8005 PMIC)
>> - IQS: industrial-grade variant without modem (PM8150 PMIC)
>>
>> Each SoM variant pairs with a common EVK carrier board provides debug
>> UART, USB, and other peripheral interfaces.
>>
>> Add compatible strings for the CQ2390M, CQ2390S, IQ2390S SoM variant and
>> its corresponding EVK boards.
>>
>> Signed-off-by: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
> Missing Krzysztof's reviewed-by.
Missed that. Will add his reviewed-by in next revision.
Thanks
Komal
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v5 17/18] phy: rockchip: usbdp: Support going from DP-only mode to USB mode
From: sashiko-bot @ 2026-06-12 17:08 UTC (permalink / raw)
To: Sebastian Reichel
Cc: linux-phy, devicetree, olteanv, conor+dt, robh, vkoul,
neil.armstrong
In-Reply-To: <20260612-rockchip-usbdp-cleanup-v5-17-efc83069869f@collabora.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
New issues:
- [Medium] The return value of `rk_udphy_power_on()` is silently ignored during Type-C mux state transitions.
- [Medium] The `usb_in_use` flag is permanently left as `true` if `rk_udphy_power_on()` fails during USB PHY initialization.
Pre-existing issues:
- [High] The `UDPHY_MODE_USB` bit in `udphy->status` is permanently leaked if `rk_udphy_usb3_phy_exit()` is called while the Type-C mux is currently in DP-only mode.
- [High] Failing to reinitialize the PHY after a transient error masks subsequent failures and reports false success.
--
commit 3ea1c2acafe2e85bbef04dfbb4e06950b88402b0
Author: Sebastian Reichel <sebastian.reichel@collabora.com>
phy: rockchip: usbdp: Support going from DP-only mode to USB mode
When a USB-C adapter, which maps all Superspeed lanes to DP is plugged
in, the USB support is disabled in the PHY. When the adapter is
unplugged and a different adapter with USB functionality is plugged in
afterwards, USB functionality is not restored as the USB controller
keeps the PHY enabled for the entire time.
> diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
> +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
[ ... ]
> @@ -1015,6 +1016,9 @@ static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode)
> ret = rk_udphy_init(udphy);
> if (ret)
> return ret;
[Severity: High]
This is a pre-existing issue, but if rk_udphy_init() fails here,
udphy->phy_needs_reinit was already set to false earlier in the block.
Will subsequent calls to rk_udphy_power_on() skip initialization and
falsely return success while the hardware remains broken?
Should phy_needs_reinit be restored to true on the error path?
> +
> + if (udphy->mode & UDPHY_MODE_USB)
> + rk_udphy_u3_port_disable(udphy, false);
> }
>
> udphy->status |= mode;
[ ... ]
> @@ -1278,6 +1282,15 @@ static int rk_udphy_usb3_phy_init(struct phy *phy)
>
> guard(mutex)(&udphy->mutex);
>
> + udphy->usb_in_use = true;
> +
> /* DP only or high-speed, disable U3 port */
> if (!(udphy->mode & UDPHY_MODE_USB) || udphy->hs) {
> rk_udphy_u3_port_disable(udphy, true);
> return 0;
> }
>
> ret = rk_udphy_power_on(udphy, UDPHY_MODE_USB);
>
> return ret;
> }
[Severity: Medium]
If rk_udphy_power_on() fails and returns an error, usb_in_use remains true.
Will this cause rk_udphy_typec_mux_set() to incorrectly attempt to power on
the USB PHY later, despite the USB controller not actively using it?
Should the flag be reverted to false on the error path?
> @@ -1295,6 +1301,13 @@ static int rk_udphy_usb3_phy_exit(struct phy *phy)
>
> guard(mutex)(&udphy->mutex);
>
> + udphy->usb_in_use = false;
> +
> /* DP only or high-speed */
> if (!(udphy->mode & UDPHY_MODE_USB) || udphy->hs)
> return 0;
[Severity: High]
This isn't a bug introduced by this patch, but if the Type-C mode
transitions to DP-only, udphy->mode loses the UDPHY_MODE_USB bit.
When rk_udphy_usb3_phy_exit() is subsequently called, it checks
!(udphy->mode & UDPHY_MODE_USB) and returns 0 early, skipping
rk_udphy_power_off().
Does this result in a permanent leak of the PHY's clocks and resets, since
udphy->status never clears the UDPHY_MODE_USB bit?
>
> rk_udphy_power_off(udphy, UDPHY_MODE_USB);
>
> return 0;
> }
[ ... ]
> @@ -1325,8 +1334,20 @@ static int rk_udphy_typec_mux_set(struct typec_mux_dev *mux,
>
> guard(mutex)(&udphy->mutex);
>
> + old_mode = udphy->mode;
> +
> rk_udphy_set_typec_state(udphy, state->mode);
>
> + /*
> + * If the new mode includes USB but the old one didn't (e.g. leaving
> + * DP-only), and the USB PHY was already initialized by the USB
> + * controller, we need to power on the USB side now since no
> + * subsequent phy_init call will come from the controller.
> + */
> + if ((udphy->mode & UDPHY_MODE_USB) && !(old_mode & UDPHY_MODE_USB) &&
> + udphy->usb_in_use && !udphy->hs)
> + rk_udphy_power_on(udphy, UDPHY_MODE_USB);
[Severity: Medium]
Does this code discard the return value of rk_udphy_power_on()?
If initialization fails, the error is ignored and the driver reports success
for the Type-C mux state transition, which could leave the USB functionality
silently broken.
Should this check the return value and at least log or propagate the error?
> +
> return 0;
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260612-rockchip-usbdp-cleanup-v5-0-efc83069869f@collabora.com?part=17
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v5 18/18] phy: rockchip: usbdp: Add some extra debug messages
From: sashiko-bot @ 2026-06-12 17:06 UTC (permalink / raw)
To: Sebastian Reichel
Cc: devicetree, conor+dt, neil.armstrong, olteanv, vkoul, linux-phy,
robh
In-Reply-To: <20260612-rockchip-usbdp-cleanup-v5-18-efc83069869f@collabora.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Missing explicit inclusion of `<linux/string_choices.h>` for string choice helpers.
--
commit 1df9f844b4fa19da9efe1fba10ad8a1d451bea55
Author: Sebastian Reichel <sebastian.reichel@collabora.com>
phy: rockchip: usbdp: Add some extra debug messages
This commit adds additional debug logging to the Rockchip USBDP PHY
driver. The new messages report port status and track PHY initialization
to help debug USB-C hotplugging behavior.
> diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> index 236331cc0d132..4042e2dd81219 100644
> --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
> +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> @@ -491,6 +491,8 @@ static void rk_udphy_u3_port_disable(struct rk_udphy *udphy, u8 disable)
> const struct rk_udphy_cfg *cfg = udphy->cfgs;
> const struct rk_udphy_grf_reg *preg;
>
> + dev_dbg(udphy->dev, "USB3 port %s\n", str_on_off(!disable));
[Severity: Low]
Does this file explicitly include <linux/string_choices.h>? Relying on
implicit inclusion for str_on_off() might cause build failures in the future
if header dependencies are reorganized across architectures.
[ ... ]
> @@ -784,6 +786,10 @@ static int rk_udphy_init(struct rk_udphy *udphy)
> const struct rk_udphy_cfg *cfg = udphy->cfgs;
> int ret;
>
> + dev_dbg(udphy->dev, "(re-)init PHY with USB=%s and DP=%s\n",
> + str_enabled_disabled(udphy->mode & UDPHY_MODE_USB),
> + str_enabled_disabled(udphy->mode & UDPHY_MODE_DP));
[Severity: Low]
Similarly, should we add <linux/string_choices.h> here to ensure
str_enabled_disabled() is safely resolved without relying on transitive
includes?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260612-rockchip-usbdp-cleanup-v5-0-efc83069869f@collabora.com?part=18
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v5 14/18] phy: rockchip: usbdp: Re-init the PHY on orientation change
From: sashiko-bot @ 2026-06-12 17:03 UTC (permalink / raw)
To: Sebastian Reichel
Cc: neil.armstrong, devicetree, vkoul, olteanv, linux-phy, robh,
conor+dt
In-Reply-To: <20260612-rockchip-usbdp-cleanup-v5-14-efc83069869f@collabora.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] rk_udphy_dp_phy_configure accesses shared state and modifies PHY registers without holding udphy->mutex, racing with orientation switches and PHY resets.
- [High] udphy->phy_needs_reinit is cleared before initialization but is not restored if rk_udphy_init fails, permanently breaking the PHY.
--
commit c7d9d38e9a690c6a3592fb9c0e4736966a879674
Author: Sebastian Reichel <sebastian.reichel@collabora.com>
phy: rockchip: usbdp: Re-init the PHY on orientation change
Changing the cable orientation reconfigures the lane muxing, which requires
re-initializing the PHY. This patch sets the phy_needs_reinit flag when the
cable orientation is swapped to ensure the PHY is reset and reconfigured
appropriately.
> diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> index a3b4e2e0f5786..89a08267611c5 100644
> --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
> +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
[ ... ]
> @@ -633,7 +634,10 @@ static int rk_udphy_orien_sw_set(struct typec_switch_dev *sw,
> goto unlock_ret;
> }
>
> - udphy->flip = orien == TYPEC_ORIENTATION_REVERSE;
> + if (udphy->flip != flipped)
> + udphy->phy_needs_reinit = true;
[Severity: High]
This isn't a bug introduced by this patch, but setting
udphy->phy_needs_reinit here interacts with an error handling issue.
In drivers/phy/rockchip/phy-rockchip-usbdp.c:rk_udphy_power_on(), the flag
is eagerly cleared before initialization:
rk_udphy_power_on() {
...
} else if (udphy->phy_needs_reinit) {
udphy->phy_needs_reinit = false;
...
ret = rk_udphy_init(udphy);
if (ret)
return ret;
...
}
If rk_udphy_init() fails (for example, due to a retryable PLL lock timeout
returning -EPROBE_DEFER), the flag is not restored to true. Since the
hardware is held in reset on failure, will subsequent calls to
rk_udphy_power_on() skip reinitialization entirely and falsely report
success while leaving both USB and DP functionally dead?
> +
> + udphy->flip = flipped;
> rk_udphy_set_typec_default_mapping(udphy);
[Severity: High]
This is a pre-existing issue, but can this state update race with DP PHY
configuration?
This function holds udphy->mutex while updating state like udphy->flip and
lane selections in rk_udphy_set_typec_default_mapping(). However,
rk_udphy_dp_phy_configure() is called by the generic PHY framework holding
only the DP-specific phy->mutex:
rk_udphy_dp_phy_configure() {
struct rk_udphy *udphy = phy_get_drvdata(phy);
// ... accesses udphy->dp_lane_sel without taking udphy->mutex
...
}
If a concurrent Type-C mode switch or USB PHY initialization holds
udphy->mutex and triggers rk_udphy_init(), it will assert all hardware
resets:
rk_udphy_init() {
...
rk_udphy_reset_assert_all(udphy);
...
}
Because rk_udphy_dp_phy_configure() does not acquire udphy->mutex, can its
register writes interleave with a full hardware reset, leaving the DP PHY
unconfigured and causing link training failures?
> rk_udphy_usb_bvalid_enable(udphy, true);
>
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260612-rockchip-usbdp-cleanup-v5-0-efc83069869f@collabora.com?part=14
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v5 07/18] phy: rockchip: usbdp: Support single-lane DP
From: sashiko-bot @ 2026-06-12 16:55 UTC (permalink / raw)
To: Sebastian Reichel
Cc: linux-phy, robh, conor+dt, neil.armstrong, olteanv, devicetree,
vkoul
In-Reply-To: <20260612-rockchip-usbdp-cleanup-v5-7-efc83069869f@collabora.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
New issues:
- [Medium] Incorrect USB orientation (`flip`) configuration when 1-lane DP is assigned to lane 1.
Pre-existing issues:
- [High] Writing to PMA registers while PHY clocks are disabled when DP mode is not supported.
- [High] Clock resources enabled during probe are leaked on probe error paths and upon driver unbind.
- [High] The DP PHY configuration lacks boundary checks against the physical lane count, leading to USB register corruption.
--
commit c46d73844b37e1f374324a737da2265a3fef0813
Author: Zhang Yubing <yubing.zhang@rock-chips.com>
Subject: phy: rockchip: usbdp: Support single-lane DP
This commit implements support for using a single DisplayPort line in the
Rockchip USBDP PHY driver.
> diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> index febc148a754e0..bf8394174294e 100644
> --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
> +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
[ ... ]
> @@ -923,7 +910,8 @@ static int rk_udphy_parse_lane_mux_data(struct rk_udphy *udphy)
> }
>
> udphy->mode = UDPHY_MODE_DP;
> - if (num_lanes == 2) {
> + udphy->dp_lanes = num_lanes;
> + if (num_lanes == 1 || num_lanes == 2) {
> udphy->mode |= UDPHY_MODE_USB;
> udphy->flip = (udphy->lane_mux_sel[0] == PHY_LANE_MUX_DP);
> }
[Severity: Medium]
When configuring a single DP lane, does this correctly set the flip state if
the DP lane is assigned to lane 1 instead of lane 0?
For a 1-lane DP setup where rockchip,dp-lane-mux = <1>, lane 1 is occupied
by DP, so USB must be mapped to the lane 2 and 3 pair. This requires the
flip state to be true so the driver correctly polls lane 2 for USB RX CDR
lock.
However, in this scenario lane_mux_sel[0] will not be PHY_LANE_MUX_DP, making
flip evaluate to false. This might cause the driver to poll the unconnected
lane 0 for USB lock and time out. Should this condition check if either lane
0 or lane 1 is occupied by DP?
[ ... ]
> @@ -1074,18 +1062,17 @@ static int rk_udphy_dp_phy_exit(struct phy *phy)
> static int rk_udphy_dp_phy_power_on(struct phy *phy)
> {
> struct rk_udphy *udphy = phy_get_drvdata(phy);
> - int ret, dp_lanes;
> + int ret;
>
> mutex_lock(&udphy->mutex);
>
> - dp_lanes = rk_udphy_dplane_get(udphy);
> - phy_set_bus_width(phy, dp_lanes);
> + phy_set_bus_width(phy, udphy->dp_lanes);
>
> ret = rk_udphy_power_on(udphy, UDPHY_MODE_DP);
> if (ret)
> goto unlock;
>
> - rk_udphy_dplane_enable(udphy, dp_lanes);
> + rk_udphy_dplane_enable(udphy, udphy->dp_lanes);
[Severity: High]
This is a pre-existing issue, but can this sequence crash the system if the
DP mode is not supported?
In rk_udphy_power_on(), if the mode does not include UDPHY_MODE_DP, it
prints an error message and returns 0 instead of an error code:
rk_udphy_power_on() {
if (!(udphy->mode & mode)) {
dev_info(udphy->dev, "mode 0x%02x is not support\n", mode);
return 0;
}
...
}
Because it returns success, the execution falls through in
rk_udphy_dp_phy_power_on() and proceeds to call rk_udphy_dplane_enable().
This performs register operations on memory-mapped PHY registers. Accessing
these registers while the corresponding PHY clocks remain disabled can
result in a synchronous external abort and crash the kernel. Should
rk_udphy_power_on() return an error like -ENODEV to properly abort this
sequence?
[ ... ]
> @@ -1529,7 +1518,7 @@ static int rk_udphy_probe(struct platform_device *pdev)
> ret = PTR_ERR(udphy->phy_dp);
> return dev_err_probe(dev, ret, "failed to create DP phy\n");
> }
> - phy_set_bus_width(udphy->phy_dp, rk_udphy_dplane_get(udphy));
> + phy_set_bus_width(udphy->phy_dp, udphy->dp_lanes);
[Severity: High]
This is a pre-existing issue, but does the probe sequence leak clock
resources on error paths?
In rk_udphy_get_initial_status(), if the hardware is already in DP mode,
the clocks are enabled and intentionally left enabled:
rk_udphy_get_initial_status() {
...
if (FIELD_GET(CMN_DP_LANE_MUX_ALL, value) &&
FIELD_GET(CMN_DP_LANE_EN_ALL, value))
udphy->status = UDPHY_MODE_DP;
else
rk_udphy_disable(udphy);
}
However, if subsequent operations in rk_udphy_probe() fail, the probe
function returns directly without calling clk_bulk_disable_unprepare():
rk_udphy_probe() {
...
udphy->phy_u3 = devm_phy_create(dev, dev->of_node,
&rk_udphy_usb3_phy_ops);
if (IS_ERR(udphy->phy_u3)) {
ret = PTR_ERR(udphy->phy_u3);
return dev_err_probe(dev, ret, "failed to create USB3 phy\n");
}
...
}
Additionally, there appears to be no remove callback or devm action
registered to clean up these manually enabled clocks when the driver
unbinds.
[Severity: High]
This is also a pre-existing issue, but could a consumer request more lanes
than are physically configured in udphy->dp_lanes?
In rk_udphy_dp_phy_verify_lanes(), the driver validates that the requested
lane count is 1, 2, or 4, but it does not check if the requested lanes
exceed the physically configured capacity:
rk_udphy_dp_phy_verify_lanes() {
...
switch (dp->lanes) {
case 1:
case 2:
case 4:
udphy->lanes = dp->lanes;
break;
...
}
If a consumer requests 4 lanes on a 1-lane or 2-lane configuration,
rk_udphy_dp_phy_configure() will iterate up to the requested lane count,
reading from unconfigured indices:
rk_udphy_dp_phy_configure() {
...
for (i = 0; i < udphy->lanes; i++) {
lane = udphy->dp_lane_sel[i];
...
rk_udphy_dp_set_voltage(udphy, udphy->bw, dp->voltage[i],
dp->pre[i], lane);
}
}
When writing voltage settings, this will overwrite the transceiver
registers for those unintended lanes. If one of those lanes is actively
assigned to USB, this could silently corrupt the active USB connection.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260612-rockchip-usbdp-cleanup-v5-0-efc83069869f@collabora.com?part=7
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v5 12/18] phy: rockchip: usbdp: Drop DP HPD handling
From: sashiko-bot @ 2026-06-12 16:53 UTC (permalink / raw)
To: Sebastian Reichel
Cc: conor+dt, robh, devicetree, vkoul, neil.armstrong, linux-phy,
olteanv
In-Reply-To: <20260612-rockchip-usbdp-cleanup-v5-12-efc83069869f@collabora.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Lockless access to shared Type-C lane mappings in `rk_udphy_dp_phy_configure` causes data race
--
commit 5858d851fd3d6f0beb8a1b3b702ddc25ce1b25b1
Author: Sebastian Reichel <sebastian.reichel@collabora.com>
phy: rockchip: usbdp: Drop DP HPD handling
This commit drops the HPD handling logic from the USBDP PHY. The registers
involved require the display controller power domain being enabled, so the HPD
signal should be handled by the displayport controller itself.
> diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
> +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
[ ... ]
> static int rk_udphy_dp_phy_configure(struct phy *phy,
> union phy_configure_opts *opts)
> {
[ ... ]
> if (dp->set_voltages) {
> for (i = 0; i < udphy->lanes; i++) {
> lane = udphy->dp_lane_sel[i];
> switch (udphy->link_rate) {
> case 1620:
> case 2700:
[Severity: High]
This isn't a bug introduced by this patch, but I noticed a potential data
race here. Does this loop access udphy->dp_lane_sel and
udphy->lane_mux_sel safely?
These arrays define the active Type-C DP lane mapping and are updated by
asynchronous Type-C subsystem events in rk_udphy_orien_sw_set() and
rk_udphy_typec_mux_set() under the protection of udphy->mutex.
Since rk_udphy_dp_phy_configure() does not hold udphy->mutex (only the
framework-level phy->mutex), could a concurrent Type-C cable orientation
or mode switch cause this code to read a partially updated lane mapping?
This might lead to incorrect DP PHY register programming, configuring the
wrong hardware lanes and causing link training or display failures.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260612-rockchip-usbdp-cleanup-v5-0-efc83069869f@collabora.com?part=12
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v5 13/18] phy: rockchip: usbdp: Rename mode_change to phy_needs_reinit
From: sashiko-bot @ 2026-06-12 16:52 UTC (permalink / raw)
To: Sebastian Reichel
Cc: robh, vkoul, conor+dt, devicetree, neil.armstrong, olteanv,
linux-phy
In-Reply-To: <20260612-rockchip-usbdp-cleanup-v5-13-efc83069869f@collabora.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] If `rk_udphy_init()` fails during a mode change or orientation switch, the PHY is left in a reset state but `udphy->status` is not updated and `phy_needs_reinit` is permanently lost. Subsequent operations will silently fail to reinitialize the PHY.
--
commit c4618d1b0b4a42d4505fb255a32ef513dc21e759
Author: Sebastian Reichel <sebastian.reichel@collabora.com>
phy: rockchip: usbdp: Rename mode_change to phy_needs_reinit
This patch renames the mode_change property to phy_needs_reinit. The rename
prepares the driver to also trigger a PHY re-initialization when the cable
orientation changes, not just when the mode changes.
> diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> index 7255c80e0fe2f..a3b4e2e0f5786 100644
> --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
> +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
[ ... ]
> @@ -968,15 +968,15 @@ static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode)
> }
>
> if (udphy->status == UDPHY_MODE_NONE) {
> - udphy->mode_change = false;
> + udphy->phy_needs_reinit = false;
> ret = rk_udphy_setup(udphy);
> if (ret)
> return ret;
>
> if (udphy->mode & UDPHY_MODE_USB)
> rk_udphy_u3_port_disable(udphy, false);
> - } else if (udphy->mode_change) {
> - udphy->mode_change = false;
> + } else if (udphy->phy_needs_reinit) {
> + udphy->phy_needs_reinit = false;
> if (udphy->mode == UDPHY_MODE_DP)
> rk_udphy_u3_port_disable(udphy, true);
>
[Severity: High]
This isn't a bug introduced by this patch, but if rk_udphy_init() fails
immediately after this block, the PHY is left in a reset state while the
udphy->phy_needs_reinit flag is permanently lost.
When changing modes on an already active PHY, rk_udphy_power_on() calls
rk_udphy_init() which immediately asserts all PHY resets. If rk_udphy_init()
subsequently fails (e.g., due to a PLL lock timeout), it leaves the resets
asserted and returns an error.
However, udphy->phy_needs_reinit is cleared right before this, and
udphy->status is not rolled back. As a result, the driver's state tracker
still believes the previously active modes are operational, but the hardware is
completely in reset.
Will future calls to rk_udphy_power_on() see phy_needs_reinit == false and
skip initialization, permanently breaking the active interfaces until a full
system reboot or module reload?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260612-rockchip-usbdp-cleanup-v5-0-efc83069869f@collabora.com?part=13
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ 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