* [PATCH v14 00/44] arm64: Support for Arm CCA in KVM
From: Steven Price @ 2026-05-13 13:17 UTC (permalink / raw)
To: kvm, kvmarm
Cc: Steven Price, Catalin Marinas, Marc Zyngier, Will Deacon,
James Morse, Oliver Upton, Suzuki K Poulose, Zenghui Yu,
linux-arm-kernel, linux-kernel, Joey Gouly, Alexandru Elisei,
Christoffer Dall, Fuad Tabba, linux-coco, Ganapatrao Kulkarni,
Gavin Shan, Shanker Donthineni, Alper Gun, Aneesh Kumar K . V,
Emi Kisanuki, Vishal Annapurve, WeiLin.Chang, Lorenzo.Pieralisi2
This series adds support for running protected VMs using KVM under the
Arm Confidential Compute Architecture (CCA).
This is rebased on v7.1-rc1, but still targets RMM v2.0-bet1[1].
The major updates from v13 remain but have been more fully implemented:
the RMM uses the host's page size, range based RMI APIs mean we don't
have to break everything down to base page sizes, the GIC state is
passed via system registers, and the uAPI has been simplified.
The main changes since v13 are:
* The RMI definitions and wrappers have been fully updated for RMM
v2.0-bet1. In particular the temporary RMM v1.0 SMC compatibility
patch has been dropped.
* The PSCI completion ioctl has been removed. RMM v2.0-bet1 still
requires the host to provide the target REC for PSCI calls which
name another vCPU, but KVM now performs the RMI PSCI completion
automatically before entering the REC again. Userspace no longer
needs to issue KVM_ARM_VCPU_RMI_PSCI_COMPLETE. A future spec should
remove the need for the host to provide the MPIDR mapping.
* The generic RMI init, RMM configuration, GPT setup,
delegate/undelegate helpers and SRO infrastructure have moved out of
KVM into arch/arm64/kernel/rmi.c. RMI is expected to be used by
features outside KVM, so this code should be available even when KVM
is not built.
* RMI_GRANULE_TRACKING_GET has been updated to work on a range, this
allows it to work when the region is not aligned to the tracking
size. Solves the problem reported by Mathieu[2].
* SRO support has been moved earlier in the series and improved. It
provides a cleaner way for the host to provide the RMM with the extra
memory it requires. However support is still incomplete where the
TF-RMM code does not yet implement it. This is noted by FIXMEs in the
code.
* The ARM VM type encoding has been reworked to coexist with the
upstream pKVM KVM_VM_TYPE_ARM_PROTECTED bit.
* The private-memory documentation now notes that arm64 uses
KVM_CAP_MEMORY_ATTRIBUTES.
* PMU support is dropped for now. It will be added later in a separate
series. Similarly for selecting the hash algorithm and RPV.
There are also the usual rebase updates and smaller fixes, including
changes to the RMM v2.0-bet1 range APIs, removal of REC auxiliary
granule handling, fixes to the address range descriptor encoding, and
cleanups around realm stage-2 teardown.
Stateful RMI Operations
-----------------------
The RMM v2.0 spec introduces Stateful RMI Operations (SROs), which allow
the RMM to complete an operation over several SMC calls while requesting
or returning memory to the host. This allows interrupts to be handled in
the middle of an operation and lets the RMM dynamically allocate memory
for internal tracking purposes. For example, RMI_REC_CREATE no longer
needs auxiliary granules to be provided up front, and can instead
request memory during the operation.
This series includes the generic SRO infrastructure in
arch/arm64/kernel/rmi.c and uses it for REC create/destroy. The other
cases are not yet used by TF-RMM and a future revision will be needed to
finish those paths in Linux.
This series is based on v7.1-rc1. It is also available as a git
repository:
https://gitlab.arm.com/linux-arm/linux-cca cca-host/v14
Work in progress changes for kvmtool are available from the git
repository below:
https://gitlab.arm.com/linux-arm/kvmtool-cca cca/v12
The TF-RMM has not yet merged the RMM v2.0 support, so you will need to
use a branch with RMM v2.0-bet1 support. At the time of writing the
following branch is being used:
https://git.trustedfirmware.org/TF-RMM/tf-rmm.git topics/rmm-v2.0-poc_2
(tested on commit 3340667a291a)
There is a kvm-unit-test branch which has been updated to support the
attestation used in RMMv2.0 available here:
https://gitlab.arm.com/linux-arm/kvm-unit-tests-cca cca/v4
[1] https://developer.arm.com/documentation/den0137/2-0bet1/
[2] https://lore.kernel.org/all/acrj-cKphy4hJsEG@p14s/
Jean-Philippe Brucker (6):
arm64: RMI: Propagate number of breakpoints and watchpoints to
userspace
arm64: RMI: Set breakpoint parameters through SET_ONE_REG
arm64: RMI: Propagate max SVE vector length from RMM
arm64: RMI: Configure max SVE vector length for a Realm
arm64: RMI: Provide register list for unfinalized RMI RECs
arm64: RMI: Provide accurate register list
Joey Gouly (2):
arm64: RMI: allow userspace to inject aborts
arm64: RMI: support RSI_HOST_CALL
Steven Price (33):
kvm: arm64: Avoid including linux/kvm_host.h in kvm_pgtable.h
arm64: RME: Handle Granule Protection Faults (GPFs)
arm64: RMI: Add SMC definitions for calling the RMM
arm64: RMI: Add wrappers for RMI calls
arm64: RMI: Check for RMI support at init
arm64: RMI: Configure the RMM with the host's page size
arm64: RMI: Ensure that the RMM has GPT entries for memory
arm64: RMI: Provide functions to delegate/undelegate ranges of memory
arm64: RMI: Add support for SRO
arm64: RMI: Check for RMI support at KVM init
arm64: RMI: Check for LPA2 support
arm64: RMI: Define the user ABI
arm64: RMI: Basic infrastructure for creating a realm.
KVM: arm64: Allow passing machine type in KVM creation
arm64: RMI: RTT tear down
arm64: RMI: Activate realm on first VCPU run
arm64: RMI: Allocate/free RECs to match vCPUs
arm64: RMI: Support for the VGIC in realms
KVM: arm64: Support timers in realm RECs
arm64: RMI: Handle realm enter/exit
arm64: RMI: Handle RMI_EXIT_RIPAS_CHANGE
KVM: arm64: Handle realm MMIO emulation
KVM: arm64: Expose support for private memory
arm64: RMI: Allow populating initial contents
arm64: RMI: Set RIPAS of initial memslots
arm64: RMI: Create the realm descriptor
arm64: RMI: Runtime faulting of memory
KVM: arm64: Handle realm VCPU load
KVM: arm64: Validate register access for a Realm VM
KVM: arm64: Handle Realm PSCI requests
KVM: arm64: WARN on injected undef exceptions
arm64: RMI: Prevent Device mappings for Realms
arm64: RMI: Enable realms to be created
Suzuki K Poulose (3):
kvm: arm64: Include kvm_emulate.h in kvm/arm_psci.h
kvm: arm64: Don't expose unsupported capabilities for realm guests
arm64: RMI: Allow checking SVE on VM instance
Documentation/virt/kvm/api.rst | 62 +-
arch/arm64/include/asm/kvm_emulate.h | 37 +
arch/arm64/include/asm/kvm_host.h | 13 +-
arch/arm64/include/asm/kvm_pgtable.h | 5 +-
arch/arm64/include/asm/kvm_pkvm.h | 2 +-
arch/arm64/include/asm/kvm_rmi.h | 127 +++
arch/arm64/include/asm/rmi_cmds.h | 680 +++++++++++++
arch/arm64/include/asm/rmi_smc.h | 448 ++++++++
arch/arm64/include/asm/virt.h | 1 +
arch/arm64/kernel/Makefile | 2 +-
arch/arm64/kernel/cpufeature.c | 1 +
arch/arm64/kernel/rmi.c | 605 +++++++++++
arch/arm64/kvm/Kconfig | 2 +
arch/arm64/kvm/Makefile | 2 +-
arch/arm64/kvm/arch_timer.c | 28 +-
arch/arm64/kvm/arm.c | 140 ++-
arch/arm64/kvm/guest.c | 93 +-
arch/arm64/kvm/hyp/pgtable.c | 1 +
arch/arm64/kvm/hypercalls.c | 4 +-
arch/arm64/kvm/inject_fault.c | 5 +-
arch/arm64/kvm/mmio.c | 16 +-
arch/arm64/kvm/mmu.c | 197 +++-
arch/arm64/kvm/psci.c | 15 +-
arch/arm64/kvm/reset.c | 13 +-
arch/arm64/kvm/rmi-exit.c | 215 ++++
arch/arm64/kvm/rmi.c | 1401 ++++++++++++++++++++++++++
arch/arm64/kvm/sys_regs.c | 47 +-
arch/arm64/kvm/vgic/vgic-init.c | 2 +-
arch/arm64/mm/fault.c | 28 +-
include/kvm/arm_arch_timer.h | 2 +
include/kvm/arm_psci.h | 2 +
include/uapi/linux/kvm.h | 20 +-
32 files changed, 4122 insertions(+), 94 deletions(-)
create mode 100644 arch/arm64/include/asm/kvm_rmi.h
create mode 100644 arch/arm64/include/asm/rmi_cmds.h
create mode 100644 arch/arm64/include/asm/rmi_smc.h
create mode 100644 arch/arm64/kernel/rmi.c
create mode 100644 arch/arm64/kvm/rmi-exit.c
create mode 100644 arch/arm64/kvm/rmi.c
--
2.43.0
^ permalink raw reply
* [PATCH v14 01/44] kvm: arm64: Include kvm_emulate.h in kvm/arm_psci.h
From: Steven Price @ 2026-05-13 13:17 UTC (permalink / raw)
To: kvm, kvmarm
Cc: Suzuki K Poulose, Catalin Marinas, Marc Zyngier, Will Deacon,
James Morse, Oliver Upton, Zenghui Yu, linux-arm-kernel,
linux-kernel, Joey Gouly, Alexandru Elisei, Christoffer Dall,
Fuad Tabba, linux-coco, Ganapatrao Kulkarni, Gavin Shan,
Shanker Donthineni, Alper Gun, Aneesh Kumar K . V, Emi Kisanuki,
Vishal Annapurve, WeiLin.Chang, Lorenzo.Pieralisi2, Steven Price
In-Reply-To: <20260513131757.116630-1-steven.price@arm.com>
From: Suzuki K Poulose <suzuki.poulose@arm.com>
Fix a potential build error (like below, when asm/kvm_emulate.h gets
included after the kvm/arm_psci.h) by including the missing header file
in kvm/arm_psci.h:
./include/kvm/arm_psci.h: In function ‘kvm_psci_version’:
./include/kvm/arm_psci.h:29:13: error: implicit declaration of function
‘vcpu_has_feature’; did you mean ‘cpu_have_feature’? [-Werror=implicit-function-declaration]
29 | if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_PSCI_0_2)) {
| ^~~~~~~~~~~~~~~~
| cpu_have_feature
Reviewed-by: Gavin Shan <gshan@redhat.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Steven Price <steven.price@arm.com>
---
include/kvm/arm_psci.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/kvm/arm_psci.h b/include/kvm/arm_psci.h
index cbaec804eb83..38dab7add79b 100644
--- a/include/kvm/arm_psci.h
+++ b/include/kvm/arm_psci.h
@@ -10,6 +10,8 @@
#include <linux/kvm_host.h>
#include <uapi/linux/psci.h>
+#include <asm/kvm_emulate.h>
+
#define KVM_ARM_PSCI_0_1 PSCI_VERSION(0, 1)
#define KVM_ARM_PSCI_0_2 PSCI_VERSION(0, 2)
#define KVM_ARM_PSCI_1_0 PSCI_VERSION(1, 0)
--
2.43.0
^ permalink raw reply related
* [PATCH v14 02/44] kvm: arm64: Avoid including linux/kvm_host.h in kvm_pgtable.h
From: Steven Price @ 2026-05-13 13:17 UTC (permalink / raw)
To: kvm, kvmarm
Cc: Steven Price, Catalin Marinas, Marc Zyngier, Will Deacon,
James Morse, Oliver Upton, Suzuki K Poulose, Zenghui Yu,
linux-arm-kernel, linux-kernel, Joey Gouly, Alexandru Elisei,
Christoffer Dall, Fuad Tabba, linux-coco, Ganapatrao Kulkarni,
Gavin Shan, Shanker Donthineni, Alper Gun, Aneesh Kumar K . V,
Emi Kisanuki, Vishal Annapurve, WeiLin.Chang, Lorenzo.Pieralisi2
In-Reply-To: <20260513131757.116630-1-steven.price@arm.com>
To avoid future include cycles, drop the linux/kvm_host.h include in
kvm_pgtable.h and include two _types.h headers for the types that are
actually used. Additionally provide a forward declaration for struct
kvm_s2_mmu as it's only used as a pointer in this file.
Both pgtable.c and kvm_pkvm.h relied on the indirect inclusion of
kvm_host.h, so make that explicit.
Signed-off-by: Steven Price <steven.price@arm.com>
---
New patch in v13
---
arch/arm64/include/asm/kvm_pgtable.h | 5 ++++-
arch/arm64/include/asm/kvm_pkvm.h | 2 +-
arch/arm64/kvm/hyp/pgtable.c | 1 +
3 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index 41a8687938eb..e4770ce2ccf6 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -8,9 +8,12 @@
#define __ARM64_KVM_PGTABLE_H__
#include <linux/bits.h>
-#include <linux/kvm_host.h>
+#include <linux/kvm_types.h>
+#include <linux/rbtree_types.h>
#include <linux/types.h>
+struct kvm_s2_mmu;
+
#define KVM_PGTABLE_FIRST_LEVEL -1
#define KVM_PGTABLE_LAST_LEVEL 3
diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
index 2954b311128c..1bc6a6a34ec9 100644
--- a/arch/arm64/include/asm/kvm_pkvm.h
+++ b/arch/arm64/include/asm/kvm_pkvm.h
@@ -9,7 +9,7 @@
#include <linux/arm_ffa.h>
#include <linux/memblock.h>
#include <linux/scatterlist.h>
-#include <asm/kvm_host.h>
+#include <linux/kvm_host.h>
#include <asm/kvm_pgtable.h>
/* Maximum number of VMs that can co-exist under pKVM. */
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 0c1defa5fb0f..0bcd6f06aafb 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -8,6 +8,7 @@
*/
#include <linux/bitfield.h>
+#include <linux/kvm_host.h>
#include <asm/kvm_pgtable.h>
#include <asm/stage2_pgtable.h>
--
2.43.0
^ permalink raw reply related
* [PATCH v2 12/16] drm/tidss: oldi: Convert OLDI to an aux driver
From: Tomi Valkeinen @ 2026-05-13 13:17 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen
In-Reply-To: <20260513-beagley-ai-display-v2-0-9e9bcefde6bc@ideasonboard.com>
Currently in the DT, OLDI is defined in child nodes under the DSS node.
The tidss driver will parse the DT, and create DRM bridges for the
OLDIs, and there are no Linux devices for the OLDIs.
On new SoCs the OLDIs have their own power-domains which we need to
control. The cleanest way to do this in DT is to add the PDs to the OLDI
nodes. But this means the OLDI bridge code would somehow have to
manually manage the PDs, the PDs not being under a Linux device, and
there isn't much support for that kind of setup in the PD framework.
A solution to this is to convert the OLDI to an auxiliary device/driver,
created by tidss:
- At module load time the tidss module will, in addition to registering
the tidss DRM driver, register an oldi auxiliary driver.
- At probe time tidss will parse the DT, and create an auxiliary device
for each OLDI.
The aux driver will probe, and as its of_node points to the OLDI node
containing the PD, the driver framework will take care of enabling and
disabling the PD when OLDI is used ("used" as in pm_runtime context).
Tested-by: Swamil Jain <s-jain1@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/tidss/tidss_drv.c | 51 +++-
drivers/gpu/drm/tidss/tidss_drv.h | 5 +-
drivers/gpu/drm/tidss/tidss_oldi.c | 493 ++++++++++++++++++++++++++-----------
drivers/gpu/drm/tidss/tidss_oldi.h | 7 +-
4 files changed, 400 insertions(+), 156 deletions(-)
diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c
index 5cb3e746aeb3..aef945101be4 100644
--- a/drivers/gpu/drm/tidss/tidss_drv.c
+++ b/drivers/gpu/drm/tidss/tidss_drv.c
@@ -133,10 +133,6 @@ static int tidss_probe(struct platform_device *pdev)
return ret;
}
- ret = tidss_oldi_init(tidss);
- if (ret)
- return dev_err_probe(dev, ret, "failed to init OLDI\n");
-
pm_runtime_enable(dev);
pm_runtime_set_autosuspend_delay(dev, 1000);
@@ -147,24 +143,30 @@ static int tidss_probe(struct platform_device *pdev)
dispc_runtime_resume(tidss->dispc);
#endif
+ ret = tidss_oldi_create_devices(tidss);
+ if (ret) {
+ dev_err_probe(dev, ret, "failed to create OLDI devices\n");
+ goto err_runtime_suspend;
+ }
+
ret = tidss_modeset_init(tidss);
if (ret < 0) {
if (ret != -EPROBE_DEFER)
dev_err(dev, "failed to init DRM/KMS (%d)\n", ret);
- goto err_runtime_suspend;
+ goto err_destroy_oldis;
}
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
ret = irq;
- goto err_runtime_suspend;
+ goto err_destroy_oldis;
}
tidss->irq = irq;
ret = tidss_irq_install(ddev, irq);
if (ret) {
dev_err(dev, "tidss_irq_install failed: %d\n", ret);
- goto err_runtime_suspend;
+ goto err_destroy_oldis;
}
drm_kms_helper_poll_init(ddev);
@@ -194,6 +196,9 @@ static int tidss_probe(struct platform_device *pdev)
err_irq_uninstall:
tidss_irq_uninstall(ddev);
+err_destroy_oldis:
+ tidss_oldi_destroy_devices(tidss);
+
err_runtime_suspend:
#ifndef CONFIG_PM
dispc_runtime_suspend(tidss->dispc);
@@ -201,8 +206,6 @@ static int tidss_probe(struct platform_device *pdev)
pm_runtime_dont_use_autosuspend(dev);
pm_runtime_disable(dev);
- tidss_oldi_deinit(tidss);
-
return ret;
}
@@ -218,6 +221,8 @@ static void tidss_remove(struct platform_device *pdev)
tidss_irq_uninstall(ddev);
+ tidss_oldi_destroy_devices(tidss);
+
#ifndef CONFIG_PM
/* If we don't have PM, we need to call suspend manually */
dispc_runtime_suspend(tidss->dispc);
@@ -225,8 +230,6 @@ static void tidss_remove(struct platform_device *pdev)
pm_runtime_dont_use_autosuspend(dev);
pm_runtime_disable(dev);
- tidss_oldi_deinit(tidss);
-
/* devm allocated dispc goes away with the dev so mark it NULL */
dispc_remove(tidss);
@@ -262,7 +265,31 @@ static struct platform_driver tidss_platform_driver = {
},
};
-drm_module_platform_driver(tidss_platform_driver);
+static int __init tidss_platform_driver_init(void)
+{
+ int ret;
+
+ ret = tidss_oldi_register_driver();
+ if (ret)
+ return ret;
+
+ ret = drm_platform_driver_register(&tidss_platform_driver);
+ if (ret) {
+ tidss_oldi_unregister_driver();
+ return ret;
+ }
+
+ return 0;
+}
+module_init(tidss_platform_driver_init);
+
+static void __exit tidss_platform_driver_exit(void)
+{
+ platform_driver_unregister(&tidss_platform_driver);
+ tidss_oldi_unregister_driver();
+}
+module_exit(tidss_platform_driver_exit);
+
MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
MODULE_DESCRIPTION("TI Keystone DSS Driver");
diff --git a/drivers/gpu/drm/tidss/tidss_drv.h b/drivers/gpu/drm/tidss/tidss_drv.h
index e1c1f41d8b4b..d3dba639b278 100644
--- a/drivers/gpu/drm/tidss/tidss_drv.h
+++ b/drivers/gpu/drm/tidss/tidss_drv.h
@@ -16,7 +16,8 @@
#define TIDSS_MAX_OLDI_TXES 2
typedef u32 dispc_irq_t;
-struct tidss_oldi;
+
+struct auxiliary_device;
struct tidss_device {
struct drm_device ddev; /* DRM device for DSS */
@@ -34,7 +35,7 @@ struct tidss_device {
struct drm_plane *planes[TIDSS_MAX_PLANES];
unsigned int num_oldis;
- struct tidss_oldi *oldis[TIDSS_MAX_OLDI_TXES];
+ struct auxiliary_device *oldis[TIDSS_MAX_OLDI_TXES];
unsigned int irq;
diff --git a/drivers/gpu/drm/tidss/tidss_oldi.c b/drivers/gpu/drm/tidss/tidss_oldi.c
index e925ddaa4fd6..5331732ac99e 100644
--- a/drivers/gpu/drm/tidss/tidss_oldi.c
+++ b/drivers/gpu/drm/tidss/tidss_oldi.c
@@ -5,11 +5,13 @@
* Aradhya Bhatia <a-bhatia1@ti.com>
*/
+#include <linux/auxiliary_bus.h>
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/mfd/syscon.h>
#include <linux/media-bus-format.h>
+#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <drm/drm_atomic_helper.h>
@@ -20,6 +22,12 @@
#include "tidss_dispc_regs.h"
#include "tidss_oldi.h"
+static DEFINE_IDA(tidss_oldi_ida);
+
+struct tidss_oldi_platform_data {
+ struct tidss_device *tidss;
+};
+
struct tidss_oldi {
struct tidss_device *tidss;
struct device *dev;
@@ -251,6 +259,8 @@ static void tidss_oldi_atomic_pre_enable(struct drm_bridge *bridge,
if (oldi->link_type == OLDI_MODE_SECONDARY_CLONE_SINGLE_LINK)
return;
+ WARN_ON(pm_runtime_get_sync(oldi->dev) < 0);
+
connector = drm_atomic_get_new_connector_for_encoder(state,
bridge->encoder);
if (WARN_ON(!connector))
@@ -296,6 +306,8 @@ static void tidss_oldi_atomic_post_disable(struct drm_bridge *bridge,
/* Clear OLDI Config */
tidss_disable_oldi(oldi->tidss, oldi->parent_vp);
+
+ pm_runtime_put_autosuspend(oldi->dev);
}
#define MAX_INPUT_SEL_FORMATS 1
@@ -464,174 +476,375 @@ static int get_parent_dss_vp(struct device_node *oldi_tx, u32 *parent_vp)
return -ENODEV;
}
-void tidss_oldi_deinit(struct tidss_device *tidss)
-{
- for (int i = 0; i < tidss->num_oldis; i++) {
- if (tidss->oldis[i]) {
- drm_bridge_remove(&tidss->oldis[i]->bridge);
- tidss->is_ext_vp_clk[tidss->oldis[i]->parent_vp] = false;
- tidss->oldis[i] = NULL;
- }
- }
-}
-
-int tidss_oldi_init(struct tidss_device *tidss)
+static int tidss_oldi_probe(struct auxiliary_device *auxdev,
+ const struct auxiliary_device_id *id)
{
- struct tidss_oldi *oldi;
- struct device_node *child;
- struct drm_bridge *bridge;
- u32 parent_vp, oldi_instance;
- int companion_instance = -1;
+ struct device *dev = &auxdev->dev;
+ struct tidss_oldi_platform_data *oldi_pdata = dev_get_platdata(dev);
+ struct tidss_device *tidss = oldi_pdata->tidss;
+ struct device_node *node = auxdev->dev.of_node;
enum tidss_oldi_link_type link_type = OLDI_MODE_UNSUPPORTED;
- struct device_node *oldi_parent;
- int ret = 0;
-
- tidss->num_oldis = 0;
+ int companion_instance = -1;
+ struct drm_bridge *bridge;
+ struct device_link *link;
+ struct tidss_oldi *oldi;
+ u32 oldi_instance;
+ u32 parent_vp;
+ int ret;
- oldi_parent = of_get_child_by_name(tidss->dev->of_node, "oldi-transmitters");
- if (!oldi_parent)
- /* Return gracefully */
- return 0;
+ ret = of_property_read_u32(node, "reg", &oldi_instance);
+ if (ret)
+ return ret;
- for_each_available_child_of_node(oldi_parent, child) {
- ret = get_parent_dss_vp(child, &parent_vp);
- if (ret) {
- if (ret == -ENODEV) {
- /*
- * ENODEV means that this particular OLDI node
- * is not connected with the DSS, which is not
- * a harmful case. There could be another OLDI
- * which may still be connected.
- * Continue to search for that.
- */
- continue;
- }
- goto err_put_node;
- }
+ ret = get_parent_dss_vp(node, &parent_vp);
+ if (ret)
+ return ret;
- ret = of_property_read_u32(child, "reg", &oldi_instance);
- if (ret)
- goto err_put_node;
+ /*
+ * Now that it's confirmed that OLDI is connected with DSS,
+ * let's continue getting the OLDI sinks ahead and other OLDI
+ * properties.
+ */
+ bridge = devm_drm_of_get_bridge(dev, node, OLDI_OUTPUT_PORT, 0);
+ if (IS_ERR(bridge)) {
+ /*
+ * Either there was no OLDI sink in the devicetree, or the OLDI
+ * sink has not been added yet. In any case, return.
+ */
+ ret = dev_err_probe(dev, PTR_ERR(bridge),
+ "no panel/bridge for OLDI%u.\n",
+ oldi_instance);
+ goto err_put_node;
+ }
+ link_type = get_oldi_mode(node, &companion_instance);
+ if (link_type == OLDI_MODE_UNSUPPORTED) {
+ ret = dev_err_probe(dev, -EINVAL,
+ "OLDI%u: Unsupported OLDI connection.\n",
+ oldi_instance);
+ goto err_put_node;
+ } else if ((link_type == OLDI_MODE_SECONDARY_CLONE_SINGLE_LINK) ||
+ (link_type == OLDI_MODE_CLONE_SINGLE_LINK)) {
/*
- * Now that it's confirmed that OLDI is connected with DSS,
- * let's continue getting the OLDI sinks ahead and other OLDI
- * properties.
+ * The OLDI driver cannot support OLDI clone mode properly at
+ * present. The clone mode requires 2 working encoder-bridge
+ * pipelines, generating from the same crtc. The DRM framework
+ * does not support this at present. If there were to be, say, 2
+ * OLDI sink bridges each connected to an OLDI TXes, they
+ * couldn't both be supported simultaneously. This driver still
+ * has some code pertaining to OLDI clone mode configuration in
+ * DSS hardware for future, when there is a better
+ * infrastructure in the DRM framework to support 2
+ * encoder-bridge pipelines simultaneously. Till that time, this
+ * driver shall error out if it detects a clone mode
+ * configuration.
*/
- bridge = devm_drm_of_get_bridge(tidss->dev, child,
- OLDI_OUTPUT_PORT, 0);
- if (IS_ERR(bridge)) {
- /*
- * Either there was no OLDI sink in the devicetree, or
- * the OLDI sink has not been added yet. In any case,
- * return.
- * We don't want to have an OLDI node connected to DSS
- * but not to any sink.
- */
- ret = dev_err_probe(tidss->dev, PTR_ERR(bridge),
- "no panel/bridge for OLDI%u.\n",
+ ret = dev_err_probe(dev, -EOPNOTSUPP,
+ "The OLDI driver does not support Clone Mode at present.\n");
+ goto err_put_node;
+ }
+
+ oldi = devm_drm_bridge_alloc(dev, struct tidss_oldi, bridge,
+ &tidss_oldi_bridge_funcs);
+ if (IS_ERR(oldi)) {
+ ret = PTR_ERR(oldi);
+ goto err_put_node;
+ }
+
+ oldi->parent_vp = parent_vp;
+ oldi->oldi_instance = oldi_instance;
+ oldi->companion_instance = companion_instance;
+ oldi->link_type = link_type;
+ oldi->dev = dev;
+ oldi->next_bridge = bridge;
+ oldi->tidss = tidss;
+
+ auxiliary_set_drvdata(auxdev, oldi);
+
+ /*
+ * Only the primary OLDI needs to reference the io-ctrl system
+ * registers, and the serial clock.
+ * We don't require a check for secondary OLDI in dual-link mode
+ * because the driver will not create a drm_bridge instance.
+ * But the driver will need to create a drm_bridge instance,
+ * for secondary OLDI in clone mode (once it is supported).
+ */
+ if (link_type != OLDI_MODE_SECONDARY_DUAL_LINK &&
+ link_type != OLDI_MODE_SECONDARY_CLONE_SINGLE_LINK) {
+ oldi->io_ctrl = syscon_regmap_lookup_by_phandle(node,
+ "ti,oldi-io-ctrl");
+ if (IS_ERR(oldi->io_ctrl)) {
+ ret = dev_err_probe(oldi->dev, PTR_ERR(oldi->io_ctrl),
+ "OLDI%u: syscon_regmap_lookup_by_phandle failed.\n",
oldi_instance);
goto err_put_node;
}
- link_type = get_oldi_mode(child, &companion_instance);
- if (link_type == OLDI_MODE_UNSUPPORTED) {
- ret = dev_err_probe(tidss->dev, -EINVAL,
- "OLDI%u: Unsupported OLDI connection.\n",
+ oldi->serial = of_clk_get_by_name(node, "serial");
+ if (IS_ERR(oldi->serial)) {
+ ret = dev_err_probe(oldi->dev, PTR_ERR(oldi->serial),
+ "OLDI%u: Failed to get serial clock.\n",
oldi_instance);
goto err_put_node;
- } else if ((link_type == OLDI_MODE_SECONDARY_CLONE_SINGLE_LINK) ||
- (link_type == OLDI_MODE_CLONE_SINGLE_LINK)) {
- /*
- * The OLDI driver cannot support OLDI clone mode
- * properly at present.
- * The clone mode requires 2 working encoder-bridge
- * pipelines, generating from the same crtc. The DRM
- * framework does not support this at present. If
- * there were to be, say, 2 OLDI sink bridges each
- * connected to an OLDI TXes, they couldn't both be
- * supported simultaneously.
- * This driver still has some code pertaining to OLDI
- * clone mode configuration in DSS hardware for future,
- * when there is a better infrastructure in the DRM
- * framework to support 2 encoder-bridge pipelines
- * simultaneously.
- * Till that time, this driver shall error out if it
- * detects a clone mode configuration.
- */
- ret = dev_err_probe(tidss->dev, -EOPNOTSUPP,
- "The OLDI driver does not support Clone Mode at present.\n");
- goto err_put_node;
- } else if (link_type == OLDI_MODE_SECONDARY_DUAL_LINK) {
- /*
- * This is the secondary OLDI node, which serves as a
- * companion to the primary OLDI, when it is configured
- * for the dual-link mode. Since the primary OLDI will
- * be a part of bridge chain, no need to put this one
- * too. Continue onto the next OLDI node.
- */
- continue;
}
+ }
- oldi = devm_drm_bridge_alloc(tidss->dev, struct tidss_oldi, bridge,
- &tidss_oldi_bridge_funcs);
- if (IS_ERR(oldi)) {
- ret = PTR_ERR(oldi);
- goto err_put_node;
- }
+ if (link_type != OLDI_MODE_SECONDARY_DUAL_LINK) {
+ /* Register the bridge. */
+ oldi->bridge.of_node = node;
+ oldi->bridge.driver_private = oldi;
- oldi->parent_vp = parent_vp;
- oldi->oldi_instance = oldi_instance;
- oldi->companion_instance = companion_instance;
- oldi->link_type = link_type;
- oldi->dev = tidss->dev;
- oldi->next_bridge = bridge;
+ tidss->is_ext_vp_clk[oldi->parent_vp] = true;
- /*
- * Only the primary OLDI needs to reference the io-ctrl system
- * registers, and the serial clock.
- * We don't require a check for secondary OLDI in dual-link mode
- * because the driver will not create a drm_bridge instance.
- * But the driver will need to create a drm_bridge instance,
- * for secondary OLDI in clone mode (once it is supported).
- */
- if (link_type != OLDI_MODE_SECONDARY_CLONE_SINGLE_LINK) {
- oldi->io_ctrl = syscon_regmap_lookup_by_phandle(child,
- "ti,oldi-io-ctrl");
- if (IS_ERR(oldi->io_ctrl)) {
- ret = dev_err_probe(oldi->dev, PTR_ERR(oldi->io_ctrl),
- "OLDI%u: syscon_regmap_lookup_by_phandle failed.\n",
- oldi_instance);
- goto err_put_node;
- }
+ drm_bridge_add(&oldi->bridge);
+ }
+
+ link = device_link_add(&auxdev->dev, tidss->dev,
+ DL_FLAG_PM_RUNTIME |
+ DL_FLAG_AUTOREMOVE_CONSUMER);
+ if (!link) {
+ ret = -EINVAL;
+ goto err_bridge_remove;
+ }
+
+ pm_runtime_enable(dev);
+ pm_runtime_set_autosuspend_delay(dev, 500);
+ pm_runtime_use_autosuspend(dev);
+
+ return 0;
+
+err_bridge_remove:
+ if (link_type != OLDI_MODE_SECONDARY_DUAL_LINK) {
+ drm_bridge_remove(&oldi->bridge);
+ tidss->is_ext_vp_clk[oldi->parent_vp] = false;
+ }
+
+err_put_node:
+ return ret;
+}
+
+static void tidss_oldi_remove(struct auxiliary_device *auxdev)
+{
+ struct tidss_oldi *oldi = auxiliary_get_drvdata(auxdev);
+ struct tidss_device *tidss = oldi->tidss;
+ struct device *dev = &auxdev->dev;
+
+ pm_runtime_dont_use_autosuspend(dev);
+ pm_runtime_disable(dev);
+
+ if (oldi->link_type != OLDI_MODE_SECONDARY_DUAL_LINK) {
+ drm_bridge_remove(&oldi->bridge);
- oldi->serial = of_clk_get_by_name(child, "serial");
- if (IS_ERR(oldi->serial)) {
- ret = dev_err_probe(oldi->dev, PTR_ERR(oldi->serial),
- "OLDI%u: Failed to get serial clock.\n",
- oldi_instance);
- goto err_put_node;
+ tidss->is_ext_vp_clk[oldi->parent_vp] = false;
+ }
+}
+
+static const struct auxiliary_device_id tidss_oldi_aux_id_table[] = {
+ { .name = "tidss.oldi" },
+ {}
+};
+
+static struct auxiliary_driver oldi_aux_driver = {
+ .name = "oldi",
+ .probe = tidss_oldi_probe,
+ .remove = tidss_oldi_remove,
+ .id_table = tidss_oldi_aux_id_table,
+};
+
+static void tidss_oldi_aux_device_release(struct device *dev)
+{
+ struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
+
+ ida_free(&tidss_oldi_ida, auxdev->id);
+
+ of_node_put(auxdev->dev.of_node);
+
+ kfree(auxdev->dev.platform_data);
+ kfree(auxdev);
+}
+
+static struct auxiliary_device *
+tidss_oldi_create_device(struct tidss_device *tidss,
+ struct device_node *oldi_tx)
+{
+ struct tidss_oldi_platform_data *oldi_pdata;
+ struct auxiliary_device *companion_auxdev;
+ struct auxiliary_device *auxdev;
+ u32 oldi_aux_id;
+ int ret;
+
+ /*
+ * Allocate the ID first, so that we get a lower ID for the primary
+ * OLDI, instead of the companion grabbing it in the call below. Note
+ * that the ID allocated here often matches the OLDI hardware index,
+ * but not always.
+ * The OLDI hardware index cannot be used as an ID, as, say, OLDI 1 on
+ * two DSS instances would produce the exact same device name
+ * ("tidss.oldi.1").
+ */
+ ret = ida_alloc(&tidss_oldi_ida, GFP_KERNEL);
+ if (ret < 0)
+ return ERR_PTR(ret);
+
+ oldi_aux_id = ret;
+
+ companion_auxdev = NULL;
+
+ /*
+ * If this is the primary OLDI and there is a companion, create the
+ * auxdev for the secondary OLDI first, as the secondary will act as
+ * a supplier for the primary OLDI.
+ */
+ if (!of_property_read_bool(oldi_tx, "ti,secondary-oldi")) {
+ struct device_node *companion_node;
+
+ companion_node = of_parse_phandle(oldi_tx, "ti,companion-oldi", 0);
+ if (companion_node) {
+ companion_auxdev =
+ tidss_oldi_create_device(tidss, companion_node);
+
+ of_node_put(companion_node);
+
+ if (IS_ERR(companion_auxdev)) {
+ dev_err(tidss->dev,
+ "Failed to create secondary oldi device\n");
+ ret = PTR_ERR(companion_auxdev);
+ goto err_free_ida;
}
}
+ }
- /* Register the bridge. */
- oldi->bridge.of_node = child;
- oldi->bridge.driver_private = oldi;
+ oldi_pdata = kzalloc_obj(*oldi_pdata);
+ if (!oldi_pdata) {
+ ret = -ENOMEM;
+ goto err_free_ida;
+ }
- tidss->oldis[tidss->num_oldis++] = oldi;
- tidss->is_ext_vp_clk[oldi->parent_vp] = true;
- oldi->tidss = tidss;
+ oldi_pdata->tidss = tidss;
- drm_bridge_add(&oldi->bridge);
+ auxdev = kzalloc_obj(*auxdev);
+ if (!auxdev) {
+ ret = -ENOMEM;
+ goto err_free_pdata;
+ }
+
+ *auxdev = (struct auxiliary_device) {
+ .name = "oldi",
+ .id = oldi_aux_id,
+ .dev = {
+ .parent = tidss->dev,
+ .of_node = of_node_get(oldi_tx),
+ .release = tidss_oldi_aux_device_release,
+ .platform_data = oldi_pdata,
+ },
+ };
+
+ ret = auxiliary_device_init(auxdev);
+ if (ret) {
+ dev_err(tidss->dev, "OLDI auxiliary_device_init failed: %d\n",
+ ret);
+ goto err_free_auxdev;
+ }
+
+ /*
+ * Create a device-link between the primary and the secondary, so that
+ * the secondary will be powered on when the primary is used.
+ */
+ if (companion_auxdev) {
+ struct device_link *link;
+
+ link = device_link_add(&auxdev->dev, &companion_auxdev->dev,
+ DL_FLAG_PM_RUNTIME |
+ DL_FLAG_AUTOREMOVE_CONSUMER |
+ DL_FLAG_AUTOREMOVE_SUPPLIER);
+ if (!link) {
+ dev_err(tidss->dev,
+ "device_link_add failed between primary and secondary OLDI\n");
+ ret = -EINVAL;
+ goto err_uninit_auxdev;
+ }
+ }
+
+ ret = auxiliary_device_add(auxdev);
+ if (ret) {
+ dev_err(tidss->dev, "OLDI auxiliary_device_add failed: %d\n",
+ ret);
+ goto err_uninit_auxdev;
}
- of_node_put(child);
- of_node_put(oldi_parent);
+ tidss->oldis[tidss->num_oldis++] = auxdev;
+
+ return auxdev;
+
+err_uninit_auxdev:
+ auxiliary_device_uninit(auxdev);
+ /* return here, as the rest are done in auxdev's release */
+ return ERR_PTR(ret);
+
+err_free_auxdev:
+ kfree(auxdev);
+err_free_pdata:
+ kfree(oldi_pdata);
+err_free_ida:
+ ida_free(&tidss_oldi_ida, oldi_aux_id);
+
+ return ERR_PTR(ret);
+}
+
+int tidss_oldi_create_devices(struct tidss_device *tidss)
+{
+ struct device_node *oldi_txes;
+ struct device_node *oldi_tx;
+ int ret;
+
+ oldi_txes = of_get_child_by_name(tidss->dev->of_node,
+ "oldi-transmitters");
+ if (!oldi_txes)
+ return 0;
+
+ /*
+ * Look for primary OLDIs and create devices for them. For dual-link
+ * cases, the primary's create_device call will also create the
+ * secondary device.
+ */
+ for_each_available_child_of_node(oldi_txes, oldi_tx) {
+ struct auxiliary_device *auxdev;
+
+ if (of_property_read_bool(oldi_tx, "ti,secondary-oldi"))
+ continue;
+
+ auxdev = tidss_oldi_create_device(tidss, oldi_tx);
+ if (IS_ERR(auxdev)) {
+ ret = PTR_ERR(auxdev);
+ goto err_destroy_oldis;
+ }
+ }
+
+ of_node_put(oldi_txes);
return 0;
-err_put_node:
- of_node_put(child);
- of_node_put(oldi_parent);
+err_destroy_oldis:
+ tidss_oldi_destroy_devices(tidss);
+
+ of_node_put(oldi_tx);
+ of_node_put(oldi_txes);
+
return ret;
}
+
+void tidss_oldi_destroy_devices(struct tidss_device *tidss)
+{
+ for (unsigned int i = 0; i < tidss->num_oldis; ++i)
+ auxiliary_device_destroy(tidss->oldis[i]);
+}
+
+int tidss_oldi_register_driver(void)
+{
+ return auxiliary_driver_register(&oldi_aux_driver);
+}
+
+void tidss_oldi_unregister_driver(void)
+{
+ auxiliary_driver_unregister(&oldi_aux_driver);
+}
diff --git a/drivers/gpu/drm/tidss/tidss_oldi.h b/drivers/gpu/drm/tidss/tidss_oldi.h
index a361e6dbfce3..2069bd46aaae 100644
--- a/drivers/gpu/drm/tidss/tidss_oldi.h
+++ b/drivers/gpu/drm/tidss/tidss_oldi.h
@@ -36,7 +36,10 @@ enum tidss_oldi_link_type {
OLDI_MODE_SECONDARY_DUAL_LINK,
};
-int tidss_oldi_init(struct tidss_device *tidss);
-void tidss_oldi_deinit(struct tidss_device *tidss);
+int tidss_oldi_create_devices(struct tidss_device *tidss);
+void tidss_oldi_destroy_devices(struct tidss_device *tidss);
+
+int tidss_oldi_register_driver(void);
+void tidss_oldi_unregister_driver(void);
#endif /* __TIDSS_OLDI_H__ */
--
2.43.0
^ permalink raw reply related
* [PATCH v2 16/16] arm64: dts: ti: beagley-ai: Enable HDMI display and audio
From: Tomi Valkeinen @ 2026-05-13 13:17 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen, Andrew Davis, Robert Nelson
In-Reply-To: <20260513-beagley-ai-display-v2-0-9e9bcefde6bc@ideasonboard.com>
From: Andrew Davis <afd@ti.com>
Enable HDMI support for BeagleY-AI platform. The display controller used is
TIDSS and the HDMI bridge used is IT66122.
Based on DT by: Robert Nelson <robertcnelson@gmail.com>
Signed-off-by: Andrew Davis <afd@ti.com>
Signed-off-by: Swamil Jain <s-jain1@ti.com>
[tomi.valkeinen: cosmetic fixes]
Tested-by: Robert Nelson <robertcnelson@gmail.com>
Tested-by: Swamil Jain <s-jain1@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts | 197 +++++++++++++++++++++++++
1 file changed, 197 insertions(+)
diff --git a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts
index 5255e04b9ac7..b7bcc90005d7 100644
--- a/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts
+++ b/arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts
@@ -146,6 +146,34 @@ led-1 {
default-state = "on";
};
};
+
+ hdmi0: connector-hdmi {
+ compatible = "hdmi-connector";
+ label = "hdmi";
+ type = "d";
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&it66122_out>;
+ };
+ };
+ };
+
+ sound0: sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "it66122 HDMI";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,bitclock-master = <&hdmi_dailink_master>;
+ simple-audio-card,frame-master = <&hdmi_dailink_master>;
+
+ hdmi_dailink_master: simple-audio-card,cpu {
+ sound-dai = <&mcasp1>;
+ system-clock-direction-out;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&it66122>;
+ };
+ };
};
&main_pmx0 {
@@ -185,6 +213,20 @@ J722S_IOPAD(0x0240, PIN_INPUT, 7) /* (B24) MMC1_SDCD.GPIO1_48 */
bootph-all;
};
+ main_i2c1_pins_default: main-i2c1-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x01e8, PIN_INPUT_PULLUP, 0) /* (C24) I2C1_SCL */
+ J722S_IOPAD(0x01ec, PIN_INPUT_PULLUP, 0) /* (A22) I2C1_SDA */
+ >;
+ bootph-all;
+ };
+
+ main_gpio0_ioexp_intr_pins_default: main-gpio0-ioexp-intr-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x0110, PIN_INPUT, 7) /* (G27) MMC2_DAT1.GPIO0_67 */
+ >;
+ };
+
mdio_pins_default: mdio-default-pins {
pinctrl-single,pins = <
J722S_IOPAD(0x0160, PIN_OUTPUT, 0) /* (AC24) MDIO0_MDC */
@@ -227,6 +269,47 @@ vdd_3v3_sd_pins_default: vdd-3v3-sd-default-pins {
J722S_IOPAD(0x0254, PIN_OUTPUT, 7) /* (E25) USB0_DRVVBUS.GPIO1_50 */
>;
};
+
+ dss1_pins_default: dss1-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x0100, PIN_OUTPUT, 0) /* (AB23) VOUT0_VSYNC */
+ J722S_IOPAD(0x00f8, PIN_OUTPUT, 0) /* (AB24) VOUT0_HSYNC */
+ J722S_IOPAD(0x0104, PIN_OUTPUT, 0) /* (AC26) VOUT0_PCLK */
+ J722S_IOPAD(0x00fc, PIN_OUTPUT, 0) /* (AC27) VOUT0_DE */
+ J722S_IOPAD(0x00b8, PIN_OUTPUT, 0) /* (W27) VOUT0_DATA0 */
+ J722S_IOPAD(0x00bc, PIN_OUTPUT, 0) /* (W25) VOUT0_DATA1 */
+ J722S_IOPAD(0x00c0, PIN_OUTPUT, 0) /* (W24) VOUT0_DATA2 */
+ J722S_IOPAD(0x00c4, PIN_OUTPUT, 0) /* (W23) VOUT0_DATA3 */
+ J722S_IOPAD(0x00c8, PIN_OUTPUT, 0) /* (W22) VOUT0_DATA4 */
+ J722S_IOPAD(0x00cc, PIN_OUTPUT, 0) /* (W21) VOUT0_DATA5 */
+ J722S_IOPAD(0x00d0, PIN_OUTPUT, 0) /* (Y26) VOUT0_DATA6 */
+ J722S_IOPAD(0x00d4, PIN_OUTPUT, 0) /* (Y27) VOUT0_DATA7 */
+ J722S_IOPAD(0x00d8, PIN_OUTPUT, 0) /* (AA24) VOUT0_DATA8 */
+ J722S_IOPAD(0x00dc, PIN_OUTPUT, 0) /* (AA27) VOUT0_DATA9 */
+ J722S_IOPAD(0x00e0, PIN_OUTPUT, 0) /* (AA25) VOUT0_DATA10 */
+ J722S_IOPAD(0x00e4, PIN_OUTPUT, 0) /* (AB25) VOUT0_DATA11 */
+ J722S_IOPAD(0x00e8, PIN_OUTPUT, 0) /* (AA23) VOUT0_DATA12 */
+ J722S_IOPAD(0x00ec, PIN_OUTPUT, 0) /* (AA22) VOUT0_DATA13 */
+ J722S_IOPAD(0x00f0, PIN_OUTPUT, 0) /* (AB26) VOUT0_DATA14 */
+ J722S_IOPAD(0x00f4, PIN_OUTPUT, 0) /* (AB27) VOUT0_DATA15 */
+ J722S_IOPAD(0x005c, PIN_OUTPUT, 1) /* (AC25) GPMC0_AD8.VOUT0_DATA16 */
+ J722S_IOPAD(0x0060, PIN_OUTPUT, 1) /* (U26) GPMC0_AD9.VOUT0_DATA17 */
+ J722S_IOPAD(0x0064, PIN_OUTPUT, 1) /* (V27) GPMC0_AD10.VOUT0_DATA18 */
+ J722S_IOPAD(0x0068, PIN_OUTPUT, 1) /* (V25) GPMC0_AD11.VOUT0_DATA19 */
+ J722S_IOPAD(0x006c, PIN_OUTPUT, 1) /* (V26) GPMC0_AD12.VOUT0_DATA20 */
+ J722S_IOPAD(0x0070, PIN_OUTPUT, 1) /* (V24) GPMC0_AD13.VOUT0_DATA21 */
+ J722S_IOPAD(0x0074, PIN_OUTPUT, 1) /* (V22) GPMC0_AD14.VOUT0_DATA22 */
+ J722S_IOPAD(0x0078, PIN_OUTPUT, 1) /* (V23) GPMC0_AD15.VOUT0_DATA23 */
+ >;
+ };
+
+ main_mcasp1_pins_default: main-mcasp1-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x0090, PIN_INPUT, 2) /* (P27) GPMC0_BE0n_CLE.MCASP1_ACLKX */
+ J722S_IOPAD(0x0098, PIN_INPUT, 2) /* (V21) GPMC0_WAIT0.MCASP1_AFSX */
+ J722S_IOPAD(0x008c, PIN_INPUT, 2) /* (N23) GPMC0_WEn.MCASP1_AXR0 */
+ >;
+ };
};
&cpsw3g {
@@ -284,6 +367,13 @@ J722S_MCU_IOPAD(0x050, PIN_INPUT_PULLUP, 0) /* (C6) WKUP_I2C1_SDA */
>;
bootph-all;
};
+
+ hdmi_gpio_pins_default: hdmi-gpio-default-pins {
+ pinctrl-single,pins = <
+ J722S_MCU_IOPAD(0x0038, PIN_INPUT_PULLUP | PIN_DEBOUNCE_CONF6, 7) /* (D8) MCU_MCAN0_RX.MCU_GPIO0_14 HDMI_INTn */
+ J722S_MCU_IOPAD(0x0034, PIN_OUTPUT_PULLUP, 7) /* (B2) MCU_MCAN0_TX.MCU_GPIO0_13 HDMI_RSTn */
+ >;
+ };
};
&wkup_uart0 {
@@ -385,6 +475,63 @@ rtc: rtc@68 {
};
};
+&main_i2c1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c1_pins_default>;
+ clock-frequency = <400000>;
+ bootph-all;
+
+ it66122: bridge-hdmi@4c {
+ compatible = "ite,it66122";
+ reg = <0x4c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_gpio_pins_default>;
+ vcn33-supply = <&vdd_3v3>;
+ vcn18-supply = <&buck2_reg>;
+ vrf12-supply = <&ldo2_reg>;
+ reset-gpios = <&mcu_gpio0 13 GPIO_ACTIVE_LOW>;
+ interrupt-parent = <&mcu_gpio0>;
+ interrupts = <14 IRQ_TYPE_EDGE_FALLING>;
+ #sound-dai-cells = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /*
+ * HDMI can be serviced with 3 potential VPs -
+ * (DSS0 VP1 / DSS1 VP0 / DSS1 VP1).
+ * For now, we will service it with DSS1 VP1.
+ */
+ port@0 {
+ reg = <0>;
+
+ it66122_in: endpoint {
+ bus-width = <24>;
+ remote-endpoint = <&dss1_dpi0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ it66122_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+ };
+ };
+ };
+};
+
+&main_gpio0 {
+ status = "okay";
+};
+
+&mcu_gpio0 {
+ status = "okay";
+};
+
&sdhci1 {
/* SD/MMC */
vmmc-supply = <&vdd_mmc1>;
@@ -399,4 +546,54 @@ &sdhci1 {
status = "okay";
};
+&dss1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss1_pins_default>;
+
+ clocks = <&k3_clks 232 8>,
+ <&k3_clks 232 0>,
+ <&k3_clks 232 4>;
+
+ assigned-clocks = <&k3_clks 241 0>, /* DSS1-VP0 */
+ <&k3_clks 240 0>, /* DSS1-VP1 */
+ <&k3_clks 245 0>; /* DPI Output */
+
+ assigned-clock-parents = <&k3_clks 241 2>, /* PLL 17 HDMI */
+ <&k3_clks 240 1>, /* PLL 18 DSI */
+ <&k3_clks 245 2>; /* DSS1-DPI0 */
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* DSS1-VP1: DPI/HDMI Output */
+ port@0 {
+ reg = <0>;
+
+ dss1_dpi0_out: endpoint {
+ remote-endpoint = <&it66122_in>;
+ };
+ };
+ };
+};
+
+&mcasp1 {
+ status = "okay";
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcasp1_pins_default>;
+ auxclk-fs-ratio = <2177>;
+ op-mode = <0>; /* MCASP_IIS_MODE */
+ tdm-slots = <2>;
+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
+ 1 0 0 0
+ 0 0 0 0
+ 0 0 0 0
+ 0 0 0 0
+ >;
+ tx-num-evt = <32>;
+ rx-num-evt = <32>;
+};
+
#include "k3-j722s-ti-ipc-firmware.dtsi"
--
2.43.0
^ permalink raw reply related
* [PATCH v2 15/16] arm64: dts: ti: k3-am62p-j722s-common-main: Add support for DSS
From: Tomi Valkeinen @ 2026-05-13 13:17 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen, Jayesh Choudhary, Aradhya Bhatia
In-Reply-To: <20260513-beagley-ai-display-v2-0-9e9bcefde6bc@ideasonboard.com>
From: Jayesh Choudhary <j-choudhary@ti.com>
TI's AM62P and J722S SoCs support 2 display subsystems (DSS), DSS0 and
DSS1, each with two video ports (VP) and two video planes. The outputs
from the DSS VPs can be routed to two OLDI TXes (OLDI0, OLDI1), a DSI
TX, or parallel DPI output.
DSS0 supports:
- VP0: OLDI0 in single-link mode or OLDI0 and OLDI1 in dual-link or
clone mode.
- VP1: DPI
DSS1 supports:
- VP0: OLDI1 in single-link mode, or DPI
- VP1: DPI or DSI
The DSI is only connected to VP1 of DSS1, but OLDI and DPI are shared
between the DSS instances. Thus only a single VP can output to DPI, and
a single VP can use an OLDI block. Note that in single-link
configuration OLDI0 can be used by DSS0, and at the same time OLDI1 can
be used by DSS1.
Add the necessary nodes to k3-am62p-j722s-common-main.dtsi, including
DSS0, DSS1, OLDI0, OLDI1, DPHY and DSI.
An important note about OLDIs:
We have two OLDI hardware blocks. Each OLDI has certain configuration
that has to be done before it can be used. The OLDI blocks get this
configuration directly from the DSS block, via DSS registers. However,
as a single OLDI block can be used either with DSS0 or DSS1, the
source for the configuration changes according to (probably, this is
unclear) a DSS related clock mux.
So, afaics, when thinking about Linux device hierarchy wrt. control
busses, OLDI blocks are children of DSS blocks, and they reside in a
special DSS bus. And the OLDI parent changes according to the mux. As
far as I know, there is no way we can represent this in the DT.
Thus the solution used here (and in the driver) is that each DSS node
contains the OLDI nodes that can be used with that DSS. Thus the DSS0
node has two child nodes, OLDI0 and OLDI1, and the DSS1 node has one
child node, OLDI1. The OLDI1 nodes thus refer to the same piece of
hardware, and they cannot be used at the same time. The selection which
OLDI nodes to use are chosen in the board dts files, so assuming the dts
files are correct, no resource conflict can happen.
This is not a very nice solution, but the hardware doesn't make it easy
to have a clean solution, and, most importantly, this works.
[j-choudhary@ti.com: Refactor changes for k3-am62p-j722s-common-main.dtsi
and add changes for new OLDI driver support]
Signed-off-by: Aradhya Bhatia <a-bhatia1@ti.com>
Signed-off-by: Jayesh Choudhary <j-choudhary@ti.com>
Signed-off-by: Swamil Jain <s-jain1@ti.com>
[tomi.valkeinen: various fixes and improvements]
Tested-by: Swamil Jain <s-jain1@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
.../boot/dts/ti/k3-am62p-j722s-common-main.dtsi | 109 +++++++++++++++++++++
arch/arm64/boot/dts/ti/k3-am62p.dtsi | 16 +++
arch/arm64/boot/dts/ti/k3-j722s.dtsi | 16 +++
3 files changed, 141 insertions(+)
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 41067f2f1425..6bdd7e7a8cee 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
@@ -64,6 +64,11 @@ audio_refclk1: clock-controller@82e4 {
#clock-cells = <0>;
};
+ dss_oldi_io_ctrl: dss-oldi-io-ctrl@8600 {
+ compatible = "ti,am625-dss-oldi-io-ctrl", "syscon";
+ reg = <0x8600 0x200>;
+ };
+
phy_gmii_sel: phy@4044 {
compatible = "ti,am654-phy-gmii-sel";
reg = <0x4044 0x8>;
@@ -1110,6 +1115,110 @@ dphy0: phy@30110000 {
status = "disabled";
};
+ dss0: dss@30200000 {
+ compatible = "ti,am62p-dss";
+ reg = <0x00 0x30200000 0x00 0x1000>, /* common */
+ <0x00 0x30202000 0x00 0x1000>, /* vidl1 */
+ <0x00 0x30206000 0x00 0x1000>, /* vid */
+ <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
+ <0x00 0x30208000 0x00 0x1000>, /* ovr2 */
+ <0x00 0x3020a000 0x00 0x1000>, /* vp1: Used for OLDI */
+ <0x00 0x3020b000 0x00 0x1000>, /* vp2: Used as DPI */
+ <0x00 0x30201000 0x00 0x1000>; /* common1 */
+ reg-names = "common", "vidl1", "vid",
+ "ovr1", "ovr2", "vp1", "vp2", "common1";
+ power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>; /* DSS0 */
+ clocks = <&k3_clks 186 6>,
+ <&dss0_vp1_clk>,
+ <&k3_clks 186 2>;
+ clock-names = "fck", "vp1", "vp2";
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ ti,dpi-io-ctrl = <&main_conf 0x8300>;
+ status = "disabled";
+
+ oldi-transmitters {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dss0_oldi0: oldi@0 {
+ reg = <0>;
+ clocks = <&k3_clks 186 0>;
+ clock-names = "serial";
+ ti,oldi-io-ctrl = <&dss_oldi_io_ctrl>;
+ status = "disabled";
+ power-domains = <&k3_pds 243 TI_SCI_PD_EXCLUSIVE>; /* OLDI0_VD */
+ };
+
+ dss0_oldi1: oldi@1 {
+ reg = <1>;
+ status = "disabled";
+ power-domains = <&k3_pds 244 TI_SCI_PD_EXCLUSIVE>; /* OLDI1_VD */
+ };
+ };
+ };
+
+ dss1: dss@30220000 {
+ compatible = "ti,am62p-dss";
+ reg = <0x00 0x30220000 0x00 0x1000>, /* common */
+ <0x00 0x30222000 0x00 0x1000>, /* vidl1 */
+ <0x00 0x30226000 0x00 0x1000>, /* vid */
+ <0x00 0x30227000 0x00 0x1000>, /* ovr1 */
+ <0x00 0x30228000 0x00 0x1000>, /* ovr2 */
+ <0x00 0x3022a000 0x00 0x1000>, /* vp1: Used for DPI/OLDI */
+ <0x00 0x3022b000 0x00 0x1000>, /* vp2: Used DPI/DSI */
+ <0x00 0x30221000 0x00 0x1000>; /* common1 */
+ reg-names = "common", "vidl1", "vid",
+ "ovr1", "ovr2", "vp1", "vp2", "common1";
+ power-domains = <&k3_pds 232 TI_SCI_PD_EXCLUSIVE>; /* DSS1 */
+ clocks = <&k3_clks 232 8>,
+ <&dss1_vp1_clk>,
+ <&k3_clks 232 4>;
+ clock-names = "fck", "vp1", "vp2";
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ ti,dpi-io-ctrl = <&main_conf 0x8300>;
+ status = "disabled";
+
+ oldi-transmitters {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dss1_oldi1: oldi@1 {
+ reg = <1>;
+ clocks = <&k3_clks 232 0>;
+ clock-names = "serial";
+ ti,oldi-io-ctrl = <&dss_oldi_io_ctrl>;
+ status = "disabled";
+ power-domains = <&k3_pds 244 TI_SCI_PD_EXCLUSIVE>; /* OLDI1_VD */
+ };
+ };
+ };
+
+ dphy_tx0: phy@301c0000 {
+ compatible = "ti,j721e-dphy";
+ reg = <0x0 0x301c0000 0x0 0x1000>;
+ clocks = <&k3_clks 238 16>, <&k3_clks 238 1>;
+ clock-names = "psm", "pll_ref";
+ #phy-cells = <0>;
+ power-domains = <&k3_pds 238 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 238 1>;
+ assigned-clock-parents = <&k3_clks 238 2>;
+ assigned-clock-rates = <25000000>;
+ status = "disabled";
+ };
+
+ dsi0: dsi@30500000 {
+ compatible = "ti,j721e-dsi";
+ reg = <0x0 0x30500000 0x0 0x100000>, <0x0 0x30270000 0x0 0x100>;
+ clocks = <&k3_clks 231 2>, <&k3_clks 231 5>;
+ clock-names = "dsi_p_clk", "dsi_sys_clk";
+ power-domains = <&k3_pds 231 TI_SCI_PD_EXCLUSIVE>;
+ interrupt-parent = <&gic500>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&dphy_tx0>;
+ phy-names = "dphy";
+ status = "disabled";
+ };
+
vpu: video-codec@30210000 {
compatible = "ti,j721s2-wave521c", "cnm,wave521c";
reg = <0x00 0x30210000 0x00 0x10000>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62p.dtsi b/arch/arm64/boot/dts/ti/k3-am62p.dtsi
index 9d6266d6ddb8..074dc44ec049 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p.dtsi
@@ -144,6 +144,22 @@ cbass_wakeup: bus@b00000 {
};
};
+ dss0_vp1_clk: clock-divider-oldi-dss0 {
+ compatible = "fixed-factor-clock";
+ clocks = <&k3_clks 186 0>;
+ #clock-cells = <0>;
+ clock-div = <7>;
+ clock-mult = <1>;
+ };
+
+ dss1_vp1_clk: clock-divider-oldi-dss1 {
+ compatible = "fixed-factor-clock";
+ clocks = <&k3_clks 232 0>;
+ #clock-cells = <0>;
+ clock-div = <7>;
+ clock-mult = <1>;
+ };
+
#include "k3-am62p-j722s-common-thermal.dtsi"
};
diff --git a/arch/arm64/boot/dts/ti/k3-j722s.dtsi b/arch/arm64/boot/dts/ti/k3-j722s.dtsi
index 059c65ece183..f5b74281ab3d 100644
--- a/arch/arm64/boot/dts/ti/k3-j722s.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j722s.dtsi
@@ -227,6 +227,22 @@ cbass_wakeup: bus@b00000 {
};
};
+ dss0_vp1_clk: clock-divider-oldi-dss0 {
+ compatible = "fixed-factor-clock";
+ clocks = <&k3_clks 186 0>;
+ #clock-cells = <0>;
+ clock-div = <7>;
+ clock-mult = <1>;
+ };
+
+ dss1_vp1_clk: clock-divider-oldi-dss1 {
+ compatible = "fixed-factor-clock";
+ clocks = <&k3_clks 232 0>;
+ #clock-cells = <0>;
+ clock-div = <7>;
+ clock-mult = <1>;
+ };
+
#include "k3-am62p-j722s-common-thermal.dtsi"
};
--
2.43.0
^ permalink raw reply related
* [PATCH v2 13/16] drm/tidss: Add support for AM62P display subsystem
From: Tomi Valkeinen @ 2026-05-13 13:17 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen
In-Reply-To: <20260513-beagley-ai-display-v2-0-9e9bcefde6bc@ideasonboard.com>
From: Swamil Jain <s-jain1@ti.com>
The DSS controller on TI's AM62P SoC features two instances of the TI
DSS. Each DSS instance supports two video ports, similar to the DSS
controller found on the TI AM62X SoC. This allows three independent
video streams to be supported: OLDI, DPI, and DSI.
Since the DSS instances on AM62P are architecturally similar to those
on the AM62X DSS controller, the existing dispc_am625_feats
configuration can be reused for the AM62P DSS support.
This commit adds the necessary device tree compatibility entry for
"ti,am62p-dss" in the tidss driver, pointing to dispc_am625_feats,
thereby enabling DSS support on AM62P devices.
Signed-off-by: Swamil Jain <s-jain1@ti.com>
Tested-by: Swamil Jain <s-jain1@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/tidss/tidss_drv.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c
index aef945101be4..2d056dc1c5ff 100644
--- a/drivers/gpu/drm/tidss/tidss_drv.c
+++ b/drivers/gpu/drm/tidss/tidss_drv.c
@@ -246,6 +246,7 @@ static const struct of_device_id tidss_of_table[] = {
{ .compatible = "ti,am625-dss", .data = &dispc_am625_feats, },
{ .compatible = "ti,am62a7-dss", .data = &dispc_am62a7_feats, },
{ .compatible = "ti,am62l-dss", .data = &dispc_am62l_feats, },
+ { .compatible = "ti,am62p-dss", .data = &dispc_am625_feats, },
{ .compatible = "ti,am65x-dss", .data = &dispc_am65x_feats, },
{ .compatible = "ti,j721e-dss", .data = &dispc_j721e_feats, },
{ }
--
2.43.0
^ permalink raw reply related
* [PATCH v2 09/16] drm/tidss: Add external data and sync signal edge configuration
From: Tomi Valkeinen @ 2026-05-13 13:17 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen
In-Reply-To: <20260513-beagley-ai-display-v2-0-9e9bcefde6bc@ideasonboard.com>
The DPI output pipeline in K3 SoCs contains the display subsystem (DSS)
which produces the in-SoC parallel video signal, and a DPI block which
adjusts the signal to the external MIPI DPI output.
The DSS IP has registers to configure whether the data and sync signals
are driven on rising or falling clock edge, and on some SoCs these are
automatically conveyed to the DPI block which needs that configuration
to properly output the MIPI DPI signal.
However, on some SoCs the DPI block configuration has to be done
manually, using an extra register outside the DSS, DPI0_CLK_CTRL from
MAIN_CTRL_MMR_CFG0 block, which controls the DPI block's behavior.
Add the support to get the regmap to the register via syscon, and
configure the bits before enabling the video output.
Original patch from Louis Chauvet <louis.chauvet@bootlin.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/tidss/tidss_dispc.c | 21 +++++++++++++++++++++
drivers/gpu/drm/tidss/tidss_dispc_regs.h | 4 ++++
2 files changed, 25 insertions(+)
diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c
index c21ac3f51720..92cba069ed6c 100644
--- a/drivers/gpu/drm/tidss/tidss_dispc.c
+++ b/drivers/gpu/drm/tidss/tidss_dispc.c
@@ -467,6 +467,8 @@ struct dispc_device {
const struct dispc_features *feat;
struct clk *fclk;
+ struct regmap *syscon_dpi_io_ctrl;
+ unsigned int syscon_dpi_io_ctrl_offset;
bool is_enabled;
@@ -1201,6 +1203,13 @@ void dispc_vp_prepare(struct dispc_device *dispc, u32 hw_videoport,
mode->crtc_hdisplay - 1) |
FIELD_PREP(DISPC_VP_SIZE_SCREEN_VDISPLAY_MASK,
mode->crtc_vdisplay - 1));
+
+ if (dispc->vp_data[hw_videoport].dpi_output && dispc->syscon_dpi_io_ctrl) {
+ regmap_write(dispc->syscon_dpi_io_ctrl,
+ dispc->syscon_dpi_io_ctrl_offset + 0x0,
+ (!ipc ? DPI0_CLK_CTRL_DATA_CLK_INVDIS : 0) |
+ (rf ? DPI0_CLK_CTRL_SYNC_CLK_INVDIS : 0));
+ }
}
void dispc_vp_enable(struct dispc_device *dispc, u32 hw_videoport)
@@ -2989,6 +2998,18 @@ int dispc_init(struct tidss_device *tidss)
dispc_init_errata(dispc);
+ dispc->syscon_dpi_io_ctrl =
+ syscon_regmap_lookup_by_phandle_args(tidss->dev->of_node,
+ "ti,dpi-io-ctrl", 1,
+ &dispc->syscon_dpi_io_ctrl_offset);
+
+ if (PTR_ERR(dispc->syscon_dpi_io_ctrl) == -ENODEV)
+ dispc->syscon_dpi_io_ctrl = NULL;
+ else if (IS_ERR(dispc->syscon_dpi_io_ctrl))
+ return dev_err_probe(dispc->dev,
+ PTR_ERR(dispc->syscon_dpi_io_ctrl),
+ "DISPC: syscon_regmap_lookup_by_phandle failed.\n");
+
dispc->fourccs = devm_kcalloc(dev, ARRAY_SIZE(dispc_color_formats),
sizeof(*dispc->fourccs), GFP_KERNEL);
if (!dispc->fourccs)
diff --git a/drivers/gpu/drm/tidss/tidss_dispc_regs.h b/drivers/gpu/drm/tidss/tidss_dispc_regs.h
index 382027dddce8..4cdde24d8372 100644
--- a/drivers/gpu/drm/tidss/tidss_dispc_regs.h
+++ b/drivers/gpu/drm/tidss/tidss_dispc_regs.h
@@ -333,4 +333,8 @@ enum oldi_mode_reg_val { SPWG_18 = 0, JEIDA_24 = 1, SPWG_24 = 2 };
#define AM65X_OLDI_PWRDN_TX BIT(8)
+/* Bits in the MAIN_CTRL_MMR_CFG0_DPI0_CLK_CTRL register */
+#define DPI0_CLK_CTRL_DATA_CLK_INVDIS BIT(8)
+#define DPI0_CLK_CTRL_SYNC_CLK_INVDIS BIT(9)
+
#endif /* __TIDSS_DISPC_REGS_H */
--
2.43.0
^ permalink raw reply related
* [PATCH v2 10/16] drm/tidss: Add support for DPIENABLE bit
From: Tomi Valkeinen @ 2026-05-13 13:17 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen
In-Reply-To: <20260513-beagley-ai-display-v2-0-9e9bcefde6bc@ideasonboard.com>
Many (or even all?) K3 SoCs have DSS VP_CONTROL.DPIENABLE bit described
in their documentation. This bit controls whether the DPI block is
enabled, and is set to 1 by default (i.e. DPI is enabled at HW reset).
However, in almost all SoCs the setting does not actually do anything,
and at the moment the bit is not managed by the driver.
The exception is AM62L, which does have DPIENABLE connected, and
disabling the DPI block when it is not in use provides power savings.
Let's add a new feature flag for this, 'has_vp_control_dpienable', and
implement the support. Disable DPIENABLE for all videoports at resume
time, so that it is 0 by default. Specifically enable and disable it in
dispc_vp_enable() and dispc_vp_disable() for DPI output.
Tested-by: Swamil Jain <s-jain1@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/tidss/tidss_dispc.c | 23 +++++++++++++++++++++--
drivers/gpu/drm/tidss/tidss_dispc.h | 2 ++
drivers/gpu/drm/tidss/tidss_dispc_regs.h | 1 +
3 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c
index 92cba069ed6c..82e0b3184cc4 100644
--- a/drivers/gpu/drm/tidss/tidss_dispc.c
+++ b/drivers/gpu/drm/tidss/tidss_dispc.c
@@ -442,6 +442,8 @@ const struct dispc_features dispc_am62l_feats = {
},
.vid_order = {0},
+
+ .has_vp_control_dpienable = true,
};
static const u16 *dispc_common_regmap;
@@ -1214,6 +1216,11 @@ void dispc_vp_prepare(struct dispc_device *dispc, u32 hw_videoport,
void dispc_vp_enable(struct dispc_device *dispc, u32 hw_videoport)
{
+ if (dispc->feat->has_vp_control_dpienable &&
+ dispc->vp_data[hw_videoport].dpi_output)
+ VP_REG_FLD_MOD(dispc, hw_videoport, DISPC_VP_CONTROL, 1,
+ DISPC_VP_CONTROL_DPIENABLE_MASK);
+
VP_REG_FLD_MOD(dispc, hw_videoport, DISPC_VP_CONTROL, 1,
DISPC_VP_CONTROL_ENABLE_MASK);
}
@@ -1222,6 +1229,11 @@ void dispc_vp_disable(struct dispc_device *dispc, u32 hw_videoport)
{
VP_REG_FLD_MOD(dispc, hw_videoport, DISPC_VP_CONTROL, 0,
DISPC_VP_CONTROL_ENABLE_MASK);
+
+ if (dispc->feat->has_vp_control_dpienable &&
+ dispc->vp_data[hw_videoport].dpi_output)
+ VP_REG_FLD_MOD(dispc, hw_videoport, DISPC_VP_CONTROL, 0,
+ DISPC_VP_CONTROL_DPIENABLE_MASK);
}
void dispc_vp_unprepare(struct dispc_device *dispc, u32 hw_videoport)
@@ -2445,10 +2457,17 @@ static void dispc_vp_init(struct dispc_device *dispc)
dev_dbg(dispc->dev, "%s()\n", __func__);
- /* Enable the gamma Shadow bit-field for all VPs*/
- for (i = 0; i < dispc->feat->num_vps; i++)
+ for (i = 0; i < dispc->feat->num_vps; i++) {
+ /* Enable the gamma Shadow bit-field for all VPs*/
VP_REG_FLD_MOD(dispc, i, DISPC_VP_CONFIG, 1,
DISPC_VP_CONFIG_GAMMAENABLE_MASK);
+
+ if (dispc->feat->has_vp_control_dpienable) {
+ /* Disable DPIENABLE for all VPs */
+ VP_REG_FLD_MOD(dispc, i, DISPC_VP_CONTROL, 0,
+ DISPC_VP_CONTROL_DPIENABLE_MASK);
+ }
+ }
}
static void dispc_initial_config(struct dispc_device *dispc)
diff --git a/drivers/gpu/drm/tidss/tidss_dispc.h b/drivers/gpu/drm/tidss/tidss_dispc.h
index 6f53d554259c..0fbfb86adfbf 100644
--- a/drivers/gpu/drm/tidss/tidss_dispc.h
+++ b/drivers/gpu/drm/tidss/tidss_dispc.h
@@ -92,6 +92,8 @@ struct dispc_features {
u32 num_vids;
struct dispc_vid_info vid_info[TIDSS_MAX_PLANES];
u32 vid_order[TIDSS_MAX_PLANES];
+ /* The DSS has VP_CONTROL.DPIENABLE bit */
+ bool has_vp_control_dpienable;
};
extern const struct dispc_features dispc_k2g_feats;
diff --git a/drivers/gpu/drm/tidss/tidss_dispc_regs.h b/drivers/gpu/drm/tidss/tidss_dispc_regs.h
index 4cdde24d8372..4246c72efdd5 100644
--- a/drivers/gpu/drm/tidss/tidss_dispc_regs.h
+++ b/drivers/gpu/drm/tidss/tidss_dispc_regs.h
@@ -230,6 +230,7 @@ enum dispc_common_regs {
#define DISPC_VP_CONTROL 0x4
#define DISPC_VP_CONTROL_DATALINES_MASK GENMASK(10, 8)
+#define DISPC_VP_CONTROL_DPIENABLE_MASK GENMASK(6, 6)
#define DISPC_VP_CONTROL_GOBIT_MASK GENMASK(5, 5)
#define DISPC_VP_CONTROL_ENABLE_MASK GENMASK(0, 0)
--
2.43.0
^ permalink raw reply related
* [PATCH v2 01/16] dt-bindings: display: ti: Move ti,am62l-dss binding to a new binding file
From: Tomi Valkeinen @ 2026-05-13 13:17 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen
In-Reply-To: <20260513-beagley-ai-display-v2-0-9e9bcefde6bc@ideasonboard.com>
We currently have two binding files for different TI K3 DSS versions:
ti,j721e-dss.yaml which contains bindings for the "full" DSS version,
with four planes and outputs, and ti,am65x-dss.yaml which used to
contain bindings for the "lite" DSS version, with two planes and
outputs.
ti,am62l-dss binding was added recently to the ti,am65x-dss.yaml file,
which only has a single plane and a single output. To keep with the
above "binding file per DSS model" style, and to simplify the
ti,am65x-dss.yaml file, let's move the ti,am62l-dss to a separate, new
file.
Reviewed-by: "Rob Herring (Arm)" <robh@kernel.org>
Tested-by: Swamil Jain <s-jain1@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
.../bindings/display/ti/ti,am62l-dss.yaml | 136 +++++++++++++++++++++
.../bindings/display/ti/ti,am65x-dss.yaml | 94 +++-----------
MAINTAINERS | 1 +
3 files changed, 156 insertions(+), 75 deletions(-)
diff --git a/Documentation/devicetree/bindings/display/ti/ti,am62l-dss.yaml b/Documentation/devicetree/bindings/display/ti/ti,am62l-dss.yaml
new file mode 100644
index 000000000000..ce6185dca18d
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/ti/ti,am62l-dss.yaml
@@ -0,0 +1,136 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2026 Texas Instruments Incorporated
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/ti/ti,am62l-dss.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments AM62L Display Subsystem
+
+maintainers:
+ - Tomi Valkeinen <tomi.valkeinen@ti.com>
+
+description: |
+ The AM62L display subsystem is a cut-down version of the TI Keystone
+ Display SubSystem. It has a single output port which supports DPI
+ format and a single video "lite plane" which does not support scaling.
+ The output port is routed to the SoC boundary via the DPI interface,
+ and the same DPI signals are also routed internally to the DSI Tx
+ controller present within the SoC. Due to clocking limitations only
+ one of the interfaces (DSI or DPI) can be used at a time.
+
+properties:
+ compatible:
+ const: ti,am62l-dss
+
+ reg:
+ description:
+ Addresses to each DSS memory region described in the SoC's TRM.
+ items:
+ - description: common DSS register area
+ - description: VIDL1 light video plane
+ - description: OVR1 overlay manager for vp1
+ - description: VP1 video port 1
+ - description: common1 DSS register area
+
+ reg-names:
+ items:
+ - const: common
+ - const: vidl1
+ - const: ovr1
+ - const: vp1
+ - const: common1
+
+ clocks:
+ items:
+ - description: fck DSS functional clock
+ - description: vp1 Video Port 1 pixel clock
+
+ clock-names:
+ items:
+ - const: fck
+ - const: vp1
+
+ assigned-clocks:
+ minItems: 1
+ maxItems: 2
+
+ assigned-clock-parents:
+ minItems: 1
+ maxItems: 2
+
+ interrupts:
+ maxItems: 1
+
+ power-domains:
+ maxItems: 1
+ description: phandle to the associated power domain
+
+ dma-coherent: true
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/properties/port
+ description:
+ The DSS DPI output port node from video port 1, which may be
+ connected to the external DPI pins or to the internal DSI Tx
+ controller.
+
+ required:
+ - port@0
+
+ max-memory-bandwidth:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ Input memory (from main memory to dispc) bandwidth limit in
+ bytes per second
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - clocks
+ - clock-names
+ - interrupts
+ - ports
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ bus {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ dss: dss@30200000 {
+ compatible = "ti,am62l-dss";
+ reg = <0x00 0x30200000 0x00 0x1000>, /* common */
+ <0x00 0x30202000 0x00 0x1000>, /* vidl1 */
+ <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
+ <0x00 0x3020a000 0x00 0x1000>, /* vp1 */
+ <0x00 0x30201000 0x00 0x1000>; /* common1 */
+ reg-names = "common", "vidl1", "ovr1", "vp1", "common1";
+ power-domains = <&scmi_pds 39>;
+ clocks = <&scmi_clk 162>,
+ <&scmi_clk 161>;
+ clock-names = "fck", "vp1";
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ dpi0_out: endpoint {
+ remote-endpoint = <&dsi_in>;
+ };
+ };
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
index 49a007cbcd3a..75d9640398f0 100644
--- a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
+++ b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
@@ -18,68 +18,45 @@ description: |
internally routed to 2 OLDI TXes. The second video port supports DPI
format. The first plane is full video plane with all features and the
second is a "lite plane" without scaling support.
- The AM62L display subsystem has a single output port which supports DPI
- format but it only supports single video "lite plane" which does not support
- scaling. The output port is routed to SoC boundary via DPI interface and same
- DPI signals are also routed internally to DSI Tx controller present within the
- SoC. Due to clocking limitations only one of the interface i.e. either DSI or
- DPI can be used at once.
properties:
compatible:
enum:
- ti,am625-dss
- ti,am62a7-dss
- - ti,am62l-dss
- ti,am65x-dss
reg:
description:
Addresses to each DSS memory region described in the SoC's TRM.
- oneOf:
- - items:
- - description: common DSS register area
- - description: VIDL1 light video plane
- - description: VID video plane
- - description: OVR1 overlay manager for vp1
- - description: OVR2 overlay manager for vp2
- - description: VP1 video port 1
- - description: VP2 video port 2
- - description: common1 DSS register area
- - items:
- - description: common DSS register area
- - description: VIDL1 light video plane
- - description: OVR1 overlay manager for vp1
- - description: VP1 video port 1
- - description: common1 DSS register area
+ items:
+ - description: common DSS register area
+ - description: VIDL1 light video plane
+ - description: VID video plane
+ - description: OVR1 overlay manager for vp1
+ - description: OVR2 overlay manager for vp2
+ - description: VP1 video port 1
+ - description: VP2 video port 2
+ - description: common1 DSS register area
reg-names:
- oneOf:
- - items:
- - const: common
- - const: vidl1
- - const: vid
- - const: ovr1
- - const: ovr2
- - const: vp1
- - const: vp2
- - const: common1
- - items:
- - const: common
- - const: vidl1
- - const: ovr1
- - const: vp1
- - const: common1
+ items:
+ - const: common
+ - const: vidl1
+ - const: vid
+ - const: ovr1
+ - const: ovr2
+ - const: vp1
+ - const: vp2
+ - const: common1
clocks:
- minItems: 2
items:
- description: fck DSS functional clock
- description: vp1 Video Port 1 pixel clock
- description: vp2 Video Port 2 pixel clock
clock-names:
- minItems: 2
items:
- const: fck
- const: vp1
@@ -113,8 +90,6 @@ properties:
For AM625 DSS, the internal DPI output port node from video
port 1.
For AM62A7 DSS, the port is tied off inside the SoC.
- For AM62L DSS, the DSS DPI output port node from video port 1
- or DSI Tx controller node connected to video port 1.
properties:
endpoint@0:
$ref: /schemas/graph.yaml#/properties/endpoint
@@ -189,38 +164,7 @@ allOf:
properties:
compatible:
contains:
- const: ti,am62l-dss
- then:
- properties:
- ports:
- properties:
- port@1: false
- reg:
- maxItems: 5
- reg-names:
- maxItems: 5
- clocks:
- maxItems: 2
- clock-names:
- maxItems: 2
- else:
- properties:
- reg:
- minItems: 8
- reg-names:
- minItems: 8
- clocks:
- minItems: 3
- clock-names:
- minItems: 3
-
- - if:
- properties:
- compatible:
- contains:
- enum:
- - ti,am62l-dss
- - ti,am65x-dss
+ const: ti,am65x-dss
then:
properties:
oldi-transmitters: false
diff --git a/MAINTAINERS b/MAINTAINERS
index d1cc0e12fe1f..902502e1d63c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8756,6 +8756,7 @@ L: dri-devel@lists.freedesktop.org
S: Maintained
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: Documentation/devicetree/bindings/display/ti/ti,am625-oldi.yaml
+F: Documentation/devicetree/bindings/display/ti/ti,am62l-dss.yaml
F: Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
F: Documentation/devicetree/bindings/display/ti/ti,j721e-dss.yaml
F: Documentation/devicetree/bindings/display/ti/ti,k2g-dss.yaml
--
2.43.0
^ permalink raw reply related
* [PATCH v2 06/16] drm/tidss: Remove extra pm_runtime_mark_last_busy
From: Tomi Valkeinen @ 2026-05-13 13:17 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen
In-Reply-To: <20260513-beagley-ai-display-v2-0-9e9bcefde6bc@ideasonboard.com>
pm_runtime_put_autosuspend() calls pm_runtime_mark_last_busy(), so no
need to call pm_runtime_mark_last_busy() explicitly in the driver.
Tested-by: Swamil Jain <s-jain1@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/tidss/tidss_drv.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c
index 1c8cc18bc53c..5cb3e746aeb3 100644
--- a/drivers/gpu/drm/tidss/tidss_drv.c
+++ b/drivers/gpu/drm/tidss/tidss_drv.c
@@ -42,8 +42,6 @@ void tidss_runtime_put(struct tidss_device *tidss)
{
int r;
- pm_runtime_mark_last_busy(tidss->dev);
-
r = pm_runtime_put_autosuspend(tidss->dev);
WARN_ON(r < 0);
}
--
2.43.0
^ permalink raw reply related
* [PATCH v2 07/16] drm/tidss: oldi: Remove define for unused register OLDI_LB_CTRL
From: Tomi Valkeinen @ 2026-05-13 13:17 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen
In-Reply-To: <20260513-beagley-ai-display-v2-0-9e9bcefde6bc@ideasonboard.com>
OLDI_LB_CTRL define is not used, and doesn't seem to exist at least on
some SoCs. Let's remove the define.
Tested-by: Swamil Jain <s-jain1@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/tidss/tidss_oldi.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/gpu/drm/tidss/tidss_oldi.h b/drivers/gpu/drm/tidss/tidss_oldi.h
index 8cd535c5ee65..a361e6dbfce3 100644
--- a/drivers/gpu/drm/tidss/tidss_oldi.h
+++ b/drivers/gpu/drm/tidss/tidss_oldi.h
@@ -20,7 +20,6 @@ struct tidss_oldi;
/* Register offsets */
#define OLDI_PD_CTRL 0x100
-#define OLDI_LB_CTRL 0x104
/* Power control bits */
#define OLDI_PWRDOWN_TX(n) BIT(n)
--
2.43.0
^ permalink raw reply related
* [PATCH v2 04/16] dt-bindings: display: ti,am65x-dss: Add ti,dpi-io-ctrl
From: Tomi Valkeinen @ 2026-05-13 13:17 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen
In-Reply-To: <20260513-beagley-ai-display-v2-0-9e9bcefde6bc@ideasonboard.com>
The DPI output pipeline in K3 SoCs contains the display subsystem (DSS)
which produces the in-SoC parallel video signal, and a DPI block which
adjusts the signal to the external MIPI DPI output.
The DSS IP has registers to configure whether the data and sync signals
are driven on rising or falling clock edge, and on some SoCs these are
automatically conveyed to the DPI block which needs that configuration
to properly output the MIPI DPI signal.
However, on some SoCs the DPI block configuration has to be done
manually, using an extra register outside the DSS, DPI0_CLK_CTRL in
MAIN_CTRL_MMR_CFG0 block, which controls the DPI block's behavior.
Currently the DPI0_CLK_CTRL is never written, so it's always 0, meaning
the data and sync are always driven on a rising clock edge regardless of
the DSS configuration.
Add 'ti,dpi-io-ctrl' property, which contains phandle to the
MAIN_CTRL_MMR_CFG0 block and the offset to the DPI0_CLK_CTRL register,
so that the DSS driver can configure the data and sync signals
correctly.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
.../devicetree/bindings/display/ti/ti,am65x-dss.yaml | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
index 588d72d4ec0d..902ae2122d86 100644
--- a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
+++ b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
@@ -113,6 +113,17 @@ properties:
and OLDI_CLK_IO_CTRL registers. This property is needed for OLDI
interface to work.
+ ti,dpi-io-ctrl:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ description:
+ phandle to a syscon device node containing the DPI0_CLK_CTRL register,
+ with the offset to DPI0_CLK_CTRL as an argument.
+ maxItems: 1
+ items:
+ items:
+ - description: phandle to the syscon node
+ - description: DPI0_CLK_CTRL register offset
+
max-memory-bandwidth:
$ref: /schemas/types.yaml#/definitions/uint32
description:
--
2.43.0
^ permalink raw reply related
* [PATCH v2 03/16] dt-bindings: display: ti,am625-oldi: Add optional power-domain for OLDI
From: Tomi Valkeinen @ 2026-05-13 13:17 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen
In-Reply-To: <20260513-beagley-ai-display-v2-0-9e9bcefde6bc@ideasonboard.com>
On some SoCs the OLDI blocks belong to the same power-domain as the main
DSS block, but on some more recent SoCs the OLDI blocks have a
controllable power-domain.
Add the power-domain to the DT binding.
Tested-by: Swamil Jain <s-jain1@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
Documentation/devicetree/bindings/display/ti/ti,am625-oldi.yaml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/display/ti/ti,am625-oldi.yaml b/Documentation/devicetree/bindings/display/ti/ti,am625-oldi.yaml
index 8203ec5e5bb3..5dbf1f76dd3f 100644
--- a/Documentation/devicetree/bindings/display/ti/ti,am625-oldi.yaml
+++ b/Documentation/devicetree/bindings/display/ti/ti,am625-oldi.yaml
@@ -29,6 +29,9 @@ properties:
clock-names:
const: serial
+ power-domains:
+ maxItems: 1
+
ti,companion-oldi:
$ref: /schemas/types.yaml#/definitions/phandle
description:
--
2.43.0
^ permalink raw reply related
* [PATCH v2 00/16] drm/tidss: Add BeagleY-AI display support (and some more)
From: Tomi Valkeinen @ 2026-05-13 13:17 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lee Jones, Aradhya Bhatia, Nishanth Menon, Vignesh Raghavendra,
Swamil Jain, Devarsh Thakkar, Louis Chauvet
Cc: devicetree, dri-devel, linux-kernel, linux-arm-kernel,
Tomi Valkeinen, Jayesh Choudhary, Aradhya Bhatia, Andrew Davis,
Robert Nelson
This series aims to add display support for all display interfaces on
BeagleY-AI board. More generally, it adds display support for TI AM62P,
J722S, and related SoCs, and, as a bit extra, improves AM62L's DPI
handling.
The main topics to highlight:
- The data and sync signal polarities require accessing a register
(DPI0_CLK_CTRL) in the CTRL_MMR block. This has already been discussed
e.g. in
https://lore.kernel.org/all/20250730-fix-edge-handling-v1-0-1bdfb3fe7922%40bootlin.com/.
In this series the whole CTRL_MMR ("main_conf") block is changed to a
syscon, which allows simpler access to the DPI0_CLK_CTRL register.
- The tidss OLDI support will now use auxiliary device/driver. This seems
to solve quite neatly the requirement to have a power-domain for each
OLDI. The main issue that remains is that on AM62P (and similar) we
will have three OLDI TX DT nodes, even if there are only two in the
hardware.
With this series one can use the HDMI output on BeagleY-AI. I have also
tested the DSI output with Raspberry Pi's 7" DSI display, and OLDI
output with an oscilloscope (I don't have a suitable OLDI panel).
Tomi
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
Changes in v2:
- Add Rb and Tb tags
- Drop "dt-bindings: mfd: syscon: Add ti,am625-dss-dpi0-clk-ctrl
compatible", which is now implemented with the below changes.
- New patch "dt-bindings: display: ti,am65x-dss: Add ti,dpi-io-ctrl"
- Modify "drm/tidss: Add external data and sync signal edge
configuration" to use the 'ti,dpi-io-ctrl' with offset.
- New patch "arm64: dts: ti: k3-am62p-j722s-common-main: Make main_conf
a syscon".
- Modify "arm64: dts: ti: k3-am62p-j722s-common-main: Add support for
DSS" to set 'ti,dpi-io-ctrl' properties
- Drop generic desc in DT bindings for power-domains property
- Fix pm_runtime_get_sync() return value check
- Link to v1: https://lore.kernel.org/r/20260420-beagley-ai-display-v1-0-f628543dfd14@ideasonboard.com
---
Andrew Davis (1):
arm64: dts: ti: beagley-ai: Enable HDMI display and audio
Jayesh Choudhary (1):
arm64: dts: ti: k3-am62p-j722s-common-main: Add support for DSS
Swamil Jain (1):
drm/tidss: Add support for AM62P display subsystem
Tomi Valkeinen (13):
dt-bindings: display: ti: Move ti,am62l-dss binding to a new binding file
dt-bindings: display: ti,am65x-dss: Simplify binding
dt-bindings: display: ti,am625-oldi: Add optional power-domain for OLDI
dt-bindings: display: ti,am65x-dss: Add ti,dpi-io-ctrl
dt-bindings: display: ti,am65x-dss: Add AM62P DSS
drm/tidss: Remove extra pm_runtime_mark_last_busy
drm/tidss: oldi: Remove define for unused register OLDI_LB_CTRL
drm/tidss: Add mechanism to detect DPI output
drm/tidss: Add external data and sync signal edge configuration
drm/tidss: Add support for DPIENABLE bit
drm/tidss: oldi: Fix OLDI signal polarities
drm/tidss: oldi: Convert OLDI to an aux driver
arm64: dts: ti: k3-am62p-j722s-common-main: Make main_conf a syscon
.../bindings/display/ti/ti,am625-oldi.yaml | 3 +
.../bindings/display/ti/ti,am62l-dss.yaml | 136 ++++++
.../bindings/display/ti/ti,am65x-dss.yaml | 187 +++-----
MAINTAINERS | 1 +
.../boot/dts/ti/k3-am62p-j722s-common-main.dtsi | 111 ++++-
arch/arm64/boot/dts/ti/k3-am62p.dtsi | 16 +
arch/arm64/boot/dts/ti/k3-am67a-beagley-ai.dts | 197 ++++++++
arch/arm64/boot/dts/ti/k3-j722s.dtsi | 16 +
drivers/gpu/drm/tidss/tidss_crtc.c | 10 +-
drivers/gpu/drm/tidss/tidss_crtc.h | 4 +-
drivers/gpu/drm/tidss/tidss_dispc.c | 49 +-
drivers/gpu/drm/tidss/tidss_dispc.h | 5 +-
drivers/gpu/drm/tidss/tidss_dispc_regs.h | 5 +
drivers/gpu/drm/tidss/tidss_drv.c | 54 ++-
drivers/gpu/drm/tidss/tidss_drv.h | 5 +-
drivers/gpu/drm/tidss/tidss_kms.c | 55 ++-
drivers/gpu/drm/tidss/tidss_oldi.c | 531 +++++++++++++++------
drivers/gpu/drm/tidss/tidss_oldi.h | 8 +-
18 files changed, 1104 insertions(+), 289 deletions(-)
---
base-commit: 3131ff5a117498bb4b9db3a238bb311cbf8383ce
change-id: 20260420-beagley-ai-display-d7f634cde5f4
prerequisite-message-id: <20260415110409.2577633-1-s-jain1@ti.com>
prerequisite-patch-id: 654d90f9cddec8b41e6fb1b3776a632606fef88c
Best regards,
--
Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
^ permalink raw reply
* Re: [PATCH 2/4] clk: renesas: r8a73a4: Implement ZT/ZTR trace clock on R-Mobile APE6
From: Geert Uytterhoeven @ 2026-05-13 13:15 UTC (permalink / raw)
To: Marek Vasut
Cc: linux-arm-kernel, Conor Dooley, Krzysztof Kozlowski, Magnus Damm,
Michael Turquette, Rob Herring, Stephen Boyd, devicetree,
linux-clk, linux-kernel, linux-renesas-soc
In-Reply-To: <20260502185557.93061-3-marek.vasut+renesas@mailbox.org>
Hi Marek,
On Sat, 2 May 2026 at 20:56, Marek Vasut
<marek.vasut+renesas@mailbox.org> wrote:
> Implement ZT trace bus and ZTR trace clock on the R-Mobile APE6.
>
> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Thanks for your patch!
/sys/kernel/debug/clk/clk_summary looks a bit off to me:
zt 0 0 0 208000000
ztr 0 0 0 277333334
> --- a/drivers/clk/renesas/clk-r8a73a4.c
> +++ b/drivers/clk/renesas/clk-r8a73a4.c
> @@ -43,6 +43,8 @@ static struct div4_clk div4_clks[] = {
> { "m1", CPG_FRQCRA, 4 },
> { "m2", CPG_FRQCRA, 0 },
> { "zx", CPG_FRQCRB, 12 },
> + { "ztr", CPG_FRQCRB, 16 },
20?
> + { "zt", CPG_FRQCRB, 12 },
16? (12 is zx, cfr. above).
I.e. the same shifts as on R-Mobile A1.
> { "zs", CPG_FRQCRB, 8 },
> { "hp", CPG_FRQCRB, 4 },
> { NULL, 0, 0 },
After fixing the shifts, I get:
zt 0 0 0 277333334
ztr 0 0 0 277333334
which looks much better. If you agree, I can fix this while applying.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH 4/4] ARM: dts: renesas: r8a73a4: Describe coresight on R-Mobile APE6
From: Geert Uytterhoeven @ 2026-05-13 13:13 UTC (permalink / raw)
To: Marek Vasut
Cc: linux-arm-kernel, Conor Dooley, Geert Uytterhoeven,
Krzysztof Kozlowski, Magnus Damm, Michael Turquette, Rob Herring,
Stephen Boyd, devicetree, linux-clk, linux-kernel,
linux-renesas-soc
In-Reply-To: <20260502185557.93061-5-marek.vasut+renesas@mailbox.org>
On Sat, 2 May 2026 at 20:56, Marek Vasut
<marek.vasut+renesas@mailbox.org> wrote:
> Describe coresight topology on R-Mobile APE6. Extend the current PTM node
> with connection funnel, TPIU, ETB and replicator. The coresight on this
> hardware is clocked from the ZT/ZTR trace clock.
>
> Note that only core 0 part of the topology is described, because the
> other cores are still not present in the DT.
>
> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
LGTM, so
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
i.e. will queue in renesas-devel for v7.2.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH 3/4] ARM: dts: renesas: r8a73a4: Add ZT/ZTR trace clock on R-Mobile APE6
From: Geert Uytterhoeven @ 2026-05-13 13:12 UTC (permalink / raw)
To: Marek Vasut
Cc: linux-arm-kernel, Conor Dooley, Krzysztof Kozlowski, Magnus Damm,
Michael Turquette, Rob Herring, Stephen Boyd, devicetree,
linux-clk, linux-kernel, linux-renesas-soc
In-Reply-To: <20260502185557.93061-4-marek.vasut+renesas@mailbox.org>
On Sat, 2 May 2026 at 20:56, Marek Vasut
<marek.vasut+renesas@mailbox.org> wrote:
> Add ZT trace bus and ZTR trace clock on the R-Mobile APE6.
> These clock supply the coresight tracing modules, PTM, TPIU,
> ETB and replicator. Without these clock, the coresight tracing
> can not be operated.
>
> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
i.e. will queue in renesas-devel for v7.2.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH 1/4] dt-bindings: clock: renesas,cpg-clocks: Document ZT/ZTR trace clock on R-Mobile APE6
From: Geert Uytterhoeven @ 2026-05-13 13:12 UTC (permalink / raw)
To: Marek Vasut
Cc: linux-arm-kernel, Conor Dooley, Krzysztof Kozlowski, Magnus Damm,
Michael Turquette, Rob Herring, Stephen Boyd, devicetree,
linux-clk, linux-kernel, linux-renesas-soc
In-Reply-To: <20260502185557.93061-2-marek.vasut+renesas@mailbox.org>
On Sat, 2 May 2026 at 20:56, Marek Vasut
<marek.vasut+renesas@mailbox.org> wrote:
> Document ZT trace bus and ZTR trace clock on the R-Mobile APE6.
> These clock supply the coresight tracing modules, PTM, TPIU,
> ETB and replicator. Without these clock, the coresight tracing
> can not be operated. While this does change the ABI, it does so
> by extending the existing clock-output-names, therefore if an
> old software is used with new DT, the coresight tracing parts
> will likely fail to probe, otherwise if new software is used
> with an old DT, there is no impact.
>
> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
i.e. will queue for v7.2 in a branch shared by clock and DTS.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH] Documentation: KVM: Document guest-visible compatibility expectations
From: Eric Auger @ 2026-05-13 13:03 UTC (permalink / raw)
To: Paolo Bonzini, David Woodhouse, Marc Zyngier
Cc: Jonathan Corbet, Shuah Khan, kvm, linux-doc, linux-kernel,
Sean Christopherson, Jim Mattson, Oliver Upton, Joey Gouly,
Suzuki K Poulose, Zenghui Yu, Catalin Marinas, Will Deacon,
Raghavendra Rao Ananta, Kees Cook, Arnd Bergmann,
Nathan Chancellor, linux-arm-kernel, kvmarm, linux-kselftest
In-Reply-To: <ba08dfe9-932b-40c3-9fdf-fc891d52e1d8@redhat.com>
Hi,
On 5/13/26 2:43 PM, Paolo Bonzini wrote:
> On 5/13/26 11:24, David Woodhouse wrote:
>> On Wed, 2026-05-13 at 09:42 +0100, Marc Zyngier wrote:
>>> If userspace is not a total joke, it will read all the ID registers,
>>> and configure what it wants to see, assuming it is a feature that can
>>> be configured (not everything can, because the architecture itself is
>>> not fully backward compatible).
>>>
>>> Yes, this is buggy at times, because the combinatorial explosion of
>>> CPU capabilities and supported features makes it pretty hard to test
>>> (and really nobody actually does). But overall, it works, and QEMU is
>>> growing an infrastructure to manage it in a "user friendly" way.
>>
>> Yes, that is precisely what I'm asking for. I'm prepared to deal with
>> the fact that KVM/Arm64 is not a stable and mature platform like x86
>> is, and that userspace has to find all the random changes from one
>> version to the next, and explicitly pin things down to be compatible.
>>
>> All I'm asking for is that KVM makes it *possible* to pin things down
>> to the behaviour of previously released Linux/KVM kernels.
>>
>>> But really, this isn't what David is asking. He's demanding "bug for
>>> bug" compatibility. For that, we have two possible cases:
>>
>> No, I am not asking you to meet that bar. I merely observed that x86
>> does and that it would be nice. But we are a *long* way from that.
>
> x86 doesn't do bug-for-bug compatibility, thankfully - we have quirks
> but only 11 of them, or about one per year since we started adding
> them. We only add quirks, generally speaking, when 1) we change the
> way file descriptors are initialized, 2) guests in the wild were
> relying on it, or 3) it prevends restoring state saved from an old
> kernel. Is there anything else?
>
> So you're asking something not really far from this:
>
>>> - this is a behaviour that is not allowed by the architecture: we fix
>>> it for good. We do that on every release. Some minor, some much more
>>> visible. And there is no way we will add this sort of "bring the
>>> bugs back" type of behaviours. Specially when it is really obvious
>>> that no SW can make any reasonable use of the defect. We allow
>>> userspace to keep behaving as before, but the guest will not see a
>>> non-compliant behaviour.
>
> ... where for example
> https://lore.kernel.org/kvm/e03f092dfbb7d391a6bf2797ba01e122ba080bcd.camel@infradead.org/
> is an example of a bug that "no SW can make any reasonable use of".
>
>> Marc, this is complete nonsense and you should know better.
>> Once a behaviour is present in a released version of Linux/KVM, we
>> can't just declare it "wrong" and unilaterally impose a change in
>> guest-visible behaviour on *running* guests as a side-effect of a
>> kernel upgrade.
>>
>> The criterion for *KVM* to remain compatible is "once it has been in a
>> released version of the kernel". Not "once it is in the architecture".
>
> That is *also* obviously nonsense though, isn't it (see example
> above)? The truth is in the middle, "once it is in the architecture"
> is likely too narrow but "once it is in a Linux release" is way too
> broad. And besides, both miss the point of *configurability* which is
> the basis of it all.
>
> The main difference between x86 and Arm is the default state at
> creation; x86 defaults to a blank slate, mostly; and when we didn't do
> that, we regretted it later (cue the STUFF_FEATURE_MSRS quirk). It's
> too late to change the behavior for Arm, but I think we can agree that
> patches such as
> https://lore.kernel.org/kvm/20260511113558.3325004-2-dwmw2@infradead.org/
> ("KVM: arm64: vgic: Allow userspace to set IIDR revision 1") are what
> the letter and spirit of this proposal is about.
>
> Marc did not mention having to deal with guests in the wild. Let's
> ignore it for now because even defining "guests in the wild" is hard;
> and anyway it's not related to the patch that triggered the discussion.
>
> So we have the third case, "restoring state saved from an old kernel".
> If this case arises, I do believe that Arm will have to deal with it
> and introduce quirks or KVM_GET/SET_REG hacks. Maybe it hasn't
> happened yet, lucky you.
for info, this qemu series was merged laterly.
[PATCH v10 0/7] Mitigation of "failed to load
cpu:cpreg_vmstate_array_len" migration failures <https://lore.kernel.org/all/20260420140552.104369-1-eric.auger@redhat.com/#r>
https://lore.kernel.org/all/20260420140552.104369-1-eric.auger@redhat.com/#r
It brings an infrastructure to mitigate some migration failures accross different kernel versions.
Also there is [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model, under review
https://lore.kernel.org/all/20260503073541.790215-1-eric.auger@redhat.com/
This series aims at beeing able to offer the capacity to set writable ID regs on the host passthrough vcpu model.
Thanks
Eric
>
> Overall, even if we may disagree about the details, are we really on
> terribly distant grounds, or are we not?
>
> Paolo
>
^ permalink raw reply
* Re: [PATCH RFC] printk: remove BOOT_PRINTK_DELAY
From: Petr Mladek @ 2026-05-13 13:04 UTC (permalink / raw)
To: Andrew Murray
Cc: Jonathan Corbet, Shuah Khan, Russell King, Florian Fainelli,
Ray Jui, Scott Branden, Broadcom internal kernel review list,
Steven Rostedt, John Ogness, Sergey Senozhatsky, Andrew Morton,
Sebastian Andrzej Siewior, Randy Dunlap, Clark Williams,
linux-doc, linux-kernel, linux-arm-kernel, linux-rpi-kernel,
linux-rt-devel, Linus Torvalds
In-Reply-To: <CALqELGxhXO=kzh9bpztd9=Ug9ykPL2NALo9Apq3=Oj6aeiEcKg@mail.gmail.com>
On Wed 2026-05-06 23:37:01, Andrew Murray wrote:
> On Tue, 5 May 2026 at 15:26, Petr Mladek <pmladek@suse.com> wrote:
> >
> > On Tue 2026-05-05 14:45:00, Andrew Murray wrote:
> > > The CONFIG_BOOT_PRINTK_DELAY option enables support for the boot_delay
> > > kernel parameter, this allows for a configurable delay to be added before
> > > each and every printk is emitted. This is DEBUG_KERNEL option that is
> > > helpful for debugging as kernel output can be slowed down during boot
> > > allowing messages to be seen before scrolling off the screen, or to
> > > correlate timing between some physical event and console output.
> > >
> > > However, since the introduction of nbcon and the legacy printer thread for
> > > PREEMPT_RT kernels, printk records are now emited to the console
> > > asynchronously to the caller of printk and its boot_delay. The delay added
> > > by boot_delay continues to slow down the calling process, but may not have
> > > any impact to the rate in which records are emited to the console. For
> > > example, if delay_use is set to 100ms, and the printer thread has a
> > > backlog of more than 100ms, perhaps due to a slow serial console, then the
> > > records will appear to be printed without any delay between them.
> > >
> > > It would be unhelpful to add a delay to the printer thread, and it would
> > > not be possible to disallow selection of CONFIG_BOOT_PRINTK_DELAY at build
> > > time as it's not possible to detect which consoles are nbcon enabled at
> > > build time. Therefore, let's remove this feature.
> >
> > Heh, Randy proposed to remove "boot_delay" few days ago.
> > This RFC goes even further and remove both "boot_delay" and
> > "printk_delay".
>
> Apologies, I didn't see this. I'll co-ordinate with Randy.
No need to apologize.
> > Honestly, I do not feel comfortable by this. The delay seems to
> > be handy when there is only graphical console. I would suggest
> > to do:
> >
> > 1. Obsolete "boot_delay" with "printk_delay" as
> > proposed in Randy's thread, see
> > https://lore.kernel.org/all/afn2sYKKsqG4QBVX@pathway.suse.cz/
>
> Your suggestion was:
>
> " 1. Add "printk_delay" early_param() which would allow
> to set "printk_delay_msec" via command line."
>
> And I assume the intent is to replicate the functionality of
> boot_delay, by allowing printk_delay to be used to introduce delays
> from early_param time? Thus deprecating delay_use.
Exactly.
>
> " 2. Modify boot_delay_setup() to set "printk_delay_msec" as well.
> In addition, it might print a message that it has been
> obsoleted by "printk_delay" and will be removed."
>
> Given the intent may be to deprecate boot_delay, I'm not sure that
> setting printk_delay_msec as well would be beneficial, as this would
> extend its functionality to add delays beyond SYSTEM_RUNNING which is
> where boot_delay stops. Unless you mean to use boot_delay as an alias
> to an early_param hook for printk_delay?
I do not think that this is a big problem. As you write below, it is
a debug feature. IMHO, people debugging boot problems won't mind when
the delay continues beyond SYSTEM_RUNNING. And if anyone complains
than we would at least know that there are people using this feature ;-)
> It seems that there are also differences in behavior between
> printk_delay and boot_use, with printk_delay unconditionally adding
> delays to all printks, and delay_use which considers the loglevel.
The unconditional delay does not make much sense. I consider it a bug.
> >
> > 2. Move printk_delay() from vprintk_emit() to
> > console_emit_next_record() and nbcon_emit_next_record().
> >
> > For nbcon console, even better would be to use a sleeping
> > wait in nbcon_kthread_func(). But it would need some
> > changes to call it only when a record was really emitted.
> > Also we would need to use the busy wait in
> > __nbcon_atomic_flush_pending_con().
>
> This makes sense.
>
> If the use case (in a post kthread printk thread world), is only
> relevant for graphical consoles, then I do wonder if printk_delay and
> boot_delay can be replaced with a more specific solution? Now that we
> have printk threads, the time in which a printk is presented to the
> user may not relate to when it was created, and I fear people may
> continue to debug issues that rely on that assumption.
>
> I think the most pragmatic solution for now is:
> - Move the printk delay to the point where the printk is actually
> printed (e.g. console_flush_one_record and descendants)
> - Add an early_param to allow for printk_delay_msec to be set
> - Deprecate boot_delay, by using it as an alias for setting
> printk_delay_msec, and include a user mesage that it is being
> deprecated and that it now extends to beyond boot (which could impact
> performance on non PREEMPT_RT and non nbcon systems)
Sounds good.
> - Update printk_delay function to use the appropiate mechanism to
> delay based on stage of boot and using printk_delay_msec instead of
> boot_delay.
Good point! I thought that mdelay() can be used even for the early
messages because parse_early_param() is called right before
parse_args() in start_kernel() in init/main.c.
But parse_early_param() might be called even earlier, for example,
by setup_arch in arch/x86/kernel/setup.c. And it is called before
+ tsc_early_init()
+ tsc_enable_sched_clock()
+ loops_per_jiffy = get_loops_per_jiffy()
which seems to be used by
+ mdelay()
+ udelay()
+ __const_udelay()
Anyway, it has to be done before printk_delay_msec() can be set
via an early parameter.
> If that makes sense I can fashion a patchset.
That would be great.
Best Regards,
Petr
PS: Note that I am traveling the following week so my review might
get delayed.
^ permalink raw reply
* Re: [PATCH v7 0/3] ARM: omap1: use real firmware node lookup for GPIOs on Nokia 770
From: Andreas Kemnade @ 2026-05-13 12:59 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Bartosz Golaszewski, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, Andy Shevchenko, Daniel Scally, Heikki Krogerus,
Sakari Ailus, Aaro Koskinen, Janusz Krzysztofik, Tony Lindgren,
Russell King, Dmitry Torokhov, Kevin Hilman, Arnd Bergmann,
driver-core, linux-kernel, linux-acpi, linux-arm-kernel,
linux-omap
In-Reply-To: <CAMRc=MdN9EpQVW=1Sb-9hRdt56Y5NNbskujjq2RiXhu90t0QyA@mail.gmail.com>
Hi,
On Mon, 11 May 2026 15:34:39 +0200
Bartosz Golaszewski <brgl@kernel.org> wrote:
> On Thu, Apr 30, 2026 at 9:31 AM Bartosz Golaszewski
> <bartosz.golaszewski@oss.qualcomm.com> wrote:
> >
> > This converts Nokia 770 to using real firmware node lookup for GPIOs by
> > attaching the software nodes describing GPIO controllers to their target
> > devices.
> >
> > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
> > ---
>
> Hi!
>
> Gentle ping, can this be queued now for v7.2?
>
So any objections from your side, Aaro?
Regards,
Andreas
^ permalink raw reply
* Re: [PATCH] perf arm-spe: Don't warn about the discard bit if it doesn't exist
From: Ian Rogers @ 2026-05-13 12:55 UTC (permalink / raw)
To: Leo Yan
Cc: James Clark, John Garry, Will Deacon, Mike Leach, Leo Yan,
Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Adrian Hunter, linux-arm-kernel, linux-perf-users, linux-kernel
In-Reply-To: <20260513102024.GE34802@e132581.arm.com>
On Wed, May 13, 2026 at 3:20 AM Leo Yan <leo.yan@arm.com> wrote:
>
> On Fri, Apr 10, 2026 at 12:05:12PM +0100, James Clark wrote:
> > Opening an SPE event shows a warning that doesn't concern the user:
> >
> > $ perf record -e arm_spe
> > Unknown/empty format name: discard
> >
> > Perf only wants to know if the discard bit is set for configuring the
> > event, not in response to anything the user has done. Fix it by adding
> > another helper that returns if a config bit exists without warning.
> >
> > We should probably keep the warning in evsel__get_config_val() to avoid
> > having every caller having to do it, and most format bits should never
> > be missing.
> >
> > Add a test for the new helper. Rename the parent test function to be
> > more generic rather than adding a new one as it requires a lot of
> > boilerplate.
> >
> > Signed-off-by: James Clark <james.clark@linaro.org>
>
> Reviewed-by: Leo Yan <leo.yan@arm.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Thanks,
Ian
^ permalink raw reply
* Re: [PATCH 2/2] KVM: arm64: nv: Don't save/restore FP register during a nested ERET or exception
From: Marc Zyngier @ 2026-05-13 12:49 UTC (permalink / raw)
To: Mark Rutland
Cc: kvmarm, linux-arm-kernel, kvm, Steffen Eiden, Joey Gouly,
Suzuki K Poulose, Oliver Upton, Zenghui Yu, Will Deacon,
Fuad Tabba
In-Reply-To: <agRuiKHWWn_88YzT@J2N7QTR9R3>
Hi Mark,
Thanks for looking into this.
On Wed, 13 May 2026 13:28:56 +0100,
Mark Rutland <mark.rutland@arm.com> wrote:
>
> On Tue, May 12, 2026 at 03:07:55PM +0100, Marc Zyngier wrote:
> > When switching between L1 and L2, we diligently use a non-preemptible
> > put/load sequence in order to make sure that the old state is saved,
> > while the new state is brought in. Crucially, this includes the FP
> > registers.
> >
> > However, this is a bit silly. The FP registers are completely shared
> > between the various ELs (just like the GPRs, really), and eagerly
> > save/restoring those in a non-preemptible section is just overhead.
> > Not to mention that the next access will end-up trapping, something
> > that becomes exponentially expensive as we nest deeper.
> >
> > The temptation is therefore to completely drop this save/restore thing.
> > Why is it valid to do so? By analogy, the hypervisor doesn't try to
> > poloce things between EL1 and EL0, or between EL2 and EL0. Why should
> > it do so between EL2 and EL1 (or EL2 and L2 EL0)?
> >
> > Once you admit that the FP (and by extension SVE) registers are EL-agnostic,
> > the things that matter are:
>
> s/poloce/police/ ?
That.
>
> The above is a bit flowery; it would be nice to remove the rhetorical
> questions and just state that (aside from some control registers) the
> FPSIMD/SVE/SME state is shared between exception levels and doesn't need
> to be saved/restored.
>
> How about:
>
> When switching between L1 and L2, we save the old state using
> kvm_arch_vcpu_put(), mutate the state in memory, then load the new
> state using kvm_arch_vcpu_load(). Any live FPSIMD/SVE state is saved
> and unbound, such that it can be lazily restored on a subsequent trap.
>
> The FPSIMD/SVE state is shared by exception levels, and only a handful
> of related control registers need to be changed when transitioning
> between L1 and L2. The save/restore of the common state is needless
> overhead, especially as trapping becomes exponentially more expensive
> with nesting.
>
> Avoid this overhead by leaving the common FPSIMD/SVE state live on the
> CPU, and only switching the state that is distinct for L1 and L2:
>
Sold. Do you offer a CMAAS (Commit Message As A Service)? Asking for a
friend... ;-)
> > - the trap controls: the effective values are recomputed on each entry
> > into the guest to take the EL into account and merge the L0 and L1
> > configuration if in a nested context, or directly use the L0 configuration
> > in non-nested context (see __activate_traps()).
> >
> > - the VL settings: the effective values are are also recomputed on each
> > entry into the guest (see fpsimd_lazy_switch_to_guest()).
>
> This is true for FPSIMD+SVE today. For SME, SMCR_ELx also contains other
> controls, and will need to be dealt with similarly. It might be worth
> noting that (and that ZCR_ELx could gain new controls in future).
>
Yeah. I tried not to worry too much about SME, but given that it is on
people's radar, I'll drop a comment here.
> > Since we appear to cover all bases, use the vcpu flags indicating the
> > handling of a nested ERET or exception delivery to avoid the whole FP
> > save/restore shenanigans.
> >
> > For an EL1 L3 guest where L1 and L2 have this optimisation, this
> > results in at least a 10% wall clock reduction when running an I/O
> > heavy workload, generating a high rate of nested exceptions.
> >
> > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > ---
> > arch/arm64/kvm/fpsimd.c | 8 ++++++++
> > 1 file changed, 8 insertions(+)
> >
> > diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
> > index 15e17aca1dec0..73eda0f46b127 100644
> > --- a/arch/arm64/kvm/fpsimd.c
> > +++ b/arch/arm64/kvm/fpsimd.c
> > @@ -28,6 +28,10 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
> > if (!system_supports_fpsimd())
> > return;
> >
> > + if (vcpu_get_flag(vcpu, IN_NESTED_ERET) ||
> > + vcpu_get_flag(vcpu, IN_NESTED_EXCEPTION))
> > + return;
> > +
>
> I think we need a comment as to why this is safe, with some other detail
> from the commit message. It would also be good to have asserts here to
> catch if something goes wrong.
>
> How about:
>
> /*
> * Avoid needless save/restore of the guest's common
> * FPSIMD/SVE/SME regs during transitions between L1/L2.
> *
> * These transitions only happens in a non-preemptible context
> * where the host regs have already been saved and unbound. The
> * live registers are either free or owned by the guest.
> */
> if (vcpu_get_flag(vcpu, IN_NESTED_ERET) ||
> vcpu_get_flag(vcpu, IN_NESTED_EXCEPTION) {
> WARN_ON_ONCE(host_owns_fp_regs());
> return;
> }
>
> ... ?
>
> Note: I didn't add WARN_ON_ONCE(preemptible()), since
> kvm_arch_vcpu_load_fp() should *never* be called in a preemptible
> context.
>
> > /*
> > * Ensure that any host FPSIMD/SVE/SME state is saved and unbound such
> > * that the host kernel is responsible for restoring this state upon
> > @@ -102,6 +106,10 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
> > {
> > unsigned long flags;
> >
> > + if (vcpu_get_flag(vcpu, IN_NESTED_ERET) ||
> > + vcpu_get_flag(vcpu, IN_NESTED_EXCEPTION))
> > + return;
>
> Likewise here, but we can reduce the comment, e.g.
>
> /*
> * See comment in kvm_arch_vcpu_load_fp().
> */
> if (vcpu_get_flag(vcpu, IN_NESTED_ERET) ||
> vcpu_get_flag(vcpu, IN_NESTED_EXCEPTION) {
> WARN_ON_ONCE(host_owns_fp_regs());
> return;
> }
Yup, that all looks good to me. I'll repost that next week with these
changes.
Thanks again,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply
* Re: [PATCH v4 2/8] media: dt-bindings: add rockchip rk3588 vicap
From: Rob Herring @ 2026-05-13 12:48 UTC (permalink / raw)
To: Michael Riesch
Cc: Mehdi Djait, Laurent Pinchart, Mauro Carvalho Chehab,
Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner, Kever Yang,
Jagan Teki,
Кузнецов Михаил,
Charalampos Mitrodimas, Sebastian Reichel, Nicolas Dufresne,
Collabora Kernel Team, Sakari Ailus, linux-media, devicetree,
linux-arm-kernel, linux-rockchip, linux-kernel, Conor Dooley
In-Reply-To: <20260508-rk3588-vicap-v4-2-6a6cd6f7c90b@collabora.com>
On Fri, May 08, 2026 at 09:31:45PM +0200, Michael Riesch wrote:
> Add documentation for the Rockchip RK3588 Video Capture (VICAP) unit. To
> that end, make the existing rockchip,rk3568-vicap documentation more
> general and introduce variant specific constraints.
>
> Acked-by: Conor Dooley <conor.dooley@microchip.com>
> Signed-off-by: Michael Riesch <michael.riesch@collabora.com>
> ---
> .../bindings/media/rockchip,rk3568-vicap.yaml | 187 ++++++++++++++++++---
> 1 file changed, 163 insertions(+), 24 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml b/Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml
> index 18cd0a5a5318174910e04f6ef7558c92cbfec899..897ed00c239bdfe33777a8f8474fb27fa6265e49 100644
> --- a/Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml
> +++ b/Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml
> @@ -15,9 +15,15 @@ description:
> the data from camera sensors, video decoders, or other companion ICs and
> transfers it into system main memory by AXI bus.
>
> + The Rockchip RK3588 Video Capture (VICAP) is similar to its RK3568
> + counterpart, but features six MIPI CSI-2 ports and additional connections
> + to the image signal processor (ISP) blocks.
> +
> properties:
> compatible:
> - const: rockchip,rk3568-vicap
> + enum:
> + - rockchip,rk3568-vicap
> + - rockchip,rk3588-vicap
>
> reg:
> maxItems: 1
> @@ -26,37 +32,23 @@ properties:
> maxItems: 1
>
> clocks:
> - items:
> - - description: ACLK
> - - description: HCLK
> - - description: DCLK
> - - description: ICLK
> + minItems: 4
> + maxItems: 5
>
> clock-names:
> - items:
> - - const: aclk
> - - const: hclk
> - - const: dclk
> - - const: iclk
Just keep this here and add iclk1 on the end along with 'minItems: 4'.
> + minItems: 4
> + maxItems: 5
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox