* [PATCH net-next v1] net: macb: fix use of at91_default_usrio without CONFIG_OF
From: Conor Dooley @ 2026-03-30 9:02 UTC (permalink / raw)
To: netdev
Cc: conor, Conor Dooley, kernel test robot, Jiawen Wu, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Nicolas Ferre, Claudiu Beznea, devicetree, linux-kernel,
linux-riscv
From: Conor Dooley <conor.dooley@microchip.com>
If CONFIG_OF is not enabled, at91_default_usrio is used undeclared in
gem_default_config. Rather than move the struct around, take the
opportunity to rename gem_default_config, as the only compatible it is
ever used for is "cdns,macb" - not "cdns,gem" at all! With that done,
remove the use of default_gem_config as a fallback in probe, as every
device has a specific set of match data.
It pains me a little to leave at91_default_usrio in match data used by
"cdns,macb", but this is probably required to avoid regressing anyone.
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202603280028.wQjUrIvv-lkp@intel.com/
Reported-by: Jiawen Wu <jiawenwu@trustnetic.com>
Closes: https://lore.kernel.org/all/06a701dcc014$86def5b0$949ce110$@trustnetic.com/
Fixes: a17871778ee28 ("net: macb: rename macb_default_usrio to at91_default_usrio as not all platforms have mii mode control in usrio")
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
lkp also reported this over the weekend, but against the dev copy in my
tree. I had thought that CONFIG_OF was standard off on x86, but I guess
it isn't, given lkp didn't catch it until randconfigs.
CC: Andrew Lunn <andrew+netdev@lunn.ch>
CC: David S. Miller <davem@davemloft.net>
CC: Eric Dumazet <edumazet@google.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Paolo Abeni <pabeni@redhat.com>
CC: Nicolas Ferre <nicolas.ferre@microchip.com>
CC: Claudiu Beznea <claudiu.beznea@tuxon.dev>
CC: netdev@vger.kernel.org
CC: devicetree@vger.kernel.org
CC: linux-kernel@vger.kernel.org
CC: linux-riscv@lists.infradead.org
---
drivers/net/ethernet/cadence/macb_main.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 12e2b2f4aaf88..4f70e4fcf4606 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -5716,9 +5716,18 @@ static const struct macb_config pic64hpsc_config = {
.jumbo_max_len = 16383,
};
+static const struct macb_config macb_macb_config = {
+ .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE |
+ MACB_CAPS_JUMBO |
+ MACB_CAPS_GEM_HAS_PTP,
+ .dma_burst_length = 16,
+ .usrio = &at91_default_usrio,
+ .jumbo_max_len = 10240,
+};
+
static const struct of_device_id macb_dt_ids[] = {
{ .compatible = "cdns,at91sam9260-macb", .data = &at91sam9260_config },
- { .compatible = "cdns,macb" },
+ { .compatible = "cdns,macb", .data = &macb_macb_config},
{ .compatible = "cdns,np4-macb", .data = &np4_config },
{ .compatible = "cdns,pc302-gem", .data = &pc302gem_config },
{ .compatible = "cdns,gem", .data = &pc302gem_config },
@@ -5747,15 +5756,6 @@ static const struct of_device_id macb_dt_ids[] = {
MODULE_DEVICE_TABLE(of, macb_dt_ids);
#endif /* CONFIG_OF */
-static const struct macb_config default_gem_config = {
- .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE |
- MACB_CAPS_JUMBO |
- MACB_CAPS_GEM_HAS_PTP,
- .dma_burst_length = 16,
- .usrio = &at91_default_usrio,
- .jumbo_max_len = 10240,
-};
-
static int macb_probe(struct platform_device *pdev)
{
struct clk *pclk, *hclk = NULL, *tx_clk = NULL, *rx_clk = NULL;
@@ -5778,7 +5778,7 @@ static int macb_probe(struct platform_device *pdev)
macb_config = of_device_get_match_data(&pdev->dev);
if (!macb_config)
- macb_config = &default_gem_config;
+ return -EINVAL;
err = macb_clk_init(pdev, &pclk, &hclk, &tx_clk, &rx_clk, &tsu_clk,
macb_config);
--
2.53.0
^ permalink raw reply related
* Re: [PATCH v5 1/2] dt-bindings: phy: qcom: Add CSI2 C-PHY/DPHY schema
From: Bryan O'Donoghue @ 2026-03-30 9:02 UTC (permalink / raw)
To: Neil Armstrong, Konrad Dybcio, Vinod Koul, Kishon Vijay Abraham I,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Bryan O'Donoghue, Vladimir Zapolskiy, linux-arm-msm,
linux-phy, linux-media, devicetree, linux-kernel
In-Reply-To: <016c03b8-27c3-41dc-a630-8e7095db1f88@linaro.org>
On 30/03/2026 08:49, Neil Armstrong wrote:
> On 3/27/26 18:42, Bryan O'Donoghue wrote:
>> On 27/03/2026 15:28, Neil Armstrong wrote:
>>>> To be frankly honest you can make an argument for it either way.
>>>> However my honestly held position is analysing other upstream
>>>> implementations connecting to the PHY means we can't make the PHY
>>>> device a drivers/phy device - it would have to be a V4L2 device and
>>>> then for me the question is why is that even required ?
>>>
>>> This is plain wrong, DT definition is different from software
>>> implementation, you can do whatever you want if you describe HW
>>> accurately.
>>
>> I'm not sure what point it is you are trying to make here. Are you
>> trying to say drivers/phy is OK with you but you want an endpoint ? If
>> so, please just say so.
>
> I'm against using the "phys = <>" property in the CAMSS to reference the
> PHYs, a "PHY" in the classic terminology is tied to a single consumer,
> and if it can be shared to multiple consumer you must model a mux or
> whatever in the middle.
The CSIPHY-to-CSID routing is runtime-configurable and is already
managed by the media controller framework.
DT describes static hardware connections. The dynamic mux is a software
concern, not a hardware description concern.
> The PHY API as an internal software implementation is probably fine,
> even if it makes implementation of split mode much much harder and
> doesn't really solve anything, you can just call init()/poweron()/
> poweroff()/exit() directly from the CSIPHY media callbacks.
Great.
>> I can see an argument for that hence my response to Konrad, I just
>> don't see why its a Qualcomm specific argument and of course
>> understood stuff bubbles up in review, we have a public debate and
>> come to a consensus - that's a good thing.
>>
>> However, I'd want wider buy-in and understanding that endpoints in the
>> PHYs is a more accurate description of the data-flow.
>
> It is, and it was designed for that, and extensively used in the media
> DT representation, so I wonder here you would not use it...
> In an ideal world, you would add nodes for each CAMSS hw elements and
> adds port/endpoints links between all nodes to describe the data graph,
> this would be used to construct the media controller graph, and make it
> much easier supporting new hardware.
Yes but be pragmatic Neil. The first step in making the monolith into
sub-nodes is the CSIPHY.
Once the CSIPHY is in, we can follow on with adding new nodes that way
IPE, BPS, ICP, JPEG whatever and also work on implementing the old stuff
in that new way.
>
>>
>> We've been applying DT bindings aplenty without that so far. So we
>> would establish new CSI2 PHY bindings should represent the sensor
>> endpoints.
>
> We've been using a dummy representation of CAMM in a single node with
> only endpoints connecting to the sensors and hiding all the hardware
> layout in code, it doesn't scale and makes supporting new HW hard.
> I mean this is common sense, why would we continue to stick to the
> current CAMSS bindings ???
We _won't_ I just don't support a big bang integration. Progressive
changes over a longer timeline make the transition manageable, without
accepting endless sub-standard stuff in the meantime or holding up all
new SoC submission unless/until.
I mean there is a CAMSS meeting which I've been running for nearly a
year now that both you and Vlad are invited to where we have been
discussing this for months...
Anyway one conclusion of that is we want to transition to individual
nodes for everything.
PHY is the first step which I'm taking because its easier for me as
CAMSS maintainer to convince the CAMSS maintainer to take the relevant
patches.
drivers/phy notwithstanding.
>>
>> Is that what you want ?
>>
>>> The CSIPHYs are not tied to a single "consumer" block, they can be
>>> connected to different consumers at runtime, which is not something
>>> classic PHY devices are designed for. So they are de facto a media
>>> element in the dynamic camera pipeline.
>>
>> The existing CAMSS binding and media graph are not changed by this
>> series.
>
> This is not my point, I don't care about the software implementation at
> all, I care about accurate hardware representation. Using the "phys =
> <>" property does not describe hardware accurately.
>
> In other words: The CSIPHY are not connected to CAMSS. This is _not_
> true, tying the CSIPHYs to the CAMSS block hides the real data muxing in
> software.
>
> Please remind DT is used by multiple operating systems, and properly
> describing hardware in DT will help have good software support over all
> OSes, not just Linux.
>
>>
>>> And actually Rob Herring asked use to define the complete data flow,
>>> it was a strong requirement. I don't see why we wouldn't here.
>>
>> I'm implementing feedback from Rob.
>>
>> https://lore.kernel.org/linux-media/20250710230846.GA44483-
>> robh@kernel.org/
>
> Where did he ask using the PHY DT bindings ? Is he aware those CSIPHYs
> are muxed to multiple consumers which are burried in the CAMSS code ?
I freely admit to taking the initiative of phys = <> but Neil there is
_no_change_ to the media graph and the "mux" is a runtime configuration
that is one register in the CSID.
You seriously want a mux device in the kernel to model one bit in a
register ?
No.
>>
>> To me, here is where we stand:
>>
>> - Individual nodes - we all agree that
>> - As sub-nodes - I think the majority agrees this Krzsztof, Dmitry
>> I'm fine with it too.
>> - drivers/phy - I think we are accepting this is also fine ?
>
> Like I said this adds a supplementary API layer for no reason and will
> make life harder, but I don't care personally.
>
>> - endpoints should flow into the PHY and then back to the controller
>>
>> I get that argument. In fact I _like_ that argument at least I like my
>> conception of that argument.
>>
>> I'll stipulate to that argument meaning then that, new CSI2 PHYs shall
>> include endpoints for this purpose globally.
>>
>> As I've said before, there's nothing Qualcomm specific about this
>> discussion, really.
>
> There is, because the current Qualcomm CAMSS bindings are insufficient
> and should be entirely redesigned from the ground up to properly
> describe the HW.
The long term plan is to do that. Discussed extensively with the Qcom
teams delivering CAMSS, even invited community members along.
Here are the meeting notes - its all in the public domain
https://docs.google.com/document/d/1yUwWHaKLuovKVgGTzvKm68K1zS6xBONVzjOsRjDl03U/edit?tab=t.0#heading=h.mtbm7qfohwfs
---
bod
^ permalink raw reply
* Re: [PATCH v2 4/9] mm: move free_reserved_area() to mm/memblock.c
From: Vlastimil Babka (SUSE) @ 2026-03-30 9:00 UTC (permalink / raw)
To: Mike Rapoport, Andrew Morton
Cc: Alexander Potapenko, Alexander Viro, Andreas Larsson,
Ard Biesheuvel, Borislav Petkov, Brendan Jackman,
Christophe Leroy (CS GROUP), Catalin Marinas, Christian Brauner,
David S. Miller, Dave Hansen, David Hildenbrand, Dmitry Vyukov,
Ilias Apalodimas, Ingo Molnar, Jan Kara, Johannes Weiner,
Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
Marco Elver, Marek Szyprowski, Masami Hiramatsu, Michael Ellerman,
Michal Hocko, Nicholas Piggin, H. Peter Anvin, Rob Herring,
Robin Murphy, Saravana Kannan, Suren Baghdasaryan,
Thomas Gleixner, Will Deacon, Zi Yan, devicetree, iommu,
kasan-dev, linux-arm-kernel, linux-efi, linux-fsdevel,
linux-kernel, linux-mm, linux-trace-kernel, linuxppc-dev,
sparclinux, x86
In-Reply-To: <20260323074836.3653702-5-rppt@kernel.org>
On 3/23/26 08:48, Mike Rapoport wrote:
> From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
>
> free_reserved_area() is related to memblock as it frees reserved memory
> back to the buddy allocator, similar to what memblock_free_late() does.
>
> Move free_reserved_area() to mm/memblock.c to prepare for further
> consolidation of the functions that free reserved memory.
>
> No functional changes.
>
> Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
^ permalink raw reply
* Re: [PATCH v11 6/7] media: qcom: camss: Add support for PHY API devices
From: Loic Poulain @ 2026-03-30 8:55 UTC (permalink / raw)
To: Bryan O'Donoghue
Cc: Bjorn Andersson, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Robert Foss, Todor Tomov,
Mauro Carvalho Chehab, Konrad Dybcio, Vladimir Zapolskiy,
Bryan O'Donoghue, linux-arm-msm, linux-clk, devicetree,
linux-kernel, linux-media, Krzysztof Kozlowski,
Christopher Obbard
In-Reply-To: <20260326-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v11-6-5b93415be6dd@linaro.org>
Hi Bryan,
On Thu, Mar 26, 2026 at 2:29 AM Bryan O'Donoghue
<bryan.odonoghue@linaro.org> wrote:
>
> Add the ability to use a PHY pointer which interacts with the standard PHY
> API.
>
> In the first instance the code will try to use the new PHY interface. If no
> PHYs are present in the DT then the legacy method will be attempted.
This looks good and pragmatic to me. I just wanted to raise another
idea for discussion: would it be feasible to always rely on the PHY
interface, without maintaining a separate legacy path, by creating a
platform_device and attached resources from the legacy PHY
descriptors? This would allow camss driver to handle both cases
uniformly.
>
> Reviewed-by: Christopher Obbard <christopher.obbard@linaro.org>
> Tested-by: Christopher Obbard <christopher.obbard@linaro.org>
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
> drivers/media/platform/qcom/camss/Kconfig | 1 +
> drivers/media/platform/qcom/camss/camss-csiphy.c | 189 +++++++++++++++++++++--
> drivers/media/platform/qcom/camss/camss-csiphy.h | 7 +
> drivers/media/platform/qcom/camss/camss.c | 72 +++++++--
> 4 files changed, 239 insertions(+), 30 deletions(-)
^ permalink raw reply
* [PATCH v3 7/7] arm64: tegra: Add PWM controllers on Tegra264
From: Mikko Perttunen @ 2026-03-30 8:53 UTC (permalink / raw)
To: Thierry Reding, Uwe Kleine-König, Jonathan Hunter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pwm, linux-tegra, linux-kernel, devicetree, Thierry Reding,
Mikko Perttunen
In-Reply-To: <20260330-t264-pwm-v3-0-5714427d5976@nvidia.com>
From: Thierry Reding <treding@nvidia.com>
Tegra264 has a number of PWM controllers that are similar but
incompatible with those found on earlier chips.
Signed-off-by: Thierry Reding <treding@nvidia.com>
[mperttunen: Adjust commit message]
Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
---
arch/arm64/boot/dts/nvidia/tegra264.dtsi | 72 ++++++++++++++++++++++++++++++++
1 file changed, 72 insertions(+)
diff --git a/arch/arm64/boot/dts/nvidia/tegra264.dtsi b/arch/arm64/boot/dts/nvidia/tegra264.dtsi
index 7644a41d5f72..13fd04068016 100644
--- a/arch/arm64/boot/dts/nvidia/tegra264.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra264.dtsi
@@ -3336,6 +3336,18 @@ i2c3: i2c@c610000 {
status = "disabled";
};
+ pwm4: pwm@c6a0000 {
+ compatible = "nvidia,tegra264-pwm";
+ reg = <0x0 0xc6a0000 0x0 0x10000>;
+ status = "disabled";
+
+ clocks = <&bpmp TEGRA264_CLK_PWM4>;
+ resets = <&bpmp TEGRA264_RESET_PWM4>;
+ reset-names = "pwm";
+
+ #pwm-cells = <2>;
+ };
+
pmc: pmc@c800000 {
compatible = "nvidia,tegra264-pmc";
reg = <0x0 0x0c800000 0x0 0x100000>,
@@ -3538,6 +3550,66 @@ i2c16: i2c@c430000 {
status = "disabled";
};
+ pwm2: pwm@c5e0000 {
+ compatible = "nvidia,tegra264-pwm";
+ reg = <0x0 0xc5e0000 0x0 0x10000>;
+ status = "disabled";
+
+ clocks = <&bpmp TEGRA264_CLK_PWM2>;
+ resets = <&bpmp TEGRA264_RESET_PWM2>;
+ reset-names = "pwm";
+
+ #pwm-cells = <2>;
+ };
+
+ pwm3: pwm@c5f0000 {
+ compatible = "nvidia,tegra264-pwm";
+ reg = <0x0 0xc5f0000 0x0 0x10000>;
+ status = "disabled";
+
+ clocks = <&bpmp TEGRA264_CLK_PWM3>;
+ resets = <&bpmp TEGRA264_RESET_PWM3>;
+ reset-names = "pwm";
+
+ #pwm-cells = <2>;
+ };
+
+ pwm5: pwm@c600000 {
+ compatible = "nvidia,tegra264-pwm";
+ reg = <0x0 0xc600000 0x0 0x10000>;
+ status = "disabled";
+
+ clocks = <&bpmp TEGRA264_CLK_PWM5>;
+ resets = <&bpmp TEGRA264_RESET_PWM5>;
+ reset-names = "pwm";
+
+ #pwm-cells = <2>;
+ };
+
+ pwm9: pwm@c610000 {
+ compatible = "nvidia,tegra264-pwm";
+ reg = <0x0 0xc610000 0x0 0x10000>;
+ status = "disabled";
+
+ clocks = <&bpmp TEGRA264_CLK_PWM9>;
+ resets = <&bpmp TEGRA264_RESET_PWM9>;
+ reset-names = "pwm";
+
+ #pwm-cells = <2>;
+ };
+
+ pwm10: pwm@c620000 {
+ compatible = "nvidia,tegra264-pwm";
+ reg = <0x0 0xc620000 0x0 0x10000>;
+ status = "disabled";
+
+ clocks = <&bpmp TEGRA264_CLK_PWM10>;
+ resets = <&bpmp TEGRA264_RESET_PWM10>;
+ reset-names = "pwm";
+
+ #pwm-cells = <2>;
+ };
+
i2c0: i2c@c630000 {
compatible = "nvidia,tegra264-i2c";
reg = <0x00 0x0c630000 0x0 0x10000>;
--
2.53.0
^ permalink raw reply related
* [PATCH v3 6/7] pwm: tegra: Add support for Tegra264
From: Mikko Perttunen @ 2026-03-30 8:53 UTC (permalink / raw)
To: Thierry Reding, Uwe Kleine-König, Jonathan Hunter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pwm, linux-tegra, linux-kernel, devicetree, Yi-Wei Wang,
Mikko Perttunen
In-Reply-To: <20260330-t264-pwm-v3-0-5714427d5976@nvidia.com>
Tegra264 changes the register layout to accommodate wider fields
for duty and scale, and adds configurable depth which will be
supported in a later patch.
Add SoC data and update top comment to describe register layout
in more detail.
Co-developed-by: Yi-Wei Wang <yiweiw@nvidia.com>
Signed-off-by: Yi-Wei Wang <yiweiw@nvidia.com>
Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
---
drivers/pwm/pwm-tegra.c | 75 ++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 61 insertions(+), 14 deletions(-)
diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c
index 857301baad51..c1e8a804d783 100644
--- a/drivers/pwm/pwm-tegra.c
+++ b/drivers/pwm/pwm-tegra.c
@@ -7,22 +7,60 @@
* Copyright (c) 2010-2020, NVIDIA Corporation.
* Based on arch/arm/plat-mxc/pwm.c by Sascha Hauer <s.hauer@pengutronix.de>
*
- * Overview of Tegra Pulse Width Modulator Register:
- * 1. 13-bit: Frequency division (SCALE)
- * 2. 8-bit : Pulse division (DUTY)
- * 3. 1-bit : Enable bit
+ * Overview of Tegra Pulse Width Modulator Register
+ * CSR_0 of Tegra20, Tegra186, and Tegra194:
+ * +-------+-------+-----------------------------------------------------------+
+ * | Bit | Field | Description |
+ * +-------+-------+-----------------------------------------------------------+
+ * | 31 | ENB | Enable Pulse width modulator. |
+ * | | | 0 = DISABLE, 1 = ENABLE. |
+ * +-------+-------+-----------------------------------------------------------+
+ * | 30:16 | PWM_0 | Pulse width that needs to be programmed. |
+ * | | | 0 = Always low. |
+ * | | | 1 = 1 / 256 pulse high. |
+ * | | | 2 = 2 / 256 pulse high. |
+ * | | | N = N / 256 pulse high. |
+ * | | | Only 8 bits are usable [23:16]. |
+ * | | | Bit[24] can be programmed to 1 to achieve 100% duty |
+ * | | | cycle. In this case the other bits [23:16] are set to |
+ * | | | don’t care. |
+ * +-------+-------+-----------------------------------------------------------+
+ * | 12:0 | PFM_0 | Frequency divider that needs to be programmed, also known |
+ * | | | as SCALE. Division by (1 + PFM_0). |
+ * +-------+-------+-----------------------------------------------------------+
*
- * The PWM clock frequency is divided by 256 before subdividing it based
- * on the programmable frequency division value to generate the required
- * frequency for PWM output. The maximum output frequency that can be
- * achieved is (max rate of source clock) / 256.
- * e.g. if source clock rate is 408 MHz, maximum output frequency can be:
- * 408 MHz/256 = 1.6 MHz.
- * This 1.6 MHz frequency can further be divided using SCALE value in PWM.
+ * CSR_0 of Tegra264:
+ * +-------+-------+-----------------------------------------------------------+
+ * | Bit | Field | Description |
+ * +-------+-------+-----------------------------------------------------------+
+ * | 31:16 | PWM_0 | Pulse width that needs to be programmed. |
+ * | | | 0 = Always low. |
+ * | | | 1 = 1 / (1 + CSR_1.DEPTH) pulse high. |
+ * | | | 2 = 2 / (1 + CSR_1.DEPTH) pulse high. |
+ * | | | N = N / (1 + CSR_1.DEPTH) pulse high. |
+ * +-------+-------+-----------------------------------------------------------+
+ * | 15:0 | PFM_0 | Frequency divider that needs to be programmed, also known |
+ * | | | as SCALE. Division by (1 + PFM_0). |
+ * +-------+-------+-----------------------------------------------------------+
+ *
+ * CSR_1 of Tegra264:
+ * +-------+-------+-----------------------------------------------------------+
+ * | Bit | Field | Description |
+ * +-------+-------+-----------------------------------------------------------+
+ * | 31 | ENB | Enable Pulse width modulator. |
+ * | | | 0 = DISABLE, 1 = ENABLE. |
+ * +-------+-------+-----------------------------------------------------------+
+ * | 30:15 | DEPTH | Depth for pulse width modulator. This controls the pulse |
+ * | | | time generated. Division by (1 + CSR_1.DEPTH). |
+ * +-------+-------+-----------------------------------------------------------+
*
- * PWM pulse width: 8 bits are usable [23:16] for varying pulse width.
- * To achieve 100% duty cycle, program Bit [24] of this register to
- * 1’b1. In which case the other bits [23:16] are set to don't care.
+ * The PWM clock frequency is divided by DEPTH = (1 + CSR_1.DEPTH) before subdividing it
+ * based on the programmable frequency division value to generate the required frequency
+ * for PWM output. DEPTH is fixed to 256 before Tegra264. The maximum output frequency
+ * that can be achieved is (max rate of source clock) / DEPTH.
+ * e.g. if source clock rate is 408 MHz, and DEPTH = 256, maximum output frequency can be:
+ * 408 MHz / 256 ~= 1.6 MHz.
+ * This 1.6 MHz frequency can further be divided using SCALE value in PWM.
*
* Limitations:
* - When PWM is disabled, the output is driven to inactive.
@@ -56,6 +94,7 @@
#define PWM_SCALE_SHIFT 0
#define PWM_CSR_0 0
+#define PWM_CSR_1 4
#define PWM_DEPTH 256
@@ -418,10 +457,18 @@ static const struct tegra_pwm_soc tegra186_pwm_soc = {
.scale_width = 13,
};
+static const struct tegra_pwm_soc tegra264_pwm_soc = {
+ .num_channels = 1,
+ .enable_reg = PWM_CSR_1,
+ .duty_width = 16,
+ .scale_width = 16,
+};
+
static const struct of_device_id tegra_pwm_of_match[] = {
{ .compatible = "nvidia,tegra20-pwm", .data = &tegra20_pwm_soc },
{ .compatible = "nvidia,tegra186-pwm", .data = &tegra186_pwm_soc },
{ .compatible = "nvidia,tegra194-pwm", .data = &tegra186_pwm_soc },
+ { .compatible = "nvidia,tegra264-pwm", .data = &tegra264_pwm_soc },
{ }
};
MODULE_DEVICE_TABLE(of, tegra_pwm_of_match);
--
2.53.0
^ permalink raw reply related
* [PATCH v3 5/7] pwm: tegra: Parametrize duty and scale field widths
From: Mikko Perttunen @ 2026-03-30 8:53 UTC (permalink / raw)
To: Thierry Reding, Uwe Kleine-König, Jonathan Hunter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pwm, linux-tegra, linux-kernel, devicetree, Yi-Wei Wang,
Thierry Reding, Mikko Perttunen
In-Reply-To: <20260330-t264-pwm-v3-0-5714427d5976@nvidia.com>
Tegra264 has wider fields for the duty and scale register fields.
Parameterize the driver in preparation. The depth value also
becomes disconnected from the width of the duty field, so define
it separately.
Co-developed-by: Yi-Wei Wang <yiweiw@nvidia.com>
Signed-off-by: Yi-Wei Wang <yiweiw@nvidia.com>
Reviewed-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
---
drivers/pwm/pwm-tegra.c | 29 ++++++++++++++++++-----------
1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c
index 22d709986e8c..857301baad51 100644
--- a/drivers/pwm/pwm-tegra.c
+++ b/drivers/pwm/pwm-tegra.c
@@ -52,16 +52,19 @@
#include <soc/tegra/common.h>
#define PWM_ENABLE (1 << 31)
-#define PWM_DUTY_WIDTH 8
#define PWM_DUTY_SHIFT 16
-#define PWM_SCALE_WIDTH 13
#define PWM_SCALE_SHIFT 0
#define PWM_CSR_0 0
+#define PWM_DEPTH 256
+
struct tegra_pwm_soc {
unsigned int num_channels;
unsigned int enable_reg;
+
+ unsigned int duty_width;
+ unsigned int scale_width;
};
struct tegra_pwm_chip {
@@ -106,22 +109,22 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
/*
* Convert from duty_ns / period_ns to a fixed number of duty ticks
- * per (1 << PWM_DUTY_WIDTH) cycles and make sure to round to the
+ * per PWM_DEPTH cycles and make sure to round to the
* nearest integer during division.
*/
- c *= (1 << PWM_DUTY_WIDTH);
+ c *= PWM_DEPTH;
c = DIV_ROUND_CLOSEST_ULL(c, period_ns);
val = (u32)c << PWM_DUTY_SHIFT;
/*
- * min period = max clock limit >> PWM_DUTY_WIDTH
+ * min period = max clock limit / PWM_DEPTH
*/
if (period_ns < pc->min_period_ns)
return -EINVAL;
/*
- * Compute the prescaler value for which (1 << PWM_DUTY_WIDTH)
+ * Compute the prescaler value for which PWM_DEPTH
* cycles at the PWM clock rate will take period_ns nanoseconds.
*
* num_channels: If single instance of PWM controller has multiple
@@ -135,7 +138,7 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
*/
if (pc->soc->num_channels == 1) {
/*
- * Rate is multiplied with 2^PWM_DUTY_WIDTH so that it matches
+ * Rate is multiplied with PWM_DEPTH so that it matches
* with the maximum possible rate that the controller can
* provide. Any further lower value can be derived by setting
* PFM bits[0:12].
@@ -145,7 +148,7 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
* source clock rate as required_clk_rate, PWM controller will
* be able to configure the requested period.
*/
- required_clk_rate = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC << PWM_DUTY_WIDTH,
+ required_clk_rate = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * PWM_DEPTH,
period_ns);
if (required_clk_rate > clk_round_rate(pc->clk, required_clk_rate))
@@ -169,7 +172,7 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
/* Consider precision in PWM_SCALE_WIDTH rate calculation */
rate = mul_u64_u64_div_u64(pc->clk_rate, period_ns,
- (u64)NSEC_PER_SEC << PWM_DUTY_WIDTH);
+ (u64)NSEC_PER_SEC * PWM_DEPTH);
/*
* Since the actual PWM divider is the register's frequency divider
@@ -185,7 +188,7 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
* Make sure that the rate will fit in the register's frequency
* divider field.
*/
- if (rate >> PWM_SCALE_WIDTH)
+ if (rate >> pc->soc->scale_width)
return -EINVAL;
val |= rate << PWM_SCALE_SHIFT;
@@ -324,7 +327,7 @@ static int tegra_pwm_probe(struct platform_device *pdev)
/* Set minimum limit of PWM period for the IP */
pc->min_period_ns =
- (NSEC_PER_SEC / (pc->clk_rate >> PWM_DUTY_WIDTH)) + 1;
+ (NSEC_PER_SEC / (pc->clk_rate / PWM_DEPTH)) + 1;
pc->rst = devm_reset_control_get_exclusive(&pdev->dev, "pwm");
if (IS_ERR(pc->rst)) {
@@ -404,11 +407,15 @@ static int __maybe_unused tegra_pwm_runtime_resume(struct device *dev)
static const struct tegra_pwm_soc tegra20_pwm_soc = {
.num_channels = 4,
.enable_reg = PWM_CSR_0,
+ .duty_width = 8,
+ .scale_width = 13,
};
static const struct tegra_pwm_soc tegra186_pwm_soc = {
.num_channels = 1,
.enable_reg = PWM_CSR_0,
+ .duty_width = 8,
+ .scale_width = 13,
};
static const struct of_device_id tegra_pwm_of_match[] = {
--
2.53.0
^ permalink raw reply related
* [PATCH v3 4/7] pwm: tegra: Parametrize enable register offset
From: Mikko Perttunen @ 2026-03-30 8:53 UTC (permalink / raw)
To: Thierry Reding, Uwe Kleine-König, Jonathan Hunter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pwm, linux-tegra, linux-kernel, devicetree, Yi-Wei Wang,
Mikko Perttunen
In-Reply-To: <20260330-t264-pwm-v3-0-5714427d5976@nvidia.com>
On Tegra264, the PWM enablement bit is not located at the base address
of the PWM controller. Hence, introduce an enablement offset field in
the tegra_pwm_soc structure to describe the offset of the register.
Co-developed-by: Yi-Wei Wang <yiweiw@nvidia.com>
Signed-off-by: Yi-Wei Wang <yiweiw@nvidia.com>
Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
---
drivers/pwm/pwm-tegra.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c
index cf54f75d92a5..22d709986e8c 100644
--- a/drivers/pwm/pwm-tegra.c
+++ b/drivers/pwm/pwm-tegra.c
@@ -61,6 +61,7 @@
struct tegra_pwm_soc {
unsigned int num_channels;
+ unsigned int enable_reg;
};
struct tegra_pwm_chip {
@@ -197,8 +198,9 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
err = pm_runtime_resume_and_get(pwmchip_parent(chip));
if (err)
return err;
- } else
+ } else if (pc->soc->enable_reg == PWM_CSR_0) {
val |= PWM_ENABLE;
+ }
pwm_writel(pwm, PWM_CSR_0, val);
@@ -213,6 +215,7 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
static int tegra_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
+ struct tegra_pwm_chip *pc = to_tegra_pwm_chip(chip);
int rc = 0;
u32 val;
@@ -220,20 +223,22 @@ static int tegra_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
if (rc)
return rc;
- val = pwm_readl(pwm, PWM_CSR_0);
+
+ val = pwm_readl(pwm, pc->soc->enable_reg);
val |= PWM_ENABLE;
- pwm_writel(pwm, PWM_CSR_0, val);
+ pwm_writel(pwm, pc->soc->enable_reg, val);
return 0;
}
static void tegra_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
{
+ struct tegra_pwm_chip *pc = to_tegra_pwm_chip(chip);
u32 val;
- val = pwm_readl(pwm, PWM_CSR_0);
+ val = pwm_readl(pwm, pc->soc->enable_reg);
val &= ~PWM_ENABLE;
- pwm_writel(pwm, PWM_CSR_0, val);
+ pwm_writel(pwm, pc->soc->enable_reg, val);
pm_runtime_put_sync(pwmchip_parent(chip));
}
@@ -398,10 +403,12 @@ static int __maybe_unused tegra_pwm_runtime_resume(struct device *dev)
static const struct tegra_pwm_soc tegra20_pwm_soc = {
.num_channels = 4,
+ .enable_reg = PWM_CSR_0,
};
static const struct tegra_pwm_soc tegra186_pwm_soc = {
.num_channels = 1,
+ .enable_reg = PWM_CSR_0,
};
static const struct of_device_id tegra_pwm_of_match[] = {
--
2.53.0
^ permalink raw reply related
* [PATCH v3 3/7] pwm: tegra: Modify read/write accessors for multi-register channel
From: Mikko Perttunen @ 2026-03-30 8:53 UTC (permalink / raw)
To: Thierry Reding, Uwe Kleine-König, Jonathan Hunter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pwm, linux-tegra, linux-kernel, devicetree, Thierry Reding,
Mikko Perttunen
In-Reply-To: <20260330-t264-pwm-v3-0-5714427d5976@nvidia.com>
On Tegra264, each PWM instance has two registers (per channel, of which
there is one). Update the pwm_readl/pwm_writel helper functions to
take channel (as struct pwm_device *) and offset separately.
Reviewed-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
---
drivers/pwm/pwm-tegra.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c
index 759b98b97b6e..cf54f75d92a5 100644
--- a/drivers/pwm/pwm-tegra.c
+++ b/drivers/pwm/pwm-tegra.c
@@ -57,6 +57,8 @@
#define PWM_SCALE_WIDTH 13
#define PWM_SCALE_SHIFT 0
+#define PWM_CSR_0 0
+
struct tegra_pwm_soc {
unsigned int num_channels;
};
@@ -78,14 +80,18 @@ static inline struct tegra_pwm_chip *to_tegra_pwm_chip(struct pwm_chip *chip)
return pwmchip_get_drvdata(chip);
}
-static inline u32 pwm_readl(struct tegra_pwm_chip *pc, unsigned int offset)
+static inline u32 pwm_readl(struct pwm_device *dev, unsigned int offset)
{
- return readl(pc->regs + (offset << 4));
+ struct tegra_pwm_chip *chip = to_tegra_pwm_chip(dev->chip);
+
+ return readl(chip->regs + (dev->hwpwm * 16) + offset);
}
-static inline void pwm_writel(struct tegra_pwm_chip *pc, unsigned int offset, u32 value)
+static inline void pwm_writel(struct pwm_device *dev, unsigned int offset, u32 value)
{
- writel(value, pc->regs + (offset << 4));
+ struct tegra_pwm_chip *chip = to_tegra_pwm_chip(dev->chip);
+
+ writel(value, chip->regs + (dev->hwpwm * 16) + offset);
}
static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -194,7 +200,7 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
} else
val |= PWM_ENABLE;
- pwm_writel(pc, pwm->hwpwm, val);
+ pwm_writel(pwm, PWM_CSR_0, val);
/*
* If the PWM is not enabled, turn the clock off again to save power.
@@ -207,7 +213,6 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
static int tegra_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
- struct tegra_pwm_chip *pc = to_tegra_pwm_chip(chip);
int rc = 0;
u32 val;
@@ -215,21 +220,20 @@ static int tegra_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
if (rc)
return rc;
- val = pwm_readl(pc, pwm->hwpwm);
+ val = pwm_readl(pwm, PWM_CSR_0);
val |= PWM_ENABLE;
- pwm_writel(pc, pwm->hwpwm, val);
+ pwm_writel(pwm, PWM_CSR_0, val);
return 0;
}
static void tegra_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
{
- struct tegra_pwm_chip *pc = to_tegra_pwm_chip(chip);
u32 val;
- val = pwm_readl(pc, pwm->hwpwm);
+ val = pwm_readl(pwm, PWM_CSR_0);
val &= ~PWM_ENABLE;
- pwm_writel(pc, pwm->hwpwm, val);
+ pwm_writel(pwm, PWM_CSR_0, val);
pm_runtime_put_sync(pwmchip_parent(chip));
}
--
2.53.0
^ permalink raw reply related
* [PATCH v3 2/7] pwm: tegra: Avoid hard-coded max clock frequency
From: Mikko Perttunen @ 2026-03-30 8:53 UTC (permalink / raw)
To: Thierry Reding, Uwe Kleine-König, Jonathan Hunter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pwm, linux-tegra, linux-kernel, devicetree, Yi-Wei Wang,
Thierry Reding, Mikko Perttunen
In-Reply-To: <20260330-t264-pwm-v3-0-5714427d5976@nvidia.com>
From: Yi-Wei Wang <yiweiw@nvidia.com>
The clock driving the Tegra PWM IP can be sourced from different parent
clocks. Hence, let dev_pm_opp_set_rate() set the max clock rate based
upon the current parent clock that can be specified via device-tree.
After this, the Tegra194 SoC data becomes redundant, so get rid of it.
Signed-off-by: Yi-Wei Wang <yiweiw@nvidia.com>
Reviewed-by: Thierry Reding <treding@nvidia.com>
Co-developed-by: Mikko Perttunen <mperttunen@nvidia.com>
Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
---
drivers/pwm/pwm-tegra.c | 16 +++-------------
1 file changed, 3 insertions(+), 13 deletions(-)
diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c
index 172063b51d44..759b98b97b6e 100644
--- a/drivers/pwm/pwm-tegra.c
+++ b/drivers/pwm/pwm-tegra.c
@@ -59,9 +59,6 @@
struct tegra_pwm_soc {
unsigned int num_channels;
-
- /* Maximum IP frequency for given SoCs */
- unsigned long max_frequency;
};
struct tegra_pwm_chip {
@@ -303,7 +300,7 @@ static int tegra_pwm_probe(struct platform_device *pdev)
return ret;
/* Set maximum frequency of the IP */
- ret = dev_pm_opp_set_rate(&pdev->dev, pc->soc->max_frequency);
+ ret = dev_pm_opp_set_rate(&pdev->dev, S64_MAX);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to set max frequency: %d\n", ret);
goto put_pm;
@@ -318,7 +315,7 @@ static int tegra_pwm_probe(struct platform_device *pdev)
/* Set minimum limit of PWM period for the IP */
pc->min_period_ns =
- (NSEC_PER_SEC / (pc->soc->max_frequency >> PWM_DUTY_WIDTH)) + 1;
+ (NSEC_PER_SEC / (pc->clk_rate >> PWM_DUTY_WIDTH)) + 1;
pc->rst = devm_reset_control_get_exclusive(&pdev->dev, "pwm");
if (IS_ERR(pc->rst)) {
@@ -397,23 +394,16 @@ static int __maybe_unused tegra_pwm_runtime_resume(struct device *dev)
static const struct tegra_pwm_soc tegra20_pwm_soc = {
.num_channels = 4,
- .max_frequency = 48000000UL,
};
static const struct tegra_pwm_soc tegra186_pwm_soc = {
.num_channels = 1,
- .max_frequency = 102000000UL,
-};
-
-static const struct tegra_pwm_soc tegra194_pwm_soc = {
- .num_channels = 1,
- .max_frequency = 408000000UL,
};
static const struct of_device_id tegra_pwm_of_match[] = {
{ .compatible = "nvidia,tegra20-pwm", .data = &tegra20_pwm_soc },
{ .compatible = "nvidia,tegra186-pwm", .data = &tegra186_pwm_soc },
- { .compatible = "nvidia,tegra194-pwm", .data = &tegra194_pwm_soc },
+ { .compatible = "nvidia,tegra194-pwm", .data = &tegra186_pwm_soc },
{ }
};
MODULE_DEVICE_TABLE(of, tegra_pwm_of_match);
--
2.53.0
^ permalink raw reply related
* [PATCH v3 1/7] dt-bindings: pwm: Document Tegra264 controller
From: Mikko Perttunen @ 2026-03-30 8:53 UTC (permalink / raw)
To: Thierry Reding, Uwe Kleine-König, Jonathan Hunter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pwm, linux-tegra, linux-kernel, devicetree, Thierry Reding,
Mikko Perttunen
In-Reply-To: <20260330-t264-pwm-v3-0-5714427d5976@nvidia.com>
From: Thierry Reding <treding@nvidia.com>
Add a new compatible string for the PWM controller found on Tegra264.
The controller is similar to earlier generations but not compatible
with them.
Signed-off-by: Thierry Reding <treding@nvidia.com>
[mperttunen: Drop extra Tegra194 compatible string]
Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
---
Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.yaml b/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.yaml
index 41cea4979132..cb2f36e7b5d6 100644
--- a/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.yaml
+++ b/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.yaml
@@ -16,6 +16,7 @@ properties:
- enum:
- nvidia,tegra20-pwm
- nvidia,tegra186-pwm
+ - nvidia,tegra264-pwm
- items:
- enum:
--
2.53.0
^ permalink raw reply related
* [PATCH v3 0/7] Tegra264 PWM support
From: Mikko Perttunen @ 2026-03-30 8:53 UTC (permalink / raw)
To: Thierry Reding, Uwe Kleine-König, Jonathan Hunter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-pwm, linux-tegra, linux-kernel, devicetree, Thierry Reding,
Mikko Perttunen, Yi-Wei Wang
Hello,
this adds support for the PWM controller on Tegra264. The controller
is similar to previous generations, but the register fields are
widened, the depth is made configurable, and the enable bit moves
to a different spot.
This series adds only basic support with fixed depth -- configurable
depth will come later.
Patch 1 adds device tree bindings for Tegra264 PWM (compatible
string).
Patches 2 to 6 contain the PWM driver changes.
Patch 7 adds device tree nodes for the PWM controllers on Tegra264.
Thanks,
Mikko
---
Changes in v3:
- Fixed device tree binding patch.
- Picked up trailers.
- Link to v2: https://lore.kernel.org/r/20260325-t264-pwm-v2-0-998d885984b3@nvidia.com
Changes in v2:
- Added device tree binding and Tegra264 device tree patches by Thierry.
- Link to v1: https://lore.kernel.org/r/20260323-t264-pwm-v1-0-4c4ff743050f@nvidia.com
---
Mikko Perttunen (4):
pwm: tegra: Modify read/write accessors for multi-register channel
pwm: tegra: Parametrize enable register offset
pwm: tegra: Parametrize duty and scale field widths
pwm: tegra: Add support for Tegra264
Thierry Reding (2):
dt-bindings: pwm: Document Tegra264 controller
arm64: tegra: Add PWM controllers on Tegra264
Yi-Wei Wang (1):
pwm: tegra: Avoid hard-coded max clock frequency
.../bindings/pwm/nvidia,tegra20-pwm.yaml | 1 +
arch/arm64/boot/dts/nvidia/tegra264.dtsi | 72 +++++++++++
drivers/pwm/pwm-tegra.c | 141 ++++++++++++++-------
3 files changed, 171 insertions(+), 43 deletions(-)
---
base-commit: 11439c4635edd669ae435eec308f4ab8a0804808
change-id: 20260303-t264-pwm-57e10d039df1
^ permalink raw reply
* Re: [PATCH v4 2/2] pinctrl: qcom: Introduce IPQ5210 TLMM driver
From: Linus Walleij @ 2026-03-30 8:49 UTC (permalink / raw)
To: Kathiravan Thirumoorthy, Mukesh Ojha
Cc: Bjorn Andersson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
linux-arm-msm, linux-gpio, devicetree, linux-kernel,
Konrad Dybcio
In-Reply-To: <CAD++jLnwqDgKJMEBomgGSt-Mo90Tp0Or0EdRx3MkhM9D9dj=4g@mail.gmail.com>
On Mon, Mar 30, 2026 at 10:45 AM Linus Walleij <linusw@kernel.org> wrote:
> right before merging this patch I merged:
> https://lore.kernel.org/linux-gpio/20260327171240.3222755-2-mukesh.ojha@oss.qualcomm.com/
>
> On Mon, Mar 30, 2026 at 6:51 AM Kathiravan Thirumoorthy
> <kathiravan.thirumoorthy@oss.qualcomm.com> wrote:
>
> > + .intr_status_reg = 0xc + REG_SIZE * id, \
> > + .intr_target_reg = 0x8 + REG_SIZE * id, \
> (...)
>
> Should intr_target_reg be dropped also from this driver?
>
> If so, please send a follow-up patch.
After reading closer I can see it definitely should be dropped
so I just augmented the patch.
No need to do anything.
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: clock: qcom: Add missing power-domains property
From: Konrad Dybcio @ 2026-03-30 8:47 UTC (permalink / raw)
To: Abel Vesa, Krzysztof Kozlowski
Cc: Bjorn Andersson, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Luca Weiss, Taniya Das,
Konrad Dybcio, Dmitry Baryshkov, linux-arm-msm, linux-clk,
devicetree, linux-kernel
In-Reply-To: <szijgc6icwkzlssrxa5ceawgzaq73jo6lei6yubaxltbw64x5t@ru6x7a32igji>
On 3/27/26 2:45 PM, Abel Vesa wrote:
> On 26-03-27 14:37:17, Krzysztof Kozlowski wrote:
>> On 27/03/2026 13:13, Abel Vesa wrote:
>>> In order for the GCC votes on the GDSCs it provides to be propagated
>>> to CX, CX needs to be declared as power domain of the GCC.
>>
>> I assume this is true for Milos, not only Eliza.
>
> My understanding of it is that this is true for all platforms.
I think we once had
required:
- power-domains
in some common include, but that expectation fell apart as IPQ/router
platforms without RPM/RPMH started coming up. Maybe splitting gcc.yaml
into gcc.yaml and gcc-no-rpm.yaml or something could be useful to ensure
this common constraint
Konrad
^ permalink raw reply
* Re: [PATCH v4 2/2] pinctrl: qcom: Introduce IPQ5210 TLMM driver
From: Linus Walleij @ 2026-03-30 8:45 UTC (permalink / raw)
To: Kathiravan Thirumoorthy, Mukesh Ojha
Cc: Bjorn Andersson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
linux-arm-msm, linux-gpio, devicetree, linux-kernel,
Konrad Dybcio
In-Reply-To: <20260330-ipq5210_tlmm-v4-2-b7c40c5429e5@oss.qualcomm.com>
Hi Kathiravan,
right before merging this patch I merged:
https://lore.kernel.org/linux-gpio/20260327171240.3222755-2-mukesh.ojha@oss.qualcomm.com/
On Mon, Mar 30, 2026 at 6:51 AM Kathiravan Thirumoorthy
<kathiravan.thirumoorthy@oss.qualcomm.com> wrote:
> + .intr_status_reg = 0xc + REG_SIZE * id, \
> + .intr_target_reg = 0x8 + REG_SIZE * id, \
(...)
Should intr_target_reg be dropped also from this driver?
If so, please send a follow-up patch.
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH v4 0/2] Introduce TLMM driver for Qualcomm IPQ5210 SoC
From: Linus Walleij @ 2026-03-30 8:41 UTC (permalink / raw)
To: Kathiravan Thirumoorthy
Cc: Bjorn Andersson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
linux-arm-msm, linux-gpio, devicetree, linux-kernel,
Krzysztof Kozlowski, Konrad Dybcio
In-Reply-To: <20260330-ipq5210_tlmm-v4-0-b7c40c5429e5@oss.qualcomm.com>
On Mon, Mar 30, 2026 at 6:51 AM Kathiravan Thirumoorthy
<kathiravan.thirumoorthy@oss.qualcomm.com> wrote:
> The IPQ5210 is Qualcomm's SoC for Routers, Gateways and Access Points.
> Add the pinctrl support for the same.
>
> Signed-off-by: Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
Patches applied!
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH v11 5/7] media: qcom: camss: Add legacy_phy flag to SoC definition structures
From: Loic Poulain @ 2026-03-30 8:40 UTC (permalink / raw)
To: Bryan O'Donoghue
Cc: Bjorn Andersson, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Robert Foss, Todor Tomov,
Mauro Carvalho Chehab, Konrad Dybcio, Vladimir Zapolskiy,
Bryan O'Donoghue, linux-arm-msm, linux-clk, devicetree,
linux-kernel, linux-media, Krzysztof Kozlowski,
Christopher Obbard
In-Reply-To: <20260326-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v11-5-5b93415be6dd@linaro.org>
On Thu, Mar 26, 2026 at 2:32 AM Bryan O'Donoghue
<bryan.odonoghue@linaro.org> wrote:
>
> Flag which SoCs have legacy - builtin PHY code. This will be useful in
> subsequent patches to inform PHY bringup logic if legacy bindings are
> available.
>
> Reviewed-by: Christopher Obbard <christopher.obbard@linaro.org>
> Tested-by: Christopher Obbard <christopher.obbard@linaro.org>
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH v4 2/2] mfd: arizona: Convert GPIO IRQ handling to descriptors
From: Bartosz Golaszewski @ 2026-03-30 8:39 UTC (permalink / raw)
To: Linus Walleij
Cc: patches, linux-kernel, linux-gpio, devicetree, Lee Jones,
Bartosz Golaszewski, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Charles Keepax
In-Reply-To: <20260326-mfd-arizona-irq-v4-2-50c47ed0a18e@kernel.org>
On Thu, 26 Mar 2026 11:51:12 +0100, Linus Walleij <linusw@kernel.org> said:
> Convert the arizona polling GPIO handling to use a GPIO descriptor
> instead of passing a global GPIO number as platform data.
>
> This mechanism is not used in the kernel, but let's preserve
> the mechanism to be nice.
>
> Users can define "irq-gpios" in the devicetree or software node
> for the Arizona chip to provide the GPIO line corresponding to
> the IRQ.
>
> Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
> Signed-off-by: Linus Walleij <linusw@kernel.org>
> ---
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH v2] arm64: dts: monaco: extend fastrpc compute cb
From: Srinivas Kandagatla @ 2026-03-30 8:38 UTC (permalink / raw)
To: Konrad Dybcio, andersson, konradybcio, robh, krzk+dt, conor+dt
Cc: linux-arm-msm, devicetree, linux-kernel
In-Reply-To: <fe9bba47-13d8-4572-af8f-d4c0657f7195@oss.qualcomm.com>
On 3/27/26 1:10 PM, Konrad Dybcio wrote:
> On 3/26/26 4:41 PM, Srinivas Kandagatla wrote:
>> For some reason we ended up adding only 4 out of 11 compute cb's for
>> CDSP, add the missing compute cb. This will also improve the end
>> user-experience by enabling running multiple AI usecases in parallel.
>>
>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
>> ---
>> arch/arm64/boot/dts/qcom/monaco.dtsi | 49 ++++++++++++++++++++++++++++
>> 1 file changed, 49 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi
>> index 10e799dd4a78..38fbd44c7d8f 100644
>> --- a/arch/arm64/boot/dts/qcom/monaco.dtsi
>> +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi
>> @@ -7739,6 +7739,55 @@ compute-cb@4 {
>> <&apps_smmu 0x1964 0x0400>;
>> dma-coherent;
>> };
>> +
>> + compute-cb@5 {
>> + compatible = "qcom,fastrpc-compute-cb";
>> + reg = <5>;
>> + iommus = <&apps_smmu 0x19c5 0x0400>;
>
> I see that the other CBs have 2 iommu streams, the other one
> having "DMA" in the name - could you shed some light on that?
AFAIU, These DMA streams are relevant when NPU dma engine is in the
picture, examples can be data pipelines which involve transferring data
buffers(in/out) in-cordination with different IP blocks outside DSP. May
be something like camera/video streams directly to NPU without CPU
involving...
Personally I have not tested such usecases, but for upstream fastrpc
clients AFAIK only application streams matter as clients will explicitly
allocate the data buffers, even for sharing across ip-blocks.
--srini
>
> Konrad
^ permalink raw reply
* [PATCH v5 9/9] riscv: dts: spacemit: k1-musepi-pro: add SD card support with UHS modes
From: Iker Pedrosa @ 2026-03-30 8:38 UTC (permalink / raw)
To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Adrian Hunter, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yixun Lan, Yixun Lan
Cc: Michael Opdenacker, Javier Martinez Canillas, linux-mmc,
devicetree, linux-riscv, spacemit, linux-kernel, Iker Pedrosa,
Trevor Gamblin
In-Reply-To: <20260330-orangepi-sd-card-uhs-v5-0-bd853604322d@gmail.com>
From: Trevor Gamblin <tgamblin@baylibre.com>
Update the Muse Pi Pro devicetree with SD card support to match what
was done for the OrangePi RV2 in [1]. More precisely:
- Enable sdhci0 controller with 4-bit bus width
- Configure card detect GPIO with inversion
- Connect vmmc-supply to buck4 for 3.3V card power
- Connect vqmmc-supply to aldo1 for 1.8V/3.3V I/O switching
- Add dual pinctrl states for voltage-dependent pin configuration
- Support UHS-I SDR25, SDR50, and SDR104 modes
[1] https://lore.kernel.org/linux-riscv/20260316-orangepi-sd-card-uhs-v3-0-aefd3b7832df@gmail.com/T/#
Signed-off-by: Trevor Gamblin <tgamblin@baylibre.com>
Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
---
arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts | 66 ++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
diff --git a/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts b/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts
index 29e333b670cf0a5c4ed852668460db475b9c44cb..b63723978a4b5317c506c6df6ad410d23b0f0ea0 100644
--- a/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts
+++ b/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts
@@ -18,6 +18,24 @@ aliases {
ethernet0 = ð0;
serial0 = &uart0;
};
+ reg_dc_in: dc-in-5v {
+ compatible = "regulator-fixed";
+ regulator-name = "dc_in_5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_vcc_4v: vcc-4v {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_4v";
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <4000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
chosen {
stdout-path = "serial0";
@@ -77,3 +95,51 @@ &uart0 {
pinctrl-names = "default";
status = "okay";
};
+
+&i2c8 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c8_cfg>;
+ status = "okay";
+
+ pmic@41 {
+ compatible = "spacemit,p1";
+ reg = <0x41>;
+ interrupts = <64>;
+ vin-supply = <®_vcc_4v>;
+
+ regulators {
+ buck4: buck4 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <5000>;
+ regulator-always-on;
+ };
+
+ aldo1: aldo1 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&sdhci0 {
+ pinctrl-names = "default", "state_uhs";
+ pinctrl-0 = <&mmc1_cfg>;
+ pinctrl-1 = <&mmc1_uhs_cfg>;
+ bus-width = <4>;
+ cd-gpios = <&gpio K1_GPIO(80) GPIO_ACTIVE_HIGH>;
+ cd-inverted;
+ no-mmc;
+ no-sdio;
+ disable-wp;
+ cap-sd-highspeed;
+ vmmc-supply = <&buck4>;
+ vqmmc-supply = <&aldo1>;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ status = "okay";
+};
--
2.53.0
^ permalink raw reply related
* [PATCH v5 8/9] riscv: dts: spacemit: k1-bananapi-f3: add SD card support with UHS modes
From: Iker Pedrosa @ 2026-03-30 8:38 UTC (permalink / raw)
To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Adrian Hunter, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yixun Lan, Yixun Lan
Cc: Michael Opdenacker, Javier Martinez Canillas, linux-mmc,
devicetree, linux-riscv, spacemit, linux-kernel, Iker Pedrosa,
Anand Moon
In-Reply-To: <20260330-orangepi-sd-card-uhs-v5-0-bd853604322d@gmail.com>
Add complete SD card controller support with UHS high-speed modes.
- Enable sdhci0 controller with 4-bit bus width
- Configure card detect GPIO with inversion
- Connect vmmc-supply to buck4 for 3.3V card power
- Connect vqmmc-supply to aldo1 for 1.8V/3.3V I/O switching
- Add dual pinctrl states for voltage-dependent pin configuration
- Support UHS-I SDR25, SDR50, and SDR104 modes
This enables full SD card functionality including high-speed UHS modes
for improved performance.
Suggested-by: Anand Moon <linux.amoon@gmail.com>
Tested-by: Anand Moon <linux.amoon@gmail.com>
Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
---
arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
index 5790d927b93db350c8f53aa0f314183b3173fd76..a5bd63976a4ff772ae9a9f983042e9b032ecff95 100644
--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
+++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
@@ -220,7 +220,7 @@ buck3_1v8: buck3 {
regulator-always-on;
};
- buck4 {
+ buck4: buck4 {
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <3300000>;
regulator-ramp-delay = <5000>;
@@ -241,7 +241,7 @@ buck6 {
regulator-always-on;
};
- aldo1 {
+ aldo1: aldo1 {
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <3400000>;
regulator-boot-on;
@@ -367,3 +367,23 @@ hub_3_0: hub@2 {
reset-gpios = <&gpio K1_GPIO(124) GPIO_ACTIVE_LOW>;
};
};
+
+&sdhci0 {
+ pinctrl-names = "default", "state_uhs";
+ pinctrl-0 = <&mmc1_cfg>;
+ pinctrl-1 = <&mmc1_uhs_cfg>;
+ bus-width = <4>;
+ cd-gpios = <&gpio K1_GPIO(80) GPIO_ACTIVE_HIGH>;
+ cd-inverted;
+ broken-cd;
+ no-mmc;
+ no-sdio;
+ disable-wp;
+ cap-sd-highspeed;
+ vmmc-supply = <&buck4>;
+ vqmmc-supply = <&aldo1>;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ status = "okay";
+};
--
2.53.0
^ permalink raw reply related
* [PATCH v5 7/9] riscv: dts: spacemit: k1-orangepi-rv2: add SD card support with UHS modes
From: Iker Pedrosa @ 2026-03-30 8:38 UTC (permalink / raw)
To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Adrian Hunter, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yixun Lan, Yixun Lan
Cc: Michael Opdenacker, Javier Martinez Canillas, linux-mmc,
devicetree, linux-riscv, spacemit, linux-kernel, Iker Pedrosa,
Anand Moon, Trevor Gamblin
In-Reply-To: <20260330-orangepi-sd-card-uhs-v5-0-bd853604322d@gmail.com>
Add complete SD card controller support with UHS high-speed modes.
- Enable sdhci0 controller with 4-bit bus width
- Configure card detect GPIO with inversion
- Connect vmmc-supply to buck4 for 3.3V card power
- Connect vqmmc-supply to aldo1 for 1.8V/3.3V I/O switching
- Add dual pinctrl states for voltage-dependent pin configuration
- Support UHS-I SDR25, SDR50, and SDR104 modes
This enables full SD card functionality including high-speed UHS modes
for improved performance.
Tested-by: Anand Moon <linux.amoon@gmail.com>
Tested-by: Trevor Gamblin <tgamblin@baylibre.com>
Tested-by: Michael Opdenacker <michael.opdenacker@rootcommit.com>
Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
---
arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
index 9c417a483f6bad6e60617cf8d5400ca079588726..5f823611c969eb0e15546862228ae4f65375675a 100644
--- a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
+++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
@@ -140,3 +140,22 @@ aldo1: aldo1 {
};
};
};
+
+&sdhci0 {
+ pinctrl-names = "default", "state_uhs";
+ pinctrl-0 = <&mmc1_cfg>;
+ pinctrl-1 = <&mmc1_uhs_cfg>;
+ bus-width = <4>;
+ cd-gpios = <&gpio K1_GPIO(80) GPIO_ACTIVE_HIGH>;
+ cd-inverted;
+ no-mmc;
+ no-sdio;
+ disable-wp;
+ cap-sd-highspeed;
+ vmmc-supply = <&buck4>;
+ vqmmc-supply = <&aldo1>;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ status = "okay";
+};
--
2.53.0
^ permalink raw reply related
* [PATCH v5 6/9] riscv: dts: spacemit: k1-orangepi-rv2: add PMIC and power infrastructure
From: Iker Pedrosa @ 2026-03-30 8:38 UTC (permalink / raw)
To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Adrian Hunter, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yixun Lan, Yixun Lan
Cc: Michael Opdenacker, Javier Martinez Canillas, linux-mmc,
devicetree, linux-riscv, spacemit, linux-kernel, Iker Pedrosa,
Anand Moon, Trevor Gamblin
In-Reply-To: <20260330-orangepi-sd-card-uhs-v5-0-bd853604322d@gmail.com>
Add Spacemit P1 PMIC configuration and board power infrastructure for
voltage regulation support.
- Add board power regulators (5V input, 4V rail)
- Enable I2C8 for PMIC communication
- Configure PMIC with buck4 (vmmc) and aldo1 (vqmmc) regulators
- Set up regulator constraints for SD card operation
Tested-by: Anand Moon <linux.amoon@gmail.com>
Tested-by: Trevor Gamblin <tgamblin@baylibre.com>
Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
---
arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts | 48 ++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
index 7b7331cb3c726f11d597f81917f3a3f5fc21e1b9..9c417a483f6bad6e60617cf8d5400ca079588726 100644
--- a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
+++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
@@ -19,6 +19,25 @@ aliases {
ethernet1 = ð1;
};
+ reg_dc_in: dc-in-5v {
+ compatible = "regulator-fixed";
+ regulator-name = "dc_in_5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_vcc_4v: vcc-4v {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_4v";
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <4000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ vin-supply = <®_dc_in>;
+ };
+
chosen {
stdout-path = "serial0";
};
@@ -92,3 +111,32 @@ &uart0 {
pinctrl-0 = <&uart0_2_cfg>;
status = "okay";
};
+
+&i2c8 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c8_cfg>;
+ status = "okay";
+
+ pmic@41 {
+ compatible = "spacemit,p1";
+ reg = <0x41>;
+ interrupts = <64>;
+ vin-supply = <®_vcc_4v>;
+
+ regulators {
+ buck4: buck4 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <5000>;
+ regulator-always-on;
+ };
+
+ aldo1: aldo1 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
+};
--
2.53.0
^ permalink raw reply related
* [PATCH v5 5/9] riscv: dts: spacemit: k1: add SD card controller and pinctrl support
From: Iker Pedrosa @ 2026-03-30 8:38 UTC (permalink / raw)
To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Adrian Hunter, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yixun Lan, Yixun Lan
Cc: Michael Opdenacker, Javier Martinez Canillas, linux-mmc,
devicetree, linux-riscv, spacemit, linux-kernel, Iker Pedrosa,
Anand Moon, Trevor Gamblin
In-Reply-To: <20260330-orangepi-sd-card-uhs-v5-0-bd853604322d@gmail.com>
Add SD card controller infrastructure for SpacemiT K1 SoC with complete
pinctrl support for both standard and UHS modes.
- Add sdhci0 controller definition with clocks, resets and interrupts
- Add mmc1_cfg pinctrl for 3.3V standard SD operation
- Add mmc1_uhs_cfg pinctrl for 1.8V UHS high-speed operation
- Configure appropriate drive strength and power-source properties
This provides complete SD card infrastructure that K1-based boards can
enable.
Tested-by: Anand Moon <linux.amoon@gmail.com>
Tested-by: Trevor Gamblin <tgamblin@baylibre.com>
Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
---
arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi | 40 ++++++++++++++++++++++++++++
arch/riscv/boot/dts/spacemit/k1.dtsi | 13 +++++++++
2 files changed, 53 insertions(+)
diff --git a/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi b/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi
index b13dcb10f4d66022d27307de73a6ea3287e97441..8d82011f1af666fb78c282a2abcc0cb88f962053 100644
--- a/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi
+++ b/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi
@@ -570,4 +570,44 @@ pwm14-1-pins {
drive-strength = <32>;
};
};
+
+ mmc1_cfg: mmc1-cfg {
+ mmc1-data-cmd-pins {
+ pinmux = <K1_PADCONF(104, 0)>, /* mmc1_d3 */
+ <K1_PADCONF(105, 0)>, /* mmc1_d2 */
+ <K1_PADCONF(106, 0)>, /* mmc1_d1 */
+ <K1_PADCONF(107, 0)>, /* mmc1_d0 */
+ <K1_PADCONF(108, 0)>; /* mmc1_cmd */
+ bias-pull-up = <1>;
+ drive-strength = <7>;
+ power-source = <3300>;
+ };
+
+ mmc1-clk-pins {
+ pinmux = <K1_PADCONF(109, 0)>; /* mmc1_clk */
+ bias-pull-down = <1>;
+ drive-strength = <7>;
+ power-source = <3300>;
+ };
+ };
+
+ mmc1_uhs_cfg: mmc1-uhs-cfg {
+ mmc1-data-cmd-pins {
+ pinmux = <K1_PADCONF(104, 0)>, /* mmc1_d3 */
+ <K1_PADCONF(105, 0)>, /* mmc1_d2 */
+ <K1_PADCONF(106, 0)>, /* mmc1_d1 */
+ <K1_PADCONF(107, 0)>, /* mmc1_d0 */
+ <K1_PADCONF(108, 0)>; /* mmc1_cmd */
+ bias-pull-up = <1>;
+ drive-strength = <13>;
+ power-source = <1800>;
+ };
+
+ mmc1-clk-pins {
+ pinmux = <K1_PADCONF(109, 0)>; /* mmc1_clk */
+ bias-pull-down = <1>;
+ drive-strength = <13>;
+ power-source = <1800>;
+ };
+ };
};
diff --git a/arch/riscv/boot/dts/spacemit/k1.dtsi b/arch/riscv/boot/dts/spacemit/k1.dtsi
index f0bad6855c970a609253d4b0ca2a4fcbf06bb8e3..28949f804610c60b7fa89d957507be32e3b49f34 100644
--- a/arch/riscv/boot/dts/spacemit/k1.dtsi
+++ b/arch/riscv/boot/dts/spacemit/k1.dtsi
@@ -1211,6 +1211,19 @@ emmc: mmc@d4281000 {
interrupts = <101>;
status = "disabled";
};
+
+ sdhci0: mmc@d4280000 {
+ compatible = "spacemit,k1-sdhci";
+ reg = <0x0 0xd4280000 0x0 0x200>;
+ clocks = <&syscon_apmu CLK_SDH_AXI>,
+ <&syscon_apmu CLK_SDH0>;
+ clock-names = "core", "io";
+ resets = <&syscon_apmu RESET_SDH_AXI>,
+ <&syscon_apmu RESET_SDH0>;
+ reset-names = "axi", "sdh";
+ interrupts = <99>;
+ status = "disabled";
+ };
};
};
};
--
2.53.0
^ permalink raw reply related
* [PATCH v5 4/9] mmc: sdhci-of-k1: add comprehensive SDR tuning support
From: Iker Pedrosa @ 2026-03-30 8:38 UTC (permalink / raw)
To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Adrian Hunter, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Yixun Lan, Yixun Lan
Cc: Michael Opdenacker, Javier Martinez Canillas, linux-mmc,
devicetree, linux-riscv, spacemit, linux-kernel, Iker Pedrosa,
Anand Moon, Trevor Gamblin
In-Reply-To: <20260330-orangepi-sd-card-uhs-v5-0-bd853604322d@gmail.com>
Implement software tuning algorithm to enable UHS-I SDR modes for SD
card operation and HS200 mode for eMMC. This adds both TX and RX delay
line tuning based on the SpacemiT K1 controller capabilities.
Algorithm features:
- Add tuning register definitions (RX_CFG, DLINE_CTRL, DLINE_CFG)
- Conditional tuning: only for high-speed modes (≥100MHz)
- TX tuning: configure transmit delay line with optimal values
(dline_reg=0, delaycode=127) to ensure optimal signal output timing
- RX tuning: single-pass window detection algorithm testing full
delay range (0-255) to find optimal receive timing window
- Retry mechanism: multiple fallback delays within optimal window
for improved reliability
Tested-by: Anand Moon <linux.amoon@gmail.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Tested-by: Trevor Gamblin <tgamblin@baylibre.com>
Signed-off-by: Iker Pedrosa <ikerpedrosam@gmail.com>
---
drivers/mmc/host/sdhci-of-k1.c | 172 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 172 insertions(+)
diff --git a/drivers/mmc/host/sdhci-of-k1.c b/drivers/mmc/host/sdhci-of-k1.c
index 234e258af25996e7bbcd0b70366c7480bf62bee7..5432c94680d8c1c1555b5fb906adbc881953dd05 100644
--- a/drivers/mmc/host/sdhci-of-k1.c
+++ b/drivers/mmc/host/sdhci-of-k1.c
@@ -69,6 +69,28 @@
#define SDHC_PHY_DRIVE_SEL GENMASK(2, 0)
#define SDHC_RX_BIAS_CTRL BIT(5)
+#define SPACEMIT_SDHC_RX_CFG_REG 0x118
+#define SDHC_RX_SDCLK_SEL0_MASK GENMASK(1, 0)
+#define SDHC_RX_SDCLK_SEL1_MASK GENMASK(3, 2)
+#define SDHC_RX_SDCLK_SEL1 FIELD_PREP(SDHC_RX_SDCLK_SEL1_MASK, 1)
+
+#define SPACEMIT_SDHC_DLINE_CTRL_REG 0x130
+#define SDHC_DLINE_PU BIT(0)
+#define SDHC_RX_DLINE_CODE_MASK GENMASK(23, 16)
+#define SDHC_TX_DLINE_CODE_MASK GENMASK(31, 24)
+
+#define SPACEMIT_SDHC_DLINE_CFG_REG 0x134
+#define SDHC_RX_DLINE_REG_MASK GENMASK(7, 0)
+#define SDHC_RX_DLINE_GAIN BIT(8)
+#define SDHC_TX_DLINE_REG_MASK GENMASK(23, 16)
+
+#define SPACEMIT_RX_DLINE_REG 9
+#define SPACEMIT_RX_TUNE_DELAY_MIN 0x0
+#define SPACEMIT_RX_TUNE_DELAY_MAX 0xFF
+
+#define SPACEMIT_TX_TUNING_DLINE_REG 0x00
+#define SPACEMIT_TX_TUNING_DELAYCODE 127
+
struct spacemit_sdhci_host {
struct clk *clk_core;
struct clk *clk_io;
@@ -96,6 +118,50 @@ static inline void spacemit_sdhci_clrsetbits(struct sdhci_host *host, u32 clr, u
sdhci_writel(host, val, reg);
}
+static void spacemit_sdhci_set_rx_delay(struct sdhci_host *host, u8 delay)
+{
+ spacemit_sdhci_clrsetbits(host, SDHC_RX_DLINE_CODE_MASK,
+ FIELD_PREP(SDHC_RX_DLINE_CODE_MASK, delay),
+ SPACEMIT_SDHC_DLINE_CTRL_REG);
+}
+
+static void spacemit_sdhci_set_tx_delay(struct sdhci_host *host, u8 delay)
+{
+ spacemit_sdhci_clrsetbits(host, SDHC_TX_DLINE_CODE_MASK,
+ FIELD_PREP(SDHC_TX_DLINE_CODE_MASK, delay),
+ SPACEMIT_SDHC_DLINE_CTRL_REG);
+}
+
+static void spacemit_sdhci_set_tx_dline_reg(struct sdhci_host *host, u8 dline_reg)
+{
+ spacemit_sdhci_clrsetbits(host, SDHC_TX_DLINE_REG_MASK,
+ FIELD_PREP(SDHC_TX_DLINE_REG_MASK, dline_reg),
+ SPACEMIT_SDHC_DLINE_CFG_REG);
+}
+
+static void spacemit_sdhci_tx_tuning_prepare(struct sdhci_host *host)
+{
+ spacemit_sdhci_setbits(host, SDHC_TX_MUX_SEL, SPACEMIT_SDHC_TX_CFG_REG);
+ spacemit_sdhci_setbits(host, SDHC_DLINE_PU, SPACEMIT_SDHC_DLINE_CTRL_REG);
+ udelay(5);
+}
+
+static void spacemit_sdhci_prepare_tuning(struct sdhci_host *host)
+{
+ spacemit_sdhci_clrsetbits(host, SDHC_RX_DLINE_REG_MASK,
+ FIELD_PREP(SDHC_RX_DLINE_REG_MASK, SPACEMIT_RX_DLINE_REG),
+ SPACEMIT_SDHC_DLINE_CFG_REG);
+
+ spacemit_sdhci_setbits(host, SDHC_DLINE_PU, SPACEMIT_SDHC_DLINE_CTRL_REG);
+ udelay(5);
+
+ spacemit_sdhci_clrsetbits(host, SDHC_RX_SDCLK_SEL1_MASK, SDHC_RX_SDCLK_SEL1,
+ SPACEMIT_SDHC_RX_CFG_REG);
+
+ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200)
+ spacemit_sdhci_setbits(host, SDHC_HS200_USE_RFIFO, SPACEMIT_SDHC_PHY_FUNC_REG);
+}
+
static void spacemit_sdhci_reset(struct sdhci_host *host, u8 mask)
{
sdhci_reset(host, mask);
@@ -191,6 +257,111 @@ static unsigned int spacemit_sdhci_clk_get_max_clock(struct sdhci_host *host)
return clk_get_rate(pltfm_host->clk);
}
+static int spacemit_sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
+{
+ int current_len = 0, current_start = 0;
+ int max_pass_len = 0, max_pass_start = 0;
+ struct mmc_host *mmc = host->mmc;
+ struct mmc_ios ios = mmc->ios;
+ u8 final_delay;
+ int ret = 0;
+ int i;
+
+ /*
+ * Tuning is required for SDR50/SDR104, HS200/HS400 cards and
+ * if clock frequency is greater than 100MHz in these modes.
+ */
+ if (host->clock < 100 * 1000 * 1000 ||
+ !(ios.timing == MMC_TIMING_MMC_HS200 ||
+ ios.timing == MMC_TIMING_UHS_SDR50 ||
+ ios.timing == MMC_TIMING_UHS_SDR104))
+ return 0;
+
+ if (mmc->caps2 & MMC_CAP2_NO_MMC) {
+ spacemit_sdhci_set_tx_dline_reg(host, SPACEMIT_TX_TUNING_DLINE_REG);
+ spacemit_sdhci_set_tx_delay(host, SPACEMIT_TX_TUNING_DELAYCODE);
+ spacemit_sdhci_tx_tuning_prepare(host);
+
+ dev_dbg(mmc_dev(host->mmc), "TX tuning: dline_reg=%d, delaycode=%d\n",
+ SPACEMIT_TX_TUNING_DLINE_REG, SPACEMIT_TX_TUNING_DELAYCODE);
+ }
+
+ spacemit_sdhci_prepare_tuning(host);
+
+ for (i = SPACEMIT_RX_TUNE_DELAY_MIN; i <= SPACEMIT_RX_TUNE_DELAY_MAX; i++) {
+ spacemit_sdhci_set_rx_delay(host, i);
+ ret = mmc_send_tuning(host->mmc, opcode, NULL);
+
+ dev_dbg(mmc_dev(host->mmc), "RX delay %d: %s\n",
+ i, ret == 0 ? "pass" : "fail");
+
+ if (ret == 0) {
+ /* Test passed - extend current window */
+ if (current_len == 0)
+ current_start = i;
+ current_len++;
+ } else {
+ /* Test failed - check if current window is best so far */
+ if (current_len > max_pass_len) {
+ max_pass_len = current_len;
+ max_pass_start = current_start;
+ }
+ current_len = 0;
+ }
+ }
+
+ if (current_len > max_pass_len) {
+ max_pass_len = current_len;
+ max_pass_start = current_start;
+ }
+
+ if (max_pass_len < 3) {
+ dev_err(mmc_dev(host->mmc), "Tuning failed: no stable window found\n");
+ return -EIO;
+ }
+
+ final_delay = max_pass_start + max_pass_len / 2;
+ spacemit_sdhci_set_rx_delay(host, final_delay);
+ ret = mmc_send_tuning(host->mmc, opcode, NULL);
+ if (ret) {
+ u8 retry_delays[] = {
+ max_pass_start + max_pass_len / 4,
+ max_pass_start + (3 * max_pass_len) / 4,
+ max_pass_start,
+ max_pass_start + max_pass_len - 1
+ };
+ int retry_count = ARRAY_SIZE(retry_delays);
+
+ dev_warn(mmc_dev(mmc), "Primary delay %d failed, trying alternatives\n",
+ final_delay);
+
+ for (i = 0; i < retry_count; i++) {
+ if (retry_delays[i] >= SPACEMIT_RX_TUNE_DELAY_MIN &&
+ retry_delays[i] <= SPACEMIT_RX_TUNE_DELAY_MAX) {
+ spacemit_sdhci_set_rx_delay(host, retry_delays[i]);
+ ret = mmc_send_tuning(host->mmc, opcode, NULL);
+ if (!ret) {
+ final_delay = retry_delays[i];
+ dev_info(mmc_dev(mmc), "Retry successful with delay %d\n",
+ final_delay);
+ break;
+ }
+ }
+ }
+
+ if (ret) {
+ dev_err(mmc_dev(mmc), "All retry attempts failed\n");
+ return -EIO;
+ }
+ }
+
+ dev_dbg(mmc_dev(host->mmc),
+ "Tuning successful: window %d-%d, using delay %d\n",
+ max_pass_start, max_pass_start + max_pass_len - 1, final_delay);
+
+ return 0;
+}
+
static int spacemit_sdhci_pre_select_hs400(struct mmc_host *mmc)
{
struct sdhci_host *host = mmc_priv(mmc);
@@ -326,6 +497,7 @@ static const struct sdhci_ops spacemit_sdhci_ops = {
.set_bus_width = sdhci_set_bus_width,
.set_clock = spacemit_sdhci_set_clock,
.set_uhs_signaling = spacemit_sdhci_set_uhs_signaling,
+ .platform_execute_tuning = spacemit_sdhci_execute_tuning,
};
static const struct sdhci_pltfm_data spacemit_sdhci_k1_pdata = {
--
2.53.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox