Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH AUTOSEL 6.1 04/52] arm64: dts: qcom: sdm630: add USB QMP PHY support
From: Konrad Dybcio @ 2024-03-29 13:16 UTC (permalink / raw)
  To: Sasha Levin, linux-kernel, stable
  Cc: Dmitry Baryshkov, Bjorn Andersson, robh, krzysztof.kozlowski+dt,
	conor+dt, linux-arm-msm, devicetree
In-Reply-To: <20240329124605.3091273-4-sashal@kernel.org>

On 29.03.2024 1:44 PM, Sasha Levin wrote:
> From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> 
> [ Upstream commit bb5009a24ec3f2f2ec1e2ed7b8a5dcde9a9e28d9 ]
> 
> Define USB3 QMP PHY presend on the SDM630 / SDM660 platforms. Enable it by
> default in the USB3 host, but (for compatibility), force USB 2.0 mode
> for all defined boards. The boards should opt-in to enable USB 3.0
> support.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
> Link: https://lore.kernel.org/r/20240116-sdm660-usb3-support-v1-3-2fbd683aea77@linaro.org
> Signed-off-by: Bjorn Andersson <andersson@kernel.org>
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> ---

Hi, this depends on other kernel changes and can possibly regress something
if EPROBE_DEFER isn't handled correctly (because it will never probe)

Please drop it from all queues

Konrad

^ permalink raw reply

* [PATCH 1/3] ARM: dts: Modify GPIO table for Asrock X570D4U BMC
From: Renze Nicolai @ 2024-03-29 13:01 UTC (permalink / raw)
  To: linux-arm-kernel, devicetree, linux-kernel, linux-aspeed, arnd,
	olof, soc, robh+dt, krzysztof.kozlowski+dt, joel, andrew, renze
In-Reply-To: <20240329130152.878944-1-renze@rnplus.nl>

This commit removes button-nmi-n, this board does not have support for an NMI button.
Input status-locatorled-n has been renamed to input-locatorled-n to better indicate the signal type.
The suffix -n has been appended to the name of control-locatorbutton, button-power, control-power, button-reset, control-reset, input-id0, input-id1, input-id2, output-bmc-ready to reflect the inverted signal polarity.
GPIO output-rtc-battery-voltage-read-enable has been renamed to output-hwm-vbat-enable, input-alert1-n to input-aux-smb-alert-n, input-alert3-n to input-psu-smb-alert-n, input-mfg to input-mfg-mode-n and input-caseopen to input-case-open-n.
And GPIOs input-bmc-smb-present-n, input-pcie-wake-n, input-sleep-s3-n, input-sleep-s5-n and input-power-good have been added.

Signed-off-by: Renze Nicolai <renze@rnplus.nl>
---
 .../dts/aspeed/aspeed-bmc-asrock-x570d4u.dts  | 116 +++++++++---------
 1 file changed, 58 insertions(+), 58 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-x570d4u.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-x570d4u.dts
