* [PATCH v8 3/8] mfd: khadas-mcu: Add per-variant configuration infrastructure and VIM4 support
From: Ronald Claveau via B4 Relay @ 2026-07-02 9:55 UTC (permalink / raw)
To: Neil Armstrong, Lee Jones, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andi Shyti, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Beniamino Galvani, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Liam Girdwood, Mark Brown
Cc: linux-amlogic, devicetree, linux-kernel, linux-i2c,
linux-arm-kernel, linux-pm, Ronald Claveau
In-Reply-To: <20260702-add-mcu-fan-khadas-vim4-v8-0-244feee91a36@aliel.fr>
From: Ronald Claveau <linux-kernel-dev@aliel.fr>
Some values change per variant, add the structure to manage it.
Add an enum khadas_mcu_type used as value to match.
Also introduce khadas_mcu_fan_pdata to pass fan register address and
maximum level to the fan sub-driver, removing the hardcoded constants.
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
include/linux/mfd/khadas-mcu.h | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/include/linux/mfd/khadas-mcu.h b/include/linux/mfd/khadas-mcu.h
index a99ba2ed0e4e0..471a31787cce2 100644
--- a/include/linux/mfd/khadas-mcu.h
+++ b/include/linux/mfd/khadas-mcu.h
@@ -70,6 +70,13 @@
#define KHADAS_MCU_WOL_INIT_START_REG 0x87 /* WO */
#define KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG 0x88 /* WO */
+/* VIM4 specific registers */
+#define KHADAS_MCU_VIM4_REST_CONF_REG 0x2c /* WO - reset EEPROM */
+#define KHADAS_MCU_VIM4_LED_ON_RAM_REG 0x89 /* WO - LED volatile */
+#define KHADAS_MCU_VIM4_FAN_CTRL_REG 0x8a /* WO */
+#define KHADAS_MCU_VIM4_WDT_EN_REG 0x8b /* WO */
+#define KHADAS_MCU_VIM4_SYS_RST_REG 0x91 /* WO */
+
enum {
KHADAS_BOARD_VIM1 = 0x1,
KHADAS_BOARD_VIM2,
@@ -88,4 +95,19 @@ struct khadas_mcu {
struct regmap *regmap;
};
+/**
+ * struct khadas_mcu_fan_pdata - fan sub-driver configuration
+ * @fan_reg: register address to write the fan level
+ * @max_level: maximum fan level
+ */
+struct khadas_mcu_fan_pdata {
+ unsigned int fan_reg;
+ unsigned int max_level;
+};
+
+enum khadas_mcu_type {
+ KHADAS_MCU_GENERIC, /* VIM1/2/3, Edge, Edge-V */
+ KHADAS_MCU_VIM4,
+};
+
#endif /* MFD_KHADAS_MCU_H */
--
2.49.0
^ permalink raw reply related
* [PATCH v8 0/8] Add VIM4 MCU/FAN support
From: Ronald Claveau via B4 Relay @ 2026-07-02 9:55 UTC (permalink / raw)
To: Neil Armstrong, Lee Jones, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andi Shyti, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Beniamino Galvani, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Liam Girdwood, Mark Brown
Cc: linux-amlogic, devicetree, linux-kernel, linux-i2c,
linux-arm-kernel, linux-pm, Ronald Claveau, Conor Dooley
The Khadas VIM4 board features a different MCU variant compared to
previous VIM boards.
While it shares the same I2C-based communication model,
it differs in some ways:
- A distinct register map with its own volatile/writeable register set
- A fan control with 0–100 levels instead of the 0–3 levels previously
- A fan power supply gated through a regulator
This series adds support for this new variant by:
1. Refactoring the khadas-mcu MFD driver to use per-variant data
structures (regmap config, cells, fan platform data),
and adding the khadas,vim4-mcu compatible string.
2. Extending the fan thermal driver to retrieve the fan register
and maximum level from platform_data,
and to optionally manage a power regulator for the fan supply.
3. Adding the corresponding DTS node for the VIM4, wiring the MCU to
the I2C AO_A bus and exposing it as a thermal cooling device.
Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
Changes in v8:
- PATCH 4: Define constant for fan max level, remove extra space for unnecessary alignment.
Thanks to Lee's review.
- Link to v7: https://lore.kernel.org/r/20260603-add-mcu-fan-khadas-vim4-v7-0-594ba8a965d8@aliel.fr
Changes in v7:
- PATCH 3-4: Simplify the per-variant handling by using local variables in khadas_mcu_probe()
instead of introducing a dedicated data structure. Thanks to Lee's review.
- Link to v6: https://lore.kernel.org/r/20260516-add-mcu-fan-khadas-vim4-v6-0-cccc9b61f465@aliel.fr
Changes in v6:
- PATCH 4: Address Lee's review comments:
- Use an enum to discriminate between MCU types instead of passing
MFD data through the DT match table
- Fix error code from -EINVAL to -ENODEV when no MCU type is matched
- Make khadas_mcu_fan_cells and khadas_mcu_cells const
- Use dev_err_probe() for regmap initialization error
- Document fan speed levels for max_level
- Link to v5: https://lore.kernel.org/r/20260424-add-mcu-fan-khadas-vim4-v5-0-afcfa7157b23@aliel.fr
Changes in v5:
- PATCH 5: Replace devm_regulator_get_optional() with devm_regulator_get()
to simplify error handling and remove NULL checks, also
ordering as reverse christmas according to Neil's feedback.
- Link to v4: https://lore.kernel.org/r/20260421-add-mcu-fan-khadas-vim4-v4-0-447114a28f2d@aliel.fr
Changes in v4:
- PATCH 1: limit fan-supply property by compatible according to Conor's feedback.
- Link to v3: https://lore.kernel.org/r/20260417-add-mcu-fan-khadas-vim4-v3-0-a6a7f570b11b@aliel.fr
Changes in v3:
- PATCH 1: adding comment on vim4 compatible saying it is not discoverable,
thanks to Rob's and Neil's feedback.
- Link to v2: https://lore.kernel.org/r/20260403-add-mcu-fan-khadas-vim4-v2-0-70536b22439a@aliel.fr
Changes in v2:
- PATCH 5: Add regulator_disable on suspend thanks to Neil's feedback.
- Link to v1: https://lore.kernel.org/r/20260402-add-mcu-fan-khadas-vim4-v1-0-2b12eb4ac7b0@aliel.fr
---
Ronald Claveau (8):
dt-bindings: mfd: khadas: Add new compatible for Khadas VIM4 MCU
dt-bindings: i2c: amlogic: Add compatible for T7 SOC
mfd: khadas-mcu: Add per-variant configuration infrastructure and VIM4 support
mfd: khadas-mcu: Add support for VIM4 MCU variant
thermal: khadas-mcu-fan: Add fan config from platform data Add regulator support
arm64: dts: amlogic: t7: Add i2c pinctrl node
arm64: dts: amlogic: t7: Add i2c controller node
arm64: dts: amlogic: t7: khadas-vim4: Add i2c MCU fan node
.../bindings/i2c/amlogic,meson6-i2c.yaml | 13 ++-
.../devicetree/bindings/mfd/khadas,mcu.yaml | 18 ++++
.../dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts | 13 +++
arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 20 ++++
drivers/mfd/khadas-mcu.c | 118 ++++++++++++++++++---
drivers/thermal/khadas_mcu_fan.c | 37 +++++--
include/linux/mfd/khadas-mcu.h | 22 ++++
7 files changed, 214 insertions(+), 27 deletions(-)
---
base-commit: f7b64ed948718290209074a50bb0df17e5944873
change-id: 20260402-add-mcu-fan-khadas-vim4-ac1cbe553c9b
prerequisite-message-id: <20260326092645.1053261-1-jian.hu@amlogic.com>
prerequisite-patch-id: f03a086b4137158412b2d47b3de793b858de8dde
prerequisite-patch-id: 123970c9b29c2090440f2fd71c85d3c6fd8e36de
prerequisite-patch-id: 3e2e56b0926ba327b520f935df4ced5089bbe503
prerequisite-patch-id: 65a5d76ffdbc9b3aab3385bb65cb027004c30e7e
prerequisite-patch-id: 237269801826dd3ad7fb16eb4d7d6d4eab504278
prerequisite-patch-id: 57e9b08a968aedf543d3d0d56cf1ca4db20b2a16
prerequisite-change-id: 20260326-add-bcm43752-compatible-e264a4f7973a:v2
prerequisite-patch-id: cd98b74fa56af72af2553f391c400981d83cd4f4
prerequisite-patch-id: b730f5e42be1d89d193e63a0265495cdbf2c7d7b
prerequisite-change-id: 20260330-fix-invalid-property-bbe54d933f71:v2
prerequisite-patch-id: 8d675e7a239985c762843515b241f0a2f45f9c92
prerequisite-change-id: 20260331-fix-aml-t7-null-reset-2b608ebf9da4:v1
prerequisite-patch-id: 5b5de77af11747ce964404fb827d2ee2bff47ea5
prerequisite-patch-id: 1e37fc75fed1e533adee0f3e7e6ead1f8ff3c55c
prerequisite-patch-id: 65a5d76ffdbc9b3aab3385bb65cb027004c30e7e
prerequisite-patch-id: 2daf583fb5e7449a02bd217d8aca330171b598aa
prerequisite-patch-id: 237269801826dd3ad7fb16eb4d7d6d4eab504278
prerequisite-patch-id: d1ddf9b7710e91f8062de83bd7ba55afb2c4c112
prerequisite-patch-id: 57e9b08a968aedf543d3d0d56cf1ca4db20b2a16
prerequisite-patch-id: cd98b74fa56af72af2553f391c400981d83cd4f4
prerequisite-patch-id: b730f5e42be1d89d193e63a0265495cdbf2c7d7b
prerequisite-patch-id: 9debd88fa60febed9cd7208f86603b4c2d270520
prerequisite-patch-id: 314ef9ff0c4d1d15dab1dea9d92aa065f1eac3e9
Best regards,
--
Ronald Claveau <linux-kernel-dev@aliel.fr>
^ permalink raw reply
* [PATCH v8 5/8] thermal: khadas-mcu-fan: Add fan config from platform data Add regulator support
From: Ronald Claveau via B4 Relay @ 2026-07-02 9:55 UTC (permalink / raw)
To: Neil Armstrong, Lee Jones, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andi Shyti, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Beniamino Galvani, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Liam Girdwood, Mark Brown
Cc: linux-amlogic, devicetree, linux-kernel, linux-i2c,
linux-arm-kernel, linux-pm, Ronald Claveau
In-Reply-To: <20260702-add-mcu-fan-khadas-vim4-v8-0-244feee91a36@aliel.fr>
From: Ronald Claveau <linux-kernel-dev@aliel.fr>
Replace the hardcoded MAX_LEVEL constant and fan register
with values read from platform_data (fan_reg, max_level),
as new MCUs need different values.
Optionally acquire and enable a "fan" regulator supply
at probe time and on resume,
so boards that gate fan power through a regulator are handled.
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
drivers/thermal/khadas_mcu_fan.c | 37 ++++++++++++++++++++++++++++++-------
1 file changed, 30 insertions(+), 7 deletions(-)
diff --git a/drivers/thermal/khadas_mcu_fan.c b/drivers/thermal/khadas_mcu_fan.c
index d35e5313bea41..5603fa099a858 100644
--- a/drivers/thermal/khadas_mcu_fan.c
+++ b/drivers/thermal/khadas_mcu_fan.c
@@ -13,13 +13,15 @@
#include <linux/regmap.h>
#include <linux/sysfs.h>
#include <linux/thermal.h>
-
-#define MAX_LEVEL 3
+#include <linux/regulator/consumer.h>
struct khadas_mcu_fan_ctx {
struct khadas_mcu *mcu;
+ unsigned int fan_reg;
unsigned int level;
+ unsigned int max_level;
struct thermal_cooling_device *cdev;
+ struct regulator *power;
};
static int khadas_mcu_fan_set_level(struct khadas_mcu_fan_ctx *ctx,
@@ -27,8 +29,7 @@ static int khadas_mcu_fan_set_level(struct khadas_mcu_fan_ctx *ctx,
{
int ret;
- ret = regmap_write(ctx->mcu->regmap, KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG,
- level);
+ ret = regmap_write(ctx->mcu->regmap, ctx->fan_reg, level);
if (ret)
return ret;
@@ -40,7 +41,9 @@ static int khadas_mcu_fan_set_level(struct khadas_mcu_fan_ctx *ctx,
static int khadas_mcu_fan_get_max_state(struct thermal_cooling_device *cdev,
unsigned long *state)
{
- *state = MAX_LEVEL;
+ struct khadas_mcu_fan_ctx *ctx = cdev->devdata;
+
+ *state = ctx->max_level;
return 0;
}
@@ -61,7 +64,7 @@ khadas_mcu_fan_set_cur_state(struct thermal_cooling_device *cdev,
{
struct khadas_mcu_fan_ctx *ctx = cdev->devdata;
- if (state > MAX_LEVEL)
+ if (state > ctx->max_level)
return -EINVAL;
if (state == ctx->level)
@@ -78,6 +81,7 @@ static const struct thermal_cooling_device_ops khadas_mcu_fan_cooling_ops = {
static int khadas_mcu_fan_probe(struct platform_device *pdev)
{
+ const struct khadas_mcu_fan_pdata *pdata = dev_get_platdata(&pdev->dev);
struct khadas_mcu *mcu = dev_get_drvdata(pdev->dev.parent);
struct thermal_cooling_device *cdev;
struct device *dev = &pdev->dev;
@@ -87,7 +91,21 @@ static int khadas_mcu_fan_probe(struct platform_device *pdev)
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
+
ctx->mcu = mcu;
+ ctx->fan_reg = pdata->fan_reg;
+ ctx->max_level = pdata->max_level;
+
+ ctx->power = devm_regulator_get(dev->parent, "fan");
+ if (IS_ERR(ctx->power))
+ return PTR_ERR(ctx->power);
+
+ ret = regulator_enable(ctx->power);
+ if (ret) {
+ dev_err(dev, "Failed to enable fan power supply: %d\n", ret);
+ return ret;
+ }
+
platform_set_drvdata(pdev, ctx);
cdev = devm_thermal_of_cooling_device_register(dev->parent,
@@ -124,12 +142,17 @@ static int khadas_mcu_fan_suspend(struct device *dev)
ctx->level = level_save;
- return 0;
+ return regulator_disable(ctx->power);
}
static int khadas_mcu_fan_resume(struct device *dev)
{
struct khadas_mcu_fan_ctx *ctx = dev_get_drvdata(dev);
+ int ret;
+
+ ret = regulator_enable(ctx->power);
+ if (ret)
+ return ret;
return khadas_mcu_fan_set_level(ctx, ctx->level);
}
--
2.49.0
^ permalink raw reply related
* [PATCH v8 4/8] mfd: khadas-mcu: Add support for VIM4 MCU variant
From: Ronald Claveau via B4 Relay @ 2026-07-02 9:55 UTC (permalink / raw)
To: Neil Armstrong, Lee Jones, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andi Shyti, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Beniamino Galvani, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Liam Girdwood, Mark Brown
Cc: linux-amlogic, devicetree, linux-kernel, linux-i2c,
linux-arm-kernel, linux-pm, Ronald Claveau
In-Reply-To: <20260702-add-mcu-fan-khadas-vim4-v8-0-244feee91a36@aliel.fr>
From: Ronald Claveau <linux-kernel-dev@aliel.fr>
Refactor probe() to use per-variant values
instead of hardcoded globals.
Add dedicated regmap configuration for the VIM4 MCU,
with its own volatile/writeable registers.
Add the fan control register
(0–100 levels vs 0–3 for previous supported boards).
Add a new compatible string "khadas,vim4-mcu".
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
drivers/mfd/khadas-mcu.c | 118 ++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 102 insertions(+), 16 deletions(-)
diff --git a/drivers/mfd/khadas-mcu.c b/drivers/mfd/khadas-mcu.c
index ba981a7886921..d2ca7deda45c6 100644
--- a/drivers/mfd/khadas-mcu.c
+++ b/drivers/mfd/khadas-mcu.c
@@ -13,6 +13,9 @@
#include <linux/module.h>
#include <linux/regmap.h>
+#define KHADAS_MCU_FAN_LEVEL_MAX 3
+#define KHADAS_MCU_VIM4_FAN_LEVEL_MAX 0x64
+
static bool khadas_mcu_reg_volatile(struct device *dev, unsigned int reg)
{
if (reg >= KHADAS_MCU_USER_DATA_0_REG &&
@@ -75,47 +78,129 @@ static const struct regmap_config khadas_mcu_regmap_config = {
.cache_type = REGCACHE_MAPLE,
};
-static struct mfd_cell khadas_mcu_fan_cells[] = {
+static const struct khadas_mcu_fan_pdata khadas_mcu_fan_pdata = {
+ .fan_reg = KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG,
+ .max_level = KHADAS_MCU_FAN_LEVEL_MAX,
+};
+
+static const struct mfd_cell khadas_mcu_fan_cells[] = {
/* VIM1/2 Rev13+ and VIM3 only */
- { .name = "khadas-mcu-fan-ctrl", },
+ {
+ .name = "khadas-mcu-fan-ctrl",
+ .platform_data = &khadas_mcu_fan_pdata,
+ .pdata_size = sizeof(khadas_mcu_fan_pdata),
+ },
};
-static struct mfd_cell khadas_mcu_cells[] = {
+static const struct mfd_cell khadas_mcu_cells[] = {
{ .name = "khadas-mcu-user-mem", },
};
+static bool khadas_mcu_vim4_reg_volatile(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case KHADAS_MCU_PWR_OFF_CMD_REG:
+ case KHADAS_MCU_VIM4_REST_CONF_REG:
+ case KHADAS_MCU_WOL_INIT_START_REG:
+ case KHADAS_MCU_VIM4_LED_ON_RAM_REG:
+ case KHADAS_MCU_VIM4_FAN_CTRL_REG:
+ case KHADAS_MCU_VIM4_WDT_EN_REG:
+ case KHADAS_MCU_VIM4_SYS_RST_REG:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool khadas_mcu_vim4_reg_writeable(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case KHADAS_MCU_VERSION_0_REG:
+ case KHADAS_MCU_VERSION_1_REG:
+ case KHADAS_MCU_SHUTDOWN_NORMAL_STATUS_REG:
+ return false;
+ default:
+ return true;
+ }
+}
+
+static const struct regmap_config khadas_mcu_vim4_regmap_config = {
+ .reg_bits = 8,
+ .reg_stride = 1,
+ .val_bits = 8,
+ .max_register = KHADAS_MCU_VIM4_SYS_RST_REG,
+ .volatile_reg = khadas_mcu_vim4_reg_volatile,
+ .writeable_reg = khadas_mcu_vim4_reg_writeable,
+ .cache_type = REGCACHE_MAPLE,
+};
+
+static const struct khadas_mcu_fan_pdata khadas_vim4_fan_pdata = {
+ .fan_reg = KHADAS_MCU_VIM4_FAN_CTRL_REG,
+ .max_level = KHADAS_MCU_VIM4_FAN_LEVEL_MAX,
+};
+
+static const struct mfd_cell khadas_mcu_vim4_cells[] = {
+ {
+ .name = "khadas-mcu-fan-ctrl",
+ .platform_data = &khadas_vim4_fan_pdata,
+ .pdata_size = sizeof(khadas_vim4_fan_pdata),
+ },
+};
+
static int khadas_mcu_probe(struct i2c_client *client)
{
+ const struct mfd_cell *cells, *fan_cells;
+ const struct regmap_config *regmap_cfg;
struct device *dev = &client->dev;
+ int ncells, nfan_cells, ret;
struct khadas_mcu *ddata;
- int ret;
ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata)
return -ENOMEM;
+ switch ((uintptr_t)i2c_get_match_data(client)) {
+ case KHADAS_MCU_GENERIC:
+ regmap_cfg = &khadas_mcu_regmap_config;
+ cells = khadas_mcu_cells;
+ ncells = ARRAY_SIZE(khadas_mcu_cells);
+ fan_cells = khadas_mcu_fan_cells;
+ nfan_cells = ARRAY_SIZE(khadas_mcu_fan_cells);
+ break;
+ case KHADAS_MCU_VIM4:
+ regmap_cfg = &khadas_mcu_vim4_regmap_config;
+ cells = NULL;
+ ncells = 0;
+ fan_cells = khadas_mcu_vim4_cells;
+ nfan_cells = ARRAY_SIZE(khadas_mcu_vim4_cells);
+ break;
+ default:
+ return -ENODEV;
+ }
+
i2c_set_clientdata(client, ddata);
ddata->dev = dev;
- ddata->regmap = devm_regmap_init_i2c(client, &khadas_mcu_regmap_config);
+ ddata->regmap = devm_regmap_init_i2c(client, regmap_cfg);
if (IS_ERR(ddata->regmap)) {
ret = PTR_ERR(ddata->regmap);
- dev_err(dev, "Failed to allocate register map: %d\n", ret);
- return ret;
+ return dev_err_probe(dev, ret, "Failed to allocate register map\n");
}
- ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
- khadas_mcu_cells,
- ARRAY_SIZE(khadas_mcu_cells),
- NULL, 0, NULL);
- if (ret)
- return ret;
+ if (cells && ncells) {
+ ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
+ cells,
+ ncells,
+ NULL, 0, NULL);
+ if (ret)
+ return ret;
+ }
if (of_property_present(dev->of_node, "#cooling-cells"))
return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
- khadas_mcu_fan_cells,
- ARRAY_SIZE(khadas_mcu_fan_cells),
+ fan_cells,
+ nfan_cells,
NULL, 0, NULL);
return 0;
@@ -123,7 +208,8 @@ static int khadas_mcu_probe(struct i2c_client *client)
#ifdef CONFIG_OF
static const struct of_device_id khadas_mcu_of_match[] = {
- { .compatible = "khadas,mcu", },
+ { .compatible = "khadas,mcu", .data = (void *)KHADAS_MCU_GENERIC },
+ { .compatible = "khadas,vim4-mcu", .data = (void *)KHADAS_MCU_VIM4 },
{},
};
MODULE_DEVICE_TABLE(of, khadas_mcu_of_match);
--
2.49.0
^ permalink raw reply related
* Re: [PATCH net-next v11 1/7] dt-bindings: phy: document the serdes PHY on sa8255p
From: Bartosz Golaszewski @ 2026-07-02 9:44 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Vinod Koul, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Maxime Coquelin,
Alexandre Torgue, Giuseppe Cavallaro, Chen-Yu Tsai,
Jernej Skrabec, Neil Armstrong, Kevin Hilman, Jerome Brunet,
Shawn Guo, Fabio Estevam, Jan Petrous, s32, Mohd Ayaan Anwar,
Romain Gantois, Magnus Damm, Maxime Ripard, Christophe Roullier,
Radu Rendec, linux-arm-msm, devicetree, linux-kernel, netdev,
linux-stm32, linux-arm-kernel, Drew Fustini, linux-sunxi,
linux-amlogic, linux-mips, imx, linux-renesas-soc, linux-rockchip,
sophgo, linux-riscv, Bartosz Golaszewski, Bartosz Golaszewski,
Bartosz Golaszewski
In-Reply-To: <CAMuHMdXNG=C=XcioQUEN1M7cQgKhO0AxUyg5X+TWb2rQ3-H3fw@mail.gmail.com>
On Thu, 2 Jul 2026 11:16:22 +0200, Geert Uytterhoeven
<geert@linux-m68k.org> said:
> Hi Bartosz,
>
> On Thu, 2 Jul 2026 at 11:12, Bartosz Golaszewski <brgl@kernel.org> wrote:
>> On Tue, 30 Jun 2026 12:23:16 +0200, Vinod Koul <vkoul@kernel.org> said:
>> > On 29-06-26, 16:51, Geert Uytterhoeven wrote:
>> >> > Russell King asked me to put the PHY logic for SCMI pm domains into the PHY
>> >> > driver instead of the MAC driver where it was previously. Instead of cramming
>> >> > both HLOS and firmware handling into the same driver, I figured it makes more
>> >> > sense to have a dedicated, cleaner driver as the two share very little code (if
>> >> > any).
>> >>
>> >> I think you are mixing up DT bindings and driver implementation?
>> >
>> > Should the bindings change if we have different driver and firmware
>> > implementations? Isn't binding supposed to be agnostic of
>> > implementations..?
>>
>> I've thought about it some more and I believe this question is philosophical in
>> nature.
>>
>> sa8775p and sa8255p are *the same* hardware. I can flash different firmware on
>> the same Lemans Ride board and it becomes one or the other. Yet they are not
>> described by the same DTS and the bindings differ as well. I don't see why we
>> wouldn't allow the same approach for the this PHY.
>>
>> We treat it as different HW variant when it's managed by firmware - just like
>> we do with the rest of the SoC.
>
> DT describes hardware, not software policy.
>
I'll defer to DT maintainers then for that particular case because it affects
more than just this platform. For instance: Qualcomm Nord[1] is already being
upstreamed with a similar split into common parts and then sources specific to
the SCMI and non-SCMI variants - even though it's the same SoC.
Bartosz
[1] https://lore.kernel.org/all/20260526051300.1669201-1-shengchao.guo@oss.qualcomm.com/
^ permalink raw reply
* [PATCH v10 5/5] phy: airoha: Add support for Airoha AN7581 USB PHY
From: Christian Marangi @ 2026-07-02 9:38 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Brian Masney, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Christian Marangi, Vinod Koul,
Neil Armstrong, Lorenzo Bianconi, Felix Fietkau, linux-clk,
devicetree, linux-kernel, linux-arm-kernel, linux-phy
In-Reply-To: <20260702093812.15918-1-ansuelsmth@gmail.com>
Add support for Airoha AN7581 USB PHY driver. AN7581 supports up to 2
USB port with USB 2.0 mode always supported and USB 3.0 mode available
only if the Serdes port is correctly configured for USB 3.0.
If the USB 3.0 mode is not configured, the modes needs to be also
disabled in the xHCI node or the driver will report unsable clock and
fail probe.
For USB 2.0 Slew Rate calibration, airoha,usb2-monitor-clk-sel is
mandatory and is used to select the monitor clock for calibration.
Normally it's 1 for USB port 1 and 2 for USB port 2.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
MAINTAINERS | 1 +
drivers/phy/airoha/Kconfig | 11 +
drivers/phy/airoha/Makefile | 1 +
drivers/phy/airoha/phy-an7581-usb.c | 559 ++++++++++++++++++++++++++++
4 files changed, 572 insertions(+)
create mode 100644 drivers/phy/airoha/phy-an7581-usb.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 952653034c4c..844f676254ac 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -782,6 +782,7 @@ M: Christian Marangi <ansuelsmth@gmail.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml
+F: drivers/phy/airoha/phy-an7581-usb.c
AIRSPY MEDIA DRIVER
L: linux-media@vger.kernel.org
diff --git a/drivers/phy/airoha/Kconfig b/drivers/phy/airoha/Kconfig
index 9a1b625a7701..634448ee39b5 100644
--- a/drivers/phy/airoha/Kconfig
+++ b/drivers/phy/airoha/Kconfig
@@ -11,3 +11,14 @@ config PHY_AIROHA_AN7581_PCIE
Say Y here to add support for Airoha AN7581 PCIe PHY driver.
This driver create the basic PHY instance and provides initialize
callback for PCIe GEN3 port.
+
+config PHY_AIROHA_AN7581_USB
+ tristate "Airoha AN7581 USB PHY Driver"
+ depends on ARCH_AIROHA || COMPILE_TEST
+ depends on OF
+ select GENERIC_PHY
+ select REGMAP_MMIO
+ help
+ Say 'Y' here to add support for Airoha AN7581 USB PHY driver.
+ This driver create the basic PHY instance and provides initialize
+ callback for USB port.
diff --git a/drivers/phy/airoha/Makefile b/drivers/phy/airoha/Makefile
index 912f3e11a061..944bf842deba 100644
--- a/drivers/phy/airoha/Makefile
+++ b/drivers/phy/airoha/Makefile
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_PHY_AIROHA_AN7581_PCIE) += phy-an7581-pcie.o
+obj-$(CONFIG_PHY_AIROHA_AN7581_USB) += phy-an7581-usb.o
diff --git a/drivers/phy/airoha/phy-an7581-usb.c b/drivers/phy/airoha/phy-an7581-usb.c
new file mode 100644
index 000000000000..92c5e5c2fbf3
--- /dev/null
+++ b/drivers/phy/airoha/phy-an7581-usb.c
@@ -0,0 +1,559 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Author: Christian Marangi <ansuelsmth@gmail.com>
+ */
+
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/soc/airoha,scu-ssr.h>
+#include <linux/bitfield.h>
+#include <linux/math.h>
+#include <linux/module.h>
+#include <linux/mfd/syscon.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+/* U2PHY */
+#define AIROHA_USB_PHY_FMCR0 0x100
+#define AIROHA_USB_PHY_MONCLK_SEL GENMASK(27, 26)
+#define AIROHA_USB_PHY_MONCLK_SEL0 FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x0)
+#define AIROHA_USB_PHY_MONCLK_SEL1 FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x1)
+#define AIROHA_USB_PHY_MONCLK_SEL2 FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x2)
+#define AIROHA_USB_PHY_MONCLK_SEL3 FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x3)
+#define AIROHA_USB_PHY_FREQDET_EN BIT(24)
+#define AIROHA_USB_PHY_CYCLECNT GENMASK(23, 0)
+#define AIROHA_USB_PHY_FMMONR0 0x10c
+#define AIROHA_USB_PHY_USB_FM_OUT GENMASK(31, 0)
+#define AIROHA_USB_PHY_FMMONR1 0x110
+#define AIROHA_USB_PHY_FRCK_EN BIT(8)
+
+#define AIROHA_USB_PHY_USBPHYACR4 0x310
+#define AIROHA_USB_PHY_USB20_FS_CR GENMASK(10, 8)
+#define AIROHA_USB_PHY_USB20_FS_CR_MAX FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x0)
+#define AIROHA_USB_PHY_USB20_FS_CR_NORMAL FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x2)
+#define AIROHA_USB_PHY_USB20_FS_CR_SMALLER FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x4)
+#define AIROHA_USB_PHY_USB20_FS_CR_MIN FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x6)
+#define AIROHA_USB_PHY_USB20_FS_SR GENMASK(2, 0)
+#define AIROHA_USB_PHY_USB20_FS_SR_MAX FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x0)
+#define AIROHA_USB_PHY_USB20_FS_SR_NORMAL FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x2)
+#define AIROHA_USB_PHY_USB20_FS_SR_SMALLER FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x4)
+#define AIROHA_USB_PHY_USB20_FS_SR_MIN FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x6)
+#define AIROHA_USB_PHY_USBPHYACR5 0x314
+#define AIROHA_USB_PHY_USB20_HSTX_SRCAL_EN BIT(15)
+#define AIROHA_USB_PHY_USB20_HSTX_SRCTRL GENMASK(14, 12)
+#define AIROHA_USB_PHY_USBPHYACR6 0x318
+#define AIROHA_USB_PHY_USB20_BC11_SW_EN BIT(23)
+#define AIROHA_USB_PHY_USB20_DISCTH GENMASK(7, 4)
+#define AIROHA_USB_PHY_USB20_DISCTH_400 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x0)
+#define AIROHA_USB_PHY_USB20_DISCTH_420 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x1)
+#define AIROHA_USB_PHY_USB20_DISCTH_440 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x2)
+#define AIROHA_USB_PHY_USB20_DISCTH_460 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x3)
+#define AIROHA_USB_PHY_USB20_DISCTH_480 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x4)
+#define AIROHA_USB_PHY_USB20_DISCTH_500 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x5)
+#define AIROHA_USB_PHY_USB20_DISCTH_520 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x6)
+#define AIROHA_USB_PHY_USB20_DISCTH_540 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x7)
+#define AIROHA_USB_PHY_USB20_DISCTH_560 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x8)
+#define AIROHA_USB_PHY_USB20_DISCTH_580 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x9)
+#define AIROHA_USB_PHY_USB20_DISCTH_600 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xa)
+#define AIROHA_USB_PHY_USB20_DISCTH_620 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xb)
+#define AIROHA_USB_PHY_USB20_DISCTH_640 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xc)
+#define AIROHA_USB_PHY_USB20_DISCTH_660 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xd)
+#define AIROHA_USB_PHY_USB20_DISCTH_680 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xe)
+#define AIROHA_USB_PHY_USB20_DISCTH_700 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xf)
+#define AIROHA_USB_PHY_USB20_SQTH GENMASK(3, 0)
+#define AIROHA_USB_PHY_USB20_SQTH_85 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x0)
+#define AIROHA_USB_PHY_USB20_SQTH_90 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x1)
+#define AIROHA_USB_PHY_USB20_SQTH_95 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x2)
+#define AIROHA_USB_PHY_USB20_SQTH_100 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x3)
+#define AIROHA_USB_PHY_USB20_SQTH_105 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x4)
+#define AIROHA_USB_PHY_USB20_SQTH_110 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x5)
+#define AIROHA_USB_PHY_USB20_SQTH_115 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x6)
+#define AIROHA_USB_PHY_USB20_SQTH_120 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x7)
+#define AIROHA_USB_PHY_USB20_SQTH_125 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x8)
+#define AIROHA_USB_PHY_USB20_SQTH_130 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x9)
+#define AIROHA_USB_PHY_USB20_SQTH_135 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xa)
+#define AIROHA_USB_PHY_USB20_SQTH_140 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xb)
+#define AIROHA_USB_PHY_USB20_SQTH_145 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xc)
+#define AIROHA_USB_PHY_USB20_SQTH_150 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xd)
+#define AIROHA_USB_PHY_USB20_SQTH_155 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xe)
+#define AIROHA_USB_PHY_USB20_SQTH_160 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xf)
+
+#define AIROHA_USB_PHY_U2PHYDTM1 0x36c
+#define AIROHA_USB_PHY_FORCE_IDDIG BIT(9)
+#define AIROHA_USB_PHY_IDDIG BIT(1)
+
+#define AIROHA_USB_PHY_GPIO_CTLD 0x80c
+#define AIROHA_USB_PHY_C60802_GPIO_CTLD GENMASK(31, 0)
+#define AIROHA_USB_PHY_SSUSB_IP_SW_RST BIT(31)
+#define AIROHA_USB_PHY_MCU_BUS_CK_GATE_EN BIT(30)
+#define AIROHA_USB_PHY_FORCE_SSUSB_IP_SW_RST BIT(29)
+#define AIROHA_USB_PHY_SSUSB_SW_RST BIT(28)
+
+#define AIROHA_USB_PHY_U3_PHYA_REG0 0xb00
+#define AIROHA_USB_PHY_SSUSB_BG_DIV GENMASK(29, 28)
+#define AIROHA_USB_PHY_SSUSB_BG_DIV_2 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x0)
+#define AIROHA_USB_PHY_SSUSB_BG_DIV_4 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x1)
+#define AIROHA_USB_PHY_SSUSB_BG_DIV_8 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x2)
+#define AIROHA_USB_PHY_SSUSB_BG_DIV_16 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x3)
+#define AIROHA_USB_PHY_U3_PHYA_REG1 0xb04
+#define AIROHA_USB_PHY_SSUSB_XTAL_TOP_RESERVE GENMASK(25, 10)
+#define AIROHA_USB_PHY_U3_PHYA_REG6 0xb18
+#define AIROHA_USB_PHY_SSUSB_CDR_RESERVE GENMASK(31, 24)
+#define AIROHA_USB_PHY_U3_PHYA_REG8 0xb20
+#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY GENMASK(7, 6)
+#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_32 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x0)
+#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_64 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x1)
+#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_128 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x2)
+#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_216 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x3)
+
+#define AIROHA_USB_PHY_U3_PHYA_DA_REG19 0xc38
+#define AIROHA_USB_PHY_SSUSB_PLL_SSC_DELTA1_U3 GENMASK(15, 0)
+
+#define AIROHA_USB_PHY_U2_FM_DET_CYCLE_CNT 1024
+#define AIROHA_USB_PHY_REF_CK 20
+#define AIROHA_USB_PHY_U2_SR_COEF 28
+#define AIROHA_USB_PHY_U2_SR_COEF_DIVISOR 1000
+
+#define AIROHA_USB_PHY_DEFAULT_SR_CALIBRATION 0x5
+#define AIROHA_USB_PHY_FREQDET_SLEEP 1000 /* 1ms */
+#define AIROHA_USB_PHY_FREQDET_TIMEOUT (AIROHA_USB_PHY_FREQDET_SLEEP * 10)
+
+struct an7581_usb_phy_instance {
+ struct phy *phy;
+ u32 type;
+};
+
+enum an7581_usb_phy_instance_type {
+ AIROHA_PHY_USB2,
+ AIROHA_PHY_USB3,
+
+ AIROHA_PHY_USB_MAX,
+};
+
+struct an7581_usb_phy_priv {
+ struct device *dev;
+ struct regmap *regmap;
+
+ unsigned int monclk_sel;
+
+ struct phy *serdes_phy;
+ struct an7581_usb_phy_instance *phys[AIROHA_PHY_USB_MAX];
+};
+
+static void an7581_usb_phy_u2_slew_rate_calibration(struct an7581_usb_phy_priv *priv)
+{
+ u32 fm_out = 0;
+ u32 srctrl;
+
+ /* Enable HS TX SR calibration */
+ regmap_set_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR5,
+ AIROHA_USB_PHY_USB20_HSTX_SRCAL_EN);
+
+ usleep_range(1000, 1500);
+
+ /* Enable Free run clock */
+ regmap_set_bits(priv->regmap, AIROHA_USB_PHY_FMMONR1,
+ AIROHA_USB_PHY_FRCK_EN);
+
+ /* Select Monitor Clock */
+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_FMCR0,
+ AIROHA_USB_PHY_MONCLK_SEL,
+ FIELD_PREP(AIROHA_USB_PHY_MONCLK_SEL,
+ priv->monclk_sel));
+
+ /* Set cyclecnt */
+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_FMCR0,
+ AIROHA_USB_PHY_CYCLECNT,
+ FIELD_PREP(AIROHA_USB_PHY_CYCLECNT,
+ AIROHA_USB_PHY_U2_FM_DET_CYCLE_CNT));
+
+ /* Enable Frequency meter */
+ regmap_set_bits(priv->regmap, AIROHA_USB_PHY_FMCR0,
+ AIROHA_USB_PHY_FREQDET_EN);
+
+ /* Timeout can happen and we will apply workaround at the end */
+ regmap_read_poll_timeout(priv->regmap, AIROHA_USB_PHY_FMMONR0, fm_out,
+ fm_out, AIROHA_USB_PHY_FREQDET_SLEEP,
+ AIROHA_USB_PHY_FREQDET_TIMEOUT);
+
+ /* Disable Frequency meter */
+ regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_FMCR0,
+ AIROHA_USB_PHY_FREQDET_EN);
+
+ /* Disable Free run clock */
+ regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_FMMONR1,
+ AIROHA_USB_PHY_FRCK_EN);
+
+ /* Disable HS TX SR calibration */
+ regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR5,
+ AIROHA_USB_PHY_USB20_HSTX_SRCAL_EN);
+
+ usleep_range(1000, 1500);
+
+ /* Frequency was not detected, use default SR calibration value */
+ if (!fm_out) {
+ srctrl = AIROHA_USB_PHY_DEFAULT_SR_CALIBRATION;
+ dev_err(priv->dev, "Frequency not detected, using default SR calibration.\n");
+ } else {
+ /* (1024 / FM_OUT) * REF_CK * U2_SR_COEF (round to the nearest digits) */
+ srctrl = AIROHA_USB_PHY_REF_CK * AIROHA_USB_PHY_U2_SR_COEF;
+ srctrl = (srctrl * AIROHA_USB_PHY_U2_FM_DET_CYCLE_CNT) / fm_out;
+ srctrl = DIV_ROUND_CLOSEST(srctrl, AIROHA_USB_PHY_U2_SR_COEF_DIVISOR);
+ dev_dbg(priv->dev, "SR calibration applied: %x\n", srctrl);
+ }
+
+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR5,
+ AIROHA_USB_PHY_USB20_HSTX_SRCTRL,
+ FIELD_PREP(AIROHA_USB_PHY_USB20_HSTX_SRCTRL, srctrl));
+}
+
+static void an7581_usb_phy_u2_init(struct an7581_usb_phy_priv *priv)
+{
+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR4,
+ AIROHA_USB_PHY_USB20_FS_CR,
+ AIROHA_USB_PHY_USB20_FS_CR_MIN);
+
+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR4,
+ AIROHA_USB_PHY_USB20_FS_SR,
+ AIROHA_USB_PHY_USB20_FS_SR_NORMAL);
+
+ /* FIXME: evaluate if needed */
+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6,
+ AIROHA_USB_PHY_USB20_SQTH,
+ AIROHA_USB_PHY_USB20_SQTH_130);
+
+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6,
+ AIROHA_USB_PHY_USB20_DISCTH,
+ AIROHA_USB_PHY_USB20_DISCTH_600);
+
+ /* Enable the USB port and then disable after calibration */
+ regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6,
+ AIROHA_USB_PHY_USB20_BC11_SW_EN);
+
+ an7581_usb_phy_u2_slew_rate_calibration(priv);
+
+ regmap_set_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6,
+ AIROHA_USB_PHY_USB20_BC11_SW_EN);
+
+ usleep_range(1000, 1500);
+}
+
+/*
+ * USB 3.0 mode can only work if USB serdes is correctly set.
+ * This is validated in xLate function.
+ */
+static void an7581_usb_phy_u3_init(struct an7581_usb_phy_priv *priv)
+{
+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG8,
+ AIROHA_USB_PHY_SSUSB_CDR_RST_DLY,
+ AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_32);
+
+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG6,
+ AIROHA_USB_PHY_SSUSB_CDR_RESERVE,
+ FIELD_PREP(AIROHA_USB_PHY_SSUSB_CDR_RESERVE, 0xe));
+
+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG0,
+ AIROHA_USB_PHY_SSUSB_BG_DIV,
+ AIROHA_USB_PHY_SSUSB_BG_DIV_4);
+
+ regmap_set_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG1,
+ FIELD_PREP(AIROHA_USB_PHY_SSUSB_XTAL_TOP_RESERVE, 0x600));
+
+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_DA_REG19,
+ AIROHA_USB_PHY_SSUSB_PLL_SSC_DELTA1_U3,
+ FIELD_PREP(AIROHA_USB_PHY_SSUSB_PLL_SSC_DELTA1_U3, 0x43));
+}
+
+static int an7581_usb_phy_init(struct phy *phy)
+{
+ struct an7581_usb_phy_instance *instance = phy_get_drvdata(phy);
+ struct an7581_usb_phy_priv *priv = dev_get_drvdata(phy->dev.parent);
+ int ret;
+
+ switch (instance->type) {
+ case PHY_TYPE_USB2:
+ an7581_usb_phy_u2_init(priv);
+ break;
+ case PHY_TYPE_USB3:
+ ret = phy_set_mode(priv->serdes_phy, PHY_MODE_USB_DEVICE_SS);
+ if (ret)
+ return ret;
+
+ an7581_usb_phy_u3_init(priv);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int an7581_usb_phy_u2_power_on(struct an7581_usb_phy_priv *priv)
+{
+ regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6,
+ AIROHA_USB_PHY_USB20_BC11_SW_EN);
+
+ usleep_range(1000, 1500);
+
+ return 0;
+}
+
+static int an7581_usb_phy_u3_power_on(struct an7581_usb_phy_priv *priv)
+{
+ regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_GPIO_CTLD,
+ AIROHA_USB_PHY_SSUSB_IP_SW_RST |
+ AIROHA_USB_PHY_MCU_BUS_CK_GATE_EN |
+ AIROHA_USB_PHY_FORCE_SSUSB_IP_SW_RST |
+ AIROHA_USB_PHY_SSUSB_SW_RST);
+
+ usleep_range(1000, 1500);
+
+ return 0;
+}
+
+static int an7581_usb_phy_power_on(struct phy *phy)
+{
+ struct an7581_usb_phy_instance *instance = phy_get_drvdata(phy);
+ struct an7581_usb_phy_priv *priv = dev_get_drvdata(phy->dev.parent);
+
+ switch (instance->type) {
+ case PHY_TYPE_USB2:
+ an7581_usb_phy_u2_power_on(priv);
+ break;
+ case PHY_TYPE_USB3:
+ an7581_usb_phy_u3_power_on(priv);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int an7581_usb_phy_u2_power_off(struct an7581_usb_phy_priv *priv)
+{
+ regmap_set_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6,
+ AIROHA_USB_PHY_USB20_BC11_SW_EN);
+
+ usleep_range(1000, 1500);
+
+ return 0;
+}
+
+static int an7581_usb_phy_u3_power_off(struct an7581_usb_phy_priv *priv)
+{
+ regmap_set_bits(priv->regmap, AIROHA_USB_PHY_GPIO_CTLD,
+ AIROHA_USB_PHY_SSUSB_IP_SW_RST |
+ AIROHA_USB_PHY_FORCE_SSUSB_IP_SW_RST);
+
+ usleep_range(1000, 1500);
+
+ return 0;
+}
+
+static int an7581_usb_phy_power_off(struct phy *phy)
+{
+ struct an7581_usb_phy_instance *instance = phy_get_drvdata(phy);
+ struct an7581_usb_phy_priv *priv = dev_get_drvdata(phy->dev.parent);
+
+ switch (instance->type) {
+ case PHY_TYPE_USB2:
+ an7581_usb_phy_u2_power_off(priv);
+ break;
+ case PHY_TYPE_USB3:
+ an7581_usb_phy_u3_power_off(priv);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int an7581_usb_phy_u2_set_mode(struct an7581_usb_phy_priv *priv,
+ enum phy_mode mode)
+{
+ u32 val;
+
+ /*
+ * For Device and Host mode, enable force IDDIG.
+ * For Device set IDDIG, for Host clear IDDIG.
+ * For OTG disable force and clear IDDIG bit while at it.
+ */
+ switch (mode) {
+ case PHY_MODE_USB_DEVICE:
+ val = AIROHA_USB_PHY_FORCE_IDDIG |
+ AIROHA_USB_PHY_IDDIG;
+ break;
+ case PHY_MODE_USB_HOST:
+ val = AIROHA_USB_PHY_FORCE_IDDIG;
+ break;
+ case PHY_MODE_USB_OTG:
+ val = 0;
+ break;
+ default:
+ return 0;
+ }
+
+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U2PHYDTM1,
+ AIROHA_USB_PHY_FORCE_IDDIG |
+ AIROHA_USB_PHY_IDDIG, val);
+
+ return 0;
+}
+
+static int an7581_usb_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
+{
+ struct an7581_usb_phy_instance *instance = phy_get_drvdata(phy);
+ struct an7581_usb_phy_priv *priv = dev_get_drvdata(phy->dev.parent);
+
+ switch (instance->type) {
+ case PHY_TYPE_USB2:
+ return an7581_usb_phy_u2_set_mode(priv, mode);
+ default:
+ return 0;
+ }
+}
+
+static struct phy *an7581_usb_phy_xlate(struct device *dev,
+ const struct of_phandle_args *args)
+{
+ struct an7581_usb_phy_priv *priv = dev_get_drvdata(dev);
+ struct an7581_usb_phy_instance *instance = NULL;
+ unsigned int index, phy_type;
+
+ if (args->args_count != 1) {
+ dev_err(dev, "invalid number of cells in 'phy' property\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ phy_type = args->args[0];
+ if (!(phy_type == PHY_TYPE_USB2 || phy_type == PHY_TYPE_USB3)) {
+ dev_err(dev, "unsupported device type: %d\n", phy_type);
+ return ERR_PTR(-EINVAL);
+ }
+
+ for (index = 0; index < AIROHA_PHY_USB_MAX; index++)
+ if (priv->phys[index] &&
+ phy_type == priv->phys[index]->type) {
+ instance = priv->phys[index];
+ break;
+ }
+
+ if (!instance) {
+ dev_err(dev, "failed to find appropriate phy\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (instance->type == PHY_TYPE_USB3 && !priv->serdes_phy) {
+ dev_err(dev, "missing serdes phy for USB 3.0\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ return instance->phy;
+}
+
+static const struct phy_ops airoha_phy = {
+ .init = an7581_usb_phy_init,
+ .power_on = an7581_usb_phy_power_on,
+ .power_off = an7581_usb_phy_power_off,
+ .set_mode = an7581_usb_phy_set_mode,
+ .owner = THIS_MODULE,
+};
+
+static const struct regmap_config an7581_usb_phy_regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+};
+
+static int an7581_usb_phy_probe(struct platform_device *pdev)
+{
+ struct phy_provider *phy_provider;
+ struct an7581_usb_phy_priv *priv;
+ struct device *dev = &pdev->dev;
+ unsigned int index;
+ void __iomem *base;
+ int ret;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->dev = dev;
+
+ ret = of_property_read_u32(dev->of_node, "airoha,usb2-monitor-clk-sel",
+ &priv->monclk_sel);
+ if (ret)
+ return dev_err_probe(dev, ret, "Monitor clock selection is mandatory for USB PHY calibration\n");
+
+ if (priv->monclk_sel > 3)
+ return dev_err_probe(dev, -EINVAL, "only 4 Monitor clock are selectable on the SoC\n");
+
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ priv->regmap = devm_regmap_init_mmio(dev, base, &an7581_usb_phy_regmap_config);
+ if (IS_ERR(priv->regmap))
+ return PTR_ERR(priv->regmap);
+
+ platform_set_drvdata(pdev, priv);
+
+ for (index = 0; index < AIROHA_PHY_USB_MAX; index++) {
+ struct an7581_usb_phy_instance *instance;
+ u32 phy_type;
+
+ switch (index) {
+ case AIROHA_PHY_USB2:
+ phy_type = PHY_TYPE_USB2;
+ break;
+ case AIROHA_PHY_USB3:
+ phy_type = PHY_TYPE_USB3;
+ break;
+ }
+
+ if (phy_type == PHY_TYPE_USB3) {
+ priv->serdes_phy = devm_phy_optional_get(dev, NULL);
+ if (IS_ERR(priv->serdes_phy))
+ return dev_err_probe(dev, PTR_ERR(priv->serdes_phy), "error on serdes phy for USB 3.0\n");
+ }
+
+ instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
+ if (!instance)
+ return -ENOMEM;
+
+ instance->type = phy_type;
+ priv->phys[index] = instance;
+
+ instance->phy = devm_phy_create(dev, NULL, &airoha_phy);
+ if (IS_ERR(instance->phy))
+ return dev_err_probe(dev, PTR_ERR(instance->phy), "failed to create phy\n");
+
+ phy_set_drvdata(instance->phy, instance);
+ }
+
+ phy_provider = devm_of_phy_provider_register(&pdev->dev, an7581_usb_phy_xlate);
+
+ return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id airoha_phy_id_table[] = {
+ { .compatible = "airoha,an7581-usb-phy" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, airoha_phy_id_table);
+
+static struct platform_driver an7581_usb_driver = {
+ .probe = an7581_usb_phy_probe,
+ .driver = {
+ .name = "airoha-an7581-usb-phy",
+ .of_match_table = airoha_phy_id_table,
+ },
+};
+
+module_platform_driver(an7581_usb_driver);
+
+MODULE_DESCRIPTION("Airoha AN7581 USB PHY driver");
+MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
+MODULE_LICENSE("GPL");
--
2.53.0
^ permalink raw reply related
* [PATCH v10 3/5] clk: en7523: Add support for selecting the Serdes port in SCU
From: Christian Marangi @ 2026-07-02 9:38 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Brian Masney, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Christian Marangi, Vinod Koul,
Neil Armstrong, Lorenzo Bianconi, Felix Fietkau, linux-clk,
devicetree, linux-kernel, linux-arm-kernel, linux-phy
In-Reply-To: <20260702093812.15918-1-ansuelsmth@gmail.com>
In the SCU register for clock and reset, there are also some register to
select the Serdes port mode. The Airoha AN7581 SoC have 4 different Serdes
that can switch between PCIe, USB or Ethernet mode.
Add a simple PHY provider that expose the .set_mode OP to toggle the
requested mode for the Serdes port.
Reviewed-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/clk/Kconfig | 1 +
drivers/clk/clk-en7523.c | 218 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 216 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 1717ce75a907..4d58c35d88bc 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -221,6 +221,7 @@ config COMMON_CLK_EN7523
bool "Clock driver for Airoha/EcoNet SoC system clocks"
depends on OF
depends on ARCH_AIROHA || ECONET || COMPILE_TEST
+ select GENERIC_PHY
default ARCH_AIROHA
help
This driver provides the fixed clocks and gates present on Airoha
diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c
index 1ab0e2eca5d3..183cf7fe4bda 100644
--- a/drivers/clk/clk-en7523.c
+++ b/drivers/clk/clk-en7523.c
@@ -6,14 +6,18 @@
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/platform_device.h>
+#include <linux/phy.h>
+#include <linux/phy/phy.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/reset-controller.h>
+#include <linux/spinlock.h>
#include <dt-bindings/clock/en7523-clk.h>
#include <dt-bindings/reset/airoha,en7523-reset.h>
#include <dt-bindings/reset/airoha,en7581-reset.h>
#include <dt-bindings/clock/econet,en751221-scu.h>
#include <dt-bindings/reset/econet,en751221-scu.h>
+#include <dt-bindings/soc/airoha,scu-ssr.h>
#define RST_NR_PER_BANK 32
@@ -40,9 +44,22 @@
#define REG_HIR_MASK GENMASK(31, 16)
/* EN7581 */
#define REG_NP_SCU_PCIC 0x88
+#define REG_NP_SCU_SSR3 0x94
+#define REG_SSUSB_HSGMII_SEL_MASK BIT(29)
+#define REG_SSUSB_HSGMII_SEL_HSGMII FIELD_PREP_CONST(REG_SSUSB_HSGMII_SEL_MASK, 0x0)
+#define REG_SSUSB_HSGMII_SEL_USB FIELD_PREP_CONST(REG_SSUSB_HSGMII_SEL_MASK, 0x1)
#define REG_NP_SCU_SSTR 0x9c
#define REG_PCIE_XSI0_SEL_MASK GENMASK(14, 13)
+#define REG_PCIE_XSI0_SEL_PCIE FIELD_PREP_CONST(REG_PCIE_XSI0_SEL_MASK, 0x0)
+#define REG_PCIE_XSI0_SEL_XFI FIELD_PREP_CONST(REG_PCIE_XSI0_SEL_MASK, 0x1)
+#define REG_PCIE_XSI0_SEL_HSGMII FIELD_PREP_CONST(REG_PCIE_XSI0_SEL_MASK, 0x2)
#define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11)
+#define REG_PCIE_XSI1_SEL_PCIE FIELD_PREP_CONST(REG_PCIE_XSI1_SEL_MASK, 0x0)
+#define REG_PCIE_XSI1_SEL_XFI FIELD_PREP_CONST(REG_PCIE_XSI1_SEL_MASK, 0x1)
+#define REG_PCIE_XSI1_SEL_HSGMII FIELD_PREP_CONST(REG_PCIE_XSI1_SEL_MASK, 0x2)
+#define REG_USB_PCIE_SEL_MASK BIT(3)
+#define REG_USB_PCIE_SEL_PCIE FIELD_PREP_CONST(REG_USB_PCIE_SEL_MASK, 0x0)
+#define REG_USB_PCIE_SEL_USB FIELD_PREP_CONST(REG_USB_PCIE_SEL_MASK, 0x1)
#define REG_CRYPTO_CLKSRC2 0x20c
/* EN751221 */
#define EN751221_REG_SPI_DIV 0x0cc
@@ -81,6 +98,8 @@ enum en_hir {
HIR_MAX = 14,
};
+#define EN_SERDES_PHY_NUM 4
+
struct en_clk_desc {
int id;
const char *name;
@@ -113,6 +132,18 @@ struct en_rst_data {
struct reset_controller_dev rcdev;
};
+struct en_serdes_phy_instance {
+ struct phy *phy;
+ unsigned int serdes_port;
+};
+
+struct en_clk_priv {
+ void __iomem *base;
+ /* protect SCU register */
+ spinlock_t lock;
+ struct en_serdes_phy_instance *serdes_phys[EN_SERDES_PHY_NUM];
+};
+
struct en_clk_soc_data {
u32 num_clocks;
const struct clk_ops pcie_ops;
@@ -830,12 +861,179 @@ static int en7581_reset_register(struct device *dev, void __iomem *base,
return devm_reset_controller_register(dev, &rst_data->rcdev);
}
+static int en7581_serdes_phy_set_mode(struct phy *phy, enum phy_mode mode,
+ int submode)
+{
+ struct en_serdes_phy_instance *instance = phy_get_drvdata(phy);
+ struct en_clk_priv *priv = dev_get_drvdata(phy->dev.parent);
+ u32 reg, mask, sel, val;
+ unsigned long flags;
+
+ switch (instance->serdes_port) {
+ case AIROHA_SCU_SERDES_PCIE1:
+ reg = REG_NP_SCU_SSTR;
+ mask = REG_PCIE_XSI0_SEL_MASK;
+
+ if (mode != PHY_MODE_ETHERNET && mode != PHY_MODE_PCIE)
+ return -EINVAL;
+
+ if (mode == PHY_MODE_ETHERNET) {
+ switch (submode) {
+ case PHY_INTERFACE_MODE_USXGMII:
+ case PHY_INTERFACE_MODE_10GBASER:
+ sel = REG_PCIE_XSI0_SEL_XFI;
+ break;
+ case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_1000BASEX:
+ case PHY_INTERFACE_MODE_2500BASEX:
+ sel = REG_PCIE_XSI0_SEL_HSGMII;
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else {
+ sel = REG_PCIE_XSI0_SEL_PCIE;
+ }
+
+ break;
+ case AIROHA_SCU_SERDES_PCIE2:
+ reg = REG_NP_SCU_SSTR;
+ mask = REG_PCIE_XSI1_SEL_MASK;
+
+ if (mode != PHY_MODE_ETHERNET && mode != PHY_MODE_PCIE)
+ return -EINVAL;
+
+ if (mode == PHY_MODE_ETHERNET) {
+ switch (submode) {
+ case PHY_INTERFACE_MODE_USXGMII:
+ case PHY_INTERFACE_MODE_10GBASER:
+ sel = REG_PCIE_XSI1_SEL_XFI;
+ break;
+ case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_1000BASEX:
+ case PHY_INTERFACE_MODE_2500BASEX:
+ sel = REG_PCIE_XSI1_SEL_HSGMII;
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else {
+ sel = REG_PCIE_XSI1_SEL_PCIE;
+ }
+
+ break;
+ case AIROHA_SCU_SERDES_USB1:
+ reg = REG_NP_SCU_SSR3;
+ mask = REG_SSUSB_HSGMII_SEL_MASK;
+
+ if (mode != PHY_MODE_ETHERNET && mode != PHY_MODE_USB_DEVICE &&
+ mode != PHY_MODE_USB_DEVICE_SS)
+ return -EINVAL;
+
+ if (mode == PHY_MODE_ETHERNET)
+ sel = REG_SSUSB_HSGMII_SEL_HSGMII;
+ else
+ sel = REG_SSUSB_HSGMII_SEL_USB;
+
+ break;
+ case AIROHA_SCU_SERDES_USB2:
+ reg = REG_NP_SCU_SSTR;
+ mask = REG_USB_PCIE_SEL_MASK;
+
+ if (mode != PHY_MODE_PCIE && mode != PHY_MODE_USB_DEVICE &&
+ mode != PHY_MODE_USB_DEVICE_SS)
+ return -EINVAL;
+
+ if (mode == PHY_MODE_PCIE)
+ sel = REG_USB_PCIE_SEL_PCIE;
+ else
+ sel = REG_USB_PCIE_SEL_USB;
+
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&priv->lock, flags);
+ val = readl(priv->base + reg);
+ val &= ~mask;
+ val |= sel;
+ writel(val, priv->base + reg);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+
+static const struct phy_ops en7581_serdes_phy_ops = {
+ .set_mode = en7581_serdes_phy_set_mode,
+ .owner = THIS_MODULE,
+};
+
+static struct phy *en7581_serdes_phy_xlate(struct device *dev,
+ const struct of_phandle_args *args)
+{
+ struct en_clk_priv *priv = dev_get_drvdata(dev);
+ struct en_serdes_phy_instance *instance;
+ unsigned int serdes_port;
+
+ if (args->args_count != 1) {
+ dev_err(dev, "invalid number of cells in 'phy' property\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ serdes_port = args->args[0];
+ if (serdes_port >= EN_SERDES_PHY_NUM) {
+ dev_err(dev, "invalid serdes port: %d\n", serdes_port);
+ return ERR_PTR(-EINVAL);
+ }
+
+ instance = priv->serdes_phys[serdes_port];
+ if (!instance) {
+ dev_err(dev, "failed to find appropriate serdes phy\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ return instance->phy;
+}
+
+static int en7581_serdes_phy_register(struct device *dev)
+{
+ struct en_clk_priv *priv = dev_get_drvdata(dev);
+ struct phy_provider *phy_provider;
+ int i;
+
+ for (i = 0; i < EN_SERDES_PHY_NUM; i++) {
+ struct en_serdes_phy_instance *instance;
+
+ instance = devm_kzalloc(dev, sizeof(*instance),
+ GFP_KERNEL);
+ if (!instance)
+ return -ENOMEM;
+
+ instance->phy = devm_phy_create(dev, NULL,
+ &en7581_serdes_phy_ops);
+ if (IS_ERR(instance->phy))
+ return dev_err_probe(dev, PTR_ERR(instance->phy), "failed to create phy\n");
+
+ instance->serdes_port = i;
+ priv->serdes_phys[i] = instance;
+
+ phy_set_drvdata(instance->phy, instance);
+ }
+
+ phy_provider = devm_of_phy_provider_register(dev, en7581_serdes_phy_xlate);
+
+ return PTR_ERR_OR_ZERO(phy_provider);
+}
+
static int en7581_clk_hw_init(struct platform_device *pdev,
struct clk_hw_onecell_data *clk_data)
{
+ struct en_clk_priv *priv = platform_get_drvdata(pdev);
struct regmap *map;
void __iomem *base;
u32 val;
+ int ret;
map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu");
if (IS_ERR(map))
@@ -845,6 +1043,8 @@ static int en7581_clk_hw_init(struct platform_device *pdev,
if (IS_ERR(base))
return PTR_ERR(base);
+ priv->base = base;
+
en7581_register_clocks(&pdev->dev, clk_data, map, base);
val = readl(base + REG_NP_SCU_SSTR);
@@ -853,9 +1053,12 @@ static int en7581_clk_hw_init(struct platform_device *pdev,
val = readl(base + REG_NP_SCU_PCIC);
writel(val | 3, base + REG_NP_SCU_PCIC);
- return en7581_reset_register(&pdev->dev, base, en7581_rst_map,
- ARRAY_SIZE(en7581_rst_map),
- en7581_rst_ofs);
+ ret = en7581_reset_register(&pdev->dev, base, en7581_rst_map,
+ ARRAY_SIZE(en7581_rst_map), en7581_rst_ofs);
+ if (ret)
+ return ret;
+
+ return en7581_serdes_phy_register(&pdev->dev);
}
static enum en_hir get_hw_id(void __iomem *np_base)
@@ -962,16 +1165,25 @@ static int en7523_clk_probe(struct platform_device *pdev)
struct device_node *node = pdev->dev.of_node;
const struct en_clk_soc_data *soc_data;
struct clk_hw_onecell_data *clk_data;
+ struct en_clk_priv *priv;
int r;
soc_data = device_get_match_data(&pdev->dev);
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ spin_lock_init(&priv->lock);
+
clk_data = devm_kzalloc(&pdev->dev,
struct_size(clk_data, hws, soc_data->num_clocks),
GFP_KERNEL);
if (!clk_data)
return -ENOMEM;
+ platform_set_drvdata(pdev, priv);
+
clk_data->num = soc_data->num_clocks;
r = soc_data->hw_init(pdev, clk_data);
if (r)
--
2.53.0
^ permalink raw reply related
* [PATCH v10 2/5] dt-bindings: phy: Add documentation for Airoha AN7581 USB PHY
From: Christian Marangi @ 2026-07-02 9:38 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Brian Masney, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Christian Marangi, Vinod Koul,
Neil Armstrong, Lorenzo Bianconi, Felix Fietkau, linux-clk,
devicetree, linux-kernel, linux-arm-kernel, linux-phy
Cc: Krzysztof Kozlowski
In-Reply-To: <20260702093812.15918-1-ansuelsmth@gmail.com>
Add documentation for Airoha AN7581 USB PHY that describe the USB PHY
for the USB controller.
Airoha AN7581 SoC support a maximum of 2 USB port. The USB 2.0 mode is
always supported. The USB 3.0 mode is optional and depends on the Serdes
mode currently configured on the system for the relevant USB port.
To correctly calibrate, the USB 2.0 port require correct value in
"airoha,usb2-monitor-clk-sel" property. Both the 2 USB 2.0 port permit
selecting one of the 4 monitor clock for calibration (internal clock not
exposed to the system) but each port have only one of the 4 actually
connected in HW hence the correct value needs to be specified in DT
based on board and the physical port. Normally it's monitor clock 1 for
USB1 and monitor clock 2 for USB2.
To correctly setup the Serdes mode attached to the USB 3.0 mode, a phys
property is required with the phandle pointing to the correct Serdes port
provided by the SCU node. Providing the phys property is optional if USB
3.0 is not used.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
.../bindings/phy/airoha,an7581-usb-phy.yaml | 62 +++++++++++++++++++
MAINTAINERS | 6 ++
2 files changed, 68 insertions(+)
create mode 100644 Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml
diff --git a/Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml b/Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml
new file mode 100644
index 000000000000..f42e3d49a61f
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/airoha,an7581-usb-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Airoha AN7581 SoC USB PHY
+
+maintainers:
+ - Christian Marangi <ansuelsmth@gmail.com>
+
+description: >
+ The Airoha AN7581 SoC USB PHY describes the USB PHY for the USB controller.
+
+ Airoha AN7581 SoC support a maximum of 2 USB port. The USB 2.0 mode is
+ always supported. The USB 3.0 mode is optional and depends on the Serdes
+ mode currently configured on the system for the relevant USB port.
+
+properties:
+ compatible:
+ const: airoha,an7581-usb-phy
+
+ reg:
+ maxItems: 1
+
+ airoha,usb2-monitor-clk-sel:
+ description: Describe what oscillator across the available 4
+ should be selected for USB 2.0 Slew Rate calibration.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1, 2, 3]
+
+ phys:
+ items:
+ - description: phandle to Serdes PHY. Optional if USB 3.0 is not used.
+
+ '#phy-cells':
+ description: The cell contains the mode, PHY_TYPE_USB2 or PHY_TYPE_USB3,
+ as defined in dt-bindings/phy/phy.h.
+ const: 1
+
+required:
+ - compatible
+ - reg
+ - airoha,usb2-monitor-clk-sel
+ - '#phy-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/soc/airoha,scu-ssr.h>
+
+ phy@1fac0000 {
+ compatible = "airoha,an7581-usb-phy";
+ reg = <0x1fac0000 0x10000>;
+
+ airoha,usb2-monitor-clk-sel = <1>;
+ phys = <&scu AIROHA_SCU_SERDES_USB1>;
+
+ #phy-cells = <1>;
+ };
+
diff --git a/MAINTAINERS b/MAINTAINERS
index 1705eb823dd0..05e90c3f7fe0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -777,6 +777,12 @@ S: Maintained
F: Documentation/devicetree/bindings/spi/airoha,en7581-snand.yaml
F: drivers/spi/spi-airoha-snfi.c
+AIROHA USB PHY DRIVER
+M: Christian Marangi <ansuelsmth@gmail.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml
+
AIRSPY MEDIA DRIVER
L: linux-media@vger.kernel.org
S: Orphan
--
2.53.0
^ permalink raw reply related
* [PATCH v10 1/5] dt-bindings: clock: airoha: Add PHY binding for Serdes port
From: Christian Marangi @ 2026-07-02 9:38 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Brian Masney, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Christian Marangi, Vinod Koul,
Neil Armstrong, Lorenzo Bianconi, Felix Fietkau, linux-clk,
devicetree, linux-kernel, linux-arm-kernel, linux-phy
Cc: Krzysztof Kozlowski
In-Reply-To: <20260702093812.15918-1-ansuelsmth@gmail.com>
Add PHY cell property for Serdes port selection. Currently supported only
for Airoha AN7581 SoC, that support up to 4 Serdes port.
The Serdes port can support both PCIe, USB3 or Ethernet mode.
- PCIe1 Serdes can support PCIe or Ethernet mode.
- PCIe2 Serdes can support PCIe or Ethernet mode.
- USB1 Serdes can support USB3 or HSGMII mode.
- USB2 Serdes can support USB3 or PCIe mode.
Add bindings to permit correct reference of the Serdes ports in DT.
Values are just symbolic and enumerates the Serdes port with a specific
number for precise reference.
The available Serdes port can be selected following the dt-binding header
in [2].
[2] <include/dt-bindings/soc/airoha,scu-ssr.h>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
.../devicetree/bindings/clock/airoha,en7523-scu.yaml | 9 +++++++++
include/dt-bindings/soc/airoha,scu-ssr.h | 11 +++++++++++
2 files changed, 20 insertions(+)
create mode 100644 include/dt-bindings/soc/airoha,scu-ssr.h
diff --git a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
index eb24a5687639..913ddc16182b 100644
--- a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
+++ b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
@@ -23,6 +23,7 @@ description: |
All these identifiers can be found in:
[1]: <include/dt-bindings/clock/en7523-clk.h>.
+ [2]: <include/dt-bindings/soc/airoha,scu-ssr.h>.
The clocks are provided inside a system controller node.
@@ -50,6 +51,12 @@ properties:
description: ID of the controller reset line
const: 1
+ '#phy-cells':
+ description:
+ The first cell indicates the serdes phy number, see [2] for the
+ available serdes port.
+ const: 1
+
required:
- compatible
- reg
@@ -65,6 +72,8 @@ allOf:
reg:
minItems: 2
+ '#phy-cells': false
+
- if:
properties:
compatible:
diff --git a/include/dt-bindings/soc/airoha,scu-ssr.h b/include/dt-bindings/soc/airoha,scu-ssr.h
new file mode 100644
index 000000000000..33c64844ada3
--- /dev/null
+++ b/include/dt-bindings/soc/airoha,scu-ssr.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+
+#ifndef __DT_BINDINGS_AIROHA_SCU_SSR_H
+#define __DT_BINDINGS_AIROHA_SCU_SSR_H
+
+#define AIROHA_SCU_SERDES_PCIE1 0
+#define AIROHA_SCU_SERDES_PCIE2 1
+#define AIROHA_SCU_SERDES_USB1 2
+#define AIROHA_SCU_SERDES_USB2 3
+
+#endif /* __DT_BINDINGS_AIROHA_SCU_SSR_H */
--
2.53.0
^ permalink raw reply related
* Re: [PATCH v2 2/6] mm/rmap: use huge_ptep_get() in try_to_unmap_one()
From: Muchun Song @ 2026-07-02 9:35 UTC (permalink / raw)
To: Dev Jain, david
Cc: riel, vbabka, harry, jannh, lance.yang, kas, linux-mm,
linux-kernel, rcampbell, apopple, ziy, matthew.brost,
joshua.hahnjy, rakie.kim, byungchul, gourry, ying.huang,
nao.horiguchi, ak, mel, pfalcato, jpoimboe, dave.hansen, tglx,
catalin.marinas, will, linux-arm-kernel, ryan.roberts,
anshuman.khandual, stable, osalvador, akpm, ljs, liam
In-Reply-To: <a6a00b38-612f-439d-9b75-337170e3af30@arm.com>
> On Jul 2, 2026, at 17:08, Dev Jain <dev.jain@arm.com> wrote:
>
>
>
> On 02/07/26 2:17 pm, Muchun Song wrote:
>>
>>
>> On 2026/7/2 13:13, Dev Jain wrote:
>>> try_to_unmap_one() handles hugetlb folios when memory failure needs
>>> to replace a poisoned hugetlb mapping with a hwpoison entry. In that
>>> case page_vma_mapped_walk() returns the pte pointer to the hugetlb folio
>>> in pvmw.pte, but the code reads it with ptep_get().
>>>
>>> On arches which provide their own huge_ptep_get() to dereference a huge
>>> pte pointer, accessing via ptep_get() would cause pte_pfn(), pte_present()
>>> etc to misbehave.
>>>
>>> It is not clear whether this has a trivially visible effect to userspace.
>>>
>>> Just use huge_ptep_get() for dereferencing a huge pte pointer.
>>>
>>> Fixes: c7ab0d2fdc84 ("mm: convert try_to_unmap_one() to use page_vma_mapped_walk()")
>>> Cc: stable@vger.kernel.org
>>> Reported-by: David Hildenbrand <david@kernel.org>
>>> Signed-off-by: Dev Jain <dev.jain@arm.com>
>>> ---
>>> include/linux/hugetlb.h | 3 +++
>>> mm/rmap.c | 16 ++++++++++------
>>> 2 files changed, 13 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
>>> index 2abaf99321e90..fdb7bdf7645c5 100644
>>> --- a/include/linux/hugetlb.h
>>> +++ b/include/linux/hugetlb.h
>>> @@ -1261,6 +1261,9 @@ static inline void hugetlb_count_sub(long l, struct mm_struct *mm)
>>> {
>>> }
>>> +pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr,
>>> + pte_t *ptep);
>>> +
>>
>> Maybe I didn't express my thoughts clearly in the first version, let me
>> explain in more detail.
>>
>> We should define this stub as a no-op for !CONFIG_HUGETLB_PAGE (like
>> set_huge_pte_at, that is why I mentioned 5d4af6195c87c6 for your reference
>> in your previous version). Currently, you've added a declaration, but the
>> function itself doesn't actually exist, which seems quite strange to me.
>
> https://lore.kernel.org/all/a4fe8ba6-2ecd-4bb9-95a9-27f9f1e87d2e@kernel.org/
>
> David suggested this. Honestly I quite like David's suggestion, what do you
> think?
Thanks for pointing that out, I missed it earlier. That said, looking at
hugetlb.h, it already contains quite a few no-op stubs. To keep things
consistent, I'd personally prefer a stub here. Since David suggested this,
I’d love to hear his thoughts on this as well.
Muchun,
Thanks
>
>
>>
>> Muchun,
>> Thanks.
>>> static inline pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
>>> unsigned long addr, pte_t *ptep)
>>> {
>>> diff --git a/mm/rmap.c b/mm/rmap.c
>>> index 1c77d5dc06e9f..aa8a254efaecc 100644
>>> --- a/mm/rmap.c
>>> +++ b/mm/rmap.c
>>> @@ -2095,11 +2095,16 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma,
>>> /* Unexpected PMD-mapped THP? */
>>> VM_BUG_ON_FOLIO(!pvmw.pte, folio);
>>> - /*
>>> - * Handle PFN swap PTEs, such as device-exclusive ones, that
>>> - * actually map pages.
>>> - */
>>> - pteval = ptep_get(pvmw.pte);
>>> + address = pvmw.address;
>>> + if (folio_test_hugetlb(folio)) {
>>> + pteval = huge_ptep_get(mm, address, pvmw.pte);
>>> + } else {
>>> + /*
>>> + * Handle PFN swap PTEs, such as device-exclusive ones,
>>> + * that actually map pages.
>>> + */
>>> + pteval = ptep_get(pvmw.pte);
>>> + }
>>> if (likely(pte_present(pteval))) {
>>> pfn = pte_pfn(pteval);
>>> } else {
>>> @@ -2110,7 +2115,6 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma,
>>> }
>>> subpage = folio_page(folio, pfn - folio_pfn(folio));
>>> - address = pvmw.address;
>>> anon_exclusive = folio_test_anon(folio) &&
>>> PageAnonExclusive(subpage);
^ permalink raw reply
* Re: [PATCH 02/42] drm/mediatek: Export OVL formats definitions and format conversion API
From: CK Hu (胡俊光) @ 2026-07-02 9:36 UTC (permalink / raw)
To: AngeloGioacchino Del Regno, chunkuang.hu@kernel.org
Cc: robh@kernel.org, tzimmermann@suse.de, simona@ffwll.ch,
mripard@kernel.org, kernel@collabora.com,
linux-mediatek@lists.infradead.org,
maarten.lankhorst@linux.intel.com,
dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
conor+dt@kernel.org, devicetree@vger.kernel.org,
krzk+dt@kernel.org, Paul-pl Chen (陳柏霖),
p.zabel@pengutronix.de, Nancy Lin (林欣螢),
airlied@gmail.com, Justin Yeh (葉英茂),
matthias.bgg@gmail.com, linux-arm-kernel@lists.infradead.org,
Jason-JH Lin (林睿祥)
In-Reply-To: <20260701122057.19648-3-angelogioacchino.delregno@collabora.com>
On Wed, 2026-07-01 at 14:20 +0200, AngeloGioacchino Del Regno wrote:
> From: Nancy Lin <nancy.lin@mediatek.com>
>
> In upcoming SoCs, the OVL component will be divided into multiple
> smaller hardware units to enhance flexibility. To facilitate this
> transition, the OVL format definitions and format conversion API
> should be exported for reuse across these units.
>
> Signed-off-by: Nancy Lin <nancy.lin@mediatek.com>
> Signed-off-by: Paul-pl Chen <paul-pl.chen@mediatek.com>
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> ---
[snip]
>
> -static unsigned int mtk_ovl_fmt_convert(struct mtk_disp_ovl *ovl,
> - struct mtk_plane_state *state)
> +unsigned int mtk_ovl_fmt_convert(unsigned int fmt, unsigned int blend_mode,
> + bool fmt_rgb565_is_0, bool color_convert,
> + u8 clrfmt_shift, u32 clrfmt_man, u32 byte_swap, u32 rgb_swap)
> {
> - unsigned int fmt = state->pending.format;
> - unsigned int blend_mode = DRM_MODE_BLEND_COVERAGE;
> -
> - /*
> - * For the platforms where OVL_CON_CLRFMT_MAN is defined in the hardware data sheet
> - * and supports premultiplied color formats, such as OVL_CON_CLRFMT_PARGB8888.
> - *
> - * Check blend_modes in the driver data to see if premultiplied mode is supported.
> - * If not, use coverage mode instead to set it to the supported color formats.
> - *
> - * Current DRM assumption is that alpha is default premultiplied, so the bitmask of
> - * blend_modes must include BIT(DRM_MODE_BLEND_PREMULTI). Otherwise, mtk_plane_init()
> - * will get an error return from drm_plane_create_blend_mode_property() and
> - * state->base.pixel_blend_mode should not be used.
> - */
> - if (ovl->data->blend_modes & BIT(DRM_MODE_BLEND_PREMULTI))
> - blend_mode = state->base.pixel_blend_mode;
> + unsigned int con = 0;
> + bool need_byte_swap = false, need_rgb_swap = false;
>
> switch (fmt) {
> default:
> case DRM_FORMAT_RGB565:
> - return OVL_CON_CLRFMT_RGB565(ovl);
> + con = fmt_rgb565_is_0 ?
> + OVL_CON_CLRFMT_RGB565(clrfmt_shift) : OVL_CON_CLRFMT_RGB888(clrfmt_shift);
> + break;
One more indent.
> case DRM_FORMAT_BGR565:
> - return OVL_CON_CLRFMT_RGB565(ovl) | OVL_CON_BYTE_SWAP;
> + con = fmt_rgb565_is_0 ?
> + OVL_CON_CLRFMT_RGB565(clrfmt_shift) : OVL_CON_CLRFMT_RGB888(clrfmt_shift);
> + need_byte_swap = true; /* RGB565 -> BGR565 */
> + break;
> case DRM_FORMAT_RGB888:
> - return OVL_CON_CLRFMT_RGB888(ovl);
> + con = fmt_rgb565_is_0 ?
> + OVL_CON_CLRFMT_RGB888(clrfmt_shift) : OVL_CON_CLRFMT_RGB565(clrfmt_shift);
> + break;
> case DRM_FORMAT_BGR888:
> - return OVL_CON_CLRFMT_RGB888(ovl) | OVL_CON_BYTE_SWAP;
> + con = fmt_rgb565_is_0 ?
> + OVL_CON_CLRFMT_RGB888(clrfmt_shift) : OVL_CON_CLRFMT_RGB565(clrfmt_shift);
> + need_byte_swap = true; /* RGB888 -> BGR888 */
> + break;
> case DRM_FORMAT_RGBX8888:
> case DRM_FORMAT_RGBA8888:
> case DRM_FORMAT_RGBX1010102:
> case DRM_FORMAT_RGBA1010102:
> - return blend_mode == DRM_MODE_BLEND_COVERAGE ?
> - OVL_CON_CLRFMT_RGBA8888 :
> - OVL_CON_CLRFMT_PRGBA8888;
> + if (blend_mode == DRM_MODE_BLEND_COVERAGE) {
> + con = OVL_CON_CLRFMT_RGBA8888(clrfmt_shift);
> + } else {
> + con = OVL_CON_CLRFMT_PARGB8888(clrfmt_shift, clrfmt_man);
> + need_byte_swap = true; /* PARGB8888 -> PBGRA8888 */
> + need_rgb_swap = true; /* PBGRA8888 -> PRGBA8888 */
> + }
> + break;
> case DRM_FORMAT_BGRX8888:
> case DRM_FORMAT_BGRA8888:
> case DRM_FORMAT_BGRX1010102:
> case DRM_FORMAT_BGRA1010102:
> - return blend_mode == DRM_MODE_BLEND_COVERAGE ?
> - OVL_CON_CLRFMT_BGRA8888 :
> - OVL_CON_CLRFMT_PBGRA8888;
> + if (blend_mode == DRM_MODE_BLEND_COVERAGE) {
> + con = OVL_CON_CLRFMT_RGBA8888(clrfmt_shift);
> + need_byte_swap = true; /* RGB8888 -> BGR8888 */
/* RGBA8888 -> BGRA8888 */
Regards,
CK
> + } else {
> + con = OVL_CON_CLRFMT_PARGB8888(clrfmt_shift, clrfmt_man);
> + need_byte_swap = true; /* PARGB8888 -> PBGRA8888 */
> + }
> + break;
> case DRM_FORMAT_XRGB8888:
> case DRM_FORMAT_ARGB8888:
> case DRM_FORMAT_XRGB2101010:
> case DRM_FORMAT_ARGB2101010:
> - return blend_mode == DRM_MODE_BLEND_COVERAGE ?
> - OVL_CON_CLRFMT_ARGB8888 :
> - OVL_CON_CLRFMT_PARGB8888;
> + if (blend_mode == DRM_MODE_BLEND_COVERAGE)
> + con = OVL_CON_CLRFMT_ARGB8888(clrfmt_shift);
> + else
> + con = OVL_CON_CLRFMT_PARGB8888(clrfmt_shift, clrfmt_man);
> + break;
> case DRM_FORMAT_XBGR8888:
> case DRM_FORMAT_ABGR8888:
> case DRM_FORMAT_XBGR2101010:
> case DRM_FORMAT_ABGR2101010:
> - return blend_mode == DRM_MODE_BLEND_COVERAGE ?
> - OVL_CON_CLRFMT_ABGR8888 :
> - OVL_CON_CLRFMT_PABGR8888;
> + if (blend_mode == DRM_MODE_BLEND_COVERAGE) {
> + con = OVL_CON_CLRFMT_ARGB8888(clrfmt_shift);
> + need_rgb_swap = true; /* ARGB8888 -> ABGR8888 */
> + } else {
> + con = OVL_CON_CLRFMT_PARGB8888(clrfmt_shift, clrfmt_man);
> + need_rgb_swap = true; /* PARGB8888 -> PABGR8888 */
> + }
> + break;
> case DRM_FORMAT_UYVY:
> - return OVL_CON_CLRFMT_UYVY | OVL_CON_MTX_YUV_TO_RGB;
> + con = OVL_CON_CLRFMT_UYVY(clrfmt_shift);
> + if (color_convert)
> + con |= OVL_CON_MTX_YUV_TO_RGB;
> + break;
> case DRM_FORMAT_YUYV:
> - return OVL_CON_CLRFMT_YUYV | OVL_CON_MTX_YUV_TO_RGB;
> + con = OVL_CON_CLRFMT_YUYV(clrfmt_shift);
> + if (color_convert)
> + con |= OVL_CON_MTX_YUV_TO_RGB;
> + break;
> }
> +
> + if (need_byte_swap)
> + con |= byte_swap;
> +
> + if (need_rgb_swap)
> + con |= rgb_swap;
> +
> + return con;
> }
>
^ permalink raw reply
* [PATCH 16/18] arm64: dts: ti: k3-j721e: Add overlay for DS90UB954-Q1EVM
From: Yemike Abhilash Chandra @ 2026-07-02 9:31 UTC (permalink / raw)
To: nm, vigneshr, kristo, robh, krzk+dt, conor+dt
Cc: Frank.Li, s.hauer, kernel, festevam, andersson, geert,
dmitry.baryshkov, arnd, ebiggers, luca.weiss, michal.simek, sven,
linux-arm-kernel, devicetree, linux-kernel, imx, r-donadkar,
devarsht, u-kumar1
In-Reply-To: <20260702093123.1048575-1-y-abhilashchandra@ti.com>
DS90UB954-Q1EVM consists of a DS90UB954 deserializer which aggregates
data from up to 2x cameras over the FPDLink-III interface, and can be
used to connect FPDLink-III based sensors to TI EVMs.
Add an overlay to support it on J721E-EVM.
Link: https://www.ti.com/tool/DS90UB954-Q1EVM
Signed-off-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
---
arch/arm64/boot/dts/ti/Makefile | 4 +
.../arm64/boot/dts/ti/k3-j721e-evm-ub954.dtso | 93 +++++++++++++++++++
2 files changed, 97 insertions(+)
create mode 100644 arch/arm64/boot/dts/ti/k3-j721e-evm-ub954.dtso
diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 3eb0304e89ef..386fc77e4c49 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -146,6 +146,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-gesi.dtb
dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-gesi-exp-board.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-pcie0-ep.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-pcie1-ep.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-ub954.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk.dtb
dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk-csi2-dual-imx219.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk-fpdlink-fusion.dtbo
@@ -297,6 +298,8 @@ k3-j721e-evm-pcie0-ep-dtbs := k3-j721e-common-proc-board.dtb \
k3-j721e-evm-pcie0-ep.dtbo
k3-j721e-evm-pcie1-ep-dtbs := k3-j721e-common-proc-board.dtb \
k3-j721e-evm-pcie1-ep.dtbo
+k3-j721e-evm-ub954-dtbs := k3-j721e-common-proc-board.dtb \
+ k3-j721e-evm-ub954.dtbo
k3-j721e-sk-csi2-dual-imx219-dtbs := k3-j721e-sk.dtb \
k3-j721e-sk-csi2-dual-imx219.dtbo
k3-j721e-sk-fpdlink-fusion-dtbs := k3-j721e-sk.dtb \
@@ -388,6 +391,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
k3-j721e-evm-fpdlink-fusion.dtb \
k3-j721e-evm-pcie0-ep.dtb \
k3-j721e-evm-pcie1-ep.dtb \
+ k3-j721e-evm-ub954.dtb \
k3-j721e-sk-csi2-dual-imx219.dtb \
k3-j721e-sk-fpdlink-fusion.dtb \
k3-j721e-sk-v3link-fusion.dtb \
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-evm-ub954.dtso b/arch/arm64/boot/dts/ti/k3-j721e-evm-ub954.dtso
new file mode 100644
index 000000000000..4e24ee86cddb
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j721e-evm-ub954.dtso
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for DS90UB954-Q1EVM FPDLink-III deserializer board on J721E EVM
+ * https://www.ti.com/tool/DS90UB954-Q1EVM
+ *
+ * Copyright (C) 2024-2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+ clk_fusion_25M_fixed: fixed-clock-25M {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+};
+
+
+&main_i2c6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ deser@3d {
+ compatible = "ti,ds90ub954-q1";
+ reg = <0x3d>;
+ clock-names = "refclk";
+ clocks = <&clk_fusion_25M_fixed>;
+ i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+ deserializer_0_ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0{
+ reg= <0>;
+ status = "disabled";
+ };
+
+ port@1{
+ reg= <1>;
+ status = "disabled";
+ };
+
+ /* CSI-2 TX */
+ port@2 {
+ reg = <2>;
+ ds90ub960_0_csi_out: endpoint {
+ data-lanes = <1 2 3 4>;
+ clock-lanes = <0>;
+ link-frequencies = /bits/ 64 <800000000>;
+ remote-endpoint = <&csi2_phy0>;
+ };
+ };
+ };
+
+ deserializer_0_links: links {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+&cdns_csi2rx0 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi0_port0: port@0 {
+ reg = <0>;
+ status = "okay";
+
+ csi2_phy0: endpoint {
+ remote-endpoint = <&ds90ub960_0_csi_out>;
+ data-lanes = <1 2 3 4>;
+ clock-lanes = <0>;
+ link-frequencies = /bits/ 64 <800000000>;
+ };
+ };
+ };
+};
+
+&ti_csi2rx0 {
+ status = "okay";
+};
+
+&dphy0 {
+ status = "okay";
+};
--
2.34.1
^ permalink raw reply related
* [PATCH 18/18] arm64: defconfig: Enable DS90UB960 deserializer and DS90UB953 serializer
From: Yemike Abhilash Chandra @ 2026-07-02 9:31 UTC (permalink / raw)
To: nm, vigneshr, kristo, robh, krzk+dt, conor+dt
Cc: Frank.Li, s.hauer, kernel, festevam, andersson, geert,
dmitry.baryshkov, arnd, ebiggers, luca.weiss, michal.simek, sven,
linux-arm-kernel, devicetree, linux-kernel, imx, r-donadkar,
devarsht, u-kumar1
In-Reply-To: <20260702093123.1048575-1-y-abhilashchandra@ti.com>
Enable building Texas Instruments DS90UB960 deserializer and
DS90UB953 serializer drivers as modules.
Signed-off-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
---
arch/arm64/configs/defconfig | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 207e213cc45b..bf4703160015 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -914,6 +914,8 @@ CONFIG_SDR_PLATFORM_DRIVERS=y
CONFIG_V4L_MEM2MEM_DRIVERS=y
CONFIG_VIDEO_AMPHION_VPU=m
CONFIG_VIDEO_CADENCE_CSI2RX=m
+CONFIG_VIDEO_DS90UB960=m
+CONFIG_VIDEO_DS90UB953=m
CONFIG_VIDEO_WAVE_VPU=m
CONFIG_VIDEO_E5010_JPEG_ENC=m
CONFIG_VIDEO_MEDIATEK_JPEG=m
--
2.34.1
^ permalink raw reply related
* [PATCH 17/18] arm64: dts: ti: k3-v3link: Add overlay for IMX219+UB953 serializer
From: Yemike Abhilash Chandra @ 2026-07-02 9:31 UTC (permalink / raw)
To: nm, vigneshr, kristo, robh, krzk+dt, conor+dt
Cc: Frank.Li, s.hauer, kernel, festevam, andersson, geert,
dmitry.baryshkov, arnd, ebiggers, luca.weiss, michal.simek, sven,
linux-arm-kernel, devicetree, linux-kernel, imx, r-donadkar,
devarsht, u-kumar1
In-Reply-To: <20260702093123.1048575-1-y-abhilashchandra@ti.com>
From: Jianzhong Xu <xuj@ti.com>
Arducam V3Link camera solution is shipped with an UB953 serializer
and an IMX219 sensor. [1]
Add an overlay for interfacing the UB953 serilaizer and IMX219 sensor
with the RX0 port on the UB960 deserializer. This overlay can be used to
interface an IMX219 sensor on any platform that supports the V3Link
fusion board.
[1]: https://docs.arducam.com/V3Link-Camera-Solution/V3Link-Camera-Solution-on-TI-Platform/Introduction/
Signed-off-by: Jianzhong Xu <xuj@ti.com>
Signed-off-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
---
arch/arm64/boot/dts/ti/Makefile | 31 +++--
.../boot/dts/ti/k3-v3link-imx219-0-0.dtso | 127 ++++++++++++++++++
2 files changed, 146 insertions(+), 12 deletions(-)
create mode 100644 arch/arm64/boot/dts/ti/k3-v3link-imx219-0-0.dtso
diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 386fc77e4c49..f252d402cb85 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -195,6 +195,9 @@ dtb-$(CONFIG_ARCH_K3) += k3-j784s4-j742s2-evm-usb0-type-a.dtbo
# Boards with J742S2 SoC
dtb-$(CONFIG_ARCH_K3) += k3-j742s2-evm.dtb
+# IMX219 FPDLink Sensors
+dtb-$(CONFIG_ARCH_K3) += k3-v3link-imx219-0-0.dtbo
+
# Build time test only, enabled by CONFIG_OF_ALL_DTBS
k3-am625-beagleplay-csi2-ov5640-dtbs := k3-am625-beagleplay.dtb \
k3-am625-beagleplay-csi2-ov5640.dtbo
@@ -278,16 +281,18 @@ k3-am68-sk-base-board-pcie1-ep-dtbs := k3-am68-sk-base-board.dtb \
k3-am68-sk-base-board-pcie1-ep.dtbo
k3-am68-sk-fpdlink-fusion-dtbs := k3-am68-sk-base-board.dtb \
k3-j721e-sk-fpdlink-fusion.dtbo
-k3-am68-sk-v3link-fusion-dtbs := k3-am68-sk-base-board.dtb \
- k3-am68-sk-v3link-fusion.dtbo
+k3-am68-sk-v3link-fusion-imx219-dtbs := k3-am68-sk-base-board.dtb \
+ k3-am68-sk-v3link-fusion.dtbo \
+ k3-v3link-imx219-0-0.dtbo
k3-am69-sk-csi2-dual-imx219-dtbs := k3-am69-sk.dtb \
k3-j721e-sk-csi2-dual-imx219.dtbo
k3-am69-sk-fpdlink-fusion-dtbs := k3-am69-sk.dtb \
k3-j721e-sk-fpdlink-fusion.dtbo
k3-am69-sk-pcie0-ep-dtbs := k3-am69-sk.dtb \
k3-am69-sk-pcie0-ep.dtbo
-k3-am69-sk-v3link-fusion-dtbs := k3-am69-sk.dtb \
- k3-am68-sk-v3link-fusion.dtbo
+k3-am69-sk-v3link-fusion-imx219-dtbs := k3-am69-sk.dtb \
+ k3-am68-sk-v3link-fusion.dtbo \
+ k3-v3link-imx219-0-0.dtbo
k3-j7200-evm-pcie1-ep-dtbs := k3-j7200-common-proc-board.dtb \
k3-j7200-evm-pcie1-ep.dtbo
k3-j721e-common-proc-board-infotainment-dtbs := k3-j721e-common-proc-board.dtb \
@@ -304,8 +309,9 @@ k3-j721e-sk-csi2-dual-imx219-dtbs := k3-j721e-sk.dtb \
k3-j721e-sk-csi2-dual-imx219.dtbo
k3-j721e-sk-fpdlink-fusion-dtbs := k3-j721e-sk.dtb \
k3-j721e-sk-fpdlink-fusion.dtbo
-k3-j721e-sk-v3link-fusion-dtbs := k3-j721e-sk.dtb \
- k3-am68-sk-v3link-fusion.dtbo
+k3-j721e-sk-v3link-fusion-imx219-dtbs := k3-j721e-sk.dtb \
+ k3-am68-sk-v3link-fusion.dtbo \
+ k3-v3link-imx219-0-0.dtbo
k3-j721s2-evm-fpdlink-fusion-dtbs := k3-j721s2-evm.dtb \
k3-j721s2-evm-fusion.dtbo
k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \
@@ -322,8 +328,9 @@ k3-j722s-evm-fpdlink-fusion-dtbs := k3-j722s-evm.dtb \
k3-j722s-evm-fpdlink-fusion.dtbo
k3-j722s-evm-fpdlink-iv-fusion-dtbs := k3-j722s-evm.dtb \
k3-j722s-evm-fpdlink-iv-fusion.dtbo
-k3-j722s-evm-v3link-fusion-dtbs := k3-j722s-evm.dtb \
- k3-j722s-evm-v3link-fusion.dtbo
+k3-j722s-evm-v3link-fusion-imx219-dtbs := k3-j722s-evm.dtb \
+ k3-j722s-evm-v3link-fusion.dtbo \
+ k3-v3link-imx219-0-0.dtbo
k3-j742s2-evm-usb0-type-a-dtbs := k3-j742s2-evm.dtb \
k3-j784s4-j742s2-evm-usb0-type-a.dtbo
k3-j784s4-evm-fpdlink-fusion-dtbs := k3-j784s4-evm.dtb \
@@ -381,11 +388,11 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
k3-am68-sk-base-board-csi2-dual-imx219.dtb \
k3-am68-sk-base-board-pcie1-ep.dtb \
k3-am68-sk-fpdlink-fusion.dtb \
- k3-am68-sk-v3link-fusion.dtb \
+ k3-am68-sk-v3link-fusion-imx219.dtb \
k3-am69-sk-csi2-dual-imx219.dtb \
k3-am69-sk-fpdlink-fusion.dtb \
k3-am69-sk-pcie0-ep.dtb \
- k3-am69-sk-v3link-fusion.dtb \
+ k3-am69-sk-v3link-fusion-imx219.dtb \
k3-j7200-evm-pcie1-ep.dtb \
k3-j721e-common-proc-board-infotainment.dtb \
k3-j721e-evm-fpdlink-fusion.dtb \
@@ -394,7 +401,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
k3-j721e-evm-ub954.dtb \
k3-j721e-sk-csi2-dual-imx219.dtb \
k3-j721e-sk-fpdlink-fusion.dtb \
- k3-j721e-sk-v3link-fusion.dtb \
+ k3-j721e-sk-v3link-fusion-imx219.dtb \
k3-j721s2-evm-fpdlink-fusion.dtb \
k3-j721s2-evm-pcie1-ep.dtb \
k3-j721s2-evm-ub954.dtb \
@@ -403,7 +410,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
k3-j722s-evm-csi2-quad-tevi-ov5640.dtb \
k3-j722s-evm-fpdlink-fusion.dtb \
k3-j722s-evm-fpdlink-iv-fusion.dtb \
- k3-j722s-evm-v3link-fusion.dtb \
+ k3-j722s-evm-v3link-fusion-imx219.dtb \
k3-j742s2-evm-usb0-type-a.dtb \
k3-j784s4-evm-fpdlink-fusion.dtb \
k3-j784s4-evm-fpdlink-iv-fusion.dtb \
diff --git a/arch/arm64/boot/dts/ti/k3-v3link-imx219-0-0.dtso b/arch/arm64/boot/dts/ti/k3-v3link-imx219-0-0.dtso
new file mode 100644
index 000000000000..049438f9fc89
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-v3link-imx219-0-0.dtso
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IMX219 Camera Module for V3-Link d-ch Adapter Board
+ * https://docs.arducam.com/V3Link-Camera-Solution/V3Link-Camera-Solution-on-TI-Platform/Introduction/
+ *
+ * Copyright (c) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+ clk_imx219_fixed_00: imx219-xclk-00 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ };
+
+ reg_2p8v: regulator-2p8v {
+ compatible = "regulator-fixed";
+ regulator-name = "2P8V";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ reg_1p8v: regulator-1p8v {
+ compatible = "regulator-fixed";
+ regulator-name = "1P8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ reg_1p2v: regulator-1p2v {
+ compatible = "regulator-fixed";
+ regulator-name = "1P2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+};
+
+&deserializer_0_ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* FPDLink RX 0 */
+ port@0 {
+ reg = <0>;
+
+ ub960_fpd3_1_in: endpoint {
+ remote-endpoint = <&ub953_1_out>;
+ };
+ };
+};
+
+&deserializer_0_links {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ link@0 {
+ reg = <0>;
+ i2c-alias = <0x44>;
+
+ ti,rx-mode = <3>;
+
+ serializer: serializer {
+ compatible = "ti,ds90ub953-q1";
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ #clock-cells = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ ub953_1_in: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2>;
+ remote-endpoint = <&sensor_1_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ ub953_1_out: endpoint {
+ remote-endpoint = <&ub960_fpd3_1_in>;
+ };
+ };
+ };
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sensor@10 {
+ compatible = "sony,imx219";
+ reg = <0x10>;
+
+ clocks = <&clk_imx219_fixed_00>;
+
+ VANA-supply = <®_2p8v>;
+ VDIG-supply = <®_1p8v>;
+ VDDL-supply = <®_1p2v>;
+
+ reset-gpios = <&serializer 1 GPIO_ACTIVE_HIGH>;
+
+ port {
+ sensor_1_out: endpoint {
+ remote-endpoint = <&ub953_1_in>;
+ link-frequencies = /bits/ 64 <456000000>;
+ clock-lanes = <0>;
+ data-lanes = <1 2>;
+ };
+ };
+ };
+ };
+ };
+ };
+};
--
2.34.1
^ permalink raw reply related
* [PATCH 14/18] arm64: dts: ti: k3-j722s-evm: Add overlay for J7EXPA01EVM Fusion2
From: Yemike Abhilash Chandra @ 2026-07-02 9:31 UTC (permalink / raw)
To: nm, vigneshr, kristo, robh, krzk+dt, conor+dt
Cc: Frank.Li, s.hauer, kernel, festevam, andersson, geert,
dmitry.baryshkov, arnd, ebiggers, luca.weiss, michal.simek, sven,
linux-arm-kernel, devicetree, linux-kernel, imx, r-donadkar,
devarsht, u-kumar1
In-Reply-To: <20260702093123.1048575-1-y-abhilashchandra@ti.com>
J7EXPA01EVM Fusion2 serial capture expansion board features 3 UB9702
deserializers, each capable of aggregating data from up to 4x cameras
over the FPDLink-IV interface. Add support for the same on J722S-EVM.
EVM schematics and design files : https://www.ti.com/tool/J7EXPA01EVM
Signed-off-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
---
arch/arm64/boot/dts/ti/Makefile | 4 +
.../ti/k3-j722s-evm-fpdlink-iv-fusion.dtso | 296 ++++++++++++++++++
2 files changed, 300 insertions(+)
create mode 100644 arch/arm64/boot/dts/ti/k3-j722s-evm-fpdlink-iv-fusion.dtso
diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 7da84197402e..0246f582ca00 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -175,6 +175,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm.dtb
dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-csi2-quad-rpi-cam-imx219.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-csi2-quad-tevi-ov5640.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-fpdlink-fusion.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-fpdlink-iv-fusion.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-v3link-fusion.dtbo
# Boards with J784s4 SoC
@@ -313,6 +314,8 @@ k3-j722s-evm-csi2-quad-tevi-ov5640-dtbs := k3-j722s-evm.dtb \
k3-j722s-evm-csi2-quad-tevi-ov5640.dtbo
k3-j722s-evm-fpdlink-fusion-dtbs := k3-j722s-evm.dtb \
k3-j722s-evm-fpdlink-fusion.dtbo
+k3-j722s-evm-fpdlink-iv-fusion-dtbs := k3-j722s-evm.dtb \
+ k3-j722s-evm-fpdlink-iv-fusion.dtbo
k3-j722s-evm-v3link-fusion-dtbs := k3-j722s-evm.dtb \
k3-j722s-evm-v3link-fusion.dtbo
k3-j742s2-evm-usb0-type-a-dtbs := k3-j742s2-evm.dtb \
@@ -391,6 +394,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
k3-j722s-evm-csi2-quad-rpi-cam-imx219.dtb \
k3-j722s-evm-csi2-quad-tevi-ov5640.dtb \
k3-j722s-evm-fpdlink-fusion.dtb \
+ k3-j722s-evm-fpdlink-iv-fusion.dtb \
k3-j722s-evm-v3link-fusion.dtb \
k3-j742s2-evm-usb0-type-a.dtb \
k3-j784s4-evm-fpdlink-fusion.dtb \
diff --git a/arch/arm64/boot/dts/ti/k3-j722s-evm-fpdlink-iv-fusion.dtso b/arch/arm64/boot/dts/ti/k3-j722s-evm-fpdlink-iv-fusion.dtso
new file mode 100644
index 000000000000..91bf23345b92
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j722s-evm-fpdlink-iv-fusion.dtso
@@ -0,0 +1,296 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for FPDLink IV UB9702 Deserializer on J722S
+ * https://www.ti.com/tool/J7EXPA01EVM
+ *
+ * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+ clk_fusion_25M_fixed: fixed-clock-25M {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+};
+
+&main_pmx0 {
+ csi_expansion_interface_reset: csi-expansion-interface-reset-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x114, PIN_OUTPUT, 7) /* (G26) GPIO0_68 */
+ >;
+ };
+};
+
+&main_gpio0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&csi_expansion_interface_reset>;
+
+ line68-hog{
+ gpio-hog;
+ gpios = <68 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "CSI2_EXP_RSTZ";
+ };
+};
+
+&pca9543_0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ deser@3d {
+ compatible = "ti,ds90ub9702-q1";
+ reg = <0x3d>;
+ clocks = <&clk_fusion_25M_fixed>;
+ clock-names = "refclk";
+ i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+ deserializer_0_ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0{
+ reg= <0>;
+ status = "disabled";
+ };
+
+ port@1{
+ reg= <1>;
+ status = "disabled";
+ };
+
+ port@2{
+ reg= <2>;
+ status = "disabled";
+ };
+
+ port@3{
+ reg= <3>;
+ status = "disabled";
+ };
+
+ /* CSI-2 TX */
+ port@4 {
+ reg = <4>;
+ ds90ub970_0_csi_out: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ remote-endpoint = <&csi2_phy0>;
+ };
+ };
+
+ port@5{
+ reg= <5>;
+ status = "disabled";
+ };
+ };
+
+ deserializer_0_links: links {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ deser@30 {
+ compatible = "ti,ds90ub9702-q1";
+ reg = <0x30>;
+ clocks = <&clk_fusion_25M_fixed>;
+ clock-names = "refclk";
+ i2c-alias-pool = <0x5a 0x5b 0x5c 0x5d 0x5e 0x5f>;
+
+ deserializer_1_ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0{
+ reg= <0>;
+ status = "disabled";
+ };
+
+ port@1{
+ reg= <1>;
+ status = "disabled";
+ };
+
+ port@2{
+ reg= <2>;
+ status = "disabled";
+ };
+
+ port@3{
+ reg= <3>;
+ status = "disabled";
+ };
+
+ /* CSI-2 TX */
+ port@4 {
+ reg = <4>;
+ ds90ub970_1_csi_out: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ remote-endpoint = <&csi2_phy1>;
+ };
+ };
+
+ port@5{
+ reg= <5>;
+ status = "disabled";
+ };
+ };
+
+ deserializer_1_links: links {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ deser@32 {
+ compatible = "ti,ds90ub9702-q1";
+ reg = <0x32>;
+ clocks = <&clk_fusion_25M_fixed>;
+ clock-names = "refclk";
+ i2c-alias-pool = <0x6a 0x6b 0x6c 0x6d 0x6e 0x6f>;
+
+ deserializer_2_ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0{
+ reg= <0>;
+ status = "disabled";
+ };
+
+ port@1{
+ reg= <1>;
+ status = "disabled";
+ };
+
+ port@2{
+ reg= <2>;
+ status = "disabled";
+ };
+
+ port@3{
+ reg= <3>;
+ status = "disabled";
+ };
+
+ /* CSI-2 TX */
+ port@4 {
+ reg = <4>;
+ ds90ub970_2_csi_out: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ remote-endpoint = <&csi2_phy2>;
+ };
+ };
+
+ port@5{
+ reg= <5>;
+ status = "disabled";
+ };
+ };
+
+ deserializer_2_links: links {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+};
+
+&cdns_csi2rx0 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi0_port0: port@0 {
+ reg = <0>;
+ status = "okay";
+
+ csi2_phy0: endpoint {
+ remote-endpoint = <&ds90ub970_0_csi_out>;
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ };
+ };
+ };
+};
+
+&cdns_csi2rx1 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi1_port0: port@0 {
+ reg = <0>;
+ status = "okay";
+
+ csi2_phy1: endpoint {
+ remote-endpoint = <&ds90ub970_1_csi_out>;
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ };
+ };
+ };
+};
+
+&cdns_csi2rx2 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi2_port0: port@0 {
+ reg = <0>;
+ status = "okay";
+
+ csi2_phy2: endpoint {
+ remote-endpoint = <&ds90ub970_2_csi_out>;
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ };
+ };
+ };
+};
+
+&ti_csi2rx0 {
+ status = "okay";
+};
+
+&dphy0 {
+ status = "okay";
+};
+
+&ti_csi2rx1 {
+ status = "okay";
+};
+
+&dphy1 {
+ status = "okay";
+};
+
+&ti_csi2rx2 {
+ status = "okay";
+};
+
+&dphy2 {
+ status = "okay";
+};
--
2.34.1
^ permalink raw reply related
* [PATCH 15/18] arm64: dts: ti: k3-j721s2: Add overlay for DS90UB954-Q1EVM
From: Yemike Abhilash Chandra @ 2026-07-02 9:31 UTC (permalink / raw)
To: nm, vigneshr, kristo, robh, krzk+dt, conor+dt
Cc: Frank.Li, s.hauer, kernel, festevam, andersson, geert,
dmitry.baryshkov, arnd, ebiggers, luca.weiss, michal.simek, sven,
linux-arm-kernel, devicetree, linux-kernel, imx, r-donadkar,
devarsht, u-kumar1
In-Reply-To: <20260702093123.1048575-1-y-abhilashchandra@ti.com>
DS90UB954-Q1EVM consists of a DS90UB954 deserializer which aggregates
data from up to 2x cameras over the FPDLink-III interface, and can be
used to connect FPDLink-III based sensors to TI EVMs.
Add an overlay to support it on J721S2-EVM.
Link: https://www.ti.com/tool/DS90UB954-Q1EVM
Signed-off-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
---
arch/arm64/boot/dts/ti/Makefile | 4 +
.../boot/dts/ti/k3-j721s2-evm-ub954.dtso | 93 +++++++++++++++++++
2 files changed, 97 insertions(+)
create mode 100644 arch/arm64/boot/dts/ti/k3-j721s2-evm-ub954.dtso
diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 0246f582ca00..3eb0304e89ef 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -167,6 +167,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-gesi-exp-board.dtbo
k3-j721s2-evm-dtbs := k3-j721s2-common-proc-board.dtb k3-j721s2-evm-gesi-exp-board.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm.dtb
dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-pcie1-ep.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-ub954.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-usb0-type-a.dtbo
# Boards with J722s SoC
@@ -306,6 +307,8 @@ k3-j721s2-evm-fpdlink-fusion-dtbs := k3-j721s2-evm.dtb \
k3-j721s2-evm-fusion.dtbo
k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \
k3-j721s2-evm-pcie1-ep.dtbo
+k3-j721s2-evm-ub954-dtbs := k3-j721s2-evm.dtb \
+ k3-j721s2-evm-ub954.dtbo
k3-j721s2-evm-usb0-type-a-dtbs := k3-j721s2-common-proc-board.dtb \
k3-j721s2-evm-usb0-type-a.dtbo
k3-j722s-evm-csi2-quad-rpi-cam-imx219-dtbs := k3-j722s-evm.dtb \
@@ -390,6 +393,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
k3-j721e-sk-v3link-fusion.dtb \
k3-j721s2-evm-fpdlink-fusion.dtb \
k3-j721s2-evm-pcie1-ep.dtb \
+ k3-j721s2-evm-ub954.dtb \
k3-j721s2-evm-usb0-type-a.dtb \
k3-j722s-evm-csi2-quad-rpi-cam-imx219.dtb \
k3-j722s-evm-csi2-quad-tevi-ov5640.dtb \
diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-evm-ub954.dtso b/arch/arm64/boot/dts/ti/k3-j721s2-evm-ub954.dtso
new file mode 100644
index 000000000000..6b058da0ad4b
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-evm-ub954.dtso
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for DS90UB954-Q1EVM FPDLink-III deserializer board on J721S2 and J784S4 EVM
+ * https://www.ti.com/tool/DS90UB954-Q1EVM
+ *
+ * Copyright (C) 2024-2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+ clk_fusion_25M_fixed: fixed-clock-25M {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+};
+
+
+&main_i2c5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ deser@3d {
+ compatible = "ti,ds90ub954-q1";
+ reg = <0x3d>;
+ clock-names = "refclk";
+ clocks = <&clk_fusion_25M_fixed>;
+ i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+ deserializer_0_ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0{
+ reg= <0>;
+ status = "disabled";
+ };
+
+ port@1{
+ reg= <1>;
+ status = "disabled";
+ };
+
+ /* CSI-2 TX */
+ port@2 {
+ reg = <2>;
+ ds90ub960_0_csi_out: endpoint {
+ data-lanes = <1 2 3 4>;
+ clock-lanes = <0>;
+ link-frequencies = /bits/ 64 <800000000>;
+ remote-endpoint = <&csi2_phy0>;
+ };
+ };
+ };
+
+ deserializer_0_links: links {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+&cdns_csi2rx0 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi0_port0: port@0 {
+ reg = <0>;
+ status = "okay";
+
+ csi2_phy0: endpoint {
+ remote-endpoint = <&ds90ub960_0_csi_out>;
+ data-lanes = <1 2 3 4>;
+ clock-lanes = <0>;
+ link-frequencies = /bits/ 64 <800000000>;
+ };
+ };
+ };
+};
+
+&ti_csi2rx0 {
+ status = "okay";
+};
+
+&dphy0 {
+ status = "okay";
+};
--
2.34.1
^ permalink raw reply related
* [PATCH 12/18] arm64: dts: ti: k3-j722s-evm: Add overlay for dual Arducam V3link fusion
From: Yemike Abhilash Chandra @ 2026-07-02 9:31 UTC (permalink / raw)
To: nm, vigneshr, kristo, robh, krzk+dt, conor+dt
Cc: Frank.Li, s.hauer, kernel, festevam, andersson, geert,
dmitry.baryshkov, arnd, ebiggers, luca.weiss, michal.simek, sven,
linux-arm-kernel, devicetree, linux-kernel, imx, r-donadkar,
devarsht, u-kumar1
In-Reply-To: <20260702093123.1048575-1-y-abhilashchandra@ti.com>
From: Vaishnav Achath <vaishnav.a@ti.com>
Arducam's V3Link mini fusion board [1] has a single DS90UB960
deserializer which can aggregate input from up to 4x V3Link (and
FPD-Link III) based cameras over a single 22-pin FFC (4-lane) CSI-2
connector. Add an overlay supporting two such boards, each connected to
one of the two CSI RX inputs on J722S.
[1] https://www.arducam.com/downloads/datasheet/Arducam_V3Link_Datasheet.pdf
Signed-off-by: Vaishnav Achath <vaishnav.a@ti.com>
Signed-off-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
---
arch/arm64/boot/dts/ti/Makefile | 4 +
.../dts/ti/k3-j722s-evm-v3link-fusion.dtso | 213 ++++++++++++++++++
2 files changed, 217 insertions(+)
create mode 100644 arch/arm64/boot/dts/ti/k3-j722s-evm-v3link-fusion.dtso
diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index b14c9a8c94b9..0741f9c16034 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -175,6 +175,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm.dtb
dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-csi2-quad-rpi-cam-imx219.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-csi2-quad-tevi-ov5640.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-fpdlink-fusion.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-v3link-fusion.dtbo
# Boards with J784s4 SoC
dtb-$(CONFIG_ARCH_K3) += k3-am69-aquila-clover.dtb
@@ -311,6 +312,8 @@ k3-j722s-evm-csi2-quad-tevi-ov5640-dtbs := k3-j722s-evm.dtb \
k3-j722s-evm-csi2-quad-tevi-ov5640.dtbo
k3-j722s-evm-fpdlink-fusion-dtbs := k3-j722s-evm.dtb \
k3-j722s-evm-fpdlink-fusion.dtbo
+k3-j722s-evm-v3link-fusion-dtbs := k3-j722s-evm.dtb \
+ k3-j722s-evm-v3link-fusion.dtbo
k3-j742s2-evm-usb0-type-a-dtbs := k3-j742s2-evm.dtb \
k3-j784s4-j742s2-evm-usb0-type-a.dtbo
k3-j784s4-evm-fpdlink-fusion-dtbs := k3-j784s4-evm.dtb \
@@ -385,6 +388,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
k3-j722s-evm-csi2-quad-rpi-cam-imx219.dtb \
k3-j722s-evm-csi2-quad-tevi-ov5640.dtb \
k3-j722s-evm-fpdlink-fusion.dtb \
+ k3-j722s-evm-v3link-fusion.dtb \
k3-j742s2-evm-usb0-type-a.dtb \
k3-j784s4-evm-fpdlink-fusion.dtb \
k3-j784s4-evm-pcie0-pcie1-ep.dtb \
diff --git a/arch/arm64/boot/dts/ti/k3-j722s-evm-v3link-fusion.dtso b/arch/arm64/boot/dts/ti/k3-j722s-evm-v3link-fusion.dtso
new file mode 100644
index 000000000000..c5baf35c0ac6
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j722s-evm-v3link-fusion.dtso
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for Arducam V3Link UC-A09 board
+ * https://www.arducam.com/fpd-link-3-cameras/
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+ clk_fusion_25M_fixed: fixed-clock-25M {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+};
+
+&csi01_mux {
+ idle-state = <1>;
+};
+
+&csi23_mux {
+ idle-state = <1>;
+};
+
+&pca9543_0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* CAM0 I2C */
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ deser@30 {
+ compatible = "ti,ds90ub960-q1";
+ reg = <0x30>;
+
+ clock-names = "refclk";
+ clocks = <&clk_fusion_25M_fixed>;
+
+ i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+ deserializer_0_ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0{
+ reg= <0>;
+ status = "disabled";
+ };
+
+ port@1{
+ reg= <1>;
+ status = "disabled";
+ };
+
+ port@2{
+ reg= <2>;
+ status = "disabled";
+ };
+
+ port@3{
+ reg= <3>;
+ status = "disabled";
+ };
+
+ /* CSI-2 TX */
+ port@4 {
+ reg = <4>;
+ ds90ub960_0_csi_out: endpoint {
+ data-lanes = <1 2 3 4>;
+ clock-lanes = <0>;
+ link-frequencies = /bits/ 64 <800000000>;
+ remote-endpoint = <&csi2_phy0>;
+ };
+ };
+
+ port@5{
+ reg= <5>;
+ status = "disabled";
+ };
+ };
+
+ deserializer_0_links: links {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+
+ /* CAM1 I2C */
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ deser@30 {
+ compatible = "ti,ds90ub960-q1";
+ reg = <0x30>;
+
+ clock-names = "refclk";
+ clocks = <&clk_fusion_25M_fixed>;
+
+ i2c-alias-pool = <0x5a 0x5b 0x5c 0x5d 0x5e 0x5f>;
+
+ deserializer_1_ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0{
+ reg= <0>;
+ status = "disabled";
+ };
+
+ port@1{
+ reg= <1>;
+ status = "disabled";
+ };
+
+ port@2{
+ reg= <2>;
+ status = "disabled";
+ };
+
+ port@3{
+ reg= <3>;
+ status = "disabled";
+ };
+
+ /* CSI-2 TX */
+ port@4 {
+ reg = <4>;
+ ds90ub960_1_csi_out: endpoint {
+ data-lanes = <1 2 3 4>;
+ clock-lanes = <0>;
+ link-frequencies = /bits/ 64 <800000000>;
+ remote-endpoint = <&csi2_phy1>;
+ };
+ };
+
+ port@5{
+ reg= <5>;
+ status = "disabled";
+ };
+ };
+
+ deserializer_1_links: links {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+};
+
+&cdns_csi2rx0 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi0_port0: port@0 {
+ reg = <0>;
+ status = "okay";
+
+ csi2_phy0: endpoint {
+ remote-endpoint = <&ds90ub960_0_csi_out>;
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ };
+ };
+ };
+};
+
+&cdns_csi2rx1 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi1_port0: port@0 {
+ reg = <0>;
+ status = "okay";
+
+ csi2_phy1: endpoint {
+ remote-endpoint = <&ds90ub960_1_csi_out>;
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ };
+ };
+ };
+};
+
+&ti_csi2rx0 {
+ status = "okay";
+};
+
+&dphy0 {
+ status = "okay";
+};
+
+&ti_csi2rx1 {
+ status = "okay";
+};
+
+&dphy1 {
+ status = "okay";
+};
--
2.34.1
^ permalink raw reply related
* [PATCH 13/18] arm64: dts: ti: k3-j784s4-evm: Add overlay for J7EXPA01EVM Fusion2
From: Yemike Abhilash Chandra @ 2026-07-02 9:31 UTC (permalink / raw)
To: nm, vigneshr, kristo, robh, krzk+dt, conor+dt
Cc: Frank.Li, s.hauer, kernel, festevam, andersson, geert,
dmitry.baryshkov, arnd, ebiggers, luca.weiss, michal.simek, sven,
linux-arm-kernel, devicetree, linux-kernel, imx, r-donadkar,
devarsht, u-kumar1
In-Reply-To: <20260702093123.1048575-1-y-abhilashchandra@ti.com>
From: Vaishnav Achath <vaishnav.a@ti.com>
J7EXPA01EVM Fusion2 serial capture expansion board features 3 UB9702
deserializers, each capable of aggregating data from up to 4x cameras
over the FPDLink-IV interface. Add support for the same on J784S4-EVM.
EVM schematics and design files : https://www.ti.com/tool/J7EXPA01EVM
Signed-off-by: Vaishnav Achath <vaishnav.a@ti.com>
Signed-off-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
---
arch/arm64/boot/dts/ti/Makefile | 4 +
.../ti/k3-j784s4-evm-fpdlink-iv-fusion.dtso | 281 ++++++++++++++++++
2 files changed, 285 insertions(+)
create mode 100644 arch/arm64/boot/dts/ti/k3-j784s4-evm-fpdlink-iv-fusion.dtso
diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 0741f9c16034..7da84197402e 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -183,6 +183,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am69-aquila-dev.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am69-sk.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am69-sk-pcie0-ep.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm-fpdlink-iv-fusion.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm-pcie0-pcie1-ep.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm-quad-port-eth-exp1.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm-usxgmii-exp1-exp2.dtbo
@@ -318,6 +319,8 @@ k3-j742s2-evm-usb0-type-a-dtbs := k3-j742s2-evm.dtb \
k3-j784s4-j742s2-evm-usb0-type-a.dtbo
k3-j784s4-evm-fpdlink-fusion-dtbs := k3-j784s4-evm.dtb \
k3-j721s2-evm-fusion.dtbo
+k3-j784s4-evm-fpdlink-iv-fusion-dtbs := k3-j784s4-evm.dtb \
+ k3-j784s4-evm-fpdlink-iv-fusion.dtbo
k3-j784s4-evm-pcie0-pcie1-ep-dtbs := k3-j784s4-evm.dtb \
k3-j784s4-evm-pcie0-pcie1-ep.dtbo
k3-j784s4-evm-quad-port-eth-exp1-dtbs := k3-j784s4-evm.dtb \
@@ -391,6 +394,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
k3-j722s-evm-v3link-fusion.dtb \
k3-j742s2-evm-usb0-type-a.dtb \
k3-j784s4-evm-fpdlink-fusion.dtb \
+ k3-j784s4-evm-fpdlink-iv-fusion.dtb \
k3-j784s4-evm-pcie0-pcie1-ep.dtb \
k3-j784s4-evm-quad-port-eth-exp1.dtb \
k3-j784s4-evm-usb0-type-a.dtb \
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm-fpdlink-iv-fusion.dtso b/arch/arm64/boot/dts/ti/k3-j784s4-evm-fpdlink-iv-fusion.dtso
new file mode 100644
index 000000000000..9f4479a03856
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm-fpdlink-iv-fusion.dtso
@@ -0,0 +1,281 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * DT Overlay for FPDLink IV UB9702 Deserializer on J784S4 EVM
+ * https://www.ti.com/tool/J7EXPA01EVM
+ *
+ * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+ clk_fusion_25M_fixed: fixed-clock-25M {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+};
+
+&exp5 {
+ p0-hog{
+ gpio-hog;
+ gpios = <0 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "CSI2_EXP_RSTZ";
+ };
+};
+
+&main_i2c5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ deser@3d {
+ compatible = "ti,ds90ub9702-q1";
+ reg = <0x3d>;
+ clocks = <&clk_fusion_25M_fixed>;
+ clock-names = "refclk";
+ i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+ deserializer_0_ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0{
+ reg= <0>;
+ status = "disabled";
+ };
+
+ port@1{
+ reg= <1>;
+ status = "disabled";
+ };
+
+ port@2{
+ reg= <2>;
+ status = "disabled";
+ };
+
+ port@3{
+ reg= <3>;
+ status = "disabled";
+ };
+
+ /* CSI-2 TX */
+ port@4 {
+ reg = <4>;
+ ds90ub970_0_csi_out: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ remote-endpoint = <&csi2_phy0>;
+ };
+ };
+
+ port@5{
+ reg= <5>;
+ status = "disabled";
+ };
+ };
+
+ deserializer_0_links: links {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ deser@30 {
+ compatible = "ti,ds90ub9702-q1";
+ reg = <0x30>;
+ clocks = <&clk_fusion_25M_fixed>;
+ clock-names = "refclk";
+ i2c-alias-pool = <0x5a 0x5b 0x5c 0x5d 0x5e 0x5f>;
+
+ deserializer_1_ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0{
+ reg= <0>;
+ status = "disabled";
+ };
+
+ port@1{
+ reg= <1>;
+ status = "disabled";
+ };
+
+ port@2{
+ reg= <2>;
+ status = "disabled";
+ };
+
+ port@3{
+ reg= <3>;
+ status = "disabled";
+ };
+
+ /* CSI-2 TX */
+ port@4 {
+ reg = <4>;
+ ds90ub970_1_csi_out: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ remote-endpoint = <&csi2_phy1>;
+ };
+ };
+
+ port@5{
+ reg= <5>;
+ status = "disabled";
+ };
+ };
+
+ deserializer_1_links: links {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ deser@32 {
+ compatible = "ti,ds90ub9702-q1";
+ reg = <0x32>;
+ clocks = <&clk_fusion_25M_fixed>;
+ clock-names = "refclk";
+ i2c-alias-pool = <0x6a 0x6b 0x6c 0x6d 0x6e 0x6f>;
+
+ deserializer_2_ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0{
+ reg= <0>;
+ status = "disabled";
+ };
+
+ port@1{
+ reg= <1>;
+ status = "disabled";
+ };
+
+ port@2{
+ reg= <2>;
+ status = "disabled";
+ };
+
+ port@3{
+ reg= <3>;
+ status = "disabled";
+ };
+
+ /* CSI-2 TX */
+ port@4 {
+ reg = <4>;
+ ds90ub970_2_csi_out: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ remote-endpoint = <&csi2_phy2>;
+ };
+ };
+
+ port@5{
+ reg= <5>;
+ status = "disabled";
+ };
+ };
+
+ deserializer_2_links: links {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+&cdns_csi2rx0 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi0_port0: port@0 {
+ reg = <0>;
+ status = "okay";
+
+ csi2_phy0: endpoint {
+ remote-endpoint = <&ds90ub970_0_csi_out>;
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+
+ };
+ };
+ };
+};
+
+&cdns_csi2rx1 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi1_port0: port@0 {
+ reg = <0>;
+ status = "okay";
+
+ csi2_phy1: endpoint {
+ remote-endpoint = <&ds90ub970_1_csi_out>;
+ bus-type = <4>; /* CSI2 DPHY */
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ };
+ };
+ };
+};
+
+&cdns_csi2rx2 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi2_port0: port@0 {
+ reg = <0>;
+ status = "okay";
+
+ csi2_phy2: endpoint {
+ remote-endpoint = <&ds90ub970_2_csi_out>;
+ bus-type = <4>; /* CSI2 DPHY */
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ };
+ };
+ };
+};
+
+&ti_csi2rx0 {
+ status = "okay";
+};
+
+&ti_csi2rx1 {
+ status = "okay";
+};
+
+&ti_csi2rx2 {
+ status = "okay";
+};
+
+&dphy0 {
+ status = "okay";
+};
+
+&dphy1 {
+ status = "okay";
+};
+
+&dphy2 {
+ status = "okay";
+};
--
2.34.1
^ permalink raw reply related
* [PATCH 10/18] arm64: dts: ti: k3-j722s-evm: Add overlay for fusion application daughter board
From: Yemike Abhilash Chandra @ 2026-07-02 9:31 UTC (permalink / raw)
To: nm, vigneshr, kristo, robh, krzk+dt, conor+dt
Cc: Frank.Li, s.hauer, kernel, festevam, andersson, geert,
dmitry.baryshkov, arnd, ebiggers, luca.weiss, michal.simek, sven,
linux-arm-kernel, devicetree, linux-kernel, imx, r-donadkar,
devarsht, u-kumar1
In-Reply-To: <20260702093123.1048575-1-y-abhilashchandra@ti.com>
From: Vaishnav Achath <vaishnav.a@ti.com>
Fusion application daughter board [1] can be used to connect multiple
FPDLink-III based sensors to TI EVMs. The board has two DS90UB960
deserializers, each of which aggregates input from up to 4x FPDLink-III
sensors. Up to 8x sensors can simultaneously stream over the two CSI RX
ports on J722S EVM.
[1]: https://svtronics.com/product/fusion-application-daughter-board-evm577pfusion-v1-0/?srsltid=AfmBOooMsRAd5ibFOGJaKbjsC3j9-loTPK2wWqsqPq2Adj55g1nPluxX
Signed-off-by: Vaishnav Achath <vaishnav.a@ti.com>
Signed-off-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
---
arch/arm64/boot/dts/ti/Makefile | 4 +
.../dts/ti/k3-j722s-evm-fpdlink-fusion.dtso | 196 ++++++++++++++++++
2 files changed, 200 insertions(+)
create mode 100644 arch/arm64/boot/dts/ti/k3-j722s-evm-fpdlink-fusion.dtso
diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index b31bf2f305aa..cb16eb9039aa 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -173,6 +173,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai.dtb
dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm.dtb
dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-csi2-quad-rpi-cam-imx219.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-csi2-quad-tevi-ov5640.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm-fpdlink-fusion.dtbo
# Boards with J784s4 SoC
dtb-$(CONFIG_ARCH_K3) += k3-am69-aquila-clover.dtb
@@ -301,6 +302,8 @@ k3-j722s-evm-csi2-quad-rpi-cam-imx219-dtbs := k3-j722s-evm.dtb \
k3-j722s-evm-csi2-quad-rpi-cam-imx219.dtbo
k3-j722s-evm-csi2-quad-tevi-ov5640-dtbs := k3-j722s-evm.dtb \
k3-j722s-evm-csi2-quad-tevi-ov5640.dtbo
+k3-j722s-evm-fpdlink-fusion-dtbs := k3-j722s-evm.dtb \
+ k3-j722s-evm-fpdlink-fusion.dtbo
k3-j742s2-evm-usb0-type-a-dtbs := k3-j742s2-evm.dtb \
k3-j784s4-j742s2-evm-usb0-type-a.dtbo
k3-j784s4-evm-fpdlink-fusion-dtbs := k3-j784s4-evm.dtb \
@@ -371,6 +374,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
k3-j721s2-evm-usb0-type-a.dtb \
k3-j722s-evm-csi2-quad-rpi-cam-imx219.dtb \
k3-j722s-evm-csi2-quad-tevi-ov5640.dtb \
+ k3-j722s-evm-fpdlink-fusion.dtb \
k3-j742s2-evm-usb0-type-a.dtb \
k3-j784s4-evm-fpdlink-fusion.dtb \
k3-j784s4-evm-pcie0-pcie1-ep.dtb \
diff --git a/arch/arm64/boot/dts/ti/k3-j722s-evm-fpdlink-fusion.dtso b/arch/arm64/boot/dts/ti/k3-j722s-evm-fpdlink-fusion.dtso
new file mode 100644
index 000000000000..cbad2409a9c1
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j722s-evm-fpdlink-fusion.dtso
@@ -0,0 +1,196 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for Fusion (FPD-Link III) board on J721E EVM
+ * https://svtronics.com/portfolio/evm577pfusion-v1-0-fusion/
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+ clk_fusion_25M_fixed: fixed-clock-25M {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+};
+
+
+&pca9543_0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ deser@3d {
+ compatible = "ti,ds90ub960-q1";
+ reg = <0x3d>;
+ clocks = <&clk_fusion_25M_fixed>;
+ clock-names = "refclk";
+ i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+ ds90ub960_0_ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0{
+ reg= <0>;
+ status = "disabled";
+ };
+
+ port@1{
+ reg= <1>;
+ status = "disabled";
+ };
+
+ port@2{
+ reg= <2>;
+ status = "disabled";
+ };
+
+ port@3{
+ reg= <3>;
+ status = "disabled";
+ };
+
+ /* CSI-2 TX */
+ port@4 {
+ reg = <4>;
+ ds90ub960_0_csi_out: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ remote-endpoint = <&csi2_phy0>;
+ };
+ };
+
+ port@5{
+ reg= <5>;
+ status = "disabled";
+ };
+ };
+
+ ds90ub960_0_links: links {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ deser@36 {
+ compatible = "ti,ds90ub960-q1";
+ reg = <0x36>;
+ clocks = <&clk_fusion_25M_fixed>;
+ clock-names = "refclk";
+ i2c-alias-pool = <0x5a 0x5b 0x5c 0x5d 0x5e 0x5f>;
+
+ ds90ub960_1_ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0{
+ reg= <0>;
+ status = "disabled";
+ };
+
+ port@1{
+ reg= <1>;
+ status = "disabled";
+ };
+
+ port@2{
+ reg= <2>;
+ status = "disabled";
+ };
+
+ port@3{
+ reg= <3>;
+ status = "disabled";
+ };
+
+ /* CSI-2 TX */
+ port@4 {
+ reg = <4>;
+ ds90ub960_1_csi_out: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ remote-endpoint = <&csi2_phy1>;
+ };
+ };
+
+ port@5{
+ reg= <5>;
+ status = "disabled";
+ };
+ };
+
+ ds90ub960_1_links: links {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ };
+};
+
+&cdns_csi2rx0 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi0_port0: port@0 {
+ reg = <0>;
+ status = "okay";
+
+ csi2_phy0: endpoint {
+ remote-endpoint = <&ds90ub960_0_csi_out>;
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ };
+ };
+ };
+};
+
+&cdns_csi2rx1 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi1_port0: port@0 {
+ reg = <0>;
+ status = "okay";
+
+ csi2_phy1: endpoint {
+ remote-endpoint = <&ds90ub960_1_csi_out>;
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ };
+ };
+ };
+};
+
+&ti_csi2rx0 {
+ status = "okay";
+};
+
+&dphy0 {
+ status = "okay";
+};
+
+&ti_csi2rx1 {
+ status = "okay";
+};
+
+&dphy1 {
+ status = "okay";
+};
--
2.34.1
^ permalink raw reply related
* [PATCH 11/18] arm64: dts: ti: k3-am68-sk: Add overlay for dual Arducam V3link fusion
From: Yemike Abhilash Chandra @ 2026-07-02 9:31 UTC (permalink / raw)
To: nm, vigneshr, kristo, robh, krzk+dt, conor+dt
Cc: Frank.Li, s.hauer, kernel, festevam, andersson, geert,
dmitry.baryshkov, arnd, ebiggers, luca.weiss, michal.simek, sven,
linux-arm-kernel, devicetree, linux-kernel, imx, r-donadkar,
devarsht, u-kumar1
In-Reply-To: <20260702093123.1048575-1-y-abhilashchandra@ti.com>
From: Vaishnav Achath <vaishnav.a@ti.com>
Arducam's V3Link mini fusion board [1] has a single DS90UB960
deserializer which can aggregate input from up to 4x V3Link (and
FPD-Link III) based cameras over a single 22-pin FFC (4-lane) CSI-2
connector. Add an overlay supporting two such boards, each connected to
one of the two CSI RX inputs on AM68-SK.
The same overlay can be reused on AM69-SK and J721E-SK.
[1] https://www.arducam.com/downloads/datasheet/Arducam_V3Link_Datasheet.pdf
Signed-off-by: Vaishnav Achath <vaishnav.a@ti.com>
Signed-off-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
---
arch/arm64/boot/dts/ti/Makefile | 10 +
.../boot/dts/ti/k3-am68-sk-v3link-fusion.dtso | 204 ++++++++++++++++++
2 files changed, 214 insertions(+)
create mode 100644 arch/arm64/boot/dts/ti/k3-am68-sk-v3link-fusion.dtso
diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index cb16eb9039aa..b14c9a8c94b9 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -160,6 +160,7 @@ k3-am68-phyboard-izar-peb-av-15-dtbs := k3-am68-phyboard-izar.dtb \
k3-am68-phyboard-izar-peb-av-15.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-am68-sk-base-board.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am68-sk-base-board-pcie1-ep.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am68-sk-v3link-fusion.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j721s2-common-proc-board.dtb
dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-fusion.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-gesi-exp-board.dtbo
@@ -272,12 +273,16 @@ k3-am68-sk-base-board-pcie1-ep-dtbs := k3-am68-sk-base-board.dtb \
k3-am68-sk-base-board-pcie1-ep.dtbo
k3-am68-sk-fpdlink-fusion-dtbs := k3-am68-sk-base-board.dtb \
k3-j721e-sk-fpdlink-fusion.dtbo
+k3-am68-sk-v3link-fusion-dtbs := k3-am68-sk-base-board.dtb \
+ k3-am68-sk-v3link-fusion.dtbo
k3-am69-sk-csi2-dual-imx219-dtbs := k3-am69-sk.dtb \
k3-j721e-sk-csi2-dual-imx219.dtbo
k3-am69-sk-fpdlink-fusion-dtbs := k3-am69-sk.dtb \
k3-j721e-sk-fpdlink-fusion.dtbo
k3-am69-sk-pcie0-ep-dtbs := k3-am69-sk.dtb \
k3-am69-sk-pcie0-ep.dtbo
+k3-am69-sk-v3link-fusion-dtbs := k3-am69-sk.dtb \
+ k3-am68-sk-v3link-fusion.dtbo
k3-j7200-evm-pcie1-ep-dtbs := k3-j7200-common-proc-board.dtb \
k3-j7200-evm-pcie1-ep.dtbo
k3-j721e-common-proc-board-infotainment-dtbs := k3-j721e-common-proc-board.dtb \
@@ -292,6 +297,8 @@ k3-j721e-sk-csi2-dual-imx219-dtbs := k3-j721e-sk.dtb \
k3-j721e-sk-csi2-dual-imx219.dtbo
k3-j721e-sk-fpdlink-fusion-dtbs := k3-j721e-sk.dtb \
k3-j721e-sk-fpdlink-fusion.dtbo
+k3-j721e-sk-v3link-fusion-dtbs := k3-j721e-sk.dtb \
+ k3-am68-sk-v3link-fusion.dtbo
k3-j721s2-evm-fpdlink-fusion-dtbs := k3-j721s2-evm.dtb \
k3-j721s2-evm-fusion.dtbo
k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \
@@ -359,9 +366,11 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
k3-am68-sk-base-board-csi2-dual-imx219.dtb \
k3-am68-sk-base-board-pcie1-ep.dtb \
k3-am68-sk-fpdlink-fusion.dtb \
+ k3-am68-sk-v3link-fusion.dtb \
k3-am69-sk-csi2-dual-imx219.dtb \
k3-am69-sk-fpdlink-fusion.dtb \
k3-am69-sk-pcie0-ep.dtb \
+ k3-am69-sk-v3link-fusion.dtb \
k3-j7200-evm-pcie1-ep.dtb \
k3-j721e-common-proc-board-infotainment.dtb \
k3-j721e-evm-fpdlink-fusion.dtb \
@@ -369,6 +378,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
k3-j721e-evm-pcie1-ep.dtb \
k3-j721e-sk-csi2-dual-imx219.dtb \
k3-j721e-sk-fpdlink-fusion.dtb \
+ k3-j721e-sk-v3link-fusion.dtb \
k3-j721s2-evm-fpdlink-fusion.dtb \
k3-j721s2-evm-pcie1-ep.dtb \
k3-j721s2-evm-usb0-type-a.dtb \
diff --git a/arch/arm64/boot/dts/ti/k3-am68-sk-v3link-fusion.dtso b/arch/arm64/boot/dts/ti/k3-am68-sk-v3link-fusion.dtso
new file mode 100644
index 000000000000..cfbf59c45782
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am68-sk-v3link-fusion.dtso
@@ -0,0 +1,204 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for Arducam V3Link UC-A09 board
+ * https://www.arducam.com/fpd-link-3-cameras/
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+ clk_fusion_25M_fixed: fixed-clock-25M {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+};
+
+&csi_mux {
+ idle-state = <1>;
+};
+
+&cam0_i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ deser@30 {
+ compatible = "ti,ds90ub960-q1";
+ reg = <0x30>;
+
+ clock-names = "refclk";
+ clocks = <&clk_fusion_25M_fixed>;
+
+ i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+ deserializer_0_ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0{
+ reg= <0>;
+ status = "disabled";
+ };
+
+ port@1{
+ reg= <1>;
+ status = "disabled";
+ };
+
+ port@2{
+ reg= <2>;
+ status = "disabled";
+ };
+
+ port@3{
+ reg= <3>;
+ status = "disabled";
+ };
+
+ /* CSI-2 TX */
+ port@4 {
+ reg = <4>;
+ ds90ub960_0_csi_out: endpoint {
+ data-lanes = <1 2 3 4>;
+ clock-lanes = <0>;
+ link-frequencies = /bits/ 64 <800000000>;
+ remote-endpoint = <&csi2_phy0>;
+ };
+ };
+
+ port@5{
+ reg= <5>;
+ status = "disabled";
+ };
+ };
+
+ deserializer_0_links: links {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+&cam1_i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ deser@30 {
+ compatible = "ti,ds90ub960-q1";
+ reg = <0x30>;
+
+ clock-names = "refclk";
+ clocks = <&clk_fusion_25M_fixed>;
+
+ i2c-alias-pool = <0x5a 0x5b 0x5c 0x5d 0x5e 0x5f>;
+
+ deserializer_1_ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0{
+ reg= <0>;
+ status = "disabled";
+ };
+
+ port@1{
+ reg= <1>;
+ status = "disabled";
+ };
+
+ port@2{
+ reg= <2>;
+ status = "disabled";
+ };
+
+ port@3{
+ reg= <3>;
+ status = "disabled";
+ };
+
+ /* CSI-2 TX */
+ port@4 {
+ reg = <4>;
+ ds90ub960_1_csi_out: endpoint {
+ data-lanes = <1 2 3 4>;
+ clock-lanes = <0>;
+ link-frequencies = /bits/ 64 <800000000>;
+ remote-endpoint = <&csi2_phy1>;
+ };
+ };
+
+ port@5{
+ reg= <5>;
+ status = "disabled";
+ };
+ };
+
+ deserializer_1_links: links {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+&cdns_csi2rx0 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi0_port0: port@0 {
+ reg = <0>;
+ status = "okay";
+
+ csi2_phy0: endpoint {
+ remote-endpoint = <&ds90ub960_0_csi_out>;
+ bus-type = <4>; /* CSI2 DPHY. */
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ };
+ };
+ };
+};
+
+&cdns_csi2rx1 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi1_port0: port@0 {
+ reg = <0>;
+ status = "okay";
+
+ csi2_phy1: endpoint {
+ remote-endpoint = <&ds90ub960_1_csi_out>;
+ bus-type = <4>; /* CSI2 DPHY. */
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ };
+ };
+ };
+};
+
+&ti_csi2rx0 {
+ status = "okay";
+};
+
+&dphy0 {
+ status = "okay";
+};
+
+&ti_csi2rx1 {
+ status = "okay";
+};
+
+&dphy1 {
+ status = "okay";
+};
--
2.34.1
^ permalink raw reply related
* [PATCH 08/18] arm64: dts: ti: k3-j721s2: Add overlay for fusion application daughter board
From: Yemike Abhilash Chandra @ 2026-07-02 9:31 UTC (permalink / raw)
To: nm, vigneshr, kristo, robh, krzk+dt, conor+dt
Cc: Frank.Li, s.hauer, kernel, festevam, andersson, geert,
dmitry.baryshkov, arnd, ebiggers, luca.weiss, michal.simek, sven,
linux-arm-kernel, devicetree, linux-kernel, imx, r-donadkar,
devarsht, u-kumar1
In-Reply-To: <20260702093123.1048575-1-y-abhilashchandra@ti.com>
From: Vaishnav Achath <vaishnav.a@ti.com>
Fusion application daughter board [1] can be used to connect multiple
FPDLink-III based sensors to TI EVMs. The board has two DS90UB960
deserializers, each of which aggregates input from up to 4x FPDLink-III
sensors. Up to 8x sensors can simultaneously stream over the two CSI RX
ports on J721S2.
CSI2RX connectivity on J784S4 and J742S2 is the same as that of J721S2,
hence the same overlay can be reused.
[1]: https://svtronics.com/product/fusion-application-daughter-board-evm577pfusion-v1-0/?srsltid=AfmBOooMsRAd5ibFOGJaKbjsC3j9-loTPK2wWqsqPq2Adj55g1nPluxX
Signed-off-by: Vaishnav Achath <vaishnav.a@ti.com>
Signed-off-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
---
arch/arm64/boot/dts/ti/Makefile | 7 +
.../boot/dts/ti/k3-j721s2-evm-fusion.dtso | 191 ++++++++++++++++++
2 files changed, 198 insertions(+)
create mode 100644 arch/arm64/boot/dts/ti/k3-j721s2-evm-fusion.dtso
diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 7e2ed5c94e79..79ce2ff38cc3 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -160,6 +160,7 @@ k3-am68-phyboard-izar-peb-av-15-dtbs := k3-am68-phyboard-izar.dtb \
dtb-$(CONFIG_ARCH_K3) += k3-am68-sk-base-board.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am68-sk-base-board-pcie1-ep.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j721s2-common-proc-board.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-fusion.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-gesi-exp-board.dtbo
k3-j721s2-evm-dtbs := k3-j721s2-common-proc-board.dtb k3-j721s2-evm-gesi-exp-board.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm.dtb
@@ -283,6 +284,8 @@ k3-j721e-evm-pcie1-ep-dtbs := k3-j721e-common-proc-board.dtb \
k3-j721e-evm-pcie1-ep.dtbo
k3-j721e-sk-csi2-dual-imx219-dtbs := k3-j721e-sk.dtb \
k3-j721e-sk-csi2-dual-imx219.dtbo
+k3-j721s2-evm-fpdlink-fusion-dtbs := k3-j721s2-evm.dtb \
+ k3-j721s2-evm-fusion.dtbo
k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \
k3-j721s2-evm-pcie1-ep.dtbo
k3-j721s2-evm-usb0-type-a-dtbs := k3-j721s2-common-proc-board.dtb \
@@ -293,6 +296,8 @@ k3-j722s-evm-csi2-quad-tevi-ov5640-dtbs := k3-j722s-evm.dtb \
k3-j722s-evm-csi2-quad-tevi-ov5640.dtbo
k3-j742s2-evm-usb0-type-a-dtbs := k3-j742s2-evm.dtb \
k3-j784s4-j742s2-evm-usb0-type-a.dtbo
+k3-j784s4-evm-fpdlink-fusion-dtbs := k3-j784s4-evm.dtb \
+ k3-j721s2-evm-fusion.dtbo
k3-j784s4-evm-pcie0-pcie1-ep-dtbs := k3-j784s4-evm.dtb \
k3-j784s4-evm-pcie0-pcie1-ep.dtbo
k3-j784s4-evm-quad-port-eth-exp1-dtbs := k3-j784s4-evm.dtb \
@@ -351,11 +356,13 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
k3-j721e-evm-pcie0-ep.dtb \
k3-j721e-evm-pcie1-ep.dtb \
k3-j721e-sk-csi2-dual-imx219.dtb \
+ k3-j721s2-evm-fpdlink-fusion.dtb \
k3-j721s2-evm-pcie1-ep.dtb \
k3-j721s2-evm-usb0-type-a.dtb \
k3-j722s-evm-csi2-quad-rpi-cam-imx219.dtb \
k3-j722s-evm-csi2-quad-tevi-ov5640.dtb \
k3-j742s2-evm-usb0-type-a.dtb \
+ k3-j784s4-evm-fpdlink-fusion.dtb \
k3-j784s4-evm-pcie0-pcie1-ep.dtb \
k3-j784s4-evm-quad-port-eth-exp1.dtb \
k3-j784s4-evm-usb0-type-a.dtb \
diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-evm-fusion.dtso b/arch/arm64/boot/dts/ti/k3-j721s2-evm-fusion.dtso
new file mode 100644
index 000000000000..f200cdaa1bab
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-evm-fusion.dtso
@@ -0,0 +1,191 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for Fusion (FPD-Link III) board on J721S2 and J784S4 EVM
+ * https://svtronics.com/portfolio/evm577pfusion-v1-0-fusion/
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+ clk_fusion_25M_fixed: fixed-clock-25M {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+};
+
+
+&main_i2c5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ deser@3d {
+ compatible = "ti,ds90ub960-q1";
+ reg = <0x3d>;
+ clocks = <&clk_fusion_25M_fixed>;
+ clock-names = "refclk";
+ i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+ deserializer_0_ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0{
+ reg= <0>;
+ status = "disabled";
+ };
+
+ port@1{
+ reg= <1>;
+ status = "disabled";
+ };
+
+ port@2{
+ reg= <2>;
+ status = "disabled";
+ };
+
+ port@3{
+ reg= <3>;
+ status = "disabled";
+ };
+
+ /* CSI-2 TX */
+ port@4 {
+ reg = <4>;
+ ds90ub960_0_csi_out: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ remote-endpoint = <&csi2_phy0>;
+ };
+ };
+
+ port@5{
+ reg= <5>;
+ status = "disabled";
+ };
+ };
+
+ deserializer_0_links: links {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ deser@36 {
+ compatible = "ti,ds90ub960-q1";
+ reg = <0x36>;
+ clocks = <&clk_fusion_25M_fixed>;
+ clock-names = "refclk";
+ i2c-alias-pool = <0x5a 0x5b 0x5c 0x5d 0x5e 0x5f>;
+
+ deserializer_1_ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0{
+ reg= <0>;
+ status = "disabled";
+ };
+
+ port@1{
+ reg= <1>;
+ status = "disabled";
+ };
+
+ port@2{
+ reg= <2>;
+ status = "disabled";
+ };
+
+ port@3{
+ reg= <3>;
+ status = "disabled";
+ };
+
+ /* CSI-2 TX */
+ port@4 {
+ reg = <4>;
+ ds90ub960_1_csi_out: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ remote-endpoint = <&csi2_phy1>;
+ };
+ };
+
+ port@5{
+ reg= <5>;
+ status = "disabled";
+ };
+ };
+
+ deserializer_1_links: links {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+&cdns_csi2rx0 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi0_port0: port@0 {
+ reg = <0>;
+ status = "okay";
+
+ csi2_phy0: endpoint {
+ remote-endpoint = <&ds90ub960_0_csi_out>;
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+
+ };
+ };
+ };
+};
+
+&cdns_csi2rx1 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi1_port0: port@0 {
+ reg = <0>;
+ status = "okay";
+
+ csi2_phy1: endpoint {
+ remote-endpoint = <&ds90ub960_1_csi_out>;
+ bus-type = <4>; /* CSI2 DPHY */
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ };
+ };
+ };
+};
+
+&ti_csi2rx0 {
+ status = "okay";
+};
+
+&dphy0 {
+ status = "okay";
+};
+
+&ti_csi2rx1 {
+ status = "okay";
+};
+
+&dphy1 {
+ status = "okay";
+};
--
2.34.1
^ permalink raw reply related
* [PATCH 05/18] arm64: dts: ti: k3-am62p-j722s: Add multiple channels for CSI2RX DMA
From: Yemike Abhilash Chandra @ 2026-07-02 9:31 UTC (permalink / raw)
To: nm, vigneshr, kristo, robh, krzk+dt, conor+dt
Cc: Frank.Li, s.hauer, kernel, festevam, andersson, geert,
dmitry.baryshkov, arnd, ebiggers, luca.weiss, michal.simek, sven,
linux-arm-kernel, devicetree, linux-kernel, imx, r-donadkar,
devarsht, u-kumar1
In-Reply-To: <20260702093123.1048575-1-y-abhilashchandra@ti.com>
From: Vaishnav Achath <vaishnav.a@ti.com>
J721E CSI2RX SHIM layer can support up to 32 DMA channel contexts,
Add additional DMA channels to enable multistream support for CSI2RX.
Signed-off-by: Vaishnav Achath <vaishnav.a@ti.com>
Signed-off-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
---
arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi
index f130c7cb998d..ecb537b96fca 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi
@@ -1053,8 +1053,10 @@ ti_csi2rx0: ticsi2rx@30102000 {
ranges;
#address-cells = <2>;
#size-cells = <2>;
- dmas = <&main_bcdma_csi 0 0x5000 0>;
- dma-names = "rx0";
+ dmas = <&main_bcdma_csi 0 0x5000 0>, <&main_bcdma_csi 0 0x5001 0>,
+ <&main_bcdma_csi 0 0x5002 0>, <&main_bcdma_csi 0 0x5003 0>,
+ <&main_bcdma_csi 0 0x5004 0>, <&main_bcdma_csi 0 0x5005 0>;
+ dma-names = "rx0", "rx1", "rx2", "rx3", "rx4", "rx5";
power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
status = "disabled";
--
2.34.1
^ permalink raw reply related
* [PATCH 06/18] arm64: dts: ti: k3-j722s-main: Add multiple channels for CSI2RX DMA
From: Yemike Abhilash Chandra @ 2026-07-02 9:31 UTC (permalink / raw)
To: nm, vigneshr, kristo, robh, krzk+dt, conor+dt
Cc: Frank.Li, s.hauer, kernel, festevam, andersson, geert,
dmitry.baryshkov, arnd, ebiggers, luca.weiss, michal.simek, sven,
linux-arm-kernel, devicetree, linux-kernel, imx, r-donadkar,
devarsht, u-kumar1
In-Reply-To: <20260702093123.1048575-1-y-abhilashchandra@ti.com>
From: Vaishnav Achath <vaishnav.a@ti.com>
J721E CSI2RX SHIM layer can support up to 32 DMA channel contexts,
Add additional DMA channels to enable multistream support for CSI2RX.
Signed-off-by: Vaishnav Achath <vaishnav.a@ti.com>
Tested-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
---
arch/arm64/boot/dts/ti/k3-j722s-main.dtsi | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/boot/dts/ti/k3-j722s-main.dtsi b/arch/arm64/boot/dts/ti/k3-j722s-main.dtsi
index d1dbf1e24fbf..98d2090c4c9c 100644
--- a/arch/arm64/boot/dts/ti/k3-j722s-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j722s-main.dtsi
@@ -173,8 +173,9 @@ ti_csi2rx1: ticsi2rx@30122000 {
ranges;
#address-cells = <2>;
#size-cells = <2>;
- dmas = <&main_bcdma_csi 0 0x5100 0>;
- dma-names = "rx0";
+ dmas = <&main_bcdma_csi 0 0x5100 0>, <&main_bcdma_csi 0 0x5101 0>,
+ <&main_bcdma_csi 0 0x5102 0>, <&main_bcdma_csi 0 0x5103 0>;
+ dma-names = "rx0", "rx1", "rx2", "rx3";
power-domains = <&k3_pds 247 TI_SCI_PD_EXCLUSIVE>;
status = "disabled";
@@ -230,8 +231,9 @@ ti_csi2rx2: ticsi2rx@30142000 {
#address-cells = <2>;
#size-cells = <2>;
power-domains = <&k3_pds 248 TI_SCI_PD_EXCLUSIVE>;
- dmas = <&main_bcdma_csi 0 0x5200 0>;
- dma-names = "rx0";
+ dmas = <&main_bcdma_csi 0 0x5200 0>, <&main_bcdma_csi 0 0x5201 0>,
+ <&main_bcdma_csi 0 0x5202 0>, <&main_bcdma_csi 0 0x5203 0>;
+ dma-names = "rx0", "rx1", "rx2", "rx3";
status = "disabled";
cdns_csi2rx2: csi-bridge@30141000 {
@@ -285,8 +287,9 @@ ti_csi2rx3: ticsi2rx@30162000 {
ranges;
#address-cells = <2>;
#size-cells = <2>;
- dmas = <&main_bcdma_csi 0 0x5300 0>;
- dma-names = "rx0";
+ dmas = <&main_bcdma_csi 0 0x5300 0>, <&main_bcdma_csi 0 0x5301 0>,
+ <&main_bcdma_csi 0 0x5302 0>, <&main_bcdma_csi 0 0x5303 0>;
+ dma-names = "rx0", "rx1", "rx2", "rx3";
power-domains = <&k3_pds 249 TI_SCI_PD_EXCLUSIVE>;
status = "disabled";
--
2.34.1
^ permalink raw reply related
* [PATCH 00/18] Add DT support for CSI2RX multi-stream
From: Yemike Abhilash Chandra @ 2026-07-02 9:31 UTC (permalink / raw)
To: nm, vigneshr, kristo, robh, krzk+dt, conor+dt
Cc: Frank.Li, s.hauer, kernel, festevam, andersson, geert,
dmitry.baryshkov, arnd, ebiggers, luca.weiss, michal.simek, sven,
linux-arm-kernel, devicetree, linux-kernel, imx, r-donadkar,
devarsht, u-kumar1
Driver support for CSI2RX multi-stream was merged last cycle[0]. This
series adds the corresponding device tree support.
Patch 1 is a cleanup fixing indentation in the existing CSI2RX nodes.
The next few patches i.e. (Patch 2 to Patch 6) add the additional DMA
channels required for CSI2RX multi-stream capture.
Multi-stream capture uses a SERDES pair based on the FPD-Link or
V3Link protocol. The serializer takes the input from a camera sensor
and converts it to the FPD-Link standard, while the deserializer
aggregates streams from multiple serializers and sends them over the
CSI-2 RX interface. Each CSI2RX instance therefore indirectly receives
input from multiple sensors.
The remaining patches add overlays for various deserializer boards,
and for the UB953 serializer with the IMX219 sensor. Also enabling
DS90UB960 deserializer and DS90UB953 serializer drivers in the
arm64 defconfig.
Testlogs:
J721E + Fusion application daughter board: https://gist.github.com/Yemike-Abhilash-Chandra/341cea78c93a5849a9b318a5fa1ad5b2
J721S2 + Fusion application daughter board: https://gist.github.com/Yemike-Abhilash-Chandra/e676bda929ae940f9c85e8dd3d03f644
J784s4s + Fusion application daughter board: https://gist.github.com/Yemike-Abhilash-Chandra/e69f077af78468b9e5dfc20b9bdef374
AM68 + Fusion application daughter board: https://gist.github.com/Yemike-Abhilash-Chandra/aa913e3533b227a477d6363c04692474
J721E + DS90UB954-Q1EVM: https://gist.github.com/Yemike-Abhilash-Chandra/f1bfaa7f62b185c492a81659100a9c02
J721S2 + DS90UB954-Q1EVM: https://gist.github.com/Yemike-Abhilash-Chandra/15dda67fffc542d30bcc3a83dd7d5782
J784s4s + J7EXPA01EVM Fusion2: https://gist.github.com/Yemike-Abhilash-Chandra/22a74bae79c1fc7eb92d158fc1ee81b5
AM68 + Arducam V3link: https://gist.github.com/Yemike-Abhilash-Chandra/8188ac234b21406f336032c14c9fa9d4
J722S + Arducam V3link: https://gist.github.com/Yemike-Abhilash-Chandra/24d49bd30ba3a499ff7c93fa4d5cc1ad
(grep for "ds90ub960" for the deserializer logs and "ds90ub953" for the serializer.
grep for "running tests" to see the actual test pattern genertaion capture logs from
the sensor over the SERDES)
dtbs_check: make CONFIG_OF_ALL_DTBS=y dtstree=arch/arm64/boot/dts/ti dtbs_check gives no errors
Branch: https://github.com/Yemike-Abhilash-Chandra/linux/tree/CSI_MT_DT_V3
[0]: https://lore.kernel.org/all/20260520120022.539913-1-r-donadkar@ti.com/
Jianzhong Xu (1):
arm64: dts: ti: k3-v3link: Add overlay for IMX219+UB953 serializer
Vaishnav Achath (13):
arm64: dts: ti: k3-{j721e/j721s2}-main: Fix indentation in CSI2RX node
arm64: dts: ti: k3-j721e-main: Add multiple channels for CSI2RX DMA
arm64: dts: ti: k3-j721s2-main: Add multiple channels for CSI2RX DMA
arm64: dts: ti: k3-j784s4-j742s2-main-common: Add multiple channels
for CSI2RX DMA
arm64: dts: ti: k3-am62p-j722s: Add multiple channels for CSI2RX DMA
arm64: dts: ti: k3-j722s-main: Add multiple channels for CSI2RX DMA
arm64: dts: ti: k3-j721e: Add overlay for fusion application daughter
board
arm64: dts: ti: k3-j721s2: Add overlay for fusion application daughter
board
arm64: dts: ti: k3-j721e-sk: Add overlay for fusion application
daughter board
arm64: dts: ti: k3-j722s-evm: Add overlay for fusion application
daughter board
arm64: dts: ti: k3-am68-sk: Add overlay for dual Arducam V3link fusion
arm64: dts: ti: k3-j722s-evm: Add overlay for dual Arducam V3link
fusion
arm64: dts: ti: k3-j784s4-evm: Add overlay for J7EXPA01EVM Fusion2
Yemike Abhilash Chandra (4):
arm64: dts: ti: k3-j722s-evm: Add overlay for J7EXPA01EVM Fusion2
arm64: dts: ti: k3-j721s2: Add overlay for DS90UB954-Q1EVM
arm64: dts: ti: k3-j721e: Add overlay for DS90UB954-Q1EVM
arm64: defconfig: Enable DS90UB960 deserializer and DS90UB953
serializer
arch/arm64/boot/dts/ti/Makefile | 62 ++++
.../dts/ti/k3-am62p-j722s-common-main.dtsi | 6 +-
.../boot/dts/ti/k3-am68-sk-v3link-fusion.dtso | 204 ++++++++++++
.../boot/dts/ti/k3-j721e-evm-fusion.dtso | 191 +++++++++++
.../arm64/boot/dts/ti/k3-j721e-evm-ub954.dtso | 93 ++++++
arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 24 +-
.../dts/ti/k3-j721e-sk-fpdlink-fusion.dtso | 191 +++++++++++
.../boot/dts/ti/k3-j721s2-evm-fusion.dtso | 191 +++++++++++
.../boot/dts/ti/k3-j721s2-evm-ub954.dtso | 93 ++++++
arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi | 22 +-
.../dts/ti/k3-j722s-evm-fpdlink-fusion.dtso | 196 ++++++++++++
.../ti/k3-j722s-evm-fpdlink-iv-fusion.dtso | 296 ++++++++++++++++++
.../dts/ti/k3-j722s-evm-v3link-fusion.dtso | 213 +++++++++++++
arch/arm64/boot/dts/ti/k3-j722s-main.dtsi | 15 +-
.../ti/k3-j784s4-evm-fpdlink-iv-fusion.dtso | 281 +++++++++++++++++
.../dts/ti/k3-j784s4-j742s2-main-common.dtsi | 21 +-
.../boot/dts/ti/k3-v3link-imx219-0-0.dtso | 127 ++++++++
arch/arm64/configs/defconfig | 2 +
18 files changed, 2200 insertions(+), 28 deletions(-)
create mode 100644 arch/arm64/boot/dts/ti/k3-am68-sk-v3link-fusion.dtso
create mode 100644 arch/arm64/boot/dts/ti/k3-j721e-evm-fusion.dtso
create mode 100644 arch/arm64/boot/dts/ti/k3-j721e-evm-ub954.dtso
create mode 100644 arch/arm64/boot/dts/ti/k3-j721e-sk-fpdlink-fusion.dtso
create mode 100644 arch/arm64/boot/dts/ti/k3-j721s2-evm-fusion.dtso
create mode 100644 arch/arm64/boot/dts/ti/k3-j721s2-evm-ub954.dtso
create mode 100644 arch/arm64/boot/dts/ti/k3-j722s-evm-fpdlink-fusion.dtso
create mode 100644 arch/arm64/boot/dts/ti/k3-j722s-evm-fpdlink-iv-fusion.dtso
create mode 100644 arch/arm64/boot/dts/ti/k3-j722s-evm-v3link-fusion.dtso
create mode 100644 arch/arm64/boot/dts/ti/k3-j784s4-evm-fpdlink-iv-fusion.dtso
create mode 100644 arch/arm64/boot/dts/ti/k3-v3link-imx219-0-0.dtso
--
2.34.1
^ permalink raw reply
* [PATCH 09/18] arm64: dts: ti: k3-j721e-sk: Add overlay for fusion application daughter board
From: Yemike Abhilash Chandra @ 2026-07-02 9:31 UTC (permalink / raw)
To: nm, vigneshr, kristo, robh, krzk+dt, conor+dt
Cc: Frank.Li, s.hauer, kernel, festevam, andersson, geert,
dmitry.baryshkov, arnd, ebiggers, luca.weiss, michal.simek, sven,
linux-arm-kernel, devicetree, linux-kernel, imx, r-donadkar,
devarsht, u-kumar1
In-Reply-To: <20260702093123.1048575-1-y-abhilashchandra@ti.com>
From: Vaishnav Achath <vaishnav.a@ti.com>
Fusion application daughter board [1] can be used to connect multiple
FPDLink-III based sensors to TI EVMs. The board has two DS90UB960
deserializers, each of which aggregates input from up to 4x FPDLink-III
sensors. Up to 8x sensors can simultaneously stream over the two CSI RX
ports on J721E SK.
CSI2RX connectivity on AM68-SK and AM69-SK is the same as that of J721E-SK,
hence the same overlay can be reused.
[1]: https://svtronics.com/product/fusion-application-daughter-board-evm577pfusion-v1-0/?srsltid=AfmBOooMsRAd5ibFOGJaKbjsC3j9-loTPK2wWqsqPq2Adj55g1nPluxX
Signed-off-by: Vaishnav Achath <vaishnav.a@ti.com>
Signed-off-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
---
arch/arm64/boot/dts/ti/Makefile | 10 +
.../dts/ti/k3-j721e-sk-fpdlink-fusion.dtso | 191 ++++++++++++++++++
2 files changed, 201 insertions(+)
create mode 100644 arch/arm64/boot/dts/ti/k3-j721e-sk-fpdlink-fusion.dtso
diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 79ce2ff38cc3..b31bf2f305aa 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -148,6 +148,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-pcie0-ep.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-pcie1-ep.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk.dtb
dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk-csi2-dual-imx219.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk-fpdlink-fusion.dtbo
# Boards with J721s2 SoC
dtb-$(CONFIG_ARCH_K3) += k3-am68-phyboard-izar.dtb
@@ -268,8 +269,12 @@ k3-am68-sk-base-board-csi2-dual-imx219-dtbs := k3-am68-sk-base-board.dtb \
k3-j721e-sk-csi2-dual-imx219.dtbo
k3-am68-sk-base-board-pcie1-ep-dtbs := k3-am68-sk-base-board.dtb \
k3-am68-sk-base-board-pcie1-ep.dtbo
+k3-am68-sk-fpdlink-fusion-dtbs := k3-am68-sk-base-board.dtb \
+ k3-j721e-sk-fpdlink-fusion.dtbo
k3-am69-sk-csi2-dual-imx219-dtbs := k3-am69-sk.dtb \
k3-j721e-sk-csi2-dual-imx219.dtbo
+k3-am69-sk-fpdlink-fusion-dtbs := k3-am69-sk.dtb \
+ k3-j721e-sk-fpdlink-fusion.dtbo
k3-am69-sk-pcie0-ep-dtbs := k3-am69-sk.dtb \
k3-am69-sk-pcie0-ep.dtbo
k3-j7200-evm-pcie1-ep-dtbs := k3-j7200-common-proc-board.dtb \
@@ -284,6 +289,8 @@ k3-j721e-evm-pcie1-ep-dtbs := k3-j721e-common-proc-board.dtb \
k3-j721e-evm-pcie1-ep.dtbo
k3-j721e-sk-csi2-dual-imx219-dtbs := k3-j721e-sk.dtb \
k3-j721e-sk-csi2-dual-imx219.dtbo
+k3-j721e-sk-fpdlink-fusion-dtbs := k3-j721e-sk.dtb \
+ k3-j721e-sk-fpdlink-fusion.dtbo
k3-j721s2-evm-fpdlink-fusion-dtbs := k3-j721s2-evm.dtb \
k3-j721s2-evm-fusion.dtbo
k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \
@@ -348,7 +355,9 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
k3-am68-phyboard-izar-peb-av-15.dtb \
k3-am68-sk-base-board-csi2-dual-imx219.dtb \
k3-am68-sk-base-board-pcie1-ep.dtb \
+ k3-am68-sk-fpdlink-fusion.dtb \
k3-am69-sk-csi2-dual-imx219.dtb \
+ k3-am69-sk-fpdlink-fusion.dtb \
k3-am69-sk-pcie0-ep.dtb \
k3-j7200-evm-pcie1-ep.dtb \
k3-j721e-common-proc-board-infotainment.dtb \
@@ -356,6 +365,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
k3-j721e-evm-pcie0-ep.dtb \
k3-j721e-evm-pcie1-ep.dtb \
k3-j721e-sk-csi2-dual-imx219.dtb \
+ k3-j721e-sk-fpdlink-fusion.dtb \
k3-j721s2-evm-fpdlink-fusion.dtb \
k3-j721s2-evm-pcie1-ep.dtb \
k3-j721s2-evm-usb0-type-a.dtb \
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-sk-fpdlink-fusion.dtso b/arch/arm64/boot/dts/ti/k3-j721e-sk-fpdlink-fusion.dtso
new file mode 100644
index 000000000000..dd82ec3accfe
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j721e-sk-fpdlink-fusion.dtso
@@ -0,0 +1,191 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DT Overlay for Fusion (FPD-Link III) board on J721E SK,
+ * AM68 SK or AM69 SK.
+ * https://svtronics.com/portfolio/evm577pfusion-v1-0-fusion/
+ *
+ * Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+ clk_fusion_25M_fixed: fixed-clock-25M {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+};
+
+
+&cam0_i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ deser@3d {
+ compatible = "ti,ds90ub960-q1";
+ reg = <0x3d>;
+ clocks = <&clk_fusion_25M_fixed>;
+ clock-names = "refclk";
+ i2c-alias-pool = <0x4a 0x4b 0x4c 0x4d 0x4e 0x4f>;
+
+ deserializer_0_ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0{
+ reg= <0>;
+ status = "disabled";
+ };
+
+ port@1{
+ reg= <1>;
+ status = "disabled";
+ };
+
+ port@2{
+ reg= <2>;
+ status = "disabled";
+ };
+
+ port@3{
+ reg= <3>;
+ status = "disabled";
+ };
+
+ /* CSI-2 TX*/
+ port@4 {
+ reg = <4>;
+ ds90ub960_0_csi_out: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ remote-endpoint = <&csi2_phy0>;
+ };
+ };
+
+ port@5{
+ reg= <5>;
+ status = "disabled";
+ };
+ };
+
+ deserializer_0_links: links {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ deser@36 {
+ compatible = "ti,ds90ub960-q1";
+ reg = <0x36>;
+ clocks = <&clk_fusion_25M_fixed>;
+ clock-names = "refclk";
+ i2c-alias-pool = <0x5a 0x5b 0x5c 0x5d 0x5e 0x5f>;
+
+ deserializer_1_ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0{
+ reg= <0>;
+ status = "disabled";
+ };
+
+ port@1{
+ reg= <1>;
+ status = "disabled";
+ };
+
+ port@2{
+ reg= <2>;
+ status = "disabled";
+ };
+
+ port@3{
+ reg= <3>;
+ status = "disabled";
+ };
+
+ /* CSI-2 TX*/
+ port@4 {
+ reg = <4>;
+ ds90ub960_1_csi_out: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ remote-endpoint = <&csi2_phy1>;
+ };
+ };
+
+ port@5{
+ reg= <5>;
+ status = "disabled";
+ };
+ };
+
+ deserializer_1_links: links {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+&cdns_csi2rx0 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi0_port0: port@0 {
+ reg = <0>;
+ status = "okay";
+
+ csi2_phy0: endpoint {
+ remote-endpoint = <&ds90ub960_0_csi_out>;
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+
+ };
+ };
+ };
+};
+
+&cdns_csi2rx1 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi1_port0: port@0 {
+ reg = <0>;
+ status = "okay";
+
+ csi2_phy1: endpoint {
+ remote-endpoint = <&ds90ub960_1_csi_out>;
+ bus-type = <4>; /* CSI2 DPHY */
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <800000000>;
+ };
+ };
+ };
+};
+
+&ti_csi2rx0 {
+ status = "okay";
+};
+
+&dphy0 {
+ status = "okay";
+};
+
+&ti_csi2rx1 {
+ status = "okay";
+};
+
+&dphy1 {
+ status = "okay";
+};
--
2.34.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox