* [PATCH v3 06/20] drm/colorop: Rename __drm_colorop_state_reset()
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard
In-Reply-To: <20260424-drm-mode-config-init-v3-0-8b68d9db0d8b@kernel.org>
__drm_colorop_state_reset() is used to initialize a newly allocated
drm_colorop_state, and is being typically called by drm_colorop_reset().
Since we want to consolidate DRM objects state allocation around the
atomic_create_state callback that will only allocate and initialize a
new drm_colorop_state instance, we will need to call
__drm_colorop_state_reset() from both the reset and atomic_create paths.
To avoid any confusion, we can thus rename __drm_colorop_state_reset()
to __drm_colorop_state_init().
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/drm_colorop.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c
index 48d0b7ae3fc9..4c4d0a953e35 100644
--- a/drivers/gpu/drm/drm_colorop.c
+++ b/drivers/gpu/drm/drm_colorop.c
@@ -498,19 +498,19 @@ void drm_colorop_atomic_destroy_state(struct drm_colorop *colorop,
__drm_atomic_helper_colorop_destroy_state(state);
kfree(state);
}
/**
- * __drm_colorop_state_reset - resets colorop state to default values
+ * __drm_colorop_state_init - Initializes colorop state to default values
* @colorop_state: atomic colorop state, must not be NULL
* @colorop: colorop object, must not be NULL
*
* Initializes the newly allocated @colorop_state with default
* values. This is useful for drivers that subclass the colorop state.
*/
-static void __drm_colorop_state_reset(struct drm_colorop_state *colorop_state,
- struct drm_colorop *colorop)
+static void __drm_colorop_state_init(struct drm_colorop_state *colorop_state,
+ struct drm_colorop *colorop)
{
u64 val;
colorop_state->colorop = colorop;
colorop_state->bypass = true;
@@ -537,11 +537,11 @@ static void __drm_colorop_state_reset(struct drm_colorop_state *colorop_state,
*/
static void __drm_colorop_reset(struct drm_colorop *colorop,
struct drm_colorop_state *colorop_state)
{
if (colorop_state)
- __drm_colorop_state_reset(colorop_state, colorop);
+ __drm_colorop_state_init(colorop_state, colorop);
colorop->state = colorop_state;
}
void drm_colorop_reset(struct drm_colorop *colorop)
--
2.53.0
^ permalink raw reply related
* [PATCH v3 05/20] drm/mode-config: Document drm_private_obj exclusion from drm_mode_config_reset()
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
Laurent Pinchart
In-Reply-To: <20260424-drm-mode-config-init-v3-0-8b68d9db0d8b@kernel.org>
drm_mode_config_reset() does not reset drm_private_states by design.
This is especially significant for the DP MST and tunneling code that
expect to be preserved across a suspend/resume cycle, where
drm_mode_config_reset() is also used.
Document this expectation.
Link: https://lore.kernel.org/dri-devel/aOaQLx-7EpsHRwkH@ideak-desk/
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/drm_mode_config.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 66f7dc37b597..c33382a38191 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -187,10 +187,14 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
* @dev: drm device
*
* This functions calls all the crtc's, encoder's and connector's ->reset
* callback. Drivers can use this in e.g. their driver load or resume code to
* reset hardware and software state.
+ *
+ * Note that &drm_private_obj structures are expected to be stable across
+ * suspend/resume cycles, and drm_mode_config_reset() does not affect these
+ * structures.
*/
void drm_mode_config_reset(struct drm_device *dev)
{
struct drm_crtc *crtc;
struct drm_colorop *colorop;
--
2.53.0
^ permalink raw reply related
* [PATCH v3 03/20] drm/atomic: Drop drm_private_obj.state assignment from create_state
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard
In-Reply-To: <20260424-drm-mode-config-init-v3-0-8b68d9db0d8b@kernel.org>
The initial intent of the atomic_create_state hook was to simply
allocate a proper drm_private_state and return it, without any side
effect.
However, __drm_atomic_helper_private_obj_create_state(), which most
atomic_create_state implementations call, introduces a side effect by
setting drm_private_obj.state to the newly allocated state.
This assignment defeats the purpose, but is also redundant since
drm_atomic_private_obj_init(), the only call site for the
atomic_create_state hook, will also set this pointer to the newly
allocated state.
Drop the assignment in __drm_atomic_helper_private_obj_create_state().
Fixes: e7be39ed1716 ("drm/atomic-helper: Add private_obj atomic_create_state helper")
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/drm_atomic_state_helper.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 76746ad4a1bb..875149494b00 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -729,12 +729,10 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
void __drm_atomic_helper_private_obj_create_state(struct drm_private_obj *obj,
struct drm_private_state *state)
{
if (state)
state->obj = obj;
-
- obj->state = state;
}
EXPORT_SYMBOL(__drm_atomic_helper_private_obj_create_state);
/**
* __drm_atomic_helper_private_obj_duplicate_state - copy atomic private state
--
2.53.0
^ permalink raw reply related
* [PATCH v3 04/20] drm/atomic: Expand atomic_create_state expectations for drm_private_obj
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard
In-Reply-To: <20260424-drm-mode-config-init-v3-0-8b68d9db0d8b@kernel.org>
The atomic_create_state callback documentation for planes, CRTCs, and
connectors explicitly states the expected behaviour: the returned
state must not be assigned to the object's state pointer, and hardware
must not be touched.
The drm_private_state_funcs.atomic_create_state documentation is
missing this clarification. Add it for consistency.
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
include/drm/drm_atomic.h | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index f03cd199aee7..f7f9c6c85f3a 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -263,11 +263,14 @@ struct drm_private_state;
struct drm_private_state_funcs {
/**
* @atomic_create_state:
*
* Allocates a pristine, initialized, state for the private
- * object and returns it.
+ * object and returns it. This callback must have no side
+ * effects: in particular, the returned state must not be
+ * assigned to the object's state pointer and it must not affect
+ * the hardware state.
*
* RETURNS:
*
* A new, pristine, private state instance or an error pointer
* on failure.
--
2.53.0
^ permalink raw reply related
* [PATCH v3 02/20] drm/colorop: Fix typos in the doc
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard
In-Reply-To: <20260424-drm-mode-config-init-v3-0-8b68d9db0d8b@kernel.org>
In the documentation of drm_colorop introduced by commit cfc27680ee20
("drm/colorop: Introduce new drm_colorop mode object"), the
documentation of __drm_colorop_state_reset() and __drm_colorop_reset()
were mentioning CRTC when they really meant colorop, probably due to
copy and paste.
Fixes: cfc27680ee20 ("drm/colorop: Introduce new drm_colorop mode object")
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
drivers/gpu/drm/drm_colorop.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c
index 764d12060666..48d0b7ae3fc9 100644
--- a/drivers/gpu/drm/drm_colorop.c
+++ b/drivers/gpu/drm/drm_colorop.c
@@ -503,11 +503,11 @@ void drm_colorop_atomic_destroy_state(struct drm_colorop *colorop,
* __drm_colorop_state_reset - resets colorop state to default values
* @colorop_state: atomic colorop state, must not be NULL
* @colorop: colorop object, must not be NULL
*
* Initializes the newly allocated @colorop_state with default
- * values. This is useful for drivers that subclass the CRTC state.
+ * values. This is useful for drivers that subclass the colorop state.
*/
static void __drm_colorop_state_reset(struct drm_colorop_state *colorop_state,
struct drm_colorop *colorop)
{
u64 val;
@@ -526,14 +526,14 @@ static void __drm_colorop_state_reset(struct drm_colorop_state *colorop_state,
/**
* __drm_colorop_reset - reset state on colorop
* @colorop: drm colorop
* @colorop_state: colorop state to assign
*
- * Initializes the newly allocated @colorop_state and assigns it to
- * the &drm_crtc->state pointer of @colorop, usually required when
- * initializing the drivers or when called from the &drm_colorop_funcs.reset
- * hook.
+ * Initializes the newly allocated @colorop_state and assigns it to the
+ * &drm_colorop->state pointer of @colorop, usually required when
+ * initializing the drivers or when called from the
+ * &drm_colorop_funcs.reset hook.
*
* This is useful for drivers that subclass the colorop state.
*/
static void __drm_colorop_reset(struct drm_colorop *colorop,
struct drm_colorop_state *colorop_state)
--
2.53.0
^ permalink raw reply related
* [PATCH v3 01/20] drm/atomic: Document atomic state lifetime
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard
In-Reply-To: <20260424-drm-mode-config-init-v3-0-8b68d9db0d8b@kernel.org>
How drm_atomic_state structures and the various entity structures are
allocated and freed isn't really trivial. Document it.
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
Documentation/gpu/drm-kms.rst | 6 +++++
drivers/gpu/drm/drm_atomic.c | 55 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+)
diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
index 2292e65f044c..017c7b196ed7 100644
--- a/Documentation/gpu/drm-kms.rst
+++ b/Documentation/gpu/drm-kms.rst
@@ -280,10 +280,16 @@ structure, ordering of committing state changes to hardware is sequenced using
:c:type:`struct drm_crtc_commit <drm_crtc_commit>`.
Read on in this chapter, and also in :ref:`drm_atomic_helper` for more detailed
coverage of specific topics.
+Atomic State Lifetime
+---------------------
+
+.. kernel-doc:: drivers/gpu/drm/drm_atomic.c
+ :doc: state lifetime
+
Handling Driver Private State
-----------------------------
.. kernel-doc:: drivers/gpu/drm/drm_atomic.c
:doc: handling driver private state
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 41c57063f3b4..253a00f450b0 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -45,10 +45,65 @@
#include <drm/drm_colorop.h>
#include "drm_crtc_internal.h"
#include "drm_internal.h"
+/**
+ * DOC: state lifetime
+ *
+ * &struct drm_atomic_state represents an update to video pipeline
+ * state. Despite its confusing name, it's actually a transient object
+ * that holds a state update as a collection of pointers to individual
+ * objects' states. &struct drm_atomic_state has a much shorter lifetime
+ * than the objects' states, since it's only allocated while preparing,
+ * checking or committing the update, while object states are allocated
+ * when preparing the update and kept alive as long as they are active
+ * in the device.
+ *
+ * Their respective lifetimes are:
+ *
+ * - at reset time, the object reset implementation will allocate a new
+ * default state and will store it in the object state pointer.
+ *
+ * - whenever a new update is needed:
+ *
+ * + A new &struct drm_atomic_state is allocated using
+ * drm_atomic_state_alloc().
+ *
+ * + The current active state of affected entity is copied into this
+ * new &struct drm_atomic_state using drm_atomic_get_plane_state(),
+ * drm_atomic_get_crtc_state(), drm_atomic_get_connector_state(), or
+ * drm_atomic_get_private_obj_state(). This new state can then be
+ * modified.
+ *
+ * At that point, &struct drm_atomic_state stores three state
+ * pointers for any affected entity: the "old" and "new" states, and
+ * state_to_destroy. The old state is the state currently active in
+ * the hardware, which is either the one initialized by reset() or a
+ * newer one if a commit has been made. The new state is the state
+ * we just allocated and we might eventually commit to the hardware.
+ * The state_to_destroy points to the state we'll eventually have to
+ * free when the drm_atomic_state will be destroyed, and points to
+ * the new state for now since the old state is still the active
+ * state.
+ *
+ * + After the state is populated, it is checked. If the check is
+ * successful, the update is committed. Part of the commit is a call
+ * to drm_atomic_helper_swap_state() which will turn the new states
+ * into the active states. Doing so involves updating the object's
+ * state pointer (&drm_crtc.state or similar) to point to the new
+ * state, and state_to_destroy will now point to the old states,
+ * that used to be active but aren't anymore.
+ *
+ * + When the commit is done, and when all references to our &struct
+ * drm_atomic_state are put, drm_atomic_state_clear() runs and will
+ * free all state_to_destroy (ie. old states).
+ *
+ * + Now, we don't have any active &struct drm_atomic_state anymore,
+ * and only the entity active states remain allocated.
+ */
+
void __drm_crtc_commit_free(struct kref *kref)
{
struct drm_crtc_commit *commit =
container_of(kref, struct drm_crtc_commit, ref);
--
2.53.0
^ permalink raw reply related
* [PATCH v3 00/20] drm/atomic: Rework initial state allocation
From: Maxime Ripard @ 2026-04-24 10:18 UTC (permalink / raw)
To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
Raspberry Pi Kernel Maintenance
Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
Laurent Pinchart, Laurent Pinchart
Hi,
This series started from my work on the hardware state readout[1], and
more specifically a discussion with Thomas[2].
This series expands the work that has been merged recently to make
drm_private_obj and drm_private_state allocation a bit more consistent
and ended up creating a new atomic_create_state callback to allocate a
new state with no side effect.
The first patches document the existing behaviour and fix a few
cleanups and typos.
Then, __drm_*_state_reset() helpers are renamed to
__drm_*_state_init() to clarify that they initialize rather than
reset state, and we add the new atomic_create_state callback to
every other DRM object (planes, CRTCs, connectors, colorops).
Next, we leverage those new callbacks to create a new helper,
drm_mode_config_create_initial_state(), to create the initial state
for all the objects of a driver, and update the driver skeleton to
recommend it.
Finally, we convert the tidss driver and the bridge_connector to the
new pattern.
This was tested on a TI SK-AM62, with the tidss driver.
Let me know what you think,
Maxime
1: https://lore.kernel.org/dri-devel/20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org/
2: https://lore.kernel.org/dri-devel/5920ffe5-b6b1-484b-b320-332b9eb9db82@suse.de/
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
Changes in v3:
- Reintroduce state documentation that was dropped by accident
- Change name to drm_mode_config_create_initial_state()
- Don't call drm_mode_config_create_initial_state() in drm_dev_register
anymore
- Drop __drm_atomic_helper_*_create_state
- Improve documentation and commit messages where necessary
- Collected tags
- Link to v2: https://lore.kernel.org/r/20260320-drm-mode-config-init-v2-0-c63f1134e76c@kernel.org
Changes in v2:
- Change the _state_reset function names to _state_init
- Change the colorop too
- Various doc improvements
- Link to v1: https://lore.kernel.org/r/20260310-drm-mode-config-init-v1-0-de7397c8e1cf@kernel.org
---
Maxime Ripard (20):
drm/atomic: Document atomic state lifetime
drm/colorop: Fix typos in the doc
drm/atomic: Drop drm_private_obj.state assignment from create_state
drm/atomic: Expand atomic_create_state expectations for drm_private_obj
drm/mode-config: Document drm_private_obj exclusion from drm_mode_config_reset()
drm/colorop: Rename __drm_colorop_state_reset()
drm/colorop: Create drm_atomic_helper_colorop_create_state()
drm/atomic-state-helper: Fix __drm_atomic_helper_plane_reset() doc typo
drm/atomic-state-helper: Rename __drm_atomic_helper_plane_state_reset()
drm/plane: Add new atomic_create_state callback
drm/atomic-state-helper: Rename __drm_atomic_helper_crtc_state_reset()
drm/crtc: Add new atomic_create_state callback
drm/atomic-state-helper: Rename __drm_atomic_helper_connector_state_reset()
drm/hdmi: Rename __drm_atomic_helper_connector_hdmi_reset()
drm/connector: Add new atomic_create_state callback
drm/mode-config: Create drm_mode_config_create_initial_state()
drm/drv: Switch skeleton to drm_mode_config_create_initial_state()
drm/tidss: Switch to drm_mode_config_create_initial_state()
drm/tidss: Convert to atomic_create_state
drm/bridge_connector: Convert to atomic_create_state
Documentation/gpu/drm-kms.rst | 6 +
drivers/gpu/drm/display/drm_bridge_connector.c | 17 ++-
drivers/gpu/drm/display/drm_hdmi_state_helper.c | 13 +-
drivers/gpu/drm/drm_atomic.c | 63 +++++++++
drivers/gpu/drm/drm_atomic_state_helper.c | 136 +++++++++++++++---
drivers/gpu/drm/drm_colorop.c | 41 ++++--
drivers/gpu/drm/drm_drv.c | 4 +-
drivers/gpu/drm/drm_mode_config.c | 154 ++++++++++++++++++++-
drivers/gpu/drm/i915/display/intel_crtc.c | 2 +-
drivers/gpu/drm/i915/display/intel_plane.c | 2 +-
drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 2 +-
drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 2 +-
drivers/gpu/drm/tidss/tidss_crtc.c | 17 +--
drivers/gpu/drm/tidss/tidss_drv.c | 6 +-
drivers/gpu/drm/tidss/tidss_plane.c | 2 +-
drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +-
include/drm/display/drm_hdmi_state_helper.h | 4 +-
include/drm/drm_atomic.h | 5 +-
include/drm/drm_atomic_state_helper.h | 14 +-
include/drm/drm_colorop.h | 2 +
include/drm/drm_connector.h | 16 +++
include/drm/drm_crtc.h | 16 +++
include/drm/drm_mode_config.h | 1 +
include/drm/drm_plane.h | 16 +++
24 files changed, 476 insertions(+), 67 deletions(-)
---
base-commit: ea61048876a7137897da26dac49ee234fb38a35a
change-id: 20260310-drm-mode-config-init-1e1f52b745d0
Best regards,
--
Maxime Ripard <mripard@kernel.org>
^ permalink raw reply
* Re: [PATCH v13 2/3] pwm: Add Allwinner's D1/T113-S3/R329 SoCs PWM support
From: Uwe Kleine-König @ 2026-04-24 10:13 UTC (permalink / raw)
To: Aleksandr Shubin
Cc: linux-kernel, Brandon Cheo Fusi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Philipp Zabel, Lukas Schmid, linux-pwm, devicetree,
linux-arm-kernel, linux-sunxi, linux-riscv
In-Reply-To: <20260221183609.95403-3-privatesub2@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 9902 bytes --]
On Sat, Feb 21, 2026 at 09:35:52PM +0300, Aleksandr Shubin wrote:
> Allwinner's D1, T113-S3 and R329 SoCs have a quite different PWM
> controllers with ones supported by pwm-sun4i driver.
>
> This patch adds a PWM controller driver for Allwinner's D1,
> T113-S3 and R329 SoCs. The main difference between these SoCs
> is the number of channels defined by the DT property.
>
> Co-developed-by: Brandon Cheo Fusi <fusibrandon13@gmail.com>
> Signed-off-by: Brandon Cheo Fusi <fusibrandon13@gmail.com>
> Signed-off-by: Aleksandr Shubin <privatesub2@gmail.com>
> ---
> drivers/pwm/Kconfig | 10 +
> drivers/pwm/Makefile | 1 +
> drivers/pwm/pwm-sun8i.c | 393 ++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 404 insertions(+)
> create mode 100644 drivers/pwm/pwm-sun8i.c
>
> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
> index 6f3147518376..44d844eba589 100644
> --- a/drivers/pwm/Kconfig
> +++ b/drivers/pwm/Kconfig
> @@ -736,6 +736,16 @@ config PWM_SUN4I
> To compile this driver as a module, choose M here: the module
> will be called pwm-sun4i.
>
> +config PWM_SUN8I
> + tristate "Allwinner D1/T113s/R329 PWM support"
> + depends on ARCH_SUNXI || COMPILE_TEST
> + depends on COMMON_CLK
> + help
> + Generic PWM framework driver for Allwinner D1/T113s/R329 SoCs.
> +
> + To compile this driver as a module, choose M here: the module
> + will be called pwm-sun8i.
> +
> config PWM_SUNPLUS
> tristate "Sunplus PWM support"
> depends on ARCH_SUNPLUS || COMPILE_TEST
> diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
> index 0dc0d2b69025..ba2e0ec7fc17 100644
> --- a/drivers/pwm/Makefile
> +++ b/drivers/pwm/Makefile
> @@ -67,6 +67,7 @@ obj-$(CONFIG_PWM_STM32) += pwm-stm32.o
> obj-$(CONFIG_PWM_STM32_LP) += pwm-stm32-lp.o
> obj-$(CONFIG_PWM_STMPE) += pwm-stmpe.o
> obj-$(CONFIG_PWM_SUN4I) += pwm-sun4i.o
> +obj-$(CONFIG_PWM_SUN8I) += pwm-sun8i.o
> obj-$(CONFIG_PWM_SUNPLUS) += pwm-sunplus.o
> obj-$(CONFIG_PWM_TEGRA) += pwm-tegra.o
> obj-$(CONFIG_PWM_TH1520) += pwm_th1520.o
> diff --git a/drivers/pwm/pwm-sun8i.c b/drivers/pwm/pwm-sun8i.c
> new file mode 100644
> index 000000000000..6e196f31314b
> --- /dev/null
> +++ b/drivers/pwm/pwm-sun8i.c
> @@ -0,0 +1,393 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * PWM Controller Driver for sunxi platforms (D1, T113-S3 and R329)
> + *
> + * Limitations:
> + * - When the parameters change, the current running period is not completed
> + * and new settings are applied immediately.
> + * - The PWM output goes to a HIGH-Z state when the channel is disabled.
> + * - Changing the clock configuration (SUN8I_PWM_CLK_CFG)
> + * may cause a brief output glitch.
> + *
> + * Copyright (c) 2023 Aleksandr Shubin <privatesub2@gmail.com>
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/clk.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/pwm.h>
> +#include <linux/reset.h>
> +
> +#define SUN8I_PWM_CLK_CFG(pair) (0x20 + ((pair) * 0x4))
A word about the range of `pair` would be good. Something like:
/*
* Shared clock register. SUN8I_PWM_CLK_CFG(pair) configures the settings
* for channels 2·pair and 2·pair+1. Maximal value for pair is hardware
* dependant, it cannot be bigger than 8.
*/
> +#define SUN8I_PWM_CLK_CFG_SRC GENMASK(8, 7)
> +#define SUN8I_PWM_CLK_SRC_HOSC 0x0
> +#define SUN8I_PWM_CLK_SRC_BUS 0x1
SUN8I_PWM_CLK_SRC_HOSC and SUN8I_PWM_CLK_SRC_BUS are values for
SUN8I_PWM_CLK_CFG_SRC, right? It would be great if they were named
SUN8I_PWM_CLK_CFG_SRC_HOSC and SUN8I_PWM_CLK_CFG_SRC_BUS then.
And then it might be sensible to define it to
FIELD_PREP(SUN8I_PWM_CLK_CFG_SRC, 1)
(and 0 respectively).
I hope there is no conflict with the reference manual.
Speaking of the reference manual: Is there a public one? If yes, adding
a link to it would be awesome.
> +#define SUN8I_PWM_CLK_CFG_DIV_M GENMASK(3, 0)
> +#define SUN8I_PWM_CLK_DIV_M_MAX 8
> +
> +#define SUN8I_PWM_CLK_GATE 0x40
> +#define SUN8I_PWM_CLK_GATE_BYPASS(chan) BIT((chan) + 16)
> +#define SUN8I_PWM_CLK_GATE_GATING(chan) BIT(chan)
> +
> +#define SUN8I_PWM_ENABLE 0x80
> +#define SUN8I_PWM_ENABLE_EN(chan) BIT(chan)
> +
> +#define SUN8I_PWM_CTL(chan) (0x100 + (chan) * 0x20)
> +#define SUN8I_PWM_CTL_ACT_STA BIT(8)
> +#define SUN8I_PWM_CTL_PRESCAL_K GENMASK(7, 0)
> +#define SUN8I_PWM_CTL_PRESCAL_K_MAX field_max(SUN8I_PWM_CTL_PRESCAL_K)
> +
> +#define SUN8I_PWM_PERIOD(chan) (0x104 + (chan) * 0x20)
> +#define SUN8I_PWM_PERIOD_ENTIRE_CYCLE GENMASK(31, 16)
> +#define SUN8I_PWM_PERIOD_ACT_CYCLE GENMASK(15, 0)
> +
> +#define SUN8I_PWM_PCNTR_SIZE BIT(16)
This is unused (apart from the comment below). I'm unsure if this is a
bit field, if so to which register? Does it need a comment? Or should it
be dropped? From the discussion below, should this be
field_max(SUN8I_PWM_PERIOD_ACT_CYCLE)? (The value is different then
the calculations below needed some adaption if that is chosen.)
> +/*
> + * SUN8I_PWM_MAGIC is used to quickly compute the values of the clock dividers
> + * div_m (SUN8I_PWM_CLK_CFG_DIV_M) & prescale_k (SUN8I_PWM_CTL_PRESCAL_K)
> + * without using a loop. These dividers limit the # of cycles in a period
> + * to SUN8I_PWM_PCNTR_SIZE (65536) by applying a scaling factor of
> + * 1 / (div_m * (prescale_k + 1)) to the clock source.
Here div_m is a plain divider, ...
> + *
> + * SUN8I_PWM_MAGIC is derived by solving for div_m and prescale_k
> + * such that for a given requested period,
> + *
> + * i) div_m is minimized for any prescale_k ≤ SUN8I_PWM_CTL_PRESCAL_K_MAX,
> + * ii) prescale_k is minimized.
> + *
> + * The derivation proceeds as follows, with val = # of cycles for requested
> + * period:
> + *
> + * for a given value of div_m we want the smallest prescale_k such that
> + *
> + * (val >> div_m) // (prescale_k + 1) ≤ 65536 (= SUN8I_PWM_PCNTR_SIZE)
... and here it is a shift. I assume that above 1 << div_m is actually
meant, right?
> + * This is equivalent to:
> + *
> + * (val >> div_m) ≤ 65536 * (prescale_k + 1) + prescale_k
> + * ⟺ (val >> div_m) ≤ 65537 * prescale_k + 65536
> + * ⟺ (val >> div_m) - 65536 ≤ 65537 * prescale_k
> + * ⟺ ((val >> div_m) - 65536) / 65537 ≤ prescale_k
> + *
> + * As prescale_k is integer, this becomes
> + *
> + * ((val >> div_m) - 65536) // 65537 ≤ prescale_k
> + *
> + * And is minimized at
> + *
> + * ((val >> div_m) - 65536) // 65537
> + *
> + * Now we pick the smallest div_m that satifies prescale_k ≤ 255
> + * (i.e SUN8I_PWM_CTL_PRESCAL_K_MAX),
> + *
> + * ((val >> div_m) - 65536) // 65537 ≤ 255
> + * ⟺ (val >> div_m) - 65536 ≤ 255 * 65537 + 65536
> + * ⟺ val >> div_m ≤ 255 * 65537 + 2 * 65536
> + * ⟺ val >> div_m < (255 * 65537 + 2 * 65536 + 1)
> + * ⟺ div_m = fls((val) / (255 * 65537 + 2 * 65536 + 1))
> + *
> + * Suggested by Uwe Kleine-König
> + */
> +#define SUN8I_PWM_MAGIC (255 * 65537 + 2 * 65536 + 1)
> +#define SUN8I_PWM_DIV_CONST 65537
> [...]
> +static int sun8i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> + const struct pwm_state *state)
> +{
> + struct sun8i_pwm_chip *sun8i_chip = to_sun8i_pwm_chip(chip);
> + u64 bus_rate, hosc_rate, val, ent_cycle, act_cycle;
> + u32 clk_gate, clk_cfg, pwm_en, ctl, reg_period;
> + u32 prescale_k, div_m;
> + u64 clk_src_rate;
> + u8 clk_src;
> +
> + pwm_en = sun8i_pwm_readl(sun8i_chip, SUN8I_PWM_ENABLE);
> + clk_gate = sun8i_pwm_readl(sun8i_chip, SUN8I_PWM_CLK_GATE);
> +
> + if (!state->enabled) {
> + if (state->enabled != pwm->state.enabled) {
Can we make this
if (pwm_en & SUN8I_PWM_ENABLE_EN(pwm->hwpwm)) {
? Then it depends on the hardware settings instead of cached state. Same
for the other usage of pwm->state below.
> + clk_gate &= ~SUN8I_PWM_CLK_GATE_GATING(pwm->hwpwm);
> + pwm_en &= ~SUN8I_PWM_ENABLE_EN(pwm->hwpwm);
> + sun8i_pwm_writel(sun8i_chip, pwm_en, SUN8I_PWM_ENABLE);
> + sun8i_pwm_writel(sun8i_chip, clk_gate, SUN8I_PWM_CLK_GATE);
> + }
> + return 0;
> + }
> +
> + ctl = sun8i_pwm_readl(sun8i_chip, SUN8I_PWM_CTL(pwm->hwpwm));
> + clk_cfg = sun8i_pwm_readl(sun8i_chip, SUN8I_PWM_CLK_CFG(pwm->hwpwm / 2));
> + hosc_rate = clk_get_rate(sun8i_chip->clk_hosc);
> + bus_rate = clk_get_rate(sun8i_chip->clk_apb);
> +
> [...]
> +static int sun8i_pwm_probe(struct platform_device *pdev)
> +{
> + struct pwm_chip *chip;
> + struct sun8i_pwm_chip *sun8i_chip;
> + struct clk *clk_bus;
> + struct reset_control *rst;
> + u32 npwm;
> + int ret;
> +
> + ret = of_property_read_u32(pdev->dev.of_node, "allwinner,npwms", &npwm);
> + if (ret < 0)
> + return dev_err_probe(&pdev->dev, ret,
> + "Failed to get allwinner,npwms\n");
I failed to reply to your question about a non-vendored name for this in
v10
(https://lore.kernel.org/linux-pwm/CAF4idNmDMQpFppUvCBbC1=SNMQBrTOqmFO60SMvKvaHvNJy=Bg@mail.gmail.com).
"npwms" would be good.
> + if (npwm < 1 || npwm > 16)
> + return dev_err_probe(&pdev->dev, -EINVAL,
> + "Invalid allwinner,npwms\n");
I think there is a corner case if npwm is odd. In that case the last
channel must not check for hwpwm ^ 1 being enabled in .apply(). So
either .apply() should be more clever, or only even values for npwm
should be supported.
> + chip = devm_pwmchip_alloc(&pdev->dev, npwm, sizeof(*sun8i_chip));
> + if (IS_ERR(chip))
> + return PTR_ERR(chip);
> + sun8i_chip = to_sun8i_pwm_chip(chip);
> +
> + sun8i_chip->base = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(sun8i_chip->base))
> + return PTR_ERR(sun8i_chip->base);
> [...]
Best regards
Uwe
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH v3 4/5] KVM: arm64: Enable HDBSS support and handle HDBSSF events
From: Leonardo Bras @ 2026-04-24 10:08 UTC (permalink / raw)
To: Tian Zheng
Cc: Leonardo Bras, maz, oupton, catalin.marinas, corbet, pbonzini,
will, yuzenghui, wangzhou1, liuyonglong, Jonathan.Cameron,
yezhenyu2, linuxarm, joey.gouly, kvmarm, kvm, linux-arm-kernel,
linux-doc, linux-kernel, skhan, suzuki.poulose
In-Reply-To: <0403d30d-e75e-4922-b8c1-8cae349f3dc2@huawei.com>
On Fri, Apr 24, 2026 at 02:48:26PM +0800, Tian Zheng wrote:
>
> On 4/21/2026 10:18 PM, Leonardo Bras wrote:
> > On Mon, Mar 30, 2026 at 12:31:28PM +0100, Leonardo Bras wrote:
> > > On Sat, Mar 28, 2026 at 02:05:25PM +0800, Tian Zheng wrote:
> > > > On 3/27/2026 11:00 PM, Leonardo Bras wrote:
> > > > > On Fri, Mar 27, 2026 at 03:35:29PM +0800, Tian Zheng wrote:
> > > > > > On 3/26/2026 2:05 AM, Leonardo Bras wrote:
> > > > > > > Hello Tian,
> > > > > > >
> > > > > > > I am currently working on HACDBS enablement(which will be rebased on top of
> > > > > > > this patchset) and due to the fact HACDBS and HDBSS are kind of
> > > > > > > complementary I will sometimes come with some questions for issues I have
> > > > > > > faced myself on that part. :)
> > > > > > >
> > > > > > > (see below)
> > > > > > Of course! Happy to exchange ideas and learn together.
> > > > > :)
> > Hello Tian,
> >
> > On the above, HACDBS depends on HACDBSIRQ which can be announced by either
> > device-tree or ACPI.
> >
> > Do you think it's ok for it to be ACPI only, for now?
> >
> > Thanks!
> > Leo
>
> Hi Leo,
>
> No problem with ACPI-only for HACDBSIRQ for now.
Awesome!
I got it all working on my side, so I will try to send a freestanding patch
with the required needs from HDBSS :)
>
> Feel free to let me know if you have any questions while working
> on HACDBS on top of HDBSS.
>
Will do:)
Thanks!
Leo
> Tian
>
^ permalink raw reply
* Re: [PATCH v4 4/4] arm64: dts: amlogic: t7: khadas-vim4: Enable Bluetooth
From: Neil Armstrong @ 2026-04-24 10:04 UTC (permalink / raw)
To: Ronald Claveau, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-kernel, linux-amlogic, devicetree, linux-kernel
In-Reply-To: <20260420-add-bluetooth-t7-vim4-v4-4-9505df0e7016@aliel.fr>
On 4/20/26 15:54, Ronald Claveau wrote:
> Enable UART C on the Khadas VIM4 board and attach the BCM43438
> compatible Bluetooth controller to it. The node configures the RTS/CTS
> hardware flow control, the associated pinmux, the power supplies (vddao_3v3
> and vddao_1v8), the 32 kHz LPO clock shared with the wifi32k fixed
> clock, and the GPIO lines used for host wakeup, device wakeup and
> shutdown.
>
> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
> ---
> .../dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts | 19 +++++++++++++++++++
> 1 file changed, 19 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
> index 3227ab27de107..8ea7ae609fbd5 100644
> --- a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
> +++ b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
> @@ -251,3 +251,22 @@ &sd_emmc_c {
> &uart_a {
> status = "okay";
> };
> +
> +&uart_c {
> + status = "okay";
> + pinctrl-0 = <&uart_c_pins>;
> + pinctrl-names = "default";
> + uart-has-rtscts;
> +
> + bluetooth {
> + compatible = "brcm,bcm43438-bt";
> + shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
> + host-wakeup-gpios = <&gpio GPIOX_18 GPIO_ACTIVE_HIGH>;
> + device-wakeup-gpios = <&gpio GPIOX_19 GPIO_ACTIVE_HIGH>;
> + max-speed = <3000000>;
> + clocks = <&wifi32k>;
> + clock-names = "lpo";
> + vbat-supply = <&vddao_3v3>;
> + vddio-supply = <&vddao_1v8>;
> + };
> +};
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH v4 8/8] arm64: dts: amlogic: t7: khadas-vim4: Add i2c MCU fan node
From: Neil Armstrong @ 2026-04-24 10:01 UTC (permalink / raw)
To: linux-kernel-dev, Lee Jones, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andi Shyti, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Beniamino Galvani, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Liam Girdwood, Mark Brown
Cc: linux-amlogic, devicetree, linux-kernel, linux-i2c,
linux-arm-kernel, linux-pm
In-Reply-To: <20260421-add-mcu-fan-khadas-vim4-v4-8-447114a28f2d@aliel.fr>
On 4/21/26 13:49, Ronald Claveau via B4 Relay wrote:
> From: Ronald Claveau <linux-kernel-dev@aliel.fr>
>
> Enable and configure i2c MCU node to get fan working on Khadas VIM4.
>
> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
> ---
> .../boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
> index 69d6118ba57e7..5d7f5390f3a66 100644
> --- a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
> +++ b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
> @@ -157,6 +157,19 @@ wifi32k: wifi32k {
> };
> };
>
> +&i2c_m_ao_a {
> + status = "okay";
> + pinctrl-0 = <&i2c0_ao_d_pins>;
> + pinctrl-names = "default";
> +
> + khadas_mcu: system-controller@18 {
> + compatible = "khadas,vim4-mcu";
> + reg = <0x18>;
> + fan-supply = <&vcc5v>;
> + #cooling-cells = <2>;
> + };
> +};
> +
> &pwm_ab {
> status = "okay";
> pinctrl-0 = <&pwm_a_pins>;
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH v4 7/8] arm64: dts: amlogic: t7: Add i2c controller node
From: Neil Armstrong @ 2026-04-24 10:00 UTC (permalink / raw)
To: linux-kernel-dev, Lee Jones, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andi Shyti, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Beniamino Galvani, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Liam Girdwood, Mark Brown
Cc: linux-amlogic, devicetree, linux-kernel, linux-i2c,
linux-arm-kernel, linux-pm
In-Reply-To: <20260421-add-mcu-fan-khadas-vim4-v4-7-447114a28f2d@aliel.fr>
On 4/21/26 13:49, Ronald Claveau via B4 Relay wrote:
> From: Ronald Claveau <linux-kernel-dev@aliel.fr>
>
> Add the T7 i2c controller node used by the Khadas VIM4
> for MCU communication.
>
> Use amlogic,meson-axg-i2c as fallback compatible.
>
> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
> ---
> arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> index e96fe10b251a0..560c9dce35266 100644
> --- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> @@ -711,6 +711,16 @@ pwm_ao_cd: pwm@60000 {
> status = "disabled";
> };
>
> + i2c_m_ao_a: i2c@76000 {
> + compatible = "amlogic,t7-i2c", "amlogic,meson-axg-i2c";
> + reg = <0x0 0x76000 0x0 0x48>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + interrupts = <GIC_SPI 330 IRQ_TYPE_EDGE_RISING>;
> + clocks = <&clkc_periphs CLKID_SYS_I2C_AO_A>;
> + status = "disabled";
> + };
> +
> sd_emmc_a: mmc@88000 {
> compatible = "amlogic,t7-mmc", "amlogic,meson-axg-mmc";
> reg = <0x0 0x88000 0x0 0x800>;
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH v4 6/8] arm64: dts: amlogic: t7: Add i2c pinctrl node
From: Neil Armstrong @ 2026-04-24 10:00 UTC (permalink / raw)
To: linux-kernel-dev, Lee Jones, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andi Shyti, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Beniamino Galvani, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Liam Girdwood, Mark Brown
Cc: linux-amlogic, devicetree, linux-kernel, linux-i2c,
linux-arm-kernel, linux-pm
In-Reply-To: <20260421-add-mcu-fan-khadas-vim4-v4-6-447114a28f2d@aliel.fr>
On 4/21/26 13:49, Ronald Claveau via B4 Relay wrote:
> From: Ronald Claveau <linux-kernel-dev@aliel.fr>
>
> Add the T7 pinctrl used by the Khadas VIM4 for MCU communication.
>
> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
> ---
> arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> index 7fe72c94ed623..e96fe10b251a0 100644
> --- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> @@ -376,6 +376,16 @@ mux {
> };
> };
>
> + i2c0_ao_d_pins: i2c0-ao-d {
> + mux {
> + groups = "i2c0_ao_sck_d",
> + "i2c0_ao_sda_d";
> + function = "i2c0_ao";
> + bias-disable;
> + drive-strength-microamp = <3000>;
> + };
> + };
> +
> pwm_a_pins: pwm-a {
> mux {
> groups = "pwm_a";
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH v4 5/8] thermal: khadas-mcu-fan: Add fan config from platform data Add regulator support
From: Neil Armstrong @ 2026-04-24 10:00 UTC (permalink / raw)
To: linux-kernel-dev, Lee Jones, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andi Shyti, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Beniamino Galvani, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Liam Girdwood, Mark Brown
Cc: linux-amlogic, devicetree, linux-kernel, linux-i2c,
linux-arm-kernel, linux-pm
In-Reply-To: <20260421-add-mcu-fan-khadas-vim4-v4-5-447114a28f2d@aliel.fr>
On 4/21/26 13:49, Ronald Claveau via B4 Relay wrote:
> From: Ronald Claveau <linux-kernel-dev@aliel.fr>
>
> Replace the hardcoded MAX_LEVEL constant and fan register
> with values read from platform_data (fan_reg, max_level),
> as new MCUs need different values.
>
> Optionally acquire and enable a "fan" regulator supply
> at probe time and on resume,
> so boards that gate fan power through a regulator are handled.
>
> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
> ---
> drivers/thermal/khadas_mcu_fan.c | 49 +++++++++++++++++++++++++++++++++++-----
> 1 file changed, 43 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/thermal/khadas_mcu_fan.c b/drivers/thermal/khadas_mcu_fan.c
> index d35e5313bea41..24559bf65de46 100644
> --- a/drivers/thermal/khadas_mcu_fan.c
> +++ b/drivers/thermal/khadas_mcu_fan.c
> @@ -13,13 +13,15 @@
> #include <linux/regmap.h>
> #include <linux/sysfs.h>
> #include <linux/thermal.h>
> -
> -#define MAX_LEVEL 3
> +#include <linux/regulator/consumer.h>
>
> struct khadas_mcu_fan_ctx {
> struct khadas_mcu *mcu;
> + unsigned int fan_reg;
> unsigned int level;
> + unsigned int max_level;
> struct thermal_cooling_device *cdev;
> + struct regulator *power;
> };
>
> static int khadas_mcu_fan_set_level(struct khadas_mcu_fan_ctx *ctx,
> @@ -27,8 +29,7 @@ static int khadas_mcu_fan_set_level(struct khadas_mcu_fan_ctx *ctx,
> {
> int ret;
>
> - ret = regmap_write(ctx->mcu->regmap, KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG,
> - level);
> + ret = regmap_write(ctx->mcu->regmap, ctx->fan_reg, level);
> if (ret)
> return ret;
>
> @@ -40,7 +41,9 @@ static int khadas_mcu_fan_set_level(struct khadas_mcu_fan_ctx *ctx,
> static int khadas_mcu_fan_get_max_state(struct thermal_cooling_device *cdev,
> unsigned long *state)
> {
> - *state = MAX_LEVEL;
> + struct khadas_mcu_fan_ctx *ctx = cdev->devdata;
> +
> + *state = ctx->max_level;
>
> return 0;
> }
> @@ -61,7 +64,7 @@ khadas_mcu_fan_set_cur_state(struct thermal_cooling_device *cdev,
> {
> struct khadas_mcu_fan_ctx *ctx = cdev->devdata;
>
> - if (state > MAX_LEVEL)
> + if (state > ctx->max_level)
> return -EINVAL;
>
> if (state == ctx->level)
> @@ -83,11 +86,32 @@ static int khadas_mcu_fan_probe(struct platform_device *pdev)
> struct device *dev = &pdev->dev;
> struct khadas_mcu_fan_ctx *ctx;
> int ret;
> + const struct khadas_mcu_fan_pdata *pdata = dev_get_platdata(&pdev->dev);
Move this on top to respect reverse christmas ordering.
>
> ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
> if (!ctx)
> return -ENOMEM;
> +
> ctx->mcu = mcu;
> + ctx->fan_reg = pdata->fan_reg;
> + ctx->max_level = pdata->max_level;
> +
> + ctx->power = devm_regulator_get_optional(dev->parent, "fan");
> + if (IS_ERR(ctx->power)) {
> + if (PTR_ERR(ctx->power) == -ENODEV)
> + ctx->power = NULL;
> + else
> + return PTR_ERR(ctx->power);
> + }
> +
> + if (ctx->power) {
> + ret = regulator_enable(ctx->power);
> + if (ret) {
> + dev_err(dev, "Failed to enable fan power supply: %d\n", ret);
> + return ret;
> + }
> + }
Or you can request with devm_regulator_get(dev->parent, "fan"); which will
return a dummy regulator, and then you can just call regulator_enable & disable
and remove all those checks.
> +
> platform_set_drvdata(pdev, ctx);
>
> cdev = devm_thermal_of_cooling_device_register(dev->parent,
> @@ -124,12 +148,25 @@ static int khadas_mcu_fan_suspend(struct device *dev)
>
> ctx->level = level_save;
>
> + if (ctx->power) {
> + ret = regulator_disable(ctx->power);
> + if (ret)
> + return ret;
> + }
if (ctx->power)
return regulator_disable(ctx->power);
> +
> return 0;
> }
>
> static int khadas_mcu_fan_resume(struct device *dev)
> {
> struct khadas_mcu_fan_ctx *ctx = dev_get_drvdata(dev);
> + int ret;
> +
> + if (ctx->power) {
> + ret = regulator_enable(ctx->power);
> + if (ret)
> + return ret;
> + }
>
> return khadas_mcu_fan_set_level(ctx, ctx->level);
> }
>
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH v4 4/8] mfd: khadas-mcu: Add support for VIM4 MCU variant
From: Neil Armstrong @ 2026-04-24 9:55 UTC (permalink / raw)
To: linux-kernel-dev, Lee Jones, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andi Shyti, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Beniamino Galvani, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Liam Girdwood, Mark Brown
Cc: linux-amlogic, devicetree, linux-kernel, linux-i2c,
linux-arm-kernel, linux-pm
In-Reply-To: <20260421-add-mcu-fan-khadas-vim4-v4-4-447114a28f2d@aliel.fr>
On 4/21/26 13:49, Ronald Claveau via B4 Relay wrote:
> From: Ronald Claveau <linux-kernel-dev@aliel.fr>
>
> Refactor probe() to use per-variant khadas_mcu_data
> instead of hardcoded globals.
>
> Add dedicated regmap configuration and device data for the VIM4 MCU,
> with its own volatile/writeable registers.
>
> Add the fan control register
> (0–100 levels vs 0–3 for previous supported boards).
>
> Add a new compatible string "khadas,vim4-mcu".
>
> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
> ---
> drivers/mfd/khadas-mcu.c | 106 ++++++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 95 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/mfd/khadas-mcu.c b/drivers/mfd/khadas-mcu.c
> index ba981a7886921..b36b3b3ab73c0 100644
> --- a/drivers/mfd/khadas-mcu.c
> +++ b/drivers/mfd/khadas-mcu.c
> @@ -75,15 +75,91 @@ static const struct regmap_config khadas_mcu_regmap_config = {
> .cache_type = REGCACHE_MAPLE,
> };
>
> +static const struct khadas_mcu_fan_pdata khadas_mcu_fan_pdata = {
> + .fan_reg = KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG,
> + .max_level = 3,
> +};
> +
> static struct mfd_cell khadas_mcu_fan_cells[] = {
> /* VIM1/2 Rev13+ and VIM3 only */
> - { .name = "khadas-mcu-fan-ctrl", },
> + {
> + .name = "khadas-mcu-fan-ctrl",
> + .platform_data = &khadas_mcu_fan_pdata,
> + .pdata_size = sizeof(khadas_mcu_fan_pdata),
> + },
> };
>
> static struct mfd_cell khadas_mcu_cells[] = {
> { .name = "khadas-mcu-user-mem", },
> };
>
> +static const struct khadas_mcu_data khadas_mcu_data = {
> + .regmap_config = &khadas_mcu_regmap_config,
> + .cells = khadas_mcu_cells,
> + .ncells = ARRAY_SIZE(khadas_mcu_cells),
> + .fan_cells = khadas_mcu_fan_cells,
> + .nfan_cells = ARRAY_SIZE(khadas_mcu_fan_cells),
> +};
> +
> +static bool khadas_mcu_vim4_reg_volatile(struct device *dev, unsigned int reg)
> +{
> + switch (reg) {
> + case KHADAS_MCU_PWR_OFF_CMD_REG:
> + case KHADAS_MCU_VIM4_REST_CONF_REG:
> + case KHADAS_MCU_WOL_INIT_START_REG:
> + case KHADAS_MCU_VIM4_LED_ON_RAM_REG:
> + case KHADAS_MCU_VIM4_FAN_CTRL_REG:
> + case KHADAS_MCU_VIM4_WDT_EN_REG:
> + case KHADAS_MCU_VIM4_SYS_RST_REG:
> + return true;
> + default:
> + return false;
> + }
> +}
> +
> +static bool khadas_mcu_vim4_reg_writeable(struct device *dev, unsigned int reg)
> +{
> + switch (reg) {
> + case KHADAS_MCU_VERSION_0_REG:
> + case KHADAS_MCU_VERSION_1_REG:
> + case KHADAS_MCU_SHUTDOWN_NORMAL_STATUS_REG:
> + return false;
> + default:
> + return true;
> + }
> +}
> +
> +static const struct regmap_config khadas_mcu_vim4_regmap_config = {
> + .reg_bits = 8,
> + .reg_stride = 1,
> + .val_bits = 8,
> + .max_register = KHADAS_MCU_VIM4_SYS_RST_REG,
> + .volatile_reg = khadas_mcu_vim4_reg_volatile,
> + .writeable_reg = khadas_mcu_vim4_reg_writeable,
> + .cache_type = REGCACHE_MAPLE,
> +};
> +
> +static const struct khadas_mcu_fan_pdata khadas_vim4_fan_pdata = {
> + .fan_reg = KHADAS_MCU_VIM4_FAN_CTRL_REG,
> + .max_level = 0x64,
> +};
> +
> +static const struct mfd_cell khadas_mcu_vim4_cells[] = {
> + {
> + .name = "khadas-mcu-fan-ctrl",
> + .platform_data = &khadas_vim4_fan_pdata,
> + .pdata_size = sizeof(khadas_vim4_fan_pdata),
> + },
> +};
> +
> +static const struct khadas_mcu_data khadas_vim4_mcu_data = {
> + .regmap_config = &khadas_mcu_vim4_regmap_config,
> + .cells = NULL,
> + .ncells = 0,
> + .fan_cells = khadas_mcu_vim4_cells,
> + .nfan_cells = ARRAY_SIZE(khadas_mcu_vim4_cells),
> +};
> +
> static int khadas_mcu_probe(struct i2c_client *client)
> {
> struct device *dev = &client->dev;
> @@ -94,28 +170,35 @@ static int khadas_mcu_probe(struct i2c_client *client)
> if (!ddata)
> return -ENOMEM;
>
> + ddata->data = i2c_get_match_data(client);
> + if (!ddata->data)
> + return -EINVAL;
> +
> i2c_set_clientdata(client, ddata);
>
> ddata->dev = dev;
>
> - ddata->regmap = devm_regmap_init_i2c(client, &khadas_mcu_regmap_config);
> + ddata->regmap = devm_regmap_init_i2c(client,
> + ddata->data->regmap_config);
> if (IS_ERR(ddata->regmap)) {
> ret = PTR_ERR(ddata->regmap);
> dev_err(dev, "Failed to allocate register map: %d\n", ret);
> return ret;
> }
>
> - ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
> - khadas_mcu_cells,
> - ARRAY_SIZE(khadas_mcu_cells),
> - NULL, 0, NULL);
> - if (ret)
> - return ret;
> + if (ddata->data->cells && ddata->data->ncells) {
> + ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
> + ddata->data->cells,
> + ddata->data->ncells,
> + NULL, 0, NULL);
> + if (ret)
> + return ret;
> + }
>
> if (of_property_present(dev->of_node, "#cooling-cells"))
> return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
> - khadas_mcu_fan_cells,
> - ARRAY_SIZE(khadas_mcu_fan_cells),
> + ddata->data->fan_cells,
> + ddata->data->nfan_cells,
> NULL, 0, NULL);
>
> return 0;
> @@ -123,7 +206,8 @@ static int khadas_mcu_probe(struct i2c_client *client)
>
> #ifdef CONFIG_OF
> static const struct of_device_id khadas_mcu_of_match[] = {
> - { .compatible = "khadas,mcu", },
> + { .compatible = "khadas,mcu", .data = &khadas_mcu_data },
> + { .compatible = "khadas,vim4-mcu", .data = &khadas_vim4_mcu_data },
> {},
> };
> MODULE_DEVICE_TABLE(of, khadas_mcu_of_match);
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH v4 3/8] mfd: khadas-mcu: Add per-variant configuration infrastructure and VIM4 support
From: Neil Armstrong @ 2026-04-24 9:55 UTC (permalink / raw)
To: linux-kernel-dev, Lee Jones, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andi Shyti, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Beniamino Galvani, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Liam Girdwood, Mark Brown
Cc: linux-amlogic, devicetree, linux-kernel, linux-i2c,
linux-arm-kernel, linux-pm
In-Reply-To: <20260421-add-mcu-fan-khadas-vim4-v4-3-447114a28f2d@aliel.fr>
On 4/21/26 13:49, Ronald Claveau via B4 Relay wrote:
> From: Ronald Claveau <linux-kernel-dev@aliel.fr>
>
> Introduce a per-variant configuration structure (khadas_mcu_data)
> holding the regmap config and MFD cells,
> selected at probe time via the of_device_id match data.
> This makes adding other variants straightforward.
>
> Also introduce khadas_mcu_fan_pdata to pass fan register address and
> maximum level to the fan sub-driver, removing the hardcoded constants.
>
> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
> ---
> include/linux/mfd/khadas-mcu.h | 39 +++++++++++++++++++++++++++++++++++++--
> 1 file changed, 37 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/mfd/khadas-mcu.h b/include/linux/mfd/khadas-mcu.h
> index a99ba2ed0e4e0..75e275d3fa8d9 100644
> --- a/include/linux/mfd/khadas-mcu.h
> +++ b/include/linux/mfd/khadas-mcu.h
> @@ -70,6 +70,13 @@
> #define KHADAS_MCU_WOL_INIT_START_REG 0x87 /* WO */
> #define KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG 0x88 /* WO */
>
> +/* VIM4 specific registers */
> +#define KHADAS_MCU_VIM4_REST_CONF_REG 0x2c /* WO - reset EEPROM */
> +#define KHADAS_MCU_VIM4_LED_ON_RAM_REG 0x89 /* WO - LED volatile */
> +#define KHADAS_MCU_VIM4_FAN_CTRL_REG 0x8a /* WO */
> +#define KHADAS_MCU_VIM4_WDT_EN_REG 0x8b /* WO */
> +#define KHADAS_MCU_VIM4_SYS_RST_REG 0x91 /* WO */
> +
> enum {
> KHADAS_BOARD_VIM1 = 0x1,
> KHADAS_BOARD_VIM2,
> @@ -82,10 +89,38 @@ enum {
> * struct khadas_mcu - Khadas MCU structure
> * @device: device reference used for logs
> * @regmap: register map
> + * @data: pointer to variant-specific config
> */
> struct khadas_mcu {
> - struct device *dev;
> - struct regmap *regmap;
> + struct device *dev;
> + struct regmap *regmap;
> + const struct khadas_mcu_data *data;
> +};
> +
> +/**
> + * struct khadas_mcu_data - per-variant configuration
> + * @regmap_config: regmap configuration
> + * @cells: MFD sub-devices
> + * @ncells: number of sub-devices
> + * @fan_cells: MFD fan sub-devices
> + * @nfan_cells: number of fan sub-devices
> + */
> +struct khadas_mcu_data {
> + const struct regmap_config *regmap_config;
> + const struct mfd_cell *cells;
> + int ncells;
> + const struct mfd_cell *fan_cells;
> + int nfan_cells;
> +};
> +
> +/**
> + * struct khadas_mcu_fan_pdata - fan sub-driver configuration
> + * @fan_reg: register address to write the fan level
> + * @max_level: maximum fan level
> + */
> +struct khadas_mcu_fan_pdata {
> + unsigned int fan_reg;
> + unsigned int max_level;
> };
>
> #endif /* MFD_KHADAS_MCU_H */
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH v4 8/8] arm64: dts: amlogic: t7: khadas-vim4: Add fan cooling to thermal zones
From: Neil Armstrong @ 2026-04-24 9:53 UTC (permalink / raw)
To: linux-kernel-dev, Guillaume La Roque, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl
Cc: linux-pm, linux-amlogic, devicetree, linux-kernel,
linux-arm-kernel
In-Reply-To: <20260423-add-thermal-t7-vim4-v4-8-d4c1528d5044@aliel.fr>
On 4/23/26 18:07, Ronald Claveau via B4 Relay wrote:
> From: Ronald Claveau <linux-kernel-dev@aliel.fr>
>
> Add an active trip at 50°C to all six thermal zones and map it to the
> khadas_mcu fan controller, using cooling states 30 to 100.
>
> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
> ---
> .../dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts | 102 +++++++++++++++++++++
> 1 file changed, 102 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
> index 5d7f5390f3a66..ba9219073dd0a 100644
> --- a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
> +++ b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
> @@ -157,6 +157,74 @@ wifi32k: wifi32k {
> };
> };
>
> +&a53_thermal {
> + trips {
> + a53_active: a53-active {
> + temperature = <50000>; /* millicelsius */
> + hysteresis = <2000>; /* millicelsius */
> + type = "active";
> + };
> + };
> +
> + cooling-maps {
> + map {
> + trip = <&a53_active>;
> + cooling-device = <&khadas_mcu 30 100>;
> + };
> + };
> +};
> +
> +&a73_thermal {
> + trips {
> + a73_active: a73-active {
> + temperature = <50000>; /* millicelsius */
> + hysteresis = <2000>; /* millicelsius */
> + type = "active";
> + };
> + };
> +
> + cooling-maps {
> + map {
> + trip = <&a73_active>;
> + cooling-device = <&khadas_mcu 30 100>;
> + };
> + };
> +};
> +
> +&gpu_thermal {
> + trips {
> + gpu_active: gpu-active {
> + temperature = <50000>; /* millicelsius */
> + hysteresis = <2000>; /* millicelsius */
> + type = "active";
> + };
> + };
> +
> + cooling-maps {
> + map {
> + trip = <&gpu_active>;
> + cooling-device = <&khadas_mcu 30 100>;
> + };
> + };
> +};
> +
> +&hevc_thermal {
> + trips {
> + hevc_active: hevc-active {
> + temperature = <50000>; /* millicelsius */
> + hysteresis = <2000>; /* millicelsius */
> + type = "active";
> + };
> + };
> +
> + cooling-maps {
> + map {
> + trip = <&hevc_active>;
> + cooling-device = <&khadas_mcu 30 100>;
> + };
> + };
> +};
> +
> &i2c_m_ao_a {
> status = "okay";
> pinctrl-0 = <&i2c0_ao_d_pins>;
> @@ -170,6 +238,23 @@ khadas_mcu: system-controller@18 {
> };
> };
>
> +&nna_thermal {
> + trips {
> + nna_active: nna-active {
> + temperature = <50000>; /* millicelsius */
> + hysteresis = <2000>; /* millicelsius */
> + type = "active";
> + };
> + };
> +
> + cooling-maps {
> + map {
> + trip = <&nna_active>;
> + cooling-device = <&khadas_mcu 30 100>;
> + };
> + };
> +};
> +
> &pwm_ab {
> status = "okay";
> pinctrl-0 = <&pwm_a_pins>;
> @@ -266,3 +351,20 @@ &uart_a {
> clocks = <&xtal>, <&xtal>, <&xtal>;
> clock-names = "xtal", "pclk", "baud";
> };
> +
> +&vpu_thermal {
> + trips {
> + vpu_active: vpu-active {
> + temperature = <50000>; /* millicelsius */
> + hysteresis = <2000>; /* millicelsius */
> + type = "active";
> + };
> + };
> +
> + cooling-maps {
> + map {
> + trip = <&vpu_active>;
> + cooling-device = <&khadas_mcu 30 100>;
> + };
> + };
> +};
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH v4 7/8] arm64: dts: amlogic: t7: Add thermal zones
From: Neil Armstrong @ 2026-04-24 9:53 UTC (permalink / raw)
To: linux-kernel-dev, Guillaume La Roque, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl
Cc: linux-pm, linux-amlogic, devicetree, linux-kernel,
linux-arm-kernel
In-Reply-To: <20260423-add-thermal-t7-vim4-v4-7-d4c1528d5044@aliel.fr>
On 4/23/26 18:07, Ronald Claveau via B4 Relay wrote:
> From: Ronald Claveau <linux-kernel-dev@aliel.fr>
>
> Add thermal zones for all six sensors: a53, a73, gpu, nna, vpu, and hevc.
>
> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
> ---
> arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 179 ++++++++++++++++++++++++++++
> 1 file changed, 179 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> index 62f259b2b17d2..c6ea0f20a879f 100644
> --- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> @@ -9,6 +9,7 @@
> #include <dt-bindings/clock/amlogic,t7-scmi.h>
> #include <dt-bindings/clock/amlogic,t7-pll-clkc.h>
> #include <dt-bindings/clock/amlogic,t7-peripherals-clkc.h>
> +#include <dt-bindings/thermal/thermal.h>
>
> / {
> interrupt-parent = <&gic>;
> @@ -829,6 +830,184 @@ hevc_tsensor: temperature-sensor@9a000 {
> amlogic,secure-monitor = <&sm 5>;
> };
> };
> + };
> +
> + thermal-zones {
> + a53_thermal: a53-thermal {
> + polling-delay = <1000>;
> + polling-delay-passive = <100>;
> + thermal-sensors = <&a53_tsensor>;
> +
> + trips {
> + a53_passive: a53-passive {
> + temperature = <85000>; /* millicelsius */
> + hysteresis = <2000>; /* millicelsius */
> + type = "passive";
> + };
> +
> + a53_hot: a53-hot {
> + temperature = <95000>; /* millicelsius */
> + hysteresis = <2000>; /* millicelsius */
> + type = "hot";
> + };
> +
> + a53_critical: a53-critical {
> + temperature = <110000>; /* millicelsius */
> + hysteresis = <2000>; /* millicelsius */
> + type = "critical";
> + };
> + };
> +
> + cooling-maps {
> + map-a53 {
> + trip = <&a53_passive>;
> + cooling-device =
> + <&cpu100 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> + <&cpu101 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> + <&cpu102 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> + <&cpu103 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> + };
> + };
> + };
> +
> + a73_thermal: a73-thermal {
> + polling-delay = <1000>;
> + polling-delay-passive = <100>;
> + thermal-sensors = <&a73_tsensor>;
> +
> + trips {
> + a73_passive: a73-passive {
> + temperature = <85000>; /* millicelsius */
> + hysteresis = <2000>; /* millicelsius */
> + type = "passive";
> + };
> +
> + a73_hot: a73-hot {
> + temperature = <95000>; /* millicelsius */
> + hysteresis = <2000>; /* millicelsius */
> + type = "hot";
> + };
> +
> + a73_critical: a73-critical {
> + temperature = <110000>; /* millicelsius */
> + hysteresis = <2000>; /* millicelsius */
> + type = "critical";
> + };
> + };
> +
> + cooling-maps {
> + map-a73 {
> + trip = <&a73_passive>;
> + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> + };
> + };
> + };
> +
> + gpu_thermal: gpu-thermal {
> + polling-delay = <1000>;
> + polling-delay-passive = <100>;
> + thermal-sensors = <&gpu_tsensor>;
> +
> + trips {
> + gpu_passive: gpu-passive {
> + temperature = <95000>;
> + hysteresis = <5000>;
> + type = "passive";
> + };
> +
> + gpu_hot: gpu-hot {
> + temperature = <105000>;
> + hysteresis = <5000>;
> + type = "passive";
> + };
>
> + gpu_critical: gpu-critical {
> + temperature = <115000>;
> + hysteresis = <1000>;
> + type = "critical";
> + };
> + };
> + };
> +
> + hevc_thermal: hevc-thermal {
> + polling-delay = <1000>;
> + polling-delay-passive = <100>;
> + thermal-sensors = <&hevc_tsensor>;
> +
> + trips {
> + hevc_passive: hevc-passive {
> + temperature = <95000>;
> + hysteresis = <5000>;
> + type = "passive";
> + };
> +
> + hevc_hot: hevc-hot {
> + temperature = <105000>;
> + hysteresis = <5000>;
> + type = "passive";
> + };
> +
> + hevc_critical: hevc-critical {
> + temperature = <115000>;
> + hysteresis = <1000>;
> + type = "critical";
> + };
> + };
> + };
> +
> + nna_thermal: nna-thermal {
> + polling-delay = <1000>;
> + polling-delay-passive = <100>;
> + thermal-sensors = <&nna_tsensor>;
> +
> + trips {
> + nna_passive: nna-passive {
> + temperature = <95000>;
> + hysteresis = <5000>;
> + type = "passive";
> + };
> +
> + nna_hot: nna-hot {
> + temperature = <105000>;
> + hysteresis = <5000>;
> + type = "passive";
> + };
> +
> + nna_critical: nna-critical {
> + temperature = <115000>;
> + hysteresis = <1000>;
> + type = "critical";
> + };
> + };
> + };
> +
> + vpu_thermal: vpu-thermal {
> + polling-delay = <1000>;
> + polling-delay-passive = <100>;
> + thermal-sensors = <&vpu_tsensor>;
> +
> + trips {
> + vpu_passive: vpu-passive {
> + temperature = <95000>;
> + hysteresis = <5000>;
> + type = "passive";
> + };
> +
> + vpu_hot: vpu-hot {
> + temperature = <105000>;
> + hysteresis = <5000>;
> + type = "passive";
> + };
> +
> + vpu_critical: vpu-critical {
> + temperature = <115000>;
> + hysteresis = <1000>;
> + type = "critical";
> + };
> + };
> + };
> };
> };
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH v4 6/8] arm64: dts: amlogic: t7: Add thermal sensor nodes
From: Neil Armstrong @ 2026-04-24 9:52 UTC (permalink / raw)
To: linux-kernel-dev, Guillaume La Roque, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl
Cc: linux-pm, linux-amlogic, devicetree, linux-kernel,
linux-arm-kernel
In-Reply-To: <20260423-add-thermal-t7-vim4-v4-6-d4c1528d5044@aliel.fr>
On 4/23/26 18:07, Ronald Claveau via B4 Relay wrote:
> From: Ronald Claveau <linux-kernel-dev@aliel.fr>
>
> Add six temperature sensor nodes using the amlogic,t7-thermal compatible:
> a73, a53, gpu, nna, vpu, and hevc. Each sensor retrieves its calibration
> data from the secure monitor via the amlogic,secure-monitor phandle with
> the corresponding tsensor_id argument.
>
> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
> ---
> arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 58 +++++++++++++++++++++++++++++
> 1 file changed, 58 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> index 7aec65f036a9c..62f259b2b17d2 100644
> --- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> @@ -656,6 +656,24 @@ sec_ao: ao-secure@10220 {
> amlogic,has-chip-id;
> };
>
> + a73_tsensor: temperature-sensor@20000 {
> + compatible = "amlogic,t7-thermal";
> + reg = <0x0 0x20000 0x0 0x50>;
> + interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&clkc_periphs CLKID_TS>;
> + #thermal-sensor-cells = <0>;
> + amlogic,secure-monitor = <&sm 1>;
> + };
> +
> + a53_tsensor: temperature-sensor@22000 {
> + compatible = "amlogic,t7-thermal";
> + reg = <0x0 0x22000 0x0 0x50>;
> + interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&clkc_periphs CLKID_TS>;
> + #thermal-sensor-cells = <0>;
> + amlogic,secure-monitor = <&sm 2>;
> + };
> +
> pwm_ao_ef: pwm@30000 {
> compatible = "amlogic,t7-pwm", "amlogic,meson-s4-pwm";
> reg = <0x0 0x30000 0x0 0x24>;
> @@ -770,6 +788,46 @@ sd_emmc_c: mmc@8c000 {
> assigned-clock-parents = <&xtal>;
> status = "disabled";
> };
> +
> + gpu_tsensor: temperature-sensor@94000 {
> + compatible = "amlogic,t7-thermal";
> + reg = <0x0 0x94000 0x0 0x50>;
> + interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&clkc_periphs CLKID_TS>;
> + power-domains = <&pwrc PWRC_T7_MALI_TOP_ID>;
> + #thermal-sensor-cells = <0>;
> + amlogic,secure-monitor = <&sm 3>;
> + };
> +
> + nna_tsensor: temperature-sensor@96000 {
> + compatible = "amlogic,t7-thermal";
> + reg = <0x0 0x96000 0x0 0x50>;
> + interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&clkc_periphs CLKID_TS>;
> + power-domains = <&pwrc PWRC_T7_NNA_TOP_ID>;
> + #thermal-sensor-cells = <0>;
> + amlogic,secure-monitor = <&sm 4>;
> + };
> +
> + vpu_tsensor: temperature-sensor@98000 {
> + compatible = "amlogic,t7-thermal";
> + reg = <0x0 0x98000 0x0 0x50>;
> + interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&clkc_periphs CLKID_TS>;
> + power-domains = <&pwrc PWRC_T7_VPU_HDMI_ID>;
> + #thermal-sensor-cells = <0>;
> + amlogic,secure-monitor = <&sm 6>;
> + };
> +
> + hevc_tsensor: temperature-sensor@9a000 {
> + compatible = "amlogic,t7-thermal";
> + reg = <0x0 0x9a000 0x0 0x50>;
> + interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&clkc_periphs CLKID_TS>;
> + power-domains = <&pwrc PWRC_T7_DOS_HEVC_ID>;
> + #thermal-sensor-cells = <0>;
> + amlogic,secure-monitor = <&sm 5>;
> + };
> };
>
> };
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH v4 5/8] arm64: dts: amlogic: t7: Add cooling cells to all CPUs
From: Neil Armstrong @ 2026-04-24 9:52 UTC (permalink / raw)
To: linux-kernel-dev, Guillaume La Roque, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl
Cc: linux-pm, linux-amlogic, devicetree, linux-kernel,
linux-arm-kernel
In-Reply-To: <20260423-add-thermal-t7-vim4-v4-5-d4c1528d5044@aliel.fr>
On 4/23/26 18:07, Ronald Claveau via B4 Relay wrote:
> From: Ronald Claveau <linux-kernel-dev@aliel.fr>
>
> Add #cooling-cells = <2> to all CPU nodes (both little and big cluster)
> to allow them to be used as cooling devices in thermal zone mappings.
>
> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
> ---
> arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> index 560c9dce35266..7aec65f036a9c 100644
> --- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> @@ -63,6 +63,7 @@ cpu100: cpu@100 {
> i-cache-size = <0x8000>;
> i-cache-sets = <32>;
> next-level-cache = <&l2_cache_l>;
> + #cooling-cells = <2>;
> };
>
> cpu101: cpu@101 {
> @@ -77,6 +78,7 @@ cpu101: cpu@101 {
> i-cache-size = <0x8000>;
> i-cache-sets = <32>;
> next-level-cache = <&l2_cache_l>;
> + #cooling-cells = <2>;
> };
>
> cpu102: cpu@102 {
> @@ -91,6 +93,7 @@ cpu102: cpu@102 {
> i-cache-size = <0x8000>;
> i-cache-sets = <32>;
> next-level-cache = <&l2_cache_l>;
> + #cooling-cells = <2>;
> };
>
> cpu103: cpu@103 {
> @@ -105,6 +108,7 @@ cpu103: cpu@103 {
> i-cache-size = <0x8000>;
> i-cache-sets = <32>;
> next-level-cache = <&l2_cache_l>;
> + #cooling-cells = <2>;
> };
>
> cpu0: cpu@0 {
> @@ -119,6 +123,7 @@ cpu0: cpu@0 {
> i-cache-size = <0x10000>;
> i-cache-sets = <64>;
> next-level-cache = <&l2_cache_b>;
> + #cooling-cells = <2>;
> };
>
> cpu1: cpu@1 {
> @@ -133,6 +138,7 @@ cpu1: cpu@1 {
> i-cache-size = <0x10000>;
> i-cache-sets = <64>;
> next-level-cache = <&l2_cache_b>;
> + #cooling-cells = <2>;
> };
>
> cpu2: cpu@2 {
> @@ -147,6 +153,7 @@ cpu2: cpu@2 {
> i-cache-size = <0x10000>;
> i-cache-sets = <64>;
> next-level-cache = <&l2_cache_b>;
> + #cooling-cells = <2>;
> };
>
> cpu3: cpu@3 {
> @@ -161,6 +168,7 @@ cpu3: cpu@3 {
> i-cache-size = <0x10000>;
> i-cache-sets = <64>;
> next-level-cache = <&l2_cache_b>;
> + #cooling-cells = <2>;
> };
>
> l2_cache_l: l2-cache-cluster0 {
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH v4 3/8] firmware: meson: sm: Add thermal calibration SMC call
From: Neil Armstrong @ 2026-04-24 9:47 UTC (permalink / raw)
To: linux-kernel-dev, Guillaume La Roque, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl
Cc: linux-pm, linux-amlogic, devicetree, linux-kernel,
linux-arm-kernel
In-Reply-To: <20260423-add-thermal-t7-vim4-v4-3-d4c1528d5044@aliel.fr>
On 4/23/26 18:07, Ronald Claveau via B4 Relay wrote:
> From: Ronald Claveau <linux-kernel-dev@aliel.fr>
>
> Add SM_THERMAL_CALIB_READ at SMC ID 0x82000047 in the command
> table and implement meson_sm_get_thermal_calib(), which forwards the
> tsensor_id argument to the secure monitor and returns the calibration data.
>
> Also realign the CMD() column to improve readability.
>
> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
> ---
> drivers/firmware/meson/meson_sm.c | 29 ++++++++++++++++++++++++-----
> 1 file changed, 24 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/firmware/meson/meson_sm.c b/drivers/firmware/meson/meson_sm.c
> index 3ab67aaa9e5da..4e57986724212 100644
> --- a/drivers/firmware/meson/meson_sm.c
> +++ b/drivers/firmware/meson/meson_sm.c
> @@ -41,12 +41,13 @@ static const struct meson_sm_chip gxbb_chip = {
> .cmd_shmem_in_base = 0x82000020,
> .cmd_shmem_out_base = 0x82000021,
> .cmd = {
> - CMD(SM_EFUSE_READ, 0x82000030),
> - CMD(SM_EFUSE_WRITE, 0x82000031),
> + CMD(SM_EFUSE_READ, 0x82000030),
> + CMD(SM_EFUSE_WRITE, 0x82000031),
> CMD(SM_EFUSE_USER_MAX, 0x82000033),
> - CMD(SM_GET_CHIP_ID, 0x82000044),
> - CMD(SM_A1_PWRC_SET, 0x82000093),
> - CMD(SM_A1_PWRC_GET, 0x82000095),
> + CMD(SM_GET_CHIP_ID, 0x82000044),
> + CMD(SM_THERMAL_CALIB_READ, 0x82000047),
> + CMD(SM_A1_PWRC_SET, 0x82000093),
> + CMD(SM_A1_PWRC_GET, 0x82000095),
> { /* sentinel */ },
> },
> };
> @@ -245,6 +246,24 @@ struct meson_sm_firmware *meson_sm_get(struct device_node *sm_node)
> }
> EXPORT_SYMBOL_GPL(meson_sm_get);
>
> +/**
> + *
> + * meson_sm_get_thermal_calib - Read thermal sensor calibration data.
> + * @fw: Pointer to secure-monitor firmware.
> + * @trim_info: Pointer to store the returned calibration data.
> + * @tsensor_id: Sensor index to identify which sensor's calibration data
> + * to retrieve
> + *
> + * Return: 0 on success, negative error code on failure.
> + */
> +int meson_sm_get_thermal_calib(struct meson_sm_firmware *fw, u32 *trim_info,
> + u32 tsensor_id)
> +{
> + return meson_sm_call(fw, SM_THERMAL_CALIB_READ, trim_info, tsensor_id,
> + 0, 0, 0, 0);
> +}
> +EXPORT_SYMBOL_GPL(meson_sm_get_thermal_calib);
> +
> #define SM_CHIP_ID_LENGTH 119
> #define SM_CHIP_ID_OFFSET 4
> #define SM_CHIP_ID_SIZE 12
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH v4 2/8] firmware: meson: sm: Thermal calibration read via secure monitor
From: Neil Armstrong @ 2026-04-24 9:47 UTC (permalink / raw)
To: linux-kernel-dev, Guillaume La Roque, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl
Cc: linux-pm, linux-amlogic, devicetree, linux-kernel,
linux-arm-kernel
In-Reply-To: <20260423-add-thermal-t7-vim4-v4-2-d4c1528d5044@aliel.fr>
On 4/23/26 18:07, Ronald Claveau via B4 Relay wrote:
> From: Ronald Claveau <linux-kernel-dev@aliel.fr>
>
> Add SM_THERMAL_CALIB_READ to the secure monitor command enum and
> introduce meson_sm_get_thermal_calib() to allow drivers to retrieve
> thermal sensor calibration data through the firmware interface.
>
> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
> ---
> include/linux/firmware/meson/meson_sm.h | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/include/linux/firmware/meson/meson_sm.h b/include/linux/firmware/meson/meson_sm.h
> index 8eaf8922ab020..3ebc2bd9a9760 100644
> --- a/include/linux/firmware/meson/meson_sm.h
> +++ b/include/linux/firmware/meson/meson_sm.h
> @@ -12,6 +12,7 @@ enum {
> SM_EFUSE_WRITE,
> SM_EFUSE_USER_MAX,
> SM_GET_CHIP_ID,
> + SM_THERMAL_CALIB_READ,
> SM_A1_PWRC_SET,
> SM_A1_PWRC_GET,
> };
> @@ -27,5 +28,7 @@ int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer,
> unsigned int bsize, unsigned int cmd_index, u32 arg0,
> u32 arg1, u32 arg2, u32 arg3, u32 arg4);
> struct meson_sm_firmware *meson_sm_get(struct device_node *firmware_node);
> +int meson_sm_get_thermal_calib(struct meson_sm_firmware *fw, u32 *trim_info,
> + u32 tsensor_id);
>
> #endif /* _MESON_SM_FW_H_ */
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH] iio: fix header includes across multiple drivers
From: Andy Shevchenko @ 2026-04-24 9:45 UTC (permalink / raw)
To: David Lechner
Cc: Caio Morais, jic23, nuno.sa, andy, michal.simek, linux-iio,
linux-arm-kernel
In-Reply-To: <a9307e04-3754-465e-a610-92c6e83cc3e6@baylibre.com>
On Thu, Apr 23, 2026 at 01:45:12PM -0500, David Lechner wrote:
> On 4/23/26 1:33 PM, Caio Morais wrote:
> >
> > Remove unnecessary includes and add missing ones as reported by the
> > include-what-you-use (IWYU) tool.
> >
> > Files changed:
> > - drivers/iio/adc/xilinx-xadc-events.c
> > - drivers/iio/buffer/industrialio-triggered-buffer.c
> > - drivers/iio/common/st_sensors/st_sensors_i2c.c
> > - drivers/iio/common/st_sensors/st_sensors_spi.c
>
> We'll want to split these up, one patch per file in case they every
> need to be backported as a dependency to a fix.
Per driver actually, as the last two belong to the same driver
(different busses though).
...
> This looks like sorting alphabetically, not actually adding or removing
> any headers as seen by the equal number of insertions and deletions.
>
> Usually we don't bother with sorting unless we are making other
> changes on top of that.
Right. At bare minimum we expect sorting + IWYU patch series.
...
> > #include <linux/device.h>
> > #include <linux/err.h>
> > #include <linux/i2c.h>
> > +#include <linux/iio/iio.h>
> > #include <linux/linkage.h>
> > #include <linux/module.h>
> > #include <linux/regmap.h>
> > -#include <linux/iio/iio.h>
>
> On this one, it would be more logical to move the iio header
> down one line to group it with the one below.
Hmm... Personally I consider them different group, I would rather see
linux/*
...blank line...
linux/iio/*
...blank line...
linux/_whatever_driver_specific_
> > #include <linux/iio/common/st_sensors_i2c.h>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* [PATCH v5 2/2] arm64: dts: amlogic: add support for Amediatech X98Q
From: christian.koever-draxl @ 2026-04-24 9:36 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, neil.armstrong, khilman
Cc: jbrunet, martin.blumenstingl, devicetree, linux-amlogic,
linux-arm-kernel, linux-kernel,
Christian Stefan Kövér-Draxl
In-Reply-To: <20260424093633.10734-1-christian.koever-draxl@student.uibk.ac.at>
From: Christian Stefan Kövér-Draxl <christian.koever-draxl@student.uibk.ac.at>
Add dts enabling core hardware for the Amediatech X98Q TV box.
The board features:
- Amlogic S905W2 (Meson S4) SoC
- 1 GiB RAM (2 GiB variants exist)
- eMMC and microSD card slot
- SDIO-based WiFi module (unsupported)
- RMII Ethernet with internal PHY
- IR receiver and UART console
- Status LED
Enabled peripherals:
- eMMC (HS200)
- SD card interface
- SDIO bus (WiFi, no driver yet)
- Ethernet (RMII)
- UART_B
- IR receiver
- PWM-controlled CPU regulator
- PWM and Fixed regulators for core and IO rails
Known limitations:
- No support for the onboard WiFi module
- Missing multimedia (HDMI/audio)
Signed-off-by: Christian Stefan Kövér-Draxl <christian.koever-draxl@student.uibk.ac.at>
---
arch/arm64/boot/dts/amlogic/Makefile | 1 +
.../boot/dts/amlogic/meson-s4-s905w2-x98q.dts | 249 ++++++++++++++++++
2 files changed, 250 insertions(+)
create mode 100644 arch/arm64/boot/dts/amlogic/meson-s4-s905w2-x98q.dts
diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 15f9c817e502..c7752684dea6 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -85,6 +85,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-ugoos-am3.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxm-vega-s96.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxm-wetek-core2.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-s4-s805x2-aq222.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-s4-s905w2-x98q.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-s4-s905y4-khadas-vim1s.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air-gbit.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-s4-s905w2-x98q.dts b/arch/arm64/boot/dts/amlogic/meson-s4-s905w2-x98q.dts
index 000000000000..fe84259a20f3
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-s4-s905w2-x98q.dts
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2026 Christian Stefan Köver-Draxl
+ * Based on meson-s4-s905y4-khadas-vim1s.dts:
+ * - Copyright (c) 2026 Khadas Technology Co., Ltd.
+ */
+
+/dts-v1/;
+
+#include "meson-s4.dtsi"
+
+/ {
+ model = "Shenzhen Amediatech Technology Co., Ltd X98Q";
+ compatible = "amediatech,x98q", "amlogic,s905w2", "amlogic,s4";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ mmc0 = &emmc; /* eMMC */
+ mmc1 = &sd; /* SD card */
+ mmc2 = &sdio; /* SDIO */
+ serial0 = &uart_b;
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x40000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /* 52 MiB reserved for ARM Trusted Firmware */
+ secmon_reserved: secmon@5000000 {
+ reg = <0x0 0x05000000 0x0 0x3400000>;
+ no-map;
+ };
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ reset-gpios = <&gpio GPIOB_9 GPIO_ACTIVE_LOW>;
+ };
+
+ sdio_32k: sdio-32k {
+ compatible = "pwm-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+ clocks = <&sdio_32k>;
+ clock-names = "ext_clock";
+ };
+
+ main_5v: regulator-main-5v {
+ compatible = "regulator-fixed";
+ regulator-name = "5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ sd_3v3: regulator-sd-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "SD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio GPIOD_4 GPIO_ACTIVE_LOW>;
+ regulator-always-on;
+ };
+
+ vddio_sd: regulator-vddio-sd {
+ compatible = "regulator-gpio";
+ regulator-name = "VDDIO_SD";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ gpios = <&gpio GPIOD_9 GPIO_ACTIVE_HIGH>;
+ gpios-states = <1>;
+ states = <1800000 1 3300000 0>;
+ };
+
+ vddao_3v3: regulator-vddao-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDAO_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&main_5v>;
+ regulator-always-on;
+ };
+
+ vddio_ao1v8: regulator-vddio-ao1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDIO_AO1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vddao_3v3>;
+ regulator-always-on;
+ };
+
+ /* SY8120B1ABC DC/DC Regulator. */
+ vddcpu: regulator-vddcpu {
+ compatible = "pwm-regulator";
+
+ regulator-name = "VDDCPU";
+ regulator-min-microvolt = <689000>;
+ regulator-max-microvolt = <1049000>;
+
+ vin-supply = <&main_5v>;
+
+ pwms = <&pwm_ij 1 1500 0>;
+ pwm-dutycycle-range = <100 0>;
+
+ regulator-boot-on;
+ regulator-always-on;
+ /* Voltage Duty-Cycle */
+ voltage-table = <1049000 0>,
+ <1039000 3>,
+ <1029000 6>,
+ <1019000 9>,
+ <1009000 12>,
+ <999000 14>,
+ <989000 17>,
+ <979000 20>,
+ <969000 23>,
+ <959000 26>,
+ <949000 29>,
+ <939000 31>,
+ <929000 34>,
+ <919000 37>,
+ <909000 40>,
+ <899000 43>,
+ <889000 45>,
+ <879000 48>,
+ <869000 51>,
+ <859000 54>,
+ <849000 56>,
+ <839000 59>,
+ <829000 62>,
+ <819000 65>,
+ <809000 68>,
+ <799000 70>,
+ <789000 73>,
+ <779000 76>,
+ <769000 79>,
+ <759000 81>,
+ <749000 84>,
+ <739000 87>,
+ <729000 89>,
+ <719000 92>,
+ <709000 95>,
+ <699000 98>,
+ <689000 100>;
+ };
+};
+
+&emmc {
+ status = "okay";
+ pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>;
+ pinctrl-1 = <&emmc_clk_gate_pins>;
+ pinctrl-names = "default", "clk-gate";
+
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ max-frequency = <200000000>;
+ non-removable;
+ disable-wp;
+
+ mmc-pwrseq = <&emmc_pwrseq>;
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddio_ao1v8>;
+};
+
+ðmac {
+ status = "okay";
+ phy-handle = <&internal_ephy>;
+ phy-mode = "rmii";
+};
+
+&ir {
+ status = "okay";
+ pinctrl-0 = <&remote_pins>;
+ pinctrl-names = "default";
+};
+
+&pwm_ef {
+ status = "okay";
+ pinctrl-0 = <&pwm_e_pins1>;
+ pinctrl-names = "default";
+};
+
+&pwm_ij {
+ status = "okay";
+};
+
+&sd {
+ status = "okay";
+ pinctrl-0 = <&sdcard_pins>;
+ pinctrl-1 = <&sdcard_clk_gate_pins>;
+ pinctrl-names = "default", "clk-gate";
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <50000000>;
+ disable-wp;
+
+ cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
+
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddao_3v3>;
+};
+
+&sdio {
+ status = "okay";
+ pinctrl-0 = <&sdio_pins>;
+ pinctrl-1 = <&sdio_clk_gate_pins>;
+ pinctrl-names = "default", "clk-gate";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ bus-width = <4>;
+ cap-sd-highspeed;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ max-frequency = <200000000>;
+ non-removable;
+ disable-wp;
+
+ no-sd;
+ no-mmc;
+ mmc-pwrseq = <&sdio_pwrseq>;
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddio_ao1v8>;
+
+ wifi: wifi@1 {
+ /* Amlogic W150S1 */
+ reg = <1>;
+ };
+};
+
+&uart_b {
+ status = "okay";
+};
--
2.54.0
^ permalink raw reply related
* [PATCH v5 0/2] Add support for Amediatech X98Q (Amlogic S905W2)
From: christian.koever-draxl @ 2026-04-24 9:36 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, neil.armstrong, khilman
Cc: jbrunet, martin.blumenstingl, devicetree, linux-amlogic,
linux-arm-kernel, linux-kernel,
Christian Stefan Kövér-Draxl
From: Christian Stefan Kövér-Draxl <christian.koever-draxl@student.uibk.ac.at>
Supported features:
- 1GB RAM (2GB variants exist)
- 10/100 Ethernet (Internal PHY)
- eMMC and SD card storage
- PWM-based CPU voltage regulation
- UART (Serial console)
Notes:
- The console uses uart_b at 921600 baud.
- Verified memory via /proc/device-tree; U-Boot patches the node.
- Tested on the 2GB RAM plus 16GB eMMC variant.
Changes in v5:
- Drop Wireless SDIO Module comment.
- Add generic description of Wireless SDIO Module in dts.
Changes in v4:
- Add/Change hardware description to cover letter and dts patch.
Changes in v3:
- Change position of the entry in the amlogic.yaml.
- Change formatting of the Amlogic W150S1 Wi-Fi module comment.
- Fix several formatting issues.
Changes in v2:
- Split dt-bindings and dts changes into separate patches.
- Updated model string to match documented vendor prefix.
- Put vddio_sd states array in a single line.
- Added a comment for the unsupported Amlogic W150S1 Wi-Fi module.
Christian Stefan Kövér-Draxl (2):
dt-bindings: arm: amlogic: add support for Amediatech X98Q
arm64: dts: amlogic: add support for Amediatech X98Q
.../devicetree/bindings/arm/amlogic.yaml | 7 +
arch/arm64/boot/dts/amlogic/Makefile | 1 +
.../boot/dts/amlogic/meson-s4-s905w2-x98q.dts | 249 ++++++++++++++++++
3 files changed, 257 insertions(+)
create mode 100644 arch/arm64/boot/dts/amlogic/meson-s4-s905w2-x98q.dts
--
2.54.0
^ 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