index 3c975bc41ae7..34bc382bf492 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-x570d4u.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-x570d4u.dts
@@ -79,64 +79,64 @@ iio-hwmon {
 &gpio {
 	status = "okay";
 	gpio-line-names =
-	/*A0-A3*/       "status-locatorled-n",                    "",                      "button-nmi-n",          "",
-	/*A4-A7*/       "",                                       "",                      "",                      "",
-	/*B0-B3*/       "input-bios-post-cmplt-n",                "",                      "",                      "",
-	/*B4-B7*/       "",                                       "",                      "",                      "",
-	/*C0-C3*/       "",                                       "",                      "",                      "",
-	/*C4-C7*/       "",                                       "",                      "control-locatorbutton", "",
-	/*D0-D3*/       "button-power",                           "control-power",         "button-reset",          "control-reset",
-	/*D4-D7*/       "",                                       "",                      "",                      "",
-	/*E0-E3*/       "",                                       "",                      "",                      "",
-	/*E4-E7*/       "",                                       "",                      "",                      "",
-	/*F0-F3*/       "",                                       "",                      "",                      "",
-	/*F4-F7*/       "",                                       "",                      "",                      "",
-	/*G0-G3*/       "output-rtc-battery-voltage-read-enable", "input-id0",             "input-id1",             "input-id2",
-	/*G4-G7*/       "input-alert1-n",                         "input-alert2-n",        "input-alert3-n",        "",
-	/*H0-H3*/       "",                                       "",                      "",                      "",
-	/*H4-H7*/       "input-mfg",                              "",                      "led-heartbeat-n",       "input-caseopen",
-	/*I0-I3*/       "",                                       "",                      "",                      "",
-	/*I4-I7*/       "",                                       "",                      "",                      "",
-	/*J0-J3*/       "output-bmc-ready",                       "",                      "",                      "",
-	/*J4-J7*/       "",                                       "",                      "",                      "",
-	/*K0-K3*/       "",                                       "",                      "",                      "",
-	/*K4-K7*/       "",                                       "",                      "",                      "",
-	/*L0-L3*/       "",                                       "",                      "",                      "",
-	/*L4-L7*/       "",                                       "",                      "",                      "",
-	/*M0-M3*/       "",                                       "",                      "",                      "",
-	/*M4-M7*/       "",                                       "",                      "",                      "",
-	/*N0-N3*/       "",                                       "",                      "",                      "",
-	/*N4-N7*/       "",                                       "",                      "",                      "",
-	/*O0-O3*/       "",                                       "",                      "",                      "",
-	/*O4-O7*/       "",                                       "",                      "",                      "",
-	/*P0-P3*/       "",                                       "",                      "",                      "",
-	/*P4-P7*/       "",                                       "",                      "",                      "",
-	/*Q0-Q3*/       "",                                       "",                      "",                      "",
-	/*Q4-Q7*/       "",                                       "",                      "",                      "",
-	/*R0-R3*/       "",                                       "",                      "",                      "",
-	/*R4-R7*/       "",                                       "",                      "",                      "",
-	/*S0-S3*/       "input-bmc-pchhot-n",                     "",                      "",                      "",
-	/*S4-S7*/       "",                                       "",                      "",                      "",
-	/*T0-T3*/       "",                                       "",                      "",                      "",
-	/*T4-T7*/       "",                                       "",                      "",                      "",
-	/*U0-U3*/       "",                                       "",                      "",                      "",
-	/*U4-U7*/       "",                                       "",                      "",                      "",
-	/*V0-V3*/       "",                                       "",                      "",                      "",
-	/*V4-V7*/       "",                                       "",                      "",                      "",
-	/*W0-W3*/       "",                                       "",                      "",                      "",
-	/*W4-W7*/       "",                                       "",                      "",                      "",
-	/*X0-X3*/       "",                                       "",                      "",                      "",
-	/*X4-X7*/       "",                                       "",                      "",                      "",
-	/*Y0-Y3*/       "",                                       "",                      "",                      "",
-	/*Y4-Y7*/       "",                                       "",                      "",                      "",
-	/*Z0-Z3*/       "",                                       "",                      "led-fault-n",           "output-bmc-throttle-n",
-	/*Z4-Z7*/       "",                                       "",                      "",                      "",
-	/*AA0-AA3*/     "input-cpu1-thermtrip-latch-n",           "",                      "input-cpu1-prochot-n",  "",
-	/*AA4-AC7*/     "",                                       "",                      "",                      "",
-	/*AB0-AB3*/     "",                                       "",                      "",                      "",
-	/*AB4-AC7*/     "",                                       "",                      "",                      "",
-	/*AC0-AC3*/     "",                                       "",                      "",                      "",
-	/*AC4-AC7*/     "",                                       "",                      "",                      "";
+	/*A0-A3*/       "input-locatorled-n",                     "",                      "",                        "",
+	/*A4-A7*/       "",                                       "",                      "",                        "",
+	/*B0-B3*/       "input-bios-post-cmplt-n",                "",                      "",                        "",
+	/*B4-B7*/       "",                                       "",                      "",                        "",
+	/*C0-C3*/       "",                                       "",                      "",                        "",
+	/*C4-C7*/       "",                                       "",                      "control-locatorbutton-n", "",
+	/*D0-D3*/       "button-power-n",                         "control-power-n",       "button-reset-n",          "control-reset-n",
+	/*D4-D7*/       "",                                       "",                      "",                        "",
+	/*E0-E3*/       "",                                       "",                      "",                        "",
+	/*E4-E7*/       "",                                       "",                      "",                        "",
+	/*F0-F3*/       "",                                       "",                      "",                        "",
+	/*F4-F7*/       "",                                       "",                      "",                        "",
+	/*G0-G3*/       "output-hwm-vbat-enable",                 "input-id0-n",           "input-id1-n",             "input-id2-n",
+	/*G4-G7*/       "input-aux-smb-alert-n",                  "",                      "input-psu-smb-alert-n",   "",
+	/*H0-H3*/       "",                                       "",                      "",                        "",
+	/*H4-H7*/       "input-mfg-mode-n",                       "",                      "led-heartbeat-n",         "input-case-open-n",
+	/*I0-I3*/       "",                                       "",                      "",                        "",
+	/*I4-I7*/       "",                                       "",                      "",                        "",
+	/*J0-J3*/       "output-bmc-ready-n",                     "",                      "",                        "",
+	/*J4-J7*/       "",                                       "",                      "",                        "",
+	/*K0-K3*/       "",                                       "",                      "",                        "",
+	/*K4-K7*/       "",                                       "",                      "",                        "",
+	/*L0-L3*/       "",                                       "",                      "",                        "",
+	/*L4-L7*/       "",                                       "",                      "",                        "",
+	/*M0-M3*/       "",                                       "",                      "",                        "",
+	/*M4-M7*/       "",                                       "",                      "",                        "",
+	/*N0-N3*/       "",                                       "",                      "",                        "",
+	/*N4-N7*/       "",                                       "",                      "",                        "",
+	/*O0-O3*/       "",                                       "",                      "",                        "",
+	/*O4-O7*/       "",                                       "",                      "",                        "",
+	/*P0-P3*/       "",                                       "",                      "",                        "",
+	/*P4-P7*/       "",                                       "",                      "",                        "",
+	/*Q0-Q3*/       "",                                       "",                      "",                        "",
+	/*Q4-Q7*/       "input-bmc-smb-present-n",                "",                      "",                        "input-pcie-wake-n",
+	/*R0-R3*/       "",                                       "",                      "",                        "",
+	/*R4-R7*/       "",                                       "",                      "",                        "",
+	/*S0-S3*/       "input-bmc-pchhot-n",                     "",                      "",                        "",
+	/*S4-S7*/       "",                                       "",                      "",                        "",
+	/*T0-T3*/       "",                                       "",                      "",                        "",
+	/*T4-T7*/       "",                                       "",                      "",                        "",
+	/*U0-U3*/       "",                                       "",                      "",                        "",
+	/*U4-U7*/       "",                                       "",                      "",                        "",
+	/*V0-V3*/       "",                                       "",                      "",                        "",
+	/*V4-V7*/       "",                                       "",                      "",                        "",
+	/*W0-W3*/       "",                                       "",                      "",                        "",
+	/*W4-W7*/       "",                                       "",                      "",                        "",
+	/*X0-X3*/       "",                                       "",                      "",                        "",
+	/*X4-X7*/       "",                                       "",                      "",                        "",
+	/*Y0-Y3*/       "input-sleep-s3-n",                       "input-sleep-s5-n",      "",                        "",
+	/*Y4-Y7*/       "",                                       "",                      "",                        "",
+	/*Z0-Z3*/       "",                                       "",                      "led-fault-n",             "output-bmc-throttle-n",
+	/*Z4-Z7*/       "",                                       "",                      "",                        "",
+	/*AA0-AA3*/     "input-cpu1-thermtrip-latch-n",           "",                      "input-cpu1-prochot-n",    "",
+	/*AA4-AC7*/     "",                                       "",                      "",                        "",
+	/*AB0-AB3*/     "",                                       "input-power-good",      "",                        "",
+	/*AB4-AC7*/     "",                                       "",                      "",                        "",
+	/*AC0-AC3*/     "",                                       "",                      "",                        "",
+	/*AC4-AC7*/     "",                                       "",                      "",                        "";
 };
 
 &fmc {
-- 
2.44.0


^ permalink raw reply related

* [PATCH 0/3] ARM: dts: Update devicetree of Asrock X570D4U BMC
From: Renze Nicolai @ 2024-03-29 13:01 UTC (permalink / raw)
  To: linux-arm-kernel, devicetree, linux-kernel, linux-aspeed, arnd,
	olof, soc, robh+dt, krzysztof.kozlowski+dt, joel, andrew, renze

Hello,

These patches change the GPIO table, ADC channel configuration and
I2C bus configuration of the devicetree for the X570D4U BMC as part of
ongoing efforts to support OpenBMC on this platform.

Best regards,
Renze Nicolai

Renze Nicolai (3):
  ARM: dts: Modify GPIO table for Asrock X570D4U BMC
  ARM: dts: Disable unused ADC channels for Asrock X570D4U BMC
  ARM: dts: Modify I2C bus configuration

 .../dts/aspeed/aspeed-bmc-asrock-x570d4u.dts  | 152 +++++++++---------
 1 file changed, 78 insertions(+), 74 deletions(-)

-- 
2.44.0


^ permalink raw reply

* Re: [PATCH 13/13] ASoC: ti: davinci-i2s: Opitonally drive DX pin during capture streams
From: Bastien Curutchet @ 2024-03-29 13:24 UTC (permalink / raw)
  To: Péter Ujfalusi, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai
  Cc: linux-sound, devicetree, linux-kernel, alsa-devel,
	Thomas Petazzoni, herve.codina, christophercordahi
In-Reply-To: <16e6cded-33c1-408c-9bfc-b0b9a8da4cbf@bootlin.com>

Hi Péter,

>> Can you use aplay /dev/zero and a DT property to select T1 framing for
>> the playback? Or that would be too coarse for timing the start of
>> playback and capture?
>>
> 
> That's a good idea, thank you. I'll try this and come back to you.
> 
>

I tried it and it works fine, thank you.

We still need to run some performance tests before fully adopting it but
anyway I'll send a new iteration of the patch series that drops the
drive-dx part and just keeps a DT property to select T1 framing.

Best regards,
Bastien

^ permalink raw reply

* Re: 回复: [PATCH v2 1/2] ASoC: dt-bindings: Add bindings for Cadence I2S-MC controller
From: Mark Brown @ 2024-03-29 13:36 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Xingyu Wu, Liam Girdwood, Claudiu Beznea, Jaroslav Kysela,
	Takashi Iwai, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	alsa-devel@alsa-project.org, linux-sound@vger.kernel.org
In-Reply-To: <7b4a35d0-6764-4c6a-9f1d-57481324c680@linaro.org>

[-- Attachment #1: Type: text/plain, Size: 577 bytes --]

On Fri, Mar 29, 2024 at 12:42:22PM +0100, Krzysztof Kozlowski wrote:

> I stated and I keep my statement that such block is usually not usable
> on its own and always needs some sort of quirks or SoC-specific
> implementation. At least this is what I saw in other similar cases, but
> not exactly I2S.

I wouldn't be so pessimistic, especially not for I2S - a good portion of
quirks there are extra features rather than things needed for basic
operation, a lot of things that might in the past have been quirks for
basic operation are these days hidden behind the DT bindings.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH v6 0/2] ASoC: nau8325: Modify driver code and dtschema.
From: Mark Brown @ 2024-03-29 13:44 UTC (permalink / raw)
  To: Seven Lee
  Cc: lgirdwood, alsa-devel, devicetree, linux-sound,
	krzysztof.kozlowski+dt, linux-kernel, robh+dt, conor+dt, perex,
	tiwai, YHCHuang, KCHSU0, CTLIN0, SJLIN0, scott6986,
	supercraig0719, dardar923
In-Reply-To: <20240329085402.3424749-1-wtli@nuvoton.com>

[-- Attachment #1: Type: text/plain, Size: 356 bytes --]

On Fri, Mar 29, 2024 at 04:54:00PM +0800, Seven Lee wrote:
> Revise properties description and use standard units in dtschema.
> The unit conversion driver based on the attribute must also be
> changed accordingly.

My applying the prior version raced with you sending this new one, could
you please send incremental patches with the changes from your v6?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* [PATCH v4 0/8] cpufreq: sun50i: Add Allwinner H616 support
From: Andre Przywara @ 2024-03-29 14:13 UTC (permalink / raw)
  To: Yangtao Li, Viresh Kumar, Nishanth Menon, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Rafael J . Wysocki
  Cc: linux-pm, devicetree, linux-sunxi, linux-arm-kernel,
	Brandon Cheo Fusi, Martin Botka, Martin Botka, Chris Morgan,
	Ryan Walklin, Mark Rutland, Lorenzo Pieralisi, Sudeep Holla

This series adds cpufreq support to the Allwinner H616 SoC.
v4 allows compilation outside of arm/arm64, by making the SMCCC call
optional, the rest of the changes are added tags and cosmetic fixes.
This is based on Martin's original series from about half a year ago[1].
Thanks for the comments on the list!
See below for a changelog.

=================
The various H616 chips seem to be qualified by production batches, and
there is a table that translates from some efuses values to actual speed
bin indexes. Also the die revision has a say here: we can derive this
from the SoC ID, already provided by TF-A through the SMCCC SoC ID
interface.
So while the H6 had explicit speed bin indexes in the efuses, this is
conceptually not that different, and after refactoring patch 4/8 this
can be neatly integrated into the existing (H6) sun50i-cpufreq-nvmem
driver.
On top of that, not all chips are qualified to reach the full 1.5GHz,
and the BSP kernel describes different OPPs for each speedbin. This
requires to add support for the opp-supported-hw DT property, to be
able to describe those requirements properly.

Patch 1/8 exports the SoC ID function, so that we can call it from our
driver. Patch 2/8 blocks the affected SoCs from the generic DT cpufreq
driver, patch 3/8 adds the DT binding documentation.
Patch 4/8 refactors the existing speedbin determination for the H6, to
be able to plug in the H616 version later more easily.
Patch 5/8 adds support for the opp-supported-hw property. This is done
in a generic way, so it's usable for other SoCs as well, and the code
will figure out if the current DT requires use of this feature.
Patch 6/8 then eventually adds the H616 bits to the driver, and ties
that to the new compatible string.
Patch 7/8 add the CPU OPP table as a .dtsi to the DT directory, the
values in there were taken from the BSP source.
Patch 8/8 then enables the OPPs for all boards we have DTs for.

Based on v6.9-rc1.

Please have a look!

Cheers,
Andre

[1] https://lore.kernel.org/linux-sunxi/20230904-cpufreq-h616-v1-0-b8842e525c43@somainline.org/T/#u

Changelog v3 .. v4:
- add Review and Ack tags
- allow to compile without CONFIG_HAVE_ARM_SMCCC_DISCOVERY
- limit opp-supported-hw array length to 1
- drop unneeded pipe after description in binding
- reorder variables in reverse christmas tree in refactor patch

Changelog v2 .. v3:
- rebased on top of v6.9-rc1
- drop node name suffix from DT bindings
- drop multiple nodes per frequency in DT bindings example
- add H700 nvmem value and OPPs
- print warning for unknown nvmem values
- add #cooling-cells properties to CPU DT nodes
- use one DT node per frequency for OPP table entries
- include OPP table for newly added Longan board

Changelog v1 .. v2:
- extend commit messages
- add H618/H700 SoC IDs
- fix binding compatible enum
- fix binding documentation
- allow additional suffix to OPP node name
- shorten existing DT binding example
- add another (opp-supported-hw) binding example
- move speed bin decoding refactoring to separate patch (Brandon)
- move opp-supported-hw support to separate patch
- merge opp-supported-hw and microvolt suffix handling
- rewrite OPP tables without opp-microvolt-speed suffix


Andre Przywara (2):
  cpufreq: sun50i: Add support for opp_supported_hw
  arm64: dts: allwinner: h616: enable DVFS for all boards

Brandon Cheo Fusi (1):
  cpufreq: sun50i: Refactor speed bin decoding

Martin Botka (5):
  firmware: smccc: Export revision soc_id function
  cpufreq: dt-platdev: Blocklist Allwinner H616/618 SoCs
  dt-bindings: opp: Describe H616 OPPs and opp-supported-hw
  cpufreq: sun50i: Add H616 support
  arm64: dts: allwinner: h616: Add CPU OPPs table

 .../allwinner,sun50i-h6-operating-points.yaml |  87 ++++----
 .../sun50i-h616-bigtreetech-cb1.dtsi          |   5 +
 .../dts/allwinner/sun50i-h616-cpu-opp.dtsi    | 125 +++++++++++
 .../allwinner/sun50i-h616-orangepi-zero2.dts  |   5 +
 .../dts/allwinner/sun50i-h616-x96-mate.dts    |   5 +
 .../arm64/boot/dts/allwinner/sun50i-h616.dtsi |   8 +
 .../sun50i-h618-longan-module-3h.dtsi         |   5 +
 .../allwinner/sun50i-h618-orangepi-zero2w.dts |   5 +
 .../allwinner/sun50i-h618-orangepi-zero3.dts  |   5 +
 .../sun50i-h618-transpeed-8k618-t.dts         |   5 +
 drivers/cpufreq/cpufreq-dt-platdev.c          |   3 +
 drivers/cpufreq/sun50i-cpufreq-nvmem.c        | 206 +++++++++++++++---
 drivers/firmware/smccc/smccc.c                |   1 +
 13 files changed, 388 insertions(+), 77 deletions(-)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi

-- 
2.35.8


^ permalink raw reply

* [PATCH v4 1/8] firmware: smccc: Export revision soc_id function
From: Andre Przywara @ 2024-03-29 14:13 UTC (permalink / raw)
  To: Yangtao Li, Viresh Kumar, Nishanth Menon, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Rafael J . Wysocki, Mark Rutland,
	Lorenzo Pieralisi, Sudeep Holla
  Cc: linux-pm, devicetree, linux-sunxi, linux-arm-kernel,
	Brandon Cheo Fusi, Martin Botka, Martin Botka, Chris Morgan,
	Ryan Walklin
In-Reply-To: <20240329141311.27158-1-andre.przywara@arm.com>

From: Martin Botka <martin.botka@somainline.org>

The "SoC ID revision" as provided via the SMCCC SOCID interface can be
valuable information for drivers, when certain functionality depends
on a die revision, for instance.
One example is the sun50i-cpufreq-nvmem driver, which needs this
information to determine the speed bin of the SoC.

Export the arm_smccc_get_soc_id_revision() function so that it can be
called by any driver.

Signed-off-by: Martin Botka <martin.botka@somainline.org>
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Sudeep Holla <sudeep.holla@arm.com>
---
 drivers/firmware/smccc/smccc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/firmware/smccc/smccc.c b/drivers/firmware/smccc/smccc.c
index db818f9dcb8ee..d670635914ecb 100644
--- a/drivers/firmware/smccc/smccc.c
+++ b/drivers/firmware/smccc/smccc.c
@@ -69,6 +69,7 @@ s32 arm_smccc_get_soc_id_revision(void)
 {
 	return smccc_soc_id_revision;
 }
+EXPORT_SYMBOL_GPL(arm_smccc_get_soc_id_revision);
 
 static int __init smccc_devices_init(void)
 {
-- 
2.35.8


^ permalink raw reply related

* [PATCH v4 2/8] cpufreq: dt-platdev: Blocklist Allwinner H616/618 SoCs
From: Andre Przywara @ 2024-03-29 14:13 UTC (permalink / raw)
  To: Yangtao Li, Viresh Kumar, Nishanth Menon, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Rafael J . Wysocki
  Cc: linux-pm, devicetree, linux-sunxi, linux-arm-kernel,
	Brandon Cheo Fusi, Martin Botka, Martin Botka, Chris Morgan,
	Ryan Walklin
In-Reply-To: <20240329141311.27158-1-andre.przywara@arm.com>

From: Martin Botka <martin.botka@somainline.org>

The AllWinner H616 SoC will use the (extended) H6 OPP driver, so add
them to the cpufreq-dt blocklist, to not create the device twice.
This also affects the closely related sibling SoCs H618 and H700.

Signed-off-by: Martin Botka <martin.botka@somainline.org>
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
 drivers/cpufreq/cpufreq-dt-platdev.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
index b993a498084bc..86d8baa816795 100644
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -104,6 +104,9 @@ static const struct of_device_id allowlist[] __initconst = {
  */
 static const struct of_device_id blocklist[] __initconst = {
 	{ .compatible = "allwinner,sun50i-h6", },
+	{ .compatible = "allwinner,sun50i-h616", },
+	{ .compatible = "allwinner,sun50i-h618", },
+	{ .compatible = "allwinner,sun50i-h700", },
 
 	{ .compatible = "apple,arm-platform", },
 
-- 
2.35.8


^ permalink raw reply related

* [PATCH v4 3/8] dt-bindings: opp: Describe H616 OPPs and opp-supported-hw
From: Andre Przywara @ 2024-03-29 14:13 UTC (permalink / raw)
  To: Yangtao Li, Viresh Kumar, Nishanth Menon, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Rafael J . Wysocki
  Cc: linux-pm, devicetree, linux-sunxi, linux-arm-kernel,
	Brandon Cheo Fusi, Martin Botka, Martin Botka, Chris Morgan,
	Ryan Walklin, Rob Herring
In-Reply-To: <20240329141311.27158-1-andre.przywara@arm.com>

From: Martin Botka <martin.botka@somainline.org>

Compared to the existing Allwinner H6 OPP scheme, the H616 uses a
similar NVMEM based mechanism to determine the silicon revision, which
is required to select the right frequency / voltage pair for the OPPs.
However it limits the maximum frequency for some speed bins, also seems
to not support all frequencies in all speed bins, which requires us to
introduce the opp-supported-hw property.

Add this property to the list of allowed properties, also drop the
requirement for the revision specific opp-microvolt properties, since
they might not be needed if using opp-supported-hw.

Also use to opportunity to adjust some wording, and drop a sentence
referring to the Linux driver and the OPP subsystem.

Shorten the existing example and add another example, showcasing the
opp-supported-hw property.

Signed-off-by: Martin Botka <martin.botka@somainline.org>
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 .../allwinner,sun50i-h6-operating-points.yaml | 87 +++++++++----------
 1 file changed, 43 insertions(+), 44 deletions(-)

diff --git a/Documentation/devicetree/bindings/opp/allwinner,sun50i-h6-operating-points.yaml b/Documentation/devicetree/bindings/opp/allwinner,sun50i-h6-operating-points.yaml
index 51f62c3ae1947..ec5e424bb3c83 100644
--- a/Documentation/devicetree/bindings/opp/allwinner,sun50i-h6-operating-points.yaml
+++ b/Documentation/devicetree/bindings/opp/allwinner,sun50i-h6-operating-points.yaml
@@ -13,25 +13,25 @@ maintainers:
 description: |
   For some SoCs, the CPU frequency subset and voltage value of each
   OPP varies based on the silicon variant in use. Allwinner Process
-  Voltage Scaling Tables defines the voltage and frequency value based
-  on the speedbin blown in the efuse combination. The
-  sun50i-cpufreq-nvmem driver reads the efuse value from the SoC to
-  provide the OPP framework with required information.
+  Voltage Scaling Tables define the voltage and frequency values based
+  on the speedbin blown in the efuse combination.
 
 allOf:
   - $ref: opp-v2-base.yaml#
 
 properties:
   compatible:
-    const: allwinner,sun50i-h6-operating-points
+    enum:
+      - allwinner,sun50i-h6-operating-points
+      - allwinner,sun50i-h616-operating-points
 
   nvmem-cells:
     description: |
       A phandle pointing to a nvmem-cells node representing the efuse
-      registers that has information about the speedbin that is used
+      register that has information about the speedbin that is used
       to select the right frequency/voltage value pair. Please refer
-      the for nvmem-cells bindings
-      Documentation/devicetree/bindings/nvmem/nvmem.txt and also
+      to the nvmem-cells bindings in
+      Documentation/devicetree/bindings/nvmem/nvmem.yaml and also the
       examples below.
 
   opp-shared: true
@@ -47,15 +47,18 @@ patternProperties:
     properties:
       opp-hz: true
       clock-latency-ns: true
+      opp-microvolt: true
+      opp-supported-hw:
+        maxItems: 1
+        description:
+          A single 32 bit bitmap value, representing compatible HW, one
+          bit per speed bin index.
 
     patternProperties:
       "^opp-microvolt-speed[0-9]$": true
 
     required:
       - opp-hz
-      - opp-microvolt-speed0
-      - opp-microvolt-speed1
-      - opp-microvolt-speed2
 
     unevaluatedProperties: false
 
@@ -77,58 +80,54 @@ examples:
             opp-microvolt-speed2 = <800000>;
         };
 
-        opp-720000000 {
+        opp-1080000000 {
             clock-latency-ns = <244144>; /* 8 32k periods */
-            opp-hz = /bits/ 64 <720000000>;
+            opp-hz = /bits/ 64 <1080000000>;
 
-            opp-microvolt-speed0 = <880000>;
-            opp-microvolt-speed1 = <820000>;
-            opp-microvolt-speed2 = <800000>;
+            opp-microvolt-speed0 = <1060000>;
+            opp-microvolt-speed1 = <880000>;
+            opp-microvolt-speed2 = <840000>;
         };
 
-        opp-816000000 {
+        opp-1488000000 {
             clock-latency-ns = <244144>; /* 8 32k periods */
-            opp-hz = /bits/ 64 <816000000>;
+            opp-hz = /bits/ 64 <1488000000>;
 
-            opp-microvolt-speed0 = <880000>;
-            opp-microvolt-speed1 = <820000>;
-            opp-microvolt-speed2 = <800000>;
+            opp-microvolt-speed0 = <1160000>;
+            opp-microvolt-speed1 = <1000000>;
+            opp-microvolt-speed2 = <960000>;
         };
+    };
 
-        opp-888000000 {
-            clock-latency-ns = <244144>; /* 8 32k periods */
-            opp-hz = /bits/ 64 <888000000>;
-
-            opp-microvolt-speed0 = <940000>;
-            opp-microvolt-speed1 = <820000>;
-            opp-microvolt-speed2 = <800000>;
-        };
+  - |
+    opp-table {
+        compatible = "allwinner,sun50i-h616-operating-points";
+        nvmem-cells = <&speedbin_efuse>;
+        opp-shared;
 
-        opp-1080000000 {
+        opp-480000000 {
             clock-latency-ns = <244144>; /* 8 32k periods */
-            opp-hz = /bits/ 64 <1080000000>;
+            opp-hz = /bits/ 64 <480000000>;
 
-            opp-microvolt-speed0 = <1060000>;
-            opp-microvolt-speed1 = <880000>;
-            opp-microvolt-speed2 = <840000>;
+            opp-microvolt = <900000>;
+            opp-supported-hw = <0x1f>;
         };
 
-        opp-1320000000 {
+        opp-792000000 {
             clock-latency-ns = <244144>; /* 8 32k periods */
-            opp-hz = /bits/ 64 <1320000000>;
+            opp-hz = /bits/ 64 <792000000>;
 
-            opp-microvolt-speed0 = <1160000>;
-            opp-microvolt-speed1 = <940000>;
-            opp-microvolt-speed2 = <900000>;
+            opp-microvolt-speed1 = <900000>;
+            opp-microvolt-speed4 = <940000>;
+            opp-supported-hw = <0x12>;
         };
 
-        opp-1488000000 {
+        opp-1512000000 {
             clock-latency-ns = <244144>; /* 8 32k periods */
-            opp-hz = /bits/ 64 <1488000000>;
+            opp-hz = /bits/ 64 <1512000000>;
 
-            opp-microvolt-speed0 = <1160000>;
-            opp-microvolt-speed1 = <1000000>;
-            opp-microvolt-speed2 = <960000>;
+            opp-microvolt = <1100000>;
+            opp-supported-hw = <0x0a>;
         };
     };
 
-- 
2.35.8


^ permalink raw reply related

* [PATCH v4 4/8] cpufreq: sun50i: Refactor speed bin decoding
From: Andre Przywara @ 2024-03-29 14:13 UTC (permalink / raw)
  To: Yangtao Li, Viresh Kumar, Nishanth Menon, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Rafael J . Wysocki
  Cc: linux-pm, devicetree, linux-sunxi, linux-arm-kernel,
	Brandon Cheo Fusi, Martin Botka, Martin Botka, Chris Morgan,
	Ryan Walklin
In-Reply-To: <20240329141311.27158-1-andre.przywara@arm.com>

From: Brandon Cheo Fusi <fusibrandon13@gmail.com>

Make converting the speed bin value into a speed grade generic and
determined by a platform specific callback. Also change the prototypes
involved to encode the speed bin directly in the return value.

This allows to extend the driver more easily to support more SoCs.

Signed-off-by: Brandon Cheo Fusi <fusibrandon13@gmail.com>
[Andre: merge output into return value]
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
 drivers/cpufreq/sun50i-cpufreq-nvmem.c | 74 +++++++++++++++++---------
 1 file changed, 49 insertions(+), 25 deletions(-)

diff --git a/drivers/cpufreq/sun50i-cpufreq-nvmem.c b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
index 32a9c88f8ff6d..45c56e23346e9 100644
--- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c
+++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
@@ -25,19 +25,52 @@
 
 static struct platform_device *cpufreq_dt_pdev, *sun50i_cpufreq_pdev;
 
+struct sunxi_cpufreq_data {
+	u32 (*efuse_xlate)(u32 speedbin);
+};
+
+static u32 sun50i_h6_efuse_xlate(u32 speedbin)
+{
+	u32 efuse_value;
+
+	efuse_value = (speedbin >> NVMEM_SHIFT) & NVMEM_MASK;
+
+	/*
+	 * We treat unexpected efuse values as if the SoC was from
+	 * the slowest bin. Expected efuse values are 1-3, slowest
+	 * to fastest.
+	 */
+	if (efuse_value >= 1 && efuse_value <= 3)
+		return efuse_value - 1;
+	else
+		return 0;
+}
+
+static struct sunxi_cpufreq_data sun50i_h6_cpufreq_data = {
+	.efuse_xlate = sun50i_h6_efuse_xlate,
+};
+
+static const struct of_device_id cpu_opp_match_list[] = {
+	{ .compatible = "allwinner,sun50i-h6-operating-points",
+	  .data = &sun50i_h6_cpufreq_data,
+	},
+	{}
+};
+
 /**
  * sun50i_cpufreq_get_efuse() - Determine speed grade from efuse value
- * @versions: Set to the value parsed from efuse
  *
- * Returns 0 if success.
+ * Returns non-negative speed bin index on success, a negative error
+ * value otherwise.
  */
-static int sun50i_cpufreq_get_efuse(u32 *versions)
+static int sun50i_cpufreq_get_efuse(void)
 {
+	const struct sunxi_cpufreq_data *opp_data;
 	struct nvmem_cell *speedbin_nvmem;
+	const struct of_device_id *match;
 	struct device_node *np;
 	struct device *cpu_dev;
-	u32 *speedbin, efuse_value;
-	size_t len;
+	u32 *speedbin;
 	int ret;
 
 	cpu_dev = get_cpu_device(0);
@@ -48,12 +81,12 @@ static int sun50i_cpufreq_get_efuse(u32 *versions)
 	if (!np)
 		return -ENOENT;
 
-	ret = of_device_is_compatible(np,
-				      "allwinner,sun50i-h6-operating-points");
-	if (!ret) {
+	match = of_match_node(cpu_opp_match_list, np);
+	if (!match) {
 		of_node_put(np);
 		return -ENOENT;
 	}
+	opp_data = match->data;
 
 	speedbin_nvmem = of_nvmem_cell_get(np, NULL);
 	of_node_put(np);
@@ -61,25 +94,16 @@ static int sun50i_cpufreq_get_efuse(u32 *versions)
 		return dev_err_probe(cpu_dev, PTR_ERR(speedbin_nvmem),
 				     "Could not get nvmem cell\n");
 
-	speedbin = nvmem_cell_read(speedbin_nvmem, &len);
+	speedbin = nvmem_cell_read(speedbin_nvmem, NULL);
 	nvmem_cell_put(speedbin_nvmem);
 	if (IS_ERR(speedbin))
 		return PTR_ERR(speedbin);
 
-	efuse_value = (*speedbin >> NVMEM_SHIFT) & NVMEM_MASK;
-
-	/*
-	 * We treat unexpected efuse values as if the SoC was from
-	 * the slowest bin. Expected efuse values are 1-3, slowest
-	 * to fastest.
-	 */
-	if (efuse_value >= 1 && efuse_value <= 3)
-		*versions = efuse_value - 1;
-	else
-		*versions = 0;
+	ret = opp_data->efuse_xlate(*speedbin);
 
 	kfree(speedbin);
-	return 0;
+
+	return ret;
 };
 
 static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev)
@@ -87,7 +111,7 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev)
 	int *opp_tokens;
 	char name[MAX_NAME_LEN];
 	unsigned int cpu;
-	u32 speed = 0;
+	int speed;
 	int ret;
 
 	opp_tokens = kcalloc(num_possible_cpus(), sizeof(*opp_tokens),
@@ -95,10 +119,10 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev)
 	if (!opp_tokens)
 		return -ENOMEM;
 
-	ret = sun50i_cpufreq_get_efuse(&speed);
-	if (ret) {
+	speed = sun50i_cpufreq_get_efuse();
+	if (speed < 0) {
 		kfree(opp_tokens);
-		return ret;
+		return speed;
 	}
 
 	snprintf(name, MAX_NAME_LEN, "speed%d", speed);
-- 
2.35.8


^ permalink raw reply related

* [PATCH v4 5/8] cpufreq: sun50i: Add support for opp_supported_hw
From: Andre Przywara @ 2024-03-29 14:13 UTC (permalink / raw)
  To: Yangtao Li, Viresh Kumar, Nishanth Menon, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Rafael J . Wysocki
  Cc: linux-pm, devicetree, linux-sunxi, linux-arm-kernel,
	Brandon Cheo Fusi, Martin Botka, Martin Botka, Chris Morgan,
	Ryan Walklin
In-Reply-To: <20240329141311.27158-1-andre.przywara@arm.com>

The opp_supported_hw DT property allows the DT to specify a mask of chip
revisions that a certain OPP is eligible for. This allows for easy
limiting of maximum frequencies, for instance.

Add support for that in the sun50i-cpufreq-nvmem driver. We support both
the existing opp-microvolt suffix properties as well as the
opp-supported-hw property, the generic code figures out which is needed
automatically.
However if none of the DT OPP nodes contain an opp-supported-hw
property, the core code will ignore all OPPs and the driver will fail
probing. So check the DT's eligibility first before using that feature.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
 drivers/cpufreq/sun50i-cpufreq-nvmem.c | 62 ++++++++++++++++++++++----
 1 file changed, 54 insertions(+), 8 deletions(-)

diff --git a/drivers/cpufreq/sun50i-cpufreq-nvmem.c b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
index 45c56e23346e9..8719955278d9a 100644
--- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c
+++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
@@ -57,6 +57,41 @@ static const struct of_device_id cpu_opp_match_list[] = {
 	{}
 };
 
+/**
+ * dt_has_supported_hw() - Check if any OPPs use opp-supported-hw
+ *
+ * If we ask the cpufreq framework to use the opp-supported-hw feature, it
+ * will ignore every OPP node without that DT property. If none of the OPPs
+ * have it, the driver will fail probing, due to the lack of OPPs.
+ *
+ * Returns true if we have at least one OPP with the opp-supported-hw property.
+ */
+static bool dt_has_supported_hw(void)
+{
+	bool has_opp_supported_hw = false;
+	struct device_node *np, *opp;
+	struct device *cpu_dev;
+
+	cpu_dev = get_cpu_device(0);
+	if (!cpu_dev)
+		return -ENODEV;
+
+	np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
+	if (!np)
+		return -ENOENT;
+
+	for_each_child_of_node(np, opp) {
+		if (of_find_property(opp, "opp-supported-hw", NULL)) {
+			has_opp_supported_hw = true;
+			break;
+		}
+	}
+
+	of_node_put(np);
+
+	return has_opp_supported_hw;
+}
+
 /**
  * sun50i_cpufreq_get_efuse() - Determine speed grade from efuse value
  *
@@ -110,7 +145,8 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev)
 {
 	int *opp_tokens;
 	char name[MAX_NAME_LEN];
-	unsigned int cpu;
+	unsigned int cpu, supported_hw;
+	struct dev_pm_opp_config config = {};
 	int speed;
 	int ret;
 
@@ -125,7 +161,18 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev)
 		return speed;
 	}
 
+	/*
+	 * We need at least one OPP with the "opp-supported-hw" property,
+	 * or else the upper layers will ignore every OPP and will bail out.
+	 */
+	if (dt_has_supported_hw()) {
+		supported_hw = 1U << speed;
+		config.supported_hw = &supported_hw;
+		config.supported_hw_count = 1;
+	}
+
 	snprintf(name, MAX_NAME_LEN, "speed%d", speed);
+	config.prop_name = name;
 
 	for_each_possible_cpu(cpu) {
 		struct device *cpu_dev = get_cpu_device(cpu);
@@ -135,12 +182,11 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev)
 			goto free_opp;
 		}
 
-		opp_tokens[cpu] = dev_pm_opp_set_prop_name(cpu_dev, name);
-		if (opp_tokens[cpu] < 0) {
-			ret = opp_tokens[cpu];
-			pr_err("Failed to set prop name\n");
+		ret = dev_pm_opp_set_config(cpu_dev, &config);
+		if (ret < 0)
 			goto free_opp;
-		}
+
+		opp_tokens[cpu] = ret;
 	}
 
 	cpufreq_dt_pdev = platform_device_register_simple("cpufreq-dt", -1,
@@ -155,7 +201,7 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev)
 
 free_opp:
 	for_each_possible_cpu(cpu)
-		dev_pm_opp_put_prop_name(opp_tokens[cpu]);
+		dev_pm_opp_clear_config(opp_tokens[cpu]);
 	kfree(opp_tokens);
 
 	return ret;
@@ -169,7 +215,7 @@ static void sun50i_cpufreq_nvmem_remove(struct platform_device *pdev)
 	platform_device_unregister(cpufreq_dt_pdev);
 
 	for_each_possible_cpu(cpu)
-		dev_pm_opp_put_prop_name(opp_tokens[cpu]);
+		dev_pm_opp_clear_config(opp_tokens[cpu]);
 
 	kfree(opp_tokens);
 }
-- 
2.35.8


^ permalink raw reply related

* [PATCH v4 6/8] cpufreq: sun50i: Add H616 support
From: Andre Przywara @ 2024-03-29 14:13 UTC (permalink / raw)
  To: Yangtao Li, Viresh Kumar, Nishanth Menon, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Rafael J . Wysocki
  Cc: linux-pm, devicetree, linux-sunxi, linux-arm-kernel,
	Brandon Cheo Fusi, Martin Botka, Martin Botka, Chris Morgan,
	Ryan Walklin, Mark Rutland, Lorenzo Pieralisi, Sudeep Holla
In-Reply-To: <20240329141311.27158-1-andre.przywara@arm.com>

From: Martin Botka <martin.botka@somainline.org>

The Allwinner H616/H618 SoCs have different OPP tables per SoC version
and die revision. The SoC version is stored in NVMEM, as before, though
encoded differently. The die revision is in a different register, in the
SRAM controller. Firmware already exports that value in a standardised
way, through the SMCCC SoCID mechanism. We need both values, as some chips
have the same SoC version, but they don't support the same frequencies and
they get differentiated by the die revision.

Add the new compatible string and tie the new translation function to
it. This mechanism not only covers the original H616 SoC, but also its
very close sibling SoCs H618 and H700, so add them to the list as well.

Signed-off-by: Martin Botka <martin.botka@somainline.org>
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
 drivers/cpufreq/sun50i-cpufreq-nvmem.c | 70 ++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/drivers/cpufreq/sun50i-cpufreq-nvmem.c b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
index 8719955278d9a..db355888598df 100644
--- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c
+++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
@@ -10,6 +10,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/arm-smccc.h>
 #include <linux/cpu.h>
 #include <linux/module.h>
 #include <linux/nvmem-consumer.h>
@@ -46,14 +47,80 @@ static u32 sun50i_h6_efuse_xlate(u32 speedbin)
 		return 0;
 }
 
+static int get_soc_id_revision(void)
+{
+#ifdef CONFIG_HAVE_ARM_SMCCC_DISCOVERY
+	return arm_smccc_get_soc_id_revision();
+#else
+	return SMCCC_RET_NOT_SUPPORTED;
+#endif
+}
+
+/*
+ * Judging by the OPP tables in the vendor BSP, the quality order of the
+ * returned speedbin index is 4 -> 0/2 -> 3 -> 1, from worst to best.
+ * 0 and 2 seem identical from the OPP tables' point of view.
+ */
+static u32 sun50i_h616_efuse_xlate(u32 speedbin)
+{
+	int ver_bits = get_soc_id_revision();
+	u32 value = 0;
+
+	switch (speedbin & 0xffff) {
+	case 0x2000:
+		value = 0;
+		break;
+	case 0x2400:
+	case 0x7400:
+	case 0x2c00:
+	case 0x7c00:
+		if (ver_bits != SMCCC_RET_NOT_SUPPORTED && ver_bits <= 1) {
+			/* ic version A/B */
+			value = 1;
+		} else {
+			/* ic version C and later version */
+			value = 2;
+		}
+		break;
+	case 0x5000:
+	case 0x5400:
+	case 0x6000:
+		value = 3;
+		break;
+	case 0x5c00:
+		value = 4;
+		break;
+	case 0x5d00:
+		value = 0;
+		break;
+	case 0x6c00:
+		value = 5;
+		break;
+	default:
+		pr_warn("sun50i-cpufreq-nvmem: unknown speed bin 0x%x, using default bin 0\n",
+			speedbin & 0xffff);
+		value = 0;
+		break;
+	}
+
+	return value;
+}
+
 static struct sunxi_cpufreq_data sun50i_h6_cpufreq_data = {
 	.efuse_xlate = sun50i_h6_efuse_xlate,
 };
 
+static struct sunxi_cpufreq_data sun50i_h616_cpufreq_data = {
+	.efuse_xlate = sun50i_h616_efuse_xlate,
+};
+
 static const struct of_device_id cpu_opp_match_list[] = {
 	{ .compatible = "allwinner,sun50i-h6-operating-points",
 	  .data = &sun50i_h6_cpufreq_data,
 	},
+	{ .compatible = "allwinner,sun50i-h616-operating-points",
+	  .data = &sun50i_h616_cpufreq_data,
+	},
 	{}
 };
 
@@ -230,6 +297,9 @@ static struct platform_driver sun50i_cpufreq_driver = {
 
 static const struct of_device_id sun50i_cpufreq_match_list[] = {
 	{ .compatible = "allwinner,sun50i-h6" },
+	{ .compatible = "allwinner,sun50i-h616" },
+	{ .compatible = "allwinner,sun50i-h618" },
+	{ .compatible = "allwinner,sun50i-h700" },
 	{}
 };
 MODULE_DEVICE_TABLE(of, sun50i_cpufreq_match_list);
-- 
2.35.8


^ permalink raw reply related

* [PATCH v4 7/8] arm64: dts: allwinner: h616: Add CPU OPPs table
From: Andre Przywara @ 2024-03-29 14:13 UTC (permalink / raw)
  To: Yangtao Li, Viresh Kumar, Nishanth Menon, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Rafael J . Wysocki
  Cc: linux-pm, devicetree, linux-sunxi, linux-arm-kernel,
	Brandon Cheo Fusi, Martin Botka, Martin Botka, Chris Morgan,
	Ryan Walklin
In-Reply-To: <20240329141311.27158-1-andre.przywara@arm.com>

From: Martin Botka <martin.botka@somainline.org>

Add an Operating Performance Points table for the CPU cores to enable
Dynamic Voltage & Frequency Scaling (DVFS) on the H616.
The values were taken from the BSP sources. The (newer) H700 chips we
have seen seem to use a separate speed bin, its OPP values were taken
from a live system and added to the mix.

Also add the needed cpu_speed_grade nvmem cell and the cooling cells
properties, to enable passive cooling.

Signed-off-by: Martin Botka <martin.botka@somainline.org>
[Andre: rework to minimise opp-microvolt properties]
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
 .../dts/allwinner/sun50i-h616-cpu-opp.dtsi    | 125 ++++++++++++++++++
 .../arm64/boot/dts/allwinner/sun50i-h616.dtsi |   8 ++
 2 files changed, 133 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi
new file mode 100644
index 0000000000000..6073fdf672592
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2023 Martin Botka <martin@somainline.org>
+
+/ {
+	cpu_opp_table: opp-table-cpu {
+		compatible = "allwinner,sun50i-h616-operating-points";
+		nvmem-cells = <&cpu_speed_grade>;
+		opp-shared;
+
+		opp-480000000 {
+			opp-hz = /bits/ 64 <480000000>;
+			opp-microvolt = <900000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+			opp-supported-hw = <0x3f>;
+		};
+
+		opp-600000000 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-microvolt = <900000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+			opp-supported-hw = <0x12>;
+		};
+
+		opp-720000000 {
+			opp-hz = /bits/ 64 <720000000>;
+			opp-microvolt = <900000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+			opp-supported-hw = <0x2d>;
+		};
+
+		opp-792000000 {
+			opp-hz = /bits/ 64 <792000000>;
+			opp-microvolt-speed1 = <900000>;
+			opp-microvolt-speed4 = <940000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+			opp-supported-hw = <0x12>;
+		};
+
+		opp-936000000 {
+			opp-hz = /bits/ 64 <936000000>;
+			opp-microvolt = <900000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+			opp-supported-hw = <0x0d>;
+		};
+
+		opp-1008000000 {
+			opp-hz = /bits/ 64 <1008000000>;
+			opp-microvolt-speed0 = <950000>;
+			opp-microvolt-speed1 = <940000>;
+			opp-microvolt-speed2 = <950000>;
+			opp-microvolt-speed3 = <950000>;
+			opp-microvolt-speed4 = <1020000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+			opp-supported-hw = <0x1f>;
+		};
+
+		opp-10320000 {
+			opp-hz = /bits/ 64 <1032000000>;
+			opp-microvolt = <900000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+			opp-supported-hw = <0x20>;
+		};
+
+		opp-1104000000 {
+			opp-hz = /bits/ 64 <1104000000>;
+			opp-microvolt-speed0 = <1000000>;
+			opp-microvolt-speed2 = <1000000>;
+			opp-microvolt-speed3 = <1000000>;
+			opp-microvolt-speed5 = <950000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+			opp-supported-hw = <0x2d>;
+		};
+
+		opp-1200000000 {
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-microvolt-speed0 = <1050000>;
+			opp-microvolt-speed1 = <1020000>;
+			opp-microvolt-speed2 = <1050000>;
+			opp-microvolt-speed3 = <1050000>;
+			opp-microvolt-speed4 = <1100000>;
+			opp-microvolt-speed5 = <1020000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+			opp-supported-hw = <0x3f>;
+		};
+
+		opp-1320000000 {
+			opp-hz = /bits/ 64 <1320000000>;
+			opp-microvolt = <1100000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+			opp-supported-hw = <0x1d>;
+		};
+
+		opp-1416000000 {
+			opp-hz = /bits/ 64 <1416000000>;
+			opp-microvolt = <1100000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+			opp-supported-hw = <0x2d>;
+		};
+
+		opp-1512000000 {
+			opp-hz = /bits/ 64 <1512000000>;
+			opp-microvolt-speed1 = <1100000>;
+			opp-microvolt-speed3 = <1100000>;
+			opp-microvolt-speed5 = <1160000>;
+			clock-latency-ns = <244144>; /* 8 32k periods */
+			opp-supported-hw = <0x2a>;
+		};
+	};
+};
+
+&cpu0 {
+	operating-points-v2 = <&cpu_opp_table>;
+};
+
+&cpu1 {
+	operating-points-v2 = <&cpu_opp_table>;
+};
+
+&cpu2 {
+	operating-points-v2 = <&cpu_opp_table>;
+};
+
+&cpu3 {
+	operating-points-v2 = <&cpu_opp_table>;
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
index b2e85e52d1a12..c0fa466fa9f07 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
@@ -26,6 +26,7 @@ cpu0: cpu@0 {
 			reg = <0>;
 			enable-method = "psci";
 			clocks = <&ccu CLK_CPUX>;
+			#cooling-cells = <2>;
 		};
 
 		cpu1: cpu@1 {
@@ -34,6 +35,7 @@ cpu1: cpu@1 {
 			reg = <1>;
 			enable-method = "psci";
 			clocks = <&ccu CLK_CPUX>;
+			#cooling-cells = <2>;
 		};
 
 		cpu2: cpu@2 {
@@ -42,6 +44,7 @@ cpu2: cpu@2 {
 			reg = <2>;
 			enable-method = "psci";
 			clocks = <&ccu CLK_CPUX>;
+			#cooling-cells = <2>;
 		};
 
 		cpu3: cpu@3 {
@@ -50,6 +53,7 @@ cpu3: cpu@3 {
 			reg = <3>;
 			enable-method = "psci";
 			clocks = <&ccu CLK_CPUX>;
+			#cooling-cells = <2>;
 		};
 	};
 
@@ -156,6 +160,10 @@ sid: efuse@3006000 {
 			ths_calibration: thermal-sensor-calibration@14 {
 				reg = <0x14 0x8>;
 			};
+
+			cpu_speed_grade: cpu-speed-grade@0 {
+				reg = <0x0 2>;
+			};
 		};
 
 		watchdog: watchdog@30090a0 {
-- 
2.35.8


^ permalink raw reply related

* [PATCH v4 8/8] arm64: dts: allwinner: h616: enable DVFS for all boards
From: Andre Przywara @ 2024-03-29 14:13 UTC (permalink / raw)
  To: Yangtao Li, Viresh Kumar, Nishanth Menon, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chen-Yu Tsai,
	Jernej Skrabec, Samuel Holland, Rafael J . Wysocki
  Cc: linux-pm, devicetree, linux-sunxi, linux-arm-kernel,
	Brandon Cheo Fusi, Martin Botka, Martin Botka, Chris Morgan,
	Ryan Walklin
In-Reply-To: <20240329141311.27158-1-andre.przywara@arm.com>

With the DT bindings now describing the format of the CPU OPP tables, we
can include the OPP table in each board's .dts file, and specify the CPU
power supply.
This allows to enable DVFS, and get up to 50% of performance benefit in
the highest OPP, or up to 60% power savings in the lowest OPP, compared
to the fixed 1GHz @ 1.0V OPP we are running in by default at the moment.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
 .../boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi      | 5 +++++
 arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts | 5 +++++
 arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts       | 5 +++++
 .../boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi     | 5 +++++
 .../arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero2w.dts | 5 +++++
 arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts | 5 +++++
 .../boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts     | 5 +++++
 7 files changed, 35 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
index af421ba24ce0c..d12b01c5f41b6 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
@@ -6,6 +6,7 @@
 /dts-v1/;
 
 #include "sun50i-h616.dtsi"
+#include "sun50i-h616-cpu-opp.dtsi"
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -62,6 +63,10 @@ wifi_pwrseq: wifi-pwrseq {
 	};
 };
 
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
 &mmc0 {
 	vmmc-supply = <&reg_dldo1>;
 	/* Card detection pin is not connected */
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
index b5d713926a341..a360d8567f955 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
@@ -6,12 +6,17 @@
 /dts-v1/;
 
 #include "sun50i-h616-orangepi-zero.dtsi"
+#include "sun50i-h616-cpu-opp.dtsi"
 
 / {
 	model = "OrangePi Zero2";
 	compatible = "xunlong,orangepi-zero2", "allwinner,sun50i-h616";
 };
 
+&cpu0 {
+	cpu-supply = <&reg_dcdca>;
+};
+
 &emac0 {
 	allwinner,rx-delay-ps = <3100>;
 	allwinner,tx-delay-ps = <700>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts b/arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts
index 959b6fd18483b..26d25b5b59e0f 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts
@@ -6,6 +6,7 @@
 /dts-v1/;
 
 #include "sun50i-h616.dtsi"
+#include "sun50i-h616-cpu-opp.dtsi"
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -32,6 +33,10 @@ reg_vcc5v: vcc5v {
 	};
 };
 
+&cpu0 {
+	cpu-supply = <&reg_dcdca>;
+};
+
 &ehci0 {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
index 8c1263a3939e7..e92d150aaf1c1 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
@@ -4,6 +4,11 @@
  */
 
 #include "sun50i-h616.dtsi"
+#include "sun50i-h616-cpu-opp.dtsi"
+
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
 
 &mmc2 {
 	pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero2w.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero2w.dts
index 21ca1977055d9..6a4f0da972330 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero2w.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero2w.dts
@@ -6,6 +6,7 @@
 /dts-v1/;
 
 #include "sun50i-h616.dtsi"
+#include "sun50i-h616-cpu-opp.dtsi"
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -53,6 +54,10 @@ reg_vcc3v3: vcc3v3 {
 	};
 };
 
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
 &ehci1 {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts
index b3b1b8692125f..e1cd7572a14ce 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts
@@ -6,12 +6,17 @@
 /dts-v1/;
 
 #include "sun50i-h616-orangepi-zero.dtsi"
+#include "sun50i-h616-cpu-opp.dtsi"
 
 / {
 	model = "OrangePi Zero3";
 	compatible = "xunlong,orangepi-zero3", "allwinner,sun50i-h618";
 };
 
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
 &emac0 {
 	allwinner,tx-delay-ps = <700>;
 	phy-mode = "rgmii-rxid";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
index ac0a2b7ea6f31..a6458b7a86713 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
@@ -6,6 +6,7 @@
 /dts-v1/;
 
 #include "sun50i-h616.dtsi"
+#include "sun50i-h616-cpu-opp.dtsi"
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -51,6 +52,10 @@ wifi_pwrseq: wifi_pwrseq {
 	};
 };
 
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
 &ehci0 {
 	status = "okay";
 };
-- 
2.35.8


^ permalink raw reply related

* Re: [v1 0/3] Add i.MX8Q HSIO PHY driver support
From: Frank Li @ 2024-03-29 14:14 UTC (permalink / raw)
  To: Richard Zhu
  Cc: vkoul, kishon, robh+dt, krzysztof.kozlowski+dt, conor+dt,
	linux-phy, devicetree, linux-arm-kernel, linux-kernel, kernel,
	linux-imx
In-Reply-To: <1711699790-16494-1-git-send-email-hongxing.zhu@nxp.com>

On Fri, Mar 29, 2024 at 04:09:47PM +0800, Richard Zhu wrote:
> v1 changes:
> - Rebase to the 6.9-rc1, and constify of_phandle_args in xlate.
> No other changes.

Next time please send to imx@lists.linux.dev instead of linux-imx@nxp.com.

Frank

> 
> i.MX8Q HSIO module has PHY and mix control regions.
> This patch-set adds i.MX8Q HSIO PHY driver support, and provides
> standard PHY phandles that can be used by i.MX8Q PCIe or
> SATA driver later.
> 
> [PATCH v1 1/3] dt-bindings: phy: Add i.MX8Q HSIO SerDes PHY binding
> [PATCH v1 2/3] dt-bindings: phy: phy-imx8-pcie: Add binding for
> [PATCH v1 3/3] phy: freescale: imx8q-hsio: Add i.MX8Q HSIO PHY driver
> 
> Documentation/devicetree/bindings/phy/fsl,imx8q-hsio.yaml | 143 ++++++++++++++++++++++++
> drivers/phy/freescale/Kconfig                             |   8 ++
> drivers/phy/freescale/Makefile                            |   1 +
> drivers/phy/freescale/phy-fsl-imx8q-hsio.c                | 518 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> include/dt-bindings/phy/phy-imx8-pcie.h                   |  26 +++++
> 5 files changed, 696 insertions(+)

^ permalink raw reply

* Re: [PATCH v1 1/3] dt-bindings: phy: Add i.MX8Q HSIO SerDes PHY binding
From: Frank Li @ 2024-03-29 14:16 UTC (permalink / raw)
  To: Richard Zhu
  Cc: vkoul, kishon, robh+dt, krzysztof.kozlowski+dt, conor+dt,
	linux-phy, devicetree, linux-arm-kernel, linux-kernel, kernel,
	linux-imx
In-Reply-To: <1711699790-16494-2-git-send-email-hongxing.zhu@nxp.com>

On Fri, Mar 29, 2024 at 04:09:48PM +0800, Richard Zhu wrote:
> Add i.MX8QM and i.MX8QXP HSIO SerDes PHY binding.
> - Use the controller ID to specify which controller is binded to the
> PHY.
> - Introduce one HSIO configuration, mandatory required to set
> "PCIE_AB_SELECT" and "PHY_X1_EPCS_SEL" during the initialization.
> 
> Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>

Reviewed-by: Frank Li <Frank.Li@nxp.com>
> ---
>  .../bindings/phy/fsl,imx8q-hsio.yaml          | 143 ++++++++++++++++++
>  1 file changed, 143 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8q-hsio.yaml
> 
> diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8q-hsio.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8q-hsio.yaml
> new file mode 100644
> index 000000000000..506551d4d94a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/fsl,imx8q-hsio.yaml
> @@ -0,0 +1,143 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/fsl,imx8q-hsio.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Freescale i.MX8Q SoC series HSIO SERDES PHY
> +
> +maintainers:
> +  - Richard Zhu <hongxing.zhu@nxp.com>
> +
> +properties:
> +  compatible:
> +    enum:
> +      - fsl,imx8qxp-serdes
> +      - fsl,imx8qm-serdes
> +  reg:
> +    minItems: 4
> +    maxItems: 4
> +
> +  "#phy-cells":
> +    const: 3
> +    description: |
> +      The first number defines the ID of the PHY contained in the HSIO macro.
> +      The second defines controller ID binded to the PHY. The third defines the
> +      HSIO configuratons refer to the different use cases. They are defined in
> +      dt-bindings/phy/phy-imx8-pcie.h
> +
> +  reg-names:
> +    items:
> +      - const: reg
> +      - const: phy
> +      - const: ctrl
> +      - const: misc
> +
> +  clocks:
> +    minItems: 5
> +    maxItems: 14
> +
> +  clock-names:
> +    minItems: 5
> +    maxItems: 14
> +
> +  fsl,refclk-pad-mode:
> +    description: |
> +      Specifies the mode of the refclk pad used. It can be UNUSED(PHY
> +      refclock is derived from SoC internal source), INPUT(PHY refclock
> +      is provided externally via the refclk pad) or OUTPUT(PHY refclock
> +      is derived from SoC internal source and provided on the refclk pad).
> +      Refer include/dt-bindings/phy/phy-imx8-pcie.h for the constants
> +      to be used.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    enum: [ 0, 1, 2 ]
> +
> +  power-domains:
> +    description: |
> +      i.MX8Q HSIO SerDes power domains. i.MX8QXP has one SerDes power domains.
> +      And i.MX8QM has two.
> +    minItems: 1
> +    maxItems: 2
> +
> +required:
> +  - compatible
> +  - reg
> +  - "#phy-cells"
> +  - clocks
> +  - clock-names
> +  - fsl,refclk-pad-mode
> +
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - fsl,imx8qxp-serdes
> +    then:
> +      properties:
> +        clock-names:
> +          items:
> +            - const: apb_pclk0
> +            - const: pclk0
> +            - const: phy0_crr
> +            - const: ctl0_crr
> +            - const: misc_crr
> +        power-domains:
> +          minItems: 1
> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - fsl,imx8qm-serdes
> +    then:
> +      properties:
> +        clock-names:
> +          items:
> +            - const: pclk0
> +            - const: pclk1
> +            - const: apb_pclk0
> +            - const: apb_pclk1
> +            - const: pclk2
> +            - const: epcs_tx
> +            - const: epcs_rx
> +            - const: apb_pclk2
> +            - const: phy0_crr
> +            - const: phy1_crr
> +            - const: ctl0_crr
> +            - const: ctl1_crr
> +            - const: ctl2_crr
> +            - const: misc_crr
> +        power-domains:
> +          minItems: 2
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/imx8-clock.h>
> +    #include <dt-bindings/clock/imx8-lpcg.h>
> +    #include <dt-bindings/firmware/imx/rsrc.h>
> +    #include <dt-bindings/phy/phy-imx8-pcie.h>
> +
> +    serdes: phy@5f1a0000 {
> +            compatible = "fsl,imx8qxp-serdes";
> +            reg = <0x5f1a0000 0x10000>,
> +                  <0x5f120000 0x10000>,
> +                  <0x5f140000 0x10000>,
> +                  <0x5f160000 0x10000>;
> +            reg-names = "reg", "phy", "ctrl", "misc";
> +            clocks = <&phyx1_lpcg IMX_LPCG_CLK_0>,
> +                     <&phyx1_lpcg IMX_LPCG_CLK_4>,
> +                     <&phyx1_crr1_lpcg IMX_LPCG_CLK_4>,
> +                     <&pcieb_crr3_lpcg IMX_LPCG_CLK_4>,
> +                     <&misc_crr5_lpcg IMX_LPCG_CLK_4>;
> +            clock-names = "apb_pclk0", "pclk0", "phy0_crr", "ctl0_crr",
> +                          "misc_crr";
> +            power-domains = <&pd IMX_SC_R_SERDES_1>;
> +            #phy-cells = <3>;
> +            status = "disabled";
> +    };
> +...
> -- 
> 2.37.1
> 

^ permalink raw reply

* Re: [PATCH v1 2/3] dt-bindings: phy: phy-imx8-pcie: Add binding for i.MX8Q HSIO SerDes PHY
From: Frank Li @ 2024-03-29 14:21 UTC (permalink / raw)
  To: Richard Zhu
  Cc: vkoul, kishon, robh+dt, krzysztof.kozlowski+dt, conor+dt,
	linux-phy, devicetree, linux-arm-kernel, linux-kernel, kernel,
	linux-imx
In-Reply-To: <1711699790-16494-3-git-send-email-hongxing.zhu@nxp.com>

On Fri, Mar 29, 2024 at 04:09:49PM +0800, Richard Zhu wrote:
> Add binding for controller ID and HSIO configuration setting of the
> i.MX8Q HSIO SerDes PHY.
> 
> Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> ---
>  include/dt-bindings/phy/phy-imx8-pcie.h | 26 +++++++++++++++++++++++++
>  1 file changed, 26 insertions(+)

This one should be first patch. (1/3).

After fix small improve

Reviewed-by: Frank Li <Frank.Li@nxp.com>

> 
> diff --git a/include/dt-bindings/phy/phy-imx8-pcie.h b/include/dt-bindings/phy/phy-imx8-pcie.h
> index 8bbe2d6538d8..5cd5580879fa 100644
> --- a/include/dt-bindings/phy/phy-imx8-pcie.h
> +++ b/include/dt-bindings/phy/phy-imx8-pcie.h
> @@ -11,4 +11,30 @@
>  #define IMX8_PCIE_REFCLK_PAD_INPUT	1
>  #define IMX8_PCIE_REFCLK_PAD_OUTPUT	2
>  
> +/*
> + * i.MX8QM HSIO subsystem has three lane PHYs and three controllers:
> + * PCIEA(2 lanes capapble PCIe controller), PCIEB (only support one
> + * lane) and SATA.

Suggest add empty line between segment.

> + * In the different use cases. PCIEA can be binded to PHY lane0, lane1
> + * or Lane0 and lane1. PCIEB can be binded to lane1 or lane2 PHY. SATA
> + * can only be binded to last lane2 PHY.
> + * Define i.MX8Q HSIO controller ID here to specify the controller
> + * binded to the PHY.
> + * Meanwhile, i.MX8QXP HSIO subsystem has one lane PHY and PCIEB(only
> + * support one lane) controller.
> + */
> +#define IMX8Q_HSIO_PCIEA_ID	0
> +#define IMX8Q_HSIO_PCIEB_ID	1
> +#define IMX8Q_HSIO_SATA_ID	2
> +
> +/*
> + * On i.MX8QM, PCIEA is mandatory required if the HSIO is enabled.
> + * Define configurations beside PCIEA is enabled.
> + * On i.MX8QXP, HSIO module only has PCIEB and one lane PHY.
> + * The "IMX8Q_HSIO_CFG_PCIEB" can be used on i.MX8QXP platforms.
> + */
> +#define IMX8Q_HSIO_CFG_SATA		1
> +#define IMX8Q_HSIO_CFG_PCIEB		2
> +#define IMX8Q_HSIO_CFG_PCIEBSATA	3
> +
>  #endif /* _DT_BINDINGS_IMX8_PCIE_H */
> -- 
> 2.37.1
> 

^ permalink raw reply

* Re: [PATCH v1 3/3] phy: freescale: imx8q-hsio: Add i.MX8Q HSIO PHY driver support
From: Frank Li @ 2024-03-29 14:29 UTC (permalink / raw)
  To: Richard Zhu
  Cc: vkoul, kishon, robh+dt, krzysztof.kozlowski+dt, conor+dt,
	linux-phy, devicetree, linux-arm-kernel, linux-kernel, kernel,
	linux-imx
In-Reply-To: <1711699790-16494-4-git-send-email-hongxing.zhu@nxp.com>

On Fri, Mar 29, 2024 at 04:09:50PM +0800, Richard Zhu wrote:
> Add i.MX8Q HSIO PHY driver support.
> - Add one HSIO configuration property, that used to select the
> "PCIE_AB_SELECT" and "PHY_X1_EPCS_SEL" during the initialization.
> 
> Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> ---
>  drivers/phy/freescale/Kconfig              |   8 +
>  drivers/phy/freescale/Makefile             |   1 +
>  drivers/phy/freescale/phy-fsl-imx8q-hsio.c | 518 +++++++++++++++++++++
>  3 files changed, 527 insertions(+)
>  create mode 100644 drivers/phy/freescale/phy-fsl-imx8q-hsio.c
> 
> diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
> index 853958fb2c06..bcddddef1cbb 100644
> --- a/drivers/phy/freescale/Kconfig
> +++ b/drivers/phy/freescale/Kconfig
> @@ -35,6 +35,14 @@ config PHY_FSL_IMX8M_PCIE
>  	  Enable this to add support for the PCIE PHY as found on
>  	  i.MX8M family of SOCs.
>  
> +config PHY_FSL_IMX8Q_HSIO
> +	tristate "Freescale i.MX8Q HSIO PHY"
> +	depends on OF && HAS_IOMEM
> +	select GENERIC_PHY
> +	help
> +	  Enable this to add support for the HSIO PHY as found on
> +	  i.MX8Q family of SOCs.
> +
>  endif
>  
>  config PHY_FSL_LYNX_28G
> diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile
> index cedb328bc4d2..db888c37fcf9 100644
> --- a/drivers/phy/freescale/Makefile
> +++ b/drivers/phy/freescale/Makefile
> @@ -3,4 +3,5 @@ obj-$(CONFIG_PHY_FSL_IMX8MQ_USB)	+= phy-fsl-imx8mq-usb.o
>  obj-$(CONFIG_PHY_MIXEL_LVDS_PHY)	+= phy-fsl-imx8qm-lvds-phy.o
>  obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)	+= phy-fsl-imx8-mipi-dphy.o
>  obj-$(CONFIG_PHY_FSL_IMX8M_PCIE)	+= phy-fsl-imx8m-pcie.o
> +obj-$(CONFIG_PHY_FSL_IMX8Q_HSIO)	+= phy-fsl-imx8q-hsio.o
>  obj-$(CONFIG_PHY_FSL_LYNX_28G)		+= phy-fsl-lynx-28g.o
> diff --git a/drivers/phy/freescale/phy-fsl-imx8q-hsio.c b/drivers/phy/freescale/phy-fsl-imx8q-hsio.c
> new file mode 100644
> index 000000000000..14fc925c4f57
> --- /dev/null
> +++ b/drivers/phy/freescale/phy-fsl-imx8q-hsio.c
> @@ -0,0 +1,518 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2024 NXP
> + */
> +

#include <linux/bits.h> because you use BIT()

> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/pci_regs.h>
> +#include <linux/phy/phy.h>
> +#include <linux/phy/pcie.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +#include <dt-bindings/phy/phy-imx8-pcie.h>
> +
> +#define MAX_NUM_LANES	3
> +#define LANE_NUM_CLKS	5
> +
> +/* Parameters for the waiting for PCIe PHY PLL to lock */
> +#define PHY_INIT_WAIT_USLEEP_MAX	10
> +#define PHY_INIT_WAIT_TIMEOUT		(1000 * PHY_INIT_WAIT_USLEEP_MAX)
> +
> +/* i.MX8Q HSIO registers */
> +#define CTRL0			0x0
> +#define APB_RSTN_0		BIT(0)
> +#define APB_RSTN_1		BIT(1)
> +#define PIPE_RSTN_0_MASK	GENMASK(25, 24)
> +#define PIPE_RSTN_1_MASK	GENMASK(27, 26)
> +#define MODE_MASK		GENMASK(20, 17)
> +#define MODE_PCIE		0x0
> +#define MODE_SATA		0x4
> +#define DEVICE_TYPE_MASK	GENMASK(27, 24)
> +#define EPCS_TXDEEMP		BIT(5)
> +#define EPCS_TXDEEMP_SEL	BIT(6)
> +#define EPCS_PHYRESET_N		BIT(7)
> +#define RESET_N			BIT(12)
> +
> +#define IOB_RXENA		BIT(0)
> +#define IOB_TXENA		BIT(1)
> +#define IOB_A_0_TXOE		BIT(2)
> +#define IOB_A_0_M1M0_2		BIT(4)
> +#define IOB_A_0_M1M0_MASK	GENMASK(4, 3)
> +#define PHYX1_EPCS_SEL		BIT(12)
> +#define PCIE_AB_SELECT		BIT(13)
> +#define CLKREQN_OUT_OVERRIDE	GENMASK(25, 24)
> +
> +#define PHY_STTS0		0x4
> +#define LANE0_TX_PLL_LOCK	BIT(4)
> +#define LANE1_TX_PLL_LOCK	BIT(12)
> +
> +#define CTRL2			0x8
> +#define LTSSM_ENABLE		BIT(4)
> +#define BUTTON_RST_N		BIT(21)
> +#define PERST_N			BIT(22)
> +#define POWER_UP_RST_N		BIT(23)
> +
> +#define PCIE_STTS0		0xc
> +#define PM_REQ_CORE_RST		BIT(19)
> +
> +#define REG48_PMA_STATUS	0x30
> +#define REG48_PMA_RDY		BIT(7)
> +
> +struct imx8q_hsio_drvdata {
> +	int num_lane;
> +};
> +
> +struct imx8q_hsio_lane {
> +	const char * const *clk_names;
> +	struct clk_bulk_data clks[LANE_NUM_CLKS];
> +	u32 clks_cnt;
> +	u32 ctrl_id;
> +	u32 ctrl_off;
> +	u32 idx;
> +	u32 phy_off;
> +	struct imx8q_hsio_priv *priv;
> +	struct phy *phy;
> +	enum phy_mode lane_mode;
> +};
> +
> +struct imx8q_hsio_priv {
> +	void __iomem *base;
> +	struct device *dev;
> +	u32 refclk_pad_mode;
> +	u32 hsio_cfg;
> +	struct regmap *phy;
> +	struct regmap *ctrl;
> +	struct regmap *misc;
> +	const struct imx8q_hsio_drvdata *drvdata;
> +	struct imx8q_hsio_lane lane[MAX_NUM_LANES];
> +};
> +
> +static const char * const imx8q_hsio_lan0_pcie_clks[] = {"apb_pclk0", "pclk0",
> +	"ctl0_crr", "phy0_crr", "misc_crr"};
> +static const char * const imx8q_hsio_lan1_pciea_clks[] = {"apb_pclk1", "pclk1",
> +	"ctl0_crr", "phy0_crr", "misc_crr"};
> +static const char * const imx8q_hsio_lan1_pcieb_clks[] = {"apb_pclk1", "pclk1",
> +	"ctl1_crr", "phy0_crr", "misc_crr"};
> +static const char * const imx8q_hsio_lan2_pcieb_clks[] = {"apb_pclk2", "pclk2",
> +	"ctl1_crr", "phy1_crr", "misc_crr"};
> +static const char * const imx8q_hsio_lane_sata_clks[] = {"pclk2", "epcs_tx",
> +	"epcs_rx", "phy1_crr", "misc_crr"};
> +
> +static const struct regmap_config regmap_config = {
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 4,
> +};
> +
> +static int imx8q_hsio_init(struct phy *phy)
> +{
> +	int ret, i;
> +	struct imx8q_hsio_lane *lane = phy_get_drvdata(phy);
> +	struct imx8q_hsio_priv *priv = lane->priv;
> +	struct device *dev = priv->dev;
> +
> +	/* Assign clocks refer to different modes */
> +	switch (lane->ctrl_id) {
> +	case IMX8Q_HSIO_PCIEA_ID:
> +		if (lane->idx > 1) {
> +			dev_err(dev, "invalid lane ID.");
> +			return -EINVAL;
> +		}
> +
> +		lane->lane_mode = PHY_MODE_PCIE;
> +		lane->ctrl_off = 0;
> +		lane->phy_off = 0;
> +
> +		for (i = 0; i < LANE_NUM_CLKS; i++) {
> +			if (lane->idx)
> +				lane->clks[i].id = imx8q_hsio_lan1_pciea_clks[i];
> +			else
> +				lane->clks[i].id = imx8q_hsio_lan0_pcie_clks[i];
> +		}
> +		break;
> +	case IMX8Q_HSIO_PCIEB_ID:
> +		if (lane->idx > 2) {
> +			dev_err(dev, "invalid lane ID.");
> +			return -EINVAL;
> +		}
> +
> +		lane->lane_mode = PHY_MODE_PCIE;
> +		if (lane->idx == 0) {
> +			/* i.MX8QXP */
> +			lane->ctrl_off = 0;
> +			lane->phy_off = 0;
> +		} else {
> +			/*
> +			 * On i.MX8QM, only second or third lane PHY can
> +			 * be binded to PCIEB.
> +			 */
> +			lane->ctrl_off = SZ_64K;
> +			if (lane->idx == 1)
> +				lane->phy_off = 0;
> +			else /* idx == 2, the third lane is binded to PCIEB */
> +				lane->phy_off = SZ_64K;
> +		}
> +
> +		for (i = 0; i < LANE_NUM_CLKS; i++) {
> +			if (lane->idx == 1)
> +				lane->clks[i].id = imx8q_hsio_lan1_pcieb_clks[i];
> +			else if (lane->idx == 2)
> +				lane->clks[i].id = imx8q_hsio_lan2_pcieb_clks[i];
> +			else /* i.MX8QXP only has PCIEB, it's idx == 0 */
> +				lane->clks[i].id = imx8q_hsio_lan0_pcie_clks[i];
> +
> +		}
> +		break;
> +	case IMX8Q_HSIO_SATA_ID:
> +		/* On i.MX8QM, only the third lane PHY can be binded to SATA */
> +		if (lane->idx != 2) {
> +			dev_err(dev, "invalid lane ID.");
> +			return -EINVAL;
> +		}
> +		lane->ctrl_off = SZ_128K;
> +		lane->lane_mode = PHY_MODE_SATA;
> +		lane->phy_off = SZ_64K;
> +
> +		for (i = 0; i < LANE_NUM_CLKS; i++)
> +			lane->clks[i].id = imx8q_hsio_lane_sata_clks[i];
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	/* Fetch clocks */
> +	ret = devm_clk_bulk_get(dev, LANE_NUM_CLKS, lane->clks);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_bulk_prepare_enable(LANE_NUM_CLKS, lane->clks);
> +	if (ret)
> +		return ret;
> +
> +	/* allow the clocks to stabilize */
> +	usleep_range(200, 500);
> +	return 0;
> +}
> +
> +static int imx8q_hsio_exit(struct phy *phy)
> +{
> +	struct imx8q_hsio_lane *lane = phy_get_drvdata(phy);
> +
> +	clk_bulk_disable_unprepare(LANE_NUM_CLKS, lane->clks);
> +
> +	return 0;
> +}
> +
> +static void imx8q_hsio_pcie_phy_resets(struct phy *phy)
> +{
> +	struct imx8q_hsio_lane *lane = phy_get_drvdata(phy);
> +	struct imx8q_hsio_priv *priv = lane->priv;
> +
> +	regmap_clear_bits(priv->ctrl, lane->ctrl_off + CTRL2, BUTTON_RST_N);
> +	regmap_clear_bits(priv->ctrl, lane->ctrl_off + CTRL2, PERST_N);
> +	regmap_clear_bits(priv->ctrl, lane->ctrl_off + CTRL2, POWER_UP_RST_N);
> +	regmap_set_bits(priv->ctrl, lane->ctrl_off + CTRL2, BUTTON_RST_N);
> +	regmap_set_bits(priv->ctrl, lane->ctrl_off + CTRL2, PERST_N);
> +	regmap_set_bits(priv->ctrl, lane->ctrl_off + CTRL2, POWER_UP_RST_N);
> +
> +	if (lane->idx == 1) {
> +		/* The second lane */
> +		regmap_set_bits(priv->phy, lane->phy_off + CTRL0, APB_RSTN_1);
> +		regmap_set_bits(priv->phy, lane->phy_off + CTRL0, PIPE_RSTN_1_MASK);
> +	} else {
> +		regmap_set_bits(priv->phy, lane->phy_off + CTRL0, APB_RSTN_0);
> +		regmap_set_bits(priv->phy, lane->phy_off + CTRL0, PIPE_RSTN_0_MASK);
> +	}
> +}
> +
> +static void imx8q_hsio_sata_phy_resets(struct phy *phy)
> +{
> +	struct imx8q_hsio_lane *lane = phy_get_drvdata(phy);
> +	struct imx8q_hsio_priv *priv = lane->priv;
> +
> +	/* clear PHY RST, then set it */
> +	regmap_clear_bits(priv->ctrl, lane->ctrl_off + CTRL0, EPCS_PHYRESET_N);
> +
> +	regmap_set_bits(priv->ctrl, lane->ctrl_off + CTRL0, EPCS_PHYRESET_N);
> +
> +	/* CTRL RST: SET -> delay 1 us -> CLEAR -> SET */
> +	regmap_set_bits(priv->ctrl, lane->ctrl_off + CTRL0, RESET_N);
> +	udelay(1);
> +	regmap_clear_bits(priv->ctrl, lane->ctrl_off + CTRL0, RESET_N);
> +	regmap_set_bits(priv->ctrl, lane->ctrl_off + CTRL0, RESET_N);
> +}
> +
> +static void imx8q_hsio_configure_clk_pad(struct phy *phy)
> +{
> +	bool pll = false;
> +	u32 pad_mode;
> +	struct imx8q_hsio_lane *lane = phy_get_drvdata(phy);
> +	struct imx8q_hsio_priv *priv = lane->priv;
> +
> +	pad_mode = priv->refclk_pad_mode;
> +	if (pad_mode == IMX8_PCIE_REFCLK_PAD_OUTPUT) {
> +		pll = true;
> +		regmap_update_bits(priv->misc, CTRL0,
> +				   IOB_A_0_TXOE | IOB_A_0_M1M0_MASK,
> +				   IOB_A_0_TXOE | IOB_A_0_M1M0_2);
> +	}
> +
> +	regmap_update_bits(priv->misc, CTRL0, IOB_RXENA, pll ? 0 : IOB_RXENA);
> +	regmap_update_bits(priv->misc, CTRL0, IOB_TXENA, pll ? IOB_TXENA : 0);
> +}
> +
> +static int imx8q_hsio_power_on(struct phy *phy)
> +{
> +	int ret;
> +	u32 val, cond;
> +	struct imx8q_hsio_lane *lane = phy_get_drvdata(phy);
> +	struct imx8q_hsio_priv *priv = lane->priv;
> +
> +	if (lane->lane_mode == PHY_MODE_PCIE)
> +		imx8q_hsio_pcie_phy_resets(phy);
> +	else
> +		/* SATA */
> +		regmap_set_bits(priv->phy, lane->phy_off + CTRL0, APB_RSTN_0);
> +
> +	if (priv->hsio_cfg & IMX8Q_HSIO_CFG_PCIEB)
> +		regmap_set_bits(priv->misc, CTRL0, PCIE_AB_SELECT);
> +	if (priv->hsio_cfg & IMX8Q_HSIO_CFG_SATA)
> +		regmap_set_bits(priv->misc, CTRL0, PHYX1_EPCS_SEL);
> +
> +	imx8q_hsio_configure_clk_pad(phy);
> +
> +	if (lane->lane_mode == PHY_MODE_SATA) {
> +		/*
> +		 * It is possible, for PCIe and SATA are sharing
> +		 * the same clock source, HPLL or external oscillator.
> +		 * When PCIe is in low power modes (L1.X or L2 etc),
> +		 * the clock source can be turned off. In this case,
> +		 * if this clock source is required to be toggling by
> +		 * SATA, then SATA functions will be abnormal.
> +		 * Set the override here to avoid it.
> +		 */
> +		regmap_set_bits(priv->misc, CTRL0, CLKREQN_OUT_OVERRIDE);
> +		regmap_set_bits(priv->ctrl, lane->ctrl_off + CTRL0, EPCS_TXDEEMP);
> +		regmap_set_bits(priv->ctrl, lane->ctrl_off + CTRL0, EPCS_TXDEEMP_SEL);
> +
> +		imx8q_hsio_sata_phy_resets(phy);
> +	} else {
> +		/* Toggle apb_pclk to make sure clear the PM_REQ_CORE_RST bit */
> +		clk_disable_unprepare(lane->clks[0].clk);
> +		mdelay(1);
> +		ret = clk_prepare_enable(lane->clks[0].clk);
> +		if (ret) {
> +			dev_err(priv->dev, "unable to enable phy apb_pclk\n");
> +			return ret;
> +		}
> +
> +		/* Bit19 PM_REQ_CORE_RST of pcie_stts0 should be cleared. */
> +		ret = regmap_read_poll_timeout(priv->ctrl,
> +				lane->ctrl_off + PCIE_STTS0,
> +				val, (val & PM_REQ_CORE_RST) == 0,
> +				PHY_INIT_WAIT_USLEEP_MAX,
> +				PHY_INIT_WAIT_TIMEOUT);
> +		if (ret) {
> +			dev_err(priv->dev, "PM_REQ_CORE_RST is set\n");
> +			return ret;
> +		}
> +	}
> +
> +	/* Polling to check the PHY is ready or not. */
> +	if (lane->idx == 1)
> +		cond = LANE1_TX_PLL_LOCK;
> +	else
> +		cond = LANE0_TX_PLL_LOCK;

	cond = lane->idx ? LANE1_TX_PLL_LOCK : LANE0_TX_PLL_LOCK;

> +
> +	ret = regmap_read_poll_timeout(priv->phy, lane->phy_off + PHY_STTS0,
> +			val, ((val & cond) == cond),
> +			PHY_INIT_WAIT_USLEEP_MAX, PHY_INIT_WAIT_TIMEOUT);
> +	if (ret)
> +		dev_err(priv->dev, "IMX8Q PHY%d PLL lock timeout\n", lane->idx);
> +	else
> +		dev_info(priv->dev, "IMX8Q PHY%d PLL is locked\n", lane->idx);
> +
> +	if (lane->lane_mode == PHY_MODE_SATA) {
> +		cond = REG48_PMA_RDY;
> +		ret = read_poll_timeout(readb, val, ((val & cond) == cond),
> +				PHY_INIT_WAIT_USLEEP_MAX, PHY_INIT_WAIT_TIMEOUT,
> +				false, priv->base + REG48_PMA_STATUS);
> +		if (ret)
> +			dev_err(priv->dev, "PHY calibration is timeout\n");
> +		else
> +			dev_info(priv->dev, "PHY calibration is done\n");
> +	}
> +
> +	return ret;
> +}
> +
> +static int imx8q_hsio_set_mode(struct phy *phy, enum phy_mode mode,
> +				   int submode)
> +{
> +	u32 val;
> +	struct imx8q_hsio_lane *lane = phy_get_drvdata(phy);
> +	struct imx8q_hsio_priv *priv = lane->priv;
> +
> +	if (lane->lane_mode != mode)
> +		return -EINVAL;
> +
> +	val = (mode == PHY_MODE_PCIE) ? MODE_PCIE : MODE_SATA;
> +	val = FIELD_PREP(MODE_MASK, val);
> +	regmap_update_bits(priv->phy, lane->phy_off + CTRL0, MODE_MASK, val);
> +
> +	switch (submode) {
> +	case PHY_MODE_PCIE_RC:
> +		val = FIELD_PREP(DEVICE_TYPE_MASK, PCI_EXP_TYPE_ROOT_PORT);
> +		break;
> +	case PHY_MODE_PCIE_EP:
> +		val = FIELD_PREP(DEVICE_TYPE_MASK, PCI_EXP_TYPE_ENDPOINT);
> +		break;
> +	default: /* Support only PCIe EP and RC now. */
> +		return 0;
> +	}
> +	if (submode)
> +		regmap_update_bits(priv->ctrl, lane->ctrl_off + CTRL0,
> +				   DEVICE_TYPE_MASK, val);
> +
> +	return 0;
> +}
> +
> +static int imx8q_hsio_set_speed(struct phy *phy, int speed)
> +{
> +	struct imx8q_hsio_lane *lane = phy_get_drvdata(phy);
> +	struct imx8q_hsio_priv *priv = lane->priv;
> +
> +	regmap_update_bits(priv->ctrl, lane->ctrl_off + CTRL2, LTSSM_ENABLE,
> +			   speed ? LTSSM_ENABLE : 0);
> +	return 0;
> +}
> +
> +static const struct phy_ops imx8q_hsio_ops = {
> +	.init = imx8q_hsio_init,
> +	.exit = imx8q_hsio_exit,
> +	.power_on = imx8q_hsio_power_on,
> +	.set_mode = imx8q_hsio_set_mode,
> +	.set_speed = imx8q_hsio_set_speed,
> +	.owner = THIS_MODULE,
> +};
> +
> +static const struct imx8q_hsio_drvdata imx8qxp_serdes_drvdata = {
> +	.num_lane = 1,
> +};
> +
> +static const struct imx8q_hsio_drvdata imx8qm_serdes_drvdata = {
> +	.num_lane = 3,
> +};
> +
> +static const struct of_device_id imx8q_hsio_of_match[] = {
> +	{.compatible = "fsl,imx8qxp-serdes", .data = &imx8qxp_serdes_drvdata},
> +	{.compatible = "fsl,imx8qm-serdes", .data = &imx8qm_serdes_drvdata},
> +	{ },
> +};
> +
> +MODULE_DEVICE_TABLE(of, imx8q_hsio_of_match);
> +
> +static struct phy *imx8q_hsio_xlate(struct device *dev,
> +				    const struct of_phandle_args *args)
> +{
> +	struct imx8q_hsio_priv *priv = dev_get_drvdata(dev);
> +	int idx = args->args[0];
> +	int ctrl_id = args->args[1];
> +	int hsio_cfg = args->args[2];
> +
> +	if (idx >= priv->drvdata->num_lane)
> +		return ERR_PTR(-EINVAL);
> +	priv->lane[idx].idx = idx;
> +	priv->lane[idx].ctrl_id = ctrl_id;
> +	priv->hsio_cfg = hsio_cfg;
> +
> +	return priv->lane[idx].phy;
> +}
> +
> +static int imx8q_hsio_probe(struct platform_device *pdev)
> +{
> +	int i;
> +	void __iomem *off;
> +	struct device *dev = &pdev->dev;
> +	struct device_node *np = dev->of_node;
> +	const struct of_device_id *of_id;
> +	struct imx8q_hsio_priv *priv;
> +	struct phy_provider *provider;
> +
> +	of_id = of_match_device(imx8q_hsio_of_match, dev);
> +	if (!of_id)
> +		return -EINVAL;
> +
> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +	priv->dev = &pdev->dev;
> +	priv->drvdata = of_device_get_match_data(dev);
> +
> +	/* Get PHY refclk pad mode */
> +	of_property_read_u32(np, "fsl,refclk-pad-mode", &priv->refclk_pad_mode);
> +
> +	priv->base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(priv->base))
> +		return PTR_ERR(priv->base);
> +
> +	off = devm_platform_ioremap_resource_byname(pdev, "phy");
> +	priv->phy = devm_regmap_init_mmio(dev, off, &regmap_config);
> +	if (IS_ERR(priv->phy))
> +		return dev_err_probe(dev, PTR_ERR(priv->phy),
> +				     "unable to find phy csr registers\n");
> +
> +	off = devm_platform_ioremap_resource_byname(pdev, "ctrl");
> +	priv->ctrl = devm_regmap_init_mmio(dev, off, &regmap_config);
> +	if (IS_ERR(priv->ctrl))
> +		return dev_err_probe(dev, PTR_ERR(priv->ctrl),
> +				     "unable to find ctrl csr registers\n");
> +
> +	off = devm_platform_ioremap_resource_byname(pdev, "misc");
> +	priv->misc = devm_regmap_init_mmio(dev, off, &regmap_config);
> +	if (IS_ERR(priv->misc))
> +		return dev_err_probe(dev, PTR_ERR(priv->misc),
> +				     "unable to find misc csr registers\n");
> +
> +	for (i = 0; i < priv->drvdata->num_lane; i++) {
> +		struct imx8q_hsio_lane *lane = &priv->lane[i];
> +		struct phy *phy;
> +
> +		memset(lane, 0, sizeof(*lane));
> +
> +		phy = devm_phy_create(&pdev->dev, NULL, &imx8q_hsio_ops);
> +		if (IS_ERR(phy))
> +			return PTR_ERR(phy);
> +
> +		lane->priv = priv;
> +		lane->phy = phy;
> +		lane->idx = i;
> +		phy_set_drvdata(phy, lane);
> +	}
> +
> +	dev_set_drvdata(dev, priv);
> +	dev_set_drvdata(&pdev->dev, priv);
> +
> +	provider = devm_of_phy_provider_register(&pdev->dev, imx8q_hsio_xlate);
> +
> +	return PTR_ERR_OR_ZERO(provider);
> +}
> +
> +static struct platform_driver imx8q_hsio_driver = {
> +	.probe	= imx8q_hsio_probe,
> +	.driver = {
> +		.name	= "imx8q-hsio-phy",
> +		.of_match_table	= imx8q_hsio_of_match,
> +	}
> +};
> +module_platform_driver(imx8q_hsio_driver);
> +
> +MODULE_DESCRIPTION("FSL IMX8Q HSIO SERDES PHY driver");
> +MODULE_LICENSE("GPL");
> -- 
> 2.37.1
> 

^ permalink raw reply

* [PATCH v4 0/5] dmaengine: fsl-sdma: Some improvement for fsl-sdma
From: Frank Li @ 2024-03-29 14:34 UTC (permalink / raw)
  To: Vinod Koul, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, NXP Linux Team, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Joy Zou
  Cc: dmaengine, linux-arm-kernel, linux-kernel, devicetree, imx,
	Frank Li, Nicolin Chen, Shengjiu Wang, Daniel Baluta, Vipul Kumar,
	Srikanth Krishnakar, Robin Gong, Iuliana Prodan, Clark Wang

To: Vinod Koul <vkoul@kernel.org>
To: Shawn Guo <shawnguo@kernel.org>
To: Sascha Hauer <s.hauer@pengutronix.de>
To: Pengutronix Kernel Team <kernel@pengutronix.de>
To: Fabio Estevam <festevam@gmail.com>
To: NXP Linux Team <linux-imx@nxp.com>
To: Rob Herring <robh@kernel.org>
To: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
To: Conor Dooley <conor+dt@kernel.org>
To: Joy Zou <joy.zou@nxp.com>
Cc: dmaengine@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: devicetree@vger.kernel.org
Cc: imx@lists.linux.dev

Signed-off-by: Frank Li <Frank.Li@nxp.com>

Changes in v4:                                                             
- using shenjing MULT FIFO support patches, because more clear commit
message .         
- Link to v3: https://lore.kernel.org/r/20240318-sdma_upstream-v3-0-da37ddd44d49@nxp.com

Changes in v3:
- Fixed sdma firware version number (v3.6/v4.6).
- Update sdma binding doc and pass dt_binding_check
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j8  dt_binding_check DT_SCHEMA_FILES=fsl,imx-sdma.yaml
  LINT    Documentation/devicetree/bindings
  DTEX    Documentation/devicetree/bindings/dma/fsl,imx-sdma.example.dts
  CHKDT   Documentation/devicetree/bindings/processed-schema.json
  SCHEMA  Documentation/devicetree/bindings/processed-schema.json
  DTC_CHK Documentation/devicetree/bindings/dma/fsl,imx-sdma.example.dtb

- Link to v2: https://lore.kernel.org/r/20240307-sdma_upstream-v2-0-e97305a43cf5@nxp.com

Changes in v2:
- remove ccb_phy from struct sdma_engine
- add i2c test platform and sdma script version informaiton at commit
  message.
- Link to v1: https://lore.kernel.org/r/20240303-sdma_upstream-v1-0-869cd0165b09@nxp.com

---
Frank Li (1):
      dt-bindings: fsl-imx-sdma: Add I2C peripheral types ID

Nicolin Chen (1):
      dmaengine: imx-sdma: Support allocate memory from internal SRAM (iram)

Robin Gong (1):
      dmaengine: imx-sdma: Add i2c dma support

Shengjiu Wang (2):
      dmaengine: imx-sdma: Support 24bit/3bytes for sg mode
      dmaengine: imx-sdma: support dual fifo for DEV_TO_DEV

 .../devicetree/bindings/dma/fsl,imx-sdma.yaml      |  1 +
 drivers/dma/imx-sdma.c                             | 75 ++++++++++++++++++----
 include/linux/dma/imx-dma.h                        |  1 +
 3 files changed, 66 insertions(+), 11 deletions(-)
---
base-commit: af20f396b91f335f907422249285cc499fb4e0d8
change-id: 20240303-sdma_upstream-acebfa5b97f7

Best regards,
---
Frank Li <Frank.Li@nxp.com>


^ permalink raw reply

* [PATCH v4 1/5] dmaengine: imx-sdma: Support allocate memory from internal SRAM (iram)
From: Frank Li @ 2024-03-29 14:34 UTC (permalink / raw)
  To: Vinod Koul, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, NXP Linux Team, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Joy Zou
  Cc: dmaengine, linux-arm-kernel, linux-kernel, devicetree, imx,
	Frank Li, Nicolin Chen, Shengjiu Wang, Daniel Baluta
In-Reply-To: <20240329-sdma_upstream-v4-0-daeb3067dea7@nxp.com>

From: Nicolin Chen <b42378@freescale.com>

Allocate memory from SoC internal SRAM to reduce DDR access and keep DDR in
lower power state (such as self-referesh) longer.

Check iram_pool before sdma_init() so that ccb/context could be allocated
from iram because DDR maybe in self-referesh in lower power audio case
while sdma still running.

Reviewed-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Signed-off-by: Nicolin Chen <b42378@freescale.com>
Signed-off-by: Joy Zou <joy.zou@nxp.com>
Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 drivers/dma/imx-sdma.c | 46 ++++++++++++++++++++++++++++++++++++----------
 1 file changed, 36 insertions(+), 10 deletions(-)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 9b42f5e96b1e0..4f1a9d1b152d6 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -24,6 +24,7 @@
 #include <linux/semaphore.h>
 #include <linux/spinlock.h>
 #include <linux/device.h>
+#include <linux/genalloc.h>
 #include <linux/dma-mapping.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
@@ -531,6 +532,7 @@ struct sdma_engine {
 	/* clock ratio for AHB:SDMA core. 1:1 is 1, 2:1 is 0*/
 	bool				clk_ratio;
 	bool                            fw_loaded;
+	struct gen_pool			*iram_pool;
 };
 
 static int sdma_config_write(struct dma_chan *chan,
@@ -1358,8 +1360,14 @@ static int sdma_request_channel0(struct sdma_engine *sdma)
 {
 	int ret = -EBUSY;
 
-	sdma->bd0 = dma_alloc_coherent(sdma->dev, PAGE_SIZE, &sdma->bd0_phys,
-				       GFP_NOWAIT);
+	if (sdma->iram_pool)
+		sdma->bd0 = gen_pool_dma_alloc(sdma->iram_pool,
+					sizeof(struct sdma_buffer_descriptor),
+					&sdma->bd0_phys);
+	else
+		sdma->bd0 = dma_alloc_coherent(sdma->dev,
+					sizeof(struct sdma_buffer_descriptor),
+					&sdma->bd0_phys, GFP_NOWAIT);
 	if (!sdma->bd0) {
 		ret = -ENOMEM;
 		goto out;
@@ -1379,10 +1387,14 @@ static int sdma_request_channel0(struct sdma_engine *sdma)
 static int sdma_alloc_bd(struct sdma_desc *desc)
 {
 	u32 bd_size = desc->num_bd * sizeof(struct sdma_buffer_descriptor);
+	struct sdma_engine *sdma = desc->sdmac->sdma;
 	int ret = 0;
 
-	desc->bd = dma_alloc_coherent(desc->sdmac->sdma->dev, bd_size,
-				      &desc->bd_phys, GFP_NOWAIT);
+	if (sdma->iram_pool)
+		desc->bd = gen_pool_dma_alloc(sdma->iram_pool, bd_size, &desc->bd_phys);
+	else
+		desc->bd = dma_alloc_coherent(sdma->dev, bd_size, &desc->bd_phys, GFP_NOWAIT);
+
 	if (!desc->bd) {
 		ret = -ENOMEM;
 		goto out;
@@ -1394,9 +1406,12 @@ static int sdma_alloc_bd(struct sdma_desc *desc)
 static void sdma_free_bd(struct sdma_desc *desc)
 {
 	u32 bd_size = desc->num_bd * sizeof(struct sdma_buffer_descriptor);
+	struct sdma_engine *sdma = desc->sdmac->sdma;
 
-	dma_free_coherent(desc->sdmac->sdma->dev, bd_size, desc->bd,
-			  desc->bd_phys);
+	if (sdma->iram_pool)
+		gen_pool_free(sdma->iram_pool, (unsigned long)desc->bd, bd_size);
+	else
+		dma_free_coherent(desc->sdmac->sdma->dev, bd_size, desc->bd, desc->bd_phys);
 }
 
 static void sdma_desc_free(struct virt_dma_desc *vd)
@@ -2068,6 +2083,7 @@ static int sdma_init(struct sdma_engine *sdma)
 {
 	int i, ret;
 	dma_addr_t ccb_phys;
+	int ccbsize;
 
 	ret = clk_enable(sdma->clk_ipg);
 	if (ret)
@@ -2083,10 +2099,14 @@ static int sdma_init(struct sdma_engine *sdma)
 	/* Be sure SDMA has not started yet */
 	writel_relaxed(0, sdma->regs + SDMA_H_C0PTR);
 
-	sdma->channel_control = dma_alloc_coherent(sdma->dev,
-			MAX_DMA_CHANNELS * sizeof(struct sdma_channel_control) +
-			sizeof(struct sdma_context_data),
-			&ccb_phys, GFP_KERNEL);
+	ccbsize = MAX_DMA_CHANNELS * (sizeof(struct sdma_channel_control)
+		  + sizeof(struct sdma_context_data));
+
+	if (sdma->iram_pool)
+		sdma->channel_control = gen_pool_dma_alloc(sdma->iram_pool, ccbsize, &ccb_phys);
+	else
+		sdma->channel_control = dma_alloc_coherent(sdma->dev, ccbsize, &ccb_phys,
+							   GFP_KERNEL);
 
 	if (!sdma->channel_control) {
 		ret = -ENOMEM;
@@ -2272,6 +2292,12 @@ static int sdma_probe(struct platform_device *pdev)
 			vchan_init(&sdmac->vc, &sdma->dma_device);
 	}
 
+	if (np) {
+		sdma->iram_pool = of_gen_pool_get(np, "iram", 0);
+		if (sdma->iram_pool)
+			dev_info(&pdev->dev, "alloc bd from iram.\n");
+	}
+
 	ret = sdma_init(sdma);
 	if (ret)
 		goto err_init;

-- 
2.34.1


^ permalink raw reply related

* [PATCH v4 2/5] dmaengine: imx-sdma: Support 24bit/3bytes for sg mode
From: Frank Li @ 2024-03-29 14:34 UTC (permalink / raw)
  To: Vinod Koul, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, NXP Linux Team, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Joy Zou
  Cc: dmaengine, linux-arm-kernel, linux-kernel, devicetree, imx,
	Frank Li, Shengjiu Wang, Vipul Kumar, Srikanth Krishnakar,
	Robin Gong, Daniel Baluta
In-Reply-To: <20240329-sdma_upstream-v4-0-daeb3067dea7@nxp.com>

From: Shengjiu Wang <shengjiu.wang@nxp.com>

Update 3bytes buswidth that is supported by sdma.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Signed-off-by: Vipul Kumar <vipul_kumar@mentor.com>
Signed-off-by: Srikanth Krishnakar <Srikanth_Krishnakar@mentor.com>
Acked-by: Robin Gong <yibin.gong@nxp.com>
Reviewed-by: Joy Zou <joy.zou@nxp.com>
Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 drivers/dma/imx-sdma.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 4f1a9d1b152d6..6be4c1e441266 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -176,6 +176,7 @@
 
 #define SDMA_DMA_BUSWIDTHS	(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
 				 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
+				 BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
 				 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
 
 #define SDMA_DMA_DIRECTIONS	(BIT(DMA_DEV_TO_MEM) | \
@@ -1658,6 +1659,9 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
 			if (count & 3 || sg->dma_address & 3)
 				goto err_bd_out;
 			break;
+		case DMA_SLAVE_BUSWIDTH_3_BYTES:
+			bd->mode.command = 3;
+			break;
 		case DMA_SLAVE_BUSWIDTH_2_BYTES:
 			bd->mode.command = 2;
 			if (count & 1 || sg->dma_address & 1)

-- 
2.34.1


^ permalink raw reply related

* [PATCH v4 3/5] dmaengine: imx-sdma: support dual fifo for DEV_TO_DEV
From: Frank Li @ 2024-03-29 14:34 UTC (permalink / raw)
  To: Vinod Koul, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, NXP Linux Team, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Joy Zou
  Cc: dmaengine, linux-arm-kernel, linux-kernel, devicetree, imx,
	Frank Li, Shengjiu Wang, Iuliana Prodan
In-Reply-To: <20240329-sdma_upstream-v4-0-daeb3067dea7@nxp.com>

From: Shengjiu Wang <shengjiu.wang@nxp.com>

SSI and SPDIF are dual fifo interface, when support ASRC P2P
with SSI and SPDIF, the src fifo or dst fifo number can be
two.

The p2p watermark level bit 13 and 14 are designed for
these use case. This patch is to complete this function
in driver.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Signed-off-by: Joy Zou <joy.zou@nxp.com>
Acked-by: Iuliana Prodan <iuliana.prodan@nxp.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 drivers/dma/imx-sdma.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 6be4c1e441266..f68ab34a3c880 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -138,7 +138,11 @@
  *						0: Source on AIPS
  *	12		Destination Bit(DP)	1: Destination on SPBA
  *						0: Destination on AIPS
- *	13-15		---------		MUST BE 0
+ *	13		Source FIFO		1: Source is dual FIFO
+ *						0: Source is single FIFO
+ *	14		Destination FIFO	1: Destination is dual FIFO
+ *						0: Destination is single FIFO
+ *	15		---------		MUST BE 0
  *	16-23		Higher WML		HWML
  *	24-27		N			Total number of samples after
  *						which Pad adding/Swallowing
@@ -169,6 +173,8 @@
 #define SDMA_WATERMARK_LEVEL_SPDIF	BIT(10)
 #define SDMA_WATERMARK_LEVEL_SP		BIT(11)
 #define SDMA_WATERMARK_LEVEL_DP		BIT(12)
+#define SDMA_WATERMARK_LEVEL_SD		BIT(13)
+#define SDMA_WATERMARK_LEVEL_DD		BIT(14)
 #define SDMA_WATERMARK_LEVEL_HWML	(0xFF << 16)
 #define SDMA_WATERMARK_LEVEL_LWE	BIT(28)
 #define SDMA_WATERMARK_LEVEL_HWE	BIT(29)
@@ -1258,6 +1264,16 @@ static void sdma_set_watermarklevel_for_p2p(struct sdma_channel *sdmac)
 		sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_DP;
 
 	sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_CONT;
+
+	/*
+	 * Limitation: The p2p script support dual fifos in maximum,
+	 * So when fifo number is larger than 1, force enable dual
+	 * fifos.
+	 */
+	if (sdmac->n_fifos_src > 1)
+		sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_SD;
+	if (sdmac->n_fifos_dst > 1)
+		sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_DD;
 }
 
 static void sdma_set_watermarklevel_for_sais(struct sdma_channel *sdmac)

-- 
2.34.1


^ permalink raw reply related

* [PATCH v4 4/5] dt-bindings: fsl-imx-sdma: Add I2C peripheral types ID
From: Frank Li @ 2024-03-29 14:34 UTC (permalink / raw)
  To: Vinod Koul, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, NXP Linux Team, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Joy Zou
  Cc: dmaengine, linux-arm-kernel, linux-kernel, devicetree, imx,
	Frank Li
In-Reply-To: <20240329-sdma_upstream-v4-0-daeb3067dea7@nxp.com>

Add peripheral types ID 26 for I2C because sdma firmware (sdma-6q: v3.6,
sdma-7d: v4.6) support I2C DMA transfer.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml b/Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml
index b95dd8db5a30a..80bcd3a6ecaf3 100644
--- a/Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml
+++ b/Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml
@@ -93,6 +93,7 @@ properties:
           - Shared ASRC: 23
           - SAI: 24
           - HDMI Audio: 25
+          - I2C: 26
 
        The third cell: transfer priority ID
          enum:

-- 
2.34.1


^ permalink raw reply related

* [PATCH v4 5/5] dmaengine: imx-sdma: Add i2c dma support
From: Frank Li @ 2024-03-29 14:34 UTC (permalink / raw)
  To: Vinod Koul, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, NXP Linux Team, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Joy Zou
  Cc: dmaengine, linux-arm-kernel, linux-kernel, devicetree, imx,
	Frank Li, Robin Gong, Clark Wang, Daniel Baluta
In-Reply-To: <20240329-sdma_upstream-v4-0-daeb3067dea7@nxp.com>

From: Robin Gong <yibin.gong@nxp.com>

New sdma script (sdma-6q: v3.6, sdma-7d: v4.6) support i2c at imx8mp and
imx6ull. So add I2C dma support.

Signed-off-by: Robin Gong <yibin.gong@nxp.com>
Acked-by: Clark Wang <xiaoning.wang@nxp.com>
Reviewed-by: Joy Zou <joy.zou@nxp.com>
Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 drivers/dma/imx-sdma.c      | 7 +++++++
 include/linux/dma/imx-dma.h | 1 +
 2 files changed, 8 insertions(+)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index f68ab34a3c880..1ab8a7d3a50dc 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -251,6 +251,8 @@ struct sdma_script_start_addrs {
 	s32 sai_2_mcu_addr;
 	s32 uart_2_mcu_rom_addr;
 	s32 uartsh_2_mcu_rom_addr;
+	s32 i2c_2_mcu_addr;
+	s32 mcu_2_i2c_addr;
 	/* End of v3 array */
 	s32 mcu_2_zqspi_addr;
 	/* End of v4 array */
@@ -1081,6 +1083,11 @@ static int sdma_get_pc(struct sdma_channel *sdmac,
 		per_2_emi = sdma->script_addrs->sai_2_mcu_addr;
 		emi_2_per = sdma->script_addrs->mcu_2_sai_addr;
 		break;
+	case IMX_DMATYPE_I2C:
+		per_2_emi = sdma->script_addrs->i2c_2_mcu_addr;
+		emi_2_per = sdma->script_addrs->mcu_2_i2c_addr;
+		sdmac->is_ram_script = true;
+		break;
 	case IMX_DMATYPE_HDMI:
 		emi_2_per = sdma->script_addrs->hdmi_dma_addr;
 		sdmac->is_ram_script = true;
diff --git a/include/linux/dma/imx-dma.h b/include/linux/dma/imx-dma.h
index cfec5f946e237..76a8de9ae1517 100644
--- a/include/linux/dma/imx-dma.h
+++ b/include/linux/dma/imx-dma.h
@@ -41,6 +41,7 @@ enum sdma_peripheral_type {
 	IMX_DMATYPE_SAI,	/* SAI */
 	IMX_DMATYPE_MULTI_SAI,	/* MULTI FIFOs For Audio */
 	IMX_DMATYPE_HDMI,       /* HDMI Audio */
+	IMX_DMATYPE_I2C,	/* I2C */
 };
 
 enum imx_dma_prio {

-- 
2.34.1


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox