* [PATCH net-next v2 5/8] net: dsa: mt7530: replace mt7530_read with regmap_read
From: Daniel Golle @ 2026-06-13 1:11 UTC (permalink / raw)
To: Chester A. Unal, Daniel Golle, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Matthias Brugger, AngeloGioacchino Del Regno, Russell King,
netdev, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <cover.1781312667.git.daniel@makrotopia.org>
Replace all mt7530_read() calls with direct regmap_read() calls and
remove the wrapper function. The WARN_ON_ONCE error logging is dropped
as regmap provides its own error handling.
Most callsites follow the val = mt7530_read(priv, reg) pattern and are
converted mechanically using the following semantic patch:
@@
expression priv, reg;
identifier val;
@@
-val = mt7530_read(priv, reg);
+regmap_read(priv->regmap, reg, &val);
Remaining inline uses are converted by hand.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v2: drop fix for stray 'static void' leftover now correctly squashed
into 4/8
drivers/net/dsa/mt7530.c | 113 +++++++++++++++++++--------------------
1 file changed, 56 insertions(+), 57 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index fe7e4ab5ae9c..4168adca949f 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -152,28 +152,15 @@ core_clear(struct mt7530_priv *priv, u32 reg, u32 val)
static u32
-mt7530_read(struct mt7530_priv *priv, u32 reg)
+mt7530_mii_poll(struct mt7530_dummy_poll *p)
{
- int ret;
u32 val;
- ret = regmap_read(priv->regmap, reg, &val);
- if (ret) {
- WARN_ON_ONCE(1);
- dev_err(priv->dev,
- "failed to read mt7530 register\n");
- return 0;
- }
+ regmap_read(p->priv->regmap, p->reg, &val);
return val;
}
-static u32
-mt7530_mii_poll(struct mt7530_dummy_poll *p)
-{
- return mt7530_read(p->priv, p->reg);
-}
-
static int
mt7530_fdb_cmd(struct mt7530_priv *priv, enum mt7530_fdb_cmd cmd, u32 *rsp)
{
@@ -196,7 +183,7 @@ mt7530_fdb_cmd(struct mt7530_priv *priv, enum mt7530_fdb_cmd cmd, u32 *rsp)
/* Additional sanity for read command if the specified
* entry is invalid
*/
- val = mt7530_read(priv, MT7530_ATC);
+ regmap_read(priv->regmap, MT7530_ATC, &val);
if ((cmd == MT7530_FDB_READ) && (val & ATC_INVALID))
return -EINVAL;
@@ -214,7 +201,8 @@ mt7530_fdb_read(struct mt7530_priv *priv, struct mt7530_fdb *fdb)
/* Read from ARL table into an array */
for (i = 0; i < 3; i++) {
- reg[i] = mt7530_read(priv, MT7530_TSRA1 + (i * 4));
+ regmap_read(priv->regmap, MT7530_TSRA1 + (i * 4),
+ ®[i]);
dev_dbg(priv->dev, "%s(%d) reg[%d]=0x%x\n",
__func__, __LINE__, i, reg[i]);
@@ -321,7 +309,8 @@ mt7530_setup_port6(struct dsa_switch *ds, phy_interface_t interface)
regmap_update_bits(priv->regmap, MT7530_P6ECR, P6_INTF_MODE_MASK,
P6_INTF_MODE(1));
- xtal = mt7530_read(priv, MT753X_MTRAP) & MT7530_XTAL_MASK;
+ regmap_read(priv->regmap, MT753X_MTRAP, &xtal);
+ xtal &= MT7530_XTAL_MASK;
if (xtal == MT7530_XTAL_25MHZ)
ssc_delta = 0x57;
@@ -365,9 +354,9 @@ mt7531_pll_setup(struct mt7530_priv *priv)
u32 hwstrap;
u32 val;
- val = mt7530_read(priv, MT7531_CREV);
- top_sig = mt7530_read(priv, MT7531_TOP_SIG_SR);
- hwstrap = mt7530_read(priv, MT753X_TRAP);
+ regmap_read(priv->regmap, MT7531_CREV, &val);
+ regmap_read(priv->regmap, MT7531_TOP_SIG_SR, &top_sig);
+ regmap_read(priv->regmap, MT753X_TRAP, &hwstrap);
if ((val & CHIP_REV_M) > 0)
xtal = (top_sig & PAD_MCM_SMI_EN) ? MT7531_XTAL_FSEL_40MHZ :
MT7531_XTAL_FSEL_25MHZ;
@@ -376,26 +365,26 @@ mt7531_pll_setup(struct mt7530_priv *priv)
MT7531_XTAL_FSEL_40MHZ;
/* Step 1 : Disable MT7531 COREPLL */
- val = mt7530_read(priv, MT7531_PLLGP_EN);
+ regmap_read(priv->regmap, MT7531_PLLGP_EN, &val);
val &= ~EN_COREPLL;
regmap_write(priv->regmap, MT7531_PLLGP_EN, val);
/* Step 2: switch to XTAL output */
- val = mt7530_read(priv, MT7531_PLLGP_EN);
+ regmap_read(priv->regmap, MT7531_PLLGP_EN, &val);
val |= SW_CLKSW;
regmap_write(priv->regmap, MT7531_PLLGP_EN, val);
- val = mt7530_read(priv, MT7531_PLLGP_CR0);
+ regmap_read(priv->regmap, MT7531_PLLGP_CR0, &val);
val &= ~RG_COREPLL_EN;
regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
/* Step 3: disable PLLGP and enable program PLLGP */
- val = mt7530_read(priv, MT7531_PLLGP_EN);
+ regmap_read(priv->regmap, MT7531_PLLGP_EN, &val);
val |= SW_PLLGP;
regmap_write(priv->regmap, MT7531_PLLGP_EN, val);
/* Step 4: program COREPLL output frequency to 500MHz */
- val = mt7530_read(priv, MT7531_PLLGP_CR0);
+ regmap_read(priv->regmap, MT7531_PLLGP_CR0, &val);
val &= ~RG_COREPLL_POSDIV_M;
val |= 2 << RG_COREPLL_POSDIV_S;
regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
@@ -403,13 +392,13 @@ mt7531_pll_setup(struct mt7530_priv *priv)
switch (xtal) {
case MT7531_XTAL_FSEL_25MHZ:
- val = mt7530_read(priv, MT7531_PLLGP_CR0);
+ regmap_read(priv->regmap, MT7531_PLLGP_CR0, &val);
val &= ~RG_COREPLL_SDM_PCW_M;
val |= 0x140000 << RG_COREPLL_SDM_PCW_S;
regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
break;
case MT7531_XTAL_FSEL_40MHZ:
- val = mt7530_read(priv, MT7531_PLLGP_CR0);
+ regmap_read(priv->regmap, MT7531_PLLGP_CR0, &val);
val &= ~RG_COREPLL_SDM_PCW_M;
val |= 0x190000 << RG_COREPLL_SDM_PCW_S;
regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
@@ -417,14 +406,14 @@ mt7531_pll_setup(struct mt7530_priv *priv)
}
/* Set feedback divide ratio update signal to high */
- val = mt7530_read(priv, MT7531_PLLGP_CR0);
+ regmap_read(priv->regmap, MT7531_PLLGP_CR0, &val);
val |= RG_COREPLL_SDM_PCW_CHG;
regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
/* Wait for at least 16 XTAL clocks */
usleep_range(10, 20);
/* Step 5: set feedback divide ratio update signal to low */
- val = mt7530_read(priv, MT7531_PLLGP_CR0);
+ regmap_read(priv->regmap, MT7531_PLLGP_CR0, &val);
val &= ~RG_COREPLL_SDM_PCW_CHG;
regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
@@ -435,11 +424,11 @@ mt7531_pll_setup(struct mt7530_priv *priv)
regmap_write(priv->regmap, MT7531_ANA_PLLGP_CR2, 0x4f40000);
/* Step 6: Enable MT7531 PLL */
- val = mt7530_read(priv, MT7531_PLLGP_CR0);
+ regmap_read(priv->regmap, MT7531_PLLGP_CR0, &val);
val |= RG_COREPLL_EN;
regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
- val = mt7530_read(priv, MT7531_PLLGP_EN);
+ regmap_read(priv->regmap, MT7531_PLLGP_EN, &val);
val |= EN_COREPLL;
regmap_write(priv->regmap, MT7531_PLLGP_EN, val);
usleep_range(25, 35);
@@ -698,11 +687,11 @@ mt7530_read_port_stats(struct mt7530_priv *priv, int port,
{
u32 val, reg = MT7530_PORT_MIB_COUNTER(port) + offset;
- val = mt7530_read(priv, reg);
+ regmap_read(priv->regmap, reg, &val);
*data = val;
if (size == 2) {
- val = mt7530_read(priv, reg + 4);
+ regmap_read(priv->regmap, reg + 4, &val);
*data |= (u64)val << 32;
}
}
@@ -1010,7 +999,7 @@ static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
mutex_lock(&priv->reg_mutex);
- val = mt7530_read(priv, MT753X_MTRAP);
+ regmap_read(priv->regmap, MT753X_MTRAP, &val);
val &= ~MT7530_P5_PHY0_SEL & ~MT7530_P5_MAC_SEL & ~MT7530_P5_RGMII_MODE;
@@ -1378,7 +1367,7 @@ mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
if (!dsa_is_cpu_port(ds, port))
return 0;
- val = mt7530_read(priv, MT7530_GMACCR);
+ regmap_read(priv->regmap, MT7530_GMACCR, &val);
val &= ~MAX_RX_PKT_LEN_MASK;
/* RX length also includes Ethernet header, MTK tag, and FCS length */
@@ -1577,7 +1566,7 @@ mt7530_vlan_cmd(struct mt7530_priv *priv, enum mt7530_vlan_cmd cmd, u16 vid)
return ret;
}
- val = mt7530_read(priv, MT7530_VTCR);
+ regmap_read(priv->regmap, MT7530_VTCR, &val);
if (val & VTCR_INVALID) {
dev_err(priv->dev, "read VTCR invalid\n");
return -EINVAL;
@@ -1789,14 +1778,16 @@ mt7530_port_mdb_add(struct dsa_switch *ds, int port,
const u8 *addr = mdb->addr;
u16 vid = mdb->vid;
u8 port_mask = 0;
+ u32 val;
int ret;
mutex_lock(&priv->reg_mutex);
mt7530_fdb_write(priv, vid, 0, addr, 0, STATIC_EMP);
- if (!mt7530_fdb_cmd(priv, MT7530_FDB_READ, NULL))
- port_mask = (mt7530_read(priv, MT7530_ATRD) >> PORT_MAP)
- & PORT_MAP_MASK;
+ if (!mt7530_fdb_cmd(priv, MT7530_FDB_READ, NULL)) {
+ regmap_read(priv->regmap, MT7530_ATRD, &val);
+ port_mask = (val >> PORT_MAP) & PORT_MAP_MASK;
+ }
port_mask |= BIT(port);
mt7530_fdb_write(priv, vid, port_mask, addr, -1, STATIC_ENT);
@@ -1816,14 +1807,16 @@ mt7530_port_mdb_del(struct dsa_switch *ds, int port,
const u8 *addr = mdb->addr;
u16 vid = mdb->vid;
u8 port_mask = 0;
+ u32 val;
int ret;
mutex_lock(&priv->reg_mutex);
mt7530_fdb_write(priv, vid, 0, addr, 0, STATIC_EMP);
- if (!mt7530_fdb_cmd(priv, MT7530_FDB_READ, NULL))
- port_mask = (mt7530_read(priv, MT7530_ATRD) >> PORT_MAP)
- & PORT_MAP_MASK;
+ if (!mt7530_fdb_cmd(priv, MT7530_FDB_READ, NULL)) {
+ regmap_read(priv->regmap, MT7530_ATRD, &val);
+ port_mask = (val >> PORT_MAP) & PORT_MAP_MASK;
+ }
port_mask &= ~BIT(port);
mt7530_fdb_write(priv, vid, port_mask, addr, -1,
@@ -1901,7 +1894,7 @@ mt7530_hw_vlan_del(struct mt7530_priv *priv,
new_members = entry->old_members & ~BIT(entry->port);
- val = mt7530_read(priv, MT7530_VAWD1);
+ regmap_read(priv->regmap, MT7530_VAWD1, &val);
if (!(val & VLAN_VALID)) {
dev_err(priv->dev,
"Cannot be deleted due to invalid entry\n");
@@ -1928,7 +1921,7 @@ mt7530_hw_vlan_update(struct mt7530_priv *priv, u16 vid,
/* Fetch entry */
mt7530_vlan_cmd(priv, MT7530_VTCR_RD_VID, vid);
- val = mt7530_read(priv, MT7530_VAWD1);
+ regmap_read(priv->regmap, MT7530_VAWD1, &val);
entry->old_members = (val >> PORT_MEM_SHFT) & PORT_MEM_MASK;
@@ -2046,7 +2039,7 @@ static int mt753x_port_mirror_add(struct dsa_switch *ds, int port,
if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port))
return -EEXIST;
- val = mt7530_read(priv, MT753X_MIRROR_REG(priv->id));
+ regmap_read(priv->regmap, MT753X_MIRROR_REG(priv->id), &val);
/* MT7530 only supports one monitor port */
monitor_port = MT753X_MIRROR_PORT_GET(priv->id, val);
@@ -2059,7 +2052,7 @@ static int mt753x_port_mirror_add(struct dsa_switch *ds, int port,
val |= MT753X_MIRROR_PORT_SET(priv->id, mirror->to_local_port);
regmap_write(priv->regmap, MT753X_MIRROR_REG(priv->id), val);
- val = mt7530_read(priv, MT7530_PCR_P(port));
+ regmap_read(priv->regmap, MT7530_PCR_P(port), &val);
if (ingress) {
val |= PORT_RX_MIR;
priv->mirror_rx |= BIT(port);
@@ -2078,7 +2071,7 @@ static void mt753x_port_mirror_del(struct dsa_switch *ds, int port,
struct mt7530_priv *priv = ds->priv;
u32 val;
- val = mt7530_read(priv, MT7530_PCR_P(port));
+ regmap_read(priv->regmap, MT7530_PCR_P(port), &val);
if (mirror->ingress) {
val &= ~PORT_RX_MIR;
priv->mirror_rx &= ~BIT(port);
@@ -2089,7 +2082,7 @@ static void mt753x_port_mirror_del(struct dsa_switch *ds, int port,
regmap_write(priv->regmap, MT7530_PCR_P(port), val);
if (!priv->mirror_rx && !priv->mirror_tx) {
- val = mt7530_read(priv, MT753X_MIRROR_REG(priv->id));
+ regmap_read(priv->regmap, MT753X_MIRROR_REG(priv->id), &val);
val &= ~MT753X_MIRROR_EN(priv->id);
regmap_write(priv->regmap, MT753X_MIRROR_REG(priv->id), val);
}
@@ -2121,8 +2114,11 @@ mt7530_gpio_get(struct gpio_chip *gc, unsigned int offset)
{
struct mt7530_priv *priv = gpiochip_get_data(gc);
u32 bit = mt7530_gpio_to_bit(offset);
+ u32 val;
+
+ regmap_read(priv->regmap, MT7530_LED_GPIO_DATA, &val);
- return !!(mt7530_read(priv, MT7530_LED_GPIO_DATA) & bit);
+ return !!(val & bit);
}
static int
@@ -2144,8 +2140,11 @@ mt7530_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
{
struct mt7530_priv *priv = gpiochip_get_data(gc);
u32 bit = mt7530_gpio_to_bit(offset);
+ u32 val;
+
+ regmap_read(priv->regmap, MT7530_LED_GPIO_DIR, &val);
- return (mt7530_read(priv, MT7530_LED_GPIO_DIR) & bit) ?
+ return (val & bit) ?
GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
}
@@ -2436,7 +2435,7 @@ mt7530_setup(struct dsa_switch *ds)
return ret;
}
- id = mt7530_read(priv, MT7530_CREV);
+ regmap_read(priv->regmap, MT7530_CREV, &id);
id >>= CHIP_NAME_SHIFT;
if (id != MT7530_ID) {
dev_err(priv->dev, "chip %x can't be supported\n", id);
@@ -2679,7 +2678,7 @@ mt7531_setup(struct dsa_switch *ds)
return ret;
}
- id = mt7530_read(priv, MT7531_CREV);
+ regmap_read(priv->regmap, MT7531_CREV, &id);
id >>= CHIP_NAME_SHIFT;
if (id != MT7531_ID) {
@@ -2690,7 +2689,7 @@ mt7531_setup(struct dsa_switch *ds)
/* MT7531AE has got two SGMII units. One for port 5, one for port 6.
* MT7531BE has got only one SGMII unit which is for port 6.
*/
- val = mt7530_read(priv, MT7531_TOP_SIG_SR);
+ regmap_read(priv->regmap, MT7531_TOP_SIG_SR, &val);
priv->p5_sgmii = !!(val & PAD_DUAL_SGMII_EN);
/* Force link down on all ports before internal reset */
@@ -2880,7 +2879,7 @@ static void mt7531_rgmii_setup(struct mt7530_priv *priv,
{
u32 val;
- val = mt7530_read(priv, MT7531_CLKGEN_CTRL);
+ regmap_read(priv->regmap, MT7531_CLKGEN_CTRL, &val);
val |= GP_CLK_EN;
val &= ~GP_MODE_MASK;
val |= GP_MODE(MT7531_GP_MODE_RGMII);
@@ -3059,7 +3058,7 @@ static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
config->lpi_capabilities = MAC_100FD | MAC_1000FD | MAC_2500FD;
- eeecr = mt7530_read(priv, MT753X_PMEEECR_P(port));
+ regmap_read(priv->regmap, MT753X_PMEEECR_P(port), &eeecr);
/* tx_lpi_timer should be in microseconds. The time units for
* LPI threshold are unspecified.
*/
@@ -3087,7 +3086,7 @@ static void mt7530_pcs_get_state(struct phylink_pcs *pcs, unsigned int neg_mode,
int port = pcs_to_mt753x_pcs(pcs)->port;
u32 pmsr;
- pmsr = mt7530_read(priv, MT7530_PMSR_P(port));
+ regmap_read(priv->regmap, MT7530_PMSR_P(port), &pmsr);
state->link = (pmsr & PMSR_LINK);
state->an_complete = state->link;
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v2 6/8] net: dsa: mt7530: convert to use field accessor macros
From: Daniel Golle @ 2026-06-13 1:11 UTC (permalink / raw)
To: Chester A. Unal, Daniel Golle, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Matthias Brugger, AngeloGioacchino Del Regno, Russell King,
netdev, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <cover.1781312667.git.daniel@makrotopia.org>
Use FIELD_GET and FIELD_PREP instead of open-coding register fields.
Replace 0x1f constant with (PHY_MAX_ADDR - 1)
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v2: no changes
drivers/net/dsa/mt7530.c | 64 ++++++------
drivers/net/dsa/mt7530.h | 208 ++++++++++++++++++++++-----------------
2 files changed, 148 insertions(+), 124 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 4168adca949f..dcf72ab0cd66 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -208,16 +208,16 @@ mt7530_fdb_read(struct mt7530_priv *priv, struct mt7530_fdb *fdb)
__func__, __LINE__, i, reg[i]);
}
- fdb->vid = (reg[1] >> CVID) & CVID_MASK;
- fdb->aging = (reg[2] >> AGE_TIMER) & AGE_TIMER_MASK;
- fdb->port_mask = (reg[2] >> PORT_MAP) & PORT_MAP_MASK;
- fdb->mac[0] = (reg[0] >> MAC_BYTE_0) & MAC_BYTE_MASK;
- fdb->mac[1] = (reg[0] >> MAC_BYTE_1) & MAC_BYTE_MASK;
- fdb->mac[2] = (reg[0] >> MAC_BYTE_2) & MAC_BYTE_MASK;
- fdb->mac[3] = (reg[0] >> MAC_BYTE_3) & MAC_BYTE_MASK;
- fdb->mac[4] = (reg[1] >> MAC_BYTE_4) & MAC_BYTE_MASK;
- fdb->mac[5] = (reg[1] >> MAC_BYTE_5) & MAC_BYTE_MASK;
- fdb->noarp = ((reg[2] >> ENT_STATUS) & ENT_STATUS_MASK) == STATIC_ENT;
+ fdb->vid = FIELD_GET(CVID_MASK, reg[1]);
+ fdb->aging = FIELD_GET(AGE_TIMER_RD_MASK, reg[2]);
+ fdb->port_mask = FIELD_GET(PORT_MAP_MASK, reg[2]);
+ fdb->mac[0] = FIELD_GET(MAC_BYTE_0_MASK, reg[0]);
+ fdb->mac[1] = FIELD_GET(MAC_BYTE_1_MASK, reg[0]);
+ fdb->mac[2] = FIELD_GET(MAC_BYTE_2_MASK, reg[0]);
+ fdb->mac[3] = FIELD_GET(MAC_BYTE_3_MASK, reg[0]);
+ fdb->mac[4] = FIELD_GET(MAC_BYTE_4_MASK, reg[1]);
+ fdb->mac[5] = FIELD_GET(MAC_BYTE_5_MASK, reg[1]);
+ fdb->noarp = FIELD_GET(ENT_STATUS_MASK, reg[2]) == STATIC_ENT;
}
static void
@@ -228,22 +228,22 @@ mt7530_fdb_write(struct mt7530_priv *priv, u16 vid,
u32 reg[3] = { 0 };
int i;
- reg[1] |= vid & CVID_MASK;
+ reg[1] |= FIELD_PREP(CVID_MASK, vid);
reg[1] |= ATA2_IVL;
reg[1] |= ATA2_FID(FID_BRIDGED);
- reg[2] |= (aging & AGE_TIMER_MASK) << AGE_TIMER;
- reg[2] |= (port_mask & PORT_MAP_MASK) << PORT_MAP;
+ reg[2] |= FIELD_PREP(AGE_TIMER_RD_MASK, aging);
+ reg[2] |= FIELD_PREP(PORT_MAP_MASK, port_mask);
/* STATIC_ENT indicate that entry is static wouldn't
* be aged out and STATIC_EMP specified as erasing an
* entry
*/
- reg[2] |= (type & ENT_STATUS_MASK) << ENT_STATUS;
- reg[1] |= mac[5] << MAC_BYTE_5;
- reg[1] |= mac[4] << MAC_BYTE_4;
- reg[0] |= mac[3] << MAC_BYTE_3;
- reg[0] |= mac[2] << MAC_BYTE_2;
- reg[0] |= mac[1] << MAC_BYTE_1;
- reg[0] |= mac[0] << MAC_BYTE_0;
+ reg[2] |= FIELD_PREP(ENT_STATUS_MASK, type);
+ reg[1] |= FIELD_PREP(MAC_BYTE_5_MASK, mac[5]);
+ reg[1] |= FIELD_PREP(MAC_BYTE_4_MASK, mac[4]);
+ reg[0] |= FIELD_PREP(MAC_BYTE_3_MASK, mac[3]);
+ reg[0] |= FIELD_PREP(MAC_BYTE_2_MASK, mac[2]);
+ reg[0] |= FIELD_PREP(MAC_BYTE_1_MASK, mac[1]);
+ reg[0] |= FIELD_PREP(MAC_BYTE_0_MASK, mac[0]);
/* Write array into the ARL table */
for (i = 0; i < 3; i++)
@@ -385,22 +385,22 @@ mt7531_pll_setup(struct mt7530_priv *priv)
/* Step 4: program COREPLL output frequency to 500MHz */
regmap_read(priv->regmap, MT7531_PLLGP_CR0, &val);
- val &= ~RG_COREPLL_POSDIV_M;
- val |= 2 << RG_COREPLL_POSDIV_S;
+ val &= ~RG_COREPLL_POSDIV_MASK;
+ val |= RG_COREPLL_POSDIV(2);
regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
usleep_range(25, 35);
switch (xtal) {
case MT7531_XTAL_FSEL_25MHZ:
regmap_read(priv->regmap, MT7531_PLLGP_CR0, &val);
- val &= ~RG_COREPLL_SDM_PCW_M;
- val |= 0x140000 << RG_COREPLL_SDM_PCW_S;
+ val &= ~RG_COREPLL_SDM_PCW_MASK;
+ val |= RG_COREPLL_SDM_PCW(0x140000);
regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
break;
case MT7531_XTAL_FSEL_40MHZ:
regmap_read(priv->regmap, MT7531_PLLGP_CR0, &val);
- val &= ~RG_COREPLL_SDM_PCW_M;
- val |= 0x190000 << RG_COREPLL_SDM_PCW_S;
+ val &= ~RG_COREPLL_SDM_PCW_MASK;
+ val |= RG_COREPLL_SDM_PCW(0x190000);
regmap_write(priv->regmap, MT7531_PLLGP_CR0, val);
break;
}
@@ -1555,7 +1555,7 @@ mt7530_vlan_cmd(struct mt7530_priv *priv, enum mt7530_vlan_cmd cmd, u16 vid)
u32 val;
int ret;
- val = VTCR_BUSY | VTCR_FUNC(cmd) | vid;
+ val = VTCR_BUSY | VTCR_FUNC(cmd) | VTCR_VID(vid);
regmap_write(priv->regmap, MT7530_VTCR, val);
INIT_MT7530_DUMMY_POLL(&p, priv, MT7530_VTCR);
@@ -1786,7 +1786,7 @@ mt7530_port_mdb_add(struct dsa_switch *ds, int port,
mt7530_fdb_write(priv, vid, 0, addr, 0, STATIC_EMP);
if (!mt7530_fdb_cmd(priv, MT7530_FDB_READ, NULL)) {
regmap_read(priv->regmap, MT7530_ATRD, &val);
- port_mask = (val >> PORT_MAP) & PORT_MAP_MASK;
+ port_mask = FIELD_GET(PORT_MAP_MASK, val);
}
port_mask |= BIT(port);
@@ -1815,7 +1815,7 @@ mt7530_port_mdb_del(struct dsa_switch *ds, int port,
mt7530_fdb_write(priv, vid, 0, addr, 0, STATIC_EMP);
if (!mt7530_fdb_cmd(priv, MT7530_FDB_READ, NULL)) {
regmap_read(priv->regmap, MT7530_ATRD, &val);
- port_mask = (val >> PORT_MAP) & PORT_MAP_MASK;
+ port_mask = FIELD_GET(PORT_MAP_MASK, val);
}
port_mask &= ~BIT(port);
@@ -1923,7 +1923,7 @@ mt7530_hw_vlan_update(struct mt7530_priv *priv, u16 vid,
regmap_read(priv->regmap, MT7530_VAWD1, &val);
- entry->old_members = (val >> PORT_MEM_SHFT) & PORT_MEM_MASK;
+ entry->old_members = FIELD_GET(PORT_MEM_MASK, val);
/* Manipulate entry */
vlan_op(priv, entry);
@@ -2436,7 +2436,7 @@ mt7530_setup(struct dsa_switch *ds)
}
regmap_read(priv->regmap, MT7530_CREV, &id);
- id >>= CHIP_NAME_SHIFT;
+ id = FIELD_GET(CHIP_NAME_MASK, id);
if (id != MT7530_ID) {
dev_err(priv->dev, "chip %x can't be supported\n", id);
return -ENODEV;
@@ -2679,7 +2679,7 @@ mt7531_setup(struct dsa_switch *ds)
}
regmap_read(priv->regmap, MT7531_CREV, &id);
- id >>= CHIP_NAME_SHIFT;
+ id = FIELD_GET(CHIP_NAME_MASK, id);
if (id != MT7531_ID) {
dev_err(priv->dev, "chip %x can't be supported\n", id);
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index dd33b0df3419..abf19aa69520 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -6,6 +6,8 @@
#ifndef __MT7530_H
#define __MT7530_H
+#include <linux/bitfield.h>
+
#define MT7530_NUM_PORTS 7
#define MT7530_NUM_PHYS 5
#define MT7530_NUM_FDB_RECORDS 2048
@@ -146,19 +148,22 @@ enum mt753x_to_cpu_fw {
#define STATIC_ENT 3
#define MT7530_ATA2 0x78
#define ATA2_IVL BIT(15)
-#define ATA2_FID(x) (((x) & 0x7) << 12)
+#define ATA2_FID_MASK GENMASK(14, 12)
+#define ATA2_FID(x) FIELD_PREP(ATA2_FID_MASK, x)
/* Register for address table write data */
#define MT7530_ATWD 0x7c
/* Register for address table control */
#define MT7530_ATC 0x80
-#define ATC_HASH (((x) & 0xfff) << 16)
+#define ATC_HASH_MASK GENMASK(27, 16)
+#define ATC_HASH(x) FIELD_PREP(ATC_HASH_MASK, x)
#define ATC_BUSY BIT(15)
#define ATC_SRCH_END BIT(14)
#define ATC_SRCH_HIT BIT(13)
#define ATC_INVALID BIT(12)
-#define ATC_MAT(x) (((x) & 0xf) << 8)
+#define ATC_MAT_MASK GENMASK(11, 8)
+#define ATC_MAT(x) FIELD_PREP(ATC_MAT_MASK, x)
#define ATC_MAT_MACTAB ATC_MAT(0)
enum mt7530_fdb_cmd {
@@ -171,32 +176,29 @@ enum mt7530_fdb_cmd {
/* Registers for table search read address */
#define MT7530_TSRA1 0x84
-#define MAC_BYTE_0 24
-#define MAC_BYTE_1 16
-#define MAC_BYTE_2 8
-#define MAC_BYTE_3 0
-#define MAC_BYTE_MASK 0xff
+#define MAC_BYTE_0_MASK GENMASK(31, 24)
+#define MAC_BYTE_1_MASK GENMASK(23, 16)
+#define MAC_BYTE_2_MASK GENMASK(15, 8)
+#define MAC_BYTE_3_MASK GENMASK(7, 0)
#define MT7530_TSRA2 0x88
-#define MAC_BYTE_4 24
-#define MAC_BYTE_5 16
-#define CVID 0
-#define CVID_MASK 0xfff
+#define MAC_BYTE_4_MASK GENMASK(31, 24)
+#define MAC_BYTE_5_MASK GENMASK(23, 16)
+#define CVID_MASK GENMASK(11, 0)
#define MT7530_ATRD 0x8C
-#define AGE_TIMER 24
-#define AGE_TIMER_MASK 0xff
-#define PORT_MAP 4
-#define PORT_MAP_MASK 0xff
-#define ENT_STATUS 2
-#define ENT_STATUS_MASK 0x3
+#define AGE_TIMER_RD_MASK GENMASK(31, 24)
+#define PORT_MAP_MASK GENMASK(11, 4)
+#define ENT_STATUS_MASK GENMASK(3, 2)
/* Register for vlan table control */
#define MT7530_VTCR 0x90
#define VTCR_BUSY BIT(31)
#define VTCR_INVALID BIT(16)
-#define VTCR_FUNC(x) (((x) & 0xf) << 12)
-#define VTCR_VID ((x) & 0xfff)
+#define VTCR_FUNC_MASK GENMASK(15, 12)
+#define VTCR_FUNC(x) FIELD_PREP(VTCR_FUNC_MASK, x)
+#define VTCR_VID_MASK GENMASK(11, 0)
+#define VTCR_VID(x) FIELD_PREP(VTCR_VID_MASK, x)
enum mt7530_vlan_cmd {
/* Read/Write the specified VID entry from VAWD register based
@@ -216,13 +218,13 @@ enum mt7530_vlan_cmd {
/* Per VLAN Egress Tag Control */
#define VTAG_EN BIT(28)
/* VLAN Member Control */
-#define PORT_MEM(x) (((x) & 0xff) << 16)
+#define PORT_MEM_MASK GENMASK(23, 16)
+#define PORT_MEM(x) FIELD_PREP(PORT_MEM_MASK, x)
/* Filter ID */
-#define FID(x) (((x) & 0x7) << 1)
+#define FID_MASK GENMASK(3, 1)
+#define FID(x) FIELD_PREP(FID_MASK, x)
/* VLAN Entry Valid */
#define VLAN_VALID BIT(0)
-#define PORT_MEM_SHFT 16
-#define PORT_MEM_MASK 0xff
enum mt7530_fid {
FID_STANDALONE = 0,
@@ -247,11 +249,11 @@ enum mt7530_vlan_egress_attr {
/* Age count */
#define AGE_CNT_MASK GENMASK(19, 12)
#define AGE_CNT_MAX 0xff
-#define AGE_CNT(x) (AGE_CNT_MASK & ((x) << 12))
+#define AGE_CNT(x) FIELD_PREP(AGE_CNT_MASK, x)
/* Age unit */
#define AGE_UNIT_MASK GENMASK(11, 0)
#define AGE_UNIT_MAX 0xfff
-#define AGE_UNIT(x) (AGE_UNIT_MASK & (x))
+#define AGE_UNIT(x) FIELD_PREP(AGE_UNIT_MASK, x)
#define MT753X_ERLCR_P(x) (0x1040 + ((x) * 0x100))
#define ERLCR_CIR_MASK GENMASK(31, 16)
@@ -282,30 +284,31 @@ enum mt7530_stp_state {
#define MT7530_PCR_P(x) (0x2004 + ((x) * 0x100))
#define PORT_TX_MIR BIT(9)
#define PORT_RX_MIR BIT(8)
-#define PORT_VLAN(x) ((x) & 0x3)
+#define PCR_PORT_VLAN_MASK GENMASK(1, 0)
enum mt7530_port_mode {
/* Port Matrix Mode: Frames are forwarded by the PCR_MATRIX members. */
- MT7530_PORT_MATRIX_MODE = PORT_VLAN(0),
+ MT7530_PORT_MATRIX_MODE = 0,
/* Fallback Mode: Forward received frames with ingress ports that do
* not belong to the VLAN member. Frames whose VID is not listed on
* the VLAN table are forwarded by the PCR_MATRIX members.
*/
- MT7530_PORT_FALLBACK_MODE = PORT_VLAN(1),
+ MT7530_PORT_FALLBACK_MODE = 1,
/* Security Mode: Discard any frame due to ingress membership
* violation or VID missed on the VLAN table.
*/
- MT7530_PORT_SECURITY_MODE = PORT_VLAN(3),
+ MT7530_PORT_SECURITY_MODE = 3,
};
-#define PCR_MATRIX(x) (((x) & 0xff) << 16)
-#define PORT_PRI(x) (((x) & 0x7) << 24)
-#define EG_TAG(x) (((x) & 0x3) << 28)
-#define PCR_MATRIX_MASK PCR_MATRIX(0xff)
+#define PCR_MATRIX_MASK GENMASK(23, 16)
+#define PCR_MATRIX(x) FIELD_PREP(PCR_MATRIX_MASK, x)
+#define PORT_PRI_MASK GENMASK(26, 24)
+#define PORT_PRI(x) FIELD_PREP(PORT_PRI_MASK, x)
+#define EG_TAG_MASK GENMASK(29, 28)
+#define EG_TAG(x) FIELD_PREP(EG_TAG_MASK, x)
#define PCR_MATRIX_CLR PCR_MATRIX(0)
-#define PCR_PORT_VLAN_MASK PORT_VLAN(3)
/* Register for port security control */
#define MT7530_PSC_P(x) (0x200c + ((x) * 0x100))
@@ -314,10 +317,10 @@ enum mt7530_port_mode {
/* Register for port vlan control */
#define MT7530_PVC_P(x) (0x2010 + ((x) * 0x100))
#define PORT_SPEC_TAG BIT(5)
-#define PVC_EG_TAG(x) (((x) & 0x7) << 8)
-#define PVC_EG_TAG_MASK PVC_EG_TAG(7)
-#define VLAN_ATTR(x) (((x) & 0x3) << 6)
-#define VLAN_ATTR_MASK VLAN_ATTR(3)
+#define PVC_EG_TAG_MASK GENMASK(10, 8)
+#define PVC_EG_TAG(x) FIELD_PREP(PVC_EG_TAG_MASK, x)
+#define VLAN_ATTR_MASK GENMASK(7, 6)
+#define VLAN_ATTR(x) FIELD_PREP(VLAN_ATTR_MASK, x)
#define ACC_FRM_MASK GENMASK(1, 0)
enum mt7530_vlan_port_eg_tag {
@@ -337,12 +340,13 @@ enum mt7530_vlan_port_acc_frm {
MT7530_VLAN_ACC_UNTAGGED = 2,
};
-#define STAG_VPID (((x) & 0xffff) << 16)
+#define STAG_VPID_MASK GENMASK(31, 16)
+#define STAG_VPID(x) FIELD_PREP(STAG_VPID_MASK, x)
/* Register for port port-and-protocol based vlan 1 control */
#define MT7530_PPBV1_P(x) (0x2014 + ((x) * 0x100))
-#define G0_PORT_VID(x) (((x) & 0xfff) << 0)
-#define G0_PORT_VID_MASK G0_PORT_VID(0xfff)
+#define G0_PORT_VID_MASK GENMASK(11, 0)
+#define G0_PORT_VID(x) FIELD_PREP(G0_PORT_VID_MASK, x)
#define G0_PORT_VID_DEF G0_PORT_VID(0)
/* Register for port MAC control register */
@@ -418,8 +422,8 @@ enum mt7530_vlan_port_acc_frm {
#define MT7531_DIS_CLR BIT(31)
#define MT7530_GMACCR 0x30e0
-#define MAX_RX_JUMBO(x) ((x) << 2)
#define MAX_RX_JUMBO_MASK GENMASK(5, 2)
+#define MAX_RX_JUMBO(x) FIELD_PREP(MAX_RX_JUMBO_MASK, x)
#define MAX_RX_PKT_LEN_MASK GENMASK(1, 0)
#define MAX_RX_PKT_LEN_1522 0x0
#define MAX_RX_PKT_LEN_1536 0x1
@@ -505,16 +509,16 @@ enum mt7530_vlan_port_acc_frm {
/* Register for PHY Indirect Access Control */
#define MT7531_PHY_IAC 0x701C
#define MT7531_PHY_ACS_ST BIT(31)
-#define MT7531_MDIO_REG_ADDR_MASK (0x1f << 25)
-#define MT7531_MDIO_PHY_ADDR_MASK (0x1f << 20)
-#define MT7531_MDIO_CMD_MASK (0x3 << 18)
-#define MT7531_MDIO_ST_MASK (0x3 << 16)
-#define MT7531_MDIO_RW_DATA_MASK (0xffff)
-#define MT7531_MDIO_REG_ADDR(x) (((x) & 0x1f) << 25)
-#define MT7531_MDIO_DEV_ADDR(x) (((x) & 0x1f) << 25)
-#define MT7531_MDIO_PHY_ADDR(x) (((x) & 0x1f) << 20)
-#define MT7531_MDIO_CMD(x) (((x) & 0x3) << 18)
-#define MT7531_MDIO_ST(x) (((x) & 0x3) << 16)
+#define MT7531_MDIO_REG_ADDR_MASK GENMASK(29, 25)
+#define MT7531_MDIO_PHY_ADDR_MASK GENMASK(24, 20)
+#define MT7531_MDIO_CMD_MASK GENMASK(19, 18)
+#define MT7531_MDIO_ST_MASK GENMASK(17, 16)
+#define MT7531_MDIO_RW_DATA_MASK GENMASK(15, 0)
+#define MT7531_MDIO_REG_ADDR(x) FIELD_PREP(MT7531_MDIO_REG_ADDR_MASK, x)
+#define MT7531_MDIO_DEV_ADDR(x) FIELD_PREP(MT7531_MDIO_REG_ADDR_MASK, x)
+#define MT7531_MDIO_PHY_ADDR(x) FIELD_PREP(MT7531_MDIO_PHY_ADDR_MASK, x)
+#define MT7531_MDIO_CMD(x) FIELD_PREP(MT7531_MDIO_CMD_MASK, x)
+#define MT7531_MDIO_ST(x) FIELD_PREP(MT7531_MDIO_ST_MASK, x)
enum mt7531_phy_iac_cmd {
MT7531_MDIO_ADDR = 0,
@@ -542,14 +546,14 @@ enum mt7531_mdio_st {
/* Register for RGMII clock phase */
#define MT7531_CLKGEN_CTRL 0x7500
-#define CLK_SKEW_OUT(x) (((x) & 0x3) << 8)
#define CLK_SKEW_OUT_MASK GENMASK(9, 8)
-#define CLK_SKEW_IN(x) (((x) & 0x3) << 6)
+#define CLK_SKEW_OUT(x) FIELD_PREP(CLK_SKEW_OUT_MASK, x)
#define CLK_SKEW_IN_MASK GENMASK(7, 6)
+#define CLK_SKEW_IN(x) FIELD_PREP(CLK_SKEW_IN_MASK, x)
#define RXCLK_NO_DELAY BIT(5)
#define TXCLK_NO_REVERSE BIT(4)
-#define GP_MODE(x) (((x) & 0x3) << 1)
#define GP_MODE_MASK GENMASK(2, 1)
+#define GP_MODE(x) FIELD_PREP(GP_MODE_MASK, x)
#define GP_CLK_EN BIT(0)
enum mt7531_gp_mode {
@@ -599,8 +603,10 @@ enum mt7531_xtal_fsel {
#define PAD_MCM_SMI_EN BIT(0)
#define MT7530_IO_DRV_CR 0x7810
-#define P5_IO_CLK_DRV(x) ((x) & 0x3)
-#define P5_IO_DATA_DRV(x) (((x) & 0x3) << 4)
+#define P5_IO_CLK_DRV_MASK GENMASK(1, 0)
+#define P5_IO_CLK_DRV(x) FIELD_PREP(P5_IO_CLK_DRV_MASK, x)
+#define P5_IO_DATA_DRV_MASK GENMASK(5, 4)
+#define P5_IO_DATA_DRV(x) FIELD_PREP(P5_IO_DATA_DRV_MASK, x)
#define MT7531_CHIP_REV 0x781C
@@ -610,15 +616,15 @@ enum mt7531_xtal_fsel {
#define SW_PLLGP BIT(0)
#define MT7530_P6ECR 0x7830
-#define P6_INTF_MODE_MASK 0x3
-#define P6_INTF_MODE(x) ((x) & 0x3)
+#define P6_INTF_MODE_MASK GENMASK(1, 0)
+#define P6_INTF_MODE(x) FIELD_PREP(P6_INTF_MODE_MASK, x)
#define MT7531_PLLGP_CR0 0x78a8
#define RG_COREPLL_EN BIT(22)
-#define RG_COREPLL_POSDIV_S 23
-#define RG_COREPLL_POSDIV_M 0x3800000
-#define RG_COREPLL_SDM_PCW_S 1
-#define RG_COREPLL_SDM_PCW_M 0x3ffffe
+#define RG_COREPLL_POSDIV_MASK GENMASK(25, 23)
+#define RG_COREPLL_POSDIV(x) FIELD_PREP(RG_COREPLL_POSDIV_MASK, x)
+#define RG_COREPLL_SDM_PCW_MASK GENMASK(21, 1)
+#define RG_COREPLL_SDM_PCW(x) FIELD_PREP(RG_COREPLL_SDM_PCW_MASK, x)
#define RG_COREPLL_SDM_PCW_CHG BIT(0)
/* Registers for RGMII and SGMII PLL clock */
@@ -629,10 +635,10 @@ enum mt7531_xtal_fsel {
#define MT7530_TRGMII_RCK_CTRL 0x7a00
#define RX_RST BIT(31)
#define RXC_DQSISEL BIT(30)
-#define DQSI1_TAP_MASK (0x7f << 8)
-#define DQSI0_TAP_MASK 0x7f
-#define DQSI1_TAP(x) (((x) & 0x7f) << 8)
-#define DQSI0_TAP(x) ((x) & 0x7f)
+#define DQSI1_TAP_MASK GENMASK(14, 8)
+#define DQSI0_TAP_MASK GENMASK(6, 0)
+#define DQSI1_TAP(x) FIELD_PREP(DQSI1_TAP_MASK, x)
+#define DQSI0_TAP(x) FIELD_PREP(DQSI0_TAP_MASK, x)
#define MT7530_TRGMII_RCK_RTT 0x7a04
#define DQS1_GATE BIT(31)
@@ -641,8 +647,8 @@ enum mt7531_xtal_fsel {
#define MT7530_TRGMII_RD(x) (0x7a10 + (x) * 8)
#define BSLIP_EN BIT(31)
#define EDGE_CHK BIT(30)
-#define RD_TAP_MASK 0x7f
-#define RD_TAP(x) ((x) & 0x7f)
+#define RD_TAP_MASK GENMASK(6, 0)
+#define RD_TAP(x) FIELD_PREP(RD_TAP_MASK, x)
#define MT7530_TRGMII_TXCTRL 0x7a40
#define TRAIN_TXEN BIT(31)
@@ -650,18 +656,23 @@ enum mt7531_xtal_fsel {
#define TX_RST BIT(28)
#define MT7530_TRGMII_TD_ODT(i) (0x7a54 + 8 * (i))
-#define TD_DM_DRVP(x) ((x) & 0xf)
-#define TD_DM_DRVN(x) (((x) & 0xf) << 4)
+#define TD_DM_DRVP_MASK GENMASK(3, 0)
+#define TD_DM_DRVP(x) FIELD_PREP(TD_DM_DRVP_MASK, x)
+#define TD_DM_DRVN_MASK GENMASK(7, 4)
+#define TD_DM_DRVN(x) FIELD_PREP(TD_DM_DRVN_MASK, x)
#define MT7530_TRGMII_TCK_CTRL 0x7a78
-#define TCK_TAP(x) (((x) & 0xf) << 8)
+#define TCK_TAP_MASK GENMASK(11, 8)
+#define TCK_TAP(x) FIELD_PREP(TCK_TAP_MASK, x)
#define MT7530_P5RGMIIRXCR 0x7b00
#define CSR_RGMII_EDGE_ALIGN BIT(8)
-#define CSR_RGMII_RXC_0DEG_CFG(x) ((x) & 0xf)
+#define CSR_RGMII_RXC_0DEG_CFG_MASK GENMASK(3, 0)
+#define CSR_RGMII_RXC_0DEG_CFG(x) FIELD_PREP(CSR_RGMII_RXC_0DEG_CFG_MASK, x)
#define MT7530_P5RGMIITXCR 0x7b04
-#define CSR_RGMII_TXC_CFG(x) ((x) & 0x1f)
+#define CSR_RGMII_TXC_CFG_MASK GENMASK(4, 0)
+#define CSR_RGMII_TXC_CFG(x) FIELD_PREP(CSR_RGMII_TXC_CFG_MASK, x)
/* Registers for GPIO mode */
#define MT7531_GPIO_MODE0 0x7c0c
@@ -670,9 +681,9 @@ enum mt7531_xtal_fsel {
#define MT7531_GPIO_MODE1 0x7c10
#define MT7531_GPIO11_RG_RXD2_MASK GENMASK(15, 12)
-#define MT7531_EXT_P_MDC_11 (2 << 12)
+#define MT7531_EXT_P_MDC_11 FIELD_PREP(MT7531_GPIO11_RG_RXD2_MASK, 2)
#define MT7531_GPIO12_RG_RXD3_MASK GENMASK(19, 16)
-#define MT7531_EXT_P_MDIO_12 (2 << 16)
+#define MT7531_EXT_P_MDIO_12 FIELD_PREP(MT7531_GPIO12_RG_RXD3_MASK, 2)
#define MT753X_CPORT_SPTAG_CFG 0x7c10
#define CPORT_SW2FE_STAG_EN BIT(1)
@@ -704,7 +715,7 @@ enum mt7531_xtal_fsel {
#define MT7530_LED_GPIO_DATA 0x7d18
#define MT7530_CREV 0x7ffc
-#define CHIP_NAME_SHIFT 16
+#define CHIP_NAME_MASK GENMASK(31, 16)
#define MT7530_ID 0x7530
#define MT7531_CREV 0x781C
@@ -716,10 +727,13 @@ enum mt7531_xtal_fsel {
#define RG_SYSPLL_EN_NORMAL BIT(15)
#define RG_SYSPLL_VODEN BIT(14)
#define RG_SYSPLL_LF BIT(13)
-#define RG_SYSPLL_RST_DLY(x) (((x) & 0x3) << 12)
+#define RG_SYSPLL_RST_DLY_MASK GENMASK(13, 12)
+#define RG_SYSPLL_RST_DLY(x) FIELD_PREP(RG_SYSPLL_RST_DLY_MASK, x)
#define RG_SYSPLL_LVROD_EN BIT(10)
-#define RG_SYSPLL_PREDIV(x) (((x) & 0x3) << 8)
-#define RG_SYSPLL_POSDIV(x) (((x) & 0x3) << 5)
+#define RG_SYSPLL_PREDIV_MASK GENMASK(9, 8)
+#define RG_SYSPLL_PREDIV(x) FIELD_PREP(RG_SYSPLL_PREDIV_MASK, x)
+#define RG_SYSPLL_POSDIV_MASK GENMASK(6, 5)
+#define RG_SYSPLL_POSDIV(x) FIELD_PREP(RG_SYSPLL_POSDIV_MASK, x)
#define RG_SYSPLL_FBKSEL BIT(4)
#define RT_SYSPLL_EN_AFE_OLT BIT(0)
@@ -731,38 +745,48 @@ enum mt7531_xtal_fsel {
#define MT7531_PHY_PLL_OFF BIT(5)
#define MT7531_PHY_PLL_BYPASS_MODE BIT(4)
-#define MT753X_CTRL_PHY_ADDR(addr) ((addr + 1) & 0x1f)
+#define MT753X_CTRL_PHY_ADDR(addr) (((addr) + 1) & (PHY_MAX_ADDR - 1))
#define CORE_PLL_GROUP5 0x404
-#define RG_LCDDS_PCW_NCPO1(x) ((x) & 0xffff)
+#define RG_LCDDS_PCW_NCPO1_MASK GENMASK(15, 0)
+#define RG_LCDDS_PCW_NCPO1(x) FIELD_PREP(RG_LCDDS_PCW_NCPO1_MASK, x)
#define CORE_PLL_GROUP6 0x405
-#define RG_LCDDS_PCW_NCPO0(x) ((x) & 0xffff)
+#define RG_LCDDS_PCW_NCPO0_MASK GENMASK(15, 0)
+#define RG_LCDDS_PCW_NCPO0(x) FIELD_PREP(RG_LCDDS_PCW_NCPO0_MASK, x)
#define CORE_PLL_GROUP7 0x406
#define RG_LCDDS_PWDB BIT(15)
#define RG_LCDDS_ISO_EN BIT(13)
-#define RG_LCCDS_C(x) (((x) & 0x7) << 4)
+#define RG_LCCDS_C_MASK GENMASK(6, 4)
+#define RG_LCCDS_C(x) FIELD_PREP(RG_LCCDS_C_MASK, x)
#define RG_LCDDS_PCW_NCPO_CHG BIT(3)
#define CORE_PLL_GROUP10 0x409
-#define RG_LCDDS_SSC_DELTA(x) ((x) & 0xfff)
+#define RG_LCDDS_SSC_DELTA_MASK GENMASK(11, 0)
+#define RG_LCDDS_SSC_DELTA(x) FIELD_PREP(RG_LCDDS_SSC_DELTA_MASK, x)
#define CORE_PLL_GROUP11 0x40a
-#define RG_LCDDS_SSC_DELTA1(x) ((x) & 0xfff)
+#define RG_LCDDS_SSC_DELTA1_MASK GENMASK(11, 0)
+#define RG_LCDDS_SSC_DELTA1(x) FIELD_PREP(RG_LCDDS_SSC_DELTA1_MASK, x)
#define CORE_GSWPLL_GRP1 0x40d
-#define RG_GSWPLL_PREDIV(x) (((x) & 0x3) << 14)
-#define RG_GSWPLL_POSDIV_200M(x) (((x) & 0x3) << 12)
+#define RG_GSWPLL_PREDIV_MASK GENMASK(15, 14)
+#define RG_GSWPLL_PREDIV(x) FIELD_PREP(RG_GSWPLL_PREDIV_MASK, x)
+#define RG_GSWPLL_POSDIV_200M_MASK GENMASK(13, 12)
+#define RG_GSWPLL_POSDIV_200M(x) FIELD_PREP(RG_GSWPLL_POSDIV_200M_MASK, x)
#define RG_GSWPLL_EN_PRE BIT(11)
#define RG_GSWPLL_FBKSEL BIT(10)
#define RG_GSWPLL_BP BIT(9)
#define RG_GSWPLL_BR BIT(8)
-#define RG_GSWPLL_FBKDIV_200M(x) ((x) & 0xff)
+#define RG_GSWPLL_FBKDIV_200M_MASK GENMASK(7, 0)
+#define RG_GSWPLL_FBKDIV_200M(x) FIELD_PREP(RG_GSWPLL_FBKDIV_200M_MASK, x)
#define CORE_GSWPLL_GRP2 0x40e
-#define RG_GSWPLL_POSDIV_500M(x) (((x) & 0x3) << 8)
-#define RG_GSWPLL_FBKDIV_500M(x) ((x) & 0xff)
+#define RG_GSWPLL_POSDIV_500M_MASK GENMASK(9, 8)
+#define RG_GSWPLL_POSDIV_500M(x) FIELD_PREP(RG_GSWPLL_POSDIV_500M_MASK, x)
+#define RG_GSWPLL_FBKDIV_500M_MASK GENMASK(7, 0)
+#define RG_GSWPLL_FBKDIV_500M(x) FIELD_PREP(RG_GSWPLL_FBKDIV_500M_MASK, x)
#define CORE_TRGMII_GSW_CLK_CG 0x410
#define REG_GSWCK_EN BIT(0)
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v2 7/8] net: dsa: mt7530: implement port_fast_age
From: Daniel Golle @ 2026-06-13 1:11 UTC (permalink / raw)
To: Chester A. Unal, Daniel Golle, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Matthias Brugger, AngeloGioacchino Del Regno, Russell King,
netdev, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <cover.1781312667.git.daniel@makrotopia.org>
Implement the .port_fast_age DSA operation by flushing all non-static
(dynamically learned) MAC address entries from the address table.
The switch does not offer a combined "non-static AND per-port" match
mode, so flush all dynamic entries globally. This is consistent with
what other DSA drivers do (b53, realtek) and relearning is fast.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v2: no changes
drivers/net/dsa/mt7530.c | 16 ++++++++++++++++
drivers/net/dsa/mt7530.h | 1 +
2 files changed, 17 insertions(+)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index dcf72ab0cd66..c96420c291d5 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -193,6 +193,21 @@ mt7530_fdb_cmd(struct mt7530_priv *priv, enum mt7530_fdb_cmd cmd, u32 *rsp)
return 0;
}
+static void mt7530_port_fast_age(struct dsa_switch *ds, int port)
+{
+ struct mt7530_priv *priv = ds->priv;
+ struct mt7530_dummy_poll p;
+ u32 val;
+
+ /* Flush all non-static MAC address entries */
+ val = ATC_BUSY | ATC_MAT_NON_STATIC_MAC | MT7530_FDB_FLUSH;
+ regmap_write(priv->regmap, MT7530_ATC, val);
+
+ INIT_MT7530_DUMMY_POLL(&p, priv, MT7530_ATC);
+ readx_poll_timeout(mt7530_mii_poll, &p, val,
+ !(val & ATC_BUSY), 20, 20000);
+}
+
static void
mt7530_fdb_read(struct mt7530_priv *priv, struct mt7530_fdb *fdb)
{
@@ -3319,6 +3334,7 @@ static const struct dsa_switch_ops mt7530_switch_ops = {
.port_bridge_flags = mt7530_port_bridge_flags,
.port_bridge_join = mt7530_port_bridge_join,
.port_bridge_leave = mt7530_port_bridge_leave,
+ .port_fast_age = mt7530_port_fast_age,
.port_fdb_add = mt7530_port_fdb_add,
.port_fdb_del = mt7530_port_fdb_del,
.port_fdb_dump = mt7530_port_fdb_dump,
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index abf19aa69520..decad7a93dbd 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -165,6 +165,7 @@ enum mt753x_to_cpu_fw {
#define ATC_MAT_MASK GENMASK(11, 8)
#define ATC_MAT(x) FIELD_PREP(ATC_MAT_MASK, x)
#define ATC_MAT_MACTAB ATC_MAT(0)
+#define ATC_MAT_NON_STATIC_MAC ATC_MAT(4)
enum mt7530_fdb_cmd {
MT7530_FDB_READ = 0,
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v2 8/8] net: dsa: mt7530: implement port_change_conduit op
From: Daniel Golle @ 2026-06-13 1:11 UTC (permalink / raw)
To: Chester A. Unal, Daniel Golle, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Matthias Brugger, AngeloGioacchino Del Regno, Russell King,
netdev, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <cover.1781312667.git.daniel@makrotopia.org>
Allow changing the CPU port affinity of user ports at runtime via the
IFLA_DSA_CONDUIT netlink attribute. This updates the port matrix to
forward to the new CPU port instead of the old one.
Limit the operation to MT7531. There, trapped link-local frames follow
the per-port affinity, as the MT7531_CPU_PMAP destination mask is
further restricted by the port matrix. A conduit change is hence fully
honoured by the hardware, for regular traffic as well as for trapped
frames.
The MT7530 switch, including the variant embedded in the MT7621 SoC,
instead traps frames to the single CPU port set in the CPU_PORT field
of the MFC register, regardless of the affinity of the inbound user
port. With user ports affine to different CPU ports there is no
correct value for that field, so per-port CPU affinity cannot be fully
implemented for trapped frames. Routing a WAN port via the second SoC
GMAC is conventionally covered by the PHY muxing feature on these
switches, which bypasses the switch fabric and does not involve a CPU
port at all.
The switches on the MT7988, EN7581 and AN7583 SoCs only have a
single CPU port, leaving no other conduit to change to.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v2: extend commit message
drivers/net/dsa/mt7530.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index c96420c291d5..2f3e734b9f53 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -3206,6 +3206,34 @@ static int mt753x_set_mac_eee(struct dsa_switch *ds, int port,
return 0;
}
+static int
+mt753x_port_change_conduit(struct dsa_switch *ds, int port,
+ struct net_device *conduit,
+ struct netlink_ext_ack *extack)
+{
+ struct dsa_port *new_cpu_dp = conduit->dsa_ptr;
+ struct dsa_port *dp = dsa_to_port(ds, port);
+ struct mt7530_priv *priv = ds->priv;
+
+ if (priv->id != ID_MT7531)
+ return -EOPNOTSUPP;
+
+ mutex_lock(&priv->reg_mutex);
+
+ /* dp->cpu_dp still points to the old CPU port */
+ priv->ports[port].pm &= ~PCR_MATRIX(BIT(dp->cpu_dp->index));
+ priv->ports[port].pm |= PCR_MATRIX(BIT(new_cpu_dp->index));
+ if (priv->ports[port].enable)
+ regmap_update_bits(priv->regmap, MT7530_PCR_P(port),
+ PCR_MATRIX_MASK, priv->ports[port].pm);
+
+ mutex_unlock(&priv->reg_mutex);
+
+ mt7530_port_fast_age(ds, port);
+
+ return 0;
+}
+
static void
mt753x_conduit_state_change(struct dsa_switch *ds,
const struct net_device *conduit,
@@ -3317,6 +3345,7 @@ static const struct dsa_switch_ops mt7530_switch_ops = {
.setup = mt753x_setup,
.teardown = mt753x_teardown,
.preferred_default_local_cpu_port = mt753x_preferred_default_local_cpu_port,
+ .port_change_conduit = mt753x_port_change_conduit,
.get_strings = mt7530_get_strings,
.get_ethtool_stats = mt7530_get_ethtool_stats,
.get_sset_count = mt7530_get_sset_count,
--
2.54.0
^ permalink raw reply related
* Re: [PATCH v7 04/30] drm/display: scdc_helper: Add HDMI 2.0 scrambling management helpers
From: Cristian Ciocaltea @ 2026-06-13 1:30 UTC (permalink / raw)
To: Maxime Ripard
Cc: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Luca Ceresoli, Sandy Huang,
Heiko Stübner, Andy Yan, Daniel Stone, Dave Stevenson,
Maíra Canal, Raspberry Pi Kernel Maintenance, kernel,
dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip
In-Reply-To: <20260612-cordial-steadfast-cow-fcaf01@houat>
On 6/12/26 4:43 PM, Maxime Ripard wrote:
> On Tue, Jun 02, 2026 at 01:44:04AM +0300, Cristian Ciocaltea wrote:
>> +/**
>> + * drm_scdc_start_scrambling - activate scrambling and monitor SCDC status
>> + * @connector: connector
>> + *
>> + * Enables scrambling and high TMDS clock ratio on both source and sink sides.
>> + * Additionally, use a delayed work item to monitor the scrambling status on
>> + * the sink side and retry the operation, as some displays refuse to set the
>> + * scrambling bit right away.
>> + *
>> + * Returns:
>> + * Zero if scrambling is set successfully, an error code otherwise.
>> + */
>> +int drm_scdc_start_scrambling(struct drm_connector *connector)
>> +{
>> + struct drm_display_info *info = &connector->display_info;
>> + struct drm_connector_hdmi *hdmi = &connector->hdmi;
>> + int ret;
>> + u8 ver;
>> +
>> + if (!hdmi->scrambler_supported) {
>> + drm_scdc_dbg(connector, "Scrambler not supported, bailing.\n");
>> + return -EINVAL;
>> + }
>> +
>> + if (!info->is_hdmi ||
>> + !info->hdmi.scdc.supported ||
>> + !info->hdmi.scdc.scrambling.supported) {
>> + drm_scdc_dbg(connector, "Sink doesn't support scrambling.\n");
>> + return -EINVAL;
>> + }
>> +
>> + drm_scdc_dbg(connector, "Enabling scrambling\n");
>> +
>> + ret = drm_scdc_readb(connector->ddc, SCDC_SINK_VERSION, &ver);
>> + if (ret) {
>> + drm_scdc_dbg(connector, "Failed to read SCDC_SINK_VERSION: %d\n", ret);
>> + return ret;
>> + }
>> +
>> + ret = drm_scdc_writeb(connector->ddc, SCDC_SOURCE_VERSION,
>> + min_t(u8, ver, SCDC_MAX_SOURCE_VERSION));
>> + if (ret) {
>> + drm_scdc_dbg(connector, "Failed to write SCDC_SOURCE_VERSION: %d\n", ret);
>> + return ret;
>> + }
>> +
>> + hdmi->scdc_cb = drm_scdc_monitor_scrambler;
>> + WRITE_ONCE(hdmi->scrambler_enabled, true);
>> +
>> + ret = drm_scdc_try_scrambling_setup(connector);
>> + if (!ret)
>> + ret = hdmi->funcs->scrambler_enable(connector);
>> +
>> + if (ret) {
>> + WRITE_ONCE(hdmi->scrambler_enabled, false);
>> + cancel_delayed_work_sync(&hdmi->scdc_work);
>> + hdmi->scdc_cb = NULL;
>> +
>> + drm_scdc_set_scrambling(connector, false);
>> + drm_scdc_set_high_tmds_clock_ratio(connector, false);
>> + }
>> +
>> + return ret;
>> +}
>> +EXPORT_SYMBOL(drm_scdc_start_scrambling);
>
> This is also pretty significantly different than what vc4 implemented. I
> don't necessarily mind, but claiming that it's functionally equivalent
> isn't true. I think it would be a much better strategy to turn the vc4
> code into helpers as is because it's been merged 4 years ago and we know
> it's solid.
As explained in patch 25, I think there's been a slight misunderstanding of how
the CRTC reset logic was actually implemented.
> Then, if you want to add additional checks and constraints (like the
> SCDC_SINK_VERSION) that's fine, but it should come on top, and with its
> own explanation.
I'll recheck if there's anything that I might have missed from the original
implementation, while moving the additional changes to separate patch(es).
Thanks,
Cristian
^ permalink raw reply
* [PATCH v8 next 04/10 Resend] arm_mpam: Refactor rmid to reqPARTID/PMG mapping
From: Zeng Heng @ 2026-06-13 2:57 UTC (permalink / raw)
To: James Morse, ben.horgan, Dave.Martin, tan.shaopeng,
reinette.chatre, fenghuay, tglx, will, hpa, bp, babu.moger,
dave.hansen, mingo, tony.luck, gshan, catalin.marinas
Cc: linux-arm-kernel, x86, linux-kernel, Kefeng Wang
In-Reply-To: <924fbfbc-995f-e291-8849-efcb8e01ef98@huawei.com>
Hi James,
Resent from huaweicloud email to avoid being filtered as spam.
----------
>> @@ -478,6 +518,7 @@ static int __read_mon(struct mpam_resctrl_mon *mon, struct mpam_component *mon_c
>> enum resctrl_conf_type cdp_type, u32 closid, u32 rmid, u64 *val)
>> {
>> struct mon_cfg cfg;
>> + u32 reqpartid = rmid2reqpartid(rmid);
>>
>> if (!mpam_is_enabled())
>> return -EINVAL;
>> @@ -493,8 +534,8 @@ static int __read_mon(struct mpam_resctrl_mon *mon, struct mpam_component *mon_c
>> cfg = (struct mon_cfg) {
>> .mon = mon_idx,
>> .match_pmg = true,
>> - .partid = closid,
>> - .pmg = rmid,
>> + .partid = (cdp_type == CDP_CODE) ? reqpartid + 1 : reqpartid,
>> + .pmg = rmid2pmg(rmid),
>
> Not using the CLOSID here breaks multiple control groups.
>
After carefully reviewing your comments and Martin's patch series,
I tried to understand why there is insistence that CLOSID information
is necessary to support multiple control groups, but that is actually
not the case.
Before proceeding, please allow me to refer to base_partid as CPARTID
(control partition ID; I'm no longer borrowing the intPARTID concept
here). The associated partids_per_closid all share the same control
scheme.
The partids derived from partids_per_closid under a given CPARTID,
I will call MPARTID (monitor partition ID; no longer borrowing the
reqPARTID concept). These represent the PARTIDs used for different
monitoring groups under the same control scheme.
I've summarized the ID translation schemes from James and Martin as
follows:
+-------------------------------+------------------+
| CLOSID |{CDP}| RMID |
+-------------------------------+------------+-----+
| MPARTID | PMG |
| CPARTID(or MPARTID_hi) : MPARTID_lo | |
+--------------------------------------------+-----+
Where closid = cpartid (base_partid or mpartid_hi),
rmid = mpartid_lo * pmg_num + pmg,
with mpartid_lo in the range [0, partids_per_closid).
In this scheme, CLOSID and RMID are coupled together to form MPARTID,
which represents the monitor group PARTID.
In current patchset design, decoupling CLOSID and RMID, letting them
represent CPARTID and MPARTID respectively:
+---------------------------------------------+
| CLOSID |{CDP}|
+---------------------------------------------+
| CPARTID |
+---------------------------------------------+
+---------------------------------------------+
| RMID |
+---------------------------------------+-----+
| MPARTID | PMG |
| MPARTID_hi(or CPARTID) : MPARTID_lo | |
+---------------------------------------+-----+
Where closid = cpartid (base_partid or mpartid_hi),
rmid = mpartid * pmg_num + pmg,
and mpartid = mpartid_hi * partids_per_closid + mpartid_lo .
The design intent is to decouple CLOSID and RMID, rather than having
RMID depend on CLOSID to derive MPARTID. This decoupling is essential
for future dynamic allocation, because the relationship between MPARTID
and CPARTID must rely on table lookup rather than linear mapping. If
don't decouple in the static allocation design, we would need another
refactor when considering dynamic allocation extensibility.
The control path uses CLOSID alone (CPARTID), and the monitor path uses
RMID alone (the (MPARTID, PMG) pair). This definition also aligns
closely with the native resctrl concepts: CLOSID (Class of Service ID,
corresponding to CPARTID) and RMID (Resource Monitor ID, corresponding
to the (MPARTID, PMG) pair).
In the end, the number of control groups is determined by the number of
CPARTIDs. Both of these ID translation schemes support multiple control
groups.
Please allow me to rework the patch series into v9 based on my current
patches, incorporating your review feedback.
Best Regards,
Zeng Heng
^ permalink raw reply
* Re: [PATCH v2 3/7] arm64: dts: qcom: shikra: Add CAMSS node
From: Nihal Kumar Gupta @ 2026-06-13 4:10 UTC (permalink / raw)
To: Vladimir Zapolskiy, Bryan O'Donoghue, Loic Poulain,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Robert Foss, Andi Shyti, Bryan O'Donoghue,
Bjorn Andersson, Konrad Dybcio, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel, linux-i2c,
imx, linux-arm-kernel, Suresh Vankadara, Vikram Sharma
In-Reply-To: <3ec2bd75-4d88-492e-a8c2-b21000ef2afc@linaro.org>
On 12-06-2026 13:26, Vladimir Zapolskiy wrote:
>> + iommus = <&apps_smmu 0x400 0x0>;
>> + power-domains = <&gcc GCC_CAMSS_TOP_GDSC>;
>
> Please add an empty line between the properties above.
>
>> +
ACK
--
Regards,
Nihal Kumar Gupta
^ permalink raw reply
* Re: [PATCH] net: correcting section tags for .init and .exit data/functions
From: kernel test robot @ 2026-06-13 4:34 UTC (permalink / raw)
To: xur, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Neal Cardwell, Kuniyuki Iwashima, Willem de Bruijn,
David Ahern, Ido Schimmel, Andreas Färber,
Manivannan Sadhasivam, Nathan Chancellor, Nick Desaulniers,
Bill Wendling, Justin Stitt, Maciej Żenczykowski,
Yue Haibing, Jeff Layton, Kees Cook, Fernando Fernandez Mancera,
Gustavo A. R. Silva, Sabrina Dubroca, Masahiro Yamada,
Nicolas Schier, linux-kernel, linux-arm-kernel, linux-actions
Cc: llvm, oe-kbuild-all, netdev
In-Reply-To: <20260612162257.896792-1-xur@google.com>
Hi,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 2b414a95b8f7307d42173ba9e580d6d3e2bcbfce]
url: https://github.com/intel-lab-lkp/linux/commits/xur-google-com/net-correcting-section-tags-for-init-and-exit-data-functions/20260613-002737
base: 2b414a95b8f7307d42173ba9e580d6d3e2bcbfce
patch link: https://lore.kernel.org/r/20260612162257.896792-1-xur%40google.com
patch subject: [PATCH] net: correcting section tags for .init and .exit data/functions
config: loongarch-defconfig (https://download.01.org/0day-ci/archive/20260613/202606131256.P9NXJENl-lkp@intel.com/config)
compiler: clang version 23.0.0git (https://github.com/llvm/llvm-project 305faf498a4e0b52b40742c927af63ab2082e1a9)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260613/202606131256.P9NXJENl-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202606131256.P9NXJENl-lkp@intel.com/
All warnings (new ones prefixed by >>, old ones prefixed by <<):
>> WARNING: modpost: vmlinux: section mismatch in reference: tcpv6_init+0x74 (section: .text) -> mptcpv6_init (section: .init.text)
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH v2 6/7] arm64: dts: qcom: shikra-cqm-cqs-evk-imx577-camera: Add DT overlay
From: Nihal Kumar Gupta @ 2026-06-13 4:46 UTC (permalink / raw)
To: Vladimir Zapolskiy, Bryan O'Donoghue, Loic Poulain,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Robert Foss, Andi Shyti, Bryan O'Donoghue,
Bjorn Andersson, Konrad Dybcio, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel, linux-i2c,
imx, linux-arm-kernel, Suresh Vankadara, Vikram Sharma
In-Reply-To: <b10ecb42-0d4f-4037-b786-cc52bcd1bdd6@linaro.org>
On 12-06-2026 13:40, Vladimir Zapolskiy wrote:
>> + imx577_ep1: endpoint {
>> + link-frequencies = /bits/ 64 <600000000>;
>> + data-lanes = <0 1 2 3>;
>
> The numeration of data-lanes shall be started from 1, this has to be fixed.
>
Thanks for pointing it.
Will fix in v3. On MIPI D-PHY, lane 0 is the clock lane, so data lanes
must start from 1 as per video-interfaces.yaml binding spec.
>> + remote-endpoint = <&csiphy1_ep>;
>> + };
>> + };
>> + };
>> +&tlmm {
>> + cam1_reset_default: cam1-reset-default-state {
>> + pins = "gpio33";
>> + function = "gpio";
>> + drive-strength = <2>;
>> + bias-disable;
>> + };
>> +};
>
> Since it's a mezzanine specific pinctl assignment, it shall go to the
> correspondent .dtso file.
>
> It's a concidence that one .dtso file is good enough for describing the
> mezzanine for two diffferent boards, but let's exploit it by keeping one
> dt overlay file as it is now.
Agreed, will move it to the .dtso in v3.
This also eliminates the identical cam1_reset_default block duplicated across
CQM and CQS board files.
Will incorporate this for the IQS dtso file.
--
Regards,
Nihal Kumar Gupta
^ permalink raw reply
* Re: [PATCH] net: correcting section tags for .init and .exit data/functions
From: kernel test robot @ 2026-06-13 4:57 UTC (permalink / raw)
To: xur, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Neal Cardwell, Kuniyuki Iwashima, Willem de Bruijn,
David Ahern, Ido Schimmel, Andreas Färber,
Manivannan Sadhasivam, Nathan Chancellor, Nick Desaulniers,
Bill Wendling, Justin Stitt, Maciej Żenczykowski,
Yue Haibing, Jeff Layton, Kees Cook, Fernando Fernandez Mancera,
Gustavo A. R. Silva, Sabrina Dubroca, Masahiro Yamada,
Nicolas Schier, linux-kernel, linux-arm-kernel, linux-actions
Cc: oe-kbuild-all, netdev
In-Reply-To: <20260612162257.896792-1-xur@google.com>
Hi,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 2b414a95b8f7307d42173ba9e580d6d3e2bcbfce]
url: https://github.com/intel-lab-lkp/linux/commits/xur-google-com/net-correcting-section-tags-for-init-and-exit-data-functions/20260613-002737
base: 2b414a95b8f7307d42173ba9e580d6d3e2bcbfce
patch link: https://lore.kernel.org/r/20260612162257.896792-1-xur%40google.com
patch subject: [PATCH] net: correcting section tags for .init and .exit data/functions
config: csky-defconfig (https://download.01.org/0day-ci/archive/20260613/202606131254.r0pBxDPY-lkp@intel.com/config)
compiler: csky-linux-gcc (GCC) 16.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260613/202606131254.r0pBxDPY-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202606131254.r0pBxDPY-lkp@intel.com/
All warnings (new ones prefixed by >>, old ones prefixed by <<):
WARNING: modpost: vmlinux: section mismatch in reference: tcpv6_init+0x66 (section: .text) -> mptcpv6_init (section: .init.text)
>> WARNING: modpost: vmlinux: section mismatch in reference: tcpv6_exit+0x58 (section: .text) -> mptcpv6_init (section: .init.text)
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* [PATCH v2 1/2] dt-bindings: clock: exynos990: Add CLK_GOUT_PERIS_TMU_SUB_PCLK
From: Denzeel Oliva @ 2026-06-13 5:19 UTC (permalink / raw)
To: Krzysztof Kozlowski, Sylwester Nawrocki, Chanwoo Choi,
Peter Griffin, Alim Akhtar, Michael Turquette, Stephen Boyd,
Brian Masney, Rob Herring, Conor Dooley
Cc: linux-samsung-soc, linux-clk, devicetree, linux-arm-kernel,
linux-kernel, Denzeel Oliva
In-Reply-To: <20260613-exynos990-peris-fix-v2-v2-0-3dff7ade75b3@gmail.com>
Add the missing TMU_SUB_PCLK clock ID for the Exynos990 PERIS CMU.
Signed-off-by: Denzeel Oliva <wachiturroxd150@gmail.com>
---
include/dt-bindings/clock/samsung,exynos990.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/dt-bindings/clock/samsung,exynos990.h b/include/dt-bindings/clock/samsung,exynos990.h
index 47540307cb52..c06f591d9d90 100644
--- a/include/dt-bindings/clock/samsung,exynos990.h
+++ b/include/dt-bindings/clock/samsung,exynos990.h
@@ -434,5 +434,6 @@
#define CLK_GOUT_PERIS_TMU_TOP_PCLK 17
#define CLK_GOUT_PERIS_OTP_CON_BIRA_OSCCLK 18
#define CLK_GOUT_PERIS_OTP_CON_TOP_OSCCLK 19
+#define CLK_GOUT_PERIS_TMU_SUB_PCLK 20
#endif
--
2.54.0
^ permalink raw reply related
* [PATCH v2 0/2] clk: samsung: exynos990: Fix PERIS gate clock parents and add TMU_SUB
From: Denzeel Oliva @ 2026-06-13 5:19 UTC (permalink / raw)
To: Krzysztof Kozlowski, Sylwester Nawrocki, Chanwoo Choi,
Peter Griffin, Alim Akhtar, Michael Turquette, Stephen Boyd,
Brian Masney, Rob Herring, Conor Dooley
Cc: linux-samsung-soc, linux-clk, devicetree, linux-arm-kernel,
linux-kernel, Denzeel Oliva
Fix PERIS CMU gate clock parent mismatches and add the missing
TMU_SUB_PCLK clock.
Split into dt-bindings (clock ID) and driver (parent fixes) as
required by checkpatch.
Changes in v2:
- Split dt-bindings header change into separate patch (1/2)
- Driver fix now only touches clk-exynos990.c (2/2)
- Add proper cover letter
v1: TODO-add-lore-link
Signed-off-by: Denzeel Oliva <wachiturroxd150@gmail.com>
---
Denzeel Oliva (2):
dt-bindings: clock: exynos990: Add CLK_GOUT_PERIS_TMU_SUB_PCLK
clk: samsung: exynos990: Fix PERIS gate clock parents
drivers/clk/samsung/clk-exynos990.c | 24 ++++++++++++++----------
include/dt-bindings/clock/samsung,exynos990.h | 1 +
2 files changed, 15 insertions(+), 10 deletions(-)
---
base-commit: c425609d6ac4012c8bbf01ec2e10e801b1923a7b
change-id: 20260613-exynos990-peris-fix-v2-619c3a30b36c
Best regards,
--
Denzeel Oliva <wachiturroxd150@gmail.com>
^ permalink raw reply
* [PATCH v2 2/2] clk: samsung: exynos990: Fix PERIS gate clock parents
From: Denzeel Oliva @ 2026-06-13 5:19 UTC (permalink / raw)
To: Krzysztof Kozlowski, Sylwester Nawrocki, Chanwoo Choi,
Peter Griffin, Alim Akhtar, Michael Turquette, Stephen Boyd,
Brian Masney, Rob Herring, Conor Dooley
Cc: linux-samsung-soc, linux-clk, devicetree, linux-arm-kernel,
linux-kernel, Denzeel Oliva
In-Reply-To: <20260613-exynos990-peris-fix-v2-v2-0-3dff7ade75b3@gmail.com>
Correct eight PERIS gate clock parents to match the hardware clock
tree, reorder the GIC mux parents, and add the missing TMU_SUB_PCLK
gate.
Signed-off-by: Denzeel Oliva <wachiturroxd150@gmail.com>
---
drivers/clk/samsung/clk-exynos990.c | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/drivers/clk/samsung/clk-exynos990.c b/drivers/clk/samsung/clk-exynos990.c
index 4385c3b76dd6..df5928833b23 100644
--- a/drivers/clk/samsung/clk-exynos990.c
+++ b/drivers/clk/samsung/clk-exynos990.c
@@ -21,7 +21,7 @@
#define CLKS_NR_HSI0 (CLK_GOUT_HSI0_LHS_ACEL_D_HSI0_CLK + 1)
#define CLKS_NR_PERIC0 (CLK_GOUT_PERIC0_SYSREG_PCLK + 1)
#define CLKS_NR_PERIC1 (CLK_GOUT_PERIC1_XIU_P_ACLK + 1)
-#define CLKS_NR_PERIS (CLK_GOUT_PERIS_OTP_CON_TOP_OSCCLK + 1)
+#define CLKS_NR_PERIS (CLK_GOUT_PERIS_TMU_SUB_PCLK + 1)
/* ---- CMU_TOP ------------------------------------------------------------- */
@@ -2551,7 +2551,7 @@ static const unsigned long peris_clk_regs[] __initconst = {
/* Parent clock list for CMU_PERIS muxes */
PNAME(mout_peris_bus_user_p) = { "oscclk", "mout_cmu_peris_bus" };
-PNAME(mout_peris_clk_peris_gic_p) = { "oscclk", "mout_peris_bus_user" };
+PNAME(mout_peris_clk_peris_gic_p) = { "mout_peris_bus_user", "oscclk" };
static const struct samsung_mux_clock peris_mux_clks[] __initconst = {
MUX(CLK_MOUT_PERIS_BUS_USER, "mout_peris_bus_user",
@@ -2584,15 +2584,15 @@ static const struct samsung_gate_clock peris_gate_clks[] __initconst = {
CLK_CON_GAT_GOUT_BLK_PERIS_UID_RSTNSYNC_CLK_PERIS_BUSP_IPCLKPORT_CLK,
21, 0, 0),
GATE(CLK_GOUT_PERIS_CLK_PERIS_OSCCLK_CLK,
- "gout_peris_clk_peris_oscclk_clk", "mout_peris_bus_user",
+ "gout_peris_clk_peris_oscclk_clk", "oscclk",
CLK_CON_GAT_CLK_BLK_PERIS_UID_RSTNSYNC_CLK_PERIS_OSCCLK_IPCLKPORT_CLK,
21, 0, 0),
GATE(CLK_GOUT_PERIS_CLK_PERIS_GIC_CLK,
- "gout_peris_clk_peris_gic_clk", "mout_peris_bus_user",
+ "gout_peris_clk_peris_gic_clk", "mout_peris_clk_peris_gic",
CLK_CON_GAT_GOUT_BLK_PERIS_UID_RSTNSYNC_CLK_PERIS_GIC_IPCLKPORT_CLK,
21, 0, 0),
GATE(CLK_GOUT_PERIS_AD_AXI_P_PERIS_ACLKM,
- "gout_peris_ad_axi_p_peris_aclkm", "mout_peris_bus_user",
+ "gout_peris_ad_axi_p_peris_aclkm", "mout_peris_clk_peris_gic",
CLK_CON_GAT_GOUT_BLK_PERIS_UID_AD_AXI_P_PERIS_IPCLKPORT_ACLKM,
21, CLK_IGNORE_UNUSED, 0),
GATE(CLK_GOUT_PERIS_OTP_CON_BIRA_PCLK,
@@ -2600,27 +2600,31 @@ static const struct samsung_gate_clock peris_gate_clks[] __initconst = {
CLK_CON_GAT_GOUT_BLK_PERIS_UID_OTP_CON_BIRA_IPCLKPORT_PCLK,
21, 0, 0),
GATE(CLK_GOUT_PERIS_GIC_CLK,
- "gout_peris_gic_clk", "mout_peris_bus_user",
+ "gout_peris_gic_clk", "mout_peris_clk_peris_gic",
CLK_CON_GAT_GOUT_BLK_PERIS_UID_GIC_IPCLKPORT_CLK,
21, CLK_IS_CRITICAL, 0),
GATE(CLK_GOUT_PERIS_LHM_AXI_P_PERIS_CLK,
- "gout_peris_lhm_axi_p_peris_clk", "oscclk",
+ "gout_peris_lhm_axi_p_peris_clk", "mout_peris_bus_user",
CLK_CON_GAT_GOUT_BLK_PERIS_UID_LHM_AXI_P_PERIS_IPCLKPORT_I_CLK,
21, CLK_IGNORE_UNUSED, 0),
GATE(CLK_GOUT_PERIS_MCT_PCLK,
- "gout_peris_mct_pclk", "mout_peris_clk_peris_gic",
+ "gout_peris_mct_pclk", "mout_peris_bus_user",
CLK_CON_GAT_GOUT_BLK_PERIS_UID_MCT_IPCLKPORT_PCLK,
21, 0, 0),
GATE(CLK_GOUT_PERIS_OTP_CON_TOP_PCLK,
- "gout_peris_otp_con_top_pclk", "mout_peris_clk_peris_gic",
+ "gout_peris_otp_con_top_pclk", "mout_peris_bus_user",
CLK_CON_GAT_GOUT_BLK_PERIS_UID_OTP_CON_TOP_IPCLKPORT_PCLK,
21, 0, 0),
GATE(CLK_GOUT_PERIS_D_TZPC_PERIS_PCLK,
"gout_peris_d_tzpc_peris_pclk", "mout_peris_bus_user",
CLK_CON_GAT_GOUT_BLK_PERIS_UID_D_TZPC_PERIS_IPCLKPORT_PCLK,
21, 0, 0),
+ GATE(CLK_GOUT_PERIS_TMU_SUB_PCLK,
+ "gout_peris_tmu_sub_pclk", "mout_peris_bus_user",
+ CLK_CON_GAT_GOUT_BLK_PERIS_UID_TMU_SUB_IPCLKPORT_PCLK,
+ 21, 0, 0),
GATE(CLK_GOUT_PERIS_TMU_TOP_PCLK,
- "gout_peris_tmu_top_pclk", "mout_peris_clk_peris_gic",
+ "gout_peris_tmu_top_pclk", "mout_peris_bus_user",
CLK_CON_GAT_GOUT_BLK_PERIS_UID_TMU_TOP_IPCLKPORT_PCLK,
21, 0, 0),
GATE(CLK_GOUT_PERIS_OTP_CON_BIRA_OSCCLK,
--
2.54.0
^ permalink raw reply related
* Re: [PATCH v4 20/31] fs/stlmfs: Document ARM SCMI Telemetry filesystem
From: Randy Dunlap @ 2026-06-13 5:27 UTC (permalink / raw)
To: Cristian Marussi, linux-kernel, linux-arm-kernel, arm-scmi,
linux-fsdevel, linux-doc
Cc: sudeep.holla, james.quinlan, f.fainelli, vincent.guittot,
etienne.carriere, peng.fan, michal.simek, d-gole, jic23,
elif.topuz, lukasz.luba, philip.radford, brauner,
souvik.chakravarty, leitao, kas, puranjay, usama.arif,
kernel-team, Jonathan Corbet, Shuah Khan
In-Reply-To: <20260612223802.1337232-21-cristian.marussi@arm.com>
On 6/12/26 3:37 PM, Cristian Marussi wrote:
> +Design
> +======
> +
> +STLMFS is a pseudo filesystem used to expose ARM SCMI Telemetry data
> +discovered dynamically at run-time via SCMI.
> +
> +Inodes are all dynamically created at mount-time from a dedicated
> +kmem_cache based on the gathered available SCMI Telemetry information.
> +
> +Since inodes represent the discovered Telemetry entities, which in turn are
> +statically defined at the platform level and immutable throughout the same
> +session (boot), allocated inodes are freed only at unmount-time and the
> +user is not allowed to delete or create any kind of file within the STLMFS
> +filesystem after mount has completed.
> +
> +A single instance of STLMFS is created at the filesystem level, using
> +get_tree_single(), given that the same SCMI backend entities will be
> +involved no matter how many times you mount it.
> +
> +STLMFS configurations gets appplied by issuing the related SCMI commands to
get applied
or better:
are applied
> +the backend SCMI platform server: for such reason any configuration applied
> +by this FS interface will survive the unmount or the unload of the module, but
> +not a reboot.
--
~Randy
^ permalink raw reply
* Re: [PATCH v4 28/31] [RFC] docs: stlmfs: Document ARM SCMI Telemetry FS ABI
From: Randy Dunlap @ 2026-06-13 5:30 UTC (permalink / raw)
To: Cristian Marussi, linux-kernel, linux-arm-kernel, arm-scmi,
linux-fsdevel, linux-doc
Cc: sudeep.holla, james.quinlan, f.fainelli, vincent.guittot,
etienne.carriere, peng.fan, michal.simek, d-gole, jic23,
elif.topuz, lukasz.luba, philip.radford, brauner,
souvik.chakravarty, leitao, kas, puranjay, usama.arif,
kernel-team
In-Reply-To: <20260612223802.1337232-29-cristian.marussi@arm.com>
On 6/12/26 3:37 PM, Cristian Marussi wrote:
> Add full ABI dcoumentation for stlmfs under testing/
>
> Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
> ---
> v3 --> v4
> - renamed to by-components
> - updated date/versions
> - changed output of des/0x<NNN>/value to -> <tstamp> <value>
> (removed colon)
> - added Rationale and Concurrency model
> - added generation counter Description
> v2 --> v3
> - complete ABI entries docs
>
> RFC since unsure if place this into stable/ or testing/
> ---
> Documentation/ABI/testing/stlmfs | 348 +++++++++++++++++++++++++++++++
> 1 file changed, 348 insertions(+)
> create mode 100644 Documentation/ABI/testing/stlmfs
>
> diff --git a/Documentation/ABI/testing/stlmfs b/Documentation/ABI/testing/stlmfs
> new file mode 100644
> index 000000000000..826092a4baf4
> --- /dev/null
> +++ b/Documentation/ABI/testing/stlmfs
> @@ -0,0 +1,348 @@
> +What: /sys/fs/arm_telemetry/tlm_<N>/...
> +Date: Nov 2026
> +KernelVersion: 7.3
> +Contact: cristian.marussi@arm.com
> +Rationale: This filesystem provides access to SCMI telemetry data and
> + configuration.
> + The interface is required to support:
> + - hierarchical dynamically discovered telemetry objects
> + - bulk data read across multiple sources
> + - representation of complex structured data and their
> + relationship
> + - alternative high-frequency data access (ioctl/mmap)
> + These characteristics exceed the intended use of sysfs, which is
> + designed to represent devices properties with simple attribute
> + based configuration with one value per file: representing
> + telemetry Data Events with devices was deemed an abuse by
> + itself.
> + A dedicated filesystem is therefore used to provide a more
> + suitable abstraction for this class of functionality.
> +
> +Concurrency: The telemetry configuration exposed through this filesystem is
> + global to each SCMI telemetry instance, indentified by the top
identified
> + tlm_<N> directory.
> + Concurrent access from multiple user-space processes is allowed.
> + The kernel does not enforce exclusivity or ownership of the
> + interface.
> + All configuration changes are applied immediately by issuing
> + the related SCMI commands. Writes to different attributes may
> + interleave and no atomicity across multiple files is guaranteed.
> + In case of concurrent writes to the same attribute, the last
> + writer wins.
> + Read operations may observe state that has been already modified
> + and it is stale.
> + Userspace is responsible for coordinating access if stronger
> + consistency or serialization is required and this filesystem
> + provides a generation counter to aid in the detection of sudden
> + configuration changes.
> +
> +What: /sys/fs/arm_telemetry/tlm_<N>/all_des_enable
> +Date: Nov 2026
> +KernelVersion: 7.3
> +Contact: cristian.marussi@arm.com
> +Description: A boolean WO entry to enable all the discovered Data Events for
> + SCMI instance <N>.
> +Users: Any userspace telemetry tool
> +
> +What: /sys/fs/arm_telemetry/tlm_<N>/all_tstamp_des_enable
> +Date: Nov 2026
> +KernelVersion: 7.3
> +Contact: cristian.marussi@arm.com
> +Description: A boolean WO entry to enable timestamps for all the discovered
> + Data Events for SCMI instance <N>. (when available)
> +Users: Any userspace telemetry tool
> +
> +What: /sys/fs/arm_telemetry/tlm_<N>/available_update_intervals_ms
> +Date: Nov 2026
> +KernelVersion: 7.3
> +Contact: cristian.marussi@arm.com
> +Description: A RO entry that returns a space separated list of tuples of
> + values, separated by a coma, each one representing a
> + configurable update interval for SCMI instance <N>.
> + Each tuple describes a possible update interval using the
> + format <secs>,<exp> where the final represented interval is
> + calculated as: <secs> * 10 ^ <exp>
> + An example of list of tuples that can be read from this entry:
> + 3,0 4,-1 75,-2 300,-3 1,1 5,3 222,-7
> +Users: Any userspace telemetry tool
> +
> +What: /sys/fs/arm_telemetry/tlm_<N>/by-components/
> +Date: Nov 2026
> +KernelVersion: 7.3
> +Contact: cristian.marussi@arm.com
> +Description: A subdirectory that exposes an alternative topological view of
> + the same set of discovered DEs that can be already found under
> + the des/ branch.
> + This topology subtree is built following this structure:
> + by-components/
> + ├── <COMPO_TYPE_STR>
> + │ ├── <COMPO_ISTANCE_ID>
> + │ │ ├── <DE_UNIT_TYPE_STR>
> + │ │ │ └── <DE_INSTANCE_ID>
> + │ │ │ └── 0x<DE_ID>[<DE_NAME>] -> ../../../../../des/0x<DE_ID>
> +
> + The leaves are actual symlinks to an existing des/0x<DE_ID>
> + subdirectory, while the naming of the subdirectories composing
> + the inner nodes of the subtree are derived from the DataEvent
> + Descriptor in SCMI v4.0 3.12.4.6.
> +Users: Any userspace telemetry tool
> +
> +What: /sys/fs/arm_telemetry/tlm_<N>/control
> +Date: Nov 2026
> +KernelVersion: 7.3
> +Contact: cristian.marussi@arm.com
> +Description: An RW entry that can be used to discover, configure and retrieve
> + Telemetry data using the alternative binary interface based on
> + ioctls which is documented in include/uapi/linux/scmi.h
> +Users: Any userspace telemetry tool
> +
> +What: /sys/fs/arm_telemetry/tlm_<N>/current_update_intervals_ms
> +Date: Nov 2026
> +KernelVersion: 7.3
> +Contact: cristian.marussi@arm.com
> +Description: An RW entry that can be used to get or set the platform update
> + interval for SCMI instance <N>.
> + On read the returned tuple represents the current update
> + interval using the format <secs>,<exp> where the final
> + represented interval is calculated as: <secs> * 10 ^ <exp>
> + On write the accepted format is the same as on read <secs>,<exp>
> + but, optionally, the second element of the tuple can be omitted
> + and in that case the assumed value for the exponent will default
> + to -3, i.e. milliseconds.
> +Users: Any userspace telemetry tool
> +
> +What: /sys/fs/arm_telemetry/tlm_<N>/de_implementation_version
> +Date: Nov 2026
> +KernelVersion: 7.3
> +Contact: cristian.marussi@arm.com
> +Description: A RO entry that returns a string representing the 128bit UUID
> + that uniquely identifies the set of SCMI Telemetry Data Events
> + and their semantic for SCMI instance <N>.
> + This is compliant with the DE_IMPLEMENTATION_REVISION described
> + in SCMI v4.0 Telemetry 3.12.4.3.
> +Users: Any userspace telemetry tool
> +
> +What: /sys/fs/arm_telemetry/tlm_<N>/des_bulk_read
> +Date: Nov 2026
> +KernelVersion: 7.3
> +Contact: cristian.marussi@arm.com
> +Description: A RO entry that returns a multi-line string containing all the
> + the DEs enabled for SCMI instance <N>, one-per-line, formatted
> + as: <DE_ID> <TIMESTAMP> <DATA_VALUE>
> + These DEs readings represent the last value updated by the
> + platform following the configured update interval: on the
> + backend they will have been collected transparently in a number
> + of different ways: on-demand SHMTI lookup, notifications,
> + fastchannels. Data consistency is guaranteed by the underlying
> + SCMI synchronization mechanisms.
> + Any disabled or unavailable DE is simply NOT included.
> +Users: Any userspace telemetry tool
> +
> +What: /sys/fs/arm_telemetry/tlm_<N>/des_single_sample_read
> +Date: Nov 2026
> +KernelVersion: 7.3
> +Contact: cristian.marussi@arm.com
> +Description: A RO entry that returns a multi-line string containing all the
> + the DEs enabled for SCMI instance <N>, one-per-line, formmatted
formatted
> + as: <DE_ID> <TIMESTAMP> <DATA_VALUE>
> + These DEs readings are generated by triggering an explicit and
> + immediate platform update using single sample asynchronous
> + collect methods.
> + Any disabled or unavailable DE is simply NOT included.
--
~Randy
^ permalink raw reply
* Re: [PATCH v4 00/31] Introduce SCMI Telemetry FS support
From: Randy Dunlap @ 2026-06-13 5:35 UTC (permalink / raw)
To: Cristian Marussi, linux-kernel, linux-arm-kernel, arm-scmi,
linux-fsdevel, linux-doc
Cc: sudeep.holla, james.quinlan, f.fainelli, vincent.guittot,
etienne.carriere, peng.fan, michal.simek, d-gole, jic23,
elif.topuz, lukasz.luba, philip.radford, brauner,
souvik.chakravarty, leitao, kas, puranjay, usama.arif,
kernel-team
In-Reply-To: <20260612223802.1337232-1-cristian.marussi@arm.com>
On 6/12/26 3:37 PM, Cristian Marussi wrote:
> Hi all,
>
> --------------------------------------------------------------------------------
> [TLDR Summary]
> This series introduces a new SCMI driver which uses a new Telemetry FS to expose
> and configure SCMI Telemetry Data Events retrieved from the platform SCMI FW
> at runtime. The patches carrying the new STLMFS Filesystem support are tagged
> with 'stlmfs'.
> --------------------------------------------------------------------------------
> ---
> - moved from SysFS/chardev to a full fledged FS
> - added support for SCMI Telemetry BLK timestamps
>
'make htmldocs' with all documentation patches applied says:
WARNING: linext-2026-0610/Documentation/ABI/testing/stlmfs:5: tag 'contact' is invalid
Rationale: This filesystem provides access to SCMI telemetry data and
WARNING: linext-2026-0610/Documentation/ABI/testing/stlmfs:21: tag 'contact' is invalid
Concurrency: The telemetry configuration exposed through this filesystem is
Documentation/ABI/testing/stlmfs:55: ERROR: Unexpected indentation. [docutils]
Documentation/ABI/testing/stlmfs:69: ERROR: Unexpected indentation. [docutils]
Documentation/ABI/testing/stlmfs:282: ERROR: Unexpected indentation. [docutils]
WARNING: linext-2026-0610/Documentation/ABI/testing/stlmfs:39: abi_sys_fs_arm_telemetry_tlm_n doesn't have a description
linext-2026-0610/Documentation/filesystems/stlmfs.rst:255: WARNING: Title underline too short.
by-components/
----------- [docutils]
linext-2026-0610/Documentation/filesystems/stlmfs.rst: WARNING: document isn't included in any toctree [toc.not_included]
Please correct these and run 'make htmldocs' to verify that they are fixed.
>
> Thanks,
> Cristian
>
> [0]: https://developer.arm.com/documentation/den0056/f/?lang=en
> [1]: https://lore.kernel.org/arm-scmi/20250620192813.2463367-1-cristian.marussi@arm.com/
> [2]: https://git.kernel.org/pub/scm/linux/kernel/git/cris/linux.git/log/?h=scmi_telemetry_unified_fs_V4
>
> Cristian Marussi (31):
> firmware: arm_scmi: Add new SCMIv4.0 error codes definitions
> firmware: arm_scmi: Reduce the scope of protocols mutex
> firmware: arm_scmi: Allow registration of unknown-size events/reports
> firmware: arm_scmi: Allow protocols to register for notifications
> uapi: Add ARM SCMI definitions
> dt-bindings: firmware: arm,scmi: Add support for telemetry protocol
> include: trace: Add Telemetry trace events
> firmware: arm_scmi: Add basic Telemetry support
> firmware: arm_scmi: Add support to parse SHMTIs areas
> firmware: arm_scmi: Add Telemetry configuration operations
> firmware: arm_scmi: Add Telemetry DataEvent read capabilities
> firmware: arm_scmi: Add support for Telemetry reset
> firmware: arm_scmi: Add Telemetry notification support
> firmware: arm_scmi: Add support for boot-on Telemetry
> firmware: arm_scmi: Add Telemetry generation counter
> firmware: arm_scmi: Add common per-protocol debugfs support
> firmware: arm_scmi: Add Telemetry debugfs SHMTI dump support
> firmware: arm_scmi: Add Telemetry debugfs ABI documentation
> firmware: arm_scmi: stlmfs: Add System Telemetry filesystem driver
> fs/stlmfs: Document ARM SCMI Telemetry filesystem
> firmware: arm_scmi: stlmfs: Add basic mount options
> fs/stlmfs: Document ARM SCMI Telemetry FS mount options
> firmware: arm_scmi: stlmfs: Add ioctls support
> fs/stlmfs: Document alternative ioctl based binary interface
> firmware: arm_scmi: stlmfs: Add by-components view
> fs/stlmfs: Document alternative topological view
> firmware: arm_scmi: stlmfs: Add generation file
> [RFC] docs: stlmfs: Document ARM SCMI Telemetry FS ABI
> firmware: arm_scmi: stlmfs: Add lazy population support
> fs/stlmfs: Document lazy mode and related mount option
> [RFC] tools/scmi: Add SCMI Telemetry testing tool
>
> Documentation/ABI/testing/debugfs-scmi | 22 +
> Documentation/ABI/testing/stlmfs | 348 ++
> .../bindings/firmware/arm,scmi.yaml | 8 +
> Documentation/filesystems/stlmfs.rst | 342 ++
> MAINTAINERS | 1 +
> drivers/firmware/arm_scmi/Kconfig | 24 +
> drivers/firmware/arm_scmi/Makefile | 3 +-
> drivers/firmware/arm_scmi/common.h | 10 +
> drivers/firmware/arm_scmi/driver.c | 93 +-
> drivers/firmware/arm_scmi/notify.c | 30 +-
> drivers/firmware/arm_scmi/notify.h | 8 +-
> drivers/firmware/arm_scmi/protocols.h | 13 +
> .../firmware/arm_scmi/scmi_system_telemetry.c | 3146 ++++++++++++++++
> drivers/firmware/arm_scmi/telemetry.c | 3300 +++++++++++++++++
> include/linux/scmi_protocol.h | 203 +-
> include/trace/events/scmi.h | 48 +-
> include/uapi/linux/scmi.h | 289 ++
> tools/testing/scmi/Makefile | 25 +
> tools/testing/scmi/stlm.c | 434 +++
> 19 files changed, 8307 insertions(+), 40 deletions(-)
> create mode 100644 Documentation/ABI/testing/stlmfs
> create mode 100644 Documentation/filesystems/stlmfs.rst
> create mode 100644 drivers/firmware/arm_scmi/scmi_system_telemetry.c
> create mode 100644 drivers/firmware/arm_scmi/telemetry.c
> create mode 100644 include/uapi/linux/scmi.h
> create mode 100644 tools/testing/scmi/Makefile
> create mode 100644 tools/testing/scmi/stlm.c
>
--
~Randy
^ permalink raw reply
* Re: [RFC PATCH 0/2] kasan: hw_tags: Add option to tag only at allocation time
From: Lance Yang @ 2026-06-13 6:06 UTC (permalink / raw)
To: dev.jain
Cc: ryabinin.a.a, akpm, corbet, glider, andreyknvl, dvyukov,
vincenzo.frascino, kasan-dev, linux-mm, linux-kernel, skhan,
workflows, linux-doc, linux-arm-kernel, ryan.roberts,
anshuman.khandual, kaleshsingh, 21cnbao, david, will,
catalin.marinas, Lance Yang
In-Reply-To: <20260612044425.763060-1-dev.jain@arm.com>
On Fri, Jun 12, 2026 at 04:44:22AM +0000, Dev Jain wrote:
>Introduce a boot option to tag only at allocation time of the objects. This
>reduces KASAN MTE overhead, the tradeoff being reduced ability of
>catching bugs.
>
>Now, when a memory object will be freed, it will retain the random tag it
>had at allocation time. This compromises on catching UAF bugs, till the
>time the object is not reallocated, at which point it will have a new
>random tag.
>
>Hence, not catching "use-after-free-before-reallocation" and not catching
>"double-free" will be the compromise for reduced KASAN overhead.
Hmm ... do we also need to teach the KASAN KUnit tests about this mode?
With kasan.tag_only_on_alloc=on, free-time poisoning is skipped, so
some UAF and double-free reports are skipped on purpose, but the tests
still expect them :)
Cheers, Lance
^ permalink raw reply
* Re: [PATCH v6 0/7] Add support for MT6392 PMIC
From: Luca Leonardo Scorcia @ 2026-06-13 6:46 UTC (permalink / raw)
To: linux-mediatek
Cc: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Sen Chu, Sean Wang, Macpaul Lin, Lee Jones, Matthias Brugger,
AngeloGioacchino Del Regno, Linus Walleij, Julien Massot,
Louis-Alexis Eyraud, Val Packett, Fabien Parent, Akari Tsuyukusa,
Chen Zhong, linux-input, devicetree, linux-kernel, linux-pm,
linux-arm-kernel, linux-gpio
In-Reply-To: <20260612200717.361018-1-l.scorcia@gmail.com>
Please ignore this patch set. As correctly described by sashiko-bot,
the binding with no regulator node would not be usable, even if it
passed dtbs_check. I need to complete work on that and then resubmit.
Sorry about the confusion.
Il giorno ven 12 giu 2026 alle ore 22:26 Luca Leonardo Scorcia
<l.scorcia@gmail.com> ha scritto:
>
> The MediaTek MT6392 PMIC is usually found on devices powered by
> the MT8516/MT8167 SoC and is yet another MT6323/MT6397 variant.
>
> This series is mostly based around patches submitted a couple
> years ago by Fabien Parent and not merged and from Val Packett's
> submission from Jan 2025 that included extra cleanups, fixes, and a
> new dtsi file similar to ones that exist for other PMICs. Some
> comments weren't addressed and the series was ultimately not merged.
>
> These patches only enable three functions: keys, pinctrl and RTC.
> Regulators and speaker amp will follow later as I still need to further
> improve those two, but getting the main PMIC in will make the series
> easier to review.
>
> I added a handful of device tree improvements to fix some dtbs_check
> errors, added support for the pinctrl device and addressed the comments
> from last year's reviews.
>
> Please note that patch 0005 depends on patch 0004 as they both need the
> registers.h file, but they belong to different driver areas. I'm not sure
> if I'm supposed to squash them even if they belong to different driver
> areas of if it's fine like this. Any advice is welcome.
>
> The series has been tested on Xiaomi Mi Smart Clock X04G and on the
> Lenovo Smart Clock 2.
>
> Changes in v6:
> - Dropped the regulators driver for the moment
> - Explained the FCHR key name origin in the commit message
> - Introduced the MFD_CELL_* macro in the sub-devices definitions.
> A separate, independent commit introduced MFD_CELL_* to all the
> subdevices in the mt6397-core.c file for consistency
> - Replaced of_device_get_match_data with device_get_match_data
> - Removed the mfd_match_data enum in favor of the preexisting
> chip_id enum
> - Adjusted the error message if the device is unsupported
>
> Changes in v5 [5]:
> - Double checked regulator driver with data sheet and Android sources.
> The data sheet I have misses a lot of register descriptions, but
> Android sources have been helpful to fill the gaps
> - Reintroduced the required attribute for the regulator compatible
> in the bindings
> - Fixed the missing reference to the MT6392 schema
> - Fixed casts/unused vars reported by kernel test robot
> - Removed Reviewed-by tags from the regulator patches as they have been
> modified in this version
>
> Changes in v4 [4]:
> - Dropped usage of the regulator compatible
> - Fixed commit messages text to properly reference the target subsystem
> - Added supply rails to the regulator
> - Reworked the regulator schema and PMIC dtsi. Now all supplies are
> documented and the schema no longer includes voltage information
> - Removed redundant ldo- / buck- prefixes
> - Renamed the pinfunc header to mediatek,mt6392-pinfunc.h
> - Modified the MFD driver to use a simple identifier in the of_match
> data properties
>
> Changes in v3 [3]:
> - Added pinctrl device
> - Changed mt6397-rtc fallback to mt6323-rtc
> - Added schema for regulators
> - Fixed checkpatch issues
>
> Changes in v2 [2]:
> - Replaced explicit compatibles with fallbacks
>
> Initial version: [1]
>
> [1] https://lore.kernel.org/linux-mediatek/cover.1771865014.git.l.scorcia@gmail.com/
> [2] https://lore.kernel.org/linux-mediatek/20260306120521.163654-1-l.scorcia@gmail.com/
> [3] https://lore.kernel.org/linux-mediatek/20260317184507.523060-1-l.scorcia@gmail.com/
> [4] https://lore.kernel.org/linux-mediatek/20260330083429.359819-1-l.scorcia@gmail.com/
> [5] https://lore.kernel.org/linux-mediatek/20260420213529.1645560-1-l.scorcia@gmail.com/
>
> Fabien Parent (3):
> dt-bindings: mfd: mt6397: Add MT6392 PMIC
> dt-bindings: input: mtk-pmic-keys: Add MT6392 PMIC keys
> mfd: mt6397: Add support for MT6392 PMIC
>
> Luca Leonardo Scorcia (2):
> mfd: mt6397: Use MFD_CELL_* to describe sub-devices
> pinctrl: mediatek: mt6397: Add MediaTek MT6392
>
> Val Packett (2):
> input: keyboard: mtk-pmic-keys: Add MT6392 support
> arm64: dts: mediatek: Add MediaTek MT6392 PMIC dtsi
>
> .../bindings/input/mediatek,pmic-keys.yaml | 1 +
> .../bindings/mfd/mediatek,mt6397.yaml | 8 +
> arch/arm64/boot/dts/mediatek/mt6392.dtsi | 41 ++
> drivers/input/keyboard/mtk-pmic-keys.c | 17 +
> drivers/mfd/mt6397-core.c | 294 +++++------
> drivers/mfd/mt6397-irq.c | 8 +
> drivers/pinctrl/mediatek/pinctrl-mt6397.c | 37 +-
> drivers/pinctrl/mediatek/pinctrl-mtk-mt6392.h | 64 +++
> include/linux/mfd/mt6392/core.h | 43 ++
> include/linux/mfd/mt6392/registers.h | 488 ++++++++++++++++++
> include/linux/mfd/mt6397/core.h | 1 +
> 11 files changed, 840 insertions(+), 162 deletions(-)
> create mode 100644 arch/arm64/boot/dts/mediatek/mt6392.dtsi
> create mode 100644 drivers/pinctrl/mediatek/pinctrl-mtk-mt6392.h
> create mode 100644 include/linux/mfd/mt6392/core.h
> create mode 100644 include/linux/mfd/mt6392/registers.h
>
> --
> 2.43.0
>
--
Luca Leonardo Scorcia
l.scorcia@gmail.com
^ permalink raw reply
* [RFC PATCH v4 0/9] accel: rocket: Add RK3568 NPU support
From: MidG971 @ 2026-06-13 7:01 UTC (permalink / raw)
To: tomeu, ogabbay, heiko, robh, krzk+dt, conor+dt, ulf.hansson
Cc: dri-devel, linux-rockchip, devicetree, linux-arm-kernel, linux-pm,
iommu, linux-kernel, xxm, chaoyi.chen, finley.xiao, diederik,
jonas, Midgy BALON
From: Midgy BALON <midgy971@gmail.com>
RFC, not for merge. End-to-end inference does not produce correct output
yet (see Status), so per the v2 discussion this is a request for design
feedback. It probes, attaches, and submits cleanly on a stock v7.1-rc6
tree; what remains is one hardware-internal issue.
The RK3568 has a single NVDLA-derived NPU core, the same IP family as the
RK3588 NPU the driver already supports; the register layout matches. The
RK3568 differences are a 32-bit NPU AXI/IOMMU (vs 40-bit) and explicit
PVTPLL/PMU bring-up to power and de-idle the NPU before it is reachable.
Patches:
1-2 rocket: per-SoC data struct, then derive DMA width and core count
from match data (refactors, no functional change); patch 2 also
bounds-checks the per-SoC cores array.
3 rocket: RK3568 SoC data; start the PVTPLL compute clock via SCMI.
Powering on and de-idling the NPU NoC are left to the power domain.
4 rocket: reset the NPU before detaching the IOMMU on a job timeout
(the detach otherwise stalls a wedged AXI master and WARNs).
5 rocket: keep the IOMMU domain attached across jobs instead of
re-attaching per job (the per-job rk_iommu handshake on the idle
NPU MMU is slow and noisy); also drop the domain on reset and stop
the scheduler before IOMMU teardown.
6 dt-bindings: add the RK3568 NPU compatible; require rockchip,pmu
for RK3568.
7-8 arm64 dts: add the NPU and its IOMMU, and enable them on ROCK 3B.
9 pmdomain: give the RK3568 NPU power domain a regulator so genpd
owns vdd_npu via domain-supply (Suggested-by Chaoyi Chen).
Dependencies. This series no longer touches the IOMMU driver; two
in-flight Rockchip IOMMU changes are relevant but not part of it:
- Simon Xue's "iommu/rockchip: Drop global rk_ops in favor of
per-device ops" [1]. On boards with more than 4 GiB of RAM the NPU
MMU's DTE must stay below 4 GiB (its DTE address is 32-bit), so the
NPU IOMMU is described with the "rockchip,iommu" compatible, whose ops
allocate the page tables with GFP_DMA32; the SoC's other IOMMUs use
the "rockchip,rk3568-iommu" (40-bit) ops. The driver keeps a single
global ops pointer, so two ops on one SoC trip its coexistence check;
this series therefore sits on top of Simon's per-device-ops change,
which Rockchip (Chaoyi Chen) confirmed is the intended way to give the
NPU MMU its 32-bit DTE.
- "iommu/rockchip: disable fetch dte time limit" [2] (Simon Xue / Sven
Pueschel, in the iommu tree), which sets AUTO_GATING bit 31. v3 carried
a local AUTO_GATING patch; that unconditional fix has since been merged,
so this series drops its IOMMU patch. The bit is a no-op on this
hardware in any case (the page walk completes on its reset value).
Power bring-up. The NPU is brought up through the power-domain layer (no
driver hack): the NPU power-domain keeps its clocks but drops the pm_qos
phandle (qos_npu sits behind the gated NPU NoC, so genpd's power-off QoS
save faults reading it), and vdd_npu is wired as the domain's
domain-supply with the domain marked need_regulator (patch 9), so genpd
brings the rail up before it de-idles the NoC at power-on. The PMU de-idle
then ACKs without PVTPLL running; PVTPLL is only needed for compute.
Status. On v7.1-rc6 the driver probes, creates /dev/accel/accel0,
attaches an IOMMU domain, and submits jobs; the program controller
fetches and broadcasts the command list. Inference output is still
wrong. The kernel side (this series) appears complete; what remains is
mesa/Teflon userspace, which still emits RK3588-tuned config (to be
filed on mesa-dev), and the hardware: with corrected config the NPU
reads the full input and weight tensors (per its DMA counters) but the
MAC/output stage never completes and the job times out, leaving the
output at the buffer's zero-point. It is not in the command list (a
byte-exact replay of the vendor's command list behaves the same).
Pointers from anyone with RK3568 NPU experience welcome.
Known residual. On the first IOMMU attach the NPU MMU is idle with paging
already enabled; the rk_iommu stall/reset handshake does not complete in
that state and logs one burst of timeouts before the (kept) domain
settles. It is harmless here because the job times out regardless, but it
points at an idle-MMU reconfiguration corner the rk_iommu code does not
handle on this block.
[1] https://lore.kernel.org/linux-rockchip/20260310105303.128859-1-xxm@rock-chips.com/
[2] https://lore.kernel.org/all/20260428-spu-iommudtefix-v2-1-f592f579e508@pengutronix.de/
Changes since v3:
- Dropped the local AUTO_GATING patch: the correct fix (set AUTO_GATING
bit 31, "disable fetch dte time limit") has since been merged upstream
[2], so the series no longer touches the IOMMU driver.
- vdd_npu: new pmdomain patch (9) gives the RK3568 NPU domain a regulator
(need_regulator) and the board wires domain-supply, dropping the
regulator-always-on workaround (Suggested-by Chaoyi Chen). It relies on
the in-tree pmdomain default-off-if-need_regulator handling. The
"Failed to create device link ... <pmic>" line at pmdomain probe is a
pre-existing fw_devlink cyclic-dependency warning (the single
power-controller provides every domain, including the one the I2C PMIC
needs), seen the same way on RK3588; it is harmless here beyond a few
wasted EPROBE_DEFER retries, and a proper fix belongs in the
power-controller driver, not this series.
- rk356x dts: also assign the CRU CLK_NPU so the NPU AXI bus clock comes
up at 200 MHz instead of the 12 MHz boot default; order the NPU/IOMMU
nodes by unit address.
- rocket RK3568: fetch the SCMI/PVTPLL clock by name (the v3 bulk index
resolved to the wrong clock); drop the redundant driver PMU de-idle
writes (handled by the power domain).
- rocket: clear the attached IOMMU domain on reset; unwind through
rocket_core_fini() on noc_init failure; stop the scheduler before the
IOMMU teardown.
- rocket: bounds-check the cores array against the per-SoC core count.
- Binding: require rockchip,pmu on RK3568.
- Dependency framing: confirmed by Rockchip as v2 + 32-bit DTE via
Simon's per-device-ops series (was framed as v1 in v3).
Midgy BALON (9):
accel: rocket: Introduce per-SoC rocket_soc_data
accel: rocket: Derive DMA width and core count from match data
accel: rocket: Add RK3568 SoC support
accel: rocket: Reset the NPU before detaching the IOMMU on timeout
accel: rocket: Keep the IOMMU domain attached across jobs
dt-bindings: npu: rockchip,rk3588-rknn-core: Add RK3568
arm64: dts: rockchip: rk356x: Add the NPU and its IOMMU
arm64: dts: rockchip: rk3568-rock-3b: Enable the NPU
pmdomain: rockchip: Add a regulator to the RK3568 NPU power domain
.../npu/rockchip,rk3588-rknn-core.yaml | 27 +++++++++-
.../boot/dts/rockchip/rk3568-rock-3b.dts | 18 ++++++-
arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 38 ++++++++++++++
drivers/accel/rocket/rocket_core.c | 30 ++++++++++-
drivers/accel/rocket/rocket_core.h | 19 +++++++
drivers/accel/rocket/rocket_device.c | 15 ++----
drivers/accel/rocket/rocket_device.h | 3 +-
drivers/accel/rocket/rocket_drv.c | 50 ++++++++++++++++++-
drivers/accel/rocket/rocket_job.c | 45 ++++++++++++++---
drivers/pmdomain/rockchip/pm-domains.c | 36 +++++++++----
10 files changed, 245 insertions(+), 36 deletions(-)
base-commit: e43ffb69e0438cddd72aaa30898b4dc446f664f8
--
2.39.5
^ permalink raw reply
* [RFC PATCH v4 1/9] accel: rocket: Introduce per-SoC rocket_soc_data
From: MidG971 @ 2026-06-13 7:01 UTC (permalink / raw)
To: tomeu, ogabbay, heiko, robh, krzk+dt, conor+dt, ulf.hansson
Cc: dri-devel, linux-rockchip, devicetree, linux-arm-kernel, linux-pm,
iommu, linux-kernel, xxm, chaoyi.chen, finley.xiao, diederik,
jonas, Midgy BALON
In-Reply-To: <20260613070116.438906-1-midgy971@gmail.com>
From: Midgy BALON <midgy971@gmail.com>
Add a per-SoC data structure carried in the OF match table, currently
holding only the NPU AXI address width, and use it for the per-core DMA
mask instead of a hardcoded 40-bit value. No functional change: the
RK3588 AXI master is 40-bit. This prepares for SoCs with a narrower
address width.
Signed-off-by: Midgy BALON <midgy971@gmail.com>
---
drivers/accel/rocket/rocket_core.c | 7 ++++++-
drivers/accel/rocket/rocket_core.h | 11 +++++++++++
drivers/accel/rocket/rocket_drv.c | 6 +++++-
3 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c
index b3b2fa9ba645a..09c445af7de73 100644
--- a/drivers/accel/rocket/rocket_core.c
+++ b/drivers/accel/rocket/rocket_core.c
@@ -7,6 +7,7 @@
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/iommu.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
@@ -21,6 +22,10 @@ int rocket_core_init(struct rocket_core *core)
u32 version;
int err = 0;
+ core->soc_data = of_device_get_match_data(dev);
+ if (!core->soc_data)
+ return dev_err_probe(dev, -EINVAL, "missing SoC match data\n");
+
core->resets[0].id = "srst_a";
core->resets[1].id = "srst_h";
err = devm_reset_control_bulk_get_exclusive(&pdev->dev, ARRAY_SIZE(core->resets),
@@ -52,7 +57,7 @@ int rocket_core_init(struct rocket_core *core)
dma_set_max_seg_size(dev, UINT_MAX);
- err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
+ err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(core->soc_data->dma_bits));
if (err)
return err;
diff --git a/drivers/accel/rocket/rocket_core.h b/drivers/accel/rocket/rocket_core.h
index f6d7382854ca9..8ee105a0be40e 100644
--- a/drivers/accel/rocket/rocket_core.h
+++ b/drivers/accel/rocket/rocket_core.h
@@ -12,6 +12,16 @@
#include "rocket_registers.h"
+struct rocket_core;
+
+/**
+ * struct rocket_soc_data - per-SoC configuration data
+ * @dma_bits: Physical address width reachable by the NPU's AXI master.
+ */
+struct rocket_soc_data {
+ unsigned int dma_bits;
+};
+
#define rocket_pc_readl(core, reg) \
readl((core)->pc_iomem + (REG_PC_##reg))
#define rocket_pc_writel(core, reg, value) \
@@ -31,6 +41,7 @@ struct rocket_core {
struct device *dev;
struct rocket_device *rdev;
unsigned int index;
+ const struct rocket_soc_data *soc_data;
int irq;
void __iomem *pc_iomem;
diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocket_drv.c
index 8bbbce594883e..384c38e13acce 100644
--- a/drivers/accel/rocket/rocket_drv.c
+++ b/drivers/accel/rocket/rocket_drv.c
@@ -213,8 +213,12 @@ static void rocket_remove(struct platform_device *pdev)
}
}
+static const struct rocket_soc_data rk3588_soc_data = {
+ .dma_bits = 40,
+};
+
static const struct of_device_id dt_match[] = {
- { .compatible = "rockchip,rk3588-rknn-core" },
+ { .compatible = "rockchip,rk3588-rknn-core", .data = &rk3588_soc_data },
{}
};
MODULE_DEVICE_TABLE(of, dt_match);
--
2.39.5
^ permalink raw reply related
* [RFC PATCH v4 2/9] accel: rocket: Derive DMA width and core count from match data
From: MidG971 @ 2026-06-13 7:01 UTC (permalink / raw)
To: tomeu, ogabbay, heiko, robh, krzk+dt, conor+dt, ulf.hansson
Cc: dri-devel, linux-rockchip, devicetree, linux-arm-kernel, linux-pm,
iommu, linux-kernel, xxm, chaoyi.chen, finley.xiao, diederik,
jonas, Midgy BALON
In-Reply-To: <20260613070116.438906-1-midgy971@gmail.com>
From: Midgy BALON <midgy971@gmail.com>
The probe already has the per-SoC match data, which now records the core
count and DMA width. Use it for the cores array allocation and the
device DMA mask instead of re-scanning the device tree for available core
nodes.
While at it, reject a device tree that declares more NPU core nodes than
the SoC has, so the fixed-size cores array can never be overrun.
Signed-off-by: Midgy BALON <midgy971@gmail.com>
---
drivers/accel/rocket/rocket_core.h | 2 ++
drivers/accel/rocket/rocket_device.c | 15 +++++----------
drivers/accel/rocket/rocket_device.h | 3 ++-
drivers/accel/rocket/rocket_drv.c | 13 ++++++++++++-
4 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/drivers/accel/rocket/rocket_core.h b/drivers/accel/rocket/rocket_core.h
index 8ee105a0be40e..d6421251670dc 100644
--- a/drivers/accel/rocket/rocket_core.h
+++ b/drivers/accel/rocket/rocket_core.h
@@ -16,9 +16,11 @@ struct rocket_core;
/**
* struct rocket_soc_data - per-SoC configuration data
+ * @num_cores: Number of NPU cores in this SoC.
* @dma_bits: Physical address width reachable by the NPU's AXI master.
*/
struct rocket_soc_data {
+ unsigned int num_cores;
unsigned int dma_bits;
};
diff --git a/drivers/accel/rocket/rocket_device.c b/drivers/accel/rocket/rocket_device.c
index 46e6ee1e72c5f..6186f4faa3a2a 100644
--- a/drivers/accel/rocket/rocket_device.c
+++ b/drivers/accel/rocket/rocket_device.c
@@ -6,18 +6,16 @@
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
-#include <linux/of.h>
#include "rocket_device.h"
struct rocket_device *rocket_device_init(struct platform_device *pdev,
- const struct drm_driver *rocket_drm_driver)
+ const struct drm_driver *rocket_drm_driver,
+ const struct rocket_soc_data *soc_data)
{
struct device *dev = &pdev->dev;
- struct device_node *core_node;
struct rocket_device *rdev;
struct drm_device *ddev;
- unsigned int num_cores = 0;
int err;
rdev = devm_drm_dev_alloc(dev, rocket_drm_driver, struct rocket_device, ddev);
@@ -27,17 +25,14 @@ struct rocket_device *rocket_device_init(struct platform_device *pdev,
ddev = &rdev->ddev;
dev_set_drvdata(dev, rdev);
- for_each_compatible_node(core_node, NULL, "rockchip,rk3588-rknn-core")
- if (of_device_is_available(core_node))
- num_cores++;
-
- rdev->cores = devm_kcalloc(dev, num_cores, sizeof(*rdev->cores), GFP_KERNEL);
+ rdev->cores = devm_kcalloc(dev, soc_data->num_cores, sizeof(*rdev->cores),
+ GFP_KERNEL);
if (!rdev->cores)
return ERR_PTR(-ENOMEM);
dma_set_max_seg_size(dev, UINT_MAX);
- err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
+ err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(soc_data->dma_bits));
if (err)
return ERR_PTR(err);
diff --git a/drivers/accel/rocket/rocket_device.h b/drivers/accel/rocket/rocket_device.h
index ce662abc01d3d..2f74e078974e3 100644
--- a/drivers/accel/rocket/rocket_device.h
+++ b/drivers/accel/rocket/rocket_device.h
@@ -22,7 +22,8 @@ struct rocket_device {
};
struct rocket_device *rocket_device_init(struct platform_device *pdev,
- const struct drm_driver *rocket_drm_driver);
+ const struct drm_driver *rocket_drm_driver,
+ const struct rocket_soc_data *soc_data);
void rocket_device_fini(struct rocket_device *rdev);
#define to_rocket_device(drm_dev) \
((struct rocket_device *)(container_of((drm_dev), struct rocket_device, ddev)))
diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocket_drv.c
index 384c38e13acce..f0beed2d522c7 100644
--- a/drivers/accel/rocket/rocket_drv.c
+++ b/drivers/accel/rocket/rocket_drv.c
@@ -159,11 +159,15 @@ static const struct drm_driver rocket_drm_driver = {
static int rocket_probe(struct platform_device *pdev)
{
+ const struct rocket_soc_data *soc_data = of_device_get_match_data(&pdev->dev);
int ret;
+ if (!soc_data)
+ return -EINVAL;
+
if (rdev == NULL) {
/* First core probing, initialize DRM device. */
- rdev = rocket_device_init(drm_dev, &rocket_drm_driver);
+ rdev = rocket_device_init(drm_dev, &rocket_drm_driver, soc_data);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to initialize rocket device\n");
return PTR_ERR(rdev);
@@ -172,6 +176,12 @@ static int rocket_probe(struct platform_device *pdev)
unsigned int core = rdev->num_cores;
+ if (core >= soc_data->num_cores) {
+ dev_err(&pdev->dev, "too many NPU core nodes (max %u)\n",
+ soc_data->num_cores);
+ return -EINVAL;
+ }
+
dev_set_drvdata(&pdev->dev, rdev);
rdev->cores[core].rdev = rdev;
@@ -214,6 +224,7 @@ static void rocket_remove(struct platform_device *pdev)
}
static const struct rocket_soc_data rk3588_soc_data = {
+ .num_cores = 3,
.dma_bits = 40,
};
--
2.39.5
^ permalink raw reply related
* [RFC PATCH v4 4/9] accel: rocket: Reset the NPU before detaching the IOMMU on timeout
From: MidG971 @ 2026-06-13 7:01 UTC (permalink / raw)
To: tomeu, ogabbay, heiko, robh, krzk+dt, conor+dt, ulf.hansson
Cc: dri-devel, linux-rockchip, devicetree, linux-arm-kernel, linux-pm,
iommu, linux-kernel, xxm, chaoyi.chen, finley.xiao, diederik,
jonas, Midgy BALON
In-Reply-To: <20260613070116.438906-1-midgy971@gmail.com>
From: Midgy BALON <midgy971@gmail.com>
On a job timeout the NPU AXI master can be left wedged with
outstanding transactions. rocket_reset() detached the IOMMU group
before resetting the hardware, so iommu_detach_group() ->
__iommu_group_set_core_domain() asked the rk_iommu to stall and wait
for the in-flight transactions to drain. They never did, the stall
request timed out (-ETIMEDOUT) and the IOMMU core WARNed:
WARNING: drivers/iommu/iommu.c:157 __iommu_group_set_core_domain
iommu_detach_group
rocket_reset
rocket_job_timedout
Assert the core reset first: it quiesces the AXI master so the
following IOMMU detach completes cleanly. Move the detach after
rocket_core_reset() and out of the job_lock (it does not touch
in_flight_job).
Signed-off-by: Midgy BALON <midgy971@gmail.com>
---
drivers/accel/rocket/rocket_job.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/accel/rocket/rocket_job.c b/drivers/accel/rocket/rocket_job.c
index ac51bff39833f..e25234261536b 100644
--- a/drivers/accel/rocket/rocket_job.c
+++ b/drivers/accel/rocket/rocket_job.c
@@ -364,14 +364,20 @@ rocket_reset(struct rocket_core *core, struct drm_sched_job *bad)
if (core->in_flight_job)
pm_runtime_put_noidle(core->dev);
- iommu_detach_group(NULL, core->iommu_group);
-
core->in_flight_job = NULL;
}
- /* Proceed with reset now. */
+ /*
+ * Reset the NPU hardware before detaching the IOMMU. A timed-out job
+ * leaves the NPU AXI master wedged; detaching the IOMMU then issues a
+ * stall request that never drains and times out (warning in the IOMMU
+ * core). Asserting the core reset first quiesces the master so the
+ * detach completes cleanly.
+ */
rocket_core_reset(core);
+ iommu_detach_group(NULL, core->iommu_group);
+
/* NPU has been reset, we can clear the reset pending bit. */
atomic_set(&core->reset.pending, 0);
--
2.39.5
^ permalink raw reply related
* [RFC PATCH v4 5/9] accel: rocket: Keep the IOMMU domain attached across jobs
From: MidG971 @ 2026-06-13 7:01 UTC (permalink / raw)
To: tomeu, ogabbay, heiko, robh, krzk+dt, conor+dt, ulf.hansson
Cc: dri-devel, linux-rockchip, devicetree, linux-arm-kernel, linux-pm,
iommu, linux-kernel, xxm, chaoyi.chen, finley.xiao, diederik,
jonas, Midgy BALON
In-Reply-To: <20260613070116.438906-1-midgy971@gmail.com>
From: Midgy BALON <midgy971@gmail.com>
rocket attached the job's IOMMU domain in rocket_job_run() and
detached it again on every completion and reset. Each attach/detach
toggles the rk_iommu stall/force-reset/paging handshake, and on
RK3568 the NPU MMU is idle between jobs, so that handshake times out
and logs a burst of "stall/paging request timed out" errors for
every job.
Attach the per-context domain once and keep it: track the attached
domain in the core, swap it only when a job from a different context
runs, and detach it at core teardown. A reference on the attached
domain is held so it outlives the job that first attached it and is
released on swap/teardown.
Because a hardware reset (on job timeout) wipes the IOMMU page-table
base register, drop the attached domain after rocket_core_reset() so
the next job re-attaches and reprograms it. Also tear down the
scheduler before detaching the IOMMU in rocket_core_fini(), so an
in-flight job can no longer reach the domain being detached.
Signed-off-by: Midgy BALON <midgy971@gmail.com>
---
drivers/accel/rocket/rocket_core.c | 14 +++++++++++-
drivers/accel/rocket/rocket_core.h | 3 +++
drivers/accel/rocket/rocket_job.c | 35 +++++++++++++++++++++++++-----
3 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c
index 779e951596a15..6c128f585cff4 100644
--- a/drivers/accel/rocket/rocket_core.c
+++ b/drivers/accel/rocket/rocket_core.c
@@ -13,6 +13,7 @@
#include <linux/reset.h>
#include "rocket_core.h"
+#include "rocket_drv.h"
#include "rocket_job.h"
int rocket_core_init(struct rocket_core *core)
@@ -112,9 +113,20 @@ void rocket_core_fini(struct rocket_core *core)
{
pm_runtime_dont_use_autosuspend(core->dev);
pm_runtime_disable(core->dev);
+
+ /*
+ * Stop the scheduler before tearing down the IOMMU so an in-flight
+ * job can no longer touch the (about to be detached) domain.
+ */
+ rocket_job_fini(core);
+
+ if (core->attached_domain) {
+ iommu_detach_group(NULL, core->iommu_group);
+ rocket_iommu_domain_put(core->attached_domain);
+ core->attached_domain = NULL;
+ }
iommu_group_put(core->iommu_group);
core->iommu_group = NULL;
- rocket_job_fini(core);
}
void rocket_core_reset(struct rocket_core *core)
diff --git a/drivers/accel/rocket/rocket_core.h b/drivers/accel/rocket/rocket_core.h
index 5a145ba8c5a92..78791ecb32e75 100644
--- a/drivers/accel/rocket/rocket_core.h
+++ b/drivers/accel/rocket/rocket_core.h
@@ -42,6 +42,8 @@ struct rocket_soc_data {
#define rocket_core_writel(core, reg, value) \
writel(value, (core)->core_iomem + (REG_CORE_##reg) - REG_CORE_S_STATUS)
+struct rocket_iommu_domain;
+
struct rocket_core {
struct device *dev;
struct rocket_device *rdev;
@@ -56,6 +58,7 @@ struct rocket_core {
struct reset_control_bulk_data resets[2];
struct iommu_group *iommu_group;
+ struct rocket_iommu_domain *attached_domain;
struct mutex job_lock;
struct rocket_job *in_flight_job;
diff --git a/drivers/accel/rocket/rocket_job.c b/drivers/accel/rocket/rocket_job.c
index e25234261536b..368b2ebead1b3 100644
--- a/drivers/accel/rocket/rocket_job.c
+++ b/drivers/accel/rocket/rocket_job.c
@@ -9,6 +9,7 @@
#include <drm/rocket_accel.h>
#include <linux/interrupt.h>
#include <linux/iommu.h>
+#include <linux/kref.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
@@ -314,9 +315,26 @@ static struct dma_fence *rocket_job_run(struct drm_sched_job *sched_job)
if (ret < 0)
return fence;
- ret = iommu_attach_group(job->domain->domain, core->iommu_group);
- if (ret < 0)
- return fence;
+ /*
+ * Attach the job's IOMMU domain only when it differs from the one
+ * already attached. Re-attaching per job toggles the rk_iommu
+ * stall/reset handshake on an idle NPU MMU, which is slow and
+ * noisy; keep the domain attached across jobs instead.
+ */
+ if (core->attached_domain != job->domain) {
+ if (core->attached_domain) {
+ iommu_detach_group(NULL, core->iommu_group);
+ rocket_iommu_domain_put(core->attached_domain);
+ core->attached_domain = NULL;
+ }
+
+ ret = iommu_attach_group(job->domain->domain, core->iommu_group);
+ if (ret < 0)
+ return fence;
+
+ kref_get(&job->domain->kref);
+ core->attached_domain = job->domain;
+ }
scoped_guard(mutex, &core->job_lock) {
core->in_flight_job = job;
@@ -340,7 +358,6 @@ static void rocket_job_handle_irq(struct rocket_core *core)
return;
}
- iommu_detach_group(NULL, iommu_group_get(core->dev));
dma_fence_signal(core->in_flight_job->done_fence);
pm_runtime_put_autosuspend(core->dev);
core->in_flight_job = NULL;
@@ -376,7 +393,15 @@ rocket_reset(struct rocket_core *core, struct drm_sched_job *bad)
*/
rocket_core_reset(core);
- iommu_detach_group(NULL, core->iommu_group);
+ /*
+ * The reset wipes the IOMMU page-table base, so drop the attached
+ * domain to force the next job to re-attach and reprogram it.
+ */
+ if (core->attached_domain) {
+ iommu_detach_group(NULL, core->iommu_group);
+ rocket_iommu_domain_put(core->attached_domain);
+ core->attached_domain = NULL;
+ }
/* NPU has been reset, we can clear the reset pending bit. */
atomic_set(&core->reset.pending, 0);
--
2.39.5
^ permalink raw reply related
* [RFC PATCH v4 3/9] accel: rocket: Add RK3568 SoC support
From: MidG971 @ 2026-06-13 7:01 UTC (permalink / raw)
To: tomeu, ogabbay, heiko, robh, krzk+dt, conor+dt, ulf.hansson
Cc: dri-devel, linux-rockchip, devicetree, linux-arm-kernel, linux-pm,
iommu, linux-kernel, xxm, chaoyi.chen, finley.xiao, diederik,
jonas, Midgy BALON
In-Reply-To: <20260613070116.438906-1-midgy971@gmail.com>
From: Midgy BALON <midgy971@gmail.com>
The RK3568 has a single core of the same NVDLA-derived NPU IP as the
RK3588, with a 32-bit AXI master. Add rk3568_soc_data and its
compatible.
Unlike the RK3588, the RK3568 NPU's compute clock is a PVTPLL managed by
TF-A via SCMI; start it from an noc_init callback with a real rate change
(an intermediate rate defeats the clock framework's unchanged-rate
shortcut). Powering on and de-idling the NPU NoC are left to the power
domain (genpd), which performs them when the IOMMU supplier is resumed,
so the driver does not poke the PMU directly.
If noc_init fails, unwind through rocket_core_fini() so the core is torn
down completely rather than leaking the runtime-PM and IOMMU state.
Signed-off-by: Midgy BALON <midgy971@gmail.com>
---
drivers/accel/rocket/rocket_core.c | 9 +++++++++
drivers/accel/rocket/rocket_core.h | 3 +++
drivers/accel/rocket/rocket_drv.c | 31 ++++++++++++++++++++++++++++++
3 files changed, 43 insertions(+)
diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c
index 09c445af7de73..779e951596a15 100644
--- a/drivers/accel/rocket/rocket_core.c
+++ b/drivers/accel/rocket/rocket_core.c
@@ -88,6 +88,15 @@ int rocket_core_init(struct rocket_core *core)
return err;
}
+ if (core->soc_data->noc_init) {
+ err = core->soc_data->noc_init(core);
+ if (err) {
+ pm_runtime_put_sync(dev);
+ rocket_core_fini(core);
+ return err;
+ }
+ }
+
version = rocket_pc_readl(core, VERSION);
version += rocket_pc_readl(core, VERSION_NUM) & 0xffff;
diff --git a/drivers/accel/rocket/rocket_core.h b/drivers/accel/rocket/rocket_core.h
index d6421251670dc..5a145ba8c5a92 100644
--- a/drivers/accel/rocket/rocket_core.h
+++ b/drivers/accel/rocket/rocket_core.h
@@ -18,10 +18,13 @@ struct rocket_core;
* struct rocket_soc_data - per-SoC configuration data
* @num_cores: Number of NPU cores in this SoC.
* @dma_bits: Physical address width reachable by the NPU's AXI master.
+ * @noc_init: Optional callback to bring up the NPU before it is reachable.
+ * Used on RK3568 to start the PVTPLL compute clock via SCMI.
*/
struct rocket_soc_data {
unsigned int num_cores;
unsigned int dma_bits;
+ int (*noc_init)(struct rocket_core *core);
};
#define rocket_pc_readl(core, reg) \
diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocket_drv.c
index f0beed2d522c7..86484110ad6f0 100644
--- a/drivers/accel/rocket/rocket_drv.c
+++ b/drivers/accel/rocket/rocket_drv.c
@@ -10,6 +10,7 @@
#include <linux/err.h>
#include <linux/iommu.h>
#include <linux/of.h>
+#include <linux/of_clk.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
@@ -223,12 +224,42 @@ static void rocket_remove(struct platform_device *pdev)
}
}
+/*
+ * The NPU compute clock is a PVTPLL managed by TF-A via SCMI; spin it up
+ * with a real rate change (an intermediate rate defeats the clock
+ * framework's unchanged-rate shortcut). Powering on and de-idling the NPU
+ * NoC are handled by the power domain (genpd) before the NPU is accessed.
+ */
+static int rk3568_noc_init(struct rocket_core *core)
+{
+ struct clk *npu_clk;
+
+ npu_clk = of_clk_get_by_name(core->dev->of_node, "npu");
+ if (IS_ERR(npu_clk))
+ return dev_err_probe(core->dev, PTR_ERR(npu_clk),
+ "failed to get the NPU SCMI clock\n");
+
+ if (clk_set_rate(npu_clk, 600000000UL) ||
+ clk_set_rate(npu_clk, 1000000000UL))
+ dev_warn(core->dev, "failed to set the NPU compute clock rate\n");
+ clk_put(npu_clk);
+
+ return 0;
+}
+
+static const struct rocket_soc_data rk3568_soc_data = {
+ .num_cores = 1,
+ .dma_bits = 32,
+ .noc_init = rk3568_noc_init,
+};
+
static const struct rocket_soc_data rk3588_soc_data = {
.num_cores = 3,
.dma_bits = 40,
};
static const struct of_device_id dt_match[] = {
+ { .compatible = "rockchip,rk3568-rknn-core", .data = &rk3568_soc_data },
{ .compatible = "rockchip,rk3588-rknn-core", .data = &rk3588_soc_data },
{}
};
--
2.39.5
^ permalink raw reply related
* [RFC PATCH v4 7/9] arm64: dts: rockchip: rk356x: Add the NPU and its IOMMU
From: MidG971 @ 2026-06-13 7:01 UTC (permalink / raw)
To: tomeu, ogabbay, heiko, robh, krzk+dt, conor+dt, ulf.hansson
Cc: dri-devel, linux-rockchip, devicetree, linux-arm-kernel, linux-pm,
iommu, linux-kernel, xxm, chaoyi.chen, finley.xiao, diederik,
jonas, Midgy BALON
In-Reply-To: <20260613070116.438906-1-midgy971@gmail.com>
From: Midgy BALON <midgy971@gmail.com>
The RK3568 has an NVDLA-derived NPU at fde40000 with its own IOMMU at
fde4b000. Add both nodes (disabled by default) and the NPU power-domain
child under the PMU power-controller, and point rockchip,pmu at the PMU
syscon that controls the NPU NoC bus-idle.
Besides the SCMI compute clock, assign the CRU CLK_NPU so the NPU AXI
bus clock comes up at 200 MHz rather than the 12 MHz boot default.
The power-domain deliberately carries no pm_qos: qos_npu sits behind the
NPU NoC, which is gated until the NPU is brought up, so a genpd power-off
QoS save would fault reading it.
Signed-off-by: Midgy BALON <midgy971@gmail.com>
---
arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 38 +++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
index 64bdd8b7754b5..313db59c1aed8 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
@@ -512,6 +512,13 @@ power-domain@RK3568_PD_GPU {
#power-domain-cells = <0>;
};
+ pd_npu: power-domain@RK3568_PD_NPU {
+ reg = <RK3568_PD_NPU>;
+ clocks = <&cru ACLK_NPU_PRE>,
+ <&cru HCLK_NPU_PRE>;
+ #power-domain-cells = <0>;
+ };
+
/* These power domains are grouped by VD_LOGIC */
power-domain@RK3568_PD_VI {
reg = <RK3568_PD_VI>;
@@ -572,6 +579,37 @@ power-domain@RK3568_PD_RKVENC {
};
};
+ rknn_core_0: npu@fde40000 {
+ compatible = "rockchip,rk3568-rknn-core";
+ reg = <0x0 0xfde40000 0x0 0x1000>,
+ <0x0 0xfde41000 0x0 0x1000>,
+ <0x0 0xfde43000 0x0 0x1000>;
+ reg-names = "pc", "cna", "core";
+ interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru ACLK_NPU>, <&cru HCLK_NPU>,
+ <&scmi_clk SCMI_CLK_NPU>, <&cru PCLK_NPU_PRE>;
+ clock-names = "aclk", "hclk", "npu", "pclk";
+ assigned-clocks = <&scmi_clk SCMI_CLK_NPU>, <&cru CLK_NPU>;
+ assigned-clock-rates = <200000000>, <600000000>;
+ resets = <&cru SRST_A_NPU>, <&cru SRST_H_NPU>;
+ reset-names = "srst_a", "srst_h";
+ power-domains = <&power RK3568_PD_NPU>;
+ rockchip,pmu = <&pmu>;
+ iommus = <&rknn_mmu_0>;
+ status = "disabled";
+ };
+
+ rknn_mmu_0: iommu@fde4b000 {
+ compatible = "rockchip,iommu";
+ reg = <0x0 0xfde4b000 0x0 0x40>;
+ interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "aclk", "iface";
+ clocks = <&cru ACLK_NPU>, <&cru HCLK_NPU>;
+ power-domains = <&power RK3568_PD_NPU>;
+ #iommu-cells = <0>;
+ status = "disabled";
+ };
+
gpu: gpu@fde60000 {
compatible = "rockchip,rk3568-mali", "arm,mali-bifrost";
reg = <0x0 0xfde60000 0x0 0x4000>;
--
2.39.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox