sunxi: backport basic Allwinner A523 support
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
@@ -1769,6 +1769,7 @@ CONFIG_DQL=y
|
||||
# CONFIG_DRM_TI_DLPC3433 is not set
|
||||
# CONFIG_DRM_TI_SN65DSI83 is not set
|
||||
# CONFIG_DRM_TI_SN65DSI86 is not set
|
||||
# CONFIG_DRM_TI_TDP158 is not set
|
||||
# CONFIG_DRM_TI_TFP410 is not set
|
||||
# CONFIG_DRM_TI_TPD12S015 is not set
|
||||
# CONFIG_DRM_TI_TDP158 is not set
|
||||
|
||||
@@ -64,6 +64,7 @@ CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC=y
|
||||
CONFIG_DMA_DIRECT_REMAP=y
|
||||
CONFIG_DMA_NEED_SYNC=y
|
||||
CONFIG_DWMAC_SUN8I=y
|
||||
CONFIG_DWMAC_SUN55I=y
|
||||
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
|
||||
CONFIG_FRAME_POINTER=y
|
||||
CONFIG_FUNCTION_ALIGNMENT=4
|
||||
@@ -107,6 +108,8 @@ CONFIG_PINCTRL_SUN50I_H6=y
|
||||
CONFIG_PINCTRL_SUN50I_H616=y
|
||||
CONFIG_PINCTRL_SUN50I_H616_R=y
|
||||
CONFIG_PINCTRL_SUN50I_H6_R=y
|
||||
CONFIG_PINCTRL_SUN55I_A523=y
|
||||
CONFIG_PINCTRL_SUN55I_A523_R=y
|
||||
CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
|
||||
CONFIG_QUEUED_RWLOCKS=y
|
||||
CONFIG_QUEUED_SPINLOCKS=y
|
||||
@@ -133,9 +136,10 @@ CONFIG_SUN50I_H616_CCU=y
|
||||
CONFIG_SUN50I_H6_CCU=y
|
||||
CONFIG_SUN50I_H6_R_CCU=y
|
||||
CONFIG_SUN50I_IOMMU=y
|
||||
# CONFIG_SUN55I_A523_CCU is not set
|
||||
# CONFIG_SUN55I_A523_MCU_CCU is not set
|
||||
# CONFIG_SUN55I_A523_R_CCU is not set
|
||||
CONFIG_SUN55I_A523_CCU=y
|
||||
CONFIG_SUN55I_A523_MCU_CCU=y
|
||||
CONFIG_SUN55I_A523_R_CCU=y
|
||||
CONFIG_SUN55I_PCK600=y
|
||||
CONFIG_SUN6I_RTC_CCU=y
|
||||
CONFIG_SUN6I_R_INTC=y
|
||||
CONFIG_SUNXI_NMI_INTC=y
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
From fb20ccf70cf695f178d7c32e2d33b376560df0ff Mon Sep 17 00:00:00 2001
|
||||
From: Chen-Yu Tsai <wens@kernel.org>
|
||||
Date: Tue, 17 Feb 2026 17:30:03 +0800
|
||||
Subject: [PATCH] clk: sunxi-ng: sun55i-a523-r: Add missing r-spi module clock
|
||||
|
||||
When the PRCM clk driver was added, somehow the r-spi module clock
|
||||
was skipped over.
|
||||
|
||||
Add it so that r-spi can actually work.
|
||||
|
||||
Fixes: 8cea339cfb81 ("clk: sunxi-ng: add support for the A523/T527 PRCM CCU")
|
||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
||||
Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
Link: https://patch.msgid.link/20260217093004.3239051-1-wens@kernel.org
|
||||
Signed-off-by: Chen-Yu Tsai <wens@kernel.org>
|
||||
---
|
||||
drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c | 17 ++++++++++++++++-
|
||||
1 file changed, 16 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c
|
||||
@@ -83,9 +83,22 @@ static SUNXI_CCU_MUX_DATA_WITH_GATE(r_pw
|
||||
static SUNXI_CCU_GATE_HW(bus_r_pwmctrl_clk, "bus-r-pwmctrl",
|
||||
&r_apb0_clk.common.hw, 0x13c, BIT(0), 0);
|
||||
|
||||
-/* SPI clock is /M/N (same as new MMC?) */
|
||||
+static const struct clk_parent_data r_spi_parents[] = {
|
||||
+ { .fw_name = "hosc" },
|
||||
+ { .fw_name = "pll-periph" },
|
||||
+ { .name = "pll-periph0-300M" },
|
||||
+ { .name = "pll-periph1-300M" },
|
||||
+ { .name = "pll-audio" },
|
||||
+};
|
||||
+static SUNXI_CCU_DUALDIV_MUX_GATE(r_spi_clk, "r-spi", r_spi_parents, 0x150,
|
||||
+ 0, 5, /* M */
|
||||
+ 8, 5, /* P */
|
||||
+ 24, 3, /* mux */
|
||||
+ BIT(31), /* gate */
|
||||
+ 0);
|
||||
static SUNXI_CCU_GATE_HW(bus_r_spi_clk, "bus-r-spi",
|
||||
&r_ahb_clk.common.hw, 0x15c, BIT(0), 0);
|
||||
+
|
||||
static SUNXI_CCU_GATE_HW(bus_r_spinlock_clk, "bus-r-spinlock",
|
||||
&r_ahb_clk.common.hw, 0x16c, BIT(0), 0);
|
||||
static SUNXI_CCU_GATE_HW(bus_r_msgbox_clk, "bus-r-msgbox",
|
||||
@@ -138,6 +151,7 @@ static struct ccu_common *sun55i_a523_r_
|
||||
&bus_r_twd_clk.common,
|
||||
&r_pwmctrl_clk.common,
|
||||
&bus_r_pwmctrl_clk.common,
|
||||
+ &r_spi_clk.common,
|
||||
&bus_r_spi_clk.common,
|
||||
&bus_r_spinlock_clk.common,
|
||||
&bus_r_msgbox_clk.common,
|
||||
@@ -169,6 +183,7 @@ static struct clk_hw_onecell_data sun55i
|
||||
[CLK_BUS_R_TWD] = &bus_r_twd_clk.common.hw,
|
||||
[CLK_R_PWMCTRL] = &r_pwmctrl_clk.common.hw,
|
||||
[CLK_BUS_R_PWMCTRL] = &bus_r_pwmctrl_clk.common.hw,
|
||||
+ [CLK_R_SPI] = &r_spi_clk.common.hw,
|
||||
[CLK_BUS_R_SPI] = &bus_r_spi_clk.common.hw,
|
||||
[CLK_BUS_R_SPINLOCK] = &bus_r_spinlock_clk.common.hw,
|
||||
[CLK_BUS_R_MSGBOX] = &bus_r_msgbox_clk.common.hw,
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
From 7a4c13c592225cd6728ec33056bb8252ddef1617 Mon Sep 17 00:00:00 2001
|
||||
From: Chen-Yu Tsai <wens@kernel.org>
|
||||
Date: Thu, 25 Dec 2025 16:02:40 +0800
|
||||
Subject: [PATCH] mfd: axp20x: AXP717: Add type-C CC registers
|
||||
|
||||
The AXP717 has some extra registers related to type-C CC pin
|
||||
negotiation. They were missing from the original submission.
|
||||
|
||||
Add them for completeness.
|
||||
|
||||
Signed-off-by: Chen-Yu Tsai <wens@kernel.org>
|
||||
Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
Link: https://patch.msgid.link/20251225080241.3153453-1-wens@kernel.org
|
||||
Signed-off-by: Lee Jones <lee@kernel.org>
|
||||
---
|
||||
drivers/mfd/axp20x.c | 5 ++++-
|
||||
include/linux/mfd/axp20x.h | 3 +++
|
||||
2 files changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mfd/axp20x.c
|
||||
+++ b/drivers/mfd/axp20x.c
|
||||
@@ -229,6 +229,8 @@ static const struct regmap_range axp717_
|
||||
regmap_reg_range(AXP717_DCDC_OUTPUT_CONTROL, AXP717_CPUSLDO_CONTROL),
|
||||
regmap_reg_range(AXP717_ADC_CH_EN_CONTROL, AXP717_ADC_CH_EN_CONTROL),
|
||||
regmap_reg_range(AXP717_ADC_DATA_SEL, AXP717_ADC_DATA_SEL),
|
||||
+ regmap_reg_range(AXP717_TYPEC_CC_AA_EN, AXP717_TYPEC_CC_AA_EN),
|
||||
+ regmap_reg_range(AXP717_TYPEC_CC_MODE_CONTROL, AXP717_TYPEC_CC_MODE_CONTROL),
|
||||
};
|
||||
|
||||
static const struct regmap_range axp717_volatile_ranges[] = {
|
||||
@@ -237,6 +239,7 @@ static const struct regmap_range axp717_
|
||||
regmap_reg_range(AXP717_BATT_PERCENT_DATA, AXP717_BATT_PERCENT_DATA),
|
||||
regmap_reg_range(AXP717_BATT_V_H, AXP717_BATT_CHRG_I_L),
|
||||
regmap_reg_range(AXP717_ADC_DATA_H, AXP717_ADC_DATA_L),
|
||||
+ regmap_reg_range(AXP717_TYPEC_CC_STATUS, AXP717_TYPEC_CC_STATUS),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table axp717_writeable_table = {
|
||||
@@ -458,7 +461,7 @@ static const struct regmap_config axp717
|
||||
.val_bits = 8,
|
||||
.wr_table = &axp717_writeable_table,
|
||||
.volatile_table = &axp717_volatile_table,
|
||||
- .max_register = AXP717_ADC_DATA_L,
|
||||
+ .max_register = AXP717_TYPEC_CC_STATUS,
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
};
|
||||
|
||||
--- a/include/linux/mfd/axp20x.h
|
||||
+++ b/include/linux/mfd/axp20x.h
|
||||
@@ -174,6 +174,9 @@ enum axp20x_variants {
|
||||
#define AXP717_ADC_DATA_SEL 0xcd
|
||||
#define AXP717_ADC_DATA_H 0xce
|
||||
#define AXP717_ADC_DATA_L 0xcf
|
||||
+#define AXP717_TYPEC_CC_AA_EN 0xe1
|
||||
+#define AXP717_TYPEC_CC_MODE_CONTROL 0xe3
|
||||
+#define AXP717_TYPEC_CC_STATUS 0xe7
|
||||
|
||||
#define AXP806_STARTUP_SRC 0x00
|
||||
#define AXP806_CHIP_ID 0x03
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
From c81f30bde5b0449d9d82d31a66f0ffd608e610b5 Mon Sep 17 00:00:00 2001
|
||||
From: Chen-Yu Tsai <wens@kernel.org>
|
||||
Date: Sun, 21 Dec 2025 19:05:09 +0800
|
||||
Subject: [PATCH] spi: sun6i: Support A523's SPI controllers
|
||||
|
||||
The A523 has four SPI controllers. One of them supports MIPI DBI mode
|
||||
in addition to standard SPI.
|
||||
|
||||
Compared to older generations, this newer controller now has a combined
|
||||
counter for the RX FIFO ad buffer levels. In older generations, the
|
||||
RX buffer level was a separate bitfield in the FIFO status register.
|
||||
|
||||
In practice this difference is negligible. The buffer is mostly
|
||||
invisible to the implementation. If programmed I/O transfers are limited
|
||||
to the FIFO size, then the contents of the buffer seem to always be
|
||||
flushed over to the FIFO. For DMA, the DRQ trigger levels are only tied
|
||||
to the FIFO levels. In all other aspects, the controller is the same as
|
||||
the one in the R329.
|
||||
|
||||
Support the standard SPI mode controllers using the settings for R329.
|
||||
DBI is left out as there currently is no infrastructure for enabling a
|
||||
DBI host controller, as was the case for the R329.
|
||||
|
||||
Also fold the entry for the R329 to make the style consistent.
|
||||
|
||||
Signed-off-by: Chen-Yu Tsai <wens@kernel.org>
|
||||
Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
Link: https://patch.msgid.link/20251221110513.1850535-3-wens@kernel.org
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
drivers/spi/spi-sun6i.c | 11 +++++++----
|
||||
1 file changed, 7 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/spi/spi-sun6i.c
|
||||
+++ b/drivers/spi/spi-sun6i.c
|
||||
@@ -795,10 +795,13 @@ static const struct sun6i_spi_cfg sun50i
|
||||
static const struct of_device_id sun6i_spi_match[] = {
|
||||
{ .compatible = "allwinner,sun6i-a31-spi", .data = &sun6i_a31_spi_cfg },
|
||||
{ .compatible = "allwinner,sun8i-h3-spi", .data = &sun8i_h3_spi_cfg },
|
||||
- {
|
||||
- .compatible = "allwinner,sun50i-r329-spi",
|
||||
- .data = &sun50i_r329_spi_cfg
|
||||
- },
|
||||
+ { .compatible = "allwinner,sun50i-r329-spi", .data = &sun50i_r329_spi_cfg },
|
||||
+ /*
|
||||
+ * A523's SPI controller has a combined RX buffer + FIFO counter
|
||||
+ * at offset 0x400, instead of split buffer count in FIFO status
|
||||
+ * register. But in practice we only care about the FIFO level.
|
||||
+ */
|
||||
+ { .compatible = "allwinner,sun55i-a523-spi", .data = &sun50i_r329_spi_cfg },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sun6i_spi_match);
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
From 4a5ac6cd05a7e54f1585d7779464d6ed6272c134 Mon Sep 17 00:00:00 2001
|
||||
From: Chen-Yu Tsai <wens@kernel.org>
|
||||
Date: Mon, 27 Oct 2025 20:56:45 +0800
|
||||
Subject: [PATCH] ASoC: sun4i-spdif: Support SPDIF output on A523 family
|
||||
|
||||
The TX side of the SPDIF block on the A523 is almost the same the
|
||||
previous generations, the only difference being that it has separate
|
||||
module clock inputs for the TX and RX side.
|
||||
|
||||
Since this driver currently only supports TX, add support for a
|
||||
different clock name so that TX and RX clocks can be separated
|
||||
if RX support is ever added. Then add support for the A523.
|
||||
|
||||
Signed-off-by: Chen-Yu Tsai <wens@kernel.org>
|
||||
Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
Link: https://patch.msgid.link/20251027125655.793277-5-wens@kernel.org
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
sound/soc/sunxi/sun4i-spdif.c | 26 ++++++++++++++++++++++++--
|
||||
1 file changed, 24 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/sound/soc/sunxi/sun4i-spdif.c
|
||||
+++ b/sound/soc/sunxi/sun4i-spdif.c
|
||||
@@ -177,6 +177,7 @@ struct sun4i_spdif_quirks {
|
||||
bool has_reset;
|
||||
unsigned int val_fctl_ftx;
|
||||
unsigned int mclk_multiplier;
|
||||
+ const char *tx_clk_name;
|
||||
};
|
||||
|
||||
struct sun4i_spdif_dev {
|
||||
@@ -572,6 +573,14 @@ static const struct sun4i_spdif_quirks s
|
||||
.mclk_multiplier = 1,
|
||||
};
|
||||
|
||||
+static const struct sun4i_spdif_quirks sun55i_a523_spdif_quirks = {
|
||||
+ .reg_dac_txdata = SUN8I_SPDIF_TXFIFO,
|
||||
+ .val_fctl_ftx = SUN50I_H6_SPDIF_FCTL_FTX,
|
||||
+ .has_reset = true,
|
||||
+ .mclk_multiplier = 1,
|
||||
+ .tx_clk_name = "tx",
|
||||
+};
|
||||
+
|
||||
static const struct of_device_id sun4i_spdif_of_match[] = {
|
||||
{
|
||||
.compatible = "allwinner,sun4i-a10-spdif",
|
||||
@@ -594,6 +603,15 @@ static const struct of_device_id sun4i_s
|
||||
/* Essentially the same as the H6, but without RX */
|
||||
.data = &sun50i_h6_spdif_quirks,
|
||||
},
|
||||
+ {
|
||||
+ .compatible = "allwinner,sun55i-a523-spdif",
|
||||
+ /*
|
||||
+ * Almost the same as H6, but has split the TX and RX clocks,
|
||||
+ * has a separate reset bit for the RX side, and has some
|
||||
+ * expanded features for the RX side.
|
||||
+ */
|
||||
+ .data = &sun55i_a523_spdif_quirks,
|
||||
+ },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sun4i_spdif_of_match);
|
||||
@@ -635,6 +653,7 @@ static int sun4i_spdif_probe(struct plat
|
||||
const struct sun4i_spdif_quirks *quirks;
|
||||
int ret;
|
||||
void __iomem *base;
|
||||
+ const char *tx_clk_name = "spdif";
|
||||
|
||||
dev_dbg(&pdev->dev, "Entered %s\n", __func__);
|
||||
|
||||
@@ -671,9 +690,12 @@ static int sun4i_spdif_probe(struct plat
|
||||
return PTR_ERR(host->apb_clk);
|
||||
}
|
||||
|
||||
- host->spdif_clk = devm_clk_get(&pdev->dev, "spdif");
|
||||
+ if (quirks->tx_clk_name)
|
||||
+ tx_clk_name = quirks->tx_clk_name;
|
||||
+ host->spdif_clk = devm_clk_get(&pdev->dev, tx_clk_name);
|
||||
if (IS_ERR(host->spdif_clk)) {
|
||||
- dev_err(&pdev->dev, "failed to get a spdif clock.\n");
|
||||
+ dev_err(&pdev->dev, "failed to get the \"%s\" clock.\n",
|
||||
+ tx_clk_name);
|
||||
return PTR_ERR(host->spdif_clk);
|
||||
}
|
||||
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
From 460a71b5642a60574809032f0a21afff0f942474 Mon Sep 17 00:00:00 2001
|
||||
From: Chen-Yu Tsai <wens@csie.org>
|
||||
Date: Tue, 23 Sep 2025 22:02:43 +0800
|
||||
Subject: [PATCH] arm64: dts: allwinner: a523: Add GMAC200 ethernet controller
|
||||
|
||||
The A523 SoC family has a second ethernet controller, called the
|
||||
GMAC200. It is not exposed on all the SoCs in the family.
|
||||
|
||||
Add a device node for it. All the hardware specific settings are from
|
||||
the vendor BSP.
|
||||
|
||||
Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
Link: https://patch.msgid.link/20250923140247.2622602-4-wens@kernel.org
|
||||
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
|
||||
---
|
||||
.../arm64/boot/dts/allwinner/sun55i-a523.dtsi | 55 +++++++++++++++++++
|
||||
1 file changed, 55 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
|
||||
@@ -182,6 +182,16 @@
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
+ rgmii1_pins: rgmii1-pins {
|
||||
+ pins = "PJ0", "PJ1", "PJ2", "PJ3", "PJ4",
|
||||
+ "PJ5", "PJ6", "PJ7", "PJ8", "PJ9",
|
||||
+ "PJ11", "PJ12", "PJ13", "PJ14", "PJ15";
|
||||
+ allwinner,pinmux = <5>;
|
||||
+ function = "gmac1";
|
||||
+ drive-strength = <40>;
|
||||
+ bias-disable;
|
||||
+ };
|
||||
+
|
||||
uart0_pb_pins: uart0-pb-pins {
|
||||
pins = "PB9", "PB10";
|
||||
allwinner,pinmux = <2>;
|
||||
@@ -603,6 +613,51 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ gmac1: ethernet@4510000 {
|
||||
+ compatible = "allwinner,sun55i-a523-gmac200",
|
||||
+ "snps,dwmac-4.20a";
|
||||
+ reg = <0x04510000 0x10000>;
|
||||
+ clocks = <&ccu CLK_BUS_EMAC1>, <&ccu CLK_MBUS_EMAC1>;
|
||||
+ clock-names = "stmmaceth", "mbus";
|
||||
+ resets = <&ccu RST_BUS_EMAC1>;
|
||||
+ reset-names = "stmmaceth";
|
||||
+ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ interrupt-names = "macirq";
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&rgmii1_pins>;
|
||||
+ power-domains = <&pck600 PD_VO1>;
|
||||
+ syscon = <&syscon>;
|
||||
+ snps,fixed-burst;
|
||||
+ snps,axi-config = <&gmac1_stmmac_axi_setup>;
|
||||
+ snps,mtl-rx-config = <&gmac1_mtl_rx_setup>;
|
||||
+ snps,mtl-tx-config = <&gmac1_mtl_tx_setup>;
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ mdio1: mdio {
|
||||
+ compatible = "snps,dwmac-mdio";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ gmac1_mtl_rx_setup: rx-queues-config {
|
||||
+ snps,rx-queues-to-use = <1>;
|
||||
+
|
||||
+ queue0 {};
|
||||
+ };
|
||||
+
|
||||
+ gmac1_stmmac_axi_setup: stmmac-axi-config {
|
||||
+ snps,wr_osr_lmt = <0xf>;
|
||||
+ snps,rd_osr_lmt = <0xf>;
|
||||
+ snps,blen = <256 128 64 32 16 8 4>;
|
||||
+ };
|
||||
+
|
||||
+ gmac1_mtl_tx_setup: tx-queues-config {
|
||||
+ snps,tx-queues-to-use = <1>;
|
||||
+
|
||||
+ queue0 {};
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
ppu: power-controller@7001400 {
|
||||
compatible = "allwinner,sun55i-a523-ppu";
|
||||
reg = <0x07001400 0x400>;
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
From 55d43ef77712e3b7fd4c3db5715be1f405afe31e Mon Sep 17 00:00:00 2001
|
||||
From: Chen-Yu Tsai <wens@kernel.org>
|
||||
Date: Mon, 27 Oct 2025 20:56:46 +0800
|
||||
Subject: [PATCH] arm64: dts: allwinner: a523: Add DMA controller device nodes
|
||||
|
||||
The A523 has two DMA controllers. Add device nodes for both. Also hook
|
||||
up DMA for existing devices.
|
||||
|
||||
Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
Link: https://patch.msgid.link/20251027125655.793277-6-wens@kernel.org
|
||||
Signed-off-by: Chen-Yu Tsai <wens@kernel.org>
|
||||
---
|
||||
.../arm64/boot/dts/allwinner/sun55i-a523.dtsi | 56 +++++++++++++++++++
|
||||
1 file changed, 56 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
|
||||
@@ -241,6 +241,8 @@
|
||||
reg-io-width = <4>;
|
||||
clocks = <&ccu CLK_BUS_UART0>;
|
||||
resets = <&ccu RST_BUS_UART0>;
|
||||
+ dmas = <&dma 14>, <&dma 14>;
|
||||
+ dma-names = "tx", "rx";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -252,6 +254,8 @@
|
||||
reg-io-width = <4>;
|
||||
clocks = <&ccu CLK_BUS_UART1>;
|
||||
resets = <&ccu RST_BUS_UART1>;
|
||||
+ dmas = <&dma 15>, <&dma 15>;
|
||||
+ dma-names = "tx", "rx";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -263,6 +267,8 @@
|
||||
reg-io-width = <4>;
|
||||
clocks = <&ccu CLK_BUS_UART2>;
|
||||
resets = <&ccu RST_BUS_UART2>;
|
||||
+ dmas = <&dma 16>, <&dma 16>;
|
||||
+ dma-names = "tx", "rx";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -274,6 +280,8 @@
|
||||
reg-io-width = <4>;
|
||||
clocks = <&ccu CLK_BUS_UART3>;
|
||||
resets = <&ccu RST_BUS_UART3>;
|
||||
+ dmas = <&dma 17>, <&dma 17>;
|
||||
+ dma-names = "tx", "rx";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -285,6 +293,8 @@
|
||||
reg-io-width = <4>;
|
||||
clocks = <&ccu CLK_BUS_UART4>;
|
||||
resets = <&ccu RST_BUS_UART4>;
|
||||
+ dmas = <&dma 18>, <&dma 18>;
|
||||
+ dma-names = "tx", "rx";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -296,6 +306,8 @@
|
||||
reg-io-width = <4>;
|
||||
clocks = <&ccu CLK_BUS_UART5>;
|
||||
resets = <&ccu RST_BUS_UART5>;
|
||||
+ dmas = <&dma 19>, <&dma 19>;
|
||||
+ dma-names = "tx", "rx";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -307,6 +319,8 @@
|
||||
reg-io-width = <4>;
|
||||
clocks = <&ccu CLK_BUS_UART6>;
|
||||
resets = <&ccu RST_BUS_UART6>;
|
||||
+ dmas = <&dma 20>, <&dma 20>;
|
||||
+ dma-names = "tx", "rx";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -318,6 +332,8 @@
|
||||
reg-io-width = <4>;
|
||||
clocks = <&ccu CLK_BUS_UART7>;
|
||||
resets = <&ccu RST_BUS_UART7>;
|
||||
+ dmas = <&dma 21>, <&dma 21>;
|
||||
+ dma-names = "tx", "rx";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -329,6 +345,8 @@
|
||||
interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu CLK_BUS_I2C0>;
|
||||
resets = <&ccu RST_BUS_I2C0>;
|
||||
+ dmas = <&dma 43>, <&dma 43>;
|
||||
+ dma-names = "rx", "tx";
|
||||
status = "disabled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
@@ -342,6 +360,8 @@
|
||||
interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu CLK_BUS_I2C1>;
|
||||
resets = <&ccu RST_BUS_I2C1>;
|
||||
+ dmas = <&dma 44>, <&dma 44>;
|
||||
+ dma-names = "rx", "tx";
|
||||
status = "disabled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
@@ -355,6 +375,8 @@
|
||||
interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu CLK_BUS_I2C2>;
|
||||
resets = <&ccu RST_BUS_I2C2>;
|
||||
+ dmas = <&dma 45>, <&dma 45>;
|
||||
+ dma-names = "rx", "tx";
|
||||
status = "disabled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
@@ -368,6 +390,8 @@
|
||||
interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu CLK_BUS_I2C3>;
|
||||
resets = <&ccu RST_BUS_I2C3>;
|
||||
+ dmas = <&dma 46>, <&dma 46>;
|
||||
+ dma-names = "rx", "tx";
|
||||
status = "disabled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
@@ -381,6 +405,8 @@
|
||||
interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu CLK_BUS_I2C4>;
|
||||
resets = <&ccu RST_BUS_I2C4>;
|
||||
+ dmas = <&dma 47>, <&dma 47>;
|
||||
+ dma-names = "rx", "tx";
|
||||
status = "disabled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
@@ -394,6 +420,8 @@
|
||||
interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu CLK_BUS_I2C5>;
|
||||
resets = <&ccu RST_BUS_I2C5>;
|
||||
+ dmas = <&dma 48>, <&dma 48>;
|
||||
+ dma-names = "rx", "tx";
|
||||
status = "disabled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
@@ -408,6 +436,19 @@
|
||||
ranges;
|
||||
};
|
||||
|
||||
+ dma: dma-controller@3002000 {
|
||||
+ compatible = "allwinner,sun55i-a523-dma",
|
||||
+ "allwinner,sun50i-a100-dma";
|
||||
+ reg = <0x03002000 0x1000>;
|
||||
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_DMA>, <&ccu CLK_MBUS_DMA>;
|
||||
+ clock-names = "bus", "mbus";
|
||||
+ dma-channels = <16>;
|
||||
+ dma-requests = <54>;
|
||||
+ resets = <&ccu RST_BUS_DMA>;
|
||||
+ #dma-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
sid: efuse@3006000 {
|
||||
compatible = "allwinner,sun55i-a523-sid",
|
||||
"allwinner,sun50i-a64-sid";
|
||||
@@ -729,6 +770,8 @@
|
||||
reg = <0x07081400 0x400>;
|
||||
interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&r_ccu CLK_BUS_R_I2C0>;
|
||||
+ dmas = <&dma 49>, <&dma 49>;
|
||||
+ dma-names = "rx", "tx";
|
||||
resets = <&r_ccu RST_BUS_R_I2C0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&r_i2c_pins>;
|
||||
@@ -775,6 +818,19 @@
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
+ mcu_dma: dma-controller@7121000 {
|
||||
+ compatible = "allwinner,sun55i-a523-mcu-dma",
|
||||
+ "allwinner,sun50i-a100-dma";
|
||||
+ reg = <0x07121000 0x1000>;
|
||||
+ interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&mcu_ccu CLK_BUS_MCU_DMA>, <&mcu_ccu CLK_MCU_MBUS_DMA>;
|
||||
+ clock-names = "bus", "mbus";
|
||||
+ dma-channels = <16>;
|
||||
+ dma-requests = <15>;
|
||||
+ resets = <&mcu_ccu RST_BUS_MCU_DMA>;
|
||||
+ #dma-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
npu: npu@7122000 {
|
||||
compatible = "vivante,gc";
|
||||
reg = <0x07122000 0x1000>;
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
From e51b773798ea1dece229b44854256ec38d35cc41 Mon Sep 17 00:00:00 2001
|
||||
From: Chen-Yu Tsai <wens@kernel.org>
|
||||
Date: Mon, 27 Oct 2025 20:56:47 +0800
|
||||
Subject: [PATCH] arm64: dts: allwinner: a523: Add device node for SPDIF block
|
||||
|
||||
The A523 has a SPDIF interface that is capable of both playback and
|
||||
capture.
|
||||
|
||||
Add a node for it.
|
||||
|
||||
Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
Link: https://patch.msgid.link/20251027125655.793277-7-wens@kernel.org
|
||||
Signed-off-by: Chen-Yu Tsai <wens@kernel.org>
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi | 15 +++++++++++++++
|
||||
1 file changed, 15 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
|
||||
@@ -818,6 +818,21 @@
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
+ spdif: spdif@7116000 {
|
||||
+ compatible = "allwinner,sun55i-a523-spdif";
|
||||
+ reg = <0x07116000 0x400>;
|
||||
+ interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&mcu_ccu CLK_BUS_MCU_SPDIF>,
|
||||
+ <&mcu_ccu CLK_MCU_SPDIF_TX>,
|
||||
+ <&mcu_ccu CLK_MCU_SPDIF_RX>;
|
||||
+ clock-names = "apb", "tx", "rx";
|
||||
+ resets = <&mcu_ccu RST_BUS_MCU_SPDIF>;
|
||||
+ dmas = <&mcu_dma 2>, <&mcu_dma 2>;
|
||||
+ dma-names = "rx", "tx";
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
mcu_dma: dma-controller@7121000 {
|
||||
compatible = "allwinner,sun55i-a523-mcu-dma",
|
||||
"allwinner,sun50i-a100-dma";
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
From 1fe1e9b67166e304e8c3e46bdd1104519d6d1bd7 Mon Sep 17 00:00:00 2001
|
||||
From: Chen-Yu Tsai <wens@kernel.org>
|
||||
Date: Mon, 27 Oct 2025 20:56:48 +0800
|
||||
Subject: [PATCH] arm64: dts: allwinner: a523: Add device nodes for I2S
|
||||
controllers
|
||||
|
||||
The A523 family of SoCs have four I2S controllers capable of both
|
||||
playback and capture. The user manual also implies that I2S2 also
|
||||
outputs to the eDP interface controller.
|
||||
|
||||
Add device nodes for all of them.
|
||||
|
||||
Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
Link: https://patch.msgid.link/20251027125655.793277-8-wens@kernel.org
|
||||
Signed-off-by: Chen-Yu Tsai <wens@kernel.org>
|
||||
---
|
||||
.../arm64/boot/dts/allwinner/sun55i-a523.dtsi | 56 +++++++++++++++++++
|
||||
1 file changed, 56 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
|
||||
@@ -818,6 +818,62 @@
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
+ i2s0: i2s@7112000 {
|
||||
+ compatible = "allwinner,sun55i-a523-i2s",
|
||||
+ "allwinner,sun50i-r329-i2s";
|
||||
+ reg = <0x07112000 0x1000>;
|
||||
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&mcu_ccu CLK_BUS_MCU_I2S0>, <&mcu_ccu CLK_MCU_I2S0>;
|
||||
+ clock-names = "apb", "mod";
|
||||
+ resets = <&mcu_ccu RST_BUS_MCU_I2S0>;
|
||||
+ dmas = <&mcu_dma 3>, <&mcu_dma 3>;
|
||||
+ dma-names = "rx", "tx";
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ i2s1: i2s@7113000 {
|
||||
+ compatible = "allwinner,sun55i-a523-i2s",
|
||||
+ "allwinner,sun50i-r329-i2s";
|
||||
+ reg = <0x07113000 0x1000>;
|
||||
+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&mcu_ccu CLK_BUS_MCU_I2S1>, <&mcu_ccu CLK_MCU_I2S1>;
|
||||
+ clock-names = "apb", "mod";
|
||||
+ resets = <&mcu_ccu RST_BUS_MCU_I2S1>;
|
||||
+ dmas = <&mcu_dma 4>, <&mcu_dma 4>;
|
||||
+ dma-names = "rx", "tx";
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ i2s2: i2s@7114000 {
|
||||
+ compatible = "allwinner,sun55i-a523-i2s",
|
||||
+ "allwinner,sun50i-r329-i2s";
|
||||
+ reg = <0x07114000 0x1000>;
|
||||
+ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&mcu_ccu CLK_BUS_MCU_I2S2>, <&mcu_ccu CLK_MCU_I2S2>;
|
||||
+ clock-names = "apb", "mod";
|
||||
+ resets = <&mcu_ccu RST_BUS_MCU_I2S2>;
|
||||
+ dmas = <&mcu_dma 5>, <&mcu_dma 5>;
|
||||
+ dma-names = "rx", "tx";
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ i2s3: i2s@7115000 {
|
||||
+ compatible = "allwinner,sun55i-a523-i2s",
|
||||
+ "allwinner,sun50i-r329-i2s";
|
||||
+ reg = <0x07115000 0x1000>;
|
||||
+ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&mcu_ccu CLK_BUS_MCU_I2S3>, <&mcu_ccu CLK_MCU_I2S3>;
|
||||
+ clock-names = "apb", "mod";
|
||||
+ resets = <&mcu_ccu RST_BUS_MCU_I2S3>;
|
||||
+ dmas = <&mcu_dma 6>, <&mcu_dma 6>;
|
||||
+ dma-names = "rx", "tx";
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
spdif: spdif@7116000 {
|
||||
compatible = "allwinner,sun55i-a523-spdif";
|
||||
reg = <0x07116000 0x400>;
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
From a9050236f81c43fc2eaa2e13098c7fb53c3aba34 Mon Sep 17 00:00:00 2001
|
||||
From: Chen-Yu Tsai <wens@kernel.org>
|
||||
Date: Mon, 27 Oct 2025 20:56:49 +0800
|
||||
Subject: [PATCH] arm64: dts: allwinner: a523: Add I2S2 pins on PI pin group
|
||||
|
||||
The Radxa Cubie A5E exposes I2S2 through the PI pin group on the 40-pin
|
||||
GPIO header.
|
||||
|
||||
Add a pinmux setting for it so potential users can directly reference
|
||||
it.
|
||||
|
||||
Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
Link: https://patch.msgid.link/20251027125655.793277-9-wens@kernel.org
|
||||
Signed-off-by: Chen-Yu Tsai <wens@kernel.org>
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
|
||||
@@ -145,6 +145,14 @@
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <3>;
|
||||
|
||||
+ /omit-if-no-ref/
|
||||
+ i2s2_pi_pins: i2s2-pi-pins {
|
||||
+ pins = "PI2", "PI3", "PI4", "PI5";
|
||||
+ allwinner,pinmux = <5>;
|
||||
+ function = "i2s2";
|
||||
+ bias-disable;
|
||||
+ };
|
||||
+
|
||||
mmc0_pins: mmc0-pins {
|
||||
pins = "PF0" ,"PF1", "PF2", "PF3", "PF4", "PF5";
|
||||
allwinner,pinmux = <2>;
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
From ae0d3f1e6dd2c6404db2fbd7556b93eddd6c87b8 Mon Sep 17 00:00:00 2001
|
||||
From: Chen-Yu Tsai <wens@kernel.org>
|
||||
Date: Mon, 27 Oct 2025 20:56:50 +0800
|
||||
Subject: [PATCH] arm64: dts: allwinner: a523: Add SPDIF TX pin on PB and PI
|
||||
pins
|
||||
|
||||
The SPDIF TX (called OWA OUT in the datasheet) is available on three
|
||||
pins. Of those, the PH pin is unlikely to be used since it conflicts
|
||||
with the first Ethernet controller.
|
||||
|
||||
The Radxa Cubie A5E exposes SPDIF TX through the PI pin group on the
|
||||
40-pin GPIO header.
|
||||
|
||||
The Orange Pi 4A exposes SPDIF TX through both the PB and PI pin
|
||||
groups on the 40-pin GPIO header. The PB pin alternatively would be
|
||||
used for I2S0 though.
|
||||
|
||||
Add pinmux settings for both options so potential users can directly
|
||||
reference either one.
|
||||
|
||||
Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
Link: https://patch.msgid.link/20251027125655.793277-10-wens@kernel.org
|
||||
Signed-off-by: Chen-Yu Tsai <wens@kernel.org>
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
|
||||
@@ -200,6 +200,20 @@
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
+ /omit-if-no-ref/
|
||||
+ spdif_out_pb_pin: spdif-pb-pin {
|
||||
+ pins = "PB8";
|
||||
+ function = "spdif";
|
||||
+ allwinner,pinmux = <2>;
|
||||
+ };
|
||||
+
|
||||
+ /omit-if-no-ref/
|
||||
+ spdif_out_pi_pin: spdif-pi-pin {
|
||||
+ pins = "PI10";
|
||||
+ function = "spdif";
|
||||
+ allwinner,pinmux = <2>;
|
||||
+ };
|
||||
+
|
||||
uart0_pb_pins: uart0-pb-pins {
|
||||
pins = "PB9", "PB10";
|
||||
allwinner,pinmux = <2>;
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
From 1bec3bd1f839f269dfdec3c635dd2afe15e30995 Mon Sep 17 00:00:00 2001
|
||||
From: Chen-Yu Tsai <wens@kernel.org>
|
||||
Date: Sun, 21 Dec 2025 19:05:10 +0800
|
||||
Subject: [PATCH] arm64: dts: allwinner: sun55i: Add SPI controllers
|
||||
|
||||
The A523 family SoCs have four SPI controllers. One of them also
|
||||
supports DBI mode.
|
||||
|
||||
Add device nodes for all of them. Also add pinmux nodes for spi0 on the
|
||||
PC pins, which is commonly used for SPI-NOR boot flash.
|
||||
|
||||
Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
Link: https://patch.msgid.link/20251221110513.1850535-4-wens@kernel.org
|
||||
Signed-off-by: Chen-Yu Tsai <wens@kernel.org>
|
||||
---
|
||||
.../arm64/boot/dts/allwinner/sun55i-a523.dtsi | 94 +++++++++++++++++++
|
||||
1 file changed, 94 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
|
||||
@@ -214,6 +214,43 @@
|
||||
allwinner,pinmux = <2>;
|
||||
};
|
||||
|
||||
+ /omit-if-no-ref/
|
||||
+ spi0_pc_pins: spi0-pc-pins {
|
||||
+ pins = "PC2", "PC4", "PC12";
|
||||
+ function = "spi0";
|
||||
+ allwinner,pinmux = <4>;
|
||||
+ };
|
||||
+
|
||||
+ /omit-if-no-ref/
|
||||
+ spi0_cs0_pc_pin: spi0-cs0-pc-pin {
|
||||
+ pins = "PC3";
|
||||
+ function = "spi0";
|
||||
+ allwinner,pinmux = <4>;
|
||||
+ };
|
||||
+
|
||||
+ /omit-if-no-ref/
|
||||
+ spi0_cs1_pc_pin: spi0-cs1-pc-pin {
|
||||
+ pins = "PC7";
|
||||
+ function = "spi0";
|
||||
+ allwinner,pinmux = <4>;
|
||||
+ };
|
||||
+
|
||||
+ /omit-if-no-ref/
|
||||
+ spi0_hold_pc_pin: spi0-hold-pc-pin {
|
||||
+ /* conflicts with eMMC D7 */
|
||||
+ pins = "PC16";
|
||||
+ function = "spi0";
|
||||
+ allwinner,pinmux = <4>;
|
||||
+ };
|
||||
+
|
||||
+ /omit-if-no-ref/
|
||||
+ spi0_wp_pc_pin: spi0-wp-pc-pin {
|
||||
+ /* conflicts with eMMC D2 */
|
||||
+ pins = "PC15";
|
||||
+ function = "spi0";
|
||||
+ allwinner,pinmux = <4>;
|
||||
+ };
|
||||
+
|
||||
uart0_pb_pins: uart0-pb-pins {
|
||||
pins = "PB9", "PB10";
|
||||
allwinner,pinmux = <2>;
|
||||
@@ -563,6 +600,49 @@
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
+ spi0: spi@4025000 {
|
||||
+ compatible = "allwinner,sun55i-a523-spi";
|
||||
+ reg = <0x04025000 0x1000>;
|
||||
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>;
|
||||
+ clock-names = "ahb", "mod";
|
||||
+ dmas = <&dma 22>, <&dma 22>;
|
||||
+ dma-names = "rx", "tx";
|
||||
+ resets = <&ccu RST_BUS_SPI0>;
|
||||
+ status = "disabled";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ spi1: spi@4026000 {
|
||||
+ compatible = "allwinner,sun55i-a523-spi-dbi",
|
||||
+ "allwinner,sun55i-a523-spi";
|
||||
+ reg = <0x04026000 0x1000>;
|
||||
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_SPI1>, <&ccu CLK_SPI1>;
|
||||
+ clock-names = "ahb", "mod";
|
||||
+ dmas = <&dma 23>, <&dma 23>;
|
||||
+ dma-names = "rx", "tx";
|
||||
+ resets = <&ccu RST_BUS_SPI1>;
|
||||
+ status = "disabled";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ spi2: spi@4027000 {
|
||||
+ compatible = "allwinner,sun55i-a523-spi";
|
||||
+ reg = <0x04027000 0x1000>;
|
||||
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_SPI2>, <&ccu CLK_SPI2>;
|
||||
+ clock-names = "ahb", "mod";
|
||||
+ dmas = <&dma 24>, <&dma 24>;
|
||||
+ dma-names = "rx", "tx";
|
||||
+ resets = <&ccu RST_BUS_SPI2>;
|
||||
+ status = "disabled";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
usb_otg: usb@4100000 {
|
||||
compatible = "allwinner,sun55i-a523-musb",
|
||||
"allwinner,sun8i-a33-musb";
|
||||
@@ -815,6 +895,20 @@
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
+ r_spi0: spi@7092000 {
|
||||
+ compatible = "allwinner,sun55i-a523-spi";
|
||||
+ reg = <0x07092000 0x1000>;
|
||||
+ interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&r_ccu CLK_BUS_R_SPI>, <&r_ccu CLK_R_SPI>;
|
||||
+ clock-names = "ahb", "mod";
|
||||
+ dmas = <&dma 53>, <&dma 53>;
|
||||
+ dma-names = "rx", "tx";
|
||||
+ resets = <&r_ccu RST_BUS_R_SPI>;
|
||||
+ status = "disabled";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
mcu_ccu: clock-controller@7102000 {
|
||||
compatible = "allwinner,sun55i-a523-mcu-ccu";
|
||||
reg = <0x7102000 0x200>;
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
From 7076938d20d22d5f75641f417f11edeee192e3cf Mon Sep 17 00:00:00 2001
|
||||
From: Chen-Yu Tsai <wens@csie.org>
|
||||
Date: Tue, 23 Sep 2025 22:02:44 +0800
|
||||
Subject: [PATCH] arm64: dts: allwinner: a527: cubie-a5e: Enable second
|
||||
Ethernet port
|
||||
|
||||
On the Radxa Cubie A5E board, the second Ethernet controller, aka the
|
||||
GMAC200, is connected to a second external Maxio MAE0621A PHY. The PHY
|
||||
uses an external 25MHz crystal, and has the SoC's PJ16 pin connected to
|
||||
its reset pin.
|
||||
|
||||
Enable the second Ethernet port. Also fix up the label for the existing
|
||||
external PHY connected to the first Ethernet port. An enable delay for the
|
||||
PHY supply regulator is added to make sure the PHY's internal regulators
|
||||
are fully powered and the PHY is operational.
|
||||
|
||||
Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Link: https://patch.msgid.link/20250923140247.2622602-5-wens@kernel.org
|
||||
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
|
||||
---
|
||||
.../dts/allwinner/sun55i-a527-cubie-a5e.dts | 28 +++++++++++++++++--
|
||||
1 file changed, 26 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
aliases {
|
||||
ethernet0 = &gmac0;
|
||||
+ ethernet1 = &gmac1;
|
||||
serial0 = &uart0;
|
||||
};
|
||||
|
||||
@@ -75,7 +76,7 @@
|
||||
|
||||
&gmac0 {
|
||||
phy-mode = "rgmii-id";
|
||||
- phy-handle = <&ext_rgmii_phy>;
|
||||
+ phy-handle = <&ext_rgmii0_phy>;
|
||||
phy-supply = <®_cldo3>;
|
||||
|
||||
allwinner,tx-delay-ps = <300>;
|
||||
@@ -84,13 +85,24 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&gmac1 {
|
||||
+ phy-mode = "rgmii-id";
|
||||
+ phy-handle = <&ext_rgmii1_phy>;
|
||||
+ phy-supply = <®_cldo4>;
|
||||
+
|
||||
+ tx-internal-delay-ps = <300>;
|
||||
+ rx-internal-delay-ps = <400>;
|
||||
+
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&gpu {
|
||||
mali-supply = <®_dcdc2>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&mdio0 {
|
||||
- ext_rgmii_phy: ethernet-phy@1 {
|
||||
+ ext_rgmii0_phy: ethernet-phy@1 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <1>;
|
||||
reset-gpios = <&pio 7 8 GPIO_ACTIVE_LOW>; /* PH8 */
|
||||
@@ -99,6 +111,16 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&mdio1 {
|
||||
+ ext_rgmii1_phy: ethernet-phy@1 {
|
||||
+ compatible = "ethernet-phy-ieee802.3-c22";
|
||||
+ reg = <1>;
|
||||
+ reset-gpios = <&pio 9 16 GPIO_ACTIVE_LOW>; /* PJ16 */
|
||||
+ reset-assert-us = <10000>;
|
||||
+ reset-deassert-us = <150000>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
&mmc0 {
|
||||
vmmc-supply = <®_cldo3>;
|
||||
cd-gpios = <&pio 5 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; /* PF6 */
|
||||
@@ -250,6 +272,8 @@
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-name = "vcc-pj-phy";
|
||||
+ /* enough time for the PHY to fully power on */
|
||||
+ regulator-enable-ramp-delay = <150000>;
|
||||
};
|
||||
|
||||
reg_cpusldo: cpusldo {
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi-dt.c
|
||||
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi-dt.c
|
||||
@@ -81,6 +81,12 @@ static struct sunxi_desc_pin *init_pins_
|
||||
int i, j;
|
||||
|
||||
/*
|
||||
+ * Ensure desc->npins is zeroed before accumulation to avoid
|
||||
+ * double-counting when the same desc is reused on a re-probe.
|
||||
+ */
|
||||
+ desc->npins = 0;
|
||||
+
|
||||
+ /*
|
||||
* Find the total number of pins.
|
||||
* Also work out how much memory we need to store all the pin names.
|
||||
*/
|
||||
@@ -0,0 +1,439 @@
|
||||
|
||||
From: iuncuim <iuncuim@gmail.com>
|
||||
Signed-off-by: Mikhail Kalashnikov <iuncuim@gmail.com>
|
||||
|
||||
|
||||
--- a/drivers/clk/sunxi-ng/Makefile
|
||||
+++ b/drivers/clk/sunxi-ng/Makefile
|
||||
@@ -34,6 +34,7 @@ obj-$(CONFIG_SUN50I_H6_CCU) += sun50i-h6
|
||||
obj-$(CONFIG_SUN50I_H6_R_CCU) += sun50i-h6-r-ccu.o
|
||||
obj-$(CONFIG_SUN50I_H616_CCU) += sun50i-h616-ccu.o
|
||||
obj-$(CONFIG_SUN55I_A523_CCU) += sun55i-a523-ccu.o
|
||||
+obj-$(CONFIG_SUN55I_A523_CCU) += sun55i-a523-cpu-ccu.o
|
||||
obj-$(CONFIG_SUN55I_A523_MCU_CCU) += sun55i-a523-mcu-ccu.o
|
||||
obj-$(CONFIG_SUN55I_A523_R_CCU) += sun55i-a523-r-ccu.o
|
||||
obj-$(CONFIG_SUN4I_A10_CCU) += sun4i-a10-ccu.o
|
||||
@@ -62,6 +63,7 @@ sun50i-h6-ccu-y += ccu-sun50i-h6.o
|
||||
sun50i-h6-r-ccu-y += ccu-sun50i-h6-r.o
|
||||
sun50i-h616-ccu-y += ccu-sun50i-h616.o
|
||||
sun55i-a523-ccu-y += ccu-sun55i-a523.o
|
||||
+sun55i-a523-cpu-ccu-y += ccu-sun55i-a523-cpu.o
|
||||
sun55i-a523-mcu-ccu-y += ccu-sun55i-a523-mcu.o
|
||||
sun55i-a523-r-ccu-y += ccu-sun55i-a523-r.o
|
||||
sun4i-a10-ccu-y += ccu-sun4i-a10.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523-cpu.c
|
||||
@@ -0,0 +1,219 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * Copyright (c) 2025
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/clk-provider.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/iopoll.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+#include "ccu_common.h"
|
||||
+#include "ccu_reset.h"
|
||||
+
|
||||
+#include "ccu_div.h"
|
||||
+#include "ccu_gate.h"
|
||||
+#include "ccu_mp.h"
|
||||
+#include "ccu_mult.h"
|
||||
+#include "ccu_nk.h"
|
||||
+#include "ccu_nkm.h"
|
||||
+#include "ccu_nkmp.h"
|
||||
+#include "ccu_nm.h"
|
||||
+
|
||||
+#include "ccu-sun55i-a523-cpu.h"
|
||||
+
|
||||
+#define SUN55I_A523_PLL_SSC_OFFSET 0x50
|
||||
+
|
||||
+#define SUN55I_A523_PLL_CPUL_REG 0x004
|
||||
+static struct ccu_nkmp pll_cpul_clk = {
|
||||
+ .enable = BIT(27),
|
||||
+ .lock = BIT(28),
|
||||
+ .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 20, 108), /* form shc */
|
||||
+ .p = _SUNXI_CCU_DIV(16, 2), /* P in CPUL reg */
|
||||
+ .p_reg = 0x0060,
|
||||
+ .common = {
|
||||
+ .reg = 0x0004,
|
||||
+ .features = CCU_FEATURE_CLEAR_MOD | CCU_FEATURE_CLAC_CACHED,
|
||||
+ .hw.init = CLK_HW_INIT("pll-cpul", "osc24M",
|
||||
+ &ccu_nkmp_ops,
|
||||
+ CLK_GET_RATE_NOCACHE | CLK_IS_CRITICAL \
|
||||
+ | CLK_SET_RATE_UNGATE),
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+#define SUN55I_A523_PLL_CPUB_REG 0x00c
|
||||
+static struct ccu_nkmp pll_cpub_clk = {
|
||||
+ .enable = BIT(27),
|
||||
+ .lock = BIT(28),
|
||||
+ .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 20, 108),
|
||||
+ .p = _SUNXI_CCU_DIV(16, 2), /* P in CPUB reg */
|
||||
+ .p_reg = 0x0064,
|
||||
+ .common = {
|
||||
+ .reg = 0x000c,
|
||||
+ .features = CCU_FEATURE_CLEAR_MOD | CCU_FEATURE_CLAC_CACHED,
|
||||
+ .hw.init = CLK_HW_INIT("pll-cpub", "osc24M",
|
||||
+ &ccu_nkmp_ops,
|
||||
+ CLK_GET_RATE_NOCACHE | CLK_IS_CRITICAL \
|
||||
+ | CLK_SET_RATE_UNGATE),
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+#define SUN55I_A523_CPUL_REG 0x0060
|
||||
+#define SUN55I_A523_CPUB_REG 0x0064
|
||||
+static const char * const cpul_parents[] = { "osc24M", "osc32k", "iosc", "pll-cpul", "pll-periph0-600M" };
|
||||
+
|
||||
+static SUNXI_CCU_MUX(cpul_clk, "cpul", cpul_parents,
|
||||
+ 0x0060, 24, 3, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
|
||||
+
|
||||
+static const char * const cpub_parents[] = { "osc24M", "osc32k", "iosc", "pll-cpub", "pll-periph0-600M" };
|
||||
+
|
||||
+static SUNXI_CCU_MUX(cpub_clk, "cpub", cpub_parents,
|
||||
+ 0x0064, 24, 3, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
|
||||
+
|
||||
+static struct ccu_common *sun55i_a523_ccu_cpu_clks[] = {
|
||||
+ &pll_cpul_clk.common,
|
||||
+ &pll_cpub_clk.common,
|
||||
+ &cpul_clk.common,
|
||||
+ &cpub_clk.common,
|
||||
+};
|
||||
+
|
||||
+static struct clk_hw_onecell_data sun55i_a523_ccu_cpu_hw_clks = {
|
||||
+ .hws = {
|
||||
+ [CLK_CPUL] = &pll_cpul_clk.common.hw,
|
||||
+ [CLK_CPUB] = &pll_cpub_clk.common.hw,
|
||||
+ [CLK_PLL_CPUL] = &cpul_clk.common.hw,
|
||||
+ [CLK_PLL_CPUB] = &cpub_clk.common.hw,
|
||||
+ },
|
||||
+ .num = CLK_CPU_MAX_NO,
|
||||
+};
|
||||
+
|
||||
+static const struct sunxi_ccu_desc sun55i_a523_ccu_cpu_desc = {
|
||||
+ .ccu_clks = sun55i_a523_ccu_cpu_clks,
|
||||
+ .num_ccu_clks = ARRAY_SIZE(sun55i_a523_ccu_cpu_clks),
|
||||
+ .hw_clks = &sun55i_a523_ccu_cpu_hw_clks,
|
||||
+ .resets = NULL,
|
||||
+ .num_resets = 0,
|
||||
+};
|
||||
+
|
||||
+static const u32 pll_regs[] = {
|
||||
+ SUN55I_A523_PLL_CPUL_REG,
|
||||
+ SUN55I_A523_PLL_CPUB_REG,
|
||||
+};
|
||||
+
|
||||
+static int cpupll_notifier_cb(struct notifier_block *nb,
|
||||
+ unsigned long event, void *data)
|
||||
+{
|
||||
+ struct ccu_pll_nb *pll = to_ccu_pll_nb(nb);
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (event == PRE_RATE_CHANGE) {
|
||||
+ /* Enable ssc function */
|
||||
+ set_reg(pll->common->base + pll->common->reg + SUN55I_A523_PLL_SSC_OFFSET, 1, 1, pll->enable);
|
||||
+ } else if (event == POST_RATE_CHANGE) {
|
||||
+ /* Disable ssc function */
|
||||
+ set_reg(pll->common->base + pll->common->reg + SUN55I_A523_PLL_SSC_OFFSET, 0, 1, pll->enable);
|
||||
+ }
|
||||
+
|
||||
+ ccu_helper_wait_for_clear(pll->common, BIT(26));
|
||||
+
|
||||
+ return notifier_from_errno(ret);
|
||||
+}
|
||||
+
|
||||
+static struct ccu_pll_nb sun55i_a523_pll_cpul_nb = {
|
||||
+ .common = &pll_cpul_clk.common,
|
||||
+ .enable = BIT(31), /* switch ssc mode */
|
||||
+ .clk_nb = {
|
||||
+ .notifier_call = cpupll_notifier_cb,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct ccu_pll_nb sun55i_a523_pll_cpub_nb = {
|
||||
+ .common = &pll_cpub_clk.common,
|
||||
+ .enable = BIT(31),
|
||||
+ .clk_nb = {
|
||||
+ .notifier_call = cpupll_notifier_cb,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static void ccupll_helper_wait_for_lock(void __iomem *addr, u32 lock)
|
||||
+{
|
||||
+ u32 reg;
|
||||
+
|
||||
+ WARN_ON(readl_relaxed_poll_timeout(addr, reg, reg & lock, 100, 70000));
|
||||
+}
|
||||
+
|
||||
+static void cpupll_helper_wait_for_clear(void __iomem *addr, u32 clear)
|
||||
+{
|
||||
+ u32 reg;
|
||||
+
|
||||
+ reg = readl(addr);
|
||||
+ writel(reg | clear, addr);
|
||||
+
|
||||
+ WARN_ON(readl_relaxed_poll_timeout_atomic(addr, reg, !(reg & clear), 100, 10000));
|
||||
+}
|
||||
+
|
||||
+static inline unsigned int calc_pll_ssc(unsigned int step, unsigned int scale,
|
||||
+ unsigned int ssc)
|
||||
+{
|
||||
+ return (unsigned int)(((1 << 17) * ssc) - (scale * (1 << step))) / scale;
|
||||
+}
|
||||
+
|
||||
+static int sun55i_a523_ccu_cpu_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ void __iomem *reg;
|
||||
+ u32 val;
|
||||
+ int ret, i;
|
||||
+ unsigned int step = 0x9, scale = 0xa, ssc = 0x1;
|
||||
+
|
||||
+ reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(reg))
|
||||
+ return PTR_ERR(reg);
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
|
||||
+ val = readl(reg + pll_regs[i]);
|
||||
+ val |= BIT(27) | BIT(29) | BIT(30) | BIT(31);
|
||||
+ set_reg(reg + pll_regs[i], val, 32, 0);
|
||||
+ cpupll_helper_wait_for_clear(reg + pll_regs[i], BIT(26));
|
||||
+ ccupll_helper_wait_for_lock(reg + pll_regs[i], BIT(28));
|
||||
+
|
||||
+ val = 0;
|
||||
+ ssc = calc_pll_ssc(step, scale, ssc);
|
||||
+ val = (ssc << 12 | step << 0);
|
||||
+ set_reg(reg + pll_regs[i] + SUN55I_A523_PLL_SSC_OFFSET, val, 29, 0);
|
||||
+ cpupll_helper_wait_for_clear(reg + pll_regs[i], BIT(26));
|
||||
+ }
|
||||
+
|
||||
+ set_reg(reg + SUN55I_A523_CPUL_REG, 0x3, 3, 24);
|
||||
+ set_reg(reg + SUN55I_A523_CPUB_REG, 0x3, 3, 24);
|
||||
+
|
||||
+ ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun55i_a523_ccu_cpu_desc);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Re-lock the CPU PLL after any rate changes */
|
||||
+ ccu_pll_notifier_register(&sun55i_a523_pll_cpul_nb);
|
||||
+ ccu_pll_notifier_register(&sun55i_a523_pll_cpub_nb);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id sun55i_a523_ccu_cpu_ids[] = {
|
||||
+ { .compatible = "allwinner,sun55i-a523-ccu-cpu" },
|
||||
+ { }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, sun55i_a523_ccu_cpu_ids);
|
||||
+
|
||||
+static struct platform_driver sun55i_a523_ccu_cpu_driver = {
|
||||
+ .probe = sun55i_a523_ccu_cpu_probe,
|
||||
+ .driver = {
|
||||
+ .name = "sun55i-a523-ccu-cpu",
|
||||
+ .of_match_table = sun55i_a523_ccu_cpu_ids,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(sun55i_a523_ccu_cpu_driver);
|
||||
+
|
||||
+MODULE_IMPORT_NS("SUNXI_CCU");
|
||||
+MODULE_DESCRIPTION("Support for the Allwinner A523 CPU CCU");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523-cpu.h
|
||||
@@ -0,0 +1,11 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
+/*
|
||||
+ * Copyright 2025
|
||||
+ */
|
||||
+
|
||||
+#ifndef _CCU_SUN55I_A523_CPU_H_
|
||||
+#define _CCU_SUN55I_A523_CPU_H_
|
||||
+
|
||||
+#include <dt-bindings/clock/sun55i-a523-ccu-cpu.h>
|
||||
+
|
||||
+#endif /* _CCU_SUN55I_A523_CPU_H_ */
|
||||
--- a/drivers/clk/sunxi-ng/ccu_common.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu_common.c
|
||||
@@ -39,6 +39,34 @@ void ccu_helper_wait_for_lock(struct ccu
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_helper_wait_for_lock, "SUNXI_CCU");
|
||||
|
||||
+void set_reg(char __iomem *addr, u32 val, u8 bw, u8 bs)
|
||||
+{
|
||||
+ u32 mask = (1UL << bw) - 1UL;
|
||||
+ u32 tmp = 0;
|
||||
+
|
||||
+ tmp = readl(addr);
|
||||
+ tmp &= ~(mask << bs);
|
||||
+
|
||||
+ writel(tmp | ((val & mask) << bs), addr);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(set_reg);
|
||||
+
|
||||
+void ccu_helper_wait_for_clear(struct ccu_common *common, u32 clear)
|
||||
+{
|
||||
+ void __iomem *addr;
|
||||
+ u32 reg;
|
||||
+
|
||||
+ if (!clear)
|
||||
+ return;
|
||||
+
|
||||
+ addr = common->base + common->reg;
|
||||
+ reg = readl(addr);
|
||||
+ writel(reg | clear, addr);
|
||||
+
|
||||
+ WARN_ON(readl_relaxed_poll_timeout_atomic(addr, reg, !(reg & clear), 100, 10000));
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(ccu_helper_wait_for_clear);
|
||||
+
|
||||
bool ccu_is_better_rate(struct ccu_common *common,
|
||||
unsigned long target_rate,
|
||||
unsigned long current_rate,
|
||||
--- a/drivers/clk/sunxi-ng/ccu_common.h
|
||||
+++ b/drivers/clk/sunxi-ng/ccu_common.h
|
||||
@@ -21,6 +21,10 @@
|
||||
#define CCU_FEATURE_CLOSEST_RATE BIT(9)
|
||||
#define CCU_FEATURE_DUAL_DIV BIT(10)
|
||||
#define CCU_FEATURE_UPDATE_BIT BIT(11)
|
||||
+/* Write one bit update the cfg to displl, auto clear */
|
||||
+#define CCU_FEATURE_CLEAR_MOD BIT(12)
|
||||
+/* Calculate the frequency and save it in the list first */
|
||||
+#define CCU_FEATURE_CLAC_CACHED BIT(15)
|
||||
|
||||
/* MMC timing mode switch bit */
|
||||
#define CCU_MMC_NEW_TIMING_MODE BIT(30)
|
||||
@@ -60,6 +64,7 @@ struct sunxi_ccu_desc {
|
||||
};
|
||||
|
||||
void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock);
|
||||
+void ccu_helper_wait_for_clear(struct ccu_common *common, u32 clear);
|
||||
|
||||
bool ccu_is_better_rate(struct ccu_common *common,
|
||||
unsigned long target_rate,
|
||||
@@ -83,4 +88,6 @@ int devm_sunxi_ccu_probe(struct device *
|
||||
void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
|
||||
const struct sunxi_ccu_desc *desc);
|
||||
|
||||
+void set_reg(char __iomem *addr, u32 val, u8 bw, u8 bs);
|
||||
+
|
||||
#endif /* _COMMON_H_ */
|
||||
--- a/drivers/clk/sunxi-ng/ccu_nkmp.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu_nkmp.c
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
+#include <linux/iopoll.h>
|
||||
|
||||
#include "ccu_gate.h"
|
||||
#include "ccu_nkmp.h"
|
||||
@@ -117,6 +118,8 @@ static unsigned long ccu_nkmp_recalc_rat
|
||||
if (!m)
|
||||
m++;
|
||||
|
||||
+ if (nkmp->p_reg)
|
||||
+ reg = readl(nkmp->common.base + nkmp->p_reg);
|
||||
p = reg >> nkmp->p.shift;
|
||||
p &= (1 << nkmp->p.width) - 1;
|
||||
|
||||
@@ -161,6 +164,25 @@ static int ccu_nkmp_determine_rate(struc
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static __always_inline u32 get_data_field(u32 data, u32 bits)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ if (WARN_ON(!bits))
|
||||
+ return 0;
|
||||
+ /* @bits should always be greater than 0 */
|
||||
+ for (i = 0; !(bits & (1 << i)); )
|
||||
+ i++;
|
||||
+
|
||||
+ return (data & bits) >> i;
|
||||
+}
|
||||
+
|
||||
+static __always_inline u32 get_field(const void volatile __iomem *addr, u32 bits)
|
||||
+{
|
||||
+ return get_data_field(readl(addr), bits);
|
||||
+}
|
||||
+
|
||||
+#define BITS_WIDTH(bit_start, bit_width) GENMASK((bit_start) + (bit_width) - 1, bit_start)
|
||||
static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
@@ -169,6 +191,7 @@ static int ccu_nkmp_set_rate(struct clk_
|
||||
struct _ccu_nkmp _nkmp;
|
||||
unsigned long flags;
|
||||
u32 reg;
|
||||
+ u32 back_p, new_p;
|
||||
|
||||
if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||
rate = rate * nkmp->fixed_post_div;
|
||||
@@ -211,9 +234,30 @@ static int ccu_nkmp_set_rate(struct clk_
|
||||
reg |= ((_nkmp.n - nkmp->n.offset) << nkmp->n.shift) & n_mask;
|
||||
reg |= ((_nkmp.k - nkmp->k.offset) << nkmp->k.shift) & k_mask;
|
||||
reg |= ((_nkmp.m - nkmp->m.offset) << nkmp->m.shift) & m_mask;
|
||||
- reg |= (ilog2(_nkmp.p) << nkmp->p.shift) & p_mask;
|
||||
+
|
||||
+ if (!nkmp->p_reg) {
|
||||
+ reg |= (ilog2(_nkmp.p) << nkmp->p.shift) & p_mask;
|
||||
+ writel(reg, nkmp->common.base + nkmp->common.reg);
|
||||
+ } else {
|
||||
+ back_p = get_field(nkmp->common.base + nkmp->p_reg, BITS_WIDTH(nkmp->p.shift, nkmp->p.width));
|
||||
+ new_p = ilog2(_nkmp.p);
|
||||
+ if (new_p > back_p) {
|
||||
+ set_reg(nkmp->common.base + nkmp->p_reg, new_p,
|
||||
+ nkmp->p.width, nkmp->p.shift);
|
||||
+ writel(reg, nkmp->common.base + nkmp->common.reg);
|
||||
+ } else {
|
||||
+ writel(reg, nkmp->common.base + nkmp->common.reg);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (nkmp->common.features & CCU_FEATURE_CLEAR_MOD)
|
||||
+ ccu_helper_wait_for_clear(&nkmp->common, BIT(26));
|
||||
|
||||
- writel(reg, nkmp->common.base + nkmp->common.reg);
|
||||
+ if (nkmp->p_reg) {
|
||||
+ if (new_p < back_p)
|
||||
+ set_reg(nkmp->common.base + nkmp->p_reg, new_p,
|
||||
+ nkmp->p.width, nkmp->p.shift);
|
||||
+ }
|
||||
|
||||
spin_unlock_irqrestore(nkmp->common.lock, flags);
|
||||
|
||||
--- a/drivers/clk/sunxi-ng/ccu_nkmp.h
|
||||
+++ b/drivers/clk/sunxi-ng/ccu_nkmp.h
|
||||
@@ -20,6 +20,7 @@
|
||||
struct ccu_nkmp {
|
||||
u32 enable;
|
||||
u32 lock;
|
||||
+ u16 p_reg;
|
||||
|
||||
struct ccu_mult_internal n;
|
||||
struct ccu_mult_internal k;
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/clock/sun55i-a523-ccu-cpu.h
|
||||
@@ -0,0 +1,16 @@
|
||||
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
|
||||
+/*
|
||||
+ * Copyright (C) 2025
|
||||
+ */
|
||||
+
|
||||
+#ifndef _DT_BINDINGS_CLK_CPU_SUN55I_A523_H_
|
||||
+#define _DT_BINDINGS_CLK_CPU_SUN55I_A523_H_
|
||||
+
|
||||
+#define CLK_CPUL 0
|
||||
+#define CLK_CPUB 1
|
||||
+#define CLK_PLL_CPUL 2
|
||||
+#define CLK_PLL_CPUB 3
|
||||
+
|
||||
+#define CLK_CPU_MAX_NO (CLK_PLL_CPUB + 1)
|
||||
+
|
||||
+#endif /* _DT_BINDINGS_CLK_CPU_SUN55I_A523_H_ */
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
From git@z Thu Jan 1 00:00:00 1970
|
||||
Subject: [PATCH RFC 2/5] mfd: axp20x: Refactor axp20x_is_polyphase_slave()
|
||||
From: Andre Przywara <andre.przywara@arm.com>
|
||||
Date: Fri, 19 Sep 2025 01:00:17 +0100
|
||||
Message-Id: <20250919000020.16969-3-andre.przywara@arm.com>
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
Some X-Powers AXP PMICs allow to combine certain DC/DC rails together in
|
||||
a multi-phase fashion. So far we don't actively program those
|
||||
connections, but we detect the existing setup, and prevent the connected
|
||||
regulators from being re-programmed or turned off. At the moment this is
|
||||
done in a switch/case construct, listing the known regulator pairs for
|
||||
those PMICs supported.
|
||||
|
||||
To get rid of this ever growing code section, create a data structure
|
||||
that describes the relationship, and have generic code that iterates
|
||||
over the entries and checks for matches.
|
||||
|
||||
This not only cleans that function up and makes extensions much simpler,
|
||||
but also allows to reuse this information for the upcoming programming
|
||||
of those poly-phase setups.
|
||||
|
||||
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
|
||||
---
|
||||
drivers/regulator/axp20x-regulator.c | 91 ++++++++++++++--------------
|
||||
1 file changed, 45 insertions(+), 46 deletions(-)
|
||||
|
||||
--- a/drivers/regulator/axp20x-regulator.c
|
||||
+++ b/drivers/regulator/axp20x-regulator.c
|
||||
@@ -1481,70 +1481,69 @@ static int axp20x_set_dcdc_workmode(stru
|
||||
return regmap_update_bits(rdev->regmap, reg, mask, workmode);
|
||||
}
|
||||
|
||||
+struct dualphase_regulator {
|
||||
+ int axp_id;
|
||||
+ int reg1, reg2;
|
||||
+ unsigned int polyphase_reg;
|
||||
+ unsigned int bitmask;
|
||||
+} dualphase_regulators[] = {
|
||||
+ { AXP323_ID, AXP313A_DCDC1, AXP313A_DCDC2,
|
||||
+ AXP323_DCDC_MODE_CTRL2, BIT(1), },
|
||||
+ { AXP803_ID, AXP803_DCDC2, AXP803_DCDC3, AXP803_POLYPHASE_CTRL,
|
||||
+ AXP803_DCDC23_POLYPHASE_DUAL, },
|
||||
+ { AXP803_ID, AXP803_DCDC5, AXP803_DCDC6, AXP803_POLYPHASE_CTRL,
|
||||
+ AXP803_DCDC56_POLYPHASE_DUAL, },
|
||||
+ /* AXP806's DCDC-A/B/C is a tri-phase regulator */
|
||||
+ { AXP806_ID, AXP806_DCDCD, AXP806_DCDCE, AXP806_DCDC_MODE_CTRL2,
|
||||
+ AXP806_DCDCDE_POLYPHASE_DUAL, },
|
||||
+ { AXP813_ID, AXP803_DCDC2, AXP803_DCDC3, AXP803_POLYPHASE_CTRL,
|
||||
+ AXP803_DCDC23_POLYPHASE_DUAL, },
|
||||
+ { AXP813_ID, AXP803_DCDC5, AXP803_DCDC6, AXP803_POLYPHASE_CTRL,
|
||||
+ AXP803_DCDC56_POLYPHASE_DUAL, },
|
||||
+ { AXP15060_ID, AXP15060_DCDC2, AXP15060_DCDC3, AXP15060_DCDC_MODE_CTRL1,
|
||||
+ AXP15060_DCDC23_POLYPHASE_DUAL_MASK, },
|
||||
+ { AXP15060_ID, AXP15060_DCDC4, AXP15060_DCDC6, AXP15060_DCDC_MODE_CTRL1,
|
||||
+ AXP15060_DCDC46_POLYPHASE_DUAL_MASK, },
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* This function checks whether a regulator is part of a poly-phase
|
||||
* output setup based on the registers settings. Returns true if it is.
|
||||
*/
|
||||
static bool axp20x_is_polyphase_slave(struct axp20x_dev *axp20x, int id)
|
||||
{
|
||||
+ struct dualphase_regulator *dpreg;
|
||||
u32 reg = 0;
|
||||
+ int i;
|
||||
|
||||
- /*
|
||||
- * Currently in our supported AXP variants, only AXP803, AXP806,
|
||||
- * AXP813 and AXP15060 have polyphase regulators.
|
||||
- */
|
||||
- switch (axp20x->variant) {
|
||||
- case AXP803_ID:
|
||||
- case AXP813_ID:
|
||||
- regmap_read(axp20x->regmap, AXP803_POLYPHASE_CTRL, ®);
|
||||
-
|
||||
- switch (id) {
|
||||
- case AXP803_DCDC3:
|
||||
- return !!(reg & AXP803_DCDC23_POLYPHASE_DUAL);
|
||||
- case AXP803_DCDC6:
|
||||
- return !!(reg & AXP803_DCDC56_POLYPHASE_DUAL);
|
||||
+ for (i = 0; i < ARRAY_SIZE(dualphase_regulators); i++) {
|
||||
+ dpreg = &dualphase_regulators[i];
|
||||
+
|
||||
+ if (axp20x->variant != dpreg->axp_id)
|
||||
+ continue;
|
||||
+ /* Is this the second regulator from a dual-phase pair? */
|
||||
+ if (id == dpreg->reg2) {
|
||||
+ regmap_read(axp20x->regmap, dpreg->polyphase_reg, ®);
|
||||
+
|
||||
+ return !!(reg & dpreg->bitmask);
|
||||
}
|
||||
- break;
|
||||
+ }
|
||||
|
||||
- case AXP806_ID:
|
||||
+ /*
|
||||
+ * DCDC-A/B/C can be configured either as a dual-phase (A+B) or
|
||||
+ * as a triple-phase regulator (A+B+C), but not in any other
|
||||
+ * combination. Treat this as a special case here.
|
||||
+ */
|
||||
+ if (axp20x->variant == AXP806_ID) {
|
||||
regmap_read(axp20x->regmap, AXP806_DCDC_MODE_CTRL2, ®);
|
||||
-
|
||||
- switch (id) {
|
||||
- case AXP806_DCDCB:
|
||||
+ if (id == AXP806_DCDCB)
|
||||
return (((reg & AXP806_DCDCABC_POLYPHASE_MASK) ==
|
||||
AXP806_DCDCAB_POLYPHASE_DUAL) ||
|
||||
((reg & AXP806_DCDCABC_POLYPHASE_MASK) ==
|
||||
AXP806_DCDCABC_POLYPHASE_TRI));
|
||||
- case AXP806_DCDCC:
|
||||
+ if (id == AXP806_DCDCC)
|
||||
return ((reg & AXP806_DCDCABC_POLYPHASE_MASK) ==
|
||||
AXP806_DCDCABC_POLYPHASE_TRI);
|
||||
- case AXP806_DCDCE:
|
||||
- return !!(reg & AXP806_DCDCDE_POLYPHASE_DUAL);
|
||||
- }
|
||||
- break;
|
||||
-
|
||||
- case AXP15060_ID:
|
||||
- regmap_read(axp20x->regmap, AXP15060_DCDC_MODE_CTRL1, ®);
|
||||
-
|
||||
- switch (id) {
|
||||
- case AXP15060_DCDC3:
|
||||
- return !!(reg & AXP15060_DCDC23_POLYPHASE_DUAL_MASK);
|
||||
- case AXP15060_DCDC6:
|
||||
- return !!(reg & AXP15060_DCDC46_POLYPHASE_DUAL_MASK);
|
||||
- }
|
||||
- break;
|
||||
-
|
||||
- case AXP323_ID:
|
||||
- regmap_read(axp20x->regmap, AXP323_DCDC_MODE_CTRL2, ®);
|
||||
-
|
||||
- switch (id) {
|
||||
- case AXP313A_DCDC2:
|
||||
- return !!(reg & BIT(1));
|
||||
- }
|
||||
- break;
|
||||
-
|
||||
- default:
|
||||
- return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -0,0 +1,120 @@
|
||||
From git@z Thu Jan 1 00:00:00 1970
|
||||
Subject: [PATCH RFC 3/5] mfd: axp20x: Allow programming dual-phase
|
||||
regulator pairs
|
||||
From: Andre Przywara <andre.przywara@arm.com>
|
||||
Date: Fri, 19 Sep 2025 01:00:18 +0100
|
||||
Message-Id: <20250919000020.16969-4-andre.przywara@arm.com>
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
Some X-Powers AXP PMICs allow to combine certain DC/DC rails together in
|
||||
a multi-phase fashion. So far we don't actively program those connections,
|
||||
since the PMIC reset default for the multi-phasing setup was always
|
||||
correct for the existing boards.
|
||||
Now a new set of boards appeared where the reset default is not correct,
|
||||
so we need to actively program the multi-phase setup.
|
||||
|
||||
Use the new data structure describing the dual-phased regulators, and
|
||||
the new "x-powers,polyphased" DT property to enable or disable the
|
||||
dual-phase setup on the PMICs that support it.
|
||||
|
||||
This works by checking how many regulators this DT property list:
|
||||
- If it's none, this means any existing poly-phase setup should be broken
|
||||
up.
|
||||
- If the property references at least one other regulator, we can use our
|
||||
dual-phase regulator table to find the register and bitmask required to
|
||||
establish the dual-phase connection.
|
||||
|
||||
This supports only dual-phased regulator pairs so far, but we will
|
||||
somewhat paper ov^W^W fix this in the next patch.
|
||||
|
||||
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
|
||||
---
|
||||
drivers/regulator/axp20x-regulator.c | 68 ++++++++++++++++++++++++++++
|
||||
1 file changed, 68 insertions(+)
|
||||
|
||||
--- a/drivers/regulator/axp20x-regulator.c
|
||||
+++ b/drivers/regulator/axp20x-regulator.c
|
||||
@@ -1549,6 +1549,70 @@ static bool axp20x_is_polyphase_slave(st
|
||||
return false;
|
||||
}
|
||||
|
||||
+static int axp20x_find_polyphased_reg(const struct regulator_desc *regs,
|
||||
+ int nregulators,
|
||||
+ const struct device_node *np, int index)
|
||||
+{
|
||||
+ struct of_phandle_args args;
|
||||
+ int ret, i;
|
||||
+
|
||||
+ ret = of_parse_phandle_with_fixed_args(np, "x-powers,polyphased",
|
||||
+ 0, index, &args);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ for (i = 0; i < nregulators; i++) {
|
||||
+ if (!strcmp(regs[i].name, args.np->name))
|
||||
+ return i;
|
||||
+ }
|
||||
+
|
||||
+ return -ENODEV;
|
||||
+}
|
||||
+
|
||||
+static int axp20x_parse_polyphase(struct axp20x_dev *axp20x, int primary_reg_id,
|
||||
+ const struct regulator_desc *regs,
|
||||
+ int nregulators, const struct device_node *np)
|
||||
+{
|
||||
+ struct dualphase_regulator *dpreg;
|
||||
+ int reg_id, i;
|
||||
+
|
||||
+ if (!of_property_present(np, "x-powers,polyphased"))
|
||||
+ return 0;
|
||||
+
|
||||
+ reg_id = axp20x_find_polyphased_reg(regs, nregulators, np, 0);
|
||||
+ if (reg_id < 0 && reg_id != -ENOENT) /* not just empty property */
|
||||
+ return reg_id;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(dualphase_regulators); i++) {
|
||||
+ dpreg = &dualphase_regulators[i];
|
||||
+
|
||||
+ if (axp20x->variant != dpreg->axp_id)
|
||||
+ continue;
|
||||
+
|
||||
+ if (dpreg->reg1 != primary_reg_id &&
|
||||
+ dpreg->reg2 != primary_reg_id)
|
||||
+ continue;
|
||||
+
|
||||
+ /* Empty property means breaking any polyphase setup. */
|
||||
+ if (reg_id == -ENOENT) {
|
||||
+ regmap_update_bits(axp20x->regmap, dpreg->polyphase_reg,
|
||||
+ dpreg->bitmask, 0);
|
||||
+
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if ((dpreg->reg1 == primary_reg_id && dpreg->reg2 == reg_id) ||
|
||||
+ (dpreg->reg2 == primary_reg_id && dpreg->reg1 == reg_id)) {
|
||||
+ regmap_update_bits(axp20x->regmap, dpreg->polyphase_reg,
|
||||
+ dpreg->bitmask, dpreg->bitmask);
|
||||
+
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int axp20x_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regulator_dev *rdev;
|
||||
@@ -1703,6 +1767,10 @@ static int axp20x_regulator_probe(struct
|
||||
rdev->desc->name);
|
||||
}
|
||||
|
||||
+ if (rdev->dev.of_node)
|
||||
+ axp20x_parse_polyphase(axp20x, i, regulators,
|
||||
+ nregulators, rdev->dev.of_node);
|
||||
+
|
||||
/*
|
||||
* Save AXP22X DCDC1 / DCDC5 / AXP15060 ALDO1 regulator names for later.
|
||||
*/
|
||||
@@ -0,0 +1,93 @@
|
||||
From git@z Thu Jan 1 00:00:00 1970
|
||||
Subject: [PATCH RFC 4/5] mfd: axp20x: Support tri-phase setup
|
||||
From: Andre Przywara <andre.przywara@arm.com>
|
||||
Date: Fri, 19 Sep 2025 01:00:19 +0100
|
||||
Message-Id: <20250919000020.16969-5-andre.przywara@arm.com>
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
Of the PMICs that support multi-phased regulators, all but one just
|
||||
support a dual-phase setup, with exactly two regulators tied together.
|
||||
This allows for a simple data model, since just two is somewhat of a
|
||||
special case.
|
||||
|
||||
However there is the AXP806, which supports a triple-phase setup, that is
|
||||
also used on at least one board: the Cubieboard 4, where DCDC-A+B+C
|
||||
together supply the Cortex-A15 CPU cluster.
|
||||
Since this is just one case, and a fairly old one now, let's not boil
|
||||
the ocean by coming up with a complex data structure that allows
|
||||
describing arbitrary combinations, but instead handle this as a special
|
||||
case. This is supported by the fact, that the AXP806 only supports two
|
||||
specific setups: DCDC-A+B or DCDC-A+B+C, but nothing else.
|
||||
|
||||
Add a function that checks for the regulators on this PMIC, and handle
|
||||
the two cases, plus the one without any poly-phasing.
|
||||
|
||||
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
|
||||
Acked-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
drivers/regulator/axp20x-regulator.c | 45 ++++++++++++++++++++++++++++
|
||||
1 file changed, 45 insertions(+)
|
||||
|
||||
--- a/drivers/regulator/axp20x-regulator.c
|
||||
+++ b/drivers/regulator/axp20x-regulator.c
|
||||
@@ -1569,6 +1569,39 @@ static int axp20x_find_polyphased_reg(co
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
+static int axp20x_handle_triphase(struct axp20x_dev *axp20x,
|
||||
+ int reg1, int reg2, int reg3)
|
||||
+{
|
||||
+ if (axp20x->variant == AXP806_ID && reg1 == AXP806_DCDCA) {
|
||||
+ /* no other regulator listed: single phase setup */
|
||||
+ if (reg2 == -ENOENT && reg3 == -ENOENT) {
|
||||
+ regmap_update_bits(axp20x->regmap,
|
||||
+ AXP806_DCDC_MODE_CTRL2,
|
||||
+ AXP806_DCDCABC_POLYPHASE_MASK, 0);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ /* only regulator listed is DCDC-B: dual phase setup */
|
||||
+ if (reg2 == AXP806_DCDCB && reg3 == -ENOENT) {
|
||||
+ regmap_update_bits(axp20x->regmap,
|
||||
+ AXP806_DCDC_MODE_CTRL2,
|
||||
+ AXP806_DCDCABC_POLYPHASE_MASK,
|
||||
+ AXP806_DCDCAB_POLYPHASE_DUAL);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ /* both DCDC-B+C regulators listed: tri phase setup */
|
||||
+ if ((reg2 == AXP806_DCDCB && reg3 == AXP806_DCDCC) ||
|
||||
+ (reg2 == AXP806_DCDCC && reg3 == AXP806_DCDCB)) {
|
||||
+ regmap_update_bits(axp20x->regmap,
|
||||
+ AXP806_DCDC_MODE_CTRL2,
|
||||
+ AXP806_DCDCABC_POLYPHASE_MASK,
|
||||
+ AXP806_DCDCABC_POLYPHASE_TRI);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int axp20x_parse_polyphase(struct axp20x_dev *axp20x, int primary_reg_id,
|
||||
const struct regulator_desc *regs,
|
||||
int nregulators, const struct device_node *np)
|
||||
@@ -1610,6 +1643,18 @@ static int axp20x_parse_polyphase(struct
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Special handling for the AXP806 DCDC-A/B/C tri-phase regulator. */
|
||||
+ if (axp20x->variant == AXP806_ID && primary_reg_id == AXP806_DCDCA) {
|
||||
+ int reg3_id;
|
||||
+
|
||||
+ reg3_id = axp20x_find_polyphased_reg(regs, nregulators, np, 1);
|
||||
+ if (reg3_id < 0 && reg3_id != -ENOENT)
|
||||
+ return reg_id;
|
||||
+
|
||||
+ return axp20x_handle_triphase(axp20x, primary_reg_id,
|
||||
+ reg_id, reg3_id);
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
From git@z Thu Jan 1 00:00:00 1970
|
||||
Subject: [PATCH v3 2/6] thermal/drivers/sun8i: add gpadc clock
|
||||
From: Mikhail Kalashnikov <iuncuim@gmail.com>
|
||||
Date: Sat, 25 Oct 2025 12:31:25 +0800
|
||||
Message-Id: <20251025043129.160454-3-iuncuim@gmail.com>
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
Some processors (e.g. Allwinner A523) require GPADC clocking activation for
|
||||
temperature sensors to work. So let's add support for enabling it.
|
||||
|
||||
Signed-off-by: Mikhail Kalashnikov <iuncuim@gmail.com>
|
||||
Reviewed-by: Chen-Yu Tsai <wens@kernel.org>
|
||||
---
|
||||
drivers/thermal/sun8i_thermal.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
--- a/drivers/thermal/sun8i_thermal.c
|
||||
+++ b/drivers/thermal/sun8i_thermal.c
|
||||
@@ -66,6 +66,7 @@ struct tsensor {
|
||||
};
|
||||
|
||||
struct ths_thermal_chip {
|
||||
+ bool has_gpadc_clk;
|
||||
bool has_mod_clk;
|
||||
bool has_bus_clk_reset;
|
||||
bool needs_sram;
|
||||
@@ -89,6 +90,7 @@ struct ths_device {
|
||||
struct regmap_field *sram_regmap_field;
|
||||
struct reset_control *reset;
|
||||
struct clk *bus_clk;
|
||||
+ struct clk *gpadc_clk;
|
||||
struct clk *mod_clk;
|
||||
struct tsensor sensor[MAX_SENSOR_NUM];
|
||||
};
|
||||
@@ -417,6 +419,12 @@ static int sun8i_ths_resource_init(struc
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ if (tmdev->chip->has_gpadc_clk) {
|
||||
+ tmdev->gpadc_clk = devm_clk_get_enabled(&pdev->dev, "gpadc");
|
||||
+ if (IS_ERR(tmdev->gpadc_clk))
|
||||
+ return PTR_ERR(tmdev->gpadc_clk);
|
||||
+ }
|
||||
+
|
||||
if (tmdev->chip->needs_sram) {
|
||||
struct regmap *regmap;
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
From git@z Thu Jan 1 00:00:00 1970
|
||||
Subject: [PATCH v3 3/6] thermal/drivers/sun8i: replace
|
||||
devm_reset_control_get to devm_reset_control_get_shared_deasserted
|
||||
From: Mikhail Kalashnikov <iuncuim@gmail.com>
|
||||
Date: Sat, 25 Oct 2025 12:31:26 +0800
|
||||
Message-Id: <20251025043129.160454-4-iuncuim@gmail.com>
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
The A523 processor has two temperature controllers, but they share a
|
||||
common reset line. Make it shared with the shared variant of
|
||||
devm_reset_control_get(), and also simplify the driver by switching to
|
||||
devm_reset_control_get_shared_deasserted().
|
||||
|
||||
Signed-off-by: Mikhail Kalashnikov <iuncuim@gmail.com>
|
||||
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
|
||||
---
|
||||
drivers/thermal/sun8i_thermal.c | 16 +---------------
|
||||
1 file changed, 1 insertion(+), 15 deletions(-)
|
||||
|
||||
--- a/drivers/thermal/sun8i_thermal.c
|
||||
+++ b/drivers/thermal/sun8i_thermal.c
|
||||
@@ -344,11 +344,6 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static void sun8i_ths_reset_control_assert(void *data)
|
||||
-{
|
||||
- reset_control_assert(data);
|
||||
-}
|
||||
-
|
||||
static struct regmap *sun8i_ths_get_sram_regmap(struct device_node *node)
|
||||
{
|
||||
struct platform_device *sram_pdev;
|
||||
@@ -391,19 +386,10 @@ static int sun8i_ths_resource_init(struc
|
||||
return PTR_ERR(tmdev->regmap);
|
||||
|
||||
if (tmdev->chip->has_bus_clk_reset) {
|
||||
- tmdev->reset = devm_reset_control_get(dev, NULL);
|
||||
+ tmdev->reset = devm_reset_control_get_shared_deasserted(dev, NULL);
|
||||
if (IS_ERR(tmdev->reset))
|
||||
return PTR_ERR(tmdev->reset);
|
||||
|
||||
- ret = reset_control_deassert(tmdev->reset);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- ret = devm_add_action_or_reset(dev, sun8i_ths_reset_control_assert,
|
||||
- tmdev->reset);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
tmdev->bus_clk = devm_clk_get_enabled(&pdev->dev, "bus");
|
||||
if (IS_ERR(tmdev->bus_clk))
|
||||
return PTR_ERR(tmdev->bus_clk);
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
From git@z Thu Jan 1 00:00:00 1970
|
||||
Subject: [PATCH v3 4/6] thermal/drivers/sun8i: get calibration data from
|
||||
two nvmem cells
|
||||
From: Mikhail Kalashnikov <iuncuim@gmail.com>
|
||||
Date: Sat, 25 Oct 2025 12:31:27 +0800
|
||||
Message-Id: <20251025043129.160454-5-iuncuim@gmail.com>
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
The A523 processor has calibration data in two nvmem cell. To be able to
|
||||
add support, the ability to add data from two cells into one array must be
|
||||
added.
|
||||
|
||||
Signed-off-by: Mikhail Kalashnikov <iuncuim@gmail.com>
|
||||
---
|
||||
drivers/thermal/sun8i_thermal.c | 77 ++++++++++++++++++++++-----------
|
||||
1 file changed, 52 insertions(+), 25 deletions(-)
|
||||
|
||||
--- a/drivers/thermal/sun8i_thermal.c
|
||||
+++ b/drivers/thermal/sun8i_thermal.c
|
||||
@@ -303,43 +303,70 @@ static int sun50i_h6_ths_calibrate(struc
|
||||
|
||||
static int sun8i_ths_calibrate(struct ths_device *tmdev)
|
||||
{
|
||||
- struct nvmem_cell *calcell;
|
||||
+ struct nvmem_cell *calcell = NULL;
|
||||
struct device *dev = tmdev->dev;
|
||||
- u16 *caldata;
|
||||
- size_t callen;
|
||||
+ struct device_node *np = dev_of_node(dev);
|
||||
+ struct property *prop;
|
||||
+ const char *cellname;
|
||||
+ u8 *caldata = NULL;
|
||||
+ size_t callen = 0;
|
||||
int ret = 0;
|
||||
|
||||
- calcell = nvmem_cell_get(dev, "calibration");
|
||||
- if (IS_ERR(calcell)) {
|
||||
- if (PTR_ERR(calcell) == -EPROBE_DEFER)
|
||||
- return -EPROBE_DEFER;
|
||||
- /*
|
||||
- * Even if the external calibration data stored in sid is
|
||||
- * not accessible, the THS hardware can still work, although
|
||||
- * the data won't be so accurate.
|
||||
- *
|
||||
- * The default value of calibration register is 0x800 for
|
||||
- * every sensor, and the calibration value is usually 0x7xx
|
||||
- * or 0x8xx, so they won't be away from the default value
|
||||
- * for a lot.
|
||||
- *
|
||||
- * So here we do not return error if the calibration data is
|
||||
- * not available, except the probe needs deferring.
|
||||
- */
|
||||
- goto out;
|
||||
+ of_property_for_each_string(np, "nvmem-cell-names", prop, cellname) {
|
||||
+ size_t len;
|
||||
+ u8 *caldatapart;
|
||||
+
|
||||
+ calcell = of_nvmem_cell_get(np, cellname);
|
||||
+ if (IS_ERR(calcell)) {
|
||||
+ if (PTR_ERR(calcell) == -EPROBE_DEFER)
|
||||
+ return -EPROBE_DEFER;
|
||||
+ /*
|
||||
+ * Even if the external calibration data stored in sid is
|
||||
+ * not accessible, the THS hardware can still work, although
|
||||
+ * the data won't be so accurate.
|
||||
+ *
|
||||
+ * The default value of calibration register is 0x800 for
|
||||
+ * every sensor, and the calibration value is usually 0x7xx
|
||||
+ * or 0x8xx, so they won't be away from the default value
|
||||
+ * for a lot.
|
||||
+ *
|
||||
+ * So here we do not return error if the calibration data is
|
||||
+ * not available, except the probe needs deferring.
|
||||
+ */
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ caldatapart = nvmem_cell_read(calcell, &len);
|
||||
+ nvmem_cell_put(calcell);
|
||||
+ calcell = NULL;
|
||||
+ if (IS_ERR(caldatapart)) {
|
||||
+ ret = PTR_ERR(caldatapart);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ caldata = devm_krealloc(dev, caldata, callen + len, GFP_KERNEL);
|
||||
+ if (!caldata) {
|
||||
+ kfree(caldatapart);
|
||||
+ ret = -ENOMEM;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ memcpy(caldata + callen, caldatapart, len);
|
||||
+ callen += len;
|
||||
+ kfree(caldatapart);
|
||||
}
|
||||
|
||||
- caldata = nvmem_cell_read(calcell, &callen);
|
||||
if (IS_ERR(caldata)) {
|
||||
ret = PTR_ERR(caldata);
|
||||
goto out;
|
||||
}
|
||||
|
||||
- tmdev->chip->calibrate(tmdev, caldata, callen);
|
||||
+ tmdev->chip->calibrate(tmdev, (u16 *)caldata, callen);
|
||||
|
||||
- kfree(caldata);
|
||||
+ devm_kfree(dev, caldata);
|
||||
+ caldata = NULL;
|
||||
out:
|
||||
- if (!IS_ERR(calcell))
|
||||
+ if (calcell && !IS_ERR(calcell))
|
||||
nvmem_cell_put(calcell);
|
||||
return ret;
|
||||
}
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
From git@z Thu Jan 1 00:00:00 1970
|
||||
Subject: [PATCH v3 5/6] thermal/drivers/sun8i: Add support for A523 THS0/1
|
||||
controllers
|
||||
From: Mikhail Kalashnikov <iuncuim@gmail.com>
|
||||
Date: Sat, 25 Oct 2025 12:31:28 +0800
|
||||
Message-Id: <20251025043129.160454-6-iuncuim@gmail.com>
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
The A523 processor has two temperature controllers, THS0 and THS1.
|
||||
|
||||
THS0 has only one temperature sensor, which is located in the DRAM.
|
||||
|
||||
THS1 does have 3 sensors:
|
||||
ths1_0 - "big" cores
|
||||
ths1_1 - "little" cores
|
||||
ths1_2 - gpu
|
||||
|
||||
The datasheet mentions a fourth sensor in the NPU, but lacks any registers
|
||||
for operation other than calibration registers. The vendor code reads the
|
||||
value from ths1_2, but uses separate calibration data, so we get two
|
||||
different values from real one.
|
||||
|
||||
Signed-off-by: Mikhail Kalashnikov <iuncuim@gmail.com>
|
||||
---
|
||||
drivers/thermal/sun8i_thermal.c | 133 ++++++++++++++++++++++++++++++++
|
||||
1 file changed, 133 insertions(+)
|
||||
|
||||
--- a/drivers/thermal/sun8i_thermal.c
|
||||
+++ b/drivers/thermal/sun8i_thermal.c
|
||||
@@ -59,6 +59,12 @@
|
||||
#define SUN50I_H6_THS_PC_TEMP_PERIOD(x) ((GENMASK(19, 0) & (x)) << 12)
|
||||
#define SUN50I_H6_THS_DATA_IRQ_STS(x) BIT(x)
|
||||
|
||||
+#define SUN55I_A523_DELIMITER 0x7c8
|
||||
+#define SUN55I_A523_OFFSET_ABOVE 2736
|
||||
+#define SUN55I_A523_OFFSET_BELOW 2825
|
||||
+#define SUN55I_A523_SCALE_ABOVE 74
|
||||
+#define SUN55I_A523_SCALE_BELOW 65
|
||||
+
|
||||
struct tsensor {
|
||||
struct ths_device *tmdev;
|
||||
struct thermal_zone_device *tzd;
|
||||
@@ -116,6 +122,15 @@ static int sun50i_h5_calc_temp(struct th
|
||||
return -1590 * reg / 10 + 276000;
|
||||
}
|
||||
|
||||
+static int sun55i_a523_calc_temp(struct ths_device *tmdev,
|
||||
+ int id, int reg)
|
||||
+{
|
||||
+ if (reg >= SUN55I_A523_DELIMITER)
|
||||
+ return SUN55I_A523_SCALE_ABOVE * (SUN55I_A523_OFFSET_ABOVE - reg);
|
||||
+ else
|
||||
+ return SUN55I_A523_SCALE_BELOW * (SUN55I_A523_OFFSET_BELOW - reg);
|
||||
+}
|
||||
+
|
||||
static int sun8i_ths_get_temp(struct thermal_zone_device *tz, int *temp)
|
||||
{
|
||||
struct tsensor *s = thermal_zone_device_priv(tz);
|
||||
@@ -301,6 +316,97 @@ static int sun50i_h6_ths_calibrate(struc
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * The A523 nvmem calibration values. The ths1_3 is not used as it
|
||||
+ * doesn't have its own sensor and doesn't have any internal switch.
|
||||
+ * Instead, the value from the ths1_2 sensor is used, which gives the
|
||||
+ * illusion of an independent sensor for NPU and GPU when using
|
||||
+ * different calibration values.
|
||||
+ *
|
||||
+ * efuse layout 0x38-0x3F (caldata[0..3]):
|
||||
+ * caldata[0] caldata[1] caldata[2] caldata[3]
|
||||
+ * 0 16 24 32 36 48 60 64
|
||||
+ * +---------------+---------------+---------------+---------------+
|
||||
+ * | | | temp | ths1_0 | ths1_1 | +
|
||||
+ * +---------------+---------------+---------------+---------------+
|
||||
+ *
|
||||
+ * efuse layout 0x44-0x4B (caldata[4..7]):
|
||||
+ * caldata[4] caldata[5] caldata[6] caldata[7]
|
||||
+ * 0 12 16 24 32 36 48 64
|
||||
+ * +---------------+---------------+---------------+---------------+
|
||||
+ * | ths1_2 | ths1_3 | ths0 | | +
|
||||
+ * +---------------+---------------+---------------+---------------+
|
||||
+ */
|
||||
+static int sun55i_a523_ths_calibrate(struct ths_device *tmdev,
|
||||
+ u16 *caldata, int callen)
|
||||
+{
|
||||
+ struct device *dev = tmdev->dev;
|
||||
+ int i, ft_temp;
|
||||
+
|
||||
+ if (!caldata[0])
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ft_temp = (((caldata[2] << 8) | (caldata[1] >> 8)) & FT_TEMP_MASK) * 100;
|
||||
+
|
||||
+ for (i = 0; i < tmdev->chip->sensor_num; i++) {
|
||||
+ int sensor_reg, sensor_temp, cdata, offset;
|
||||
+ /*
|
||||
+ * Chips ths0 and ths1 have common parameters for value
|
||||
+ * calibration. To separate them we can use the number of
|
||||
+ * temperature sensors on each chip.
|
||||
+ * For ths0 this value is 1.
|
||||
+ */
|
||||
+ if (tmdev->chip->sensor_num == 1) {
|
||||
+ sensor_reg = ((caldata[5] >> 8) | (caldata[6] << 8)) & TEMP_CALIB_MASK;
|
||||
+ } else {
|
||||
+ switch (i) {
|
||||
+ case 0:
|
||||
+ sensor_reg = (caldata[2] >> 4) & TEMP_CALIB_MASK;
|
||||
+ break;
|
||||
+ case 1:
|
||||
+ sensor_reg = caldata[3] & TEMP_CALIB_MASK;
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ sensor_reg = caldata[4] & TEMP_CALIB_MASK;
|
||||
+ break;
|
||||
+ default:
|
||||
+ sensor_reg = 0;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ sensor_temp = tmdev->chip->calc_temp(tmdev, i, sensor_reg);
|
||||
+
|
||||
+ /*
|
||||
+ * Calibration data is CALIBRATE_DEFAULT - (calculated
|
||||
+ * temperature from sensor reading at factory temperature
|
||||
+ * minus actual factory temperature) * X (scale from
|
||||
+ * temperature to register values)
|
||||
+ */
|
||||
+ cdata = CALIBRATE_DEFAULT -
|
||||
+ ((sensor_temp - ft_temp) / SUN55I_A523_SCALE_ABOVE);
|
||||
+
|
||||
+ if (cdata & ~TEMP_CALIB_MASK) {
|
||||
+ /*
|
||||
+ * Calibration value more than 12-bit, but calibration
|
||||
+ * register is 12-bit. In this case, ths hardware can
|
||||
+ * still work without calibration, although the data
|
||||
+ * won't be so accurate.
|
||||
+ */
|
||||
+ dev_warn(dev, "sensor%d is not calibrated.\n", i);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ offset = (i % 2) * 16;
|
||||
+ regmap_update_bits(tmdev->regmap,
|
||||
+ SUN50I_H6_THS_TEMP_CALIB + (i / 2 * 4),
|
||||
+ TEMP_CALIB_MASK << offset,
|
||||
+ cdata << offset);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int sun8i_ths_calibrate(struct ths_device *tmdev)
|
||||
{
|
||||
struct nvmem_cell *calcell = NULL;
|
||||
@@ -730,6 +836,31 @@ static const struct ths_thermal_chip sun
|
||||
.calc_temp = sun8i_ths_calc_temp,
|
||||
};
|
||||
|
||||
+/* The A523 has a shared reset line for both chips */
|
||||
+static const struct ths_thermal_chip sun55i_a523_ths0 = {
|
||||
+ .sensor_num = 1,
|
||||
+ .has_bus_clk_reset = true,
|
||||
+ .has_gpadc_clk = true,
|
||||
+ .ft_deviation = 5000,
|
||||
+ .temp_data_base = SUN50I_H6_THS_TEMP_DATA,
|
||||
+ .calibrate = sun55i_a523_ths_calibrate,
|
||||
+ .init = sun50i_h6_thermal_init,
|
||||
+ .irq_ack = sun50i_h6_irq_ack,
|
||||
+ .calc_temp = sun55i_a523_calc_temp,
|
||||
+};
|
||||
+
|
||||
+static const struct ths_thermal_chip sun55i_a523_ths1 = {
|
||||
+ .sensor_num = 3,
|
||||
+ .has_bus_clk_reset = true,
|
||||
+ .has_gpadc_clk = true,
|
||||
+ .ft_deviation = 5000,
|
||||
+ .temp_data_base = SUN50I_H6_THS_TEMP_DATA,
|
||||
+ .calibrate = sun55i_a523_ths_calibrate,
|
||||
+ .init = sun50i_h6_thermal_init,
|
||||
+ .irq_ack = sun50i_h6_irq_ack,
|
||||
+ .calc_temp = sun55i_a523_calc_temp,
|
||||
+};
|
||||
+
|
||||
static const struct of_device_id of_ths_match[] = {
|
||||
{ .compatible = "allwinner,sun8i-a83t-ths", .data = &sun8i_a83t_ths },
|
||||
{ .compatible = "allwinner,sun8i-h3-ths", .data = &sun8i_h3_ths },
|
||||
@@ -740,6 +871,8 @@ static const struct of_device_id of_ths_
|
||||
{ .compatible = "allwinner,sun50i-h6-ths", .data = &sun50i_h6_ths },
|
||||
{ .compatible = "allwinner,sun20i-d1-ths", .data = &sun20i_d1_ths },
|
||||
{ .compatible = "allwinner,sun50i-h616-ths", .data = &sun50i_h616_ths },
|
||||
+ { .compatible = "allwinner,sun55i-a523-ths0", .data = &sun55i_a523_ths0 },
|
||||
+ { .compatible = "allwinner,sun55i-a523-ths1", .data = &sun55i_a523_ths1 },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_ths_match);
|
||||
+264
@@ -0,0 +1,264 @@
|
||||
From git@z Thu Jan 1 00:00:00 1970
|
||||
Subject: [PATCH v3 6/6] Allwinner: A523: add support for A523 THS0/1
|
||||
controllers
|
||||
From: Mikhail Kalashnikov <iuncuim@gmail.com>
|
||||
Date: Sat, 25 Oct 2025 12:31:29 +0800
|
||||
Message-Id: <20251025043129.160454-7-iuncuim@gmail.com>
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
The A523 processor has two temperature controllers, THS0 and THS1.
|
||||
THS0 has only one temperature sensor, which is located in the DRAM.
|
||||
|
||||
THS1 does have 3 sensors:
|
||||
ths1_0 - "big" cores
|
||||
ths1_1 - "little" cores
|
||||
ths1_2 - gpu
|
||||
|
||||
Add the thermal sensor configuration and the thermal zones.
|
||||
Trips temperature, polling-delay and sustainable-power parameters are
|
||||
derived from the manufacturer's BSP.
|
||||
|
||||
Signed-off-by: Mikhail Kalashnikov <iuncuim@gmail.com>
|
||||
---
|
||||
.../arm64/boot/dts/allwinner/sun55i-a523.dtsi | 154 ++++++++++++++++++
|
||||
1 file changed, 154 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <dt-bindings/reset/sun55i-a523-r-ccu.h>
|
||||
#include <dt-bindings/power/allwinner,sun55i-a523-ppu.h>
|
||||
#include <dt-bindings/power/allwinner,sun55i-a523-pck-600.h>
|
||||
+#include <dt-bindings/thermal/thermal.h>
|
||||
|
||||
/ {
|
||||
interrupt-parent = <&gic>;
|
||||
@@ -26,6 +27,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <0x000>;
|
||||
enable-method = "psci";
|
||||
+ #cooling-cells = <2>;
|
||||
};
|
||||
|
||||
cpu1: cpu@100 {
|
||||
@@ -33,6 +35,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <0x100>;
|
||||
enable-method = "psci";
|
||||
+ #cooling-cells = <2>;
|
||||
};
|
||||
|
||||
cpu2: cpu@200 {
|
||||
@@ -40,6 +43,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <0x200>;
|
||||
enable-method = "psci";
|
||||
+ #cooling-cells = <2>;
|
||||
};
|
||||
|
||||
cpu3: cpu@300 {
|
||||
@@ -47,6 +51,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <0x300>;
|
||||
enable-method = "psci";
|
||||
+ #cooling-cells = <2>;
|
||||
};
|
||||
|
||||
cpu4: cpu@400 {
|
||||
@@ -54,6 +59,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <0x400>;
|
||||
enable-method = "psci";
|
||||
+ #cooling-cells = <2>;
|
||||
};
|
||||
|
||||
cpu5: cpu@500 {
|
||||
@@ -61,6 +67,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <0x500>;
|
||||
enable-method = "psci";
|
||||
+ #cooling-cells = <2>;
|
||||
};
|
||||
|
||||
cpu6: cpu@600 {
|
||||
@@ -68,6 +75,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <0x600>;
|
||||
enable-method = "psci";
|
||||
+ #cooling-cells = <2>;
|
||||
};
|
||||
|
||||
cpu7: cpu@700 {
|
||||
@@ -75,6 +83,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <0x700>;
|
||||
enable-method = "psci";
|
||||
+ #cooling-cells = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -508,12 +517,46 @@
|
||||
#dma-cells = <1>;
|
||||
};
|
||||
|
||||
+ ths1: thermal-sensor@2009400 {
|
||||
+ compatible = "allwinner,sun55i-a523-ths1";
|
||||
+ reg = <0x02009400 0x400>;
|
||||
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_GPADC1>;
|
||||
+ clock-names = "bus", "gpadc";
|
||||
+ resets = <&ccu RST_BUS_THS>;
|
||||
+ nvmem-cells = <&ths_calibration0>, <&ths_calibration1>;
|
||||
+ nvmem-cell-names = "calibration",
|
||||
+ "calibration-second-part";
|
||||
+ #thermal-sensor-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ ths0: thermal-sensor@200a000 {
|
||||
+ compatible = "allwinner,sun55i-a523-ths0";
|
||||
+ reg = <0x0200a000 0x400>;
|
||||
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_GPADC0>;
|
||||
+ clock-names = "bus", "gpadc";
|
||||
+ resets = <&ccu RST_BUS_THS>;
|
||||
+ nvmem-cells = <&ths_calibration0>, <&ths_calibration1>;
|
||||
+ nvmem-cell-names = "calibration",
|
||||
+ "calibration-second-part";
|
||||
+ #thermal-sensor-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
sid: efuse@3006000 {
|
||||
compatible = "allwinner,sun55i-a523-sid",
|
||||
"allwinner,sun50i-a64-sid";
|
||||
reg = <0x03006000 0x1000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
+
|
||||
+ ths_calibration0: ths-calibration0@38 {
|
||||
+ reg = <0x38 0x8>;
|
||||
+ };
|
||||
+
|
||||
+ ths_calibration1: ths-calibration1@44 {
|
||||
+ reg = <0x44 0x8>;
|
||||
+ };
|
||||
};
|
||||
|
||||
gic: interrupt-controller@3400000 {
|
||||
@@ -1030,4 +1073,115 @@
|
||||
power-domains = <&ppu PD_NPU>;
|
||||
};
|
||||
};
|
||||
+
|
||||
+ thermal-zones {
|
||||
+ cpu0_thermal: cpu0-thermal {
|
||||
+ polling-delay-passive = <100>;
|
||||
+ polling-delay = <1000>;
|
||||
+ thermal-sensors = <&ths1 1>;
|
||||
+ sustainable-power = <1200>;
|
||||
+
|
||||
+ trips {
|
||||
+ cpu0_threshold: cpu-trip-0 {
|
||||
+ temperature = <70000>;
|
||||
+ type = "passive";
|
||||
+ hysteresis = <0>;
|
||||
+ };
|
||||
+ cpu0_target: cpu-trip-1 {
|
||||
+ temperature = <90000>;
|
||||
+ type = "passive";
|
||||
+ hysteresis = <0>;
|
||||
+ };
|
||||
+ cpu0_critical: cpu-trip-2 {
|
||||
+ temperature = <110000>;
|
||||
+ type = "critical";
|
||||
+ hysteresis = <0>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ cooling-maps {
|
||||
+ map0 {
|
||||
+ trip = <&cpu0_target>;
|
||||
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
|
||||
+ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
|
||||
+ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
|
||||
+ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ cpu4_thermal: cpu4-thermal {
|
||||
+ polling-delay-passive = <100>;
|
||||
+ polling-delay = <1000>;
|
||||
+ thermal-sensors = <&ths1 0>;
|
||||
+ sustainable-power = <1600>;
|
||||
+
|
||||
+ trips {
|
||||
+ cpu4_threshold: cpu-trip-0 {
|
||||
+ temperature = <70000>;
|
||||
+ type = "passive";
|
||||
+ hysteresis = <0>;
|
||||
+ };
|
||||
+ cpu4_target: cpu-trip-1 {
|
||||
+ temperature = <90000>;
|
||||
+ type = "passive";
|
||||
+ hysteresis = <0>;
|
||||
+ };
|
||||
+ cpu4_critical: cpu-trip-2 {
|
||||
+ temperature = <110000>;
|
||||
+ type = "critical";
|
||||
+ hysteresis = <0>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ cooling-maps {
|
||||
+ map0 {
|
||||
+ trip = <&cpu4_target>;
|
||||
+ cooling-device = <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
|
||||
+ <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
|
||||
+ <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
|
||||
+ <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ gpu-thermal {
|
||||
+ polling-delay-passive = <100>;
|
||||
+ polling-delay = <1000>;
|
||||
+ thermal-sensors = <&ths1 2>;
|
||||
+ sustainable-power = <2400>;
|
||||
+
|
||||
+ gpu-trips {
|
||||
+ gpu_temp_threshold: gpu-trip-0 {
|
||||
+ temperature = <60000>;
|
||||
+ type = "passive";
|
||||
+ hysteresis = <0>;
|
||||
+ };
|
||||
+ gpu_temp_target: gpu-trip-1 {
|
||||
+ temperature = <90000>;
|
||||
+ type = "passive";
|
||||
+ hysteresis = <0>;
|
||||
+ };
|
||||
+ gpu_temp_critical: gpu-trip-2 {
|
||||
+ temperature = <110000>;
|
||||
+ type = "critical";
|
||||
+ hysteresis = <0>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ ddr-thermal {
|
||||
+ polling-delay-passive = <0>;
|
||||
+ polling-delay = <0>;
|
||||
+ thermal-sensors = <&ths0>;
|
||||
+
|
||||
+ trips {
|
||||
+ ddr_temp_critical: ddr-trip-0 {
|
||||
+ temperature = <110000>;
|
||||
+ type = "critical";
|
||||
+ hysteresis = <0>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
From git@z Thu Jan 1 00:00:00 1970
|
||||
Subject: [PATCH RFC 5/5] arm64: dts: allwinner: a523: Mark dual-phased
|
||||
regulators
|
||||
From: Andre Przywara <andre.przywara@arm.com>
|
||||
Date: Fri, 19 Sep 2025 01:00:20 +0100
|
||||
Message-Id: <20250919000020.16969-6-andre.przywara@arm.com>
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
The X-Powers AXP323 PMIC on the boards with a SoC from the Allwinner
|
||||
A523 family typically uses DCDC1 and DCDC2 in a dual-phase setup to
|
||||
supply the "big" CPU cluster. For some reason this dual-phase
|
||||
configuration is not the PMIC's reset default, but needs to be actively
|
||||
programmed at runtime.
|
||||
|
||||
Add the newly introduced x-powers,polyphased property in the board DTs,
|
||||
to mark this connection and let drivers program the dual-phase setup.
|
||||
|
||||
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts | 5 ++++-
|
||||
arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dts | 5 ++++-
|
||||
arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts | 5 ++++-
|
||||
arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dts | 5 ++++-
|
||||
4 files changed, 16 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts
|
||||
@@ -320,9 +320,12 @@
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <1160000>;
|
||||
regulator-name = "vdd-cpub";
|
||||
+ x-powers,polyphased = <®_dcdc2_323>;
|
||||
};
|
||||
|
||||
- /* DCDC2 is polyphased with DCDC1 */
|
||||
+ reg_dcdc2_323: dcdc2 {
|
||||
+ /* dual-phased with DCDC1 */
|
||||
+ };
|
||||
|
||||
/* RISC-V management core supply */
|
||||
reg_dcdc3_323: dcdc3 {
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dts
|
||||
@@ -252,9 +252,12 @@
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <1160000>;
|
||||
regulator-name = "vdd-cpub";
|
||||
+ x-powers,polyphased = <®_dcdc2_323>;
|
||||
};
|
||||
|
||||
- /* DCDC2 is polyphased with DCDC1 */
|
||||
+ reg_dcdc2_323: dcdc2 {
|
||||
+ /* dual-phased with DCDC1 */
|
||||
+ };
|
||||
|
||||
reg_dcdc3_323: dcdc3 {
|
||||
regulator-always-on;
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts
|
||||
@@ -308,9 +308,12 @@
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <1160000>;
|
||||
regulator-name = "vdd-cpub";
|
||||
+ x-powers,polyphased = <®_dcdc2_323>;
|
||||
};
|
||||
|
||||
- /* DCDC2 is polyphased with DCDC1 */
|
||||
+ reg_dcdc2_323: dcdc2 {
|
||||
+ /* dual-phased with DCDC1 */
|
||||
+ };
|
||||
|
||||
/* Some RISC-V management core related voltage */
|
||||
reg_dcdc3_323: dcdc3 {
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dts
|
||||
@@ -345,9 +345,12 @@
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <1150000>;
|
||||
regulator-name = "vdd-cpub";
|
||||
+ x-powers,polyphased = <®_dcdc2_323>;
|
||||
};
|
||||
|
||||
- /* DCDC2 is polyphased with DCDC1 */
|
||||
+ reg_dcdc2_323: dcdc2 {
|
||||
+ /* dual-phased with DCDC1 */
|
||||
+ };
|
||||
|
||||
/* Some RISC-V management core related voltage */
|
||||
reg_dcdc3_323: dcdc3 {
|
||||
+264
@@ -0,0 +1,264 @@
|
||||
--- /dev/null
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun55i-a523-cpu-opp.dtsi
|
||||
@@ -0,0 +1,173 @@
|
||||
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
+
|
||||
+/ {
|
||||
+ cpu0_opp_table: opp-table-cluster0 {
|
||||
+ compatible = "operating-points-v2";
|
||||
+ opp-shared;
|
||||
+
|
||||
+ opp-408000000 {
|
||||
+ opp-hz = /bits/ 64 <408000000>;
|
||||
+ opp-microvolt = <900000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp-672000000 {
|
||||
+ opp-hz = /bits/ 64 <672000000>;
|
||||
+ opp-microvolt = <900000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp-792000000 {
|
||||
+ opp-hz = /bits/ 64 <792000000>;
|
||||
+ opp-microvolt = <900000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp-936000000 {
|
||||
+ opp-hz = /bits/ 64 <936000000>;
|
||||
+ opp-microvolt = <920000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp-1008000000 {
|
||||
+ opp-hz = /bits/ 64 <1008000000>;
|
||||
+ opp-microvolt = <920000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp-1104000000 {
|
||||
+ opp-hz = /bits/ 64 <1104000000>;
|
||||
+ opp-microvolt = <960000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp-1224000000 {
|
||||
+ opp-hz = /bits/ 64 <1224000000>;
|
||||
+ opp-microvolt = <1000000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp-1320000000 {
|
||||
+ opp-hz = /bits/ 64 <1320000000>;
|
||||
+ opp-microvolt = <1050000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp-1416000000 {
|
||||
+ opp-hz = /bits/ 64 <1416000000>;
|
||||
+ opp-microvolt = <1100000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ cpu1_opp_table: opp-table-cluster1 {
|
||||
+ compatible = "operating-points-v2";
|
||||
+ opp-shared;
|
||||
+
|
||||
+ opp-408000000 {
|
||||
+ opp-hz = /bits/ 64 <408000000>;
|
||||
+ opp-microvolt = <900000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp-672000000 {
|
||||
+ opp-hz = /bits/ 64 <672000000>;
|
||||
+ opp-microvolt = <900000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp-840000000 {
|
||||
+ opp-hz = /bits/ 64 <840000000>;
|
||||
+ opp-microvolt = <900000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp-1008000000 {
|
||||
+ opp-hz = /bits/ 64 <1008000000>;
|
||||
+ opp-microvolt = <900000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp-1200000000 {
|
||||
+ opp-hz = /bits/ 64 <1200000000>;
|
||||
+ opp-microvolt = <920000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp-1344000000 {
|
||||
+ opp-hz = /bits/ 64 <1344000000>;
|
||||
+ opp-microvolt = <960000>; //fixme
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp-1488000000 {
|
||||
+ opp-hz = /bits/ 64 <1488000000>;
|
||||
+ opp-microvolt = <1000000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp-1584000000 {
|
||||
+ opp-hz = /bits/ 64 <1584000000>;
|
||||
+ opp-microvolt = <1050000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp-1680000000 {
|
||||
+ opp-hz = /bits/ 64 <1680000000>;
|
||||
+ opp-microvolt = <1100000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp-1800000000 {
|
||||
+ opp-hz = /bits/ 64 <1800000000>;
|
||||
+ opp-microvolt = <1150000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp-1992000000 {
|
||||
+ opp-hz = /bits/ 64 <1992000000>;
|
||||
+ opp-microvolt = <1220000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&cpu0 {
|
||||
+ capacity-dmips-mhz = <5>;
|
||||
+ operating-points-v2 = <&cpu0_opp_table>;
|
||||
+};
|
||||
+
|
||||
+&cpu1 {
|
||||
+ capacity-dmips-mhz = <5>;
|
||||
+ operating-points-v2 = <&cpu0_opp_table>;
|
||||
+};
|
||||
+
|
||||
+&cpu2 {
|
||||
+ capacity-dmips-mhz = <5>;
|
||||
+ operating-points-v2 = <&cpu0_opp_table>;
|
||||
+};
|
||||
+
|
||||
+&cpu3 {
|
||||
+ capacity-dmips-mhz = <5>;
|
||||
+ operating-points-v2 = <&cpu0_opp_table>;
|
||||
+};
|
||||
+
|
||||
+&cpu4 {
|
||||
+ capacity-dmips-mhz = <9>;
|
||||
+ operating-points-v2 = <&cpu1_opp_table>;
|
||||
+};
|
||||
+
|
||||
+&cpu5 {
|
||||
+ capacity-dmips-mhz = <9>;
|
||||
+ operating-points-v2 = <&cpu1_opp_table>;
|
||||
+};
|
||||
+
|
||||
+&cpu6 {
|
||||
+ capacity-dmips-mhz = <9>;
|
||||
+ operating-points-v2 = <&cpu1_opp_table>;
|
||||
+};
|
||||
+
|
||||
+&cpu7 {
|
||||
+ capacity-dmips-mhz = <9>;
|
||||
+ operating-points-v2 = <&cpu1_opp_table>;
|
||||
+};
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/clock/sun6i-rtc.h>
|
||||
#include <dt-bindings/clock/sun55i-a523-ccu.h>
|
||||
+#include <dt-bindings/clock/sun55i-a523-ccu-cpu.h>
|
||||
#include <dt-bindings/clock/sun55i-a523-mcu-ccu.h>
|
||||
#include <dt-bindings/clock/sun55i-a523-r-ccu.h>
|
||||
#include <dt-bindings/reset/sun55i-a523-ccu.h>
|
||||
@@ -27,6 +28,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <0x000>;
|
||||
enable-method = "psci";
|
||||
+ clocks = <&ccu_cpu CLK_CPUL>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
|
||||
@@ -35,6 +37,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <0x100>;
|
||||
enable-method = "psci";
|
||||
+ clocks = <&ccu_cpu CLK_CPUL>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
|
||||
@@ -43,6 +46,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <0x200>;
|
||||
enable-method = "psci";
|
||||
+ clocks = <&ccu_cpu CLK_CPUL>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
|
||||
@@ -51,6 +55,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <0x300>;
|
||||
enable-method = "psci";
|
||||
+ clocks = <&ccu_cpu CLK_CPUL>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
|
||||
@@ -59,6 +64,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <0x400>;
|
||||
enable-method = "psci";
|
||||
+ clocks = <&ccu_cpu CLK_CPUB>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
|
||||
@@ -67,6 +73,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <0x500>;
|
||||
enable-method = "psci";
|
||||
+ clocks = <&ccu_cpu CLK_CPUB>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
|
||||
@@ -75,6 +82,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <0x600>;
|
||||
enable-method = "psci";
|
||||
+ clocks = <&ccu_cpu CLK_CPUB>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
|
||||
@@ -83,6 +91,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <0x700>;
|
||||
enable-method = "psci";
|
||||
+ clocks = <&ccu_cpu CLK_CPUB>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
};
|
||||
@@ -622,6 +631,13 @@
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
+ ccu_cpu: clock@8817000 {
|
||||
+ compatible = "allwinner,sun55i-a523-ccu-cpu";
|
||||
+ reg = <0x08817000 0x4000>;
|
||||
+ #clock-cells = <1>;
|
||||
+ #reset-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
mmc2: mmc@4022000 {
|
||||
compatible = "allwinner,sun55i-a523-mmc",
|
||||
"allwinner,sun20i-d1-mmc";
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts
|
||||
@@ -4,6 +4,7 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include "sun55i-a523.dtsi"
|
||||
+#include "sun55i-a523-cpu-opp.dtsi"
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
@@ -15,6 +16,8 @@
|
||||
aliases {
|
||||
ethernet0 = &gmac0;
|
||||
ethernet1 = &gmac1;
|
||||
+ mmc0 = &mmc0;
|
||||
+ mmc1 = &mmc1;
|
||||
serial0 = &uart0;
|
||||
};
|
||||
|
||||
@@ -46,6 +49,16 @@
|
||||
<&axp717_adc 4>; /* pmic_temp */
|
||||
};
|
||||
|
||||
+ reg_3v3_wifi: 3v3-wifi {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "3v3-wifi";
|
||||
+ regulator-min-microvolt = <3300000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ vin-supply = <®_vcc5v>;
|
||||
+ gpio = <&r_pio 0 7 GPIO_ACTIVE_HIGH>; /* PL7 */
|
||||
+ enable-active-high;
|
||||
+ };
|
||||
+
|
||||
reg_vcc5v: vcc5v {
|
||||
/* board wide 5V supply from the USB-C connector */
|
||||
compatible = "regulator-fixed";
|
||||
@@ -66,6 +79,14 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&cpu0 {
|
||||
+ cpu-supply = <®_dcdc1>;
|
||||
+};
|
||||
+
|
||||
+&cpu4 {
|
||||
+ cpu-supply = <®_dcdc1_323>;
|
||||
+};
|
||||
+
|
||||
&ehci0 {
|
||||
status = "okay";
|
||||
};
|
||||
@@ -128,6 +149,23 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&mmc1 {
|
||||
+ vmmc-supply = <®_3v3_wifi>;
|
||||
+ bus-width = <4>;
|
||||
+ non-removable;
|
||||
+ // todo: investigate why clock above 40MHz makes data errors
|
||||
+ max-frequency = <15000000>;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ wlan: wifi@1 {
|
||||
+ reg = <1>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&mmc1_pins {
|
||||
+ drive-strength = <40>;
|
||||
+};
|
||||
+
|
||||
&ohci0 {
|
||||
status = "okay";
|
||||
};
|
||||
Reference in New Issue
Block a user