* [PATCH v2 15/16] arm64: dts: mediatek: mt8195-cherry: Add USB type-A connector
From: Chen-Yu Tsai @ 2026-06-10 8:40 UTC (permalink / raw)
To: Bartosz Golaszewski, Greg Kroah-Hartman, Andy Shevchenko,
Daniel Scally, Heikki Krogerus, Sakari Ailus, Rafael J. Wysocki,
Danilo Krummrich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno
Cc: Alan Stern, Chen-Yu Tsai, linux-acpi, driver-core, linux-pm,
linux-usb, devicetree, linux-mediatek, linux-arm-kernel,
linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260610084053.2059858-1-wenst@chromium.org>
The MT8195 Cherry design features a USB type-A connector for external
devices.
Add a proper representation for it with a node for the connector and
OF graph connection to the USB hub behind it.
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
.../boot/dts/mediatek/mt8195-cherry.dtsi | 73 ++++++++++++++++++-
1 file changed, 70 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
index c95a54de3567..8a21a8b996df 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
@@ -153,7 +153,6 @@ usb_vbus: regulator-5v0-usb-vbus {
compatible = "regulator-fixed";
regulator-name = "usb-vbus";
enable-active-high;
- regulator-always-on;
vin-supply = <&pp5000_s5>;
};
@@ -267,6 +266,32 @@ tboard_thermistor2: thermal-sensor-t2 {
125000 44>;
};
+ usb-a-connector {
+ compatible = "usb-a-connector";
+ vbus-supply = <&usb_vbus>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_a_u2_ep: endpoint {
+ remote-endpoint = <&usb2_hub_p3_ep>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usb_a_u3_ep: endpoint {
+ remote-endpoint = <&usb3_hub_p3_ep>;
+ };
+ };
+ };
+ };
+
wifi-bt-connector {
compatible = "pcie-m2-e-connector";
pinctrl-names = "default";
@@ -1672,13 +1697,55 @@ vdosys1_ep_ext: endpoint@1 {
&xhci0 {
rx-fifo-depth = <3072>;
- vbus-supply = <&usb_vbus>;
+ #address-cells = <1>;
+ #size-cells = <0>;
vusb33-supply = <&mt6359_vusb_ldo_reg>;
status = "okay";
+
+ usb3_hub: usb-hub@1 {
+ compatible = "usb5e3,620";
+ reg = <1>;
+ reset-gpios = <&pio 84 GPIO_ACTIVE_LOW>;
+ vdd-supply = <&pp5000_s5>;
+ peer-hub = <&usb2_hub>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@3 {
+ reg = <3>;
+
+ usb3_hub_p3_ep: endpoint {
+ remote-endpoint = <&usb_a_u3_ep>;
+ };
+ };
+ };
+ };
+
+ usb2_hub: usb-hub@2 {
+ compatible = "usb5e3,610";
+ reg = <2>;
+ reset-gpios = <&pio 84 GPIO_ACTIVE_LOW>;
+ vdd-supply = <&pp5000_s5>;
+ peer-hub = <&usb3_hub>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@3 {
+ reg = <3>;
+
+ usb2_hub_p3_ep: endpoint {
+ remote-endpoint = <&usb_a_u2_ep>;
+ };
+ };
+ };
+ };
};
&xhci2 {
- vbus-supply = <&usb_vbus>;
vusb33-supply = <&mt6359_vusb_ldo_reg>;
status = "okay";
};
--
2.54.0.1099.g489fc7bff1-goog
^ permalink raw reply related
* [PATCH v2 14/16] arm64: dts: mediatek: mt8195-cherry: Add M.2 E-key slot
From: Chen-Yu Tsai @ 2026-06-10 8:40 UTC (permalink / raw)
To: Bartosz Golaszewski, Greg Kroah-Hartman, Andy Shevchenko,
Daniel Scally, Heikki Krogerus, Sakari Ailus, Rafael J. Wysocki,
Danilo Krummrich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno
Cc: Alan Stern, Chen-Yu Tsai, linux-acpi, driver-core, linux-pm,
linux-usb, devicetree, linux-mediatek, linux-arm-kernel,
linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260610084053.2059858-1-wenst@chromium.org>
The Mt8195 Cherry design features an M.2 E-key slot for WiFi/BT combo
cards. Only PCIe and USB are wired from the SoC to the slot, along with
some auxiliary signals.
Add the proper representation for it, replacing the PCIe wifi node and
vpcie3v3-supply property under the PCIe controller, and the vbus-supply
property under the xhci3 node.
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
.../boot/dts/mediatek/mt8195-cherry.dtsi | 74 +++++++++++++++++--
1 file changed, 69 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
index ef7afc436aef..c95a54de3567 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
@@ -266,6 +266,47 @@ tboard_thermistor2: thermal-sensor-t2 {
120000 51
125000 44>;
};
+
+ wifi-bt-connector {
+ compatible = "pcie-m2-e-connector";
+ pinctrl-names = "default";
+ pinctrl-0 = <&m2_e_key_kill_pins>;
+ vpcie3v3-supply = <&pp3300_wlan>;
+ w-disable1-gpios = <&pio 61 GPIO_ACTIVE_LOW>;
+ w-disable2-gpios = <&pio 59 GPIO_ACTIVE_LOW>;
+ /* PCIe auxiliary signals wired to controller. */
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* PCIe for WiFi */
+ port@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ wifi_ep: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&pcie1_ep>;
+ };
+ };
+
+ /* USB for Bluetooth */
+ port@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bt_ep: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&usb3_ep>;
+ };
+ };
+
+ /* SDIO, UART and I2S not implemented */
+ };
+ };
};
&adsp {
@@ -791,14 +832,14 @@ pcie@0 {
reg = <0 0 0 0 0>;
device_type = "pci";
num-lanes = <1>;
- vpcie3v3-supply = <&pp3300_wlan>;
#address-cells = <3>;
#size-cells = <2>;
ranges;
- wifi@0 {
- reg = <0 0 0 0 0>;
- wakeup-source;
+ port {
+ pcie1_ep: endpoint {
+ remote-endpoint = <&wifi_ep>;
+ };
};
};
};
@@ -1085,6 +1126,14 @@ pins-bus {
};
};
+ m2_e_key_kill_pins: m2-e-key-kill-pins {
+ pins-kill {
+ pinmux = <PINMUX_GPIO61__FUNC_GPIO61>,
+ <PINMUX_GPIO59__FUNC_GPIO59>;
+ output-high;
+ };
+ };
+
mmc0_pins_default: mmc0-default-pins {
pins-cmd-dat {
pinmux = <PINMUX_GPIO126__FUNC_MSDC0_DAT0>,
@@ -1637,9 +1686,24 @@ &xhci2 {
&xhci3 {
/* MT7921's USB Bluetooth has issues with USB2 LPM */
usb2-lpm-disable;
- vbus-supply = <&pp3300_wlan>;
vusb33-supply = <&mt6359_vusb_ldo_reg>;
status = "okay";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb3_ep: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&bt_ep>;
+ };
+ };
+ };
};
#include <arm/cros-ec-keyboard.dtsi>
--
2.54.0.1099.g489fc7bff1-goog
^ permalink raw reply related
* [PATCH v2 13/16] arm64: dts: mediatek: mt8192-asurada: Add M.2 E-key slot
From: Chen-Yu Tsai @ 2026-06-10 8:40 UTC (permalink / raw)
To: Bartosz Golaszewski, Greg Kroah-Hartman, Andy Shevchenko,
Daniel Scally, Heikki Krogerus, Sakari Ailus, Rafael J. Wysocki,
Danilo Krummrich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno
Cc: Alan Stern, Chen-Yu Tsai, linux-acpi, driver-core, linux-pm,
linux-usb, devicetree, linux-mediatek, linux-arm-kernel,
linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260610084053.2059858-1-wenst@chromium.org>
The MT8192 Asurada design features an M.2 E-key slot for WiFi/BT combo
cards. Only PCIe and USB are wired from the SoC to the slot, along with
some auxiliary signals.
Add the proper representation for it, replacing the PCIe wifi node and
vpcie3v3-supply property under the PCIe controller. Also clean up the
pcie controller node.
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
.../boot/dts/mediatek/mt8192-asurada.dtsi | 65 +++++++++++++++++--
1 file changed, 58 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
index fb4d92750770..901240384a4a 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
@@ -318,6 +318,41 @@ usb_a_u3_ep: endpoint {
};
};
};
+
+ wifi-bt-connector {
+ compatible = "pcie-m2-e-connector";
+ pinctrl-names = "default";
+ pinctrl-0 = <&m2_e_key_kill_pins>;
+ vpcie3v3-supply = <&pp3300_wlan>;
+ w-disable1-gpios = <&pio 61 GPIO_ACTIVE_LOW>;
+ w-disable2-gpios = <&pio 59 GPIO_ACTIVE_LOW>;
+ /* PCIe auxiliary signals wired to controller. */
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* PCIe for WiFi */
+ port@0 {
+ reg = <0>;
+
+ wifi_ep: endpoint {
+ remote-endpoint = <&pcie_ep>;
+ };
+ };
+
+ /* USB for Bluetooth */
+ port@2 {
+ reg = <2>;
+
+ bt_ep: endpoint {
+ remote-endpoint = <&usb2_hub_p4_ep>;
+ };
+ };
+
+ /* SDIO, UART and I2S not implemented */
+ };
+ };
};
&afe {
@@ -671,19 +706,19 @@ &pcie {
pinctrl-0 = <&pcie_pins>;
memory-region = <&wifi_restricted_dma_region>;
- pcie0: pcie@0,0 {
+ pcie@0 {
+ compatible = "pciclass,0604";
+ reg = <0 0 0 0 0>;
device_type = "pci";
- reg = <0x0000 0 0 0 0>;
num-lanes = <1>;
- bus-range = <0x1 0x1>;
-
#address-cells = <3>;
#size-cells = <2>;
ranges;
- wifi: wifi@0,0 {
- reg = <0x10000 0 0 0 0x100000>,
- <0x10000 0 0x100000 0 0x100000>;
+ port {
+ pcie_ep: endpoint {
+ remote-endpoint = <&wifi_ep>;
+ };
};
};
};
@@ -1206,6 +1241,14 @@ pins-bus {
};
};
+ m2_e_key_kill_pins: m2-e-key-kill-pins {
+ pins-kill {
+ pinmux = <PINMUX_GPIO61__FUNC_GPIO61>,
+ <PINMUX_GPIO59__FUNC_GPIO59>;
+ output-high;
+ };
+ };
+
mmc0_default_pins: mmc0-default-pins {
pins-cmd-dat {
pinmux = <PINMUX_GPIO184__FUNC_MSDC0_DAT0>,
@@ -1773,6 +1816,14 @@ usb2_hub_p3_ep: endpoint {
remote-endpoint = <&usb_a_u2_ep>;
};
};
+
+ port@4 {
+ reg = <4>;
+
+ usb2_hub_p4_ep: endpoint {
+ remote-endpoint = <&bt_ep>;
+ };
+ };
};
};
};
--
2.54.0.1099.g489fc7bff1-goog
^ permalink raw reply related
* [PATCH v2 12/16] arm64: dts: mediatek: mt8192-asurada: Add USB type-A connector
From: Chen-Yu Tsai @ 2026-06-10 8:40 UTC (permalink / raw)
To: Bartosz Golaszewski, Greg Kroah-Hartman, Andy Shevchenko,
Daniel Scally, Heikki Krogerus, Sakari Ailus, Rafael J. Wysocki,
Danilo Krummrich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno
Cc: Alan Stern, Chen-Yu Tsai, linux-acpi, driver-core, linux-pm,
linux-usb, devicetree, linux-mediatek, linux-arm-kernel,
linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260610084053.2059858-1-wenst@chromium.org>
The MT8192 Asurada design features a USB type-A connector for external
devices.
Add a proper representation for it with a node for the connector and
OF graph connection to the USB hub behind it.
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
.../boot/dts/mediatek/mt8192-asurada.dtsi | 74 ++++++++++++++++++-
1 file changed, 71 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
index b7387075cb87..fb4d92750770 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
@@ -292,6 +292,32 @@ sound: sound {
pinctrl-24 = <&aud_gpio_tdm_off_pins>;
pinctrl-25 = <&aud_gpio_tdm_on_pins>;
};
+
+ usb-a-connector {
+ compatible = "usb-a-connector";
+ vbus-supply = <&pp5000_a>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ usb_a_u2_ep: endpoint {
+ remote-endpoint = <&usb2_hub_p3_ep>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ usb_a_u3_ep: endpoint {
+ remote-endpoint = <&usb3_hub_p3_ep>;
+ };
+ };
+ };
+ };
};
&afe {
@@ -1702,11 +1728,53 @@ &uart0 {
};
&xhci {
- status = "okay";
-
wakeup-source;
vusb33-supply = <&pp3300_g>;
- vbus-supply = <&pp5000_a>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ usb3_hub: usb-hub@1 {
+ compatible = "usb5e3,620";
+ reg = <1>;
+ reset-gpios = <&pio 44 GPIO_ACTIVE_LOW>;
+ vdd-supply = <&pp5000_a>;
+ peer-hub = <&usb2_hub>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@3 {
+ reg = <3>;
+
+ usb3_hub_p3_ep: endpoint {
+ remote-endpoint = <&usb_a_u3_ep>;
+ };
+ };
+ };
+ };
+
+ usb2_hub: usb-hub@2 {
+ compatible = "usb5e3,610";
+ reg = <2>;
+ reset-gpios = <&pio 44 GPIO_ACTIVE_LOW>;
+ vdd-supply = <&pp5000_a>;
+ peer-hub = <&usb3_hub>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@3 {
+ reg = <3>;
+
+ usb2_hub_p3_ep: endpoint {
+ remote-endpoint = <&usb_a_u2_ep>;
+ };
+ };
+ };
+ };
};
#include <arm/cros-ec-keyboard.dtsi>
--
2.54.0.1099.g489fc7bff1-goog
^ permalink raw reply related
* [PATCH v2 11/16] power: sequencing: pcie-m2: Add usb and sdio targets for E-key connector
From: Chen-Yu Tsai @ 2026-06-10 8:40 UTC (permalink / raw)
To: Bartosz Golaszewski, Greg Kroah-Hartman, Andy Shevchenko,
Daniel Scally, Heikki Krogerus, Sakari Ailus, Rafael J. Wysocki,
Danilo Krummrich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno
Cc: Alan Stern, Chen-Yu Tsai, linux-acpi, driver-core, linux-pm,
linux-usb, devicetree, linux-mediatek, linux-arm-kernel,
linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260610084053.2059858-1-wenst@chromium.org>
The M.2 E-key connector allows either PCIe or SDIO for WiFi and USB or
UART for BT. Currently the driver only supports PCIe and UART.
Add power sequencing targets for SDIO and USB. To avoid adding a
complicated dependency tree, rename the existing power sequencing units
"pcie" and "uart" to "wifi" and "bt". The existing target names are left
untouched. The new "sdio" and "usb" targets just point to the renamed
"wifi" and "bt" units.
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
drivers/power/sequencing/pwrseq-pcie-m2.c | 41 +++++++++++++++--------
1 file changed, 27 insertions(+), 14 deletions(-)
diff --git a/drivers/power/sequencing/pwrseq-pcie-m2.c b/drivers/power/sequencing/pwrseq-pcie-m2.c
index 49293376956b..a21a3dbe8a5d 100644
--- a/drivers/power/sequencing/pwrseq-pcie-m2.c
+++ b/drivers/power/sequencing/pwrseq-pcie-m2.c
@@ -70,46 +70,46 @@ static const struct pwrseq_unit_data *pwrseq_pcie_m2_unit_deps[] = {
NULL
};
-static int pwrseq_pci_m2_e_uart_enable(struct pwrseq_device *pwrseq)
+static int pwrseq_pci_m2_e_bt_enable(struct pwrseq_device *pwrseq)
{
struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
return gpiod_set_value_cansleep(ctx->w_disable2_gpio, 0);
}
-static int pwrseq_pci_m2_e_uart_disable(struct pwrseq_device *pwrseq)
+static int pwrseq_pci_m2_e_bt_disable(struct pwrseq_device *pwrseq)
{
struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
return gpiod_set_value_cansleep(ctx->w_disable2_gpio, 1);
}
-static const struct pwrseq_unit_data pwrseq_pcie_m2_e_uart_unit_data = {
- .name = "uart-enable",
+static const struct pwrseq_unit_data pwrseq_pcie_m2_e_bt_unit_data = {
+ .name = "bt-enable",
.deps = pwrseq_pcie_m2_unit_deps,
- .enable = pwrseq_pci_m2_e_uart_enable,
- .disable = pwrseq_pci_m2_e_uart_disable,
+ .enable = pwrseq_pci_m2_e_bt_enable,
+ .disable = pwrseq_pci_m2_e_bt_disable,
};
-static int pwrseq_pci_m2_e_pcie_enable(struct pwrseq_device *pwrseq)
+static int pwrseq_pci_m2_e_wifi_enable(struct pwrseq_device *pwrseq)
{
struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
return gpiod_set_value_cansleep(ctx->w_disable1_gpio, 0);
}
-static int pwrseq_pci_m2_e_pcie_disable(struct pwrseq_device *pwrseq)
+static int pwrseq_pci_m2_e_wifi_disable(struct pwrseq_device *pwrseq)
{
struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
return gpiod_set_value_cansleep(ctx->w_disable1_gpio, 1);
}
-static const struct pwrseq_unit_data pwrseq_pcie_m2_e_pcie_unit_data = {
- .name = "pcie-enable",
+static const struct pwrseq_unit_data pwrseq_pcie_m2_e_wifi_unit_data = {
+ .name = "wifi-enable",
.deps = pwrseq_pcie_m2_unit_deps,
- .enable = pwrseq_pci_m2_e_pcie_enable,
- .disable = pwrseq_pci_m2_e_pcie_disable,
+ .enable = pwrseq_pci_m2_e_wifi_enable,
+ .disable = pwrseq_pci_m2_e_wifi_disable,
};
static const struct pwrseq_unit_data pwrseq_pcie_m2_m_pcie_unit_data = {
@@ -131,13 +131,24 @@ static int pwrseq_pcie_m2_e_pwup_delay(struct pwrseq_device *pwrseq)
static const struct pwrseq_target_data pwrseq_pcie_m2_e_uart_target_data = {
.name = "uart",
- .unit = &pwrseq_pcie_m2_e_uart_unit_data,
+ .unit = &pwrseq_pcie_m2_e_bt_unit_data,
.post_enable = pwrseq_pcie_m2_e_pwup_delay,
};
+static const struct pwrseq_target_data pwrseq_pcie_m2_e_usb_target_data = {
+ .name = "usb",
+ .unit = &pwrseq_pcie_m2_e_bt_unit_data,
+};
+
static const struct pwrseq_target_data pwrseq_pcie_m2_e_pcie_target_data = {
.name = "pcie",
- .unit = &pwrseq_pcie_m2_e_pcie_unit_data,
+ .unit = &pwrseq_pcie_m2_e_wifi_unit_data,
+ .post_enable = pwrseq_pcie_m2_e_pwup_delay,
+};
+
+static const struct pwrseq_target_data pwrseq_pcie_m2_e_sdio_target_data = {
+ .name = "sdio",
+ .unit = &pwrseq_pcie_m2_e_wifi_unit_data,
.post_enable = pwrseq_pcie_m2_e_pwup_delay,
};
@@ -148,7 +159,9 @@ static const struct pwrseq_target_data pwrseq_pcie_m2_m_pcie_target_data = {
static const struct pwrseq_target_data *pwrseq_pcie_m2_e_targets[] = {
&pwrseq_pcie_m2_e_pcie_target_data,
+ &pwrseq_pcie_m2_e_sdio_target_data,
&pwrseq_pcie_m2_e_uart_target_data,
+ &pwrseq_pcie_m2_e_usb_target_data,
NULL
};
--
2.54.0.1099.g489fc7bff1-goog
^ permalink raw reply related
* [PATCH v2 10/16] power: sequencing: pcie-m2: support matching on remote "port" node
From: Chen-Yu Tsai @ 2026-06-10 8:40 UTC (permalink / raw)
To: Bartosz Golaszewski, Greg Kroah-Hartman, Andy Shevchenko,
Daniel Scally, Heikki Krogerus, Sakari Ailus, Rafael J. Wysocki,
Danilo Krummrich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno
Cc: Alan Stern, Chen-Yu Tsai, linux-acpi, driver-core, linux-pm,
linux-usb, devicetree, linux-mediatek, linux-arm-kernel,
linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260610084053.2059858-1-wenst@chromium.org>
A USB hub can have multiple ports, and this driver needs to
differentiate which port is being matched to. The USB hub driver now
associates the "port" node with the usb_port device, so here we can
use the remote "port" node to check for a match. Then fall back to
the remote device node for the other connection types.
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
drivers/power/sequencing/pwrseq-pcie-m2.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/power/sequencing/pwrseq-pcie-m2.c b/drivers/power/sequencing/pwrseq-pcie-m2.c
index e82821655fc4..49293376956b 100644
--- a/drivers/power/sequencing/pwrseq-pcie-m2.c
+++ b/drivers/power/sequencing/pwrseq-pcie-m2.c
@@ -176,8 +176,17 @@ static int pwrseq_pcie_m2_match(struct pwrseq_device *pwrseq,
* parent matches the OF node of 'dev'.
*/
for_each_endpoint_of_node(ctx->of_node, endpoint) {
+ /* USB port devices are tied to the port nodes. */
+ struct device_node *remote_port __free(device_node) =
+ of_graph_get_remote_port(endpoint);
+
+ if (remote_port && remote_port == dev_of_node(dev))
+ return PWRSEQ_MATCH_OK;
+
+ /* Try the remote port parent for other types. */
struct device_node *remote __free(device_node) =
of_graph_get_remote_port_parent(endpoint);
+
if (remote && (remote == dev_of_node(dev)))
return PWRSEQ_MATCH_OK;
}
--
2.54.0.1099.g489fc7bff1-goog
^ permalink raw reply related
* [PATCH v2 09/16] dt-bindings: usb: mediatek,mtk-xhci: Allow ports for USB connections
From: Chen-Yu Tsai @ 2026-06-10 8:40 UTC (permalink / raw)
To: Bartosz Golaszewski, Greg Kroah-Hartman, Andy Shevchenko,
Daniel Scally, Heikki Krogerus, Sakari Ailus, Rafael J. Wysocki,
Danilo Krummrich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno
Cc: Alan Stern, Chen-Yu Tsai, linux-acpi, driver-core, linux-pm,
linux-usb, devicetree, linux-mediatek, linux-arm-kernel,
linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260610084053.2059858-1-wenst@chromium.org>
MediaTek's XHCI implementation supports both USB 2.0 High Speed (HS)
and USB 3.x Super Speed (SS). The block can also be synthesized with
either HS-only capability or HS+SS capability.
For example, on the MT8195, the first two instances support both HS and
SS, while the latter two instances support only HS.
Allow a ports sub-node for describing USB connections. Port 1 is Super
Speed if the controller is SS-capable, otherwise it is High Speed. Port
2 is High Speed if SS-capable. This port mapping scheme directly matches
what the hardware returns in its capability registers.
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
.../devicetree/bindings/usb/mediatek,mtk-xhci.yaml | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
index 75ecce3bdc7a..d6c75bd20b78 100644
--- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
+++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
@@ -184,6 +184,19 @@ properties:
"#size-cells":
const: 0
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ properties:
+ port@1:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: Super Speed (SS) data bus if SS-capable;
+ otherwise High Speed (HS) data bus.
+
+ port@2:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: High Speed (HS) data bus if controller is SS-capable.
+
patternProperties:
"@[0-9a-f]{1}$":
type: object
--
2.54.0.1099.g489fc7bff1-goog
^ permalink raw reply related
* [PATCH v2 08/16] Revert "dt-bindings: usb: mediatek,mtk-xhci: Add port for SuperSpeed EP"
From: Chen-Yu Tsai @ 2026-06-10 8:40 UTC (permalink / raw)
To: Bartosz Golaszewski, Greg Kroah-Hartman, Andy Shevchenko,
Daniel Scally, Heikki Krogerus, Sakari Ailus, Rafael J. Wysocki,
Danilo Krummrich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno
Cc: Alan Stern, Chen-Yu Tsai, linux-acpi, driver-core, linux-pm,
linux-usb, devicetree, linux-mediatek, linux-arm-kernel,
linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260610084053.2059858-1-wenst@chromium.org>
This reverts commit 454a1e3cd36c113341d7b71e8e691c6e47ab4a8a.
mtk-xhci handles both USB 2.0 High Speed (HS) and USB 3.x SuperSpeed
(SS) host connections. And there are USB 2.0 only mtk-xhci blocks.
The SSUSB controller handles the device or gadget mode. Saying that
SSUSB handles the HS portion is wrong.
Fixes: 454a1e3cd36c ("dt-bindings: usb: mediatek,mtk-xhci: Add port for SuperSpeed EP")
Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml | 4 ----
1 file changed, 4 deletions(-)
diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
index 231e6f35a986..75ecce3bdc7a 100644
--- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
+++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
@@ -107,10 +107,6 @@ properties:
- description: USB3/SS(P) PHY
- description: USB2/HS PHY
- port:
- $ref: /schemas/graph.yaml#/properties/port
- description: Super Speed (SS) Output endpoint to a Type-C connector
-
vusb33-supply:
description: Regulator of USB AVDD3.3v
--
2.54.0.1099.g489fc7bff1-goog
^ permalink raw reply related
* [PATCH v2 07/16] usb: hub: Power on connected M.2 E-key connectors
From: Chen-Yu Tsai @ 2026-06-10 8:40 UTC (permalink / raw)
To: Bartosz Golaszewski, Greg Kroah-Hartman, Andy Shevchenko,
Daniel Scally, Heikki Krogerus, Sakari Ailus, Rafael J. Wysocki,
Danilo Krummrich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno
Cc: Alan Stern, Chen-Yu Tsai, linux-acpi, driver-core, linux-pm,
linux-usb, devicetree, linux-mediatek, linux-arm-kernel,
linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260610084053.2059858-1-wenst@chromium.org>
The new M.2 E-key connector can have a USB connection. For the USB device
on this connector to work, its power must be enabled and the W_DISABLE2#
signal deasserted. The connector driver handles this and provides a
toggle over the power sequencing API.
This feature currently only supports a directly connected (no mux in
between) M.2 E-key connector. Existing USB connector types are not
covered. The USB A connector was recently added to the onboard devices
driver. USB B connectors have historically been managed by the USB
gadget or dual-role device controller drivers. USB C connectors are
handled by TCPM drivers.
The power sequencing API does not know whether a power sequence provider
is not needed or not available yet, so we only request it for connectors
that we know need it, which at this time is just the E-key connector.
On the USB side, the port firmware node (if present) is tied to the
usb_port device. This device is used to acquire the power sequencing
descriptor. This allows the provider to tell the different ports on one
hub apart.
This feature is not implemented in the onboard USB devices driver. The
power sequencing API expects the consumer device to make the request,
but there is no device node to instantiate a platform device to tie
the driver to. The connector is not a child node of the USB host or
hub, and the graph connection is from a USB port to the connector.
And the connector itself already has a driver.
Power sequencing is not directly enabled in the connector driver as
that would completely decouple the timing of it from the USB subsystem.
It would not be possible for the USB subsystem to toggle the power
for a power cycle or to disable the port.
This change depends on another change to make the power sequencing
framework bool instead of tristate. The USB core and hub driver are
bool, so if the power sequencing framework is built as a module, the
kernel will fail to link.
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
Changes since v1:
- Switch to fwnode instead of OF
- Tie port@ fwnode to usb_port device
- Move remote node compatible checking to separate helper
- Use usb_port device to request power sequencing descriptor
- Drop "index" parameter from pwrseq_get()
- Do not get pwrseq descriptor for SuperSpeed port; share one for one
physical port
- Add pwrseq state tracking
---
drivers/usb/core/hub.c | 38 ++++++++++++++++++++---
drivers/usb/core/hub.h | 4 +++
drivers/usb/core/port.c | 68 ++++++++++++++++++++++++++++++++++++++++-
3 files changed, 104 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 362a10f7eddb..9a9eb7e3e1fd 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -32,6 +32,7 @@
#include <linux/mutex.h>
#include <linux/random.h>
#include <linux/pm_qos.h>
+#include <linux/pwrseq/consumer.h>
#include <linux/kobject.h>
#include <linux/bitfield.h>
@@ -886,20 +887,41 @@ static void hub_tt_work(struct work_struct *work)
int usb_hub_set_port_power(struct usb_device *hdev, struct usb_hub *hub,
int port1, bool set)
{
- int ret;
+ struct usb_port *pwrseq_port = hub->ports[port1 - 1];
+ int ret = 0;
+
+ /* non-SuperSpeed USB port holds pwrseq descriptor reference. */
+ if (hub->ports[port1 - 1]->is_superspeed && hub->ports[port1 - 1]->peer)
+ pwrseq_port = hub->ports[port1 - 1]->peer;
+
+ if (set && !pwrseq_port->pwrseq_on)
+ ret = pwrseq_power_on(pwrseq_port->pwrseq);
+ else if (!set && pwrseq_port->pwrseq_on)
+ ret = pwrseq_power_off(pwrseq_port->pwrseq);
+ if (ret)
+ return ret;
if (set)
ret = set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
else
ret = usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
- if (ret)
+ if (ret) {
+ if (set && !pwrseq_port->pwrseq_on)
+ pwrseq_power_off(pwrseq_port->pwrseq);
+ else if (!set && pwrseq_port->pwrseq_on)
+ pwrseq_power_on(pwrseq_port->pwrseq);
return ret;
+ }
- if (set)
+ if (set) {
set_bit(port1, hub->power_bits);
- else
+ pwrseq_port->pwrseq_on = 1;
+ } else {
clear_bit(port1, hub->power_bits);
+ pwrseq_port->pwrseq_on = 0;
+ }
+
return 0;
}
@@ -3252,7 +3274,13 @@ int usb_port_is_power_on(struct usb_port *port, unsigned int portstatus)
ret = 1;
}
- return ret;
+ if (port->is_superspeed && port->peer)
+ port = port->peer;
+
+ if (!port->pwrseq)
+ return ret;
+
+ return ret && port->pwrseq_on;
}
static void usb_lock_port(struct usb_port *port_dev)
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
index b65d9192379d..a2ac91726c61 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -85,6 +85,7 @@ struct usb_hub {
* @port_owner: port's owner
* @peer: related usb2 and usb3 ports (share the same connector)
* @connector: USB Type-C connector
+ * @pwrseq: power sequencing descriptor for the port
* @req: default pm qos request for hubs without port power control
* @connect_type: port's connect type
* @state: device state of the usb device attached to the port
@@ -97,6 +98,7 @@ struct usb_hub {
* @usb3_lpm_u2_permit: whether USB3 U2 LPM is permitted.
* @early_stop: whether port initialization will be stopped earlier.
* @ignore_event: whether events of the port are ignored.
+ * @pwrseq_on: whether power sequencing is turned on.
*/
struct usb_port {
struct usb_device *child;
@@ -104,6 +106,7 @@ struct usb_port {
struct usb_dev_state *port_owner;
struct usb_port *peer;
struct typec_connector *connector;
+ struct pwrseq_desc *pwrseq;
struct dev_pm_qos_request *req;
enum usb_port_connect_type connect_type;
enum usb_device_state state;
@@ -118,6 +121,7 @@ struct usb_port {
unsigned int is_superspeed:1;
unsigned int usb3_lpm_u1_permit:1;
unsigned int usb3_lpm_u2_permit:1;
+ unsigned int pwrseq_on:1;
};
#define to_usb_port(_dev) \
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index d9d3e2bb8f25..a5e7fbf4aa6e 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -7,11 +7,14 @@
* Author: Lan Tianyu <tianyu.lan@intel.com>
*/
+#include <linux/cleanup.h>
#include <linux/kstrtox.h>
#include <linux/slab.h>
#include <linux/string_choices.h>
#include <linux/sysfs.h>
#include <linux/pm_qos.h>
+#include <linux/property.h>
+#include <linux/pwrseq/consumer.h>
#include <linux/component.h>
#include <linux/usb/of.h>
@@ -28,6 +31,9 @@ static bool usb_port_allow_power_off(struct usb_device *hdev,
if (hub_is_port_power_switchable(hub))
return true;
+ if (port_dev->pwrseq)
+ return true;
+
if (!IS_ENABLED(CONFIG_ACPI))
return false;
@@ -748,6 +754,43 @@ static const struct component_ops connector_ops = {
.unbind = connector_unbind,
};
+static bool port_pwrseq_is_supported(struct usb_port *port_dev)
+{
+ struct device *dev = &port_dev->dev;
+ struct fwnode_handle *port = dev->fwnode;
+ struct fwnode_handle *ep __free(fwnode_handle) =
+ fwnode_graph_get_next_port_endpoint(port, NULL);
+ if (!ep)
+ return false;
+
+ struct fwnode_handle *remote __free(fwnode_handle) =
+ fwnode_graph_get_remote_port_parent(ep);
+ if (!remote)
+ return false;
+
+ if (!fwnode_device_is_compatible(remote, "pcie-m2-e-connector")) {
+ dev_dbg(dev, "remote endpoint %pfw is not a supported connector", remote);
+ return false;
+ }
+
+ return true;
+}
+
+static struct pwrseq_desc *usb_hub_port_pwrseq_get(struct usb_port *port_dev)
+{
+ if (!IS_ENABLED(CONFIG_POWER_SEQUENCING))
+ return NULL;
+
+ /* A physical port should only have one pwrseq reference. */
+ if (port_dev->is_superspeed)
+ return NULL;
+
+ if (!port_pwrseq_is_supported(port_dev))
+ return NULL;
+
+ return pwrseq_get(&port_dev->dev, "usb");
+}
+
int usb_hub_create_port_device(struct usb_hub *hub, int port1)
{
struct usb_port *port_dev;
@@ -803,10 +846,25 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
goto err_put_kn;
}
+ port_dev->pwrseq = usb_hub_port_pwrseq_get(port_dev);
+ if (IS_ERR(port_dev->pwrseq)) {
+ retval = PTR_ERR(port_dev->pwrseq);
+ dev_err_probe(&port_dev->dev, retval,
+ "failed to get power sequencing descriptor\n");
+ goto err_put_kn;
+ }
+
+ retval = pwrseq_power_on(port_dev->pwrseq);
+ if (retval) {
+ dev_err_probe(&port_dev->dev, retval, "failed to enable power\n");
+ goto err_put_pwrseq;
+ }
+ port_dev->pwrseq_on = 1;
+
retval = component_add(&port_dev->dev, &connector_ops);
if (retval) {
dev_warn(&port_dev->dev, "failed to add component\n");
- goto err_put_kn;
+ goto err_pwrseq_off;
}
find_and_link_peer(hub, port1);
@@ -844,6 +902,11 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
}
return 0;
+err_pwrseq_off:
+ if (port_dev->pwrseq_on)
+ pwrseq_power_off(port_dev->pwrseq);
+err_put_pwrseq:
+ pwrseq_put(port_dev->pwrseq);
err_put_kn:
sysfs_put(port_dev->state_kn);
err_unregister:
@@ -860,6 +923,9 @@ void usb_hub_remove_port_device(struct usb_hub *hub, int port1)
peer = port_dev->peer;
if (peer)
unlink_peers(port_dev, peer);
+ if (port_dev->pwrseq_on)
+ pwrseq_power_off(port_dev->pwrseq);
+ pwrseq_put(port_dev->pwrseq);
component_del(&port_dev->dev, &connector_ops);
sysfs_put(port_dev->state_kn);
device_unregister(&port_dev->dev);
--
2.54.0.1099.g489fc7bff1-goog
^ permalink raw reply related
* [PATCH v2 06/16] usb: hub: Pass |struct usb_port*| to usb_port_is_power_on()
From: Chen-Yu Tsai @ 2026-06-10 8:40 UTC (permalink / raw)
To: Bartosz Golaszewski, Greg Kroah-Hartman, Andy Shevchenko,
Daniel Scally, Heikki Krogerus, Sakari Ailus, Rafael J. Wysocki,
Danilo Krummrich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno
Cc: Alan Stern, Chen-Yu Tsai, linux-acpi, driver-core, linux-pm,
linux-usb, devicetree, linux-mediatek, linux-arm-kernel,
linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260610084053.2059858-1-wenst@chromium.org>
usb_port_is_power_on() currently takes |struct usb_hub*|, but only needs
it to tell if the hub/port is SuperSpeed or not.
In a subsequent change, usb_port_is_power_on() needs access to a pwrseq
state tracking field in |struct usb_port|. Either structure can be used
to identify whether a port/hub is SuperSpeed or not, as the field in
|struct usb_port| is inherited from the hub:
port->is_superspeed = hub_is_superspeed(hub)
Replace usb_port_is_power_on()'s |struct usb_hub*| parameter with
|struct usb_port*| so a subsequent change can use it.
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
drivers/usb/core/hub.c | 11 ++++++-----
drivers/usb/core/hub.h | 2 +-
drivers/usb/core/port.c | 2 +-
3 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 985551d013b2..362a10f7eddb 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3240,11 +3240,11 @@ static bool hub_port_stop_enumerate(struct usb_hub *hub, int port1, int retries)
}
/* Check if a port is power on */
-int usb_port_is_power_on(struct usb_hub *hub, unsigned int portstatus)
+int usb_port_is_power_on(struct usb_port *port, unsigned int portstatus)
{
int ret = 0;
- if (hub_is_superspeed(hub->hdev)) {
+ if (port->is_superspeed) {
if (portstatus & USB_SS_PORT_STAT_POWER)
ret = 1;
} else {
@@ -3306,7 +3306,7 @@ static int check_port_resume_type(struct usb_device *udev,
}
/* Is the device still present? */
else if (status || port_is_suspended(hub, portstatus) ||
- !usb_port_is_power_on(hub, portstatus)) {
+ !usb_port_is_power_on(port_dev, portstatus)) {
if (status >= 0)
status = -ENODEV;
} else if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
@@ -3748,12 +3748,13 @@ static int wait_for_connected(struct usb_device *udev,
struct usb_hub *hub, int port1,
u16 *portchange, u16 *portstatus)
{
+ struct usb_port *port_dev = hub->ports[port1 - 1];
int status = 0, delay_ms = 0;
while (delay_ms < 2000) {
if (status || *portstatus & USB_PORT_STAT_CONNECTION)
break;
- if (!usb_port_is_power_on(hub, *portstatus)) {
+ if (!usb_port_is_power_on(port_dev, *portstatus)) {
status = -ENODEV;
break;
}
@@ -5449,7 +5450,7 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
* but only if the port isn't owned by someone else.
*/
if (hub_is_port_power_switchable(hub)
- && !usb_port_is_power_on(hub, portstatus)
+ && !usb_port_is_power_on(port_dev, portstatus)
&& !port_dev->port_owner)
set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
index 9ebc5ef54a32..b65d9192379d 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -138,7 +138,7 @@ extern int usb_clear_port_feature(struct usb_device *hdev,
int port1, int feature);
extern int usb_hub_port_status(struct usb_hub *hub, int port1,
u16 *status, u16 *change);
-extern int usb_port_is_power_on(struct usb_hub *hub, unsigned int portstatus);
+extern int usb_port_is_power_on(struct usb_port *port, unsigned int portstatus);
static inline bool hub_is_port_power_switchable(struct usb_hub *hub)
{
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 1846eb1206a4..d9d3e2bb8f25 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -97,7 +97,7 @@ static ssize_t disable_show(struct device *dev,
}
usb_hub_port_status(hub, port1, &portstatus, &unused);
- disabled = !usb_port_is_power_on(hub, portstatus);
+ disabled = !usb_port_is_power_on(port_dev, portstatus);
out_hdev_lock:
usb_unlock_device(hdev);
--
2.54.0.1099.g489fc7bff1-goog
^ permalink raw reply related
* [PATCH v2 05/16] usb: hub: Associate port@ fwnode with USB port device
From: Chen-Yu Tsai @ 2026-06-10 8:40 UTC (permalink / raw)
To: Bartosz Golaszewski, Greg Kroah-Hartman, Andy Shevchenko,
Daniel Scally, Heikki Krogerus, Sakari Ailus, Rafael J. Wysocki,
Danilo Krummrich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno
Cc: Alan Stern, Chen-Yu Tsai, linux-acpi, driver-core, linux-pm,
linux-usb, devicetree, linux-mediatek, linux-arm-kernel,
linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260610084053.2059858-1-wenst@chromium.org>
When a USB hub port is connected to a connector in a firmware node
graph, the port itself has a node in the graph.
Associate the port's firmware node with the USB port's device,
usb_port::dev. This is used in later changes for the M.2 slot power
sequencing provider to match against the requesting port.
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
drivers/usb/core/port.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index b1364f0c384c..1846eb1206a4 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -780,6 +780,8 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
port_dev->dev.driver = &usb_port_driver;
dev_set_name(&port_dev->dev, "%s-port%d", dev_name(&hub->hdev->dev),
port1);
+ device_set_node(&port_dev->dev,
+ fwnode_graph_get_port_by_id(dev_fwnode(&hdev->dev), port1));
mutex_init(&port_dev->status_lock);
retval = device_register(&port_dev->dev);
if (retval) {
--
2.54.0.1099.g489fc7bff1-goog
^ permalink raw reply related
* [PATCH v2 04/16] usb: hub: Return actual error from hub_configure() in hub_probe()
From: Chen-Yu Tsai @ 2026-06-10 8:40 UTC (permalink / raw)
To: Bartosz Golaszewski, Greg Kroah-Hartman, Andy Shevchenko,
Daniel Scally, Heikki Krogerus, Sakari Ailus, Rafael J. Wysocki,
Danilo Krummrich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno
Cc: Alan Stern, Chen-Yu Tsai, linux-acpi, driver-core, linux-pm,
linux-usb, devicetree, linux-mediatek, linux-arm-kernel,
linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260610084053.2059858-1-wenst@chromium.org>
The addition of power sequencing descriptor handling in the USB hub code
requires dealing with deferred probing from pwrseq_get(). The power
sequencing provider may not yet be available when the USB hub probes.
Return the actual error code from hub_configure() when it fails, so that
the driver core can notice the deferred probe request.
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
Changes since v1:
- Moved "int ret" declaration in hub_configure() over here from the next
patch
---
drivers/usb/core/hub.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 13264e86bc6d..985551d013b2 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1874,6 +1874,7 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
struct usb_host_interface *desc;
struct usb_device *hdev;
struct usb_hub *hub;
+ int ret;
desc = intf->cur_altsetting;
hdev = interface_to_usbdev(intf);
@@ -2005,14 +2006,15 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
usb_set_interface(hdev, 0, 0);
}
- if (hub_configure(hub, &desc->endpoint[0].desc) >= 0) {
+ ret = hub_configure(hub, &desc->endpoint[0].desc);
+ if (ret >= 0) {
onboard_dev_create_pdevs(hdev, &hub->onboard_devs);
return 0;
}
hub_disconnect(intf);
- return -ENODEV;
+ return ret;
}
static int
--
2.54.0.1099.g489fc7bff1-goog
^ permalink raw reply related
* [PATCH v2 03/16] power: sequencing: Change CONFIG_POWER_SEQUENCING to bool
From: Chen-Yu Tsai @ 2026-06-10 8:40 UTC (permalink / raw)
To: Bartosz Golaszewski, Greg Kroah-Hartman, Andy Shevchenko,
Daniel Scally, Heikki Krogerus, Sakari Ailus, Rafael J. Wysocki,
Danilo Krummrich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno
Cc: Alan Stern, Chen-Yu Tsai, linux-acpi, driver-core, linux-pm,
linux-usb, devicetree, linux-mediatek, linux-arm-kernel,
linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260610084053.2059858-1-wenst@chromium.org>
USB support, including the core and hub driver, is bool, no modules. To
be able to use the power sequencing API in the USB core, the former must
also be bool to avoid the latter being built as a module.
Change CONFIG_POWER_SEQUENCING to bool.
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
drivers/power/sequencing/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/power/sequencing/Kconfig b/drivers/power/sequencing/Kconfig
index 1c5f5820f5b7..27448fba9dc5 100644
--- a/drivers/power/sequencing/Kconfig
+++ b/drivers/power/sequencing/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
menuconfig POWER_SEQUENCING
- tristate "Power Sequencing support"
+ bool "Power Sequencing support"
help
Say Y here to enable the Power Sequencing subsystem.
--
2.54.0.1099.g489fc7bff1-goog
^ permalink raw reply related
* [PATCH v2 02/16] device property: Add fwnode_graph_get_next_port_endpoint()
From: Chen-Yu Tsai @ 2026-06-10 8:40 UTC (permalink / raw)
To: Bartosz Golaszewski, Greg Kroah-Hartman, Andy Shevchenko,
Daniel Scally, Heikki Krogerus, Sakari Ailus, Rafael J. Wysocki,
Danilo Krummrich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno
Cc: Alan Stern, Chen-Yu Tsai, linux-acpi, driver-core, linux-pm,
linux-usb, devicetree, linux-mediatek, linux-arm-kernel,
linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260610084053.2059858-1-wenst@chromium.org>
Due to design constraints of the power sequencing API, the consumer
must first be sure that the other side is actually a provider, or it
will continually get -EPROBE_DEFER when requesting the power
sequencing descriptor.
In the upcoming USB power sequencing integration, the USB hub driver
first needs to check whether a graph connection exists, and whether
the other side of the connection is a supported connector type. The
USB port is tied to a "port" firmware node, and this new helper will
be used to get the endpoint under the known "port" firmware node.
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
drivers/base/property.c | 33 +++++++++++++++++++++++++++++++++
include/linux/property.h | 2 ++
2 files changed, 35 insertions(+)
diff --git a/drivers/base/property.c b/drivers/base/property.c
index a2afd854a604..cf14f9b0a3e0 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -1099,6 +1099,39 @@ int fwnode_irq_get_byname(const struct fwnode_handle *fwnode, const char *name)
}
EXPORT_SYMBOL(fwnode_irq_get_byname);
+/**
+ * fwnode_graph_get_next_port_endpoint - Get next endpoint firmware node in port
+ * @port: Pointer to the target port firmware node
+ * @prev: Previous endpoint node or %NULL to get the first
+ *
+ * The caller is responsible for calling fwnode_handle_put() on the returned
+ * fwnode pointer. Note that this function also puts a reference to @prev
+ * unconditionally.
+ *
+ * Return: an endpoint firmware node pointer or %NULL if no more endpoints
+ * are available.
+ */
+struct fwnode_handle *fwnode_graph_get_next_port_endpoint(const struct fwnode_handle *port,
+ struct fwnode_handle *prev)
+{
+ struct fwnode_handle *ep;
+
+ while (1) {
+ prev = fwnode_get_next_child_node(port, prev);
+ if (!prev)
+ break;
+
+ if (WARN(!fwnode_name_eq(prev, "endpoint"),
+ "non endpoint node is used (%pfw)", prev))
+ continue;
+
+ break;
+ }
+
+ return prev;
+}
+EXPORT_SYMBOL_GPL(fwnode_graph_get_next_port_endpoint);
+
/**
* fwnode_graph_get_next_endpoint - Get next endpoint firmware node
* @fwnode: Pointer to the parent firmware node
diff --git a/include/linux/property.h b/include/linux/property.h
index 11f3b54c7de0..2e744c6f251d 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -500,6 +500,8 @@ int fwnode_get_phy_mode(const struct fwnode_handle *fwnode);
void __iomem *fwnode_iomap(struct fwnode_handle *fwnode, int index);
struct fwnode_handle *fwnode_graph_get_port_by_id(struct fwnode_handle *fwnode, u32 id);
+struct fwnode_handle *fwnode_graph_get_next_port_endpoint(
+ const struct fwnode_handle *port, struct fwnode_handle *prev);
struct fwnode_handle *fwnode_graph_get_next_endpoint(
const struct fwnode_handle *fwnode, struct fwnode_handle *prev);
struct fwnode_handle *
--
2.54.0.1099.g489fc7bff1-goog
^ permalink raw reply related
* [PATCH v2 01/16] device property: Add fwnode_graph_get_port_by_id()
From: Chen-Yu Tsai @ 2026-06-10 8:40 UTC (permalink / raw)
To: Bartosz Golaszewski, Greg Kroah-Hartman, Andy Shevchenko,
Daniel Scally, Heikki Krogerus, Sakari Ailus, Rafael J. Wysocki,
Danilo Krummrich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno
Cc: Alan Stern, Chen-Yu Tsai, linux-acpi, driver-core, linux-pm,
linux-usb, devicetree, linux-mediatek, linux-arm-kernel,
linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260610084053.2059858-1-wenst@chromium.org>
In some cases the driver needs a reference to the port firmware node.
Once such case is the upcoming USB power sequencing integration. The
USB hub port is tied to the corresponding port firmware node if it
exists.
Provide a helper for this.
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
drivers/base/property.c | 22 ++++++++++++++++++++++
include/linux/property.h | 1 +
2 files changed, 23 insertions(+)
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 9387bb83eb54..a2afd854a604 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -1346,6 +1346,28 @@ int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
}
EXPORT_SYMBOL(fwnode_graph_parse_endpoint);
+/**
+ * fwnode_graph_get_port_by_id - get the port matching a given id
+ * @fwnode: parent fwnode_handle containing the graph
+ * @id: id of the port
+ *
+ * Return: A 'port' firmware node pointer with refcount incremented.
+ *
+ * The caller is responsible for calling fwnode_handle_put() on the returned
+ * fwnode pointer.
+ */
+struct fwnode_handle *fwnode_graph_get_port_by_id(struct fwnode_handle *fwnode, u32 id)
+{
+ struct fwnode_handle *ep;
+
+ ep = fwnode_graph_get_endpoint_by_id(fwnode, id, 0, FWNODE_GRAPH_ENDPOINT_NEXT);
+ if (!ep)
+ return NULL;
+
+ return fwnode_get_next_parent(ep);
+}
+EXPORT_SYMBOL_GPL(fwnode_graph_get_port_by_id);
+
const void *device_get_match_data(const struct device *dev)
{
return fwnode_call_ptr_op(dev_fwnode(dev), device_get_match_data, dev);
diff --git a/include/linux/property.h b/include/linux/property.h
index e30ef23a9af3..11f3b54c7de0 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -499,6 +499,7 @@ int fwnode_get_phy_mode(const struct fwnode_handle *fwnode);
void __iomem *fwnode_iomap(struct fwnode_handle *fwnode, int index);
+struct fwnode_handle *fwnode_graph_get_port_by_id(struct fwnode_handle *fwnode, u32 id);
struct fwnode_handle *fwnode_graph_get_next_endpoint(
const struct fwnode_handle *fwnode, struct fwnode_handle *prev);
struct fwnode_handle *
--
2.54.0.1099.g489fc7bff1-goog
^ permalink raw reply related
* Re: [PATCH v2 1/3] dt-bindings: soc: imx: fsl,imx93-media-blk-ctrl: Allow LVDS Display Bridge child node
From: Krzysztof Kozlowski @ 2026-06-10 8:34 UTC (permalink / raw)
To: Liu Ying
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, Peng Fan,
devicetree, imx, linux-arm-kernel, linux-kernel, Marco Felsch
In-Reply-To: <aikYviBO1d560jdr@raspi>
On 10/06/2026 09:56, Liu Ying wrote:
> On Wed, Jun 10, 2026 at 09:46:39AM +0200, Krzysztof Kozlowski wrote:
>> On Mon, Jun 08, 2026 at 05:04:22PM +0800, Liu Ying wrote:
>>> i.MX93 SoC mediamix blk-ctrl contains one LDB_CTRL register and one LVDS
>>> register which control video output through a LVDS interface. Allow the
>>> LVDS Display Bridge(LDB) child node and add the child node to example.
>>>
>>> Signed-off-by: Liu Ying <victor.liu@nxp.com>
>>> ---
>>> .../bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml | 39 ++++++++++++++++++++++
>>> 1 file changed, 39 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml
>>> index d828c2e82965..124f5c206ee3 100644
>>> --- a/Documentation/devicetree/bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml
>>> +++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml
>>> @@ -26,6 +26,12 @@ properties:
>>> reg:
>>> maxItems: 1
>>>
>>> + '#address-cells':
>>> + const: 1
>>> +
>>> + '#size-cells':
>>> + const: 1
>>> +
>>> '#power-domain-cells':
>>> const: 1
>>>
>>> @@ -92,6 +98,11 @@ properties:
>>> - compatible
>>> - ports
>>>
>>> + bridge@20:
>>
>> You have dpi-bridge, so this should not be different. You should not mix
>> addressable and non-addressable nodes and NXP decided recently in
>> 3feaa4342637eef673243dd38ccb32e8dc8efd5a that everything will be
>> non-addressable.
>>
>> Writing bindings ask explicitly to post bindings, so if you decide to do
>> half-baked solutions it's on you. Half baked solutions are not allowing
>> to bypass standard rules.
>
> Mixing addressable and non-addressable nodes is allowed according to recent
> discussion[1].
>
> [1] https://lore.kernel.org/all/n6akxiayi3g6gxcqhreb4iaohmeokoalnqup6h5r2fwdt4zijt@u2wyps55ayqm/
And it is explained in commit msg in... where exactly?
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v1 13/26] s390: Introduce read/write ARM sysreg instructions
From: Steffen Eiden @ 2026-06-10 8:30 UTC (permalink / raw)
To: Janosch Frank
Cc: kvm, kvmarm, linux-arm-kernel, linux-kernel, linux-s390,
Alexander Gordeev, Andreas Grapentin, Arnd Bergmann,
Catalin Marinas, Christian Borntraeger, Claudio Imbrenda,
David Hildenbrand, Friedrich Welter, Gautam Gala, Hariharan Mari,
Heiko Carstens, Hendrik Brueckner, Ilya Leoshkevich, Joey Gouly,
Marc Zyngier, Nico Boehr, Nina Schoetterl-Glausch, Oliver Upton,
Paolo Bonzini, Suzuki K Poulose, Sven Schnelle, Ulrich Weigand,
Vasily Gorbik, Will Deacon, Zenghui Yu
In-Reply-To: <2d73aca5-1858-4a7a-a304-0971e4789dc1@linux.ibm.com>
On Tue, Jun 09, 2026 at 05:04:10PM +0200, Janosch Frank wrote:
> On 5/29/26 17:55, Steffen Eiden wrote:
> > Introduce Extract Arm System Register and Store Arm System Register to
> > enable s390 hosts to read and write system registers for arm64 guests.
> > The new instructions use the new RIE_H instruction format. Add assembler
> > macros to create instructions in RIE_H format manually. Add Support for
> > disassembling the new instructions.
> >
> > Co-developed-by: Andreas Grapentin <gra@linux.ibm.com>
> > Signed-off-by: Andreas Grapentin <gra@linux.ibm.com>
> > Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
> > ---
> > arch/s390/include/asm/sae-asm.h | 48 +++++++++++++++++++++++++++
> > arch/s390/include/asm/sae.h | 58 +++++++++++++++++++++++++++++++++
> > arch/s390/kernel/dis.c | 1 +
> > arch/s390/tools/opcodes.txt | 2 ++
> > 4 files changed, 109 insertions(+)
> > create mode 100644 arch/s390/include/asm/sae-asm.h
> >
...
> > diff --git a/arch/s390/include/asm/sae.h b/arch/s390/include/asm/sae.h
> > index fe010a1a7729..1d9a16b91b23 100644
> > --- a/arch/s390/include/asm/sae.h
> > +++ b/arch/s390/include/asm/sae.h
> > @@ -4,6 +4,7 @@
> > #include "linux/linkage.h"
> > #include <linux/types.h>
> > +#include <asm/sae-asm.h>
> > /* defined in arch/s390/kernel/entry.S */
> > asmlinkage int __sae64a(phys_addr_t sae_block_phys);
> > @@ -12,6 +13,12 @@ asmlinkage int __sae64a(phys_addr_t sae_block_phys);
> > #include <linux/io.h>
> > #include <asm/kvm_host_arm64_types.h>
> > +asm(".include \"asm/sae-asm.h\"\n");
> > +
> > +#define _SAE_ASR_REG_SHIFT 5
> > +#define SASR_FLAG_INITIALIZED 0x8
> > +#define EASR_FLAG_SA 0x8
>
> s/SA/SAVE_AREA/ or SAVEAREA
>
> I think both might fit.
yes, might be a good idea.
>
> > +
> > /**
> > * __sae64a() - Start Arm Execution
> > */
> > @@ -20,6 +27,57 @@ static inline void sae64a(struct kvm_sae_block *sae_block)
> > __sae64a(virt_to_phys(sae_block));
> > }
> > +/**
> > + * sasr() - Set Arm System Register
> > + * @arm_reg: ARM system register identifier; compile-time constant
> > + * @val: Value to set
> > + * @save_area: Pointer to SAE save area
> > + * @flags: Operation flags; compile-time constant
> > + *
> > + * Sets an ARM system register value.
> > + */
> > +static __always_inline void sasr(unsigned int arm_reg, u64 val,
> > + struct kvm_sae_save_area *save_area,
> > + u64 flags)
>
> m4 is 4 bits in length, any reason why we use a u64 here?
> Same for easr.
>
No real reason beside my preference of using u64 by default.
Do you want me to change it to u8?
Steffen
^ permalink raw reply
* Re: [PATCH net-next v8 3/6] net: stmmac: eic7700: make RGMII delay properties optional
From: Maxime Chevallier @ 2026-06-10 8:26 UTC (permalink / raw)
To: lizhi2, devicetree, andrew+netdev, davem, edumazet, kuba, robh,
krzk+dt, conor+dt, netdev, pabeni, mcoquelin.stm32,
alexandre.torgue, rmk+kernel, pjw, palmer, aou, alex, linux-riscv,
linux-stm32, linux-arm-kernel, linux-kernel
Cc: ningyu, linmin, pinkesh.vaghela, pritesh.patel, weishangjuan,
horms, lee
In-Reply-To: <20260610012937.911-1-lizhi2@eswincomputing.com>
Hi,
On 6/10/26 03:29, lizhi2@eswincomputing.com wrote:
> From: Zhi Li <lizhi2@eswincomputing.com>
>
> Make rx-internal-delay-ps and tx-internal-delay-ps optional in the
> EIC7700 DWMAC driver.
>
> The driver previously required both properties to be present and would
> fail probe when they were missing. This restricts valid hardware
> configurations where RGMII timing is instead provided by the PHY or
> board design.
>
> Update the driver to treat missing delay properties as zero delay,
> allowing systems without explicit MAC-side delay tuning to operate
> correctly.
>
> This aligns the driver behavior with the updated device tree binding
> and provides a safe default configuration when MAC-side delay
> programming is not required.
>
> Signed-off-by: Zhi Li <lizhi2@eswincomputing.com>
> ---
> drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c | 6 ------
> 1 file changed, 6 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c
> index 4ac979d874d6..ec99b597aeaf 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c
> @@ -165,9 +165,6 @@ static int eic7700_dwmac_probe(struct platform_device *pdev)
> dwc_priv->eth_clk_dly_param &= ~EIC7700_ETH_RX_ADJ_DELAY;
> dwc_priv->eth_clk_dly_param |=
> FIELD_PREP(EIC7700_ETH_RX_ADJ_DELAY, val);
> - } else {
> - return dev_err_probe(&pdev->dev, -EINVAL,
> - "missing required property rx-internal-delay-ps\n");
> }
>
> /* Read tx-internal-delay-ps and update tx_clk delay */
> @@ -187,9 +184,6 @@ static int eic7700_dwmac_probe(struct platform_device *pdev)
> dwc_priv->eth_clk_dly_param &= ~EIC7700_ETH_TX_ADJ_DELAY;
> dwc_priv->eth_clk_dly_param |=
> FIELD_PREP(EIC7700_ETH_TX_ADJ_DELAY, val);
> - } else {
> - return dev_err_probe(&pdev->dev, -EINVAL,
> - "missing required property tx-internal-delay-ps\n");
> }
I think then you need to handle RGMII, RGMII_ID, RGMII_RXID and RGMII_TXID,
by using default delays for these (usually around 2ns), as here all delays
will be set to 0, regardless of the RGMII mode in use.
Maxime
>
> dwc_priv->eic7700_hsp_regmap =
^ permalink raw reply
* [PATCH v3 1/2] dt-bindings: clock: Add Amlogic A9 AO clock controller
From: Jian Hu via B4 Relay @ 2026-06-10 8:23 UTC (permalink / raw)
To: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Xianwei Zhao,
Kevin Hilman, Martin Blumenstingl
Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
linux-arm-kernel, Jian Hu, Conor Dooley
In-Reply-To: <20260610-a9_aoclk-v3-0-b7592d6c31e2@amlogic.com>
From: Jian Hu <jian.hu@amlogic.com>
Add the Always-On clock controller dt-bindings for the Amlogic A9
SoC family.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Jian Hu <jian.hu@amlogic.com>
---
.../bindings/clock/amlogic,a9-aoclkc.yaml | 76 ++++++++++++++++++++++
include/dt-bindings/clock/amlogic,a9-aoclkc.h | 76 ++++++++++++++++++++++
2 files changed, 152 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/amlogic,a9-aoclkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a9-aoclkc.yaml
new file mode 100644
index 000000000000..1fa9b3a32fbb
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,a9-aoclkc.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2026 Amlogic, Inc. All rights reserved
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,a9-aoclkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic A9 Series Always-On Clock Controller
+
+maintainers:
+ - Neil Armstrong <neil.armstrong@linaro.org>
+ - Jerome Brunet <jbrunet@baylibre.com>
+ - Jian Hu <jian.hu@amlogic.com>
+ - Xianwei Zhao <xianwei.zhao@amlogic.com>
+
+properties:
+ compatible:
+ const: amlogic,a9-aoclkc
+
+ reg:
+ maxItems: 1
+
+ '#clock-cells':
+ const: 1
+
+ clocks:
+ minItems: 5
+ items:
+ - description: input oscillator
+ - description: input fclk div 3
+ - description: input fclk div 4
+ - description: input fclk div 5
+ - description: input sys clk
+ - description: external fixed 32k (optional)
+
+ clock-names:
+ minItems: 5
+ items:
+ - const: xtal
+ - const: fdiv3
+ - const: fdiv4
+ - const: fdiv5
+ - const: sys
+ - const: ext_32k
+
+required:
+ - compatible
+ - reg
+ - '#clock-cells'
+ - clocks
+ - clock-names
+
+additionalProperties: false
+
+examples:
+ - |
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ clock-controller@0 {
+ compatible = "amlogic,a9-aoclkc";
+ reg = <0x0 0x0 0x0 0x58>;
+ #clock-cells = <1>;
+ clocks = <&xtal>,
+ <&scmi_clk 14>,
+ <&scmi_clk 16>,
+ <&scmi_clk 18>,
+ <&scmi_clk 21>;
+ clock-names = "xtal",
+ "fdiv3",
+ "fdiv4",
+ "fdiv5",
+ "sys";
+ };
+ };
diff --git a/include/dt-bindings/clock/amlogic,a9-aoclkc.h b/include/dt-bindings/clock/amlogic,a9-aoclkc.h
new file mode 100644
index 000000000000..a7d704d4b58e
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,a9-aoclkc.h
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2026 Amlogic, Inc. All rights reserved.
+ */
+
+#ifndef __AMLOGIC_A9_AO_CLKC_H
+#define __AMLOGIC_A9_AO_CLKC_H
+
+#define CLKID_AO_XTAL_IN 0
+#define CLKID_AO_XTAL 1
+#define CLKID_AO_SYS 2
+#define CLKID_AO_SYS_I3C 3
+#define CLKID_AO_SYS_RTC_REG 4
+#define CLKID_AO_SYS_CLKTREE 5
+#define CLKID_AO_SYS_RST_CTRL 6
+#define CLKID_AO_SYS_PAD 7
+#define CLKID_AO_SYS_RTC_DIG 8
+#define CLKID_AO_SYS_IRQ 9
+#define CLKID_AO_SYS_PWRCTRL 10
+#define CLKID_AO_SYS_PWM_A 11
+#define CLKID_AO_SYS_PWM_B 12
+#define CLKID_AO_SYS_PWM_C 13
+#define CLKID_AO_SYS_PWM_D 14
+#define CLKID_AO_SYS_PWM_E 15
+#define CLKID_AO_SYS_PWM_F 16
+#define CLKID_AO_SYS_PWM_G 17
+#define CLKID_AO_SYS_I2C_A 18
+#define CLKID_AO_SYS_I2C_B 19
+#define CLKID_AO_SYS_I2C_C 20
+#define CLKID_AO_SYS_I2C_D 21
+#define CLKID_AO_SYS_SED 22
+#define CLKID_AO_SYS_IR_CTRL 23
+#define CLKID_AO_SYS_UART_B 24
+#define CLKID_AO_SYS_UART_C 25
+#define CLKID_AO_SYS_UART_D 26
+#define CLKID_AO_SYS_UART_E 27
+#define CLKID_AO_SYS_SPISG_0 28
+#define CLKID_AO_SYS_RTC_SECURE 29
+#define CLKID_AO_SYS_CEC 30
+#define CLKID_AO_SYS_AOCPU 31
+#define CLKID_AO_SYS_SRAM 32
+#define CLKID_AO_SYS_SPISG_1 33
+#define CLKID_AO_SYS_SPISG_2 34
+#define CLKID_AO_PWM_A_SEL 35
+#define CLKID_AO_PWM_A_DIV 36
+#define CLKID_AO_PWM_A 37
+#define CLKID_AO_PWM_B_SEL 38
+#define CLKID_AO_PWM_B_DIV 39
+#define CLKID_AO_PWM_B 40
+#define CLKID_AO_PWM_C_SEL 41
+#define CLKID_AO_PWM_C_DIV 42
+#define CLKID_AO_PWM_C 43
+#define CLKID_AO_PWM_D_SEL 44
+#define CLKID_AO_PWM_D_DIV 45
+#define CLKID_AO_PWM_D 46
+#define CLKID_AO_PWM_E_SEL 47
+#define CLKID_AO_PWM_E_DIV 48
+#define CLKID_AO_PWM_E 49
+#define CLKID_AO_PWM_F_SEL 50
+#define CLKID_AO_PWM_F_DIV 51
+#define CLKID_AO_PWM_F 52
+#define CLKID_AO_PWM_G_SEL 53
+#define CLKID_AO_PWM_G_DIV 54
+#define CLKID_AO_PWM_G 55
+#define CLKID_AO_RTC_DUALDIV_IN 56
+#define CLKID_AO_RTC_DUALDIV_DIV 57
+#define CLKID_AO_RTC_DUALDIV_SEL 58
+#define CLKID_AO_RTC_DUALDIV 59
+#define CLKID_AO_RTC 60
+#define CLKID_AO_CEC_DUALDIV_IN 61
+#define CLKID_AO_CEC_DUALDIV_DIV 62
+#define CLKID_AO_CEC_DUALDIV_SEL 63
+#define CLKID_AO_CEC_DUALDIV 64
+#define CLKID_AO_CEC 65
+
+#endif /* __AMLOGIC_A9_AO_CLKC_H */
--
2.47.1
^ permalink raw reply related
* [PATCH v3 2/2] clk: amlogic: Add A9 AO clock controller driver
From: Jian Hu via B4 Relay @ 2026-06-10 8:23 UTC (permalink / raw)
To: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Xianwei Zhao,
Kevin Hilman, Martin Blumenstingl
Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
linux-arm-kernel, Jian Hu
In-Reply-To: <20260610-a9_aoclk-v3-0-b7592d6c31e2@amlogic.com>
From: Jian Hu <jian.hu@amlogic.com>
Add the Always-on clock controller driver for the Amlogic A9 SoC family.
Signed-off-by: Jian Hu <jian.hu@amlogic.com>
---
drivers/clk/meson/Kconfig | 13 ++
drivers/clk/meson/Makefile | 1 +
drivers/clk/meson/a9-aoclk.c | 431 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 445 insertions(+)
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index cf8cf3f9e4ee..b71299898197 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -132,6 +132,19 @@ config COMMON_CLK_A1_PERIPHERALS
device, A1 SoC Family. Say Y if you want A1 Peripherals clock
controller to work.
+config COMMON_CLK_A9_AO
+ tristate "Amlogic A9 SoC AO clock controller support"
+ depends on ARM64 || COMPILE_TEST
+ default ARCH_MESON
+ select COMMON_CLK_MESON_REGMAP
+ select COMMON_CLK_MESON_CLKC_UTILS
+ select COMMON_CLK_MESON_DUALDIV
+ imply COMMON_CLK_SCMI
+ help
+ Support for the AO clock controller on Amlogic A311Y3 based
+ device, AKA A9.
+ Say Y if you want A9 AO clock controller to work.
+
config COMMON_CLK_C3_PLL
tristate "Amlogic C3 PLL clock controller"
depends on ARM64
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index c6719694a242..f89d027c282c 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o
obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o
+obj-$(CONFIG_COMMON_CLK_A9_AO) += a9-aoclk.o
obj-$(CONFIG_COMMON_CLK_C3_PLL) += c3-pll.o
obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
diff --git a/drivers/clk/meson/a9-aoclk.c b/drivers/clk/meson/a9-aoclk.c
new file mode 100644
index 000000000000..dd9fd8d24702
--- /dev/null
+++ b/drivers/clk/meson/a9-aoclk.c
@@ -0,0 +1,431 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
+/*
+ * Copyright (C) 2026 Amlogic, Inc. All rights reserved
+ */
+
+#include <dt-bindings/clock/amlogic,a9-aoclkc.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+#include "clk-regmap.h"
+#include "clk-dualdiv.h"
+#include "meson-clkc-utils.h"
+
+#define AO_OSCIN_CTRL 0x00
+#define AO_SYS_CLK0 0x04
+#define AO_PWM_CLK_A_CTRL 0x1c
+#define AO_PWM_CLK_B_CTRL 0x20
+#define AO_PWM_CLK_C_CTRL 0x24
+#define AO_PWM_CLK_D_CTRL 0x28
+#define AO_PWM_CLK_E_CTRL 0x2c
+#define AO_PWM_CLK_F_CTRL 0x30
+#define AO_PWM_CLK_G_CTRL 0x34
+#define AO_CEC_CTRL0 0x38
+#define AO_CEC_CTRL1 0x3c
+#define AO_RTC_BY_OSCIN_CTRL0 0x50
+#define AO_RTC_BY_OSCIN_CTRL1 0x54
+
+#define A9_COMP_SEL(_name, _reg, _shift, _mask, _pdata) \
+ MESON_COMP_SEL(a9_ao_, _name, _reg, _shift, _mask, _pdata, NULL, 0, 0)
+
+#define A9_COMP_DIV(_name, _reg, _shift, _width) \
+ MESON_COMP_DIV(a9_ao_, _name, _reg, _shift, _width, 0, CLK_SET_RATE_PARENT)
+
+#define A9_COMP_GATE(_name, _reg, _bit) \
+ MESON_COMP_GATE(a9_ao_, _name, _reg, _bit, CLK_SET_RATE_PARENT)
+
+static struct clk_regmap a9_ao_xtal_in = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = AO_OSCIN_CTRL,
+ .bit_idx = 3,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "ao_xtal_in",
+ .ops = &clk_regmap_gate_ops,
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "xtal",
+ },
+ .num_parents = 1,
+ /*
+ * ao_sys can select different clock sources. One possible clock path is:
+ * ao_xtal_in->ao_xtal->ao_sys-> ao sys gate clocks
+ *
+ * ao_xtal_in is in the parent chain of AO sys gate clocks.
+ * Since some downstream clocks are marked CLK_IS_CRITICAL,
+ * ao_xtal_in must remain enabled and is therefore marked
+ * CLK_IS_CRITICAL as well.
+ */
+ .flags = CLK_IS_CRITICAL,
+ },
+};
+
+static struct clk_regmap a9_ao_xtal = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = AO_OSCIN_CTRL,
+ .mask = 0x1,
+ .shift = 0,
+ },
+ /* ext_32k is from external PAD, do not automatically reparent */
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("ao_xtal",
+ ((const struct clk_parent_data []) {
+ { .hw = &a9_ao_xtal_in.hw },
+ { .fw_name = "ext_32k" }
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_NO_REPARENT),
+};
+
+static struct clk_regmap a9_ao_sys = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = AO_OSCIN_CTRL,
+ .mask = 0x1,
+ .shift = 1,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("ao_sys",
+ ((const struct clk_parent_data []) {
+ { .hw = &a9_ao_xtal.hw },
+ { .fw_name = "sys" }
+ }), &clk_regmap_mux_ops, 0),
+};
+
+static const struct clk_parent_data a9_ao_pclk_parents = { .hw = &a9_ao_sys.hw };
+
+#define A9_AO_PCLK(_name, _bit, _flags) \
+ MESON_PCLK(a9_ao_sys_##_name, AO_SYS_CLK0, _bit, \
+ &a9_ao_pclk_parents, _flags)
+
+/*
+ * A9 integrates a low-power microprocessor (Always-on CPU: AOCPU). Some AO sys
+ * clocks control the AOCPU modules. Mark the AOCPU-related clocks with
+ * CLK_IS_CRITICAL to avoid them being disabled and impacting AOCPU functionality.
+ * AOCPU-related clocks list:
+ * - clktree
+ * - rst_ctrl
+ * - pad
+ * - irq
+ * - pwrctrl
+ * - aocpu
+ * - sram
+ */
+static A9_AO_PCLK(i3c, 0, 0);
+static A9_AO_PCLK(rtc_reg, 1, 0);
+static A9_AO_PCLK(clktree, 2, CLK_IS_CRITICAL);
+static A9_AO_PCLK(rst_ctrl, 3, CLK_IS_CRITICAL);
+static A9_AO_PCLK(pad, 4, CLK_IS_CRITICAL);
+static A9_AO_PCLK(rtc_dig, 5, 0);
+static A9_AO_PCLK(irq, 6, CLK_IS_CRITICAL);
+static A9_AO_PCLK(pwrctrl, 7, CLK_IS_CRITICAL);
+static A9_AO_PCLK(pwm_a, 8, 0);
+static A9_AO_PCLK(pwm_b, 9, 0);
+static A9_AO_PCLK(pwm_c, 10, 0);
+static A9_AO_PCLK(pwm_d, 11, 0);
+static A9_AO_PCLK(pwm_e, 12, 0);
+static A9_AO_PCLK(pwm_f, 13, 0);
+static A9_AO_PCLK(pwm_g, 14, 0);
+static A9_AO_PCLK(i2c_a, 15, 0);
+static A9_AO_PCLK(i2c_b, 16, 0);
+static A9_AO_PCLK(i2c_c, 17, 0);
+static A9_AO_PCLK(i2c_d, 18, 0);
+static A9_AO_PCLK(sed, 19, 0);
+static A9_AO_PCLK(ir_ctrl, 20, 0);
+static A9_AO_PCLK(uart_b, 21, 0);
+static A9_AO_PCLK(uart_c, 22, 0);
+static A9_AO_PCLK(uart_d, 23, 0);
+static A9_AO_PCLK(uart_e, 24, 0);
+static A9_AO_PCLK(spisg_0, 25, 0);
+static A9_AO_PCLK(rtc_secure, 26, 0);
+static A9_AO_PCLK(cec, 27, 0);
+static A9_AO_PCLK(aocpu, 28, CLK_IS_CRITICAL);
+static A9_AO_PCLK(sram, 29, CLK_IS_CRITICAL);
+static A9_AO_PCLK(spisg_1, 30, 0);
+static A9_AO_PCLK(spisg_2, 31, 0);
+
+static const struct clk_parent_data a9_ao_pwm_parents[] = {
+ { .hw = &a9_ao_xtal.hw },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", }
+};
+
+static A9_COMP_SEL(pwm_a, AO_PWM_CLK_A_CTRL, 9, 0x7, a9_ao_pwm_parents);
+static A9_COMP_DIV(pwm_a, AO_PWM_CLK_A_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_a, AO_PWM_CLK_A_CTRL, 8);
+
+static A9_COMP_SEL(pwm_b, AO_PWM_CLK_B_CTRL, 9, 0x7, a9_ao_pwm_parents);
+static A9_COMP_DIV(pwm_b, AO_PWM_CLK_B_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_b, AO_PWM_CLK_B_CTRL, 8);
+
+static A9_COMP_SEL(pwm_c, AO_PWM_CLK_C_CTRL, 9, 0x7, a9_ao_pwm_parents);
+static A9_COMP_DIV(pwm_c, AO_PWM_CLK_C_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_c, AO_PWM_CLK_C_CTRL, 8);
+
+static A9_COMP_SEL(pwm_d, AO_PWM_CLK_D_CTRL, 9, 0x7, a9_ao_pwm_parents);
+static A9_COMP_DIV(pwm_d, AO_PWM_CLK_D_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_d, AO_PWM_CLK_D_CTRL, 8);
+
+static A9_COMP_SEL(pwm_e, AO_PWM_CLK_E_CTRL, 9, 0x7, a9_ao_pwm_parents);
+static A9_COMP_DIV(pwm_e, AO_PWM_CLK_E_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_e, AO_PWM_CLK_E_CTRL, 8);
+
+static A9_COMP_SEL(pwm_f, AO_PWM_CLK_F_CTRL, 9, 0x7, a9_ao_pwm_parents);
+static A9_COMP_DIV(pwm_f, AO_PWM_CLK_F_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_f, AO_PWM_CLK_F_CTRL, 8);
+
+static A9_COMP_SEL(pwm_g, AO_PWM_CLK_G_CTRL, 9, 0x7, a9_ao_pwm_parents);
+static A9_COMP_DIV(pwm_g, AO_PWM_CLK_G_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_g, AO_PWM_CLK_G_CTRL, 8);
+
+static struct clk_regmap a9_ao_rtc_dualdiv_in = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = AO_RTC_BY_OSCIN_CTRL0,
+ .bit_idx = 31,
+ },
+ .hw.init = CLK_HW_INIT_HW("ao_rtc_dualdiv_in", &a9_ao_xtal.hw,
+ &clk_regmap_gate_ops, 0),
+};
+
+static const struct meson_clk_dualdiv_param a9_ao_dualdiv_table[] = {
+ { 733, 732, 8, 11, 1 },
+ { /* sentinel */ }
+};
+
+static struct clk_regmap a9_ao_rtc_dualdiv_div = {
+ .data = &(struct meson_clk_dualdiv_data){
+ .n1 = {
+ .reg_off = AO_RTC_BY_OSCIN_CTRL0,
+ .shift = 0,
+ .width = 12,
+ },
+ .n2 = {
+ .reg_off = AO_RTC_BY_OSCIN_CTRL0,
+ .shift = 12,
+ .width = 12,
+ },
+ .m1 = {
+ .reg_off = AO_RTC_BY_OSCIN_CTRL1,
+ .shift = 0,
+ .width = 12,
+ },
+ .m2 = {
+ .reg_off = AO_RTC_BY_OSCIN_CTRL1,
+ .shift = 12,
+ .width = 12,
+ },
+ .dual = {
+ .reg_off = AO_RTC_BY_OSCIN_CTRL0,
+ .shift = 28,
+ .width = 1,
+ },
+ .table = a9_ao_dualdiv_table,
+ },
+ .hw.init = CLK_HW_INIT_HW("a9_ao_rtc_dualdiv_div", &a9_ao_rtc_dualdiv_in.hw,
+ &meson_clk_dualdiv_ops, 0),
+};
+
+static struct clk_regmap a9_ao_rtc_dualdiv_sel = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = AO_RTC_BY_OSCIN_CTRL1,
+ .mask = 0x1,
+ .shift = 24,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("ao_rtc_dualdiv_sel",
+ ((const struct clk_hw *[]) {
+ &a9_ao_rtc_dualdiv_div.hw,
+ &a9_ao_rtc_dualdiv_in.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_ao_rtc_dualdiv = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = AO_RTC_BY_OSCIN_CTRL0,
+ .bit_idx = 30,
+ },
+ .hw.init = CLK_HW_INIT_HW("ao_rtc_dualdiv", &a9_ao_rtc_dualdiv_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_ao_rtc = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = AO_RTC_BY_OSCIN_CTRL1,
+ .mask = 0x1,
+ .shift = 30,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("ao_rtc",
+ ((const struct clk_hw *[]) {
+ &a9_ao_xtal.hw,
+ &a9_ao_rtc_dualdiv.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_ao_cec_dualdiv_in = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = AO_CEC_CTRL0,
+ .bit_idx = 31,
+ },
+ .hw.init = CLK_HW_INIT_HW("ao_cec_dualdiv_in", &a9_ao_xtal.hw,
+ &clk_regmap_gate_ops, 0),
+};
+
+static struct clk_regmap a9_ao_cec_dualdiv_div = {
+ .data = &(struct meson_clk_dualdiv_data){
+ .n1 = {
+ .reg_off = AO_CEC_CTRL0,
+ .shift = 0,
+ .width = 12,
+ },
+ .n2 = {
+ .reg_off = AO_CEC_CTRL0,
+ .shift = 12,
+ .width = 12,
+ },
+ .m1 = {
+ .reg_off = AO_CEC_CTRL1,
+ .shift = 0,
+ .width = 12,
+ },
+ .m2 = {
+ .reg_off = AO_CEC_CTRL1,
+ .shift = 12,
+ .width = 12,
+ },
+ .dual = {
+ .reg_off = AO_CEC_CTRL0,
+ .shift = 28,
+ .width = 1,
+ },
+ .table = a9_ao_dualdiv_table,
+ },
+ .hw.init = CLK_HW_INIT_HW("ao_cec_dualdiv_div", &a9_ao_cec_dualdiv_in.hw,
+ &meson_clk_dualdiv_ops, 0),
+};
+
+static struct clk_regmap a9_ao_cec_dualdiv_sel = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = AO_CEC_CTRL1,
+ .mask = 0x1,
+ .shift = 24,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("ao_cec_dualdiv_sel",
+ ((const struct clk_hw *[]) {
+ &a9_ao_cec_dualdiv_div.hw,
+ &a9_ao_cec_dualdiv_in.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_ao_cec_dualdiv = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = AO_CEC_CTRL0,
+ .bit_idx = 30,
+ },
+ .hw.init = CLK_HW_INIT_HW("ao_cec_dualdiv", &a9_ao_cec_dualdiv_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_ao_cec = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = AO_CEC_CTRL1,
+ .mask = 0x1,
+ .shift = 30,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("ao_cec",
+ ((const struct clk_hw *[]) {
+ &a9_ao_cec_dualdiv.hw,
+ &a9_ao_rtc.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_hw *a9_ao_hw_clks[] = {
+ [CLKID_AO_XTAL_IN] = &a9_ao_xtal_in.hw,
+ [CLKID_AO_XTAL] = &a9_ao_xtal.hw,
+ [CLKID_AO_SYS] = &a9_ao_sys.hw,
+ [CLKID_AO_SYS_I3C] = &a9_ao_sys_i3c.hw,
+ [CLKID_AO_SYS_RTC_REG] = &a9_ao_sys_rtc_reg.hw,
+ [CLKID_AO_SYS_CLKTREE] = &a9_ao_sys_clktree.hw,
+ [CLKID_AO_SYS_RST_CTRL] = &a9_ao_sys_rst_ctrl.hw,
+ [CLKID_AO_SYS_PAD] = &a9_ao_sys_pad.hw,
+ [CLKID_AO_SYS_RTC_DIG] = &a9_ao_sys_rtc_dig.hw,
+ [CLKID_AO_SYS_IRQ] = &a9_ao_sys_irq.hw,
+ [CLKID_AO_SYS_PWRCTRL] = &a9_ao_sys_pwrctrl.hw,
+ [CLKID_AO_SYS_PWM_A] = &a9_ao_sys_pwm_a.hw,
+ [CLKID_AO_SYS_PWM_B] = &a9_ao_sys_pwm_b.hw,
+ [CLKID_AO_SYS_PWM_C] = &a9_ao_sys_pwm_c.hw,
+ [CLKID_AO_SYS_PWM_D] = &a9_ao_sys_pwm_d.hw,
+ [CLKID_AO_SYS_PWM_E] = &a9_ao_sys_pwm_e.hw,
+ [CLKID_AO_SYS_PWM_F] = &a9_ao_sys_pwm_f.hw,
+ [CLKID_AO_SYS_PWM_G] = &a9_ao_sys_pwm_g.hw,
+ [CLKID_AO_SYS_I2C_A] = &a9_ao_sys_i2c_a.hw,
+ [CLKID_AO_SYS_I2C_B] = &a9_ao_sys_i2c_b.hw,
+ [CLKID_AO_SYS_I2C_C] = &a9_ao_sys_i2c_c.hw,
+ [CLKID_AO_SYS_I2C_D] = &a9_ao_sys_i2c_d.hw,
+ [CLKID_AO_SYS_SED] = &a9_ao_sys_sed.hw,
+ [CLKID_AO_SYS_IR_CTRL] = &a9_ao_sys_ir_ctrl.hw,
+ [CLKID_AO_SYS_UART_B] = &a9_ao_sys_uart_b.hw,
+ [CLKID_AO_SYS_UART_C] = &a9_ao_sys_uart_c.hw,
+ [CLKID_AO_SYS_UART_D] = &a9_ao_sys_uart_d.hw,
+ [CLKID_AO_SYS_UART_E] = &a9_ao_sys_uart_e.hw,
+ [CLKID_AO_SYS_SPISG_0] = &a9_ao_sys_spisg_0.hw,
+ [CLKID_AO_SYS_RTC_SECURE] = &a9_ao_sys_rtc_secure.hw,
+ [CLKID_AO_SYS_CEC] = &a9_ao_sys_cec.hw,
+ [CLKID_AO_SYS_AOCPU] = &a9_ao_sys_aocpu.hw,
+ [CLKID_AO_SYS_SRAM] = &a9_ao_sys_sram.hw,
+ [CLKID_AO_SYS_SPISG_1] = &a9_ao_sys_spisg_1.hw,
+ [CLKID_AO_SYS_SPISG_2] = &a9_ao_sys_spisg_2.hw,
+ [CLKID_AO_PWM_A_SEL] = &a9_ao_pwm_a_sel.hw,
+ [CLKID_AO_PWM_A_DIV] = &a9_ao_pwm_a_div.hw,
+ [CLKID_AO_PWM_A] = &a9_ao_pwm_a.hw,
+ [CLKID_AO_PWM_B_SEL] = &a9_ao_pwm_b_sel.hw,
+ [CLKID_AO_PWM_B_DIV] = &a9_ao_pwm_b_div.hw,
+ [CLKID_AO_PWM_B] = &a9_ao_pwm_b.hw,
+ [CLKID_AO_PWM_C_SEL] = &a9_ao_pwm_c_sel.hw,
+ [CLKID_AO_PWM_C_DIV] = &a9_ao_pwm_c_div.hw,
+ [CLKID_AO_PWM_C] = &a9_ao_pwm_c.hw,
+ [CLKID_AO_PWM_D_SEL] = &a9_ao_pwm_d_sel.hw,
+ [CLKID_AO_PWM_D_DIV] = &a9_ao_pwm_d_div.hw,
+ [CLKID_AO_PWM_D] = &a9_ao_pwm_d.hw,
+ [CLKID_AO_PWM_E_SEL] = &a9_ao_pwm_e_sel.hw,
+ [CLKID_AO_PWM_E_DIV] = &a9_ao_pwm_e_div.hw,
+ [CLKID_AO_PWM_E] = &a9_ao_pwm_e.hw,
+ [CLKID_AO_PWM_F_SEL] = &a9_ao_pwm_f_sel.hw,
+ [CLKID_AO_PWM_F_DIV] = &a9_ao_pwm_f_div.hw,
+ [CLKID_AO_PWM_F] = &a9_ao_pwm_f.hw,
+ [CLKID_AO_PWM_G_SEL] = &a9_ao_pwm_g_sel.hw,
+ [CLKID_AO_PWM_G_DIV] = &a9_ao_pwm_g_div.hw,
+ [CLKID_AO_PWM_G] = &a9_ao_pwm_g.hw,
+ [CLKID_AO_RTC_DUALDIV_IN] = &a9_ao_rtc_dualdiv_in.hw,
+ [CLKID_AO_RTC_DUALDIV_DIV] = &a9_ao_rtc_dualdiv_div.hw,
+ [CLKID_AO_RTC_DUALDIV_SEL] = &a9_ao_rtc_dualdiv_sel.hw,
+ [CLKID_AO_RTC_DUALDIV] = &a9_ao_rtc_dualdiv.hw,
+ [CLKID_AO_RTC] = &a9_ao_rtc.hw,
+ [CLKID_AO_CEC_DUALDIV_IN] = &a9_ao_cec_dualdiv_in.hw,
+ [CLKID_AO_CEC_DUALDIV_DIV] = &a9_ao_cec_dualdiv_div.hw,
+ [CLKID_AO_CEC_DUALDIV_SEL] = &a9_ao_cec_dualdiv_sel.hw,
+ [CLKID_AO_CEC_DUALDIV] = &a9_ao_cec_dualdiv.hw,
+ [CLKID_AO_CEC] = &a9_ao_cec.hw,
+};
+
+static const struct meson_clkc_data a9_ao_clkc_data = {
+ .hw_clks = {
+ .hws = a9_ao_hw_clks,
+ .num = ARRAY_SIZE(a9_ao_hw_clks),
+ },
+};
+
+static const struct of_device_id a9_ao_clkc_match_table[] = {
+ {
+ .compatible = "amlogic,a9-aoclkc",
+ .data = &a9_ao_clkc_data,
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(of, a9_ao_clkc_match_table);
+
+static struct platform_driver a9_ao_clkc_driver = {
+ .probe = meson_clkc_mmio_probe,
+ .driver = {
+ .name = "a9-aoclkc",
+ .of_match_table = a9_ao_clkc_match_table,
+ },
+};
+module_platform_driver(a9_ao_clkc_driver);
+
+MODULE_DESCRIPTION("Amlogic A9 Always-ON Clock Controller driver");
+MODULE_AUTHOR("Jian Hu <jian.hu@amlogic.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("CLK_MESON");
--
2.47.1
^ permalink raw reply related
* [PATCH v3 0/2] clk: amlogic: Add A9 AO clock controller
From: Jian Hu via B4 Relay @ 2026-06-10 8:23 UTC (permalink / raw)
To: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Xianwei Zhao,
Kevin Hilman, Martin Blumenstingl
Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
linux-arm-kernel, Jian Hu, Conor Dooley
This series adds Amlogic A9 AO clock support, including dt-binding and AO clock driver.
Signed-off-by: Jian Hu <jian.hu@amlogic.com>
---
Changes in v3:
- Move COMPILE_TEST after 'depends on ARM64' reported by sashiko-bot.
- Rename i2c3 to i3c reported by sashiko-bot.
- Reword the comment describing ao_xtal_in's flags.
- Use struct clk_init_data to describe ao_xtal_in's hw.init.
- Link to v2: https://lore.kernel.org/r/20260603-a9_aoclk-v2-0-f47ea616ee78@amlogic.com
Changes in v2:
- Split the A9 clock driver and send the AO clock separately.
- Rename aobus to soc.
- Use CLK_HW_INIT_FW_NAME to describe clk_init_data.
- Use CLK_HW_INIT_PARENTS_DATA to describe clk_init_data.
- Use a9_ao prefix for MESON_COMP_SEL.
- Correct duandiv name.
- Fix pwm b reg.
- Link to v1: https://lore.kernel.org/all/20260511-b4-a9_clk-v1-0-41cb4071b7c9@amlogic.com/
---
Jian Hu (2):
dt-bindings: clock: Add Amlogic A9 AO clock controller
clk: amlogic: Add A9 AO clock controller driver
.../bindings/clock/amlogic,a9-aoclkc.yaml | 76 ++++
drivers/clk/meson/Kconfig | 13 +
drivers/clk/meson/Makefile | 1 +
drivers/clk/meson/a9-aoclk.c | 431 +++++++++++++++++++++
include/dt-bindings/clock/amlogic,a9-aoclkc.h | 76 ++++
5 files changed, 597 insertions(+)
---
base-commit: ca89c88bcf69daca829044c638a8163d5ce47af0
change-id: 20260603-a9_aoclk-bbf531badc63
Best regards,
--
Jian Hu <jian.hu@amlogic.com>
^ permalink raw reply
* [soc:soc/drivers] BUILD SUCCESS 3659b131999f71aa5a261e7684821ee355cc0234
From: kernel test robot @ 2026-06-10 8:19 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linux-arm-kernel, arm
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git soc/drivers
branch HEAD: 3659b131999f71aa5a261e7684821ee355cc0234 Merge tag 'riscv-soc-drivers-for-v7.2' of https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux into soc/drivers
elapsed time: 844m
configs tested: 228
configs skipped: 2
The following configs have been built successfully.
More configs may be tested in the coming days.
tested configs:
alpha allnoconfig gcc-16.1.0
alpha allyesconfig gcc-16.1.0
alpha defconfig gcc-16.1.0
arc allmodconfig clang-23
arc allmodconfig gcc-16.1.0
arc allnoconfig gcc-16.1.0
arc allyesconfig clang-23
arc allyesconfig gcc-16.1.0
arc defconfig gcc-16.1.0
arc randconfig-001-20260610 gcc-8.5.0
arc randconfig-002-20260610 gcc-8.5.0
arm allnoconfig clang-23
arm allnoconfig gcc-16.1.0
arm allyesconfig clang-23
arm allyesconfig gcc-16.1.0
arm defconfig gcc-16.1.0
arm randconfig-001-20260610 gcc-8.5.0
arm randconfig-002-20260610 gcc-8.5.0
arm randconfig-003-20260610 gcc-8.5.0
arm randconfig-004-20260610 gcc-8.5.0
arm64 allmodconfig clang-23
arm64 allnoconfig gcc-16.1.0
arm64 defconfig gcc-16.1.0
arm64 randconfig-001-20260610 gcc-11.5.0
arm64 randconfig-002-20260610 gcc-11.5.0
arm64 randconfig-003-20260610 gcc-11.5.0
arm64 randconfig-004-20260610 gcc-11.5.0
csky allmodconfig gcc-16.1.0
csky allnoconfig gcc-16.1.0
csky defconfig gcc-16.1.0
csky randconfig-001-20260610 gcc-11.5.0
csky randconfig-002-20260610 gcc-11.5.0
hexagon allmodconfig gcc-16.1.0
hexagon allnoconfig clang-23
hexagon allnoconfig gcc-16.1.0
hexagon defconfig gcc-16.1.0
hexagon randconfig-001 gcc-11.5.0
hexagon randconfig-001-20260610 clang-22
hexagon randconfig-001-20260610 gcc-11.5.0
hexagon randconfig-002 gcc-11.5.0
hexagon randconfig-002-20260610 clang-22
hexagon randconfig-002-20260610 gcc-11.5.0
i386 allmodconfig clang-22
i386 allnoconfig gcc-14
i386 allnoconfig gcc-16.1.0
i386 allyesconfig clang-22
i386 buildonly-randconfig-001-20260610 gcc-14
i386 buildonly-randconfig-002-20260610 gcc-14
i386 buildonly-randconfig-003-20260610 gcc-14
i386 buildonly-randconfig-004-20260610 gcc-14
i386 buildonly-randconfig-005-20260610 gcc-14
i386 buildonly-randconfig-006-20260610 gcc-14
i386 defconfig gcc-16.1.0
i386 randconfig-001-20260610 gcc-14
i386 randconfig-002-20260610 gcc-14
i386 randconfig-003-20260610 gcc-14
i386 randconfig-004-20260610 gcc-14
i386 randconfig-005-20260610 gcc-14
i386 randconfig-006-20260610 gcc-14
i386 randconfig-007-20260610 gcc-14
i386 randconfig-011 gcc-14
i386 randconfig-011-20260610 gcc-14
i386 randconfig-012 gcc-14
i386 randconfig-012-20260610 gcc-14
i386 randconfig-013 gcc-14
i386 randconfig-013-20260610 gcc-14
i386 randconfig-014 gcc-14
i386 randconfig-014-20260610 gcc-14
i386 randconfig-015 gcc-14
i386 randconfig-015-20260610 gcc-14
i386 randconfig-016 gcc-14
i386 randconfig-016-20260610 gcc-14
i386 randconfig-017 gcc-14
i386 randconfig-017-20260610 gcc-14
loongarch allmodconfig clang-19
loongarch allmodconfig clang-23
loongarch allnoconfig clang-20
loongarch allnoconfig gcc-16.1.0
loongarch defconfig clang-23
loongarch randconfig-001 gcc-11.5.0
loongarch randconfig-001-20260610 clang-22
loongarch randconfig-001-20260610 gcc-11.5.0
loongarch randconfig-002 gcc-11.5.0
loongarch randconfig-002-20260610 clang-22
loongarch randconfig-002-20260610 gcc-11.5.0
m68k allmodconfig gcc-16.1.0
m68k allnoconfig gcc-16.1.0
m68k allyesconfig clang-23
m68k allyesconfig gcc-16.1.0
m68k apollo_defconfig gcc-16.1.0
m68k defconfig clang-23
microblaze allnoconfig gcc-16.1.0
microblaze allyesconfig gcc-16.1.0
microblaze defconfig clang-23
mips allmodconfig gcc-16.1.0
mips allnoconfig gcc-16.1.0
mips allyesconfig gcc-16.1.0
mips lemote2f_defconfig gcc-16.1.0
nios2 allmodconfig clang-20
nios2 allmodconfig gcc-11.5.0
nios2 allnoconfig clang-23
nios2 allnoconfig gcc-11.5.0
nios2 defconfig clang-23
nios2 randconfig-001 gcc-11.5.0
nios2 randconfig-001-20260610 clang-22
nios2 randconfig-001-20260610 gcc-11.5.0
nios2 randconfig-002 gcc-11.5.0
nios2 randconfig-002-20260610 clang-22
nios2 randconfig-002-20260610 gcc-11.5.0
openrisc allmodconfig clang-20
openrisc allmodconfig gcc-16.1.0
openrisc allnoconfig clang-23
openrisc allnoconfig gcc-16.1.0
openrisc defconfig gcc-16.1.0
parisc allmodconfig gcc-16.1.0
parisc allnoconfig clang-23
parisc allnoconfig gcc-16.1.0
parisc allyesconfig clang-23
parisc allyesconfig gcc-16.1.0
parisc defconfig gcc-16.1.0
parisc randconfig-001 gcc-8.5.0
parisc randconfig-001-20260610 gcc-8.5.0
parisc randconfig-002 gcc-8.5.0
parisc randconfig-002-20260610 gcc-8.5.0
parisc64 defconfig clang-23
powerpc allmodconfig gcc-16.1.0
powerpc allnoconfig clang-23
powerpc allnoconfig gcc-16.1.0
powerpc microwatt_defconfig gcc-16.1.0
powerpc pasemi_defconfig clang-23
powerpc randconfig-001 gcc-8.5.0
powerpc randconfig-001-20260610 gcc-8.5.0
powerpc randconfig-002 gcc-8.5.0
powerpc randconfig-002-20260610 gcc-8.5.0
powerpc64 randconfig-001 gcc-8.5.0
powerpc64 randconfig-001-20260610 gcc-8.5.0
powerpc64 randconfig-002 gcc-8.5.0
powerpc64 randconfig-002-20260610 gcc-8.5.0
riscv allmodconfig clang-23
riscv allnoconfig clang-23
riscv allnoconfig gcc-16.1.0
riscv allyesconfig clang-23
riscv defconfig gcc-16.1.0
riscv randconfig-001 gcc-16.1.0
riscv randconfig-001-20260610 gcc-16.1.0
riscv randconfig-002 gcc-16.1.0
riscv randconfig-002-20260610 gcc-16.1.0
s390 allmodconfig clang-23
s390 allnoconfig clang-23
s390 allyesconfig gcc-16.1.0
s390 defconfig gcc-16.1.0
s390 randconfig-001 gcc-16.1.0
s390 randconfig-001-20260610 gcc-16.1.0
s390 randconfig-002 gcc-16.1.0
s390 randconfig-002-20260610 gcc-16.1.0
sh allmodconfig gcc-16.1.0
sh allnoconfig clang-23
sh allnoconfig gcc-16.1.0
sh allyesconfig clang-23
sh allyesconfig gcc-16.1.0
sh defconfig gcc-14
sh polaris_defconfig gcc-16.1.0
sh randconfig-001 gcc-16.1.0
sh randconfig-001-20260610 gcc-16.1.0
sh randconfig-002 gcc-16.1.0
sh randconfig-002-20260610 gcc-16.1.0
sh se7724_defconfig gcc-16.1.0
sparc allnoconfig clang-23
sparc allnoconfig gcc-16.1.0
sparc defconfig gcc-16.1.0
sparc randconfig-001-20260610 gcc-14.3.0
sparc randconfig-002-20260610 gcc-14.3.0
sparc64 allmodconfig clang-20
sparc64 defconfig gcc-14
sparc64 randconfig-001-20260610 gcc-14.3.0
sparc64 randconfig-002-20260610 gcc-14.3.0
um allmodconfig clang-23
um allnoconfig clang-16
um allnoconfig clang-23
um allyesconfig gcc-14
um allyesconfig gcc-16.1.0
um defconfig gcc-14
um i386_defconfig gcc-14
um randconfig-001-20260610 gcc-14.3.0
um randconfig-002-20260610 gcc-14.3.0
um x86_64_defconfig gcc-14
x86_64 allmodconfig clang-22
x86_64 allnoconfig clang-22
x86_64 allnoconfig clang-23
x86_64 allyesconfig clang-22
x86_64 buildonly-randconfig-001-20260610 gcc-14
x86_64 buildonly-randconfig-002-20260610 gcc-14
x86_64 buildonly-randconfig-003-20260610 gcc-14
x86_64 buildonly-randconfig-004-20260610 gcc-14
x86_64 buildonly-randconfig-005-20260610 gcc-14
x86_64 buildonly-randconfig-006-20260610 gcc-14
x86_64 defconfig gcc-14
x86_64 kexec clang-22
x86_64 randconfig-001-20260610 gcc-13
x86_64 randconfig-002-20260610 gcc-13
x86_64 randconfig-003-20260610 gcc-13
x86_64 randconfig-004-20260610 gcc-13
x86_64 randconfig-005-20260610 gcc-13
x86_64 randconfig-006-20260610 gcc-13
x86_64 randconfig-011-20260610 gcc-14
x86_64 randconfig-012-20260610 gcc-14
x86_64 randconfig-013-20260610 gcc-14
x86_64 randconfig-014-20260610 gcc-14
x86_64 randconfig-015-20260610 gcc-14
x86_64 randconfig-016-20260610 gcc-14
x86_64 randconfig-071-20260610 gcc-14
x86_64 randconfig-072-20260610 gcc-14
x86_64 randconfig-073-20260610 gcc-14
x86_64 randconfig-074-20260610 gcc-14
x86_64 randconfig-075-20260610 gcc-14
x86_64 randconfig-076-20260610 gcc-14
x86_64 rhel-9.4 clang-22
x86_64 rhel-9.4-bpf gcc-14
x86_64 rhel-9.4-func clang-22
x86_64 rhel-9.4-kselftests clang-22
x86_64 rhel-9.4-kunit gcc-14
x86_64 rhel-9.4-ltp gcc-14
x86_64 rhel-9.4-rust clang-22
xtensa allnoconfig clang-23
xtensa allnoconfig gcc-16.1.0
xtensa allyesconfig clang-20
xtensa randconfig-001-20260610 gcc-14.3.0
xtensa randconfig-002-20260610 gcc-14.3.0
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* [PATCH v3 2/2] clk: amlogic: Add A9 peripherals clock controller driver
From: Jian Hu via B4 Relay @ 2026-06-10 8:14 UTC (permalink / raw)
To: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Xianwei Zhao,
Kevin Hilman, Martin Blumenstingl
Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
linux-arm-kernel, Jian Hu
In-Reply-To: <20260610-a9_peripherals-v3-0-d07a78085f71@amlogic.com>
From: Jian Hu <jian.hu@amlogic.com>
Add the peripherals clock controller driver for the Amlogic A9 SoC family.
Signed-off-by: Jian Hu <jian.hu@amlogic.com>
---
drivers/clk/meson/Kconfig | 15 +
drivers/clk/meson/Makefile | 1 +
drivers/clk/meson/a9-peripherals.c | 1925 ++++++++++++++++++++++++++++++++++++
3 files changed, 1941 insertions(+)
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index cf8cf3f9e4ee..86d2e270e1b8 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -132,6 +132,21 @@ config COMMON_CLK_A1_PERIPHERALS
device, A1 SoC Family. Say Y if you want A1 Peripherals clock
controller to work.
+config COMMON_CLK_A9_PERIPHERALS
+ tristate "Amlogic A9 SoC peripherals clock controller support"
+ depends on ARM64 || COMPILE_TEST
+ default ARCH_MESON
+ select COMMON_CLK_MESON_REGMAP
+ select COMMON_CLK_MESON_CLKC_UTILS
+ select COMMON_CLK_MESON_DUALDIV
+ select COMMON_CLK_MESON_VID_PLL_DIV
+ imply COMMON_CLK_SCMI
+ imply COMMON_CLK_A9_PLL
+ help
+ Support for the peripherals clock controller on Amlogic A311Y3 based
+ device, AKA A9. Peripherals are required by most peripheral to operate.
+ Say Y if you want A9 peripherals clock controller to work.
+
config COMMON_CLK_C3_PLL
tristate "Amlogic C3 PLL clock controller"
depends on ARM64
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index c6719694a242..bccd9ace9201 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o
obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o
+obj-$(CONFIG_COMMON_CLK_A9_PERIPHERALS) += a9-peripherals.o
obj-$(CONFIG_COMMON_CLK_C3_PLL) += c3-pll.o
obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
diff --git a/drivers/clk/meson/a9-peripherals.c b/drivers/clk/meson/a9-peripherals.c
new file mode 100644
index 000000000000..fef48613e186
--- /dev/null
+++ b/drivers/clk/meson/a9-peripherals.c
@@ -0,0 +1,1925 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
+/*
+ * Copyright (C) 2026 Amlogic, Inc. All rights reserved
+ */
+
+#include <dt-bindings/clock/amlogic,a9-peripherals-clkc.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+#include "clk-regmap.h"
+#include "clk-dualdiv.h"
+#include "meson-clkc-utils.h"
+#include "vid-pll-div.h"
+
+#define SYS_CLK_EN0_REG0 0x30
+#define SYS_CLK_EN0_REG1 0x34
+#define SYS_CLK_EN0_REG2 0x38
+#define SYS_CLK_EN0_REG3 0x3c
+#define SD_EMMC_CLK_CTRL0 0x90
+#define SD_EMMC_CLK_CTRL1 0x94
+#define PWM_CLK_H_CTRL 0xbc
+#define PWM_CLK_I_CTRL 0xc0
+#define PWM_CLK_J_CTRL 0xc4
+#define PWM_CLK_K_CTRL 0xc8
+#define PWM_CLK_L_CTRL 0xcc
+#define PWM_CLK_M_CTRL 0xd0
+#define PWM_CLK_N_CTRL 0xd4
+#define SPISG_CLK_CTRL 0x100
+#define SPISG_CLK_CTRL1 0x104
+#define SAR_CLK_CTRL 0x150
+#define AMFC_CLK_CTRL 0x154
+#define NNA_CLK_CTRL 0x15c
+#define USB_CLK_CTRL 0x160
+#define PCIE_TL_CLK_CTRL 0x164
+#define CMPR_CLK_CTRL 0x168
+#define DEWARP_CLK_CTRL 0x16c
+#define SC_CLK_CTRL 0x170
+#define DPTX_CLK_CTRL 0x178
+#define ISP_CLK_CTRL 0x17c
+#define CVE_CLK_CTRL 0x180
+#define PP_CLK_CTRL 0x184
+#define GLB_CLK_CTRL 0x188
+#define USB_CLK_CTRL0 0x18c
+#define USB_CLK_CTRL1 0x190
+#define CAN_CLK_CTRL 0x194
+#define CAN_CLK_CTRL1 0x198
+#define I3C_CLK_CTRL 0x19c
+#define TS_CLK_CTRL 0x1a0
+#define ETH_CLK_CTRL 0x1a4
+#define GEN_CLK_CTRL 0x1a8
+#define CLK12_24_CTRL 0x1ac
+#define MALI_CLK_CTRL 0x200
+#define MALI_STACK_CLK_CTRL 0x204
+#define DSPA_CLK_CTRL 0x220
+#define HEVCF_CLK_CTRL 0x240
+#define HCODEC_CLK_CTRL 0x244
+#define VPU_CLK_CTRL 0x260
+#define VAPB_CLK_CTRL 0x268
+#define VPU_CLKB_CTRL 0x280
+#define HDMI_CLK_CTRL 0x284
+#define HTX_CLK_CTRL 0x28c
+#define HTX_CLK_CTRL1 0x290
+#define HRX_CLK_CTRL 0x294
+#define HRX_CLK_CTRL1 0x298
+#define HRX_CLK_CTRL2 0x29c
+#define HRX_CLK_CTRL3 0x2a0
+#define VID_LOCK_CLK_CTRL 0x2a4
+#define VDIN_MEAS_CLK_CTRL 0x2a8
+#define VID_PLL_CLK_DIV 0x2b0
+#define VID_CLK_CTRL 0x2c0
+#define VID_CLK_CTRL2 0x2c4
+#define VID_CLK_DIV 0x2c8
+#define VIID_CLK_DIV 0x2cc
+#define VIID_CLK_CTRL 0x2d0
+#define MIPI_CSI_PHY_CLK_CTRL 0x2e0
+#define DSI_MEAS_CLK_CTRL 0x2f4
+
+#define A9_COMP_SEL(_name, _reg, _shift, _mask, _pdata, _table) \
+ MESON_COMP_SEL(a9_, _name, _reg, _shift, _mask, _pdata, _table, 0, 0)
+
+#define A9_COMP_DIV(_name, _reg, _shift, _width) \
+ MESON_COMP_DIV(a9_, _name, _reg, _shift, _width, 0, CLK_SET_RATE_PARENT)
+
+#define A9_COMP_GATE(_name, _reg, _bit, _iflags) \
+ MESON_COMP_GATE(a9_, _name, _reg, _bit, CLK_SET_RATE_PARENT | (_iflags))
+
+static const struct clk_parent_data a9_sys_pclk_parents = { .fw_name = "sys" };
+
+#define A9_SYS_PCLK(_name, _reg, _bit) \
+ MESON_PCLK(a9_##_name, _reg, _bit, &a9_sys_pclk_parents, 0)
+
+static A9_SYS_PCLK(sys_am_axi, SYS_CLK_EN0_REG0, 0);
+static A9_SYS_PCLK(sys_dos, SYS_CLK_EN0_REG0, 1);
+static A9_SYS_PCLK(sys_mipi_dsi, SYS_CLK_EN0_REG0, 3);
+static A9_SYS_PCLK(sys_eth_phy, SYS_CLK_EN0_REG0, 4);
+static A9_SYS_PCLK(sys_amfc, SYS_CLK_EN0_REG0, 5);
+static A9_SYS_PCLK(sys_mali, SYS_CLK_EN0_REG0, 6);
+static A9_SYS_PCLK(sys_nna, SYS_CLK_EN0_REG0, 7);
+static A9_SYS_PCLK(sys_eth_axi, SYS_CLK_EN0_REG0, 8);
+static A9_SYS_PCLK(sys_dp_apb, SYS_CLK_EN0_REG0, 9);
+static A9_SYS_PCLK(sys_edptx_apb, SYS_CLK_EN0_REG0, 10);
+static A9_SYS_PCLK(sys_u3hsg, SYS_CLK_EN0_REG0, 11);
+static A9_SYS_PCLK(sys_aucpu, SYS_CLK_EN0_REG0, 14);
+static A9_SYS_PCLK(sys_glb, SYS_CLK_EN0_REG0, 15);
+static A9_SYS_PCLK(sys_combo_dphy_apb, SYS_CLK_EN0_REG0, 17);
+static A9_SYS_PCLK(sys_hdmirx_apb, SYS_CLK_EN0_REG0, 18);
+static A9_SYS_PCLK(sys_hdmirx_pclk, SYS_CLK_EN0_REG0, 19);
+static A9_SYS_PCLK(sys_mipi_dsi_phy, SYS_CLK_EN0_REG0, 20);
+static A9_SYS_PCLK(sys_can0, SYS_CLK_EN0_REG0, 21);
+static A9_SYS_PCLK(sys_can1, SYS_CLK_EN0_REG0, 22);
+static A9_SYS_PCLK(sys_sd_emmc_a, SYS_CLK_EN0_REG0, 24);
+static A9_SYS_PCLK(sys_sd_emmc_b, SYS_CLK_EN0_REG0, 25);
+static A9_SYS_PCLK(sys_sd_emmc_c, SYS_CLK_EN0_REG0, 26);
+static A9_SYS_PCLK(sys_sc, SYS_CLK_EN0_REG0, 27);
+static A9_SYS_PCLK(sys_acodec, SYS_CLK_EN0_REG0, 28);
+static A9_SYS_PCLK(sys_mipi_isp, SYS_CLK_EN0_REG0, 29);
+static A9_SYS_PCLK(sys_msr, SYS_CLK_EN0_REG0, 30);
+static A9_SYS_PCLK(sys_audio, SYS_CLK_EN0_REG1, 0);
+static A9_SYS_PCLK(sys_mipi_dsi_b, SYS_CLK_EN0_REG1, 1);
+static A9_SYS_PCLK(sys_mipi_dsi1_phy, SYS_CLK_EN0_REG1, 2);
+static A9_SYS_PCLK(sys_eth, SYS_CLK_EN0_REG1, 3);
+static A9_SYS_PCLK(sys_eth_1g_mac, SYS_CLK_EN0_REG1, 4);
+static A9_SYS_PCLK(sys_uart_a, SYS_CLK_EN0_REG1, 5);
+static A9_SYS_PCLK(sys_uart_f, SYS_CLK_EN0_REG1, 10);
+static A9_SYS_PCLK(sys_ts_a55, SYS_CLK_EN0_REG1, 11);
+static A9_SYS_PCLK(sys_eth_1g_axi, SYS_CLK_EN0_REG1, 12);
+static A9_SYS_PCLK(sys_ts_dos, SYS_CLK_EN0_REG1, 13);
+static A9_SYS_PCLK(sys_u3drd_b, SYS_CLK_EN0_REG1, 14);
+static A9_SYS_PCLK(sys_ts_core, SYS_CLK_EN0_REG1, 15);
+static A9_SYS_PCLK(sys_ts_pll, SYS_CLK_EN0_REG1, 16);
+static A9_SYS_PCLK(sys_csi_dig_clkin, SYS_CLK_EN0_REG1, 18);
+static A9_SYS_PCLK(sys_cve, SYS_CLK_EN0_REG1, 19);
+static A9_SYS_PCLK(sys_ge2d, SYS_CLK_EN0_REG1, 20);
+static A9_SYS_PCLK(sys_spisg, SYS_CLK_EN0_REG1, 21);
+static A9_SYS_PCLK(sys_u3drd_1, SYS_CLK_EN0_REG1, 22);
+static A9_SYS_PCLK(sys_u2h, SYS_CLK_EN0_REG1, 23);
+static A9_SYS_PCLK(sys_pcie_mac_a, SYS_CLK_EN0_REG1, 24);
+static A9_SYS_PCLK(sys_u3drd_a, SYS_CLK_EN0_REG1, 25);
+static A9_SYS_PCLK(sys_u2drd, SYS_CLK_EN0_REG1, 26);
+static A9_SYS_PCLK(sys_pcie_phy, SYS_CLK_EN0_REG1, 27);
+static A9_SYS_PCLK(sys_pcie_mac_b, SYS_CLK_EN0_REG1, 28);
+static A9_SYS_PCLK(sys_periph, SYS_CLK_EN0_REG1, 29);
+static A9_SYS_PCLK(sys_pio, SYS_CLK_EN0_REG2, 0);
+static A9_SYS_PCLK(sys_i3c, SYS_CLK_EN0_REG2, 1);
+static A9_SYS_PCLK(sys_i2c_m_e, SYS_CLK_EN0_REG2, 2);
+static A9_SYS_PCLK(sys_i2c_m_f, SYS_CLK_EN0_REG2, 3);
+static A9_SYS_PCLK(sys_hdmitx_apb, SYS_CLK_EN0_REG2, 4);
+static A9_SYS_PCLK(sys_i2c_m_i, SYS_CLK_EN0_REG2, 5);
+static A9_SYS_PCLK(sys_i2c_m_g, SYS_CLK_EN0_REG2, 6);
+static A9_SYS_PCLK(sys_i2c_m_h, SYS_CLK_EN0_REG2, 7);
+static A9_SYS_PCLK(sys_hdmi20_aes, SYS_CLK_EN0_REG2, 9);
+static A9_SYS_PCLK(sys_csi2_host, SYS_CLK_EN0_REG2, 16);
+static A9_SYS_PCLK(sys_csi2_adapt, SYS_CLK_EN0_REG2, 17);
+static A9_SYS_PCLK(sys_dspa, SYS_CLK_EN0_REG2, 21);
+static A9_SYS_PCLK(sys_pp_dma, SYS_CLK_EN0_REG2, 22);
+static A9_SYS_PCLK(sys_pp_wrapper, SYS_CLK_EN0_REG2, 23);
+static A9_SYS_PCLK(sys_vpu_intr, SYS_CLK_EN0_REG2, 25);
+static A9_SYS_PCLK(sys_csi2_phy, SYS_CLK_EN0_REG2, 27);
+static A9_SYS_PCLK(sys_saradc, SYS_CLK_EN0_REG2, 28);
+static A9_SYS_PCLK(sys_pwm_j, SYS_CLK_EN0_REG2, 30);
+static A9_SYS_PCLK(sys_pwm_i, SYS_CLK_EN0_REG2, 31);
+static A9_SYS_PCLK(sys_pwm_h, SYS_CLK_EN0_REG3, 0);
+static A9_SYS_PCLK(sys_pwm_n, SYS_CLK_EN0_REG3, 8);
+static A9_SYS_PCLK(sys_pwm_m, SYS_CLK_EN0_REG3, 9);
+static A9_SYS_PCLK(sys_pwm_l, SYS_CLK_EN0_REG3, 10);
+static A9_SYS_PCLK(sys_pwm_k, SYS_CLK_EN0_REG3, 11);
+
+/* Channel 5 is unconnected. */
+static u32 a9_sd_emmc_parents_val_table[] = { 0, 1, 2, 3, 4, 6, 7 };
+static const struct clk_parent_data a9_sd_emmc_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "gp1", },
+ { .fw_name = "gp0", }
+};
+
+static A9_COMP_SEL(sd_emmc_a, SD_EMMC_CLK_CTRL0, 9, 0x7, a9_sd_emmc_parents,
+ a9_sd_emmc_parents_val_table);
+static A9_COMP_DIV(sd_emmc_a, SD_EMMC_CLK_CTRL0, 0, 7);
+static A9_COMP_GATE(sd_emmc_a, SD_EMMC_CLK_CTRL0, 8, 0);
+
+static A9_COMP_SEL(sd_emmc_b, SD_EMMC_CLK_CTRL0, 25, 0x7, a9_sd_emmc_parents,
+ a9_sd_emmc_parents_val_table);
+static A9_COMP_DIV(sd_emmc_b, SD_EMMC_CLK_CTRL0, 16, 7);
+static A9_COMP_GATE(sd_emmc_b, SD_EMMC_CLK_CTRL0, 24, 0);
+
+static A9_COMP_SEL(sd_emmc_c, SD_EMMC_CLK_CTRL1, 9, 0x7, a9_sd_emmc_parents,
+ a9_sd_emmc_parents_val_table);
+static A9_COMP_DIV(sd_emmc_c, SD_EMMC_CLK_CTRL1, 0, 7);
+static A9_COMP_GATE(sd_emmc_c, SD_EMMC_CLK_CTRL1, 8, 0);
+
+static const struct clk_parent_data a9_pwm_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", }
+};
+
+static A9_COMP_SEL(pwm_h, PWM_CLK_H_CTRL, 9, 0x7, a9_pwm_parents, NULL);
+static A9_COMP_DIV(pwm_h, PWM_CLK_H_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_h, PWM_CLK_H_CTRL, 8, 0);
+
+static A9_COMP_SEL(pwm_i, PWM_CLK_I_CTRL, 9, 0x7, a9_pwm_parents, NULL);
+static A9_COMP_DIV(pwm_i, PWM_CLK_I_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_i, PWM_CLK_I_CTRL, 8, 0);
+
+static A9_COMP_SEL(pwm_j, PWM_CLK_J_CTRL, 9, 0x7, a9_pwm_parents, NULL);
+static A9_COMP_DIV(pwm_j, PWM_CLK_J_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_j, PWM_CLK_J_CTRL, 8, 0);
+
+static A9_COMP_SEL(pwm_k, PWM_CLK_K_CTRL, 9, 0x7, a9_pwm_parents, NULL);
+static A9_COMP_DIV(pwm_k, PWM_CLK_K_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_k, PWM_CLK_K_CTRL, 8, 0);
+
+static A9_COMP_SEL(pwm_l, PWM_CLK_L_CTRL, 9, 0x7, a9_pwm_parents, NULL);
+static A9_COMP_DIV(pwm_l, PWM_CLK_L_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_l, PWM_CLK_L_CTRL, 8, 0);
+
+static A9_COMP_SEL(pwm_m, PWM_CLK_M_CTRL, 9, 0x7, a9_pwm_parents, NULL);
+static A9_COMP_DIV(pwm_m, PWM_CLK_M_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_m, PWM_CLK_M_CTRL, 8, 0);
+
+static A9_COMP_SEL(pwm_n, PWM_CLK_N_CTRL, 9, 0x7, a9_pwm_parents, NULL);
+static A9_COMP_DIV(pwm_n, PWM_CLK_N_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_n, PWM_CLK_N_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_spisg_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "sys", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", },
+ { .fw_name = "gp0", }
+};
+
+static A9_COMP_SEL(spisg, SPISG_CLK_CTRL, 9, 0x7, a9_spisg_parents, NULL);
+static A9_COMP_DIV(spisg, SPISG_CLK_CTRL, 0, 6);
+static A9_COMP_GATE(spisg, SPISG_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(spisg1, SPISG_CLK_CTRL, 25, 0x7, a9_spisg_parents, NULL);
+static A9_COMP_DIV(spisg1, SPISG_CLK_CTRL, 16, 6);
+static A9_COMP_GATE(spisg1, SPISG_CLK_CTRL, 24, 0);
+
+static A9_COMP_SEL(spisg2, SPISG_CLK_CTRL1, 9, 0x7, a9_spisg_parents, NULL);
+static A9_COMP_DIV(spisg2, SPISG_CLK_CTRL1, 0, 6);
+static A9_COMP_GATE(spisg2, SPISG_CLK_CTRL1, 8, 0);
+
+static const struct clk_parent_data a9_saradc_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "sys", }
+};
+
+static A9_COMP_SEL(saradc, SAR_CLK_CTRL, 9, 0x7, a9_saradc_parents, NULL);
+static A9_COMP_DIV(saradc, SAR_CLK_CTRL, 0, 8);
+static A9_COMP_GATE(saradc, SAR_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_amfc_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "sys", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", }
+};
+
+static A9_COMP_SEL(amfc, AMFC_CLK_CTRL, 9, 0x7, a9_amfc_parents, NULL);
+static A9_COMP_DIV(amfc, AMFC_CLK_CTRL, 0, 6);
+static A9_COMP_GATE(amfc, AMFC_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_nna_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "gp2", },
+ { .fw_name = "hifi0", }
+};
+
+static A9_COMP_SEL(nna, NNA_CLK_CTRL, 9, 0x7, a9_nna_parents, NULL);
+static A9_COMP_DIV(nna, NNA_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(nna, NNA_CLK_CTRL, 8, 0);
+
+/* Channel 5 and 6 are unconnected. */
+static u32 a9_usb_250m_parents_val_table[] = { 0, 1, 2, 3, 4, 7 };
+static const struct clk_parent_data a9_usb_250m_parents[] = {
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv7", },
+ { .fw_name = "fdiv2p5", }
+};
+
+static A9_COMP_SEL(usb_250m, USB_CLK_CTRL, 9, 0x7, a9_usb_250m_parents,
+ a9_usb_250m_parents_val_table);
+static A9_COMP_DIV(usb_250m, USB_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(usb_250m, USB_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_usb_48m_pre_parents[] = {
+ { .fw_name = "gp0", },
+ { .fw_name = "gp1", },
+ { .fw_name = "gp2", },
+ { .fw_name = "fdiv2", },
+};
+
+static A9_COMP_SEL(usb_48m_pre, USB_CLK_CTRL, 25, 0x3, a9_usb_48m_pre_parents,
+ NULL);
+static A9_COMP_DIV(usb_48m_pre, USB_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(usb_48m_pre, USB_CLK_CTRL, 24, 0);
+
+static const struct clk_parent_data a9_pcie_tl_parents[] = {
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "gp0", },
+ { .fw_name = "sys", },
+ { .fw_name = "xtal", }
+};
+
+static A9_COMP_SEL(pcie_tl, PCIE_TL_CLK_CTRL, 9, 0x7, a9_pcie_tl_parents,
+ NULL);
+static A9_COMP_DIV(pcie_tl, PCIE_TL_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(pcie_tl, PCIE_TL_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(pcie1_tl, PCIE_TL_CLK_CTRL, 25, 0x7, a9_pcie_tl_parents,
+ NULL);
+static A9_COMP_DIV(pcie1_tl, PCIE_TL_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(pcie1_tl, PCIE_TL_CLK_CTRL, 24, 0);
+
+static const struct clk_parent_data a9_cmpr_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "gp1", }
+};
+
+static A9_COMP_SEL(cmpr, CMPR_CLK_CTRL, 25, 0x7, a9_cmpr_parents, NULL);
+static A9_COMP_DIV(cmpr, CMPR_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(cmpr, CMPR_CLK_CTRL, 24, 0);
+
+static const struct clk_parent_data a9_dewarpa_parents[] = {
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", },
+ { .fw_name = "gp0", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "gp1", }
+};
+
+static A9_COMP_SEL(dewarpa, DEWARP_CLK_CTRL, 9, 0x7, a9_dewarpa_parents, NULL);
+static A9_COMP_DIV(dewarpa, DEWARP_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(dewarpa, DEWARP_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_sc_parents[] = {
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "xtal", }
+};
+
+static A9_COMP_SEL(sc_pre, SC_CLK_CTRL, 9, 0x7, a9_sc_parents, NULL);
+static A9_COMP_DIV(sc_pre, SC_CLK_CTRL, 0, 8);
+static A9_COMP_GATE(sc_pre, SC_CLK_CTRL, 8, 0);
+
+static struct clk_regmap a9_sc = {
+ .data = &(struct clk_regmap_div_data) {
+ .offset = SC_CLK_CTRL,
+ .shift = 16,
+ .width = 4,
+ },
+ .hw.init = CLK_HW_INIT_HW("sc", &a9_sc_pre.hw,
+ &clk_regmap_divider_ops, CLK_SET_RATE_PARENT),
+};
+
+static const struct clk_parent_data a9_dptx_apb2_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "sys", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", }
+};
+
+static A9_COMP_SEL(dptx_apb2, DPTX_CLK_CTRL, 9, 0x7, a9_dptx_apb2_parents, NULL);
+static A9_COMP_DIV(dptx_apb2, DPTX_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(dptx_apb2, DPTX_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_dptx_aud_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "sys", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", }
+};
+
+static A9_COMP_SEL(dptx_aud, DPTX_CLK_CTRL, 25, 0x7, a9_dptx_aud_parents, NULL);
+static A9_COMP_DIV(dptx_aud, DPTX_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(dptx_aud, DPTX_CLK_CTRL, 24, 0);
+
+static const struct clk_parent_data a9_isp_parents[] = {
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "gp0", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "xtal", }
+};
+
+static A9_COMP_SEL(isp, ISP_CLK_CTRL, 9, 0x7, a9_isp_parents, NULL);
+static A9_COMP_DIV(isp, ISP_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(isp, ISP_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_cve_vge_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "gp0", },
+ { .fw_name = "rtc", }
+};
+
+static A9_COMP_SEL(cve, CVE_CLK_CTRL, 9, 0x7, a9_cve_vge_parents, NULL);
+static A9_COMP_DIV(cve, CVE_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(cve, CVE_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(vge, CVE_CLK_CTRL, 25, 0x7, a9_cve_vge_parents, NULL);
+static A9_COMP_DIV(vge, CVE_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(vge, CVE_CLK_CTRL, 24, 0);
+
+static const struct clk_parent_data a9_pp_parents[] = {
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "gp0", },
+ { .fw_name = "sys", },
+ { .fw_name = "xtal", }
+};
+
+static A9_COMP_SEL(pp, PP_CLK_CTRL, 9, 0x7, a9_pp_parents, NULL);
+static A9_COMP_DIV(pp, PP_CLK_CTRL, 0, 6);
+static A9_COMP_GATE(pp, PP_CLK_CTRL, 8, 0);
+
+/* Channel 6 is unconnected. */
+static u32 a9_glb_parents_val_table[] = { 0, 1, 2, 3, 4, 5, 7 };
+static struct clk_regmap a9_dspa;
+
+static const struct clk_parent_data a9_glb_parents[] = {
+ { .fw_name = "xtal", },
+ { .hw = &a9_dspa.hw },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .hw = &a9_isp.hw },
+ { .fw_name = "rtc", }
+};
+
+static A9_COMP_SEL(glb, GLB_CLK_CTRL, 9, 0x7, a9_glb_parents,
+ a9_glb_parents_val_table);
+static A9_COMP_DIV(glb, GLB_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(glb, GLB_CLK_CTRL, 8, 0);
+
+static struct clk_regmap a9_usb_48m_dualdiv_in = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = USB_CLK_CTRL,
+ .bit_idx = 31,
+ },
+ .hw.init = CLK_HW_INIT_HW("usb_48m_dualdiv_in", &a9_usb_48m_pre.hw,
+ &clk_regmap_gate_ops, 0),
+};
+
+static const struct meson_clk_dualdiv_param a9_usb_48m_dualdiv_div_table[] = {
+ { 733, 732, 8, 11, 1 },
+ { /* sentinel */ }
+};
+
+static struct clk_regmap a9_usb_48m_dualdiv_div = {
+ .data = &(struct meson_clk_dualdiv_data) {
+ .n1 = {
+ .reg_off = USB_CLK_CTRL0,
+ .shift = 0,
+ .width = 12,
+ },
+ .n2 = {
+ .reg_off = USB_CLK_CTRL0,
+ .shift = 12,
+ .width = 12,
+ },
+ .m1 = {
+ .reg_off = USB_CLK_CTRL1,
+ .shift = 0,
+ .width = 12,
+ },
+ .m2 = {
+ .reg_off = USB_CLK_CTRL1,
+ .shift = 12,
+ .width = 12,
+ },
+ .dual = {
+ .reg_off = USB_CLK_CTRL0,
+ .shift = 28,
+ .width = 1,
+ },
+ .table = a9_usb_48m_dualdiv_div_table,
+ },
+ .hw.init = CLK_HW_INIT_HW("usb_48m_dualdiv_div", &a9_usb_48m_dualdiv_in.hw,
+ &meson_clk_dualdiv_ops, 0),
+};
+
+static struct clk_regmap a9_usb_48m_dualdiv_sel = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = USB_CLK_CTRL1,
+ .mask = 0x1,
+ .shift = 24,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("usb_48m_dualdiv_sel",
+ ((const struct clk_hw *[]) {
+ &a9_usb_48m_dualdiv_in.hw,
+ &a9_usb_48m_dualdiv_div.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_usb_48m_dualdiv = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = USB_CLK_CTRL0,
+ .bit_idx = 30,
+ },
+ .hw.init = CLK_HW_INIT_HW("usb_48m_dualdiv", &a9_usb_48m_dualdiv_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_usb_48m = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = USB_CLK_CTRL1,
+ .mask = 0x3,
+ .shift = 30,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("usb_48m",
+ ((const struct clk_hw *[]) {
+ &a9_usb_48m_pre.hw,
+ &a9_usb_48m_dualdiv.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+/* Channel 3 is unconnected. */
+static u32 a9_can_pe_parents_val_table[] = { 0, 1, 3 };
+static const struct clk_parent_data a9_can_pe_parents[] = {
+ { .fw_name = "sys", },
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv5", }
+};
+
+static A9_COMP_SEL(can_pe, CAN_CLK_CTRL, 9, 0x7, a9_can_pe_parents,
+ a9_can_pe_parents_val_table);
+static A9_COMP_DIV(can_pe, CAN_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(can_pe, CAN_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(can1_pe, CAN_CLK_CTRL, 25, 0x7, a9_can_pe_parents,
+ a9_can_pe_parents_val_table);
+static A9_COMP_DIV(can1_pe, CAN_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(can1_pe, CAN_CLK_CTRL, 24, 0);
+
+static const struct clk_parent_data a9_can_filter_parents[] = {
+ { .fw_name = "sys", },
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", }
+};
+
+static A9_COMP_SEL(can_filter, CAN_CLK_CTRL1, 9, 0x7, a9_can_filter_parents,
+ NULL);
+static A9_COMP_DIV(can_filter, CAN_CLK_CTRL1, 0, 7);
+static A9_COMP_GATE(can_filter, CAN_CLK_CTRL1, 8, 0);
+
+static A9_COMP_SEL(can1_filter, CAN_CLK_CTRL1, 25, 0x7, a9_can_filter_parents,
+ NULL);
+static A9_COMP_DIV(can1_filter, CAN_CLK_CTRL1, 16, 7);
+static A9_COMP_GATE(can1_filter, CAN_CLK_CTRL1, 24, 0);
+
+static const struct clk_parent_data a9_i3c_parents[] = {
+ { .fw_name = "sys", },
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv5", }
+};
+
+static A9_COMP_SEL(i3c, I3C_CLK_CTRL, 9, 0x7, a9_i3c_parents, NULL);
+static A9_COMP_DIV(i3c, I3C_CLK_CTRL, 0, 8);
+static A9_COMP_GATE(i3c, I3C_CLK_CTRL, 8, 0);
+
+static struct clk_regmap a9_ts_div = {
+ .data = &(struct clk_regmap_div_data) {
+ .offset = TS_CLK_CTRL,
+ .shift = 0,
+ .width = 8,
+ },
+ .hw.init = CLK_HW_INIT_FW_NAME("ts_div", "xtal",
+ &clk_regmap_divider_ops, 0),
+};
+
+static struct clk_regmap a9_ts = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = TS_CLK_CTRL,
+ .bit_idx = 8,
+ },
+ .hw.init = CLK_HW_INIT_HW("ts", &a9_ts_div.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_fixed_factor a9_eth_125m_div = {
+ .mult = 1,
+ .div = 8,
+ .hw.init = CLK_HW_INIT_FW_NAME("eth_125m_div", "fdiv2",
+ &clk_fixed_factor_ops, 0),
+};
+
+static struct clk_regmap a9_eth_125m = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = ETH_CLK_CTRL,
+ .bit_idx = 7,
+ },
+ .hw.init = CLK_HW_INIT_HW("eth_125m", &a9_eth_125m_div.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+/*
+ * Channel 1, 2, 3, 4, 5 and 6 are unconnected,
+ * ext_rmii connects external PAD. Do not automatically reparent.
+ */
+static u32 a9_eth_rmii_parents_val_table[] = { 0, 7 };
+static const struct clk_parent_data a9_eth_rmii_parents[] = {
+ { .fw_name = "fdiv2", },
+ { .fw_name = "ext_rmii", }
+};
+
+static struct clk_regmap a9_eth_rmii_sel = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = ETH_CLK_CTRL,
+ .mask = 0x7,
+ .shift = 9,
+ .table = a9_eth_rmii_parents_val_table,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("eth_rmii_sel",
+ a9_eth_rmii_parents,
+ &clk_regmap_mux_ops, CLK_SET_RATE_NO_REPARENT),
+};
+
+static struct clk_regmap a9_eth_rmii_div = {
+ .data = &(struct clk_regmap_div_data) {
+ .offset = ETH_CLK_CTRL,
+ .shift = 0,
+ .width = 7,
+ },
+ .hw.init = CLK_HW_INIT_HW("eth_rmii_div", &a9_eth_rmii_sel.hw,
+ &clk_regmap_divider_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_eth_rmii = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = ETH_CLK_CTRL,
+ .bit_idx = 8,
+ },
+ .hw.init = CLK_HW_INIT_HW("eth_rmii", &a9_eth_rmii_div.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+/*
+ * Channel 3(ddr_dpll_pt_clk) is manged by the DDR module;
+ * channel 12(msr_clk) is manged by clock measures module.
+ * channel 16(audio_dac1_clk) is manged by audio module.
+ * Channel 10, 11, 13, 14 are not connected.
+ */
+static u32 a9_gen_parents_val_table[] = { 0, 1, 2, 4, 5, 6, 7, 8, 9, 15, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26};
+static struct clk_regmap a9_vid_pll;
+
+static const struct clk_parent_data a9_gen_parents[] = {
+ { .fw_name = "xtal" },
+ { .fw_name = "rtc" },
+ { .fw_name = "sysplldiv16" },
+ { .hw = &a9_vid_pll.hw },
+ { .fw_name = "gp0" },
+ { .fw_name = "hifi1" },
+ { .fw_name = "hifi0" },
+ { .fw_name = "gp1" },
+ { .fw_name = "gp2" },
+ { .fw_name = "dsudiv16" },
+ { .fw_name = "cpudiv16" },
+ { .fw_name = "a78div16" },
+ { .fw_name = "fdiv2" },
+ { .fw_name = "fdiv2p5" },
+ { .fw_name = "fdiv3" },
+ { .fw_name = "fdiv4" },
+ { .fw_name = "fdiv5" },
+ { .fw_name = "fdiv7" },
+ { .fw_name = "mclk0" },
+ { .fw_name = "mclk1" }
+};
+
+static A9_COMP_SEL(gen, GEN_CLK_CTRL, 12, 0x1f, a9_gen_parents,
+ a9_gen_parents_val_table);
+static A9_COMP_DIV(gen, GEN_CLK_CTRL, 0, 11);
+static A9_COMP_GATE(gen, GEN_CLK_CTRL, 11, 0);
+
+static struct clk_regmap a9_24m_in = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = CLK12_24_CTRL,
+ .bit_idx = 11,
+ },
+ .hw.init = CLK_HW_INIT_FW_NAME("24m_in", "xtal",
+ &clk_regmap_gate_ops, 0),
+};
+
+static struct clk_regmap a9_12_24m = {
+ .data = &(struct clk_regmap_div_data) {
+ .offset = CLK12_24_CTRL,
+ .shift = 10,
+ .width = 1,
+ },
+ .hw.init = CLK_HW_INIT_HW("12_24m", &a9_24m_in.hw,
+ &clk_regmap_divider_ops, 0),
+};
+
+static const struct clk_parent_data a9_mali_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "gp1", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", }
+};
+
+static A9_COMP_SEL(mali_0, MALI_CLK_CTRL, 9, 0x7, a9_mali_parents, NULL);
+static A9_COMP_DIV(mali_0, MALI_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(mali_0, MALI_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static A9_COMP_SEL(mali_1, MALI_CLK_CTRL, 25, 0x7, a9_mali_parents, NULL);
+static A9_COMP_DIV(mali_1, MALI_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(mali_1, MALI_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap a9_mali = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = MALI_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 31,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("mali",
+ ((const struct clk_hw *[]) {
+ &a9_mali_0.hw,
+ &a9_mali_1.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static A9_COMP_SEL(mali_stack_0, MALI_STACK_CLK_CTRL, 9, 0x7, a9_mali_parents,
+ NULL);
+static A9_COMP_DIV(mali_stack_0, MALI_STACK_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(mali_stack_0, MALI_STACK_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static A9_COMP_SEL(mali_stack_1, MALI_STACK_CLK_CTRL, 25, 0x7, a9_mali_parents,
+ NULL);
+static A9_COMP_DIV(mali_stack_1, MALI_STACK_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(mali_stack_1, MALI_STACK_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap a9_mali_stack = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = MALI_STACK_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 31,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("mali_stack",
+ ((const struct clk_hw *[]) {
+ &a9_mali_stack_0.hw,
+ &a9_mali_stack_1.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static const struct clk_parent_data a9_dspa_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "gp2", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "rtc", }
+};
+
+static A9_COMP_SEL(dspa_0, DSPA_CLK_CTRL, 9, 0x7, a9_dspa_parents, NULL);
+static A9_COMP_DIV(dspa_0, DSPA_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(dspa_0, DSPA_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static A9_COMP_SEL(dspa_1, DSPA_CLK_CTRL, 25, 0x7, a9_dspa_parents, NULL);
+static A9_COMP_DIV(dspa_1, DSPA_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(dspa_1, DSPA_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap a9_dspa = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = DSPA_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 31,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("dspa",
+ ((const struct clk_hw *[]) {
+ &a9_dspa_0.hw,
+ &a9_dspa_1.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static const struct clk_parent_data a9_hevcf_parents[] = {
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "gp1", },
+ { .fw_name = "xtal", }
+};
+
+static A9_COMP_SEL(hevcf_0, HEVCF_CLK_CTRL, 9, 0x7, a9_hevcf_parents, NULL);
+static A9_COMP_DIV(hevcf_0, HEVCF_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(hevcf_0, HEVCF_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static A9_COMP_SEL(hevcf_1, HEVCF_CLK_CTRL, 25, 0x7, a9_hevcf_parents, NULL);
+static A9_COMP_DIV(hevcf_1, HEVCF_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(hevcf_1, HEVCF_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap a9_hevcf = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HEVCF_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 31,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("hevcf",
+ ((const struct clk_hw *[]) {
+ &a9_hevcf_0.hw,
+ &a9_hevcf_1.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static const struct clk_parent_data a9_hcodec_parents[] = {
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "gp0", },
+ { .fw_name = "xtal", }
+};
+
+static A9_COMP_SEL(hcodec_0, HCODEC_CLK_CTRL, 9, 0x7, a9_hcodec_parents, NULL);
+static A9_COMP_DIV(hcodec_0, HCODEC_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(hcodec_0, HCODEC_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static A9_COMP_SEL(hcodec_1, HCODEC_CLK_CTRL, 25, 0x7, a9_hcodec_parents, NULL);
+static A9_COMP_DIV(hcodec_1, HCODEC_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(hcodec_1, HCODEC_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap a9_hcodec = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HCODEC_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 31,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("hcodec",
+ ((const struct clk_hw *[]) {
+ &a9_hcodec_0.hw,
+ &a9_hcodec_1.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static const struct clk_parent_data a9_vpu_parents[] = {
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "vid1", },
+ { .fw_name = "fdiv2", },
+ { .hw = &a9_vid_pll.hw },
+ { .fw_name = "vid2", },
+ { .fw_name = "gp1", }
+};
+
+static A9_COMP_SEL(vpu_0, VPU_CLK_CTRL, 9, 0x7, a9_vpu_parents, NULL);
+static A9_COMP_DIV(vpu_0, VPU_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(vpu_0, VPU_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static A9_COMP_SEL(vpu_1, VPU_CLK_CTRL, 25, 0x7, a9_vpu_parents, NULL);
+static A9_COMP_DIV(vpu_1, VPU_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(vpu_1, VPU_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap a9_vpu = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VPU_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 31,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("vpu",
+ ((const struct clk_hw *[]) {
+ &a9_vpu_0.hw,
+ &a9_vpu_1.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static const struct clk_parent_data a9_vapb_parents[] = {
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", },
+ { .fw_name = "fdiv2", },
+ { .hw = &a9_vid_pll.hw },
+ { .fw_name = "hifi0", },
+ { .fw_name = "fdiv2p5", }
+};
+
+static A9_COMP_SEL(vapb_0, VAPB_CLK_CTRL, 9, 0x7, a9_vapb_parents, NULL);
+static A9_COMP_DIV(vapb_0, VAPB_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(vapb_0, VAPB_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static A9_COMP_SEL(vapb_1, VAPB_CLK_CTRL, 25, 0x7, a9_vapb_parents, NULL);
+static A9_COMP_DIV(vapb_1, VAPB_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(vapb_1, VAPB_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap a9_vapb = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VAPB_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 31,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("vapb",
+ ((const struct clk_hw *[]) {
+ &a9_vapb_0.hw,
+ &a9_vapb_1.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_ge2d = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = VAPB_CLK_CTRL,
+ .bit_idx = 30,
+ },
+ .hw.init = CLK_HW_INIT_HW("ge2d", &a9_vapb.hw,
+ &clk_regmap_gate_ops, 0),
+};
+
+static const struct clk_parent_data a9_vpu_clkb_tmp_parents[] = {
+ { .hw = &a9_vpu.hw },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", }
+};
+
+static A9_COMP_SEL(vpu_clkb_tmp, VPU_CLKB_CTRL, 25, 0x7, a9_vpu_clkb_tmp_parents,
+ NULL);
+static A9_COMP_DIV(vpu_clkb_tmp, VPU_CLKB_CTRL, 16, 4);
+static A9_COMP_GATE(vpu_clkb_tmp, VPU_CLKB_CTRL, 24, 0);
+
+static struct clk_regmap a9_vpu_clkb_div = {
+ .data = &(struct clk_regmap_div_data) {
+ .offset = VPU_CLKB_CTRL,
+ .shift = 0,
+ .width = 8,
+ },
+ .hw.init = CLK_HW_INIT_HW("vpu_clkb_div", &a9_vpu_clkb_tmp.hw,
+ &clk_regmap_divider_ops, 0),
+};
+
+static struct clk_regmap a9_vpu_clkb = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = VPU_CLKB_CTRL,
+ .bit_idx = 8,
+ },
+ .hw.init = CLK_HW_INIT_HW("vpu_clkb", &a9_vpu_clkb_div.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static const struct clk_parent_data a9_hdmi_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", }
+};
+
+static A9_COMP_SEL(hdmitx_sys, HDMI_CLK_CTRL, 9, 0x7, a9_hdmi_parents, NULL);
+static A9_COMP_DIV(hdmitx_sys, HDMI_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(hdmitx_sys, HDMI_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(hdmitx_prif, HTX_CLK_CTRL, 9, 0x7, a9_hdmi_parents, NULL);
+static A9_COMP_DIV(hdmitx_prif, HTX_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(hdmitx_prif, HTX_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(hdmitx_200m, HTX_CLK_CTRL, 25, 0x7, a9_hdmi_parents, NULL);
+static A9_COMP_DIV(hdmitx_200m, HTX_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(hdmitx_200m, HTX_CLK_CTRL, 24, 0);
+
+static A9_COMP_SEL(hdmitx_aud, HTX_CLK_CTRL1, 9, 0x7, a9_hdmi_parents, NULL);
+static A9_COMP_DIV(hdmitx_aud, HTX_CLK_CTRL1, 0, 7);
+static A9_COMP_GATE(hdmitx_aud, HTX_CLK_CTRL1, 8, 0);
+
+static A9_COMP_SEL(hdmirx_5m, HRX_CLK_CTRL, 9, 0x7, a9_hdmi_parents,
+ NULL);
+static A9_COMP_DIV(hdmirx_5m, HRX_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(hdmirx_5m, HRX_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(hdmirx_2m, HRX_CLK_CTRL, 25, 0x7, a9_hdmi_parents,
+ NULL);
+static A9_COMP_DIV(hdmirx_2m, HRX_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(hdmirx_2m, HRX_CLK_CTRL, 24, 0);
+
+static A9_COMP_SEL(hdmirx_cfg, HRX_CLK_CTRL1, 9, 0x7, a9_hdmi_parents,
+ NULL);
+static A9_COMP_DIV(hdmirx_cfg, HRX_CLK_CTRL1, 0, 7);
+static A9_COMP_GATE(hdmirx_cfg, HRX_CLK_CTRL1, 8, 0);
+
+static A9_COMP_SEL(hdmirx_hdcp2x, HRX_CLK_CTRL1, 25, 0x7, a9_hdmi_parents,
+ NULL);
+static A9_COMP_DIV(hdmirx_hdcp2x, HRX_CLK_CTRL1, 16, 7);
+static A9_COMP_GATE(hdmirx_hdcp2x, HRX_CLK_CTRL1, 24, 0);
+
+static A9_COMP_SEL(hdmirx_acr_ref, HRX_CLK_CTRL2, 25, 0x7, a9_hdmi_parents,
+ NULL);
+static A9_COMP_DIV(hdmirx_acr_ref, HRX_CLK_CTRL2, 16, 7);
+static A9_COMP_GATE(hdmirx_acr_ref, HRX_CLK_CTRL2, 24, 0);
+
+static A9_COMP_SEL(hdmirx_meter, HRX_CLK_CTRL3, 9, 0x7, a9_hdmi_parents,
+ NULL);
+static A9_COMP_DIV(hdmirx_meter, HRX_CLK_CTRL3, 0, 7);
+static A9_COMP_GATE(hdmirx_meter, HRX_CLK_CTRL3, 8, 0);
+
+static struct clk_regmap a9_enc, a9_enc1;
+
+static const struct clk_parent_data a9_vid_lock_parents[] = {
+ { .fw_name = "xtal", },
+ { .hw = &a9_enc.hw },
+ { .hw = &a9_enc1.hw }
+};
+
+static A9_COMP_SEL(vid_lock, VID_LOCK_CLK_CTRL, 9, 0x7, a9_vid_lock_parents,
+ NULL);
+static A9_COMP_DIV(vid_lock, VID_LOCK_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(vid_lock, VID_LOCK_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_vdin_meas_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", }
+};
+
+static A9_COMP_SEL(vdin_meas, VDIN_MEAS_CLK_CTRL, 9, 0x7, a9_vdin_meas_parents,
+ NULL);
+static A9_COMP_DIV(vdin_meas, VDIN_MEAS_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(vdin_meas, VDIN_MEAS_CLK_CTRL, 8, 0);
+
+static struct clk_regmap a9_vid_pll_div = {
+ .data = &(struct meson_vid_pll_div_data){
+ .val = {
+ .reg_off = VID_PLL_CLK_DIV,
+ .shift = 0,
+ .width = 15,
+ },
+ .sel = {
+ .reg_off = VID_PLL_CLK_DIV,
+ .shift = 16,
+ .width = 2,
+ },
+ },
+ .hw.init = CLK_HW_INIT_FW_NAME("vid_pll_div", "hdmiout2",
+ &meson_vid_pll_div_ro_ops, 0),
+};
+
+static struct clk_regmap a9_vid_pll_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VID_PLL_CLK_DIV,
+ .mask = 0x1,
+ .shift = 18,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("vid_pll_sel",
+ ((const struct clk_parent_data []) {
+ { .hw = &a9_vid_pll_div.hw },
+ { .fw_name = "hdmiout2" }
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vid_pll = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_PLL_CLK_DIV,
+ .bit_idx = 19,
+ },
+ .hw.init = CLK_HW_INIT_HW("vid_pll", &a9_vid_pll_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vid_pll_vclk = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HDMI_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 15,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("vid_pll_vclk",
+ ((const struct clk_parent_data []) {
+ { .hw = &a9_vid_pll.hw },
+ { .fw_name = "hdmipix" }
+ }), &clk_regmap_mux_ops, 0),
+};
+
+static const struct clk_parent_data a9_vclk_parents[] = {
+ { .hw = &a9_vid_pll_vclk.hw },
+ { .fw_name = "pix0", },
+ { .fw_name = "vid1", },
+ { .fw_name = "pix1", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "vid2", }
+};
+
+static struct clk_regmap a9_vclk_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VID_CLK_CTRL,
+ .mask = 0x7,
+ .shift = 16,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("vclk_sel", a9_vclk_parents,
+ &clk_regmap_mux_ops, 0),
+};
+
+static struct clk_regmap a9_vclk_in = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_DIV,
+ .bit_idx = 16,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk_in", &a9_vclk_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk_div = {
+ .data = &(struct clk_regmap_div_data){
+ .offset = VID_CLK_DIV,
+ .shift = 0,
+ .width = 8,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk_div", &a9_vclk_in.hw,
+ &clk_regmap_divider_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL,
+ .bit_idx = 19,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk", &a9_vclk_div.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk_div1_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL,
+ .bit_idx = 0,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk_div1_en", &a9_vclk.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk_div2_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL,
+ .bit_idx = 1,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk_div2_en", &a9_vclk.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_fixed_factor a9_vclk_div2 = {
+ .mult = 1,
+ .div = 2,
+ .hw.init = CLK_HW_INIT_HW("vclk_div2", &a9_vclk_div2_en.hw,
+ &clk_fixed_factor_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk_div4_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL,
+ .bit_idx = 2,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk_div4_en", &a9_vclk.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_fixed_factor a9_vclk_div4 = {
+ .mult = 1,
+ .div = 4,
+ .hw.init = CLK_HW_INIT_HW("vclk_div4", &a9_vclk_div4_en.hw,
+ &clk_fixed_factor_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk_div6_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL,
+ .bit_idx = 3,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk_div6_en", &a9_vclk.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_fixed_factor a9_vclk_div6 = {
+ .mult = 1,
+ .div = 6,
+ .hw.init = CLK_HW_INIT_HW("vclk_div6", &a9_vclk_div6_en.hw,
+ &clk_fixed_factor_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk_div12_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL,
+ .bit_idx = 4,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk_div12_en", &a9_vclk.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_fixed_factor a9_vclk_div12 = {
+ .mult = 1,
+ .div = 12,
+ .hw.init = CLK_HW_INIT_HW("vclk_div12", &a9_vclk_div12_en.hw,
+ &clk_fixed_factor_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk2_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VIID_CLK_CTRL,
+ .mask = 0x7,
+ .shift = 16,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("vclk2_sel", a9_vclk_parents,
+ &clk_regmap_mux_ops, 0),
+};
+
+static struct clk_regmap a9_vclk2_in = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VIID_CLK_DIV,
+ .bit_idx = 16,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk2_in", &a9_vclk2_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk2_div = {
+ .data = &(struct clk_regmap_div_data){
+ .offset = VIID_CLK_DIV,
+ .shift = 0,
+ .width = 8,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk2_div", &a9_vclk2_in.hw,
+ &clk_regmap_divider_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk2 = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VIID_CLK_CTRL,
+ .bit_idx = 19,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk2", &a9_vclk2_div.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk2_div1_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VIID_CLK_CTRL,
+ .bit_idx = 0,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk2_div1_en", &a9_vclk2.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk2_div2_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VIID_CLK_CTRL,
+ .bit_idx = 1,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk2_div2_en", &a9_vclk2.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_fixed_factor a9_vclk2_div2 = {
+ .mult = 1,
+ .div = 2,
+ .hw.init = CLK_HW_INIT_HW("vclk2_div2", &a9_vclk2_div2_en.hw,
+ &clk_fixed_factor_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk2_div4_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VIID_CLK_CTRL,
+ .bit_idx = 2,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk2_div4_en", &a9_vclk2.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_fixed_factor a9_vclk2_div4 = {
+ .mult = 1,
+ .div = 4,
+ .hw.init = CLK_HW_INIT_HW("vclk2_div4", &a9_vclk2_div4_en.hw,
+ &clk_fixed_factor_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk2_div6_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VIID_CLK_CTRL,
+ .bit_idx = 3,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk2_div6_en", &a9_vclk2.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_fixed_factor a9_vclk2_div6 = {
+ .mult = 1,
+ .div = 6,
+ .hw.init = CLK_HW_INIT_HW("vclk2_div6", &a9_vclk2_div6_en.hw,
+ &clk_fixed_factor_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk2_div12_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VIID_CLK_CTRL,
+ .bit_idx = 4,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk2_div12_en", &a9_vclk2.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_fixed_factor a9_vclk2_div12 = {
+ .mult = 1,
+ .div = 12,
+ .hw.init = CLK_HW_INIT_HW("vclk2_div12", &a9_vclk2_div12_en.hw,
+ &clk_fixed_factor_ops, CLK_SET_RATE_PARENT),
+};
+
+/* Channel 5, 6 and 7 are unconnected */
+static u32 a9_vid_parents_val_table[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
+static const struct clk_hw *a9_vid_parents[] = {
+ &a9_vclk_div1_en.hw,
+ &a9_vclk_div2.hw,
+ &a9_vclk_div4.hw,
+ &a9_vclk_div6.hw,
+ &a9_vclk_div12.hw,
+ &a9_vclk2_div1_en.hw,
+ &a9_vclk2_div2.hw,
+ &a9_vclk2_div4.hw,
+ &a9_vclk2_div6.hw,
+ &a9_vclk2_div12.hw
+};
+
+static struct clk_regmap a9_vdac_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VIID_CLK_DIV,
+ .mask = 0xf,
+ .shift = 28,
+ .table = a9_vid_parents_val_table,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("vdac_sel", a9_vid_parents
+ , &clk_regmap_mux_ops, 0),
+};
+
+static struct clk_regmap a9_vdac = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL2,
+ .bit_idx = 4,
+ },
+ .hw.init = CLK_HW_INIT_HW("vdac", &a9_vdac_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_enc_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VIID_CLK_DIV,
+ .mask = 0xf,
+ .shift = 12,
+ .table = a9_vid_parents_val_table,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("enc_sel", a9_vid_parents
+ , &clk_regmap_mux_ops, 0),
+};
+
+static struct clk_regmap a9_enc = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL2,
+ .bit_idx = 10,
+ },
+ .hw.init = CLK_HW_INIT_HW("enc", &a9_enc_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_enc1_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VIID_CLK_DIV,
+ .mask = 0xf,
+ .shift = 8,
+ .table = a9_vid_parents_val_table,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("enc1_sel", a9_vid_parents
+ , &clk_regmap_mux_ops, 0),
+};
+
+static struct clk_regmap a9_enc1 = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL2,
+ .bit_idx = 11,
+ },
+ .hw.init = CLK_HW_INIT_HW("enc1", &a9_enc1_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_hdmitx_pixel_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HDMI_CLK_CTRL,
+ .mask = 0xf,
+ .shift = 16,
+ .table = a9_vid_parents_val_table,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("hdmitx_pixel_sel", a9_vid_parents
+ , &clk_regmap_mux_ops, 0),
+};
+
+static struct clk_regmap a9_hdmitx_pixel = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL2,
+ .bit_idx = 5,
+ },
+ .hw.init = CLK_HW_INIT_HW("hdmitx_pixel", &a9_hdmitx_pixel_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_hdmitx_fe_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HDMI_CLK_CTRL,
+ .mask = 0xf,
+ .shift = 20,
+ .table = a9_vid_parents_val_table,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("hdmitx_fe_sel", a9_vid_parents
+ , &clk_regmap_mux_ops, 0),
+};
+
+static struct clk_regmap a9_hdmitx_fe = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL2,
+ .bit_idx = 9,
+ },
+ .hw.init = CLK_HW_INIT_HW("hdmitx_fe", &a9_hdmitx_fe_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_hdmitx1_pixel_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HDMI_CLK_CTRL,
+ .mask = 0xf,
+ .shift = 24,
+ .table = a9_vid_parents_val_table,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("hdmitx1_pixel_sel", a9_vid_parents
+ , &clk_regmap_mux_ops, 0),
+};
+
+static struct clk_regmap a9_hdmitx1_pixel = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL2,
+ .bit_idx = 12,
+ },
+ .hw.init = CLK_HW_INIT_HW("hdmitx1_pixel", &a9_hdmitx1_pixel_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_hdmitx1_fe_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HDMI_CLK_CTRL,
+ .mask = 0xf,
+ .shift = 28,
+ .table = a9_vid_parents_val_table,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("hdmitx1_fe_sel", a9_vid_parents
+ , &clk_regmap_mux_ops, 0),
+};
+
+static struct clk_regmap a9_hdmitx1_fe = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL2,
+ .bit_idx = 13,
+ },
+ .hw.init = CLK_HW_INIT_HW("hdmitx1_fe", &a9_hdmitx1_fe_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static const struct clk_parent_data a9_csi_phy_parents[] = {
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "gp0", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "xtal", }
+};
+
+static A9_COMP_SEL(csi_phy, MIPI_CSI_PHY_CLK_CTRL, 9, 0x7,
+ a9_csi_phy_parents, NULL);
+static A9_COMP_DIV(csi_phy, MIPI_CSI_PHY_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(csi_phy, MIPI_CSI_PHY_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_dsi_meas_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .hw = &a9_vid_pll.hw },
+ { .fw_name = "gp0", },
+ { .fw_name = "vid1", },
+ { .fw_name = "vid2", }
+};
+
+static A9_COMP_SEL(dsi_meas, DSI_MEAS_CLK_CTRL, 9, 0x7,
+ a9_dsi_meas_parents, NULL);
+static A9_COMP_DIV(dsi_meas, DSI_MEAS_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(dsi_meas, DSI_MEAS_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(dsi_b_meas, DSI_MEAS_CLK_CTRL, 25, 0x7,
+ a9_dsi_meas_parents, NULL);
+static A9_COMP_DIV(dsi_b_meas, DSI_MEAS_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(dsi_b_meas, DSI_MEAS_CLK_CTRL, 24, 0);
+
+static struct clk_hw *a9_peripherals_hw_clks[] = {
+ [CLKID_SYS_AM_AXI] = &a9_sys_am_axi.hw,
+ [CLKID_SYS_DOS] = &a9_sys_dos.hw,
+ [CLKID_SYS_MIPI_DSI] = &a9_sys_mipi_dsi.hw,
+ [CLKID_SYS_ETH_PHY] = &a9_sys_eth_phy.hw,
+ [CLKID_SYS_AMFC] = &a9_sys_amfc.hw,
+ [CLKID_SYS_MALI] = &a9_sys_mali.hw,
+ [CLKID_SYS_NNA] = &a9_sys_nna.hw,
+ [CLKID_SYS_ETH_AXI] = &a9_sys_eth_axi.hw,
+ [CLKID_SYS_DP_APB] = &a9_sys_dp_apb.hw,
+ [CLKID_SYS_EDPTX_APB] = &a9_sys_edptx_apb.hw,
+ [CLKID_SYS_U3HSG] = &a9_sys_u3hsg.hw,
+ [CLKID_SYS_AUCPU] = &a9_sys_aucpu.hw,
+ [CLKID_SYS_GLB] = &a9_sys_glb.hw,
+ [CLKID_SYS_COMBO_DPHY_APB] = &a9_sys_combo_dphy_apb.hw,
+ [CLKID_SYS_HDMIRX_APB] = &a9_sys_hdmirx_apb.hw,
+ [CLKID_SYS_HDMIRX_PCLK] = &a9_sys_hdmirx_pclk.hw,
+ [CLKID_SYS_MIPI_DSI_PHY] = &a9_sys_mipi_dsi_phy.hw,
+ [CLKID_SYS_CAN0] = &a9_sys_can0.hw,
+ [CLKID_SYS_CAN1] = &a9_sys_can1.hw,
+ [CLKID_SYS_SD_EMMC_A] = &a9_sys_sd_emmc_a.hw,
+ [CLKID_SYS_SD_EMMC_B] = &a9_sys_sd_emmc_b.hw,
+ [CLKID_SYS_SD_EMMC_C] = &a9_sys_sd_emmc_c.hw,
+ [CLKID_SYS_SC] = &a9_sys_sc.hw,
+ [CLKID_SYS_ACODEC] = &a9_sys_acodec.hw,
+ [CLKID_SYS_MIPI_ISP] = &a9_sys_mipi_isp.hw,
+ [CLKID_SYS_MSR] = &a9_sys_msr.hw,
+ [CLKID_SYS_AUDIO] = &a9_sys_audio.hw,
+ [CLKID_SYS_MIPI_DSI_B] = &a9_sys_mipi_dsi_b.hw,
+ [CLKID_SYS_MIPI_DSI1_PHY] = &a9_sys_mipi_dsi1_phy.hw,
+ [CLKID_SYS_ETH] = &a9_sys_eth.hw,
+ [CLKID_SYS_ETH_1G_MAC] = &a9_sys_eth_1g_mac.hw,
+ [CLKID_SYS_UART_A] = &a9_sys_uart_a.hw,
+ [CLKID_SYS_UART_F] = &a9_sys_uart_f.hw,
+ [CLKID_SYS_TS_A55] = &a9_sys_ts_a55.hw,
+ [CLKID_SYS_ETH_1G_AXI] = &a9_sys_eth_1g_axi.hw,
+ [CLKID_SYS_TS_DOS] = &a9_sys_ts_dos.hw,
+ [CLKID_SYS_U3DRD_B] = &a9_sys_u3drd_b.hw,
+ [CLKID_SYS_TS_CORE] = &a9_sys_ts_core.hw,
+ [CLKID_SYS_TS_PLL] = &a9_sys_ts_pll.hw,
+ [CLKID_SYS_CSI_DIG_CLKIN] = &a9_sys_csi_dig_clkin.hw,
+ [CLKID_SYS_CVE] = &a9_sys_cve.hw,
+ [CLKID_SYS_GE2D] = &a9_sys_ge2d.hw,
+ [CLKID_SYS_SPISG] = &a9_sys_spisg.hw,
+ [CLKID_SYS_U3DRD_1] = &a9_sys_u3drd_1.hw,
+ [CLKID_SYS_U2H] = &a9_sys_u2h.hw,
+ [CLKID_SYS_PCIE_MAC_A] = &a9_sys_pcie_mac_a.hw,
+ [CLKID_SYS_U3DRD_A] = &a9_sys_u3drd_a.hw,
+ [CLKID_SYS_U2DRD] = &a9_sys_u2drd.hw,
+ [CLKID_SYS_PCIE_PHY] = &a9_sys_pcie_phy.hw,
+ [CLKID_SYS_PCIE_MAC_B] = &a9_sys_pcie_mac_b.hw,
+ [CLKID_SYS_PERIPH] = &a9_sys_periph.hw,
+ [CLKID_SYS_PIO] = &a9_sys_pio.hw,
+ [CLKID_SYS_I3C] = &a9_sys_i3c.hw,
+ [CLKID_SYS_I2C_M_E] = &a9_sys_i2c_m_e.hw,
+ [CLKID_SYS_I2C_M_F] = &a9_sys_i2c_m_f.hw,
+ [CLKID_SYS_HDMITX_APB] = &a9_sys_hdmitx_apb.hw,
+ [CLKID_SYS_I2C_M_I] = &a9_sys_i2c_m_i.hw,
+ [CLKID_SYS_I2C_M_G] = &a9_sys_i2c_m_g.hw,
+ [CLKID_SYS_I2C_M_H] = &a9_sys_i2c_m_h.hw,
+ [CLKID_SYS_HDMI20_AES] = &a9_sys_hdmi20_aes.hw,
+ [CLKID_SYS_CSI2_HOST] = &a9_sys_csi2_host.hw,
+ [CLKID_SYS_CSI2_ADAPT] = &a9_sys_csi2_adapt.hw,
+ [CLKID_SYS_DSPA] = &a9_sys_dspa.hw,
+ [CLKID_SYS_PP_DMA] = &a9_sys_pp_dma.hw,
+ [CLKID_SYS_PP_WRAPPER] = &a9_sys_pp_wrapper.hw,
+ [CLKID_SYS_VPU_INTR] = &a9_sys_vpu_intr.hw,
+ [CLKID_SYS_CSI2_PHY] = &a9_sys_csi2_phy.hw,
+ [CLKID_SYS_SARADC] = &a9_sys_saradc.hw,
+ [CLKID_SYS_PWM_J] = &a9_sys_pwm_j.hw,
+ [CLKID_SYS_PWM_I] = &a9_sys_pwm_i.hw,
+ [CLKID_SYS_PWM_H] = &a9_sys_pwm_h.hw,
+ [CLKID_SYS_PWM_N] = &a9_sys_pwm_n.hw,
+ [CLKID_SYS_PWM_M] = &a9_sys_pwm_m.hw,
+ [CLKID_SYS_PWM_L] = &a9_sys_pwm_l.hw,
+ [CLKID_SYS_PWM_K] = &a9_sys_pwm_k.hw,
+ [CLKID_SD_EMMC_A_SEL] = &a9_sd_emmc_a_sel.hw,
+ [CLKID_SD_EMMC_A_DIV] = &a9_sd_emmc_a_div.hw,
+ [CLKID_SD_EMMC_A] = &a9_sd_emmc_a.hw,
+ [CLKID_SD_EMMC_B_SEL] = &a9_sd_emmc_b_sel.hw,
+ [CLKID_SD_EMMC_B_DIV] = &a9_sd_emmc_b_div.hw,
+ [CLKID_SD_EMMC_B] = &a9_sd_emmc_b.hw,
+ [CLKID_SD_EMMC_C_SEL] = &a9_sd_emmc_c_sel.hw,
+ [CLKID_SD_EMMC_C_DIV] = &a9_sd_emmc_c_div.hw,
+ [CLKID_SD_EMMC_C] = &a9_sd_emmc_c.hw,
+ [CLKID_PWM_H_SEL] = &a9_pwm_h_sel.hw,
+ [CLKID_PWM_H_DIV] = &a9_pwm_h_div.hw,
+ [CLKID_PWM_H] = &a9_pwm_h.hw,
+ [CLKID_PWM_I_SEL] = &a9_pwm_i_sel.hw,
+ [CLKID_PWM_I_DIV] = &a9_pwm_i_div.hw,
+ [CLKID_PWM_I] = &a9_pwm_i.hw,
+ [CLKID_PWM_J_SEL] = &a9_pwm_j_sel.hw,
+ [CLKID_PWM_J_DIV] = &a9_pwm_j_div.hw,
+ [CLKID_PWM_J] = &a9_pwm_j.hw,
+ [CLKID_PWM_K_SEL] = &a9_pwm_k_sel.hw,
+ [CLKID_PWM_K_DIV] = &a9_pwm_k_div.hw,
+ [CLKID_PWM_K] = &a9_pwm_k.hw,
+ [CLKID_PWM_L_SEL] = &a9_pwm_l_sel.hw,
+ [CLKID_PWM_L_DIV] = &a9_pwm_l_div.hw,
+ [CLKID_PWM_L] = &a9_pwm_l.hw,
+ [CLKID_PWM_M_SEL] = &a9_pwm_m_sel.hw,
+ [CLKID_PWM_M_DIV] = &a9_pwm_m_div.hw,
+ [CLKID_PWM_M] = &a9_pwm_m.hw,
+ [CLKID_PWM_N_SEL] = &a9_pwm_n_sel.hw,
+ [CLKID_PWM_N_DIV] = &a9_pwm_n_div.hw,
+ [CLKID_PWM_N] = &a9_pwm_n.hw,
+ [CLKID_SPISG_SEL] = &a9_spisg_sel.hw,
+ [CLKID_SPISG_DIV] = &a9_spisg_div.hw,
+ [CLKID_SPISG] = &a9_spisg.hw,
+ [CLKID_SPISG1_SEL] = &a9_spisg1_sel.hw,
+ [CLKID_SPISG1_DIV] = &a9_spisg1_div.hw,
+ [CLKID_SPISG1] = &a9_spisg1.hw,
+ [CLKID_SPISG2_SEL] = &a9_spisg2_sel.hw,
+ [CLKID_SPISG2_DIV] = &a9_spisg2_div.hw,
+ [CLKID_SPISG2] = &a9_spisg2.hw,
+ [CLKID_SARADC_SEL] = &a9_saradc_sel.hw,
+ [CLKID_SARADC_DIV] = &a9_saradc_div.hw,
+ [CLKID_SARADC] = &a9_saradc.hw,
+ [CLKID_AMFC_SEL] = &a9_amfc_sel.hw,
+ [CLKID_AMFC_DIV] = &a9_amfc_div.hw,
+ [CLKID_AMFC] = &a9_amfc.hw,
+ [CLKID_NNA_SEL] = &a9_nna_sel.hw,
+ [CLKID_NNA_DIV] = &a9_nna_div.hw,
+ [CLKID_NNA] = &a9_nna.hw,
+ [CLKID_USB_250M_SEL] = &a9_usb_250m_sel.hw,
+ [CLKID_USB_250M_DIV] = &a9_usb_250m_div.hw,
+ [CLKID_USB_250M] = &a9_usb_250m.hw,
+ [CLKID_USB_48M_PRE_SEL] = &a9_usb_48m_pre_sel.hw,
+ [CLKID_USB_48M_PRE_DIV] = &a9_usb_48m_pre_div.hw,
+ [CLKID_USB_48M_PRE] = &a9_usb_48m_pre.hw,
+ [CLKID_PCIE_TL_SEL] = &a9_pcie_tl_sel.hw,
+ [CLKID_PCIE_TL_DIV] = &a9_pcie_tl_div.hw,
+ [CLKID_PCIE_TL] = &a9_pcie_tl.hw,
+ [CLKID_PCIE1_TL_SEL] = &a9_pcie1_tl_sel.hw,
+ [CLKID_PCIE1_TL_DIV] = &a9_pcie1_tl_div.hw,
+ [CLKID_PCIE1_TL] = &a9_pcie1_tl.hw,
+ [CLKID_CMPR_SEL] = &a9_cmpr_sel.hw,
+ [CLKID_CMPR_DIV] = &a9_cmpr_div.hw,
+ [CLKID_CMPR] = &a9_cmpr.hw,
+ [CLKID_DEWARPA_SEL] = &a9_dewarpa_sel.hw,
+ [CLKID_DEWARPA_DIV] = &a9_dewarpa_div.hw,
+ [CLKID_DEWARPA] = &a9_dewarpa.hw,
+ [CLKID_SC_PRE_SEL] = &a9_sc_pre_sel.hw,
+ [CLKID_SC_PRE_DIV] = &a9_sc_pre_div.hw,
+ [CLKID_SC_PRE] = &a9_sc_pre.hw,
+ [CLKID_SC] = &a9_sc.hw,
+ [CLKID_DPTX_APB2_SEL] = &a9_dptx_apb2_sel.hw,
+ [CLKID_DPTX_APB2_DIV] = &a9_dptx_apb2_div.hw,
+ [CLKID_DPTX_APB2] = &a9_dptx_apb2.hw,
+ [CLKID_DPTX_AUD_SEL] = &a9_dptx_aud_sel.hw,
+ [CLKID_DPTX_AUD_DIV] = &a9_dptx_aud_div.hw,
+ [CLKID_DPTX_AUD] = &a9_dptx_aud.hw,
+ [CLKID_ISP_SEL] = &a9_isp_sel.hw,
+ [CLKID_ISP_DIV] = &a9_isp_div.hw,
+ [CLKID_ISP] = &a9_isp.hw,
+ [CLKID_CVE_SEL] = &a9_cve_sel.hw,
+ [CLKID_CVE_DIV] = &a9_cve_div.hw,
+ [CLKID_CVE] = &a9_cve.hw,
+ [CLKID_VGE_SEL] = &a9_vge_sel.hw,
+ [CLKID_VGE_DIV] = &a9_vge_div.hw,
+ [CLKID_VGE] = &a9_vge.hw,
+ [CLKID_PP_SEL] = &a9_pp_sel.hw,
+ [CLKID_PP_DIV] = &a9_pp_div.hw,
+ [CLKID_PP] = &a9_pp.hw,
+ [CLKID_GLB_SEL] = &a9_glb_sel.hw,
+ [CLKID_GLB_DIV] = &a9_glb_div.hw,
+ [CLKID_GLB] = &a9_glb.hw,
+ [CLKID_USB_48M_DUALDIV_IN] = &a9_usb_48m_dualdiv_in.hw,
+ [CLKID_USB_48M_DUALDIV_DIV] = &a9_usb_48m_dualdiv_div.hw,
+ [CLKID_USB_48M_DUALDIV_SEL] = &a9_usb_48m_dualdiv_sel.hw,
+ [CLKID_USB_48M_DUALDIV] = &a9_usb_48m_dualdiv.hw,
+ [CLKID_USB_48M] = &a9_usb_48m.hw,
+ [CLKID_CAN_PE_SEL] = &a9_can_pe_sel.hw,
+ [CLKID_CAN_PE_DIV] = &a9_can_pe_div.hw,
+ [CLKID_CAN_PE] = &a9_can_pe.hw,
+ [CLKID_CAN1_PE_SEL] = &a9_can1_pe_sel.hw,
+ [CLKID_CAN1_PE_DIV] = &a9_can1_pe_div.hw,
+ [CLKID_CAN1_PE] = &a9_can1_pe.hw,
+ [CLKID_CAN_FILTER_SEL] = &a9_can_filter_sel.hw,
+ [CLKID_CAN_FILTER_DIV] = &a9_can_filter_div.hw,
+ [CLKID_CAN_FILTER] = &a9_can_filter.hw,
+ [CLKID_CAN1_FILTER_SEL] = &a9_can1_filter_sel.hw,
+ [CLKID_CAN1_FILTER_DIV] = &a9_can1_filter_div.hw,
+ [CLKID_CAN1_FILTER] = &a9_can1_filter.hw,
+ [CLKID_I3C_SEL] = &a9_i3c_sel.hw,
+ [CLKID_I3C_DIV] = &a9_i3c_div.hw,
+ [CLKID_I3C] = &a9_i3c.hw,
+ [CLKID_TS_DIV] = &a9_ts_div.hw,
+ [CLKID_TS] = &a9_ts.hw,
+ [CLKID_ETH_125M_DIV] = &a9_eth_125m_div.hw,
+ [CLKID_ETH_125M] = &a9_eth_125m.hw,
+ [CLKID_ETH_RMII_SEL] = &a9_eth_rmii_sel.hw,
+ [CLKID_ETH_RMII_DIV] = &a9_eth_rmii_div.hw,
+ [CLKID_ETH_RMII] = &a9_eth_rmii.hw,
+ [CLKID_GEN_SEL] = &a9_gen_sel.hw,
+ [CLKID_GEN_DIV] = &a9_gen_div.hw,
+ [CLKID_GEN] = &a9_gen.hw,
+ [CLKID_CLK24M_IN] = &a9_24m_in.hw,
+ [CLKID_CLK12_24M] = &a9_12_24m.hw,
+ [CLKID_MALI_0_SEL] = &a9_mali_0_sel.hw,
+ [CLKID_MALI_0_DIV] = &a9_mali_0_div.hw,
+ [CLKID_MALI_0] = &a9_mali_0.hw,
+ [CLKID_MALI_1_SEL] = &a9_mali_1_sel.hw,
+ [CLKID_MALI_1_DIV] = &a9_mali_1_div.hw,
+ [CLKID_MALI_1] = &a9_mali_1.hw,
+ [CLKID_MALI] = &a9_mali.hw,
+ [CLKID_MALI_STACK_0_SEL] = &a9_mali_stack_0_sel.hw,
+ [CLKID_MALI_STACK_0_DIV] = &a9_mali_stack_0_div.hw,
+ [CLKID_MALI_STACK_0] = &a9_mali_stack_0.hw,
+ [CLKID_MALI_STACK_1_SEL] = &a9_mali_stack_1_sel.hw,
+ [CLKID_MALI_STACK_1_DIV] = &a9_mali_stack_1_div.hw,
+ [CLKID_MALI_STACK_1] = &a9_mali_stack_1.hw,
+ [CLKID_MALI_STACK] = &a9_mali_stack.hw,
+ [CLKID_DSPA_0_SEL] = &a9_dspa_0_sel.hw,
+ [CLKID_DSPA_0_DIV] = &a9_dspa_0_div.hw,
+ [CLKID_DSPA_0] = &a9_dspa_0.hw,
+ [CLKID_DSPA_1_SEL] = &a9_dspa_1_sel.hw,
+ [CLKID_DSPA_1_DIV] = &a9_dspa_1_div.hw,
+ [CLKID_DSPA_1] = &a9_dspa_1.hw,
+ [CLKID_DSPA] = &a9_dspa.hw,
+ [CLKID_HEVCF_0_SEL] = &a9_hevcf_0_sel.hw,
+ [CLKID_HEVCF_0_DIV] = &a9_hevcf_0_div.hw,
+ [CLKID_HEVCF_0] = &a9_hevcf_0.hw,
+ [CLKID_HEVCF_1_SEL] = &a9_hevcf_1_sel.hw,
+ [CLKID_HEVCF_1_DIV] = &a9_hevcf_1_div.hw,
+ [CLKID_HEVCF_1] = &a9_hevcf_1.hw,
+ [CLKID_HEVCF] = &a9_hevcf.hw,
+ [CLKID_HCODEC_0_SEL] = &a9_hcodec_0_sel.hw,
+ [CLKID_HCODEC_0_DIV] = &a9_hcodec_0_div.hw,
+ [CLKID_HCODEC_0] = &a9_hcodec_0.hw,
+ [CLKID_HCODEC_1_SEL] = &a9_hcodec_1_sel.hw,
+ [CLKID_HCODEC_1_DIV] = &a9_hcodec_1_div.hw,
+ [CLKID_HCODEC_1] = &a9_hcodec_1.hw,
+ [CLKID_HCODEC] = &a9_hcodec.hw,
+ [CLKID_VPU_0_SEL] = &a9_vpu_0_sel.hw,
+ [CLKID_VPU_0_DIV] = &a9_vpu_0_div.hw,
+ [CLKID_VPU_0] = &a9_vpu_0.hw,
+ [CLKID_VPU_1_SEL] = &a9_vpu_1_sel.hw,
+ [CLKID_VPU_1_DIV] = &a9_vpu_1_div.hw,
+ [CLKID_VPU_1] = &a9_vpu_1.hw,
+ [CLKID_VPU] = &a9_vpu.hw,
+ [CLKID_VAPB_0_SEL] = &a9_vapb_0_sel.hw,
+ [CLKID_VAPB_0_DIV] = &a9_vapb_0_div.hw,
+ [CLKID_VAPB_0] = &a9_vapb_0.hw,
+ [CLKID_VAPB_1_SEL] = &a9_vapb_1_sel.hw,
+ [CLKID_VAPB_1_DIV] = &a9_vapb_1_div.hw,
+ [CLKID_VAPB_1] = &a9_vapb_1.hw,
+ [CLKID_VAPB] = &a9_vapb.hw,
+ [CLKID_GE2D] = &a9_ge2d.hw,
+ [CLKID_VPU_CLKB_TMP_SEL] = &a9_vpu_clkb_tmp_sel.hw,
+ [CLKID_VPU_CLKB_TMP_DIV] = &a9_vpu_clkb_tmp_div.hw,
+ [CLKID_VPU_CLKB_TMP] = &a9_vpu_clkb_tmp.hw,
+ [CLKID_VPU_CLKB_DIV] = &a9_vpu_clkb_div.hw,
+ [CLKID_VPU_CLKB] = &a9_vpu_clkb.hw,
+ [CLKID_HDMITX_SYS_SEL] = &a9_hdmitx_sys_sel.hw,
+ [CLKID_HDMITX_SYS_DIV] = &a9_hdmitx_sys_div.hw,
+ [CLKID_HDMITX_SYS] = &a9_hdmitx_sys.hw,
+ [CLKID_HDMITX_PRIF_SEL] = &a9_hdmitx_prif_sel.hw,
+ [CLKID_HDMITX_PRIF_DIV] = &a9_hdmitx_prif_div.hw,
+ [CLKID_HDMITX_PRIF] = &a9_hdmitx_prif.hw,
+ [CLKID_HDMITX_200M_SEL] = &a9_hdmitx_200m_sel.hw,
+ [CLKID_HDMITX_200M_DIV] = &a9_hdmitx_200m_div.hw,
+ [CLKID_HDMITX_200M] = &a9_hdmitx_200m.hw,
+ [CLKID_HDMITX_AUD_SEL] = &a9_hdmitx_aud_sel.hw,
+ [CLKID_HDMITX_AUD_DIV] = &a9_hdmitx_aud_div.hw,
+ [CLKID_HDMITX_AUD] = &a9_hdmitx_aud.hw,
+ [CLKID_HDMIRX_5M_SEL] = &a9_hdmirx_5m_sel.hw,
+ [CLKID_HDMIRX_5M_DIV] = &a9_hdmirx_5m_div.hw,
+ [CLKID_HDMIRX_5M] = &a9_hdmirx_5m.hw,
+ [CLKID_HDMIRX_2M_SEL] = &a9_hdmirx_2m_sel.hw,
+ [CLKID_HDMIRX_2M_DIV] = &a9_hdmirx_2m_div.hw,
+ [CLKID_HDMIRX_2M] = &a9_hdmirx_2m.hw,
+ [CLKID_HDMIRX_CFG_SEL] = &a9_hdmirx_cfg_sel.hw,
+ [CLKID_HDMIRX_CFG_DIV] = &a9_hdmirx_cfg_div.hw,
+ [CLKID_HDMIRX_CFG] = &a9_hdmirx_cfg.hw,
+ [CLKID_HDMIRX_HDCP2X_SEL] = &a9_hdmirx_hdcp2x_sel.hw,
+ [CLKID_HDMIRX_HDCP2X_DIV] = &a9_hdmirx_hdcp2x_div.hw,
+ [CLKID_HDMIRX_HDCP2X] = &a9_hdmirx_hdcp2x.hw,
+ [CLKID_HDMIRX_ACR_REF_SEL] = &a9_hdmirx_acr_ref_sel.hw,
+ [CLKID_HDMIRX_ACR_REF_DIV] = &a9_hdmirx_acr_ref_div.hw,
+ [CLKID_HDMIRX_ACR_REF] = &a9_hdmirx_acr_ref.hw,
+ [CLKID_HDMIRX_METER_SEL] = &a9_hdmirx_meter_sel.hw,
+ [CLKID_HDMIRX_METER_DIV] = &a9_hdmirx_meter_div.hw,
+ [CLKID_HDMIRX_METER] = &a9_hdmirx_meter.hw,
+ [CLKID_VID_LOCK_SEL] = &a9_vid_lock_sel.hw,
+ [CLKID_VID_LOCK_DIV] = &a9_vid_lock_div.hw,
+ [CLKID_VID_LOCK] = &a9_vid_lock.hw,
+ [CLKID_VDIN_MEAS_SEL] = &a9_vdin_meas_sel.hw,
+ [CLKID_VDIN_MEAS_DIV] = &a9_vdin_meas_div.hw,
+ [CLKID_VDIN_MEAS] = &a9_vdin_meas.hw,
+ [CLKID_VID_PLL_DIV] = &a9_vid_pll_div.hw,
+ [CLKID_VID_PLL_SEL] = &a9_vid_pll_sel.hw,
+ [CLKID_VID_PLL] = &a9_vid_pll.hw,
+ [CLKID_VID_PLL_VCLK] = &a9_vid_pll_vclk.hw,
+ [CLKID_VCLK_SEL] = &a9_vclk_sel.hw,
+ [CLKID_VCLK_IN] = &a9_vclk_in.hw,
+ [CLKID_VCLK_DIV] = &a9_vclk_div.hw,
+ [CLKID_VCLK] = &a9_vclk.hw,
+ [CLKID_VCLK_DIV1_EN] = &a9_vclk_div1_en.hw,
+ [CLKID_VCLK_DIV2_EN] = &a9_vclk_div2_en.hw,
+ [CLKID_VCLK_DIV2] = &a9_vclk_div2.hw,
+ [CLKID_VCLK_DIV4_EN] = &a9_vclk_div4_en.hw,
+ [CLKID_VCLK_DIV4] = &a9_vclk_div4.hw,
+ [CLKID_VCLK_DIV6_EN] = &a9_vclk_div6_en.hw,
+ [CLKID_VCLK_DIV6] = &a9_vclk_div6.hw,
+ [CLKID_VCLK_DIV12_EN] = &a9_vclk_div12_en.hw,
+ [CLKID_VCLK_DIV12] = &a9_vclk_div12.hw,
+ [CLKID_VCLK2_SEL] = &a9_vclk2_sel.hw,
+ [CLKID_VCLK2_IN] = &a9_vclk2_in.hw,
+ [CLKID_VCLK2_DIV] = &a9_vclk2_div.hw,
+ [CLKID_VCLK2] = &a9_vclk2.hw,
+ [CLKID_VCLK2_DIV1_EN] = &a9_vclk2_div1_en.hw,
+ [CLKID_VCLK2_DIV2_EN] = &a9_vclk2_div2_en.hw,
+ [CLKID_VCLK2_DIV2] = &a9_vclk2_div2.hw,
+ [CLKID_VCLK2_DIV4_EN] = &a9_vclk2_div4_en.hw,
+ [CLKID_VCLK2_DIV4] = &a9_vclk2_div4.hw,
+ [CLKID_VCLK2_DIV6_EN] = &a9_vclk2_div6_en.hw,
+ [CLKID_VCLK2_DIV6] = &a9_vclk2_div6.hw,
+ [CLKID_VCLK2_DIV12_EN] = &a9_vclk2_div12_en.hw,
+ [CLKID_VCLK2_DIV12] = &a9_vclk2_div12.hw,
+ [CLKID_VDAC_SEL] = &a9_vdac_sel.hw,
+ [CLKID_VDAC] = &a9_vdac.hw,
+ [CLKID_ENC_SEL] = &a9_enc_sel.hw,
+ [CLKID_ENC] = &a9_enc.hw,
+ [CLKID_ENC1_SEL] = &a9_enc1_sel.hw,
+ [CLKID_ENC1] = &a9_enc1.hw,
+ [CLKID_HDMITX_PIXEL_SEL] = &a9_hdmitx_pixel_sel.hw,
+ [CLKID_HDMITX_PIXEL] = &a9_hdmitx_pixel.hw,
+ [CLKID_HDMITX_FE_SEL] = &a9_hdmitx_fe_sel.hw,
+ [CLKID_HDMITX_FE] = &a9_hdmitx_fe.hw,
+ [CLKID_HDMITX1_PIXEL_SEL] = &a9_hdmitx1_pixel_sel.hw,
+ [CLKID_HDMITX1_PIXEL] = &a9_hdmitx1_pixel.hw,
+ [CLKID_HDMITX1_FE_SEL] = &a9_hdmitx1_fe_sel.hw,
+ [CLKID_HDMITX1_FE] = &a9_hdmitx1_fe.hw,
+ [CLKID_CSI_PHY_SEL] = &a9_csi_phy_sel.hw,
+ [CLKID_CSI_PHY_DIV] = &a9_csi_phy_div.hw,
+ [CLKID_CSI_PHY] = &a9_csi_phy.hw,
+ [CLKID_DSI_MEAS_SEL] = &a9_dsi_meas_sel.hw,
+ [CLKID_DSI_MEAS_DIV] = &a9_dsi_meas_div.hw,
+ [CLKID_DSI_MEAS] = &a9_dsi_meas.hw,
+ [CLKID_DSI_B_MEAS_SEL] = &a9_dsi_b_meas_sel.hw,
+ [CLKID_DSI_B_MEAS_DIV] = &a9_dsi_b_meas_div.hw,
+ [CLKID_DSI_B_MEAS] = &a9_dsi_b_meas.hw,
+};
+
+static const struct meson_clkc_data a9_peripherals_clkc_data = {
+ .hw_clks = {
+ .hws = a9_peripherals_hw_clks,
+ .num = ARRAY_SIZE(a9_peripherals_hw_clks),
+ },
+};
+
+static const struct of_device_id a9_peripherals_clkc_match_table[] = {
+ {
+ .compatible = "amlogic,a9-peripherals-clkc",
+ .data = &a9_peripherals_clkc_data,
+ },
+ { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, a9_peripherals_clkc_match_table);
+
+static struct platform_driver a9_peripherals_clkc_driver = {
+ .probe = meson_clkc_mmio_probe,
+ .driver = {
+ .name = "a9-peripherals-clkc",
+ .of_match_table = a9_peripherals_clkc_match_table,
+ },
+};
+module_platform_driver(a9_peripherals_clkc_driver);
+
+MODULE_DESCRIPTION("Amlogic A9 Peripherals Clock Controller driver");
+MODULE_AUTHOR("Jian Hu <jian.hu@amlogic.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("CLK_MESON");
--
2.47.1
^ permalink raw reply related
* [PATCH v3 1/2] dt-bindings: clock: Add Amlogic A9 peripherals clock controller
From: Jian Hu via B4 Relay @ 2026-06-10 8:14 UTC (permalink / raw)
To: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Xianwei Zhao,
Kevin Hilman, Martin Blumenstingl
Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
linux-arm-kernel, Jian Hu, Conor Dooley
In-Reply-To: <20260610-a9_peripherals-v3-0-d07a78085f71@amlogic.com>
From: Jian Hu <jian.hu@amlogic.com>
Add the peripherals clock controller dt-bindings for the Amlogic A9
SoC family.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Jian Hu <jian.hu@amlogic.com>
---
.../clock/amlogic,a9-peripherals-clkc.yaml | 160 ++++++++++
.../clock/amlogic,a9-peripherals-clkc.h | 352 +++++++++++++++++++++
2 files changed, 512 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/amlogic,a9-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a9-peripherals-clkc.yaml
new file mode 100644
index 000000000000..1d0abbaa85b8
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,a9-peripherals-clkc.yaml
@@ -0,0 +1,160 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2026 Amlogic, Inc. All rights reserved
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,a9-peripherals-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic A9 Series Peripherals Clock Controller
+
+maintainers:
+ - Neil Armstrong <neil.armstrong@linaro.org>
+ - Jerome Brunet <jbrunet@baylibre.com>
+ - Jian Hu <jian.hu@amlogic.com>
+ - Xianwei Zhao <xianwei.zhao@amlogic.com>
+
+properties:
+ compatible:
+ const: amlogic,a9-peripherals-clkc
+
+ reg:
+ maxItems: 1
+
+ '#clock-cells':
+ const: 1
+
+ clocks:
+ minItems: 26
+ items:
+ - description: input oscillator
+ - description: input fclk div 2
+ - description: input fclk div 3
+ - description: input fclk div 4
+ - description: input fclk div 5
+ - description: input fclk div 7
+ - description: input fclk div 2p5
+ - description: input sys clk
+ - description: input gp1 pll
+ - description: input gp2 pll
+ - description: input sys pll div 16
+ - description: input cpu clk div 16
+ - description: input a78 clk div 16
+ - description: input dsu clk div 16
+ - description: input rtc clk
+ - description: input gp0 pll
+ - description: input hifi0 pll
+ - description: input hifi1 pll
+ - description: input mclk0 pll
+ - description: input mclk1 pll
+ - description: input video1 pll
+ - description: input video2 pll
+ - description: input hdmi out2 clk
+ - description: input hdmi pixel clk
+ - description: input pixel0 pll
+ - description: input pixel1 pll
+ - description: external input rmii oscillator (optional)
+
+ clock-names:
+ minItems: 26
+ items:
+ - const: xtal
+ - const: fdiv2
+ - const: fdiv3
+ - const: fdiv4
+ - const: fdiv5
+ - const: fdiv7
+ - const: fdiv2p5
+ - const: sys
+ - const: gp1
+ - const: gp2
+ - const: sysplldiv16
+ - const: cpudiv16
+ - const: a78div16
+ - const: dsudiv16
+ - const: rtc
+ - const: gp0
+ - const: hifi0
+ - const: hifi1
+ - const: mclk0
+ - const: mclk1
+ - const: vid1
+ - const: vid2
+ - const: hdmiout2
+ - const: hdmipix
+ - const: pix0
+ - const: pix1
+ - const: ext_rmii
+
+required:
+ - compatible
+ - reg
+ - '#clock-cells'
+ - clocks
+ - clock-names
+
+additionalProperties: false
+
+examples:
+ - |
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ clock-controller@200 {
+ compatible = "amlogic,a9-peripherals-clkc";
+ reg = <0x0 0x200 0x0 0x2f8>;
+ #clock-cells = <1>;
+ clocks = <&xtal>,
+ <&scmi_clk 10>,
+ <&scmi_clk 12>,
+ <&scmi_clk 14>,
+ <&scmi_clk 16>,
+ <&scmi_clk 18>,
+ <&scmi_clk 20>,
+ <&scmi_clk 21>,
+ <&scmi_clk 33>,
+ <&scmi_clk 34>,
+ <&scmi_clk 35>,
+ <&scmi_clk 36>,
+ <&scmi_clk 37>,
+ <&scmi_clk 38>,
+ <&scmi_clk 40>,
+ <&gp0 3>,
+ <&hifi0 3>,
+ <&hifi1 3>,
+ <&mclk0 3>,
+ <&mclk1 3>,
+ <&vid1>,
+ <&vid2>,
+ <&hdmitx 10>,
+ <&hdmitx 11>,
+ <&pix0>,
+ <&pix1>;
+ clock-names = "xtal",
+ "fdiv2",
+ "fdiv3",
+ "fdiv4",
+ "fdiv5",
+ "fdiv7",
+ "fdiv2p5",
+ "sys",
+ "gp1",
+ "gp2",
+ "sysplldiv16",
+ "cpudiv16",
+ "a78div16",
+ "dsudiv16",
+ "rtc",
+ "gp0",
+ "hifi0",
+ "hifi1",
+ "mclk0",
+ "mclk1",
+ "vid1",
+ "vid2",
+ "hdmiout2",
+ "hdmipix",
+ "pix0",
+ "pix1";
+ };
+ };
diff --git a/include/dt-bindings/clock/amlogic,a9-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,a9-peripherals-clkc.h
new file mode 100644
index 000000000000..bca69771d728
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,a9-peripherals-clkc.h
@@ -0,0 +1,352 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2026 Amlogic, Inc. All rights reserved.
+ */
+
+#ifndef __AMLOGIC_A9_PERIPHERALS_CLKC_H
+#define __AMLOGIC_A9_PERIPHERALS_CLKC_H
+
+#define CLKID_SYS_AM_AXI 0
+#define CLKID_SYS_DOS 1
+#define CLKID_SYS_MIPI_DSI 2
+#define CLKID_SYS_ETH_PHY 3
+#define CLKID_SYS_AMFC 4
+#define CLKID_SYS_MALI 5
+#define CLKID_SYS_NNA 6
+#define CLKID_SYS_ETH_AXI 7
+#define CLKID_SYS_DP_APB 8
+#define CLKID_SYS_EDPTX_APB 9
+#define CLKID_SYS_U3HSG 10
+#define CLKID_SYS_AUCPU 11
+#define CLKID_SYS_GLB 12
+#define CLKID_SYS_COMBO_DPHY_APB 13
+#define CLKID_SYS_HDMIRX_APB 14
+#define CLKID_SYS_HDMIRX_PCLK 15
+#define CLKID_SYS_MIPI_DSI_PHY 16
+#define CLKID_SYS_CAN0 17
+#define CLKID_SYS_CAN1 18
+#define CLKID_SYS_SD_EMMC_A 19
+#define CLKID_SYS_SD_EMMC_B 20
+#define CLKID_SYS_SD_EMMC_C 21
+#define CLKID_SYS_SC 22
+#define CLKID_SYS_ACODEC 23
+#define CLKID_SYS_MIPI_ISP 24
+#define CLKID_SYS_MSR 25
+#define CLKID_SYS_AUDIO 26
+#define CLKID_SYS_MIPI_DSI_B 27
+#define CLKID_SYS_MIPI_DSI1_PHY 28
+#define CLKID_SYS_ETH 29
+#define CLKID_SYS_ETH_1G_MAC 30
+#define CLKID_SYS_UART_A 31
+#define CLKID_SYS_UART_F 32
+#define CLKID_SYS_TS_A55 33
+#define CLKID_SYS_ETH_1G_AXI 34
+#define CLKID_SYS_TS_DOS 35
+#define CLKID_SYS_U3DRD_B 36
+#define CLKID_SYS_TS_CORE 37
+#define CLKID_SYS_TS_PLL 38
+#define CLKID_SYS_CSI_DIG_CLKIN 39
+#define CLKID_SYS_CVE 40
+#define CLKID_SYS_GE2D 41
+#define CLKID_SYS_SPISG 42
+#define CLKID_SYS_U3DRD_1 43
+#define CLKID_SYS_U2H 44
+#define CLKID_SYS_PCIE_MAC_A 45
+#define CLKID_SYS_U3DRD_A 46
+#define CLKID_SYS_U2DRD 47
+#define CLKID_SYS_PCIE_PHY 48
+#define CLKID_SYS_PCIE_MAC_B 49
+#define CLKID_SYS_PERIPH 50
+#define CLKID_SYS_PIO 51
+#define CLKID_SYS_I3C 52
+#define CLKID_SYS_I2C_M_E 53
+#define CLKID_SYS_I2C_M_F 54
+#define CLKID_SYS_HDMITX_APB 55
+#define CLKID_SYS_I2C_M_I 56
+#define CLKID_SYS_I2C_M_G 57
+#define CLKID_SYS_I2C_M_H 58
+#define CLKID_SYS_HDMI20_AES 59
+#define CLKID_SYS_CSI2_HOST 60
+#define CLKID_SYS_CSI2_ADAPT 61
+#define CLKID_SYS_DSPA 62
+#define CLKID_SYS_PP_DMA 63
+#define CLKID_SYS_PP_WRAPPER 64
+#define CLKID_SYS_VPU_INTR 65
+#define CLKID_SYS_CSI2_PHY 66
+#define CLKID_SYS_SARADC 67
+#define CLKID_SYS_PWM_J 68
+#define CLKID_SYS_PWM_I 69
+#define CLKID_SYS_PWM_H 70
+#define CLKID_SYS_PWM_N 71
+#define CLKID_SYS_PWM_M 72
+#define CLKID_SYS_PWM_L 73
+#define CLKID_SYS_PWM_K 74
+#define CLKID_SD_EMMC_A_SEL 75
+#define CLKID_SD_EMMC_A_DIV 76
+#define CLKID_SD_EMMC_A 77
+#define CLKID_SD_EMMC_B_SEL 78
+#define CLKID_SD_EMMC_B_DIV 79
+#define CLKID_SD_EMMC_B 80
+#define CLKID_SD_EMMC_C_SEL 81
+#define CLKID_SD_EMMC_C_DIV 82
+#define CLKID_SD_EMMC_C 83
+#define CLKID_PWM_H_SEL 84
+#define CLKID_PWM_H_DIV 85
+#define CLKID_PWM_H 86
+#define CLKID_PWM_I_SEL 87
+#define CLKID_PWM_I_DIV 88
+#define CLKID_PWM_I 89
+#define CLKID_PWM_J_SEL 90
+#define CLKID_PWM_J_DIV 91
+#define CLKID_PWM_J 92
+#define CLKID_PWM_K_SEL 93
+#define CLKID_PWM_K_DIV 94
+#define CLKID_PWM_K 95
+#define CLKID_PWM_L_SEL 96
+#define CLKID_PWM_L_DIV 97
+#define CLKID_PWM_L 98
+#define CLKID_PWM_M_SEL 99
+#define CLKID_PWM_M_DIV 100
+#define CLKID_PWM_M 101
+#define CLKID_PWM_N_SEL 102
+#define CLKID_PWM_N_DIV 103
+#define CLKID_PWM_N 104
+#define CLKID_SPISG_SEL 105
+#define CLKID_SPISG_DIV 106
+#define CLKID_SPISG 107
+#define CLKID_SPISG1_SEL 108
+#define CLKID_SPISG1_DIV 109
+#define CLKID_SPISG1 110
+#define CLKID_SPISG2_SEL 111
+#define CLKID_SPISG2_DIV 112
+#define CLKID_SPISG2 113
+#define CLKID_SARADC_SEL 114
+#define CLKID_SARADC_DIV 115
+#define CLKID_SARADC 116
+#define CLKID_AMFC_SEL 117
+#define CLKID_AMFC_DIV 118
+#define CLKID_AMFC 119
+#define CLKID_NNA_SEL 120
+#define CLKID_NNA_DIV 121
+#define CLKID_NNA 122
+#define CLKID_USB_250M_SEL 123
+#define CLKID_USB_250M_DIV 124
+#define CLKID_USB_250M 125
+#define CLKID_USB_48M_PRE_SEL 126
+#define CLKID_USB_48M_PRE_DIV 127
+#define CLKID_USB_48M_PRE 128
+#define CLKID_PCIE_TL_SEL 129
+#define CLKID_PCIE_TL_DIV 130
+#define CLKID_PCIE_TL 131
+#define CLKID_PCIE1_TL_SEL 132
+#define CLKID_PCIE1_TL_DIV 133
+#define CLKID_PCIE1_TL 134
+#define CLKID_CMPR_SEL 135
+#define CLKID_CMPR_DIV 136
+#define CLKID_CMPR 137
+#define CLKID_DEWARPA_SEL 138
+#define CLKID_DEWARPA_DIV 139
+#define CLKID_DEWARPA 140
+#define CLKID_SC_PRE_SEL 141
+#define CLKID_SC_PRE_DIV 142
+#define CLKID_SC_PRE 143
+#define CLKID_SC 144
+#define CLKID_DPTX_APB2_SEL 145
+#define CLKID_DPTX_APB2_DIV 146
+#define CLKID_DPTX_APB2 147
+#define CLKID_DPTX_AUD_SEL 148
+#define CLKID_DPTX_AUD_DIV 149
+#define CLKID_DPTX_AUD 150
+#define CLKID_ISP_SEL 151
+#define CLKID_ISP_DIV 152
+#define CLKID_ISP 153
+#define CLKID_CVE_SEL 154
+#define CLKID_CVE_DIV 155
+#define CLKID_CVE 156
+#define CLKID_VGE_SEL 157
+#define CLKID_VGE_DIV 158
+#define CLKID_VGE 159
+#define CLKID_PP_SEL 160
+#define CLKID_PP_DIV 161
+#define CLKID_PP 162
+#define CLKID_GLB_SEL 163
+#define CLKID_GLB_DIV 164
+#define CLKID_GLB 165
+#define CLKID_USB_48M_DUALDIV_IN 166
+#define CLKID_USB_48M_DUALDIV_DIV 167
+#define CLKID_USB_48M_DUALDIV_SEL 168
+#define CLKID_USB_48M_DUALDIV 169
+#define CLKID_USB_48M 170
+#define CLKID_CAN_PE_SEL 171
+#define CLKID_CAN_PE_DIV 172
+#define CLKID_CAN_PE 173
+#define CLKID_CAN1_PE_SEL 174
+#define CLKID_CAN1_PE_DIV 175
+#define CLKID_CAN1_PE 176
+#define CLKID_CAN_FILTER_SEL 177
+#define CLKID_CAN_FILTER_DIV 178
+#define CLKID_CAN_FILTER 179
+#define CLKID_CAN1_FILTER_SEL 180
+#define CLKID_CAN1_FILTER_DIV 181
+#define CLKID_CAN1_FILTER 182
+#define CLKID_I3C_SEL 183
+#define CLKID_I3C_DIV 184
+#define CLKID_I3C 185
+#define CLKID_TS_DIV 186
+#define CLKID_TS 187
+#define CLKID_ETH_125M_DIV 188
+#define CLKID_ETH_125M 189
+#define CLKID_ETH_RMII_SEL 190
+#define CLKID_ETH_RMII_DIV 191
+#define CLKID_ETH_RMII 192
+#define CLKID_GEN_SEL 193
+#define CLKID_GEN_DIV 194
+#define CLKID_GEN 195
+#define CLKID_CLK24M_IN 196
+#define CLKID_CLK12_24M 197
+#define CLKID_MALI_0_SEL 198
+#define CLKID_MALI_0_DIV 199
+#define CLKID_MALI_0 200
+#define CLKID_MALI_1_SEL 201
+#define CLKID_MALI_1_DIV 202
+#define CLKID_MALI_1 203
+#define CLKID_MALI 204
+#define CLKID_MALI_STACK_0_SEL 205
+#define CLKID_MALI_STACK_0_DIV 206
+#define CLKID_MALI_STACK_0 207
+#define CLKID_MALI_STACK_1_SEL 208
+#define CLKID_MALI_STACK_1_DIV 209
+#define CLKID_MALI_STACK_1 210
+#define CLKID_MALI_STACK 211
+#define CLKID_DSPA_0_SEL 212
+#define CLKID_DSPA_0_DIV 213
+#define CLKID_DSPA_0 214
+#define CLKID_DSPA_1_SEL 215
+#define CLKID_DSPA_1_DIV 216
+#define CLKID_DSPA_1 217
+#define CLKID_DSPA 218
+#define CLKID_HEVCF_0_SEL 219
+#define CLKID_HEVCF_0_DIV 220
+#define CLKID_HEVCF_0 221
+#define CLKID_HEVCF_1_SEL 222
+#define CLKID_HEVCF_1_DIV 223
+#define CLKID_HEVCF_1 224
+#define CLKID_HEVCF 225
+#define CLKID_HCODEC_0_SEL 226
+#define CLKID_HCODEC_0_DIV 227
+#define CLKID_HCODEC_0 228
+#define CLKID_HCODEC_1_SEL 229
+#define CLKID_HCODEC_1_DIV 230
+#define CLKID_HCODEC_1 231
+#define CLKID_HCODEC 232
+#define CLKID_VPU_0_SEL 233
+#define CLKID_VPU_0_DIV 234
+#define CLKID_VPU_0 235
+#define CLKID_VPU_1_SEL 236
+#define CLKID_VPU_1_DIV 237
+#define CLKID_VPU_1 238
+#define CLKID_VPU 239
+#define CLKID_VAPB_0_SEL 240
+#define CLKID_VAPB_0_DIV 241
+#define CLKID_VAPB_0 242
+#define CLKID_VAPB_1_SEL 243
+#define CLKID_VAPB_1_DIV 244
+#define CLKID_VAPB_1 245
+#define CLKID_VAPB 246
+#define CLKID_GE2D 247
+#define CLKID_VPU_CLKB_TMP_SEL 248
+#define CLKID_VPU_CLKB_TMP_DIV 249
+#define CLKID_VPU_CLKB_TMP 250
+#define CLKID_VPU_CLKB_DIV 251
+#define CLKID_VPU_CLKB 252
+#define CLKID_HDMITX_SYS_SEL 253
+#define CLKID_HDMITX_SYS_DIV 254
+#define CLKID_HDMITX_SYS 255
+#define CLKID_HDMITX_PRIF_SEL 256
+#define CLKID_HDMITX_PRIF_DIV 257
+#define CLKID_HDMITX_PRIF 258
+#define CLKID_HDMITX_200M_SEL 259
+#define CLKID_HDMITX_200M_DIV 260
+#define CLKID_HDMITX_200M 261
+#define CLKID_HDMITX_AUD_SEL 262
+#define CLKID_HDMITX_AUD_DIV 263
+#define CLKID_HDMITX_AUD 264
+#define CLKID_HDMIRX_5M_SEL 265
+#define CLKID_HDMIRX_5M_DIV 266
+#define CLKID_HDMIRX_5M 267
+#define CLKID_HDMIRX_2M_SEL 268
+#define CLKID_HDMIRX_2M_DIV 269
+#define CLKID_HDMIRX_2M 270
+#define CLKID_HDMIRX_CFG_SEL 271
+#define CLKID_HDMIRX_CFG_DIV 272
+#define CLKID_HDMIRX_CFG 273
+#define CLKID_HDMIRX_HDCP2X_SEL 274
+#define CLKID_HDMIRX_HDCP2X_DIV 275
+#define CLKID_HDMIRX_HDCP2X 276
+#define CLKID_HDMIRX_ACR_REF_SEL 277
+#define CLKID_HDMIRX_ACR_REF_DIV 278
+#define CLKID_HDMIRX_ACR_REF 279
+#define CLKID_HDMIRX_METER_SEL 280
+#define CLKID_HDMIRX_METER_DIV 281
+#define CLKID_HDMIRX_METER 282
+#define CLKID_VID_LOCK_SEL 283
+#define CLKID_VID_LOCK_DIV 284
+#define CLKID_VID_LOCK 285
+#define CLKID_VDIN_MEAS_SEL 286
+#define CLKID_VDIN_MEAS_DIV 287
+#define CLKID_VDIN_MEAS 288
+#define CLKID_VID_PLL_DIV 289
+#define CLKID_VID_PLL_SEL 290
+#define CLKID_VID_PLL 291
+#define CLKID_VID_PLL_VCLK 292
+#define CLKID_VCLK_SEL 293
+#define CLKID_VCLK_IN 294
+#define CLKID_VCLK_DIV 295
+#define CLKID_VCLK 296
+#define CLKID_VCLK_DIV1_EN 297
+#define CLKID_VCLK_DIV2_EN 298
+#define CLKID_VCLK_DIV2 299
+#define CLKID_VCLK_DIV4_EN 300
+#define CLKID_VCLK_DIV4 301
+#define CLKID_VCLK_DIV6_EN 302
+#define CLKID_VCLK_DIV6 303
+#define CLKID_VCLK_DIV12_EN 304
+#define CLKID_VCLK_DIV12 305
+#define CLKID_VCLK2_SEL 306
+#define CLKID_VCLK2_IN 307
+#define CLKID_VCLK2_DIV 308
+#define CLKID_VCLK2 309
+#define CLKID_VCLK2_DIV1_EN 310
+#define CLKID_VCLK2_DIV2_EN 311
+#define CLKID_VCLK2_DIV2 312
+#define CLKID_VCLK2_DIV4_EN 313
+#define CLKID_VCLK2_DIV4 314
+#define CLKID_VCLK2_DIV6_EN 315
+#define CLKID_VCLK2_DIV6 316
+#define CLKID_VCLK2_DIV12_EN 317
+#define CLKID_VCLK2_DIV12 318
+#define CLKID_VDAC_SEL 319
+#define CLKID_VDAC 320
+#define CLKID_ENC_SEL 321
+#define CLKID_ENC 322
+#define CLKID_ENC1_SEL 323
+#define CLKID_ENC1 324
+#define CLKID_HDMITX_PIXEL_SEL 325
+#define CLKID_HDMITX_PIXEL 326
+#define CLKID_HDMITX_FE_SEL 327
+#define CLKID_HDMITX_FE 328
+#define CLKID_HDMITX1_PIXEL_SEL 329
+#define CLKID_HDMITX1_PIXEL 330
+#define CLKID_HDMITX1_FE_SEL 331
+#define CLKID_HDMITX1_FE 332
+#define CLKID_CSI_PHY_SEL 333
+#define CLKID_CSI_PHY_DIV 334
+#define CLKID_CSI_PHY 335
+#define CLKID_DSI_MEAS_SEL 336
+#define CLKID_DSI_MEAS_DIV 337
+#define CLKID_DSI_MEAS 338
+#define CLKID_DSI_B_MEAS_SEL 339
+#define CLKID_DSI_B_MEAS_DIV 340
+#define CLKID_DSI_B_MEAS 341
+
+#endif /* __AMLOGIC_A9_PERIPHERALS_CLKC_H */
--
2.47.1
^ permalink raw reply related
* [PATCH v3 0/2] clk: amlogic: Add A9 peripherals clock controller
From: Jian Hu via B4 Relay @ 2026-06-10 8:14 UTC (permalink / raw)
To: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Xianwei Zhao,
Kevin Hilman, Martin Blumenstingl
Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
linux-arm-kernel, Jian Hu, Conor Dooley
This series adds Amlogic A9 peripherals clock support,
including dt-binding and peripherals clock driver.
Note that this driver depends on the A9 PLL driver, which is not yet
upstream. The Meson PLL framework is currently undergoing refactoring,
and the A9 PLL driver will be submitted as a follow-up series after
that work has been completed.
Signed-off-by: Jian Hu <jian.hu@amlogic.com>
---
Changes in v3:
- Add "depend on A9 pll" instructions in the cover-letter.
- Move COMPILE_TEST after 'depends on ARM64' reported by sashiko-bot.
- Fix usb_48m_pre_sel's parent reported by sashiko-bot.
- Fix gen_div width reported by sashiko-bot.
- Fix hdmitx1_pixel's parent reported by sashiko-bot.
- Link to v2: https://lore.kernel.org/r/20260603-a9_peripherals-v2-0-ee1b8c0a1e6c@amlogic.com
Changes in v2:
- Split the A9 clock driver and send the peripherals clock separately.
- Add COMPILE_TEST in Kconfig.
- Drop the 'optional'.
- Rename apb4 to soc.
- Sort the header file.
- Rename hifi to hifi0.
- Use CLK_HW_INIT_PARENTS_DATA to describe clk_init_data.
- Use CLK_HW_INIT_HW to describe clk_init_data.
- Use CLK_HW_INIT_PARENTS_HW to describe clk_init_data.
- Link to v1: https://lore.kernel.org/all/20260511-b4-a9_clk-v1-0-41cb4071b7c9@amlogic.com/
---
Jian Hu (2):
dt-bindings: clock: Add Amlogic A9 peripherals clock controller
clk: amlogic: Add A9 peripherals clock controller driver
.../clock/amlogic,a9-peripherals-clkc.yaml | 160 ++
drivers/clk/meson/Kconfig | 15 +
drivers/clk/meson/Makefile | 1 +
drivers/clk/meson/a9-peripherals.c | 1925 ++++++++++++++++++++
.../clock/amlogic,a9-peripherals-clkc.h | 352 ++++
5 files changed, 2453 insertions(+)
---
base-commit: ca89c88bcf69daca829044c638a8163d5ce47af0
change-id: 20260603-a9_peripherals-4214e79705dc
Best regards,
--
Jian Hu <jian.hu@amlogic.com>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox