Release develop 251105

This commit is contained in:
hongyi
2025-11-05 14:27:31 +08:00
parent 7d0c524a3d
commit 0e5056b0cb
23 changed files with 3959 additions and 2713 deletions

View File

@@ -5,3 +5,4 @@ dtb-$(CONFIG_ARCH_XUANTIE) += th1520-a-val.dtb th1520-a-val-sec.dtb
dtb-$(CONFIG_ARCH_XUANTIE) += th1520-a-val-audio.dtb th1520-a-val-audio-i2s-8ch.dtb th1520-a-val-audio-tdm.dtb th1520-a-val-audio-spdif.dtb th1520-a-val-crash.dtb
dtb-$(CONFIG_ARCH_XUANTIE) += th1520-a-val-dsi0-dsi1.dtb th1520-a-val-dsi0-hdmi.dtb
dtb-$(CONFIG_ARCH_XUANTIE) += th1520-rvbook-product.dtb th1520-rvbook-product-sec.dtb
dtb-$(CONFIG_ARCH_XUANTIE) += a200-dev.dtb

File diff suppressed because it is too large Load Diff

View File

@@ -1,125 +0,0 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
* Copyright (C) 2021-2024 Alibaba Group Holding Limited.
*/
/dts-v1/;
#include <dt-bindings/interrupt-controller/irq.h>
/ {
model = "A200 HAPS";
compatible = "sipeed,lichee-pi-4a", "sipeed,lichee-module-4a", "thead,th1520", "thead,light";
#address-cells = <2>;
#size-cells = <2>;
aliases {
serial0 = &uart0;
};
chosen {
stdout-path = "serial0:115200n8";
};
memory@0 {
device_type = "memory";
reg = <0x0 0x200000 0x0 0xffe00000>;
numa-node-id = <0>;
};
cpus: cpus {
#address-cells = <1>;
#size-cells = <0>;
timebase-frequency = <3000000>;
c910_0: cpu@0 {
compatible = "thead,c910", "riscv";
device_type = "cpu";
riscv,isa = "rv64imafdcv";
reg = <0>;
i-cache-block-size = <64>;
i-cache-size = <65536>;
i-cache-sets = <512>;
d-cache-block-size = <64>;
d-cache-size = <65536>;
d-cache-sets = <512>;
next-level-cache = <&l2_cache>;
mmu-type = "riscv,sv39";
video-4k-minfreq = <1848000000>;
qos-mid-minfreq = <750000000>;
#cooling-cells = <2>;
dynamic-power-coefficient = <500>;
cpu0_intc: interrupt-controller {
compatible = "riscv,cpu-intc";
interrupt-controller;
#interrupt-cells = <1>;
};
};
l2_cache: l2-cache {
compatible = "cache";
cache-block-size = <64>;
cache-level = <2>;
cache-size = <1048576>;
cache-sets = <1024>;
cache-unified;
};
};
uart_sclk: uart-sclk-clock {
compatible = "fixed-clock";
clock-frequency = <50000000>;
clock-output-names = "uart_sclk";
#clock-cells = <0>;
};
soc {
compatible = "simple-bus";
interrupt-parent = <&plic>;
#address-cells = <2>;
#size-cells = <2>;
dma-noncoherent;
ranges;
uart0: serial@ffe7014000 {
compatible = "snps,dw-apb-uart", "light,uart0";
reg = <0xff 0xe7014000 0x0 0x100>;
interrupts = <36 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&uart_sclk>;
reg-shift = <2>;
reg-io-width = <4>;
current-speed = <115200>; /* OpenSBI */
status = "okay";
};
/* OpenSBI */
reset: reset-sample {
compatible = "thead,reset-sample";
plic-delegate = <0xff 0xd81ffffc>;
entry-reg = <0xff 0xff019050>;
entry-cnt = <4>;
control-reg = <0xff 0xff015004>;
control-val = <0x1c>;
csr-copy = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3 0x7c5 0x7cc 0x7ce>;
};
plic: interrupt-controller@ffd8000000 {
compatible = "thead,th1520-plic", "thead,c900-plic", "riscv,plic0";
reg = <0xff 0xd8000000 0x0 0x01000000>;
interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>;
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <2>;
riscv,ndev = <240>;
};
clint: timer@ffdc000000 {
compatible = "thead,th1520-clint", "thead,c900-clint", "riscv,clint0";
reg = <0xff 0xdc000000 0x0 0x0000d000>;
interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>;
clint,has-no-64bit-mmio;
};
};
};

View File

@@ -24,11 +24,15 @@
ethernet0 = &gmac0;
ethernet1 = &gmac1;
gpio0 = &gpio0;
gpio1 = &gpio1;
gpio2 = &gpio2;
gpio3 = &gpio3;
gpio4 = &gpio4;
gpio0 = &ao_gpio0;
gpio1 = &ao_gpio1;
gpio2 = &gpio0;
gpio3 = &gpio1;
gpio4 = &gpio2;
gpio5 = &gpio3;
gpio6 = &gpio4;
gpio7 = &aw9535_0;
gpio8 = &aw9535_1;
i2c0 = &i2c0;
i2c1 = &i2c1;
@@ -38,7 +42,7 @@
i2c5 = &i2c5;
i2c6 = &i2c6;
i2c7 = &i2c7;
aoi2c1 = &aoi2c1;
i2c8 = &aoi2c1;
can0 = &can0;
can1 = &can1;
@@ -153,6 +157,181 @@
chosen {
stdout-path = "serial4";
};
lcd0_backlight: pwm-backlight@0 {
compatible = "pwm-backlight";
status = "okay";
pwms = <&pwm1 2 100000 0>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
enable-gpios = <&aw9535_1 15 GPIO_ACTIVE_HIGH>;
};
reg_vdd33_lcd0: regulator-vdd33-lcd0 {
compatible = "regulator-fixed";
regulator-name = "lcd0_vdd33";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&aw9535_1 5 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
reg_vddtp33_lcd0: regulator-vddtp33-lcd0 {
compatible = "regulator-fixed";
regulator-name = "lcd0_vddtp33";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&aw9535_1 14 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
};
&aon {
regulators {
compatible = "zhihe,a210-aon-regulator";
avdd33_emmc_reg: avdd33_emmc {
regulator-name = "avdd33_emmc";
regulator-type = "voltage";
regulator-always-on;
};
avdd33_usb2_reg: avdd33_usb2 {
regulator-name = "avdd33_usb2";
regulator-type = "voltage";
regulator-always-on;
};
dvdd08_aon_reg: dvdd08_aon {
regulator-name = "dvdd08_aon";
regulator-type = "voltage";
regulator-always-on;
};
avdd18_aon_reg: avdd18_aon {
regulator-name = "avdd18_aon";
regulator-type = "voltage";
regulator-always-on;
};
avdd18_emmc_usb2_reg: avdd18_emmc_usb2 {
regulator-name = "avdd18_emmc_usb2";
regulator-type = "voltage";
regulator-always-on;
};
avdd18_emmc_peri_reg: avdd18_emmc_peri {
regulator-name = "avdd18_emmc_peri";
regulator-type = "voltage";
regulator-always-on;
};
avdd18_top_reg: avdd18_top {
regulator-name = "avdd18_top";
regulator-type = "voltage";
regulator-always-on;
};
avdd18_pll_reg: avdd18_pll {
regulator-name = "avdd18_pll";
regulator-type = "voltage";
regulator-always-on;
};
avdd18_reg: avdd18 {
regulator-name = "avdd18";
regulator-type = "voltage";
regulator-always-on;
};
dvdd18_ddr_vaa_reg: dvdd18_ddr_vaa {
regulator-name = "dvdd18_ddr_vaa";
regulator-type = "voltage";
regulator-always-on;
};
p3v3_reg: p3v3 {
regulator-name = "p3v3";
regulator-type = "voltage";
regulator-always-on;
};
dvdd08_top_reg: dvdd08_top {
regulator-name = "dvdd08_top";
regulator-type = "voltage";
regulator-always-on;
};
dvdd06_ddr_vddqlp_reg: dvdd06_ddr_vddqlp {
regulator-name = "dvdd06_ddr_vddqlp";
regulator-type = "voltage";
regulator-always-on;
};
dvdd08_ddr_reg: dvdd08_ddr {
regulator-name = "dvdd08_ddr";
regulator-type = "voltage";
regulator-settling-time-us = <1000>;
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <800000>;
regulator-always-on;
};
dvdd_cpu_reg: dvdd_cpu {
regulator-name = "dvdd_cpu";
regulator-type = "voltage";
regulator-settling-time-us = <1000>;
regulator-min-microvolt = <600000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
};
dvddm_cpu_reg: dvddm_cpu {
regulator-name = "dvddm_cpu";
regulator-type = "voltage";
regulator-settling-time-us = <1000>;
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
};
dvdd_vp_reg: dvdd_vp {
regulator-name = "dvdd_vp";
regulator-type = "voltage";
regulator-settling-time-us = <1000>;
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <800000>;
regulator-always-on;
};
dvdd_npu_vip_reg: dvdd_npu_vip {
regulator-name = "dvdd_npu_vip";
regulator-type = "voltage";
regulator-settling-time-us = <1000>;
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
};
dvdd_cpu_p_reg: dvdd_cpu_p {
regulator-name = "dvdd_cpu_p";
regulator-type = "voltage";
regulator-settling-time-us = <1000>;
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
};
dvdd_gpu_reg: dvdd_gpu {
regulator-name = "dvdd_gpu";
regulator-type = "voltage";
regulator-settling-time-us = <1000>;
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <800000>;
regulator-always-on;
};
};
};
&aon_padctrl {
@@ -788,3 +967,66 @@
sata-clk-pwren-gpios = <&aw9535_1 13 GPIO_ACTIVE_HIGH>;
status = "disabled";
};
&mipi0_csi0 {
status = "disabled";
};
&mipi0_csi1 {
//combination 4lane mode: host addr; aphy ctrl addr; bphy ctrl addr; mipi_ctrl addr
reg = < 0x00 0x06310000 0x0 0x10000
0x00 0x063a0020 0x0 0x4
0x00 0x063a0024 0x0 0x4
0x00 0x063a0028 0x0 0x4>;
phy_name = "CSI_4LANE"; //combination 4lane
};
//config dsi display: dpu_disp0->dup_enc0->dsi0->lcd_plane
&dpu_enc0 {
status = "disabled";
ports {
/* output */
port@1 {
reg = <1>;
enc0_out: endpoint {
remote-endpoint = <&dsi0_in>;
};
};
};
};
&dhost_0 {
status = "disabled";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
dsi0_in: endpoint {
remote-endpoint = <&enc0_out>;
};
};
port@1 {
reg = <1>;
dsi0_out: endpoint {
remote-endpoint = <&panel0_in>;
};
};
};
panel0@0 {
compatible = "jadard,jd9365da-h3";
reg = <0>;
backlight = <&lcd0_backlight>;
reset-gpio = <&aw9535_0 13 0>; /* active low */
hsvcc-supply = <&reg_vdd33_lcd0>;
vspn3v3-supply = <&reg_vddtp33_lcd0>;
port {
panel0_in: endpoint {
remote-endpoint = <&dsi0_out>;
};
};
};
};

View File

@@ -1,844 +0,0 @@
/dts-v1/;
#include "a210-soc-core.dtsi"
#include "a210-soc-peri.dtsi"
#include "a210-platform-evb.dtsi"
#define SOUND_CARD_LINK(REG, FMT, CPU, M, CODEC, N) \
simple-audio-card,dai-link@##REG { \
reg = <REG>; \
format = #FMT; \
cpu { \
sound-dai = <&audio_##CPU M>; \
}; \
codec { \
sound-dai = <&codec_##CODEC N>; \
}; \
}
/ {
model = "A210 EVB configuration";
aliases {
ethernet0 = &gmac0;
ethernet1 = &gmac1;
gpio0 = &gpio0;
gpio1 = &gpio1;
gpio2 = &gpio2;
gpio3 = &gpio3;
gpio4 = &gpio4;
i2c0 = &i2c0;
i2c1 = &i2c1;
i2c2 = &i2c2;
i2c3 = &i2c3;
i2c4 = &i2c4;
i2c5 = &i2c5;
i2c6 = &i2c6;
i2c7 = &i2c7;
can0 = &can0;
can1 = &can1;
can2 = &can2;
mmc0 = &emmc;
mmc1 = &sdhci0;
serial0 = &uart0;
serial1 = &uart1;
serial2 = &uart2;
serial3 = &uart3;
serial4 = &uart4;
serial5 = &uart5;
serial6 = &uart6;
serial7 = &uart7;
serial8 = &uart8;
serial9 = &uart9;
spi0 = &qspi0;
spi1 = &qspi1;
spi2 = &spi0;
spi3 = &spi1;
pcie3x4 = &dm3x4;
pcie3x1 = &rp3x1;
};
/* The first 2M will be reserved in the Kernel, and the entire available range is set here */
memory@0 {
device_type = "memory";
reg = <0x00 0x80000000 0x01 0x00000000>; /* 4G - 64MB */
numa-node-id = <0>;
};
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
linux,cma {
compatible = "shared-dma-pool";
reusable;
size = <0x00 0x4000000>;
alloc-ranges = <0x00 0x90000000 0x00 0x4000000>;
linux,cma-default;
};
memory@1c000000 {
reg = <0x00 0x1c000000 0x00 0x2000000>;
no-map;
};
framebuffer: framebuffer@10000000 {
reg = <0x01 0x00 0x00 0x20000000>;
no-map;
};
zh_videomem@100000000 {
reg = <0x01 0x00 0x00 0x20000000>;
no-map;
};
npu_mmu_memory@130000000 {
reg = <0x01 0x30000000 0x00 0x04000000>;
no-map;
};
memblock-memory@17b800000 {
reg = <0x01 0x7b800000 0x00 0x04000000>;
no-map;
};
};
/* The bootargs in U-Boot will override the configuration set here. */
chosen {
stdout-path = "serial4";
};
};
&peri1_padctrl {
gmac0_pins: gmac0-0 {
tx-pins {
pins = "GPIO0_0", /* GMAC0_TX_CLK */
"GPIO0_2", /* GMAC0_TXEN */
"GPIO0_3", /* GMAC0_TXD0 */
"GPIO0_4", /* GMAC0_TXD1 */
"GPIO0_5", /* GMAC0_TXD2 */
"GPIO0_6"; /* GMAC0_TXD3 */
function = "gmac0";
bias-disable;
drive-strength = <25>;
input-disable;
input-schmitt-disable;
slew-rate = <0>;
};
rx-pins {
pins = "GPIO0_1", /* GMAC0_RX_CLK */
"GPIO0_7", /* GMAC0_RXDV */
"GPIO0_8", /* GMAC0_RXD0 */
"GPIO0_9", /* GMAC0_RXD1 */
"GPIO0_10", /* GMAC0_RXD2 */
"GPIO0_11"; /* GMAC0_RXD3 */
function = "gmac0";
bias-disable;
drive-strength = <1>;
input-enable;
input-schmitt-disable;
slew-rate = <0>;
};
};
mdio0_pins: mdio0-0 {
mdc-pins {
pins = "GPIO0_12"; /* GMAC0_MDC */
function = "gmac0";
bias-disable;
drive-strength = <13>;
input-disable;
input-schmitt-disable;
slew-rate = <0>;
};
mdio-pins {
pins = "GPIO0_13"; /* GMAC0_MDIO */
function = "gmac0";
bias-disable;
drive-strength = <13>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
i2c0_pins: i2c0-1 {
i2c-pins {
pins = "GPIO0_24", "GPIO0_25";
function = "i2c0";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
i2c1_pins: i2c1-1 {
i2c-pins {
pins = "GPIO0_26", "GPIO0_27";
function = "i2c1";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
pcie_x1_pins: pcie_x1-1 {
pcie_x1-pins {
pins = "GPIO0_24", "GPIO0_25", "GPIO0_26", "GPIO0_27";
function = "pcie_x1";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
pcie_x4_pins: pcie_x4-1 {
pcie_x4-pins {
pins = "GPIO0_28", "GPIO0_29", "GPIO0_30", "GPIO0_31";
function = "pcie_x4";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
gmac1_pins: gmac1-0 {
tx-pins {
pins = "GPIO1_2", /* GMAC1_TX_CLK */
"GPIO1_4", /* GMAC1_TXEN */
"GPIO1_5", /* GMAC1_TXD0 */
"GPIO1_6", /* GMAC1_TXD1 */
"GPIO1_7", /* GMAC1_TXD2 */
"GPIO1_8"; /* GMAC1_TXD3 */
function = "gmac1";
bias-disable;
drive-strength = <25>;
input-disable;
input-schmitt-disable;
slew-rate = <0>;
};
rx-pins {
pins = "GPIO1_3", /* GMAC1_RX_CLK */
"GPIO1_9", /* GMAC1_RXDV */
"GPIO1_10", /* GMAC1_RXD0 */
"GPIO1_11", /* GMAC1_RXD1 */
"GPIO1_12", /* GMAC1_RXD2 */
"GPIO1_13"; /* GMAC1_RXD3 */
function = "gmac1";
bias-disable;
drive-strength = <1>;
input-enable;
input-schmitt-disable;
slew-rate = <0>;
};
};
mdio1_pins: mdio1-0 {
mdc-pins {
pins = "GPIO1_14"; /* GMAC1_MDC */
function = "gmac1";
bias-disable;
drive-strength = <13>;
input-disable;
input-schmitt-disable;
slew-rate = <0>;
};
mdio-pins {
pins = "GPIO1_15"; /* GMAC1_MDIO */
function = "gmac1";
bias-disable;
drive-strength = <13>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
};
&peri2_padctrl {
uart4_pins: uart4-0 {
tx-pins {
pins = "GPIO2_0";
function = "uart4";
bias-disable;
drive-strength = <3>;
input-disable;
input-schmitt-disable;
slew-rate = <0>;
};
rx-pins {
pins = "GPIO2_1";
function = "uart4";
bias-disable;
drive-strength = <1>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
i2c5_pins: i2c5-0 {
i2c-pins {
pins = "GPIO2_2", "GPIO2_3";
function = "i2c5";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
uart5_pins: uart5-0 {
tx-pins {
pins = "GPIO2_2";
function = "uart5";
bias-disable;
drive-strength = <3>;
input-disable;
input-schmitt-disable;
slew-rate = <0>;
};
rx-pins {
pins = "GPIO2_3";
function = "uart5";
bias-disable;
drive-strength = <1>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
i2c6_pins: i2c6-0 {
i2c-pins {
pins = "GPIO2_4", "GPIO2_5";
function = "i2c6";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
uart7_pins: uart7-0 {
tx-pins {
pins = "GPIO2_6";
function = "uart7";
bias-disable;
drive-strength = <3>;
input-disable;
input-schmitt-disable;
slew-rate = <0>;
};
rx-pins {
pins = "GPIO2_7";
function = "uart7";
bias-disable;
drive-strength = <1>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
// i2c4_pins: i2c4-0 {
// i2c-pins {
// pins = "GPIO2_6", "GPIO2_7";
// function = "i2c4";
// bias-disable;
// drive-strength = <7>;
// input-enable;
// input-schmitt-enable;
// slew-rate = <0>;
// };
// };
i2c7_pins: i2c7-0 {
i2c-pins {
pins = "GPIO2_10", "GPIO2_11";
function = "i2c7";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
spi1_pins: spi1-1 {
spi-pins {
pins = "GPIO2_17", "GPIO2_21", "GPIO2_22";
function = "spi1";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
i2c4_pins: i2c4-2 {
i2c-pins {
pins = "GPIO2_26", "GPIO2_27";
function = "i2c4";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
hdmi_pins: hdmi-0 {
hdmi-pins {
pins = "GPIO2_25", "GPIO2_30", "GPIO2_31";
function = "hdmi";
bias-disable;
drive-strength = <3>;
input-enable;
input-schmitt-disable;
slew-rate = <0>;
};
};
sen_vclk_pins: sen_vclk-1 {
sen_vclk-pins {
pins = "GPIO3_0", "GPIO3_2";
function = "sen_vclk";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
qspi1_pins: qspi1-1 {
qspi-pins {
pins = "GPIO3_2", "GPIO3_5", "GPIO3_6", "GPIO3_7", "GPIO3_8";
function = "qspi1";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
qspi0_pins: qspi0-0 {
qspi-pins {
pins = "GPIO0_18", "GPIO0_20", "GPIO0_21", "GPIO0_22", "GPIO0_23";
function = "qspi0";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
i2c7_smb_pins: i2c7-smb-0 {
i2c-pins {
pins = "GPIO3_6", "GPIO3_7", "GPIO3_8", "GPIO3_9", "GPIO3_10";
function = "i2c7_smb";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
usb31_pins: usb31-0 {
usb31-pins {
pins = "GPIO3_10";
function = "usb31";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
};
&gmac0 {
phy-mode = "rgmii-id";
pinctrl-names = "default";
pinctrl-0 = <&gmac0_pins>;
rx-clk-delay = <0x00>; /* for RGMII */
tx-clk-delay = <0x00>; /* for RGMII */
phy-handle = <&phy0>;
};
&mdio0 {
pinctrl-names = "default";
pinctrl-0 = <&mdio0_pins>;
phy0: ethernet-phy@0 {
reg = <0x0>;
};
};
&gmac1 {
phy-mode = "rgmii-id";
pinctrl-names = "default";
pinctrl-0 = <&gmac1_pins>;
rx-clk-delay = <0x00>; /* for RGMII */
tx-clk-delay = <0x00>; /* for RGMII */
phy-handle = <&phy1>;
status = "okay";
};
&mdio1 {
pinctrl-names = "default";
pinctrl-0 = <&mdio1_pins>;
phy1: ethernet-phy@0 {
reg = <0x0>;
};
};
&spi1 {
cs-gpios = <&gpio2_porta 18 0>;
rx-sample-delay-ns = <10>;
pinctrl-names = "default";
pinctrl-0 = <&spi1_pins>;
status = "okay";
spi_norflash@0 {
status = "disabled";
#address-cells = <1>;
#size-cells = <1>;
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <50000000>;
w25q,fast-read;
};
};
&qspi0 {
cs-gpios = <&gpio0_porta 15 0>; // QSPI0_CSN1
// cs-gpios = <&gpio0_porta 19 0>; // QSPI0_CSN0
rx-sample-dly = <4>;
pinctrl-names = "default";
pinctrl-0 = <&qspi0_pins>;
spi_norflash@0 {
compatible = "jedec,spi-nor";
#address-cells = <1>;
#size-cells = <1>;
spi-tx-bus-width = <4>;
spi-rx-bus-width = <4>;
spi-max-frequency = <50000000>;
reg = <0>;
status = "disabled";
};
spi-nandflash@1 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "spi-nand";
spi-max-frequency = <100000000>;
spi-tx-bus-width = <4>;
spi-rx-bus-width = <4>;
reg = <1>;
status = "disabled";
partition@0 {
label = "nand1";
reg = <0x00000000 0x08000000>;
};
};
};
&qspi1 {
cs-gpios = <&gpio2_porta 29 0>;
rx-sample-dly = <4>;
pinctrl-names = "default";
pinctrl-0 = <&qspi1_pins>;
spi_norflash@0 {
compatible = "jedec,spi-nor";
#address-cells = <1>;
#size-cells = <1>;
spi-tx-bus-width = <4>;
spi-rx-bus-width = <4>;
spi-max-frequency = <50000000>;
reg = <0>;
status = "okay";
};
spi-nandflash@1 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "spi-nand";
spi-max-frequency = <100000000>;
spi-tx-bus-width = <4>;
spi-rx-bus-width = <4>;
reg = <1>;
status = "disabled";
partition@0 {
label = "nand1";
reg = <0x00000000 0x08000000>;
};
};
};
&i2c0 {
pinctrl-names = "default";
pinctrl-0 = <&i2c0_pins>;
clock-frequency = <400000>;
eeprom@50 {
status = "okay";
compatible = "atmel,24c02";
reg = <0x50>;
pagesize = <16>;
};
codec_es8156_dac0: es8156@8 {
compatible = "everest,es8156";
reg = <0x8>;
#sound-dai-cells = <1>;
sound-name-prefix = "ES8156_DAC0";
mclk-sclk-ratio = <4>;
status = "disabled";
};
codec_es7210_adc0: es7210@40 {
compatible = "MicArray_0";
reg = <0x40>;
#sound-dai-cells = <1>;
work-mode = "ES7210_NORMAL_I2S";
channels-max = <2>;
mclk-sclk-ratio = <4>;
sound-name-prefix = "ES7210_ADC0";
status = "disabled";
};
audio_aw87565_pa0: audio_pa0@58 {
compatible = "awinic,aw87565_pa";
reg = <0x58>;
sound-name-prefix = "AW87565_PA0";
status = "disabled";
};
audio_aw87565_pa1: audio_pa1@5b {
compatible = "awinic,aw87565_pa";
reg = <0x5b>;
sound-name-prefix = "AW87565_PA1";
status = "disabled";
};
};
&i2c1 {
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins>;
clock-frequency = <400000>;
codec_es8156_dac1: es8156@8 {
compatible = "everest,es8156";
reg = <0x8>;
#sound-dai-cells = <1>;
sound-name-prefix = "ES8156_DAC1";
mclk-sclk-ratio = <4>;
status = "disabled";
};
codec_es7210_adc1: es7210@40 {
compatible = "MicArray_1";
reg = <0x40>;
#sound-dai-cells = <1>;
work-mode = "ES7210_NORMAL_I2S";
channels-max = <2>;
mclk-sclk-ratio = <4>;
sound-name-prefix = "ES7210_ADC1";
status = "disabled";
};
audio_aw87565_pa2: audio_pa2@58 {
compatible = "awinic,aw87565_pa";
reg = <0x58>;
sound-name-prefix = "AW87565_PA2";
status = "disabled";
};
audio_aw87565_pa3: audio_pa3@5b {
compatible = "awinic,aw87565_pa";
reg = <0x5b>;
sound-name-prefix = "AW87565_PA3";
status = "disabled";
};
};
&i2c4 {
pinctrl-names = "default";
pinctrl-0 = <&i2c4_pins>;
clock-frequency = <400000>;
};
&i2c5 {
pinctrl-names = "default";
pinctrl-0 = <&i2c5_pins>;
clock-frequency = <400000>;
};
&i2c6 {
pinctrl-names = "default";
pinctrl-0 = <&i2c6_pins>;
clock-frequency = <400000>;
};
&uart4 {
pinctrl-names = "default";
pinctrl-0 = <&uart4_pins>;
};
&uart7 {
pinctrl-names = "default";
pinctrl-0 = <&uart7_pins>;
};
&emmc {
max-frequency = <196608000>;
non-removable;
mmc-hs200-1_8v;
io_fixed_1v8;
is_emmc;
no-sdio;
no-sd;
pull_up;
bus-width = <8>;
};
&sdhci0 {
max-frequency = <196608000>;
bus-width = <4>;
pull_up;
wprtn_ignore;
};
&vp_dfmu_iommu {
status = "disabled";
};
&vp_dfmu_mt {
status = "disabled";
};
&npu_dfmu_iommu {
status = "disabled";
};
&npu_dfmu_mt {
status = "disabled";
};
&vi_dfmu_iommu {
status = "disabled";
};
&vi_dfmu_mt {
status = "disabled";
};
&vo_dfmu_iommu {
status = "disabled";
};
&vo_dfmu_mt {
status = "disabled";
};
&peri1_dfmu_iommu {
status = "okay";
};
&peri1_dfmu_mt {
status = "disabled";
};
&pcie_dfmu_iommu {
status = "okay";
};
&pcie_dfmu_mt {
status = "disabled";
};
&usb_dfmu_iommu {
status = "okay";
};
&usb_dfmu_mt {
status = "disabled";
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* FIXME: clk stages overlay to be selected for real SOC. */
/* bringup stage 3: full subsys + high freq */
/* refer to maximum clk freq in p100-soc-core.dtsi */
/* bringup stage 2: full subsys + medium freq*/
&clk_peri {
peri1_spi_ssi_clk_frequency = <220000000>;
peri2_spi_ssi_clk_frequency = <220000000>;
peri1_qspi_ssi_clk_frequency = <220000000>;
peri2_qspi_ssi_clk_frequency = <220000000>;
uart_sclk_frequency = <24000000>;
emmc_ref_clk_frequency = <203076924>;
tee_clk_frequency = <200000000>;
};
&clk_pcie {
pcie_ss_axi_m_aclk_frequency = <240000000>;
};
&clk_npu {
npu_cclk_frequency = <600000000>;
npu_aclk_frequency = <600000000>;
};
&emmc {
max-frequency = <49152000>;
};
&sdhci0 {
max-frequency = <49152000>;
};
/* bringup stage 1: minisys + low freq */
&clk {
top_cfg_aclk_frequency = <165000000>;
top_pclk_frequency = <82500000>;
top_amux_clk_frequency = <240000000>;
iommu_ptw_aclk_frequency = <165000000>;
noc_cclk_frequency = <240000000>;
top_cpusys_bus_clk_frequency = <220000000>;
top_cpusys_pic_clk_frequency = <250000000>;
};
&clk_peri {
peri1_spi_ssi_clk_frequency = <220000000>;
peri2_spi_ssi_clk_frequency = <220000000>;
peri1_qspi_ssi_clk_frequency = <220000000>;
peri2_qspi_ssi_clk_frequency = <220000000>;
uart_sclk_frequency = <24000000>;
emmc_ref_clk_frequency = <203076924>;
peri1_mst_aclk_frequency = <165000000>;
peri3_mst_aclk_frequency = <220000000>;
tee_clk_frequency = <200000000>;
};
&emmc {
max-frequency = <49152000>;
};
&sdhci0 {
max-frequency = <49152000>;
};

View File

@@ -10,6 +10,8 @@
aliases {
mmc0 = &emmc;
serial4 = &uart4;
ethernet0 = &gmac0;
ethernet1 = &gmac1;
};
/* The first 2M will be reserved in the Kernel, and the entire available range is set here */
@@ -70,6 +72,51 @@
};
};
&peri1_padctrl {
gmac0_pins: gmac0-0 {
txclk-pins {
pins = "GPIO0_0", /* GMAC0_TX_CLK */
"GPIO0_12"; /* GMAC0_MDC */
function = "gmac0";
bias-disable;
drive-strength = <13>;
input-disable;
input-schmitt-disable;
slew-rate = <0>;
};
tx-pins {
pins = "GPIO0_2", /* GMAC0_TXEN */
"GPIO0_3", /* GMAC0_TXD0 */
"GPIO0_4", /* GMAC0_TXD1 */
"GPIO0_5", /* GMAC0_TXD2 */
"GPIO0_6"; /* GMAC0_TXD3 */
function = "gmac0";
bias-disable;
drive-strength = <20>;
input-disable;
input-schmitt-disable;
slew-rate = <0>;
};
rx-pins {
pins = "GPIO0_1", /* GMAC0_RX_CLK */
"GPIO0_7", /* GMAC0_RXDV */
"GPIO0_8", /* GMAC0_RXD0 */
"GPIO0_9", /* GMAC0_RXD1 */
"GPIO0_10", /* GMAC0_RXD2 */
"GPIO0_11", /* GMAC0_RXD3 */
"GPIO0_13"; /* GMAC0_MDIO */
function = "gmac0";
bias-disable;
drive-strength = <13>;
input-enable;
input-schmitt-disable;
slew-rate = <0>;
};
};
};
&uart0 {
status = "disabled";
};
@@ -244,11 +291,18 @@
};
&gmac0 {
status = "disabled";
phy-mode = "rgmii-id";
pinctrl-names = "default";
pinctrl-0 = <&gmac0_pins>;
rx-clk-delay = <0x00>; /* for RGMII */
tx-clk-delay = <0x00>; /* for RGMII */
phy-handle = <&phy0>;
};
&mdio0 {
status = "disabled";
phy0: ethernet-phy@0 {
reg = <0x0>;
};
};
&gmac1 {

View File

@@ -1,820 +0,0 @@
/dts-v1/;
#include "a210-soc-core.dtsi"
#include "a210-soc-peri.dtsi"
#include "a210-platform-evb.dtsi"
#define SOUND_CARD_LINK(REG, FMT, CPU, M, CODEC, N) \
simple-audio-card,dai-link@##REG { \
reg = <REG>; \
format = #FMT; \
cpu { \
sound-dai = <&audio_##CPU M>; \
}; \
codec { \
sound-dai = <&codec_##CODEC N>; \
}; \
}
/ {
model = "A210 EVB configuration";
aliases {
ethernet0 = &gmac0;
ethernet1 = &gmac1;
mmc0 = &emmc;
mmc1 = &sdhci0;
serial0 = &uart0;
serial1 = &uart1;
serial2 = &uart2;
serial3 = &uart3;
serial4 = &uart4;
serial5 = &uart5;
serial6 = &uart6;
serial7 = &uart7;
serial8 = &uart8;
serial9 = &uart9;
spi0 = &qspi0;
spi1 = &qspi1;
spi2 = &spi0;
spi3 = &spi1;
pcie3x4 = &dm3x4;
pcie3x1 = &rp3x1;
};
/* The first 2M will be reserved in the Kernel, and the entire available range is set here */
memory@0 {
device_type = "memory";
reg = <0x00 0x80000000 0x01 0x00000000>; /* 4G - 64MB */
numa-node-id = <0>;
};
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
linux,cma {
compatible = "shared-dma-pool";
reusable;
size = <0x00 0x4000000>;
alloc-ranges = <0x00 0x90000000 0x00 0x4000000>;
linux,cma-default;
};
memory@1c000000 {
reg = <0x00 0x1c000000 0x00 0x2000000>;
no-map;
};
framebuffer: framebuffer@10000000 {
reg = <0x01 0x00 0x00 0x20000000>;
no-map;
};
zh_videomem@100000000 {
reg = <0x01 0x00 0x00 0x20000000>;
no-map;
};
npu_mmu_memory@130000000 {
reg = <0x01 0x30000000 0x00 0x04000000>;
no-map;
};
memblock-memory@17b800000 {
reg = <0x01 0x7b800000 0x00 0x04000000>;
no-map;
};
};
/* The bootargs in U-Boot will override the configuration set here. */
chosen {
stdout-path = "serial4";
};
};
&peri1_padctrl {
gmac0_pins: gmac0-0 {
tx-pins {
pins = "GPIO0_0", /* GMAC0_TX_CLK */
"GPIO0_2", /* GMAC0_TXEN */
"GPIO0_3", /* GMAC0_TXD0 */
"GPIO0_4", /* GMAC0_TXD1 */
"GPIO0_5", /* GMAC0_TXD2 */
"GPIO0_6"; /* GMAC0_TXD3 */
function = "gmac0";
bias-disable;
drive-strength = <25>;
input-disable;
input-schmitt-disable;
slew-rate = <0>;
};
rx-pins {
pins = "GPIO0_1", /* GMAC0_RX_CLK */
"GPIO0_7", /* GMAC0_RXDV */
"GPIO0_8", /* GMAC0_RXD0 */
"GPIO0_9", /* GMAC0_RXD1 */
"GPIO0_10", /* GMAC0_RXD2 */
"GPIO0_11"; /* GMAC0_RXD3 */
function = "gmac0";
bias-disable;
drive-strength = <1>;
input-enable;
input-schmitt-disable;
slew-rate = <0>;
};
};
mdio0_pins: mdio0-0 {
mdc-pins {
pins = "GPIO0_12"; /* GMAC0_MDC */
function = "gmac0";
bias-disable;
drive-strength = <13>;
input-disable;
input-schmitt-disable;
slew-rate = <0>;
};
mdio-pins {
pins = "GPIO0_13"; /* GMAC0_MDIO */
function = "gmac0";
bias-disable;
drive-strength = <13>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
qspi0_pins: qspi0-0 {
qspi-pins {
pins = "GPIO0_18", "GPIO0_20", "GPIO0_21", "GPIO0_22", "GPIO0_23";
function = "qspi0";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
can0_pins: can0-0 {
can-pins {
pins = "GPIO0_24", "GPIO0_25";
function = "can0";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
can1_pins: can1-0 {
can-pins {
pins = "GPIO0_26", "GPIO0_27";
function = "can1";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
spi0_pins: spi0-0 {
spi-pins {
pins = "GPIO0_28", "GPIO0_29", "GPIO1_1";
function = "spi0";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
gmac1_pins: gmac1-0 {
tx-pins {
pins = "GPIO1_2", /* GMAC1_TX_CLK */
"GPIO1_4", /* GMAC1_TXEN */
"GPIO1_5", /* GMAC1_TXD0 */
"GPIO1_6", /* GMAC1_TXD1 */
"GPIO1_7", /* GMAC1_TXD2 */
"GPIO1_8"; /* GMAC1_TXD3 */
function = "gmac1";
bias-disable;
drive-strength = <25>;
input-disable;
input-schmitt-disable;
slew-rate = <0>;
};
rx-pins {
pins = "GPIO1_3", /* GMAC1_RX_CLK */
"GPIO1_9", /* GMAC1_RXDV */
"GPIO1_10", /* GMAC1_RXD0 */
"GPIO1_11", /* GMAC1_RXD1 */
"GPIO1_12", /* GMAC1_RXD2 */
"GPIO1_13"; /* GMAC1_RXD3 */
function = "gmac1";
bias-disable;
drive-strength = <1>;
input-enable;
input-schmitt-disable;
slew-rate = <0>;
};
};
mdio1_pins: mdio1-0 {
mdc-pins {
pins = "GPIO1_14"; /* GMAC1_MDC */
function = "gmac1";
bias-disable;
drive-strength = <13>;
input-disable;
input-schmitt-disable;
slew-rate = <0>;
};
mdio-pins {
pins = "GPIO1_15"; /* GMAC1_MDIO */
function = "gmac1";
bias-disable;
drive-strength = <13>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
};
&peri2_padctrl {
i2c4_pins: i2c4-2 {
i2c-pins {
pins = "GPIO0_26", "GPIO0_27";
function = "i2c4";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
uart4_pins: uart4-0 {
uart-pins {
pins = "GPIO2_0", "GPIO2_1";
function = "uart4";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
uart5_pins: uart5-0 {
uart-pins {
pins = "GPIO2_2", "GPIO2_3";
function = "uart5";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
i2c5_pins: i2c5-0 {
i2c-pins {
pins = "GPIO2_2", "GPIO2_3";
function = "i2c5";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
uart6_pins: uart6-0 {
uart-pins {
pins = "GPIO2_4", "GPIO2_5", "GPIO2_8", "GPIO2_9"; // TXD/RXD/CTSN/RTSN
function = "uart6";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
i2c6_pins: i2c6-0 {
i2c-pins {
pins = "GPIO2_4", "GPIO2_5";
function = "i2c6";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
uart7_pins: uart7-0 {
uart-pins {
pins = "GPIO2_6", "GPIO2_7";
function = "uart7";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
uart9_pins: uart9-0 {
uart-pins {
pins = "GPIO2_10", "GPIO2_11";
function = "uart9";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
i2c7_pins: i2c7-0 {
i2c-pins {
pins = "GPIO2_10", "GPIO2_11";
function = "i2c7";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
pwm1_pins: pwm1 {
pwm-pins {
pins = "GPIO2_12", "GPIO2_28"; // PWM1_CH2-0/PWM1_CH0-1
function = "pwm1";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
spi1_pins: spi1-1 {
spi-pins {
pins = "GPIO2_17", "GPIO2_21", "GPIO2_22";
function = "spi1";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
hdmi_pins: hdmi-0 {
hdmi-pins {
pins = "GPIO2_25", "GPIO2_30", "GPIO2_31";
function = "hdmi";
bias-disable;
drive-strength = <3>;
input-enable;
input-schmitt-disable;
slew-rate = <0>;
};
};
can2_pins: can2-0 {
can-pins {
pins = "GPIO3_0", "GPIO3_1";
function = "can2";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
qspi1_pins: qspi1-1 {
qspi-pins {
pins = "GPIO3_2", "GPIO3_5", "GPIO3_6", "GPIO3_7", "GPIO3_8";
function = "qspi1";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
dptx_pins: dptx-1 {
dptx-pins {
pins = "GPIO3_9";
function = "dptx";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
usb31_pins: usb31-0 {
usb31-pins {
pins = "GPIO3_10";
function = "usb31";
bias-disable;
drive-strength = <7>;
input-enable;
input-schmitt-enable;
slew-rate = <0>;
};
};
};
&spi0 {
cs-gpios = <&gpio0_porta 30 0>;
rx-sample-delay-ns = <10>;
pinctrl-names = "default";
pinctrl-0 = <&spi0_pins>;
spi_norflash@0 {
status = "okay";
#address-cells = <1>;
#size-cells = <1>;
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <50000000>;
w25q,fast-read;
};
spidev@1 {
status = "disabled";
compatible = "spidev";
#address-cells = <0x1>;
#size-cells = <0x1>;
reg = <0x1>;
spi-max-frequency = <50000000>;
};
};
&spi1 {
cs-gpios = <&gpio2_porta 18 0>;
rx-sample-delay-ns = <10>;
pinctrl-names = "default";
pinctrl-0 = <&spi1_pins>;
spi_norflash@0 {
status = "disabled";
#address-cells = <1>;
#size-cells = <1>;
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <50000000>;
w25q,fast-read;
};
};
&qspi0 {
cs-gpios = <&gpio0_porta 19 0>;
rx-sample-dly = <4>;
pinctrl-names = "default";
pinctrl-0 = <&qspi0_pins>;
spi_norflash@0 {
status = "disabled";
compatible = "jedec,spi-nor";
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
spi-tx-bus-width = <4>;
spi-rx-bus-width = <4>;
spi-max-frequency = <50000000>;
};
spi-nandflash@1 {
status = "disabled";
#address-cells = <1>;
#size-cells = <1>;
compatible = "spi-nand";
spi-max-frequency = <100000000>;
spi-tx-bus-width = <4>;
spi-rx-bus-width = <4>;
reg = <1>;
partition@0 {
label = "nand0";
reg = <0x00000000 0x08000000>;
};
};
};
&qspi1 {
cs-gpios = <&gpio2_porta 29 0>;
rx-sample-dly = <4>;
pinctrl-names = "default";
pinctrl-0 = <&qspi1_pins>;
spi_norflash@0 {
status = "okay";
compatible = "jedec,spi-nor";
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
spi-tx-bus-width = <4>;
spi-rx-bus-width = <4>;
spi-max-frequency = <50000000>;
};
spi-nandflash@1 {
status = "disabled";
#address-cells = <1>;
#size-cells = <1>;
compatible = "spi-nand";
spi-max-frequency = <100000000>;
spi-tx-bus-width = <4>;
spi-rx-bus-width = <4>;
reg = <1>;
partition@0 {
label = "nand1";
reg = <0x00000000 0x08000000>;
};
};
};
&emmc {
max-frequency = <196608000>;
non-removable;
mmc-hs200-1_8v;
io_fixed_1v8;
is_emmc;
no-sdio;
no-sd;
pull_up;
bus-width = <8>;
};
&sdhci0 {
max-frequency = <196608000>;
bus-width = <4>;
pull_up;
wprtn_ignore;
};
&gmac0 {
phy-mode = "rgmii-id";
pinctrl-names = "default";
pinctrl-0 = <&gmac0_pins>;
rx-clk-delay = <0x00>; /* for RGMII */
tx-clk-delay = <0x00>; /* for RGMII */
phy-handle = <&phy0>;
};
&mdio0 {
pinctrl-names = "default";
pinctrl-0 = <&mdio0_pins>;
phy0: ethernet-phy@0 {
reg = <0x0>;
};
};
&gmac1 {
phy-mode = "rgmii-id";
pinctrl-names = "default";
pinctrl-0 = <&gmac1_pins>;
rx-clk-delay = <0x00>; /* for RGMII */
tx-clk-delay = <0x00>; /* for RGMII */
phy-handle = <&phy1>;
};
&mdio1 {
pinctrl-names = "default";
pinctrl-0 = <&mdio1_pins>;
phy1: ethernet-phy@1 {
reg = <0x0>;
};
};
&i2c4 {
pinctrl-names = "default";
pinctrl-0 = <&i2c4_pins>;
clock-frequency = <400000>;
};
&i2c5 {
pinctrl-names = "default";
pinctrl-0 = <&i2c5_pins>;
clock-frequency = <400000>;
};
&i2c6 {
pinctrl-names = "default";
pinctrl-0 = <&i2c6_pins>;
clock-frequency = <400000>;
};
&i2c7 {
pinctrl-names = "default";
pinctrl-0 = <&i2c7_pins>;
clock-frequency = <400000>;
};
&uart4 {
pinctrl-names = "default";
pinctrl-0 = <&uart4_pins>;
};
&uart5 {
pinctrl-names = "default";
pinctrl-0 = <&uart5_pins>;
};
&uart6 {
pinctrl-names = "default";
pinctrl-0 = <&uart6_pins>;
};
&uart7 {
pinctrl-names = "default";
pinctrl-0 = <&uart7_pins>;
};
&uart9 {
pinctrl-names = "default";
pinctrl-0 = <&uart9_pins>;
};
&pwm1 {
pinctrl-names = "default";
pinctrl-0 = <&pwm1_pins>;
};
&can0 {
pinctrl-names = "default";
pinctrl-0 = <&can0_pins>;
};
&can1 {
pinctrl-names = "default";
pinctrl-0 = <&can1_pins>;
};
&can2 {
pinctrl-names = "default";
pinctrl-0 = <&can2_pins>;
};
&vp_dfmu_iommu {
status = "disabled";
};
&vp_dfmu_mt {
status = "disabled";
};
&npu_dfmu_iommu {
status = "disabled";
};
&npu_dfmu_mt {
status = "disabled";
};
&vi_dfmu_iommu {
status = "disabled";
};
&vi_dfmu_mt {
status = "disabled";
};
&vo_dfmu_iommu {
status = "disabled";
};
&vo_dfmu_mt {
status = "disabled";
};
&peri1_dfmu_iommu {
status = "disabled";
};
&peri1_dfmu_mt {
status = "disabled";
};
&pcie_dfmu_iommu {
status = "disabled";
};
&pcie_dfmu_mt {
status = "disabled";
};
&usb_dfmu_iommu {
status = "disabled";
};
&usb_dfmu_mt {
status = "disabled";
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* FIXME: clk stages overlay to be selected for real SOC. */
/* bringup stage 3: full subsys + high freq */
/* refer to maximum clk freq in p100-soc-core.dtsi */
/* bringup stage 2: full subsys + medium freq*/
&clk_peri {
peri1_spi_ssi_clk_frequency = <220000000>;
peri2_spi_ssi_clk_frequency = <220000000>;
peri1_qspi_ssi_clk_frequency = <220000000>;
peri2_qspi_ssi_clk_frequency = <220000000>;
uart_sclk_frequency = <24000000>;
emmc_ref_clk_frequency = <203076924>;
tee_clk_frequency = <200000000>;
};
&clk_pcie {
pcie_ss_axi_m_aclk_frequency = <240000000>;
};
&clk_npu {
npu_cclk_frequency = <600000000>;
npu_aclk_frequency = <600000000>;
};
&emmc {
max-frequency = <49152000>;
};
&sdhci0 {
max-frequency = <49152000>;
};
/* bringup stage 1: minisys + low freq */
&clk {
top_cfg_aclk_frequency = <165000000>;
top_pclk_frequency = <82500000>;
top_amux_clk_frequency = <240000000>;
iommu_ptw_aclk_frequency = <165000000>;
noc_cclk_frequency = <240000000>;
top_cpusys_bus_clk_frequency = <220000000>;
top_cpusys_pic_clk_frequency = <250000000>;
};
&clk_peri {
peri1_spi_ssi_clk_frequency = <220000000>;
peri2_spi_ssi_clk_frequency = <220000000>;
peri1_qspi_ssi_clk_frequency = <220000000>;
peri2_qspi_ssi_clk_frequency = <220000000>;
uart_sclk_frequency = <24000000>;
emmc_ref_clk_frequency = <203076924>;
peri1_mst_aclk_frequency = <165000000>;
peri3_mst_aclk_frequency = <220000000>;
tee_clk_frequency = <200000000>;
};
&emmc {
max-frequency = <49152000>;
};
&sdhci0 {
max-frequency = <49152000>;
};
&clk_gpu {
status = "disabled";
};
&clk_pcie {
status = "disabled";
};
&clk_usb {
status = "disabled";
};
&clk_vi {
status = "disabled";
};
&clk_vp {
status = "disabled";
};
&clk_vo {
status = "disabled";
};
&clk_npu {
status = "disabled";
};
&clk_d2d {
status = "disabled";
};
&vidmem {
status = "okay";
memory-region = <&framebuffer>;
};

View File

@@ -1682,3 +1682,60 @@
&usb2_0 {
status = "disabled";
};
&mipi0_csi0 {
status = "disabled";
};
&mipi0_csi1 {
//combination 4lane mode: host addr; aphy ctrl addr; bphy ctrl addr; mipi_ctrl addr
reg = < 0x00 0x06310000 0x0 0x10000
0x00 0x063a0020 0x0 0x4
0x00 0x063a0024 0x0 0x4
0x00 0x063a0028 0x0 0x4>;
phy_name = "CSI_4LANE"; //combination 4lane
};
//config dsi display: dpu_disp0->dup_enc0->dsi0->lcd_plane
&dpu_enc0 {
status = "disabled";
ports {
/* output */
port@1 {
reg = <1>;
enc0_out: endpoint {
remote-endpoint = <&dsi0_in>;
};
};
};
};
&dhost_0 {
status = "disabled";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
dsi0_in: endpoint {
remote-endpoint = <&enc0_out>;
};
};
port@1 {
reg = <1>;
dsi0_out: endpoint {
remote-endpoint = <&panel0_in>;
};
};
};
panel0@0 { //virtual panel0, not yet enabled
compatible = "jadard,jd9365da-h3";
reg = <0>;
port {
panel0_in: endpoint {
remote-endpoint = <&dsi0_out>;
};
};
};
};

View File

@@ -313,5 +313,593 @@
riscv,ndev = <400>;
cpu-id = <8>;
};
clocks1 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
osc_32k_die1: clock-osc-32k {
compatible = "fixed-clock";
clock-frequency = <32768>;
clock-output-names = "osc_32k_die1";
#clock-cells = <0>;
};
osc_24m_die1: clock-osc-24m {
compatible = "fixed-clock";
clock-frequency = <24000000>;
clock-output-names = "osc_24m_die1";
#clock-cells = <0>;
};
aon_110m_die1: clock-osc-110m {
compatible = "fixed-clock";
clock-frequency = <110000000>;
clock-output-names = "aon_110m_die1";
#clock-cells = <0>;
};
rc_24m_die1: clock-rc-24m {
compatible = "fixed-clock";
clock-frequency = <24000000>;
clock-output-names = "rc_24m_die1";
#clock-cells = <0>;
};
apb_clk_die1: apb-clk-clock {
compatible = "fixed-clock";
clock-frequency = <62500000>;
clock-output-names = "apb_clk_die1";
#clock-cells = <0>;
};
};
clk_die1: clock-controller@10 {
compatible = "zhihe,a210-clk-die1";
reg = <0x20 0x00260000 0x0 0x1000>,<0x20 0x00250000 0x0 0x1000>,
<0x20 0x10141600 0x0 0x100>,<0x20 0x10141400 0x0 0x100>,
<0x20 0x04810000 0x0 0x1000>,<0x20 0x05810000 0x0 0x1000>,
<0x20 0x04900000 0x0 0x1000>,<0x20 0x20250000 0x0 0x1000>,
<0x20 0x10140000 0x0 0xE00>;
reg-names = "PLL_WRAP","TOP_CRG","CPU_SS_CLK_SYSREG","CPU_SS_CPU_PLL",
"DDR0_SYSREG","DDR1_SYSREG","SLC_DUAL_SYSREG","TOP_CRG_T","CPU_SS_CCU";
#clock-cells = <1>;
clocks = <&osc_32k_die1>, <&osc_24m_die1>, <&rc_24m_die1>;
clock-names = "osc_32k", "osc_24m", "rc_24m";
assigned-clocks = <&clk_die1 AUDIO0_PLL_FOUTVCO>, <&clk_die1 AUDIO1_PLL_FOUTVCO>,
<&clk_die1 VIDEO_PLL_FOUTVCO>, <&clk_die1 GMAC_PLL_FOUTVCO>,
<&clk_die1 DVFS_PLL_FOUTVCO>, <&clk_die1 DPU0_PLL_FOUTVCO>,
<&clk_die1 DPU1_PLL_FOUTVCO>, <&clk_die1 DPU2_PLL_FOUTVCO>,
<&clk_die1 TOP_CFG_ACLK_DIV>, <&clk_die1 TOP_PCLK_DIV>,
<&clk_die1 SW_AMUX_660_CLK_EN>, <&clk_die1 SW_IOMMU_PTW_330_ACLK_EN>,
<&clk_die1 SW_NOC_CCLK_EN>, <&clk_die1 TOP_CPUSYS_BUS_CLK_DIV>,
<&clk_die1 TOP_CPUSYS_PIC_CLK_DIV>;
assigned-clock-rates = <2359296000>, <2528870400>, /* audio0_pll_foutvco,audio1_pll_foutvco */
<2640000000>, <3000000000>, /* video_pll_foutvco,gmac_pll_foutvco */
<1920000000>, <2376000000>, /* dvfs_pll_foutvco,dpu0_pll_foutvco */
<2376000000>, <2376000000>, /* dpu1_pll_foutvco,dpu2_pll_foutvco */
<330000000>, <165000000>, /* top_cfg_aclk,top_pclk */
<660000000>, <330000000>, /* top_amux_clk,iommu_ptw_aclk */
<950000000>, <1320000000>, /* noc_cclk,top_cpusys_bus_clk */
<1000000000>; /* top_cpusys_pic_clk */
status = "okay";
};
clk_gpu_die1: clock-controller@11 {
compatible = "zhihe,a210-gpu-clk-die1";
reg = <0x20 0x06D02200 0x0 0x200>, <0x20 0x06E06200 0x0 0x200>;
reg-names = "GPU_SS_PWRAP_CLK_EN","GPU_SS_TOP_CLK_EN";
#clock-cells = <1>;
assigned-clocks = <&clk_die1 TOP_GPU_CORE_CLK_DIV>;
assigned-clock-rates = <792000000>;
status = "okay";
};
clk_pcie_die1: clock-controller@12 {
compatible = "zhihe,a210-pcie-clk-die1";
reg = <0x20 0x0a000000 0x0 0x28>;
reg-names = "PCIE_CLK_EN";
#clock-cells = <1>;
assigned-clocks = <&clk_die1 TOP_PCIE_SCAN_REF_CLK0_DIV>, <&clk_die1 TOP_PCIE_SCAN_REF_CLK1_DIV>,
<&clk_die1 TOP_PCIE_AXI_M_ACLK_DIV>;
assigned-clock-rates = <396000000>, <1000000000>,
<786432000>;
status = "okay";
};
clk_usb_die1: clock-controller@13 {
compatible = "zhihe,a210-usb-clk-die1";
reg = <0x20 0x08000000 0x0 0x24>;
reg-names = "USB_CLK_EN";
#clock-cells = <1>;
assigned-clocks = <&clk_die1 TOP_USB_USB20_SCAN_REF_CLK_DIV>, <&clk_die1 TOP_USB_SCAN_REF_CLK3_DIV>,
<&clk_die1 TOP_USB_SCAN_REF_CLK2_DIV>, <&clk_die1 TOP_USB_SCAN_REF_CLK1_DIV>,
<&clk_die1 TOP_USB_SCAN_REF_CLK0_DIV>, <&clk_die1 TOP_USB_BUS_ACLK_DIV>,
<&clk_die1 TOP_USB_DP_AUX_CLK_DIV>;
assigned-clock-rates = <475200000>, <792000000>,
<600000000>, <500000000>,
<396000000>, <330000000>,
<16000000>;
status = "okay";
};
clk_vi_die1: clock-controller@14 {
compatible = "zhihe,a210-vi-clk-die1";
reg = <0x20 0x063a0200 0x0 0x200>;
reg-names = "VI_CLK";
#clock-cells = <1>;
status = "okay";
};
clk_vp_die1: clock-controller@15 {
compatible = "zhihe,a210-vp-clk-die1";
reg = <0x20 0x06b20200 0x0 0x200>;
reg-names = "VP_CLK";
#clock-cells = <1>;
assigned-clocks = <&clk_die1 TOP_VP_ACLK_DIV>, <&clk_die1 TOP_VP_VDEC_CCLK_DIV>,
<&clk_die1 TOP_VP_VENC_CCLK_DIV>, <&clk_die1 TOP_VP_G2D_CCLK_DIV>;
assigned-clock-rates = <880000000>, <786432000>,
<600000000>, <786432000>;
status = "okay";
};
clk_vo_die1: clock-controller@16 {
compatible = "zhihe,a210-vo-clk-die1";
reg = <0x20 0x06720048 0x0 0x4>, <0x20 0x06720200 0x0 0xc>;
reg-names = "VO_PATH_CTRL","VO_CLK";
#clock-cells = <1>;
assigned-clocks = <&clk_vo_die1 VO_DPUC_CLK_EN>, <&clk_vo_die1 VO_CH0_PIXCLK_EN>,
<&clk_vo_die1 VO_CH1_PIXCLK_EN>, <&clk_vo_die1 VO_CH2_PIXCLK_EN>,
<&clk_vo_die1 VO_DPU_ACLK_EN>, <&clk_vo_die1 VO_HDMI_PCLK_EN>,
<&clk_vo_die1 VO_DECOMP0_CLK_EN>, <&clk_vo_die1 VO_DECOMP1_CLK_EN>;
assigned-clock-rates = <880000000>, <594000000>,
<594000000>, <594000000>,
<880000000>, <165000000>,
<220000000>, <220000000>;
status = "okay";
};
clk_npu_die1: clock-controller@17 {
compatible = "zhihe,a210-npu-clk-die1";
reg = <0x20 0x07112210 0x0 0x4>,<0x20 0x07301050 0x0 0x4>;
reg-names = "NPU_CLK","NPU_TOP_CLK";
#clock-cells = <1>;
assigned-clocks = <&clk_die1 TOP_NPU_CCLK_DIV>, <&clk_die1 TOP_NPU_ACLK_DIV>;
assigned-clock-rates = <880000000>, <880000000>;
status = "okay";
};
clk_d2d_die1: clock-controller@18 {
compatible = "zhihe,a210-d2d-clk-die1";
reg = <0x20 0x09010000 0x0 0x4>;
reg-names = "D2D_CRG_REG";
#clock-cells = <1>;
assigned-clocks = <&clk_die1 TOP_D2D_ACLK_DIV>, <&clk_die1 TOP_D2D_REF_CLK_MUX>;
assigned-clock-rates = <950000000>, <100000000>;
status = "okay";
};
clk_peri_die1: clock-controller@19 {
compatible = "zhihe,a210-peri-clk-die1";
reg = <0x20 0x00300200 0x0 0x4>,
<0x20 0x02010200 0x0 0x8>,<0x20 0x08400200 0x0 0x8>,
<0x20 0x00540200 0x0 0x4>,<0x20 0x27420200 0x0 0x200>;
reg-names = "PERI0_SYSREG","PERI1_SYSREG","PERI2_SYSREG",
"PERI3_SYSREG","TEE_CRG";
#clock-cells = <1>;
assigned-clocks = <&clk_die1 TOP_PERI_TIMER_CLK_MUX>, <&clk_die1 TOP_PERI_I2S_2CH0_SRC_CLK_MUX>,
<&clk_die1 TOP_PERI_I2S_2CH1_SRC_CLK_MUX>, <&clk_die1 TOP_PERI_I2S_2CH2_SRC_CLK_MUX>,
<&clk_die1 TOP_PERI_I2S_8CH0_SRC_CLK_MUX>, <&clk_die1 TOP_PERI_SPI_SSI_CLK0_DIV>,
<&clk_die1 TOP_PERI_SPI_SSI_CLK1_DIV>, <&clk_die1 TOP_PERI_QSPI_SSI_CLK_MUX0>,
<&clk_die1 TOP_PERI_QSPI_SSI_CLK_MUX1>, <&clk_die1 TOP_PERI_PDM_MCLK_DIV>,
<&clk_die1 TOP_PERI_TDM_SRC_CLK_MUX>, <&clk_die1 TOP_PAD_SENSOR_VCLK0_DIV>,
<&clk_die1 TOP_PAD_SENSOR_VCLK1_DIV>, <&clk_die1 TOP_PERI_HIRES_CLK0_DIV>,
<&clk_die1 TOP_PERI_HIRES_CLK1_DIV>, <&clk_die1 TOP_TEE_CLK_DIV>,
<&clk_die1 TOP_PERI_EMMC_REF_CLK_DIV>, <&clk_die1 TOP_PERI_MST_ACLK0_DIV>,
<&clk_die1 TOP_PERI_MST_CLK1_DIV>;
assigned-clock-rates = <24000000>, <316108800>, /* peri0_timer_clk,peri1_i2s0_src_clk */
<316108800>, <316108800>, /* peri2_i2s1_src_clk,peri2_i2s2_src_clk */
<316108800>, <421478400>, /* peri2_i2s3_src_clk,peri1_spi_ssi_clk */
<421478400>, <421478400>, /* peri2_spi_ssi_clk,peri1_qspi_ssi_clk */
<421478400>, <31610880>, /* peri2_qspi_ssi_clk,peri1_pdm_mclk */
<316108800>, <74250000>, /* peri1_tdm_src_clk,top_pad_sensor_vclk0_div */
<148500000>, <80000000>, /* top_pad_sensor_vclk1,peri1_hires_clk */
<80000000>, <786432000>, /* peri2_hires_clk,emmc_ref_clk */
<330000000>, <440000000>, /* peri1_mst_aclk,peri3_mst_aclk */
<377142858>; /* tee_clk */
status = "okay";
};
clocks2 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
osc_32k_die2: clock-osc-32k {
compatible = "fixed-clock";
clock-frequency = <32768>;
clock-output-names = "osc_32k_die2";
#clock-cells = <0>;
};
osc_24m_die2: clock-osc-24m {
compatible = "fixed-clock";
clock-frequency = <24000000>;
clock-output-names = "osc_24m_die2";
#clock-cells = <0>;
};
aon_110m_die2: clock-osc-110m {
compatible = "fixed-clock";
clock-frequency = <110000000>;
clock-output-names = "aon_110m_die2";
#clock-cells = <0>;
};
rc_24m_die2: clock-rc-24m {
compatible = "fixed-clock";
clock-frequency = <24000000>;
clock-output-names = "rc_24m_die2";
#clock-cells = <0>;
};
apb_clk_die2: apb-clk-clock {
compatible = "fixed-clock";
clock-frequency = <62500000>;
clock-output-names = "apb_clk_die2";
#clock-cells = <0>;
};
};
clk_die2: clock-controller@20 {
compatible = "zhihe,a210-clk-die2";
reg = <0x40 0x00260000 0x0 0x1000>,<0x40 0x00250000 0x0 0x1000>,
<0x40 0x10141600 0x0 0x100>,<0x40 0x10141400 0x0 0x100>,
<0x40 0x04810000 0x0 0x1000>,<0x40 0x05810000 0x0 0x1000>,
<0x40 0x04900000 0x0 0x1000>,<0x40 0x20250000 0x0 0x1000>,
<0x40 0x10140000 0x0 0xE00>;
reg-names = "PLL_WRAP","TOP_CRG","CPU_SS_CLK_SYSREG","CPU_SS_CPU_PLL",
"DDR0_SYSREG","DDR1_SYSREG","SLC_DUAL_SYSREG","TOP_CRG_T","CPU_SS_CCU";
#clock-cells = <1>;
clocks = <&osc_32k_die2>, <&osc_24m_die2>, <&rc_24m_die2>;
clock-names = "osc_32k", "osc_24m", "rc_24m";
assigned-clocks = <&clk_die2 AUDIO0_PLL_FOUTVCO>, <&clk_die2 AUDIO1_PLL_FOUTVCO>,
<&clk_die2 VIDEO_PLL_FOUTVCO>, <&clk_die2 GMAC_PLL_FOUTVCO>,
<&clk_die2 DVFS_PLL_FOUTVCO>, <&clk_die2 DPU0_PLL_FOUTVCO>,
<&clk_die2 DPU1_PLL_FOUTVCO>, <&clk_die2 DPU2_PLL_FOUTVCO>,
<&clk_die2 TOP_CFG_ACLK_DIV>, <&clk_die2 TOP_PCLK_DIV>,
<&clk_die2 SW_AMUX_660_CLK_EN>, <&clk_die2 SW_IOMMU_PTW_330_ACLK_EN>,
<&clk_die2 SW_NOC_CCLK_EN>, <&clk_die2 TOP_CPUSYS_BUS_CLK_DIV>,
<&clk_die2 TOP_CPUSYS_PIC_CLK_DIV>;
assigned-clock-rates = <2359296000>, <2528870400>, /* audio0_pll_foutvco,audio1_pll_foutvco */
<2640000000>, <3000000000>, /* video_pll_foutvco,gmac_pll_foutvco */
<1920000000>, <2376000000>, /* dvfs_pll_foutvco,dpu0_pll_foutvco */
<2376000000>, <2376000000>, /* dpu1_pll_foutvco,dpu2_pll_foutvco */
<330000000>, <165000000>, /* top_cfg_aclk,top_pclk */
<660000000>, <330000000>, /* top_amux_clk,iommu_ptw_aclk */
<950000000>, <1320000000>, /* noc_cclk,top_cpusys_bus_clk */
<1000000000>; /* top_cpusys_pic_clk */
status = "okay";
};
clk_gpu_die2: clock-controller@21 {
compatible = "zhihe,a210-gpu-clk-die2";
reg = <0x40 0x06D02200 0x0 0x200>, <0x40 0x06E06200 0x0 0x200>;
reg-names = "GPU_SS_PWRAP_CLK_EN","GPU_SS_TOP_CLK_EN";
#clock-cells = <1>;
assigned-clocks = <&clk_die2 TOP_GPU_CORE_CLK_DIV>;
assigned-clock-rates = <792000000>;
status = "okay";
};
clk_pcie_die2: clock-controller@22 {
compatible = "zhihe,a210-pcie-clk-die2";
reg = <0x40 0x0a000000 0x0 0x28>;
reg-names = "PCIE_CLK_EN";
#clock-cells = <1>;
assigned-clocks = <&clk_die2 TOP_PCIE_SCAN_REF_CLK0_DIV>, <&clk_die2 TOP_PCIE_SCAN_REF_CLK1_DIV>,
<&clk_die2 TOP_PCIE_AXI_M_ACLK_DIV>;
assigned-clock-rates = <396000000>, <1000000000>,
<786432000>;
status = "okay";
};
clk_usb_die2: clock-controller@23 {
compatible = "zhihe,a210-usb-clk-die2";
reg = <0x40 0x08000000 0x0 0x24>;
reg-names = "USB_CLK_EN";
#clock-cells = <1>;
assigned-clocks = <&clk_die2 TOP_USB_USB20_SCAN_REF_CLK_DIV>, <&clk_die2 TOP_USB_SCAN_REF_CLK3_DIV>,
<&clk_die2 TOP_USB_SCAN_REF_CLK2_DIV>, <&clk_die2 TOP_USB_SCAN_REF_CLK1_DIV>,
<&clk_die2 TOP_USB_SCAN_REF_CLK0_DIV>, <&clk_die2 TOP_USB_BUS_ACLK_DIV>,
<&clk_die2 TOP_USB_DP_AUX_CLK_DIV>;
assigned-clock-rates = <475200000>, <792000000>,
<600000000>, <500000000>,
<396000000>, <330000000>,
<16000000>;
status = "okay";
};
clk_vi_die2: clock-controller@24 {
compatible = "zhihe,a210-vi-clk-die2";
reg = <0x40 0x063a0200 0x0 0x200>;
reg-names = "VI_CLK";
#clock-cells = <1>;
status = "okay";
};
clk_vp_die2: clock-controller@25 {
compatible = "zhihe,a210-vp-clk-die2";
reg = <0x40 0x06b20200 0x0 0x200>;
reg-names = "VP_CLK";
#clock-cells = <1>;
assigned-clocks = <&clk_die2 TOP_VP_ACLK_DIV>, <&clk_die2 TOP_VP_VDEC_CCLK_DIV>,
<&clk_die2 TOP_VP_VENC_CCLK_DIV>, <&clk_die2 TOP_VP_G2D_CCLK_DIV>;
assigned-clock-rates = <880000000>, <786432000>,
<600000000>, <786432000>;
status = "okay";
};
clk_vo_die2: clock-controller@26 {
compatible = "zhihe,a210-vo-clk-die2";
reg = <0x40 0x06720048 0x0 0x4>, <0x40 0x06720200 0x0 0xc>;
reg-names = "VO_PATH_CTRL","VO_CLK";
#clock-cells = <1>;
assigned-clocks = <&clk_vo_die2 VO_DPUC_CLK_EN>, <&clk_vo_die2 VO_CH0_PIXCLK_EN>,
<&clk_vo_die2 VO_CH1_PIXCLK_EN>, <&clk_vo_die2 VO_CH2_PIXCLK_EN>,
<&clk_vo_die2 VO_DPU_ACLK_EN>, <&clk_vo_die2 VO_HDMI_PCLK_EN>,
<&clk_vo_die2 VO_DECOMP0_CLK_EN>, <&clk_vo_die2 VO_DECOMP1_CLK_EN>;
assigned-clock-rates = <880000000>, <594000000>,
<594000000>, <594000000>,
<880000000>, <165000000>,
<220000000>, <220000000>;
status = "okay";
};
clk_npu_die2: clock-controller@27 {
compatible = "zhihe,a210-npu-clk-die2";
reg = <0x40 0x07112210 0x0 0x4>,<0x40 0x07301050 0x0 0x4>;
reg-names = "NPU_CLK","NPU_TOP_CLK";
#clock-cells = <1>;
assigned-clocks = <&clk_die2 TOP_NPU_CCLK_DIV>, <&clk_die2 TOP_NPU_ACLK_DIV>;
assigned-clock-rates = <880000000>, <880000000>;
status = "okay";
};
clk_d2d_die2: clock-controller@28 {
compatible = "zhihe,a210-d2d-clk-die2";
reg = <0x40 0x09010000 0x0 0x4>;
reg-names = "D2D_CRG_REG";
#clock-cells = <1>;
assigned-clocks = <&clk_die2 TOP_D2D_ACLK_DIV>, <&clk_die2 TOP_D2D_REF_CLK_MUX>;
assigned-clock-rates = <950000000>, <100000000>;
status = "okay";
};
clk_peri_die2: clock-controller@29 {
compatible = "zhihe,a210-peri-clk-die2";
reg = <0x40 0x00300200 0x0 0x4>,
<0x40 0x02010200 0x0 0x8>,<0x40 0x08400200 0x0 0x8>,
<0x40 0x00540200 0x0 0x4>,<0x40 0x27420200 0x0 0x200>;
reg-names = "PERI0_SYSREG","PERI1_SYSREG","PERI2_SYSREG",
"PERI3_SYSREG","TEE_CRG";
#clock-cells = <1>;
assigned-clocks = <&clk_die2 TOP_PERI_TIMER_CLK_MUX>, <&clk_die2 TOP_PERI_I2S_2CH0_SRC_CLK_MUX>,
<&clk_die2 TOP_PERI_I2S_2CH1_SRC_CLK_MUX>, <&clk_die2 TOP_PERI_I2S_2CH2_SRC_CLK_MUX>,
<&clk_die2 TOP_PERI_I2S_8CH0_SRC_CLK_MUX>, <&clk_die2 TOP_PERI_SPI_SSI_CLK0_DIV>,
<&clk_die2 TOP_PERI_SPI_SSI_CLK1_DIV>, <&clk_die2 TOP_PERI_QSPI_SSI_CLK_MUX0>,
<&clk_die2 TOP_PERI_QSPI_SSI_CLK_MUX1>, <&clk_die2 TOP_PERI_PDM_MCLK_DIV>,
<&clk_die2 TOP_PERI_TDM_SRC_CLK_MUX>, <&clk_die2 TOP_PAD_SENSOR_VCLK0_DIV>,
<&clk_die2 TOP_PAD_SENSOR_VCLK1_DIV>, <&clk_die2 TOP_PERI_HIRES_CLK0_DIV>,
<&clk_die2 TOP_PERI_HIRES_CLK1_DIV>, <&clk_die2 TOP_TEE_CLK_DIV>,
<&clk_die2 TOP_PERI_EMMC_REF_CLK_DIV>, <&clk_die2 TOP_PERI_MST_ACLK0_DIV>,
<&clk_die2 TOP_PERI_MST_CLK1_DIV>;
assigned-clock-rates = <24000000>, <316108800>, /* peri0_timer_clk,peri1_i2s0_src_clk */
<316108800>, <316108800>, /* peri2_i2s1_src_clk,peri2_i2s2_src_clk */
<316108800>, <421478400>, /* peri2_i2s3_src_clk,peri1_spi_ssi_clk */
<421478400>, <421478400>, /* peri2_spi_ssi_clk,peri1_qspi_ssi_clk */
<421478400>, <31610880>, /* peri2_qspi_ssi_clk,peri1_pdm_mclk */
<316108800>, <74250000>, /* peri1_tdm_src_clk,top_pad_sensor_vclk0_div */
<148500000>, <80000000>, /* top_pad_sensor_vclk1,peri1_hires_clk */
<80000000>, <786432000>, /* peri2_hires_clk,emmc_ref_clk */
<330000000>, <440000000>, /* peri1_mst_aclk,peri3_mst_aclk */
<377142858>; /* tee_clk */
status = "okay";
};
clocks3 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
osc_32k_die3: clock-osc-32k {
compatible = "fixed-clock";
clock-frequency = <32768>;
clock-output-names = "osc_32k_die3";
#clock-cells = <0>;
};
osc_24m_die3: clock-osc-24m {
compatible = "fixed-clock";
clock-frequency = <24000000>;
clock-output-names = "osc_24m_die3";
#clock-cells = <0>;
};
aon_110m_die3: clock-osc-110m {
compatible = "fixed-clock";
clock-frequency = <110000000>;
clock-output-names = "aon_110m_die3";
#clock-cells = <0>;
};
rc_24m_die3: clock-rc-24m {
compatible = "fixed-clock";
clock-frequency = <24000000>;
clock-output-names = "rc_24m_die3";
#clock-cells = <0>;
};
apb_clk_die3: apb-clk-clock {
compatible = "fixed-clock";
clock-frequency = <62500000>;
clock-output-names = "apb_clk_die3";
#clock-cells = <0>;
};
};
clk_die3: clock-controller@30 {
compatible = "zhihe,a210-clk-die3";
reg = <0x60 0x00260000 0x0 0x1000>,<0x60 0x00250000 0x0 0x1000>,
<0x60 0x10141600 0x0 0x100>,<0x60 0x10141400 0x0 0x100>,
<0x60 0x04810000 0x0 0x1000>,<0x60 0x05810000 0x0 0x1000>,
<0x60 0x04900000 0x0 0x1000>,<0x60 0x20250000 0x0 0x1000>,
<0x60 0x10140000 0x0 0xE00>;
reg-names = "PLL_WRAP","TOP_CRG","CPU_SS_CLK_SYSREG","CPU_SS_CPU_PLL",
"DDR0_SYSREG","DDR1_SYSREG","SLC_DUAL_SYSREG","TOP_CRG_T","CPU_SS_CCU";
#clock-cells = <1>;
clocks = <&osc_32k_die3>, <&osc_24m_die3>, <&rc_24m_die3>;
clock-names = "osc_32k", "osc_24m", "rc_24m";
assigned-clocks = <&clk_die3 AUDIO0_PLL_FOUTVCO>, <&clk_die3 AUDIO1_PLL_FOUTVCO>,
<&clk_die3 VIDEO_PLL_FOUTVCO>, <&clk_die3 GMAC_PLL_FOUTVCO>,
<&clk_die3 DVFS_PLL_FOUTVCO>, <&clk_die3 DPU0_PLL_FOUTVCO>,
<&clk_die3 DPU1_PLL_FOUTVCO>, <&clk_die3 DPU2_PLL_FOUTVCO>,
<&clk_die3 TOP_CFG_ACLK_DIV>, <&clk_die3 TOP_PCLK_DIV>,
<&clk_die3 SW_AMUX_660_CLK_EN>, <&clk_die3 SW_IOMMU_PTW_330_ACLK_EN>,
<&clk_die3 SW_NOC_CCLK_EN>, <&clk_die3 TOP_CPUSYS_BUS_CLK_DIV>,
<&clk_die3 TOP_CPUSYS_PIC_CLK_DIV>;
assigned-clock-rates = <2359296000>, <2528870400>, /* audio0_pll_foutvco,audio1_pll_foutvco */
<2640000000>, <3000000000>, /* video_pll_foutvco,gmac_pll_foutvco */
<1920000000>, <2376000000>, /* dvfs_pll_foutvco,dpu0_pll_foutvco */
<2376000000>, <2376000000>, /* dpu1_pll_foutvco,dpu2_pll_foutvco */
<330000000>, <165000000>, /* top_cfg_aclk,top_pclk */
<660000000>, <330000000>, /* top_amux_clk,iommu_ptw_aclk */
<950000000>, <1320000000>, /* noc_cclk,top_cpusys_bus_clk */
<1000000000>; /* top_cpusys_pic_clk */
status = "okay";
};
clk_gpu_die3: clock-controller@31 {
compatible = "zhihe,a210-gpu-clk-die3";
reg = <0x60 0x06D02200 0x0 0x200>, <0x60 0x06E06200 0x0 0x200>;
reg-names = "GPU_SS_PWRAP_CLK_EN","GPU_SS_TOP_CLK_EN";
#clock-cells = <1>;
assigned-clocks = <&clk_die3 TOP_GPU_CORE_CLK_DIV>;
assigned-clock-rates = <792000000>;
status = "okay";
};
clk_pcie_die3: clock-controller@32 {
compatible = "zhihe,a210-pcie-clk-die3";
reg = <0x60 0x0a000000 0x0 0x28>;
reg-names = "PCIE_CLK_EN";
#clock-cells = <1>;
assigned-clocks = <&clk_die3 TOP_PCIE_SCAN_REF_CLK0_DIV>, <&clk_die3 TOP_PCIE_SCAN_REF_CLK1_DIV>,
<&clk_die3 TOP_PCIE_AXI_M_ACLK_DIV>;
assigned-clock-rates = <396000000>, <1000000000>,
<786432000>;
status = "okay";
};
clk_usb_die3: clock-controller@33 {
compatible = "zhihe,a210-usb-clk-die3";
reg = <0x60 0x08000000 0x0 0x24>;
reg-names = "USB_CLK_EN";
#clock-cells = <1>;
assigned-clocks = <&clk_die3 TOP_USB_USB20_SCAN_REF_CLK_DIV>, <&clk_die3 TOP_USB_SCAN_REF_CLK3_DIV>,
<&clk_die3 TOP_USB_SCAN_REF_CLK2_DIV>, <&clk_die3 TOP_USB_SCAN_REF_CLK1_DIV>,
<&clk_die3 TOP_USB_SCAN_REF_CLK0_DIV>, <&clk_die3 TOP_USB_BUS_ACLK_DIV>,
<&clk_die3 TOP_USB_DP_AUX_CLK_DIV>;
assigned-clock-rates = <475200000>, <792000000>,
<600000000>, <500000000>,
<396000000>, <330000000>,
<16000000>;
status = "okay";
};
clk_vi_die3: clock-controller@34 {
compatible = "zhihe,a210-vi-clk-die3";
reg = <0x60 0x063a0200 0x0 0x200>;
reg-names = "VI_CLK";
#clock-cells = <1>;
status = "okay";
};
clk_vp_die3: clock-controller@35 {
compatible = "zhihe,a210-vp-clk-die3";
reg = <0x60 0x06b20200 0x0 0x200>;
reg-names = "VP_CLK";
#clock-cells = <1>;
assigned-clocks = <&clk_die3 TOP_VP_ACLK_DIV>, <&clk_die3 TOP_VP_VDEC_CCLK_DIV>,
<&clk_die3 TOP_VP_VENC_CCLK_DIV>, <&clk_die3 TOP_VP_G2D_CCLK_DIV>;
assigned-clock-rates = <880000000>, <786432000>,
<600000000>, <786432000>;
status = "okay";
};
clk_vo_die3: clock-controller@36 {
compatible = "zhihe,a210-vo-clk-die3";
reg = <0x60 0x06720048 0x0 0x4>, <0x60 0x06720200 0x0 0xc>;
reg-names = "VO_PATH_CTRL","VO_CLK";
#clock-cells = <1>;
assigned-clocks = <&clk_vo_die3 VO_DPUC_CLK_EN>, <&clk_vo_die3 VO_CH0_PIXCLK_EN>,
<&clk_vo_die3 VO_CH1_PIXCLK_EN>, <&clk_vo_die3 VO_CH2_PIXCLK_EN>,
<&clk_vo_die3 VO_DPU_ACLK_EN>, <&clk_vo_die3 VO_HDMI_PCLK_EN>,
<&clk_vo_die3 VO_DECOMP0_CLK_EN>, <&clk_vo_die3 VO_DECOMP1_CLK_EN>;
assigned-clock-rates = <880000000>, <594000000>,
<594000000>, <594000000>,
<880000000>, <165000000>,
<220000000>, <220000000>;
status = "okay";
};
clk_npu_die3: clock-controller@37 {
compatible = "zhihe,a210-npu-clk-die3";
reg = <0x60 0x07112210 0x0 0x4>,<0x60 0x07301050 0x0 0x4>;
reg-names = "NPU_CLK","NPU_TOP_CLK";
#clock-cells = <1>;
assigned-clocks = <&clk_die3 TOP_NPU_CCLK_DIV>, <&clk_die3 TOP_NPU_ACLK_DIV>;
assigned-clock-rates = <880000000>, <880000000>;
status = "okay";
};
clk_d2d_die3: clock-controller@38 {
compatible = "zhihe,a210-d2d-clk-die3";
reg = <0x60 0x09010000 0x0 0x4>;
reg-names = "D2D_CRG_REG";
#clock-cells = <1>;
assigned-clocks = <&clk_die3 TOP_D2D_ACLK_DIV>, <&clk_die3 TOP_D2D_REF_CLK_MUX>;
assigned-clock-rates = <950000000>, <100000000>;
status = "okay";
};
clk_peri_die3: clock-controller@39 {
compatible = "zhihe,a210-peri-clk-die3";
reg = <0x60 0x00300200 0x0 0x4>,
<0x60 0x02010200 0x0 0x8>,<0x60 0x08400200 0x0 0x8>,
<0x60 0x00540200 0x0 0x4>,<0x60 0x27420200 0x0 0x200>;
reg-names = "PERI0_SYSREG","PERI1_SYSREG","PERI2_SYSREG",
"PERI3_SYSREG","TEE_CRG";
#clock-cells = <1>;
assigned-clocks = <&clk_die3 TOP_PERI_TIMER_CLK_MUX>, <&clk_die3 TOP_PERI_I2S_2CH0_SRC_CLK_MUX>,
<&clk_die3 TOP_PERI_I2S_2CH1_SRC_CLK_MUX>, <&clk_die3 TOP_PERI_I2S_2CH2_SRC_CLK_MUX>,
<&clk_die3 TOP_PERI_I2S_8CH0_SRC_CLK_MUX>, <&clk_die3 TOP_PERI_SPI_SSI_CLK0_DIV>,
<&clk_die3 TOP_PERI_SPI_SSI_CLK1_DIV>, <&clk_die3 TOP_PERI_QSPI_SSI_CLK_MUX0>,
<&clk_die3 TOP_PERI_QSPI_SSI_CLK_MUX1>, <&clk_die3 TOP_PERI_PDM_MCLK_DIV>,
<&clk_die3 TOP_PERI_TDM_SRC_CLK_MUX>, <&clk_die3 TOP_PAD_SENSOR_VCLK0_DIV>,
<&clk_die3 TOP_PAD_SENSOR_VCLK1_DIV>, <&clk_die3 TOP_PERI_HIRES_CLK0_DIV>,
<&clk_die3 TOP_PERI_HIRES_CLK1_DIV>, <&clk_die3 TOP_TEE_CLK_DIV>,
<&clk_die3 TOP_PERI_EMMC_REF_CLK_DIV>, <&clk_die3 TOP_PERI_MST_ACLK0_DIV>,
<&clk_die3 TOP_PERI_MST_CLK1_DIV>;
assigned-clock-rates = <24000000>, <316108800>, /* peri0_timer_clk,peri1_i2s0_src_clk */
<316108800>, <316108800>, /* peri2_i2s1_src_clk,peri2_i2s2_src_clk */
<316108800>, <421478400>, /* peri2_i2s3_src_clk,peri1_spi_ssi_clk */
<421478400>, <421478400>, /* peri2_spi_ssi_clk,peri1_qspi_ssi_clk */
<421478400>, <31610880>, /* peri2_qspi_ssi_clk,peri1_pdm_mclk */
<316108800>, <74250000>, /* peri1_tdm_src_clk,top_pad_sensor_vclk0_div */
<148500000>, <80000000>, /* top_pad_sensor_vclk1,peri1_hires_clk */
<80000000>, <786432000>, /* peri2_hires_clk,emmc_ref_clk */
<330000000>, <440000000>, /* peri1_mst_aclk,peri3_mst_aclk */
<377142858>; /* tee_clk */
status = "okay";
};
};
};

View File

@@ -406,7 +406,7 @@
};
clk: clock-controller@0 {
compatible = "zhihe,p100-clk";
compatible = "zhihe,a210-clk";
reg = <0x00 0x00260000 0x0 0x1000>,<0x00 0x00250000 0x0 0x1000>,
<0x00 0x10141600 0x0 0x100>,<0x00 0x10141400 0x0 0x100>,
<0x00 0x04810000 0x0 0x1000>,<0x00 0x05810000 0x0 0x1000>,
@@ -417,76 +417,65 @@
#clock-cells = <1>;
clocks = <&osc_32k>, <&osc_24m>, <&rc_24m>;
clock-names = "osc_32k", "osc_24m", "rc_24m";
/* pll */
audio0_pll_foutvco_frequency = <2359296000>;
audio1_pll_foutvco_frequency = <2528870400>;
video_pll_foutvco_frequency = <2640000000>;
gmac_pll_foutvco_frequency = <3000000000>;
dvfs_pll_foutvco_frequency = <1920000000>;
dpu0_pll_foutvco_frequency = <2376000000>;
dpu1_pll_foutvco_frequency = <2376000000>;
dpu2_pll_foutvco_frequency = <2376000000>;
tee_pll_foutvco_frequency = <2400000000>;
/* top */
top_cfg_aclk_frequency = <330000000>;
top_pclk_frequency = <165000000>;
top_amux_clk_frequency = <660000000>;
iommu_ptw_aclk_frequency = <330000000>;
noc_cclk_frequency = <950000000>;
top_cpusys_bus_clk_frequency = <1320000000>;
top_cpusys_pic_clk_frequency = <1000000000>;
assigned-clocks = <&clk AUDIO0_PLL_FOUTVCO>, <&clk AUDIO1_PLL_FOUTVCO>,
<&clk VIDEO_PLL_FOUTVCO>, <&clk GMAC_PLL_FOUTVCO>,
<&clk DVFS_PLL_FOUTVCO>, <&clk DPU0_PLL_FOUTVCO>,
<&clk DPU1_PLL_FOUTVCO>, <&clk DPU2_PLL_FOUTVCO>,
<&clk TOP_CFG_ACLK_DIV>, <&clk TOP_PCLK_DIV>,
<&clk SW_AMUX_660_CLK_EN>, <&clk SW_IOMMU_PTW_330_ACLK_EN>,
<&clk SW_NOC_CCLK_EN>, <&clk TOP_CPUSYS_BUS_CLK_DIV>,
<&clk TOP_CPUSYS_PIC_CLK_DIV>;
assigned-clock-rates = <2359296000>, <2528870400>, /* audio0_pll_foutvco,audio1_pll_foutvco */
<2640000000>, <3000000000>, /* video_pll_foutvco,gmac_pll_foutvco */
<1920000000>, <2376000000>, /* dvfs_pll_foutvco,dpu0_pll_foutvco */
<2376000000>, <2376000000>, /* dpu1_pll_foutvco,dpu2_pll_foutvco */
<330000000>, <165000000>, /* top_cfg_aclk,top_pclk */
<660000000>, <330000000>, /* top_amux_clk,iommu_ptw_aclk */
<950000000>, <1320000000>, /* noc_cclk,top_cpusys_bus_clk */
<1000000000>; /* top_cpusys_pic_clk */
status = "okay";
};
clk_gpu: clock-controller@1 {
compatible = "zhihe,p100-gpu-clk";
compatible = "zhihe,a210-gpu-clk";
reg = <0x00 0x06D02200 0x0 0x200>, <0x00 0x06E06200 0x0 0x200>;
reg-names = "GPU_SS_PWRAP_CLK_EN","GPU_SS_TOP_CLK_EN";
#clock-cells = <1>;
clocks = <&clk TOP_GPU_CORE_CLK_DIV>;
clock-names = "top_gpu_core_clk";
top_gpu_core_clk_frequency = <792000000>;
assigned-clocks = <&clk TOP_GPU_CORE_CLK_DIV>;
assigned-clock-rates = <792000000>;
status = "okay";
};
clk_pcie: clock-controller@2 {
compatible = "zhihe,p100-pcie-clk";
compatible = "zhihe,a210-pcie-clk";
reg = <0x00 0x0a000000 0x0 0x28>;
reg-names = "PCIE_CLK_EN";
#clock-cells = <1>;
clocks = <&clk TOP_PCIE_SCAN_REF_CLK0_DIV>, <&clk TOP_PCIE_SCAN_REF_CLK1_DIV>,
assigned-clocks = <&clk TOP_PCIE_SCAN_REF_CLK0_DIV>, <&clk TOP_PCIE_SCAN_REF_CLK1_DIV>,
<&clk TOP_PCIE_AXI_M_ACLK_DIV>;
clock-names = "scan_ref_clk0", "scan_ref_clk1", "pcie_ss_axi_m_aclk";
scan_ref_clk0_frequency = <396000000>;
scan_ref_clk1_frequency = <1000000000>;
pcie_ss_axi_m_aclk_frequency = <786432000>;
assigned-clock-rates = <396000000>, <1000000000>,
<786432000>;
status = "okay";
};
clk_usb: clock-controller@3 {
compatible = "zhihe,p100-usb-clk";
compatible = "zhihe,a210-usb-clk";
reg = <0x00 0x08000000 0x0 0x24>;
reg-names = "USB_CLK_EN";
#clock-cells = <1>;
clocks = <&clk TOP_USB_USB20_SCAN_REF_CLK_DIV>, <&clk TOP_USB_SCAN_REF_CLK3_DIV>,
assigned-clocks = <&clk TOP_USB_USB20_SCAN_REF_CLK_DIV>, <&clk TOP_USB_SCAN_REF_CLK3_DIV>,
<&clk TOP_USB_SCAN_REF_CLK2_DIV>, <&clk TOP_USB_SCAN_REF_CLK1_DIV>,
<&clk TOP_USB_SCAN_REF_CLK0_DIV>, <&clk TOP_USB_BUS_ACLK_DIV>,
<&clk TOP_USB_DP_AUX_CLK_DIV>;
clock-names = "clkgen_usb20phy_scan_ref_clk", "clkgen_c10phy_scan_ref_clk3", "clkgen_c10phy_scan_ref_clk2",
"clkgen_c10phy_scan_ref_clk1", "clkgen_c10phy_scan_ref_clk0", "clkgen_usb_ss_bus_clk",
"clkgen_usb_ss_aux_clk";
clkgen_usb20phy_scan_ref_clk_frequency = <475200000>;
clkgen_c10phy_scan_ref_clk3_frequency = <792000000>;
clkgen_c10phy_scan_ref_clk2_frequency = <600000000>;
clkgen_c10phy_scan_ref_clk1_frequency = <500000000>;
clkgen_c10phy_scan_ref_clk0_frequency = <396000000>;
clkgen_usb_ss_bus_clk_frequency = <330000000>;
clkgen_usb_ss_aux_clk_frequency = <16000000>;
assigned-clock-rates = <475200000>, <792000000>,
<600000000>, <500000000>,
<396000000>, <330000000>,
<16000000>;
status = "okay";
};
clk_vi: clock-controller@4 {
compatible = "zhihe,p100-vi-clk";
compatible = "zhihe,a210-vi-clk";
reg = <0x00 0x063a0200 0x0 0x200>;
reg-names = "VI_CLK";
#clock-cells = <1>;
@@ -494,69 +483,62 @@
};
clk_vp: clock-controller@5 {
compatible = "zhihe,p100-vp-clk";
compatible = "zhihe,a210-vp-clk";
reg = <0x00 0x06b20200 0x0 0x200>;
reg-names = "VP_CLK";
#clock-cells = <1>;
clocks = <&clk TOP_VP_ACLK_DIV>, <&clk TOP_VP_VDEC_CCLK_DIV>,
assigned-clocks = <&clk TOP_VP_ACLK_DIV>, <&clk TOP_VP_VDEC_CCLK_DIV>,
<&clk TOP_VP_VENC_CCLK_DIV>, <&clk TOP_VP_G2D_CCLK_DIV>;
clock-names = "vp_aclk", "vdec_cclk", "venc_cclk", "g2d_cclk";
vp_aclk_frequency = <880000000>;
vdec_cclk_frequency = <786432000>;
venc_cclk_frequency = <600000000>;
g2d_cclk_frequency = <786432000>;
assigned-clock-rates = <880000000>, <786432000>,
<600000000>, <786432000>;
status = "okay";
};
clk_vo: clock-controller@6 {
compatible = "zhihe,p100-vo-clk";
compatible = "zhihe,a210-vo-clk";
reg = <0x00 0x06720048 0x0 0x4>, <0x00 0x06720200 0x0 0xc>;
reg-names = "VO_PATH_CTRL","VO_CLK";
#clock-cells = <1>;
vo_dpuc_clk_frequency = <880000000>;
dpu0_pixclk_frequency = <594000000>;
dpu1_pixclk_frequency = <594000000>;
dpu2_pixclk_frequency = <594000000>;
vo_dpu_aclk_frequency = <880000000>;
vo_hdmi_pclk_frequency = <165000000>;
vo_decomp0_clk_frequency = <220000000>;
vo_decomp1_clk_frequency = <220000000>;
assigned-clocks = <&clk_vo VO_DPUC_CLK_EN>, <&clk_vo VO_CH0_PIXCLK_EN>,
<&clk_vo VO_CH1_PIXCLK_EN>, <&clk_vo VO_CH2_PIXCLK_EN>,
<&clk_vo VO_DPU_ACLK_EN>, <&clk_vo VO_HDMI_PCLK_EN>,
<&clk_vo VO_DECOMP0_CLK_EN>, <&clk_vo VO_DECOMP1_CLK_EN>;
assigned-clock-rates = <880000000>, <594000000>,
<594000000>, <594000000>,
<880000000>, <165000000>,
<220000000>, <220000000>;
status = "okay";
};
clk_npu: clock-controller@7 {
compatible = "zhihe,p100-npu-clk";
compatible = "zhihe,a210-npu-clk";
reg = <0x00 0x07112210 0x0 0x4>,<0x00 0x07301050 0x0 0x4>;
reg-names = "NPU_CLK","NPU_TOP_CLK";
#clock-cells = <1>;
clocks = <&clk TOP_NPU_CCLK_DIV>, <&clk TOP_NPU_ACLK_DIV>;
clock-names = "npu_cclk", "npu_aclk";
npu_cclk_frequency = <880000000>;
npu_aclk_frequency = <880000000>;
assigned-clocks = <&clk TOP_NPU_CCLK_DIV>, <&clk TOP_NPU_ACLK_DIV>;
assigned-clock-rates = <880000000>, <880000000>;
status = "okay";
};
clk_d2d: clock-controller@8 {
compatible = "zhihe,p100-d2d-clk";
compatible = "zhihe,a210-d2d-clk";
reg = <0x00 0x09010000 0x0 0x4>;
reg-names = "D2D_CRG_REG";
#clock-cells = <1>;
clocks = <&clk TOP_D2D_ACLK_DIV>, <&clk TOP_D2D_REF_CLK_MUX>;
clock-names = "top_d2d_aclk", "d2d_phy_ref_clk";
top_d2d_aclk_frequency = <950000000>;
d2d_phy_ref_clk_frequency = <100000000>;
assigned-clocks = <&clk TOP_D2D_ACLK_DIV>, <&clk TOP_D2D_REF_CLK_MUX>;
assigned-clock-rates = <950000000>, <100000000>;
status = "okay";
};
clk_peri: clock-controller@9 {
compatible = "zhihe,p100-peri-clk";
compatible = "zhihe,a210-peri-clk";
reg = <0x00 0x00300200 0x0 0x4>,
<0x00 0x02010200 0x0 0x8>,<0x00 0x08400200 0x0 0x8>,
<0x00 0x00540200 0x0 0x4>,<0x00 0x27420200 0x0 0x200>;
reg-names = "PERI0_SYSREG","PERI1_SYSREG","PERI2_SYSREG",
"PERI3_SYSREG","TEE_CRG";
#clock-cells = <1>;
clocks = <&clk TOP_PERI_TIMER_CLK_MUX>, <&clk TOP_PERI_I2S_2CH0_SRC_CLK_MUX>,
assigned-clocks = <&clk TOP_PERI_TIMER_CLK_MUX>, <&clk TOP_PERI_I2S_2CH0_SRC_CLK_MUX>,
<&clk TOP_PERI_I2S_2CH1_SRC_CLK_MUX>, <&clk TOP_PERI_I2S_2CH2_SRC_CLK_MUX>,
<&clk TOP_PERI_I2S_8CH0_SRC_CLK_MUX>, <&clk TOP_PERI_SPI_SSI_CLK0_DIV>,
<&clk TOP_PERI_SPI_SSI_CLK1_DIV>, <&clk TOP_PERI_QSPI_SSI_CLK_MUX0>,
@@ -566,32 +548,16 @@
<&clk TOP_PERI_HIRES_CLK1_DIV>, <&clk TOP_TEE_CLK_DIV>,
<&clk TOP_PERI_EMMC_REF_CLK_DIV>, <&clk TOP_PERI_MST_ACLK0_DIV>,
<&clk TOP_PERI_MST_CLK1_DIV>;
clock-names = "peri0_timer_clk", "peri1_i2s0_src_clk", "peri2_i2s1_src_clk",
"peri2_i2s2_src_clk", "peri2_i2s3_src_clk", "peri1_spi_ssi_clk",
"peri2_spi_ssi_clk", "peri1_qspi_ssi_clk", "peri2_qspi_ssi_clk",
"peri1_pdm_mclk", "peri1_tdm_src_clk",
"top_pad_sensor_vclk0_div", "top_pad_sensor_vclk1_div", "peri1_hires_clk",
"peri2_hires_clk", "tee_clk", "emmc_ref_clk",
"peri1_mst_aclk", "peri3_mst_aclk";
peri0_timer_clk_frequency = <24000000>;
peri1_i2s0_src_clk_frequency = <316108800>;
peri2_i2s1_src_clk_frequency = <316108800>;
peri2_i2s2_src_clk_frequency = <316108800>;
peri2_i2s3_src_clk_frequency = <316108800>;
peri1_spi_ssi_clk_frequency = <421478400>;
peri2_spi_ssi_clk_frequency = <421478400>;
peri1_qspi_ssi_clk_frequency = <421478400>;
peri2_qspi_ssi_clk_frequency = <421478400>;
peri1_pdm_mclk_frequency = <31610880>;
peri1_tdm_src_clk_frequency = <316108800>;
top_pad_sensor_vclk0_div_frequency = <74250000>;
top_pad_sensor_vclk1_div_frequency = <148500000>;
peri1_hires_clk_frequency = <80000000>;
peri2_hires_clk_frequency = <80000000>;
emmc_ref_clk_frequency = <786432000>;
peri1_mst_aclk_frequency = <330000000>;
peri3_mst_aclk_frequency = <440000000>;
tee_clk_frequency = <377142858>;
assigned-clock-rates = <24000000>, <316108800>, /* peri0_timer_clk,peri1_i2s0_src_clk */
<316108800>, <316108800>, /* peri2_i2s1_src_clk,peri2_i2s2_src_clk */
<316108800>, <421478400>, /* peri2_i2s3_src_clk,peri1_spi_ssi_clk */
<421478400>, <421478400>, /* peri2_spi_ssi_clk,peri1_qspi_ssi_clk */
<421478400>, <31610880>, /* peri2_qspi_ssi_clk,peri1_pdm_mclk */
<316108800>, <74250000>, /* peri1_tdm_src_clk,top_pad_sensor_vclk0_div */
<148500000>, <80000000>, /* top_pad_sensor_vclk1,peri1_hires_clk */
<80000000>, <786432000>, /* peri2_hires_clk,emmc_ref_clk */
<330000000>, <440000000>, /* peri1_mst_aclk,peri3_mst_aclk */
<377142858>; /* tee_clk */
status = "okay";
};
@@ -951,7 +917,7 @@
};
tee_os_region: tee-os-region{
reg = <0x00 0x9D000000 0x00 0x1000000>;
reg = <0x00 0x88000000 0x00 0x2000000>;
permission = "no-access";
mode = "NAPOT";
};
@@ -986,22 +952,22 @@
device_pcie_mt_iopmp: pcie-mt-iopmp {
iopmp-name = "PCIE-IOPMP";
device-id = <IOPMP_DEV_PCIE_DFMU>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_pcie_0_iopmp: pcie-0-iopmp {
iopmp-name = "PCIE-IOPMP";
device-id = <IOPMP_DEV_PCIE_0>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_pcie_1_iopmp: pcie-1-iopmp {
iopmp-name = "PCIE-IOPMP";
device-id = <IOPMP_DEV_PCIE_1>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_sata_0_iopmp: sata-0-iopmp {
iopmp-name = "PCIE-IOPMP";
device-id = <IOPMP_DEV_SATA_0>;
iopmp-regions = <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_eip120i_iopmp: eip120i-iopmp {
iopmp-name = "PCIE-IOPMP";
@@ -1026,152 +992,152 @@
device_dmac_ap_iopmp: dmac-ap-iopmp {
iopmp-name = "PCIE-IOPMP";
device-id = <IOPMP_DEV_DMAC_AP>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_sd_iopmp: sd-iopmp {
iopmp-name = "PCIE-IOPMP";
device-id = <IOPMP_DEV_SD>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_emmc_iopmp: emmc-iopmp {
iopmp-name = "PCIE-IOPMP";
device-id = <IOPMP_DEV_EMMC>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_pcie_iommu_iopmp: pcie-iommu-iopmp {
iopmp-name = "PCIE-IOPMP";
device-id = <IOPMP_DEV_PCIE_IOMMU>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
/* VP iopmp*/
device_vp_mt_iopmp: vp-mt-iopmp {
iopmp-name = "VP-IOPMP";
device-id = <IOPMP_DEV_VP_DFMU>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_venc_iopmp: venc-iopmp {
iopmp-name = "VP-IOPMP";
device-id = <IOPMP_DEV_VENC>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_vdec_iopmp: vdec-iopmp {
iopmp-name = "VP-IOPMP";
device-id = <IOPMP_DEV_VDEC>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_g2d_iopmp: g2d-iopmp {
iopmp-name = "VP-IOPMP";
device-id = <IOPMP_DEV_G2D>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_vp_iommu_iopmp: vp-iommu-iopmp {
iopmp-name = "VP-IOPMP";
device-id = <IOPMP_DEV_VP_IOMMU>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
/* VI iopmp*/
device_vi_mt_iopmp: vi-mt-iopmp {
iopmp-name = "VI-IOPMP";
device-id = <IOPMP_DEV_VI_DFMU>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_isp_iopmp: isp-iopmp {
iopmp-name = "VI-IOPMP";
device-id = <IOPMP_DEV_ISP>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_vipre_iopmp: vipre-iopmp {
iopmp-name = "VI-IOPMP";
device-id = <IOPMP_DEV_VIPRE>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_dw200_iopmp: dw200-iopmp {
iopmp-name = "VI-IOPMP";
device-id = <IOPMP_DEV_DW200>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_vi_comp_decomp_iopmp: vi_comp_decomp-iopmp {
iopmp-name = "VI-IOPMP";
device-id = <IOPMP_DEV_VI_COMP_DECOMP>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_vi_iommu_iopmp: vi-iommu-iopmp {
iopmp-name = "VI-IOPMP";
device-id = <IOPMP_DEV_VI_IOMMU>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
/* NPU iopmp*/
device_npu_mt_iopmp: npu-mt-iopmp {
iopmp-name = "NPU-IOPMP";
device-id = <IOPMP_DEV_NPU_DFMU>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_npu_iopmp: npu-iopmp {
iopmp-name = "NPU-IOPMP";
device-id = <IOPMP_DEV_NPU>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_npu_iommu_iopmp: npu-iommu-iopmp {
iopmp-name = "NPU-IOPMP";
device-id = <IOPMP_DEV_NPU_IOMMU>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
/* VO iopmp */
device_vo_mt_iopmp: vo-mt-iopmp {
iopmp-name = "VO-IOPMP";
device-id = <IOPMP_DEV_VO_DFMU>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_display_0_iopmp: display-0-iopmp {
iopmp-name = "VO-IOPMP";
device-id = <IOPMP_DEV_DISPLAY_0>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_display_1_iopmp: display-1-iopmp {
iopmp-name = "VO-IOPMP";
device-id = <IOPMP_DEV_DISPLAY_1>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_auxdisp_iopmp: auxdisp-iopmp {
iopmp-name = "VO-IOPMP";
device-id = <IOPMP_DEV_AUXDISP>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_vo_iommu_iopmp: vo-iommu-iopmp {
iopmp-name = "VO-IOPMP";
device-id = <IOPMP_DEV_VO_IOMMU>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
/* PERI1 iopmp */
device_peri1_mt_iopmp: peri1-mt-iopmp {
iopmp-name = "PERI1-IOPMP";
device-id = <IOPMP_DEV_PERI1_DFMU>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_gmac_0_iopmp: gmac-0-iopmp {
iopmp-name = "PERI1-IOPMP";
device-id = <IOPMP_DEV_GMAC_0>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_gmac_1_iopmp: gmac-1-iopmp {
iopmp-name = "PERI1-IOPMP";
device-id = <IOPMP_DEV_GMAC_1>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_gmac_2_iopmp: gmac-2-iopmp {
iopmp-name = "PERI1-IOPMP";
device-id = <IOPMP_DEV_GMAC_2>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_chip_dbg_iopmp: chip-dbg-iopmp {
iopmp-name = "PERI1-IOPMP";
device-id = <IOPMP_DEVICE_CHIP_DBG>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_aon_iopmp: aon-iopmp {
iopmp-name = "PERI1-IOPMP";
@@ -1181,46 +1147,46 @@
device_peri1_iommu_iopmp: peri1-iommu-iopmp {
iopmp-name = "PERI1-IOPMP";
device-id = <IOPMP_DEV_PERI1_IOMMU>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
/* USB iopmp*/
device_usb_mt_iopmp: usb-mt-iopmp {
iopmp-name = "USB-IOPMP";
device-id = <IOPMP_DEV_USB_DFMU>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_usb3_0_iopmp: usb3-0-iopmp {
iopmp-name = "USB-IOPMP";
device-id = <IOPMP_DEV_USB3_0>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_usb2_1_iopmp: usb2-1-iopmp {
iopmp-name = "USB-IOPMP";
device-id = <IOPMP_DEV_USB2_1>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_usb2_2_iopmp: usb2-2-iopmp {
iopmp-name = "USB-IOPMP";
device-id = <IOPMP_DEV_USB2_2>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_usb_iommu_iopmp: usb-iommu-iopmp {
iopmp-name = "USB-IOPMP";
device-id = <IOPMP_DEV_USB_IOMMU>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
/* GPU iopmp*/
device_gpu_mt_iopmp: gpu-mt-iopmp {
iopmp-name = "GPU-IOPMP";
device-id = <IOPMP_DEV_GPU_SS>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
device_gpu_iopmp: gpu-iopmp {
iopmp-name = "GPU-IOPMP";
device-id = <IOPMP_DEV_GPU>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
/* D2D RX iopmp*/
@@ -1228,7 +1194,7 @@
iopmp-name = "D2D-RX-IOPMP";
device-id = <IOPMP_DEV_D2D_RX>;
global = <1>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
/* D2D CPU iopmp*/
@@ -1236,7 +1202,7 @@
iopmp-name = "D2D-SS-IOPMP";
device-id = <IOPMP_DEV_REMOTE_CPU>;
global = <1>;
iopmp-regions = <&security_device_region>, <&trust_firmware_region>, <&bypass_region>;
iopmp-regions = <&security_device_region>, <&tee_os_region>, <&trust_firmware_region>, <&bypass_region>;
};
};

View File

@@ -78,9 +78,37 @@
};
};
dsi0: dw-mipi-dsi0@6700000{
compatible = "thead,light-mipi-dsi", "simple-bus", "syscon";
compatible = "simple-bus", "syscon";
reg = <0x00 0x6700000 0x0 0x10000>;
status = "disabled";
status = "okay";
dphy_0: dsi0-dphy {
compatible = "zhihe,a210-mipi-dphy";
regmap = <&dsi0>;
vosys-regmap = <&vosys_reg>;
status = "okay";
clocks = <&osc_24m>,
<&clk_vo VO_MIPI_CFGCLK_EN>,
<&clk_vo VO_MIPI_PCLK_EN>,
<&clk_vo VO_MIPI_PIXCLK>,
<&osc_24m>;
clock-names = "refclk", "cfgclk", "pclk", "prefclk", "pcfgclk";
#phy-cells = <0>;
};
dhost_0: dsi0-host {
compatible = "verisilicon,dw-mipi-dsi";
regmap = <&dsi0>;
interrupts = <213>;
status = "okay";
clocks = <&clk_vo VO_MIPI_CFGCLK_EN>,
<&clk_vo VO_MIPI_PCLK_EN>,
<&clk_vo VO_MIPI_PIXCLK>;
clock-names = "cfgclk", "pclk", "pixclk";
phys = <&dphy_0>;
phy-names = "dphy";
#address-cells = <1>;
#size-cells = <0>;
};
};
vosys_reg: vosys@6e06000{
compatible = "thead,light-vo-subsys", "syscon";
@@ -134,11 +162,11 @@
reg = <0x0 0x8010000 0x0 0x4000>;
interrupt-parent = <&intc>;
interrupts = <179>;
clocks = <&clk_vo DPTX_I2S_CLK_EN>,
<&clk_vo DPTX_IPI_CLK_EN>,
<&clk_vo DPTX_AUX_CLK_EN>,
<&clk_vo DPTX_GTC_CLK_EN>,
<&clk_vo DPTX_PCLK_EN>;
clocks = <&clk_usb DPTX_I2S_CLK_EN>,
<&clk_usb DPTX_IPI_CLK_EN>,
<&clk_usb DPTX_AUX_CLK_EN>,
<&clk_usb DPTX_GTC_CLK_EN>,
<&clk_usb DPTX_PCLK_EN>;
clock-names = "i2s", "ipi", "aux", "gtc", "pclk";
force-hpd = <1>;
#sound-dai-cells = <1>;
@@ -147,9 +175,9 @@
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
status = "okay";
dp_tx_in: endpoint {
reg = <0>;
remote-endpoint = <&disp0_out>;
status = "okay";
};
@@ -194,6 +222,13 @@
remote-endpoint = <&hdmi_tx_in>;
};
};
dpu_disp2: port@2 { //virtual port, not yet enabled.
reg = <2>;
disp2_out: endpoint {
remote-endpoint = <&enc0_in>;
};
};
};
gpu: gpu@6c00000{
compatible = "img,gpu";
@@ -440,7 +475,7 @@
adc: adc@5a0000 {
compatible = "zhihe,a210-adc";
reg = <0x00 0x5a0000 0x0 0x8000>;
reg = <0x00 0x5a0000 0x0 0x1000>;
interrupt-parent = <&intc>;
interrupts = <260>;
clocks = <&clk_peri PERI3_ADC_PCLK_EN>;
@@ -1050,7 +1085,6 @@
reg = <0x00 0x30891000 0x0 0x1000>;
interrupt-parent = <&intc>;
interrupts = <20>;
//clocks = <&clk_peri PERI2_I2C7_IC_CLK_EN>, <&clk_peri PERI2_I2C7_PCLK_EN>;
clocks = <&aon_110m>;
clock-names = "ref", "pclk";
//power-domains = <&power_peri2>;
@@ -1799,9 +1833,9 @@
interrupt-parent = <&intc>;
interrupts = <240>;
interrupt-names = "irq_2d";
clocks = <&clk VP_G2D_PCLK_EN>,
<&clk VP_G2D_ACLK_EN>,
<&clk VP_G2D_CCLK_EN>;
clocks = <&clk_vp VP_G2D_PCLK_EN>,
<&clk_vp VP_G2D_ACLK_EN>,
<&clk_vp VP_G2D_CCLK_EN>;
clock-names = "pclk", "aclk", "cclk";
power-domains = <&power_vp_wrapper>;
status = "okay";
@@ -1825,6 +1859,7 @@
mipi0_csi0: csi@0006300000 {
compatible = "zhihe,bm-csi";
//default 2lane mode: host addr; current phy ctrl addr(csi1->aphy, csi0 bphy); mipi_ctrl addr
reg = < 0x00 0x06300000 0x0 0x10000
0x00 0x063a0024 0x0 0x4
0x00 0x063a0028 0x0 0x4>;
@@ -1843,6 +1878,7 @@
mipi0_csi1: csi@0006310000 {
compatible = "zhihe,bm-csi";
//default 2lane mode: host addr; current phy ctrl addr(csi1->aphy, csi0 bphy); mipi_ctrl addr
reg = < 0x00 0x06310000 0x0 0x10000
0x00 0x063a0020 0x0 0x4
0x00 0x063a0028 0x0 0x4>;
@@ -1861,6 +1897,7 @@
mipi1_csi0: csi@0006320000 {
compatible = "zhihe,bm-csi";
//default 2lane mode: host addr; current phy ctrl addr(csi1->aphy, csi0 bphy); mipi_ctrl addr
reg = < 0x00 0x06320000 0x0 0x10000
0x00 0x063a0034 0x0 0x4
0x00 0x063a0038 0x0 0x4>;
@@ -1878,6 +1915,7 @@
};
mipi1_csi1: csi@0006330000 {
//default 2lane mode: host addr; current phy ctrl addr(csi1->aphy, csi0 bphy); mipi_ctrl addr
compatible = "zhihe,bm-csi";
reg = < 0x00 0x06330000 0x0 0x10000
0x00 0x063a0030 0x0 0x4

12
arch/riscv/configs/a210_evb_defconfig Executable file → Normal file
View File

@@ -13,6 +13,7 @@ CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=24
CONFIG_NUMA_BALANCING=y
CONFIG_CGROUPS=y
CONFIG_MEMCG=y
@@ -241,10 +242,14 @@ CONFIG_USB_VIDEO_CLASS=m
CONFIG_DRM=y
CONFIG_DRM_LOAD_EDID_FIRMWARE=y
CONFIG_DRM_DP_AUX_CHARDEV=y
CONFIG_DRM_PANEL_SIMPLE=m
CONFIG_DRM_PANEL_JADARD_JD9365DA_H3=m
CONFIG_DRM_VERISILICON=m
CONFIG_VERISILICON_DW_DP_P100=y
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
CONFIG_BACKLIGHT_CLASS_DEVICE=m
CONFIG_BACKLIGHT_PWM=m
# CONFIG_VGA_CONSOLE is not set
CONFIG_LOGO=y
CONFIG_SOUND=m
@@ -287,6 +292,8 @@ CONFIG_MMC_SDHCI_OF_DWCMSHC=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_PCF8563=m
CONFIG_RTC_DRV_XGENE=y
CONFIG_DMADEVICES=y
CONFIG_DW_AXI_DMAC=y
CONFIG_DMATEST=m
@@ -305,6 +312,8 @@ CONFIG_IIO=y
CONFIG_PWM=y
CONFIG_PWM_THEAD=y
CONFIG_NVMEM_ZH_EFUSE=y
CONFIG_TEE=y
CONFIG_OPTEE=y
CONFIG_IOPMP=y
CONFIG_ZH_IOPMP=y
CONFIG_EXT4_FS=y
@@ -356,6 +365,3 @@ CONFIG_FTRACE_SYSCALLS=y
CONFIG_BPF_KPROBE_OVERRIDE=y
CONFIG_FUNCTION_ERROR_INJECTION=y
# CONFIG_RUNTIME_TESTING_MENU is not set
# Enable TEE
CONFIG_TEE=y
CONFIG_OPTEE=y

View File

@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_ZHIHE_CLK) += \
clk-helper.o
clk-helper.o \
clk-pll.o
obj-$(CONFIG_CLK_A210) += clk-a210.o

View File

@@ -18,9 +18,60 @@
#include "clk-helper.h"
/* top reg idx */
#define PLL_WRAP 0
#define TOP_CRG 1
#define CPU_SS_CLK_SYSREG 2
#define CPU_SS_CPU_PLL 3
#define DDR0_SYSREG 4
#define DDR1_SYSREG 5
#define SLC_DUAL_SYSREG 6
#define TOP_CRG_T 7
#define CPU_SS_CCU 8
/* gpu reg idx */
#define GPU_SS_PWRAP_CLK_EN 0
#define GPU_SS_TOP_CLK_EN 1
/* pcie reg idx */
#define PCIE_CLK_EN 0
/* usb reg idx */
#define USB_CLK_EN 0
/* vi reg idx */
#define VI_CLK 0
/* vp reg idx */
#define VP_CLK 0
/* vo reg idx */
#define VO_CLK 0
#define VO_PATH_CTRL 1
/* npu reg idx */
#define NPU_CLK 0
#define NPU_TOP_CLK 1
/* d2d reg idx */
#define D2D_CRG_REG 0
/* peri reg idx */
#define PERI0_SYSREG 0
#define PERI1_SYSREG 1
#define PERI2_SYSREG 2
#define PERI3_SYSREG 3
#define TEE_CRG 4
static u32 share_cnt_ddr_pll_clk_en;
static u32 share_cnt_peri3_clkgen_sdio_ref_clk;
enum a210_pll_clktype {
AUDIO0_PLL,
AUDIO1_PLL,
VIDEO_PLL,
GMAC_PLL,
DVFS_PLL,
DPU0_PLL,
DPU1_PLL,
DPU2_PLL,
TEE_PLL,
DDR_PLL,
C920_PLL,
C908_PLL,
};
static const char * const noc_cclk_mux_parents[] = {"dpu1_pll_foutvco", "video_pll_foutvco", "gmac_pll_foutvco"};
static const char * const top_cpu_ddr1_aclk_parents[] = {"cbus2ddr_aclk1", "gmac_pll_foutpostdiv"};
static const char * const top_cpu_ddr0_aclk_parents[] = {"cbus2ddr_aclk0", "gmac_pll_foutpostdiv"};
@@ -79,82 +130,82 @@ static const char * const vo_mipi_pixclk_mux_parents[] = {"dpu0_pixclk", "dpu1_p
static const char * const vo_hdmi_pixclk_mux_parents[] = {"dpu0_pixclk", "dpu1_pixclk", "dpu2_pixclk"};
static const char * const vo_dptx_pixclk_mux_parents[] = {"dpu0_pixclk", "dpu1_pixclk", "dpu2_pixclk"};
static struct p100_pll_rate_table p100_teepll_tbl[] = {
static struct zhihe_pll_rate_table a210_teepll_tbl[] = {
PLL_RATE(2400000000, 800000000U, 1, 100, 0, 3, 1),
};
static struct p100_pll_rate_table p100_dpu2pll_tbl[] = {
static struct zhihe_pll_rate_table a210_dpu2pll_tbl[] = {
PLL_RATE(2376000000, 1188000000U, 1, 99, 0, 2, 1),
};
static struct p100_pll_rate_table p100_dpu1pll_tbl[] = {
static struct zhihe_pll_rate_table a210_dpu1pll_tbl[] = {
PLL_RATE(2376000000, 1188000000U, 1, 99, 0, 2, 1),
};
static struct p100_pll_rate_table p100_dpu0pll_tbl[] = {
static struct zhihe_pll_rate_table a210_dpu0pll_tbl[] = {
PLL_RATE(2376000000, 1188000000U, 1, 99, 0, 2, 1),
};
static struct p100_pll_rate_table p100_dvfspll_tbl[] = {
static struct zhihe_pll_rate_table a210_dvfspll_tbl[] = {
PLL_RATE(1920000000, 960000000U, 1, 80, 0, 2, 1),
};
static struct p100_pll_rate_table p100_gmacpll_tbl[] = {
static struct zhihe_pll_rate_table a210_gmacpll_tbl[] = {
PLL_RATE(3000000000, 1000000000U, 1, 125, 0, 3, 1),
};
static struct p100_pll_rate_table p100_videopll_tbl[] = {
static struct zhihe_pll_rate_table a210_videopll_tbl[] = {
PLL_RATE(2640000000U, 1320000000U, 1, 110, 0, 2, 1),
};
static struct p100_pll_rate_table p100_audio0pll_tbl[] = {
static struct zhihe_pll_rate_table a210_audio0pll_tbl[] = {
PLL_RATE(2359296000U, 1179648000U, 1, 98, 5100274, 2, 1),
};
static struct p100_pll_rate_table p100_audio1pll_tbl[] = {
static struct zhihe_pll_rate_table a210_audio1pll_tbl[] = {
PLL_RATE(2528870400U, 1264435200U, 1, 105, 6200859, 2, 1),
};
static struct p100_pll_rate_table p100_c908pll_tbl[] = {
static struct zhihe_pll_rate_table a210_c908pll_tbl[] = {
PLL_RATE(1200000000U, 1200000000U, 1, 50, 0, 1, 1),
PLL_RATE(1500000000U, 1500000000U, 2, 125, 0, 1, 1),
PLL_RATE(1698000000U, 1698000000U, 4, 283, 0, 1, 1),
PLL_RATE(1896000000U, 1896000000U, 1, 79, 0, 1, 1),
};
static struct p100_pll_rate_table p100_c920pll_tbl[] = {
static struct zhihe_pll_rate_table a210_c920pll_tbl[] = {
PLL_RATE(1500000000U, 1500000000U, 2, 125, 0, 1, 1),
PLL_RATE(1698000000U, 1698000000U, 4, 283, 0, 1, 1),
PLL_RATE(1896000000U, 1896000000U, 1, 79, 0, 1, 1),
PLL_RATE(2298000000U, 2298000000U, 4, 383, 0, 1, 1),
};
static struct p100_clk_info_pll plls_top[] = {
PLL_PARAM(TEE_PLL, P100_PLL_VCO, p100_teepll_tbl, ARRAY_SIZE(p100_teepll_tbl), 0x160, 0x170,
static struct zhihe_clk_info_pll plls_top[] = {
PLL_PARAM(TEE_PLL, ZHIHE_PLL_VCO, a210_teepll_tbl, ARRAY_SIZE(a210_teepll_tbl), 0x160, 0x170,
BIT(0), BIT(31), BIT(30), PLL_MODE_INT, "tee_pll_foutvco_frequency"),
PLL_PARAM(DPU2_PLL, P100_PLL_VCO, p100_dpu2pll_tbl, ARRAY_SIZE(p100_dpu2pll_tbl), 0x120, 0x130,
PLL_PARAM(DPU2_PLL, ZHIHE_PLL_VCO, a210_dpu2pll_tbl, ARRAY_SIZE(a210_dpu2pll_tbl), 0x120, 0x130,
BIT(0), BIT(31), BIT(30), PLL_MODE_INT, "dpu2_pll_foutvco_frequency"),
PLL_PARAM(DPU1_PLL, P100_PLL_VCO, p100_dpu1pll_tbl, ARRAY_SIZE(p100_dpu1pll_tbl), 0x100, 0x110,
PLL_PARAM(DPU1_PLL, ZHIHE_PLL_VCO, a210_dpu1pll_tbl, ARRAY_SIZE(a210_dpu1pll_tbl), 0x100, 0x110,
BIT(0), BIT(31), BIT(30), PLL_MODE_INT, "dpu1_pll_foutvco_frequency"),
PLL_PARAM(DPU0_PLL, P100_PLL_VCO, p100_dpu0pll_tbl, ARRAY_SIZE(p100_dpu0pll_tbl), 0x80, 0x90,
PLL_PARAM(DPU0_PLL, ZHIHE_PLL_VCO, a210_dpu0pll_tbl, ARRAY_SIZE(a210_dpu0pll_tbl), 0x80, 0x90,
BIT(0), BIT(31), BIT(30), PLL_MODE_INT, "dpu0_pll_foutvco_frequency"),
PLL_PARAM(DVFS_PLL, P100_PLL_VCO, p100_dvfspll_tbl, ARRAY_SIZE(p100_dvfspll_tbl), 0x60, 0x70,
PLL_PARAM(DVFS_PLL, ZHIHE_PLL_VCO, a210_dvfspll_tbl, ARRAY_SIZE(a210_dvfspll_tbl), 0x60, 0x70,
BIT(0), BIT(31), BIT(30), PLL_MODE_INT, "dvfs_pll_foutvco_frequency"),
PLL_PARAM(AUDIO0_PLL, P100_PLL_VCO, p100_audio0pll_tbl, ARRAY_SIZE(p100_audio0pll_tbl), 0x0, 0x10,
PLL_PARAM(AUDIO0_PLL, ZHIHE_PLL_VCO, a210_audio0pll_tbl, ARRAY_SIZE(a210_audio0pll_tbl), 0x0, 0x10,
BIT(0), BIT(31), BIT(30), PLL_MODE_FRAC, "audio0_pll_foutvco_frequency"),
PLL_PARAM(AUDIO1_PLL, P100_PLL_VCO, p100_audio1pll_tbl, ARRAY_SIZE(p100_audio1pll_tbl), 0x20, 0x30,
PLL_PARAM(AUDIO1_PLL, ZHIHE_PLL_VCO, a210_audio1pll_tbl, ARRAY_SIZE(a210_audio1pll_tbl), 0x20, 0x30,
BIT(0), BIT(31), BIT(30), PLL_MODE_FRAC, "audio1_pll_foutvco_frequency"),
PLL_PARAM(GMAC_PLL, P100_PLL_VCO, p100_gmacpll_tbl, ARRAY_SIZE(p100_gmacpll_tbl), 0x40, 0x50,
PLL_PARAM(GMAC_PLL, ZHIHE_PLL_VCO, a210_gmacpll_tbl, ARRAY_SIZE(a210_gmacpll_tbl), 0x40, 0x50,
BIT(0), BIT(31), BIT(30), PLL_MODE_INT, "gmac_pll_foutvco_frequency"),
PLL_PARAM(VIDEO_PLL, P100_PLL_VCO, p100_videopll_tbl, ARRAY_SIZE(p100_videopll_tbl), 0x140, 0x150,
PLL_PARAM(VIDEO_PLL, ZHIHE_PLL_VCO, a210_videopll_tbl, ARRAY_SIZE(a210_videopll_tbl), 0x140, 0x150,
BIT(0), BIT(31), BIT(30), PLL_MODE_INT, "video_pll_foutvco_frequency"),
PLL_PARAM(C908_PLL, P100_PLL_VCO, p100_c908pll_tbl, ARRAY_SIZE(p100_c908pll_tbl), 0x0, 0x10,
PLL_PARAM(C908_PLL, ZHIHE_PLL_VCO, a210_c908pll_tbl, ARRAY_SIZE(a210_c908pll_tbl), 0x0, 0x10,
BIT(0), BIT(31), BIT(30), PLL_MODE_INT, ""),
PLL_PARAM(C920_PLL, P100_PLL_VCO, p100_c920pll_tbl, ARRAY_SIZE(p100_c920pll_tbl), 0x40, 0x50,
PLL_PARAM(C920_PLL, ZHIHE_PLL_VCO, a210_c920pll_tbl, ARRAY_SIZE(a210_c920pll_tbl), 0x40, 0x50,
BIT(0), BIT(31), BIT(30), PLL_MODE_INT, ""),
};
static struct p100_clk_reg regs_top[] = {
static struct zhihe_clk_reg regs_top[] = {
REG(PLL_WRAP),
REG(TOP_CRG),
REG(CPU_SS_CLK_SYSREG),
@@ -166,42 +217,42 @@ static struct p100_clk_reg regs_top[] = {
REG(CPU_SS_CCU),
};
static struct p100_clk_reg regs_gpu[] = {
static struct zhihe_clk_reg regs_gpu[] = {
REG(GPU_SS_PWRAP_CLK_EN),
REG(GPU_SS_TOP_CLK_EN),
};
static struct p100_clk_reg regs_pcie[] = {
static struct zhihe_clk_reg regs_pcie[] = {
REG(PCIE_CLK_EN),
};
static struct p100_clk_reg regs_usb[] = {
static struct zhihe_clk_reg regs_usb[] = {
REG(USB_CLK_EN),
};
static struct p100_clk_reg regs_vi[] = {
static struct zhihe_clk_reg regs_vi[] = {
REG(VI_CLK),
};
static struct p100_clk_reg regs_vp[] = {
static struct zhihe_clk_reg regs_vp[] = {
REG(VP_CLK),
};
static struct p100_clk_reg regs_vo[] = {
static struct zhihe_clk_reg regs_vo[] = {
REG(VO_CLK),
REG(VO_PATH_CTRL),
};
static struct p100_clk_reg regs_npu[] = {
static struct zhihe_clk_reg regs_npu[] = {
REG(NPU_CLK),
REG(NPU_TOP_CLK),
};
static struct p100_clk_reg regs_d2d[] = {
static struct zhihe_clk_reg regs_d2d[] = {
REG(D2D_CRG_REG),
};
static struct p100_clk_reg regs_peri[] = {
static struct zhihe_clk_reg regs_peri[] = {
REG(PERI0_SYSREG),
REG(PERI1_SYSREG),
REG(PERI2_SYSREG),
@@ -209,7 +260,7 @@ static struct p100_clk_reg regs_peri[] = {
REG(TEE_CRG),
};
static struct p100_clk_info info_top[] = {
static struct zhihe_clk_info info_top[] = {
/* FIXED */
FIXED(AON_OSC_CLK_PHY, "aon_osc_clk_phy", "osc_24m", 24000000),
FIXED(AON_OSC_CLK_LOGIC, "aon_osc_clk_logic", "osc_24m", 24000000),
@@ -461,7 +512,7 @@ static struct p100_clk_info info_top[] = {
ddr_pll_clkout_parents, ARRAY_SIZE(ddr_pll_clkout_parents), CLK_SET_RATE_PARENT),
};
static struct p100_clk_info info_gpu[] = {
static struct zhihe_clk_info info_gpu[] = {
FIXED_FACTOR(GPU_TOP_SYS_CLK, "gpu_top_sys_clk", "top_cfg_aclk", 1, 1),
FIXED_FACTOR(GPU_PCLK_CDT, "gpu_pclk_cdt", "gpu_top_sys_clk", 1, 2),
GATE(SW_PWR_WRAP_DFMU_PCLK_EN, "gpu_top_pclk", "gpu_pclk_cdt", GPU_SS_PWRAP_CLK_EN, 0, 7),
@@ -469,7 +520,7 @@ static struct p100_clk_info info_gpu[] = {
GATE(SW_PWR_WRAP_GPU_CORE_CLK_EN, "gpu_core_clk", "top_gpu_core_clk", GPU_SS_PWRAP_CLK_EN, 0, 0),
};
static struct p100_clk_info info_pcie[] = {
static struct zhihe_clk_info info_pcie[] = {
FIXED_FACTOR(PCIE_SS_APB_CLK, "pcie_ss_apb_clk", "gmac_pll_foutpostdiv", 1, 10),
GATE(E16PHY_PCLK_EN, "e16phy_apbs_pclk", "pcie_ss_apb_clk", PCIE_CLK_EN, 0x8, 0),
GATE(SATA_PMALIVE_CLK_EN, "sata_pmalive_clk", "aon_osc_clk_logic", PCIE_CLK_EN, 0x14, 0),
@@ -486,7 +537,7 @@ static struct p100_clk_info info_pcie[] = {
GATE(PCIE_RP_GEN3X1_PCLK_EN, "pcie_rp_gen3x1_pclk", "pcie_ss_apb_clk", PCIE_CLK_EN, 0x24, 4),
};
static struct p100_clk_info info_usb[] = {
static struct zhihe_clk_info info_usb[] = {
GATE(DPTX_I2S_CLK_EN, "usb_dptx_i2s_clk", "audio0_pll_foutvco", USB_CLK_EN, 0x4, 16),
GATE(DPTX_IPI_CLK_EN, "usb_dptx_ipi_clk", "usb_ss_gtc_clk", USB_CLK_EN, 0x4, 12),
GATE(DPTX_AUX_CLK_EN, "usb_dptx_aux_clk", "clkgen_usb_ss_aux_clk", USB_CLK_EN, 0x4, 8),
@@ -506,7 +557,7 @@ static struct p100_clk_info info_usb[] = {
GATE(USB_SS_PERI2_CFG_ACLK_EN, "usb_peri2_cfg_aclk", "aon_osc_clk_logic", USB_CLK_EN, 0x20, 4),
};
static struct p100_clk_info info_vi[] = {
static struct zhihe_clk_info info_vi[] = {
GATE(VI_VSE_CLK_EN, "dw200_vseclk", "vi_pre_vse_clk_div", VI_CLK, 0, 29),
GATE(VI_VSEOUT_CLK_EN, "dw200_vseout_clk", "vi_pre_vse_clk_div", VI_CLK, 0, 22),
DIV(VI_PRE_VSE_CLK_DIV_NUM, "vi_pre_vse_clk_div", "gmac_pll_foutpostdiv", VI_CLK, 0xc, 4, 4,
@@ -580,7 +631,7 @@ static struct p100_clk_info info_vi[] = {
GATE(VI_REC_ACLK_EN, "vi_rec_aclk", "top_cfg_aclk", VI_CLK, 0x4, 14),
};
static struct p100_clk_info info_vp[] = {
static struct zhihe_clk_info info_vp[] = {
GATE(VP_DECOMP_EXTPCLK_EN, "vp_decomp_extpclk", "top_cfg_aclk", VP_CLK, 0, 23),
GATE(VP_COMP_EXTPCLK_EN, "vp_comp_extpclk", "top_cfg_aclk", VP_CLK, 0, 22),
GATE(VP_VENC_RS_ACLK_EN, "vp_venc_rs_aclk", "vp_aclk", VP_CLK, 0, 21),
@@ -611,7 +662,7 @@ static struct p100_clk_info info_vp[] = {
12, MUX_TYPE_DIV, 2, 15),
};
static struct p100_clk_info info_vo[] = {
static struct zhihe_clk_info info_vo[] = {
GATE(VO_X2H1_CLK_EN, "vo_x2h1_clk", "top_cfg_aclk", VO_CLK, 0, 24),
GATE(VO_X2H0_CLK_EN, "vo_x2h0_clk", "top_cfg_aclk", VO_CLK, 0, 23),
GATE(VO_PTW_ACLK_EN, "vo_ptw_aclk", "iommu_ptw_aclk", VO_CLK, 0, 22),
@@ -658,7 +709,7 @@ static struct p100_clk_info info_vo[] = {
vo_dptx_pixclk_mux_parents, ARRAY_SIZE(vo_dptx_pixclk_mux_parents), CLK_SET_RATE_PARENT|CLK_SET_RATE_NO_REPARENT),
};
static struct p100_clk_info info_npu[] = {
static struct zhihe_clk_info info_npu[] = {
GATE(SW_SEMA_PCLK_EN, "npu_clkgen_sema_pclk", "top_cfg_aclk", NPU_CLK, 0, 23),
GATE(SW_SEMA_ACLK_EN, "npu_clkgen_sema_aclk", "npu_aclk", NPU_CLK, 0, 22),
GATE(SW_NPU_X2P_ACLK_EN, "npu_x2p_aclk", "top_cfg_aclk", NPU_CLK, 0, 21),
@@ -668,12 +719,12 @@ static struct p100_clk_info info_npu[] = {
GATE(SW_NPU_IP_ACLK_EN, "npu_ip_aclk", "npu_aclk", NPU_CLK, 0, 10),
};
static struct p100_clk_info info_d2d[] = {
static struct zhihe_clk_info info_d2d[] = {
GATE(D2D_SS_CTRL0_CLK_EN, "d2d_ss_ctrl0_cg_aclk", "top_d2d_aclk", D2D_CRG_REG, 0, 1),
GATE(D2D_SS_CTRL1_CLK_EN, "d2d_ss_ctrl1_cg_aclk", "top_d2d_aclk", D2D_CRG_REG, 0, 0),
};
static struct p100_clk_info info_peri[] = {
static struct zhihe_clk_info info_peri[] = {
/* PERI0 SS */
GATE(PERI0_MBOX1_PCLK_EN, "peri0_mbox1_pclk", "top_cfg_aclk", PERI0_SYSREG, 0, 6),
GATE(PERI0_MBOX0_PCLK_EN, "peri0_mbox0_pclk", "top_cfg_aclk", PERI0_SYSREG, 0, 5),
@@ -828,78 +879,134 @@ static struct p100_clk_info info_peri[] = {
GATE(TEE_KEYRAM_CLKEN, "tee_keyram_clk", "tee_pclk", TEE_CRG, 0, 0),
};
static struct p100_clk_subsys top_clk = CLK_SUBSYS("top clk", regs_top, ARRAY_SIZE(regs_top),
info_top, ARRAY_SIZE(info_top), plls_top, ARRAY_SIZE(plls_top), false);
static struct p100_clk_subsys top_clk_fpga = CLK_SUBSYS("top clk fpga", regs_top, ARRAY_SIZE(regs_top),
info_top, ARRAY_SIZE(info_top), plls_top, ARRAY_SIZE(plls_top), true);
static struct p100_clk_subsys gpu_clk = CLK_SUBSYS("gpu clk", regs_gpu, ARRAY_SIZE(regs_gpu),
info_gpu, ARRAY_SIZE(info_gpu), NULL, 0, false);
static struct p100_clk_subsys pcie_clk = CLK_SUBSYS("pcie clk", regs_pcie, ARRAY_SIZE(regs_pcie),
info_pcie, ARRAY_SIZE(info_pcie), NULL, 0, false);
static struct p100_clk_subsys usb_clk = CLK_SUBSYS("usb clk", regs_usb, ARRAY_SIZE(regs_usb),
info_usb, ARRAY_SIZE(info_usb), NULL, 0, false);
static struct p100_clk_subsys vi_clk = CLK_SUBSYS("vi clk", regs_vi, ARRAY_SIZE(regs_vi),
info_vi, ARRAY_SIZE(info_vi), NULL, 0, false);
static struct p100_clk_subsys vp_clk = CLK_SUBSYS("vp clk", regs_vp, ARRAY_SIZE(regs_vp),
info_vp, ARRAY_SIZE(info_vp), NULL, 0, false);
static struct p100_clk_subsys vo_clk = CLK_SUBSYS("vo clk", regs_vo, ARRAY_SIZE(regs_vo),
info_vo, ARRAY_SIZE(info_vo), NULL, 0, false);
static struct p100_clk_subsys npu_clk = CLK_SUBSYS("npu clk", regs_npu, ARRAY_SIZE(regs_npu),
info_npu, ARRAY_SIZE(info_npu), NULL, 0, false);
static struct p100_clk_subsys d2d_clk = CLK_SUBSYS("d2d clk", regs_d2d, ARRAY_SIZE(regs_d2d),
info_d2d, ARRAY_SIZE(info_d2d), NULL, 0, false);
static struct p100_clk_subsys peri_clk = CLK_SUBSYS("peri clk", regs_peri, ARRAY_SIZE(regs_peri),
info_peri, ARRAY_SIZE(info_peri), NULL, 0, false);
static struct zhihe_clk_subsys top_clk = CLK_SUBSYS("top clk", regs_top, ARRAY_SIZE(regs_top),
info_top, ARRAY_SIZE(info_top), plls_top, ARRAY_SIZE(plls_top), false, 0);
static struct zhihe_clk_subsys top_clk_fpga = CLK_SUBSYS("top clk fpga", regs_top, ARRAY_SIZE(regs_top),
info_top, ARRAY_SIZE(info_top), plls_top, ARRAY_SIZE(plls_top), true, 0);
static struct zhihe_clk_subsys gpu_clk = CLK_SUBSYS("gpu clk", regs_gpu, ARRAY_SIZE(regs_gpu),
info_gpu, ARRAY_SIZE(info_gpu), NULL, 0, false, 0);
static struct zhihe_clk_subsys pcie_clk = CLK_SUBSYS("pcie clk", regs_pcie, ARRAY_SIZE(regs_pcie),
info_pcie, ARRAY_SIZE(info_pcie), NULL, 0, false, 0);
static struct zhihe_clk_subsys usb_clk = CLK_SUBSYS("usb clk", regs_usb, ARRAY_SIZE(regs_usb),
info_usb, ARRAY_SIZE(info_usb), NULL, 0, false, 0);
static struct zhihe_clk_subsys vi_clk = CLK_SUBSYS("vi clk", regs_vi, ARRAY_SIZE(regs_vi),
info_vi, ARRAY_SIZE(info_vi), NULL, 0, false, 0);
static struct zhihe_clk_subsys vp_clk = CLK_SUBSYS("vp clk", regs_vp, ARRAY_SIZE(regs_vp),
info_vp, ARRAY_SIZE(info_vp), NULL, 0, false, 0);
static struct zhihe_clk_subsys vo_clk = CLK_SUBSYS("vo clk", regs_vo, ARRAY_SIZE(regs_vo),
info_vo, ARRAY_SIZE(info_vo), NULL, 0, false, 0);
static struct zhihe_clk_subsys npu_clk = CLK_SUBSYS("npu clk", regs_npu, ARRAY_SIZE(regs_npu),
info_npu, ARRAY_SIZE(info_npu), NULL, 0, false, 0);
static struct zhihe_clk_subsys d2d_clk = CLK_SUBSYS("d2d clk", regs_d2d, ARRAY_SIZE(regs_d2d),
info_d2d, ARRAY_SIZE(info_d2d), NULL, 0, false, 0);
static struct zhihe_clk_subsys peri_clk = CLK_SUBSYS("peri clk", regs_peri, ARRAY_SIZE(regs_peri),
info_peri, ARRAY_SIZE(info_peri), NULL, 0, false, 0);
static struct zhihe_clk_subsys top_clk_die1 = CLK_SUBSYS("top clk", regs_top, ARRAY_SIZE(regs_top),
info_top, ARRAY_SIZE(info_top), plls_top, ARRAY_SIZE(plls_top), false, 1);
static struct zhihe_clk_subsys gpu_clk_die1 = CLK_SUBSYS("gpu clk", regs_gpu, ARRAY_SIZE(regs_gpu),
info_gpu, ARRAY_SIZE(info_gpu), NULL, 0, false, 1);
static struct zhihe_clk_subsys pcie_clk_die1 = CLK_SUBSYS("pcie clk", regs_pcie, ARRAY_SIZE(regs_pcie),
info_pcie, ARRAY_SIZE(info_pcie), NULL, 0, false, 1);
static struct zhihe_clk_subsys usb_clk_die1 = CLK_SUBSYS("usb clk", regs_usb, ARRAY_SIZE(regs_usb),
info_usb, ARRAY_SIZE(info_usb), NULL, 0, false, 1);
static struct zhihe_clk_subsys vi_clk_die1 = CLK_SUBSYS("vi clk", regs_vi, ARRAY_SIZE(regs_vi),
info_vi, ARRAY_SIZE(info_vi), NULL, 0, false, 1);
static struct zhihe_clk_subsys vp_clk_die1 = CLK_SUBSYS("vp clk", regs_vp, ARRAY_SIZE(regs_vp),
info_vp, ARRAY_SIZE(info_vp), NULL, 0, false, 1);
static struct zhihe_clk_subsys vo_clk_die1 = CLK_SUBSYS("vo clk", regs_vo, ARRAY_SIZE(regs_vo),
info_vo, ARRAY_SIZE(info_vo), NULL, 0, false, 1);
static struct zhihe_clk_subsys npu_clk_die1 = CLK_SUBSYS("npu clk", regs_npu, ARRAY_SIZE(regs_npu),
info_npu, ARRAY_SIZE(info_npu), NULL, 0, false, 1);
static struct zhihe_clk_subsys d2d_clk_die1 = CLK_SUBSYS("d2d clk", regs_d2d, ARRAY_SIZE(regs_d2d),
info_d2d, ARRAY_SIZE(info_d2d), NULL, 0, false, 1);
static struct zhihe_clk_subsys peri_clk_die1 = CLK_SUBSYS("peri clk", regs_peri, ARRAY_SIZE(regs_peri),
info_peri, ARRAY_SIZE(info_peri), NULL, 0, false, 1);
static struct zhihe_clk_subsys top_clk_die2 = CLK_SUBSYS("top clk", regs_top, ARRAY_SIZE(regs_top),
info_top, ARRAY_SIZE(info_top), plls_top, ARRAY_SIZE(plls_top), false, 2);
static struct zhihe_clk_subsys gpu_clk_die2 = CLK_SUBSYS("gpu clk", regs_gpu, ARRAY_SIZE(regs_gpu),
info_gpu, ARRAY_SIZE(info_gpu), NULL, 0, false, 2);
static struct zhihe_clk_subsys pcie_clk_die2 = CLK_SUBSYS("pcie clk", regs_pcie, ARRAY_SIZE(regs_pcie),
info_pcie, ARRAY_SIZE(info_pcie), NULL, 0, false, 2);
static struct zhihe_clk_subsys usb_clk_die2 = CLK_SUBSYS("usb clk", regs_usb, ARRAY_SIZE(regs_usb),
info_usb, ARRAY_SIZE(info_usb), NULL, 0, false, 2);
static struct zhihe_clk_subsys vi_clk_die2 = CLK_SUBSYS("vi clk", regs_vi, ARRAY_SIZE(regs_vi),
info_vi, ARRAY_SIZE(info_vi), NULL, 0, false, 2);
static struct zhihe_clk_subsys vp_clk_die2 = CLK_SUBSYS("vp clk", regs_vp, ARRAY_SIZE(regs_vp),
info_vp, ARRAY_SIZE(info_vp), NULL, 0, false, 2);
static struct zhihe_clk_subsys vo_clk_die2 = CLK_SUBSYS("vo clk", regs_vo, ARRAY_SIZE(regs_vo),
info_vo, ARRAY_SIZE(info_vo), NULL, 0, false, 2);
static struct zhihe_clk_subsys npu_clk_die2 = CLK_SUBSYS("npu clk", regs_npu, ARRAY_SIZE(regs_npu),
info_npu, ARRAY_SIZE(info_npu), NULL, 0, false, 2);
static struct zhihe_clk_subsys d2d_clk_die2 = CLK_SUBSYS("d2d clk", regs_d2d, ARRAY_SIZE(regs_d2d),
info_d2d, ARRAY_SIZE(info_d2d), NULL, 0, false, 2);
static struct zhihe_clk_subsys peri_clk_die2 = CLK_SUBSYS("peri clk", regs_peri, ARRAY_SIZE(regs_peri),
info_peri, ARRAY_SIZE(info_peri), NULL, 0, false, 2);
static struct zhihe_clk_subsys top_clk_die3 = CLK_SUBSYS("top clk", regs_top, ARRAY_SIZE(regs_top),
info_top, ARRAY_SIZE(info_top), plls_top, ARRAY_SIZE(plls_top), false, 3);
static struct zhihe_clk_subsys gpu_clk_die3 = CLK_SUBSYS("gpu clk", regs_gpu, ARRAY_SIZE(regs_gpu),
info_gpu, ARRAY_SIZE(info_gpu), NULL, 0, false, 3);
static struct zhihe_clk_subsys pcie_clk_die3 = CLK_SUBSYS("pcie clk", regs_pcie, ARRAY_SIZE(regs_pcie),
info_pcie, ARRAY_SIZE(info_pcie), NULL, 0, false, 3);
static struct zhihe_clk_subsys usb_clk_die3 = CLK_SUBSYS("usb clk", regs_usb, ARRAY_SIZE(regs_usb),
info_usb, ARRAY_SIZE(info_usb), NULL, 0, false, 3);
static struct zhihe_clk_subsys vi_clk_die3 = CLK_SUBSYS("vi clk", regs_vi, ARRAY_SIZE(regs_vi),
info_vi, ARRAY_SIZE(info_vi), NULL, 0, false, 3);
static struct zhihe_clk_subsys vp_clk_die3 = CLK_SUBSYS("vp clk", regs_vp, ARRAY_SIZE(regs_vp),
info_vp, ARRAY_SIZE(info_vp), NULL, 0, false, 3);
static struct zhihe_clk_subsys vo_clk_die3 = CLK_SUBSYS("vo clk", regs_vo, ARRAY_SIZE(regs_vo),
info_vo, ARRAY_SIZE(info_vo), NULL, 0, false, 3);
static struct zhihe_clk_subsys npu_clk_die3 = CLK_SUBSYS("npu clk", regs_npu, ARRAY_SIZE(regs_npu),
info_npu, ARRAY_SIZE(info_npu), NULL, 0, false, 3);
static struct zhihe_clk_subsys d2d_clk_die3 = CLK_SUBSYS("d2d clk", regs_d2d, ARRAY_SIZE(regs_d2d),
info_d2d, ARRAY_SIZE(info_d2d), NULL, 0, false, 3);
static struct zhihe_clk_subsys peri_clk_die3 = CLK_SUBSYS("peri clk", regs_peri, ARRAY_SIZE(regs_peri),
info_peri, ARRAY_SIZE(info_peri), NULL, 0, false, 3);
static struct clk_onecell_data clk_data;
static int p100_clocks_probe(struct platform_device *pdev)
static int a210_clocks_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct p100_clk_subsys *priv;
struct zhihe_clk_subsys *priv;
int ret;
if (clk_data.clks == NULL) {
clk_data.clks = devm_kcalloc(dev, CLK_END, sizeof(*clk_data.clks),
GFP_KERNEL);
if (!clk_data.clks)
struct clk_onecell_data *clk_data = devm_kzalloc(dev, sizeof(*clk_data), GFP_KERNEL);
if (!clk_data)
return -ENOMEM;
clk_data.clk_num = CLK_END;
clk_data->clks = devm_kcalloc(dev, CLK_END, sizeof(*clk_data->clks),
GFP_KERNEL);
if (!clk_data->clks)
return -ENOMEM;
clk_data->clk_num = CLK_END;
for (int i = 0; i < CLK_END; i++)
clk_data.clks[i] = ERR_PTR(-ENOENT);
clk_data->clks[i] = ERR_PTR(-ENOENT);
priv = (struct zhihe_clk_subsys *)device_get_match_data(&pdev->dev);
if (priv->is_fpga) {
zhihe_clk_fake_pll_fixed_ops();
}
priv = (struct p100_clk_subsys *)device_get_match_data(&pdev->dev);
if (priv->is_fpga) {
zhihe_p100_clk_fake_pll_fixed_ops();
}
priv->clk_data = &clk_data;
priv->clk_data = clk_data;
dev_set_drvdata(dev, priv);
ret = p100_parse_regbase(pdev);
ret = zhihe_parse_regbase(pdev);
if (ret) {
dev_err(dev, "fail to parse reg base");
return ret;
}
p100_register_clock(pdev);
zhihe_register_clock(pdev);
ret = of_clk_add_provider(np, of_clk_src_onecell_get, priv->clk_data);
if (ret < 0) {
dev_err(dev, "failed to register clks for p100\n");
dev_err(dev, "failed to register clks for a210\n");
goto unregister_clks;
}
ret = zhihe_clk_of_bulk_init(dev, priv->clk_data->clks);
if (ret < 0) {
dev_err(dev, "failed to init clks for p100\n");
goto unregister_clks;
}
dev_info(dev, "succeed to register p100 %s driver\n", priv->name);
dev_info(dev, "succeed to register a210 %s driver on die%d\n", priv->name, priv->die_num);
return 0;
@@ -908,32 +1015,62 @@ unregister_clks:
return ret;
}
static const struct of_device_id p100_clk_of_match[] = {
{ .compatible = "zhihe,p100-clk", .data = (const void *)&top_clk},
{ .compatible = "zhihe,p100-clk-emu", .data = (const void *)&top_clk_fpga},
{ .compatible = "zhihe,p100-clk-haps", .data = (const void *)&top_clk_fpga},
{ .compatible = "zhihe,p100-gpu-clk", .data = (const void *)&gpu_clk},
{ .compatible = "zhihe,p100-pcie-clk", .data = (const void *)&pcie_clk},
{ .compatible = "zhihe,p100-usb-clk", .data = (const void *)&usb_clk},
{ .compatible = "zhihe,p100-vi-clk", .data = (const void *)&vi_clk},
{ .compatible = "zhihe,p100-vp-clk", .data = (const void *)&vp_clk},
{ .compatible = "zhihe,p100-vo-clk", .data = (const void *)&vo_clk},
{ .compatible = "zhihe,p100-npu-clk", .data = (const void *)&npu_clk},
{ .compatible = "zhihe,p100-d2d-clk", .data = (const void *)&d2d_clk},
{ .compatible = "zhihe,p100-peri-clk", .data = (const void *)&peri_clk},
static const struct of_device_id a210_clk_of_match[] = {
{ .compatible = "zhihe,a210-clk", .data = (const void *)&top_clk},
{ .compatible = "zhihe,a210-gpu-clk", .data = (const void *)&gpu_clk},
{ .compatible = "zhihe,a210-pcie-clk", .data = (const void *)&pcie_clk},
{ .compatible = "zhihe,a210-usb-clk", .data = (const void *)&usb_clk},
{ .compatible = "zhihe,a210-vi-clk", .data = (const void *)&vi_clk},
{ .compatible = "zhihe,a210-vp-clk", .data = (const void *)&vp_clk},
{ .compatible = "zhihe,a210-vo-clk", .data = (const void *)&vo_clk},
{ .compatible = "zhihe,a210-npu-clk", .data = (const void *)&npu_clk},
{ .compatible = "zhihe,a210-d2d-clk", .data = (const void *)&d2d_clk},
{ .compatible = "zhihe,a210-peri-clk", .data = (const void *)&peri_clk},
{ .compatible = "zhihe,a210-clk-emu", .data = (const void *)&top_clk_fpga},
{ .compatible = "zhihe,a210-clk-haps", .data = (const void *)&top_clk_fpga},
{ .compatible = "zhihe,a210-clk-die1", .data = (const void *)&top_clk_die1},
{ .compatible = "zhihe,a210-gpu-clk-die1", .data = (const void *)&gpu_clk_die1},
{ .compatible = "zhihe,a210-pcie-clk-die1", .data = (const void *)&pcie_clk_die1},
{ .compatible = "zhihe,a210-usb-clk-die1", .data = (const void *)&usb_clk_die1},
{ .compatible = "zhihe,a210-vi-clk-die1", .data = (const void *)&vi_clk_die1},
{ .compatible = "zhihe,a210-vp-clk-die1", .data = (const void *)&vp_clk_die1},
{ .compatible = "zhihe,a210-vo-clk-die1", .data = (const void *)&vo_clk_die1},
{ .compatible = "zhihe,a210-npu-clk-die1", .data = (const void *)&npu_clk_die1},
{ .compatible = "zhihe,a210-d2d-clk-die1", .data = (const void *)&d2d_clk_die1},
{ .compatible = "zhihe,a210-peri-clk-die1", .data = (const void *)&peri_clk_die1},
{ .compatible = "zhihe,a210-clk-die2", .data = (const void *)&top_clk_die2},
{ .compatible = "zhihe,a210-gpu-clk-die2", .data = (const void *)&gpu_clk_die2},
{ .compatible = "zhihe,a210-pcie-clk-die2", .data = (const void *)&pcie_clk_die2},
{ .compatible = "zhihe,a210-usb-clk-die2", .data = (const void *)&usb_clk_die2},
{ .compatible = "zhihe,a210-vi-clk-die2", .data = (const void *)&vi_clk_die2},
{ .compatible = "zhihe,a210-vp-clk-die2", .data = (const void *)&vp_clk_die2},
{ .compatible = "zhihe,a210-vo-clk-die2", .data = (const void *)&vo_clk_die2},
{ .compatible = "zhihe,a210-npu-clk-die2", .data = (const void *)&npu_clk_die2},
{ .compatible = "zhihe,a210-d2d-clk-die2", .data = (const void *)&d2d_clk_die2},
{ .compatible = "zhihe,a210-peri-clk-die2", .data = (const void *)&peri_clk_die2},
{ .compatible = "zhihe,a210-clk-die3", .data = (const void *)&top_clk_die3},
{ .compatible = "zhihe,a210-gpu-clk-die3", .data = (const void *)&gpu_clk_die3},
{ .compatible = "zhihe,a210-pcie-clk-die3", .data = (const void *)&pcie_clk_die3},
{ .compatible = "zhihe,a210-usb-clk-die3", .data = (const void *)&usb_clk_die3},
{ .compatible = "zhihe,a210-vi-clk-die3", .data = (const void *)&vi_clk_die3},
{ .compatible = "zhihe,a210-vp-clk-die3", .data = (const void *)&vp_clk_die3},
{ .compatible = "zhihe,a210-vo-clk-die3", .data = (const void *)&vo_clk_die3},
{ .compatible = "zhihe,a210-npu-clk-die3", .data = (const void *)&npu_clk_die3},
{ .compatible = "zhihe,a210-d2d-clk-die3", .data = (const void *)&d2d_clk_die3},
{ .compatible = "zhihe,a210-peri-clk-die3", .data = (const void *)&peri_clk_die3},
{ /* Sentinel */ },
};
MODULE_DEVICE_TABLE(of, p100_clk_of_match);
MODULE_DEVICE_TABLE(of, a210_clk_of_match);
static struct platform_driver p100_clk_driver = {
.probe = p100_clocks_probe,
static struct platform_driver a210_clk_driver = {
.probe = a210_clocks_probe,
.driver = {
.name = "p100-clk",
.of_match_table = of_match_ptr(p100_clk_of_match),
.name = "a210-clk",
.of_match_table = of_match_ptr(a210_clk_of_match),
},
};
module_platform_driver(p100_clk_driver);
MODULE_AUTHOR("dong.yan <yand@zhcomputing.com>");
MODULE_DESCRIPTION("Zhihe P100 clock driver");
module_platform_driver(a210_clk_driver);
MODULE_AUTHOR("dong.yan <yand@zhihecomputing.com>");
MODULE_DESCRIPTION("Zhihe A210 clock driver");
MODULE_LICENSE("GPL v2");

View File

@@ -15,32 +15,10 @@
#include "clk-helper.h"
#define P100_PLL_CFG0 0x0
#define P100_PLL_CFG1 0x04
#define P100_PLL_CFG2 0x8
#define P100_POSTDIV2_SHIFT 24
#define P100_POSTDIV2_MASK GENMASK(26, 24)
#define P100_POSTDIV1_SHIFT 20
#define P100_POSTDIV1_MASK GENMASK(22, 20)
#define P100_FBDIV_SHIFT 8
#define P100_FBDIV_MASK GENMASK(19, 8)
#define P100_REFDIV_SHIFT 0
#define P100_REFDIV_MASK GENMASK(5, 0)
#define P100_BYPASS_MASK BIT(30)
#define P100_RST_MASK BIT(29)
#define P100_DSMPD_MASK BIT(24)
#define P100_DACPD_MASK BIT(25)
#define P100_FRAC_MASK GENMASK(23, 0)
#define P100_FRAC_SHIFT 0
#define P100_FRAC_DIV BIT(24)
#define LOCK_TIMEOUT_US 10000
#define div_mask(d) ((1 << (d->width)) - 1)
DEFINE_SPINLOCK(zhihe_p100_clk_lock);
#define to_clk_p100pll(_hw) container_of(_hw, struct clk_p100pll, hw)
DEFINE_SPINLOCK(zhihe_clk_lock);
void zhihe_unregister_clocks(struct clk *clks[], unsigned int count)
{
@@ -50,296 +28,6 @@ void zhihe_unregister_clocks(struct clk *clks[], unsigned int count)
clk_unregister(clks[i]);
}
static int clk_p100_pll_wait_lock(struct clk_p100pll *pll)
{
u32 val;
return readl_poll_timeout(pll->base + pll->pll_sts_off, val,
val & pll->pll_lock_bit, 0,
LOCK_TIMEOUT_US);
}
static int clk_p100_pll_prepare(struct clk_hw *hw)
{
struct clk_p100pll *pll = to_clk_p100pll(hw);
void __iomem *cfg1_off;
u32 val;
int ret;
cfg1_off = pll->base + pll->cfg0_reg_off + P100_PLL_CFG1;
val = readl_relaxed(cfg1_off);
if (!(val & pll->pll_rst_bit))
return 0;
/* Enable RST */
val |= pll->pll_rst_bit;
writel_relaxed(val, cfg1_off);
udelay(3);
/* Disable RST */
val &= ~pll->pll_rst_bit;
writel_relaxed(val, cfg1_off);
ret = clk_p100_pll_wait_lock(pll);
if (ret)
return ret;
return 0;
}
static int clk_p100_pll_fake_prepare(struct clk_hw *hw)
{
return 0;
}
static int clk_p100_pll_is_prepared(struct clk_hw *hw)
{
struct clk_p100pll *pll = to_clk_p100pll(hw);
u32 val;
val = readl_relaxed(pll->base + pll->cfg0_reg_off + P100_PLL_CFG1);
return (val & pll->pll_rst_bit) ? 0 : 1;
}
static void clk_p100_pll_unprepare(struct clk_hw *hw)
{
struct clk_p100pll *pll = to_clk_p100pll(hw);
u32 val;
val = readl_relaxed(pll->base + pll->cfg0_reg_off + P100_PLL_CFG1);
val |= pll->pll_rst_bit;
writel_relaxed(val, pll->base + pll->cfg0_reg_off + P100_PLL_CFG1);
}
static unsigned long clk_p100_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_p100pll *pll = to_clk_p100pll(hw);
u32 refdiv, fbdiv, postdiv1, postdiv2, frac;
u32 pll_cfg0, pll_cfg1;
u64 fvco = 0;
pll_cfg0 = readl_relaxed(pll->base + pll->cfg0_reg_off);
pll_cfg1 = readl_relaxed(pll->base + pll->cfg0_reg_off + P100_PLL_CFG1);
refdiv = (pll_cfg0 & P100_REFDIV_MASK) >> P100_REFDIV_SHIFT;
fbdiv = (pll_cfg0 & P100_FBDIV_MASK) >> P100_FBDIV_SHIFT;
postdiv1 = (pll_cfg0 & P100_POSTDIV1_MASK) >> P100_POSTDIV1_SHIFT;
postdiv2 = (pll_cfg0 & P100_POSTDIV2_MASK) >> P100_POSTDIV2_SHIFT;
frac = (pll_cfg1 & P100_FRAC_MASK) >> P100_FRAC_SHIFT;
/* rate calculation:
* INT mode: FOUTVCO = FREE * FBDIV / REFDIV
* FRAC mode:FOUTVCO = (FREE * FBDIV + FREE * FRAC/BIT(24)) / REFDIV
*/
if (pll->pll_mode == PLL_MODE_FRAC)
fvco = (parent_rate * frac) / P100_FRAC_DIV;
fvco += (parent_rate * fbdiv);
do_div(fvco, refdiv);
if (pll->out_type == P100_PLL_DIV)
do_div(fvco, postdiv1 * postdiv2);
return fvco;
}
/* Zhihe P100 Pll recalc rate bypass for HAPS and EMU*/
static unsigned long clk_p100_pll_recalc_rate_fake_pll(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_p100pll *pll = to_clk_p100pll(hw);
const struct p100_pll_rate_table *rate_table = pll->rate_table;
/* return minimum supported value */
if (pll->out_type == P100_PLL_DIV)
return rate_table[0].rate;
return rate_table[0].vco_rate;
}
static const struct p100_pll_rate_table *p100_get_pll_div_settings(
struct clk_p100pll *pll, unsigned long rate)
{
const struct p100_pll_rate_table *rate_table = pll->rate_table;
int i;
for (i = 0; i < pll->rate_count; i++)
if (rate == rate_table[i].rate)
return &rate_table[i];
return NULL;
}
static const struct p100_pll_rate_table *p100_get_pll_vco_settings(
struct clk_p100pll *pll, unsigned long rate)
{
const struct p100_pll_rate_table *rate_table = pll->rate_table;
int i;
for (i = 0; i < pll->rate_count; i++)
if (rate == rate_table[i].vco_rate)
return &rate_table[i];
return NULL;
}
static inline bool clk_p100_pll_change(struct clk_p100pll *pll,
const struct p100_pll_rate_table *rate)
{
u32 refdiv_old, fbdiv_old, postdiv1_old, postdiv2_old, frac_old;
u32 cfg0, cfg1;
bool pll_changed;
cfg0 = readl_relaxed(pll->base + pll->cfg0_reg_off);
cfg1 = readl_relaxed(pll->base + pll->cfg0_reg_off + P100_PLL_CFG1);
refdiv_old = (cfg0 & P100_REFDIV_MASK) >> P100_REFDIV_SHIFT;
fbdiv_old = (cfg0 & P100_FBDIV_MASK) >> P100_FBDIV_SHIFT;
postdiv1_old = (cfg0 & P100_POSTDIV1_MASK) >> P100_POSTDIV1_SHIFT;
postdiv2_old = (cfg0 & P100_POSTDIV2_MASK) >> P100_POSTDIV2_SHIFT;
frac_old = (cfg1 & P100_FRAC_MASK) >> P100_FRAC_SHIFT;
pll_changed = rate->refdiv != refdiv_old || rate->fbdiv != fbdiv_old ||
rate->postdiv1 != postdiv1_old || rate->postdiv2 != postdiv2_old;
if (pll->pll_mode == PLL_MODE_FRAC)
pll_changed |= (rate->frac != frac_old);
return pll_changed;
}
static int clk_p100_pll_set_rate(struct clk_hw *hw, unsigned long drate,
unsigned long prate)
{
struct clk_p100pll *pll = to_clk_p100pll(hw);
const struct p100_pll_rate_table *rate;
void __iomem *cfg1_off;
u32 tmp, div_val;
int ret;
if (pll->out_type == P100_PLL_VCO) {
rate = p100_get_pll_vco_settings(pll, drate);
if (!rate) {
pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
drate, clk_hw_get_name(hw));
return -EINVAL;
}
} else {
rate = p100_get_pll_div_settings(pll, drate);
if (!rate) {
pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
drate, clk_hw_get_name(hw));
return -EINVAL;
}
}
if (!clk_p100_pll_change(pll, rate))
return 0;
/* Enable RST */
cfg1_off = pll->base + pll->cfg0_reg_off + P100_PLL_CFG1;
tmp = readl_relaxed(cfg1_off);
tmp |= pll->pll_rst_bit;
writel_relaxed(tmp, cfg1_off);
div_val = (rate->refdiv << P100_REFDIV_SHIFT) |
(rate->fbdiv << P100_FBDIV_SHIFT) |
(rate->postdiv1 << P100_POSTDIV1_SHIFT) |
(rate->postdiv2 << P100_POSTDIV2_SHIFT);
writel_relaxed(div_val, pll->base + pll->cfg0_reg_off);
if (pll->pll_mode == PLL_MODE_FRAC) {
tmp &= ~(P100_FRAC_MASK << P100_FRAC_SHIFT);
tmp |= rate->frac;
writel_relaxed(tmp, cfg1_off);
}
udelay(3);
/* Disable RST */
tmp &= ~pll->pll_rst_bit;
writel_relaxed(tmp, cfg1_off);
/* Wait Lock, ~20us cost */
ret = clk_p100_pll_wait_lock(pll);
if (ret)
return ret;
/* HW requires 30us for pll stable */
udelay(30);
return 0;
}
static long clk_p100_pllvco_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
struct clk_p100pll *pll = to_clk_p100pll(hw);
const struct p100_pll_rate_table *rate_table = pll->rate_table;
unsigned long best = 0, now = 0;
unsigned int i, best_i = 0;
for (i = 0; i < pll->rate_count; i++) {
now = rate_table[i].vco_rate;
if (rate == now) {
return rate_table[i].vco_rate;
} else if (abs(now - rate) < abs(best - rate)) {
best = now;
best_i = i;
}
}
/* return minimum supported value */
return rate_table[best_i].vco_rate;
}
static long clk_p100_plldiv_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
struct clk_p100pll *pll = to_clk_p100pll(hw);
const struct p100_pll_rate_table *rate_table = pll->rate_table;
unsigned long best = 0, now = 0;
unsigned int i, best_i = 0;
for (i = 0; i < pll->rate_count; i++) {
now = rate_table[i].rate;
if (rate == now) {
return rate_table[i].rate;
} else if (abs(now - rate) < abs(best - rate)) {
best = now;
best_i = i;
}
}
/* return minimum supported value */
return rate_table[best_i].rate;
}
static struct clk_ops clk_p100_pll_def_ops = {
.recalc_rate = clk_p100_pll_recalc_rate,
};
static struct clk_ops clk_p100_pllvco_ops = {
.prepare = clk_p100_pll_prepare,
.unprepare = clk_p100_pll_unprepare,
.is_prepared = clk_p100_pll_is_prepared,
.recalc_rate = clk_p100_pll_recalc_rate,
.round_rate = clk_p100_pllvco_round_rate,
.set_rate = clk_p100_pll_set_rate,
};
static struct clk_ops clk_p100_plldiv_ops = {
.prepare = clk_p100_pll_prepare,
.unprepare = clk_p100_pll_unprepare,
.is_prepared = clk_p100_pll_is_prepared,
.recalc_rate = clk_p100_pll_recalc_rate,
.round_rate = clk_p100_plldiv_round_rate,
.set_rate = clk_p100_pll_set_rate,
};
int zhihe_clk_set_round_rate(struct device *dev, struct clk *clk, unsigned int freq)
{
unsigned long r;
@@ -358,112 +46,33 @@ int zhihe_clk_set_round_rate(struct device *dev, struct clk *clk, unsigned int f
return ret;
}
void zhihe_p100_clk_fake_pll_fixed_ops(void)
{
clk_p100_pll_def_ops.recalc_rate = clk_p100_pll_recalc_rate_fake_pll;
clk_p100_pllvco_ops.recalc_rate = clk_p100_pll_recalc_rate_fake_pll;
clk_p100_pllvco_ops.prepare = clk_p100_pll_fake_prepare;
clk_p100_plldiv_ops.recalc_rate = clk_p100_pll_recalc_rate_fake_pll;
clk_p100_plldiv_ops.prepare = clk_p100_pll_fake_prepare;
return;
}
struct clk *zhihe_p100_pll(const char *name, const char *parent_name,
void __iomem *base,
const struct p100_clk_info_pll *pll_clk)
{
struct clk_p100pll *pll;
struct clk *clk;
struct clk_init_data init;
u32 val;
pll = kzalloc(sizeof(*pll), GFP_KERNEL);
if (!pll)
return ERR_PTR(-ENOMEM);
init.name = name;
init.flags = pll_clk->flags;
init.parent_names = &parent_name;
init.num_parents = 1;
switch (pll_clk->out_type) {
case P100_PLL_VCO:
if (pll_clk->rate_table)
init.ops = &clk_p100_pllvco_ops;
break;
case P100_PLL_DIV:
if (pll_clk->rate_table)
init.ops = &clk_p100_plldiv_ops;
break;
default:
pr_err("%s: Unknown pll out type for pll clk %s\n",
__func__, name);
};
if (!pll_clk->rate_table)
init.ops = &clk_p100_pll_def_ops;
pll->base = base;
pll->hw.init = &init;
pll->out_type = pll_clk->out_type;
pll->clk_type = pll_clk->clk_type;
pll->rate_table = pll_clk->rate_table;
pll->rate_count = pll_clk->rate_count;
pll->cfg0_reg_off = pll_clk->cfg0_reg_off;
pll->pll_sts_off = pll_clk->pll_sts_off;
pll->pll_lock_bit = pll_clk->pll_lock_bit;
pll->pll_bypass_bit = pll_clk->pll_bypass_bit;
pll->pll_rst_bit = pll_clk->pll_rst_bit;
pll->pll_mode = pll_clk->pll_mode;
val = readl_relaxed(pll->base + pll->cfg0_reg_off + P100_PLL_CFG1);
val &= ~pll->pll_bypass_bit;
val |= P100_DACPD_MASK;
val |= P100_DSMPD_MASK;
if (pll->pll_mode == PLL_MODE_FRAC) {
val &= ~P100_DSMPD_MASK;
val &= ~P100_DACPD_MASK;
}
writel_relaxed(val, pll->base + pll->cfg0_reg_off + P100_PLL_CFG1);
clk = clk_register(NULL, &pll->hw);
if (IS_ERR(clk)) {
pr_err("%s: failed to register pll %s %lu\n",
__func__, name, PTR_ERR(clk));
kfree(pll);
}
return clk;
}
static inline struct clk_p100div *to_clk_p100div(struct clk_hw *hw)
static inline struct clk_zhihediv *to_clk_zhihediv(struct clk_hw *hw)
{
struct clk_divider *divider = to_clk_divider(hw);
return container_of(divider, struct clk_p100div, divider);
return container_of(divider, struct clk_zhihediv, divider);
}
static unsigned long clk_p100div_recalc_rate(struct clk_hw *hw,
static unsigned long clk_zhihediv_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_p100div *p100_div = to_clk_p100div(hw);
struct clk_zhihediv *zhihe_div = to_clk_zhihediv(hw);
return p100_div->ops->recalc_rate(&p100_div->divider.hw, parent_rate);
return zhihe_div->ops->recalc_rate(&zhihe_div->divider.hw, parent_rate);
}
static long clk_p100div_round_rate(struct clk_hw *hw, unsigned long rate,
static long clk_zhihediv_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
struct clk_p100div *p100_div = to_clk_p100div(hw);
struct clk_zhihediv *zhihe_div = to_clk_zhihediv(hw);
return p100_div->ops->round_rate(&p100_div->divider.hw, rate, prate);
return zhihe_div->ops->round_rate(&zhihe_div->divider.hw, rate, prate);
}
static int clk_p100div_set_rate(struct clk_hw *hw, unsigned long rate,
static int clk_zhihediv_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_p100div *p100_div = to_clk_p100div(hw);
struct clk_zhihediv *zhihe_div = to_clk_zhihediv(hw);
struct clk_divider *div = to_clk_divider(hw);
unsigned int divider, value;
unsigned long flags = 0;
@@ -477,23 +86,23 @@ static int clk_p100div_set_rate(struct clk_hw *hw, unsigned long rate,
divider = DIV64_U64_ROUND_CLOSEST(parent_rate, rate);
/* DIV is zero based divider, but CDE is not */
if (p100_div->div_type == MUX_TYPE_DIV)
if (zhihe_div->div_type == MUX_TYPE_DIV)
value = divider;
else
value = divider - 1;
/* handle the div valid range */
if (value > p100_div->max_div)
value = p100_div->max_div;
if (value < p100_div->min_div)
value = p100_div->min_div;
if (value > zhihe_div->max_div)
value = zhihe_div->max_div;
if (value < zhihe_div->min_div)
value = zhihe_div->min_div;
spin_lock_irqsave(div->lock, flags);
val = readl(div->reg);
if (p100_div->sync_en != NO_DIV_EN) {
val &= ~BIT(p100_div->sync_en);
if (zhihe_div->sync_en != NO_DIV_EN) {
val &= ~BIT(zhihe_div->sync_en);
writel(val, div->reg);
udelay(1);
}
@@ -502,9 +111,9 @@ static int clk_p100div_set_rate(struct clk_hw *hw, unsigned long rate,
val |= value << div->shift;
writel(val, div->reg);
if (p100_div->sync_en != NO_DIV_EN) {
if (zhihe_div->sync_en != NO_DIV_EN) {
udelay(1);
val |= BIT(p100_div->sync_en);
val |= BIT(zhihe_div->sync_en);
writel(val, div->reg);
}
@@ -513,168 +122,168 @@ static int clk_p100div_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}
static const struct clk_ops clk_p100div_ops = {
.recalc_rate = clk_p100div_recalc_rate,
.round_rate = clk_p100div_round_rate,
.set_rate = clk_p100div_set_rate,
static const struct clk_ops clk_zhihediv_ops = {
.recalc_rate = clk_zhihediv_recalc_rate,
.round_rate = clk_zhihediv_round_rate,
.set_rate = clk_zhihediv_set_rate,
};
static struct clk *zhihe_clk_p100_divider_internal(const char *name, const char *parent,
static struct clk *zhihe_clk_divider_internal(const char *name, const char *parent,
void __iomem *reg, u8 shift, u8 width,
u8 sync, enum p100_div_type div_type,
u8 sync, enum zhihe_div_type div_type,
u16 min, u16 max, bool closest)
{
struct clk_p100div *p100_div;
struct clk_zhihediv *zhihe_div;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
p100_div = kzalloc(sizeof(*p100_div), GFP_KERNEL);
if (!p100_div)
zhihe_div = kzalloc(sizeof(*zhihe_div), GFP_KERNEL);
if (!zhihe_div)
return ERR_PTR(-ENOMEM);
init.name = name;
init.ops = &clk_p100div_ops;
init.ops = &clk_zhihediv_ops;
init.flags = CLK_SET_RATE_PARENT;
init.parent_names = parent ? &parent : NULL;
init.num_parents = parent ? 1 : 0;
p100_div->divider.reg = reg;
p100_div->divider.shift = shift;
p100_div->divider.width = width;
p100_div->divider.lock = &zhihe_p100_clk_lock;
p100_div->divider.hw.init = &init;
p100_div->ops = &clk_divider_ops;
p100_div->sync_en = sync;
p100_div->div_type = div_type;
if (p100_div->div_type == MUX_TYPE_DIV)
p100_div->divider.flags = CLK_DIVIDER_ONE_BASED;
zhihe_div->divider.reg = reg;
zhihe_div->divider.shift = shift;
zhihe_div->divider.width = width;
zhihe_div->divider.lock = &zhihe_clk_lock;
zhihe_div->divider.hw.init = &init;
zhihe_div->ops = &clk_divider_ops;
zhihe_div->sync_en = sync;
zhihe_div->div_type = div_type;
if (zhihe_div->div_type == MUX_TYPE_DIV)
zhihe_div->divider.flags = CLK_DIVIDER_ONE_BASED;
if (closest)
p100_div->divider.flags |= CLK_DIVIDER_ROUND_CLOSEST;
zhihe_div->divider.flags |= CLK_DIVIDER_ROUND_CLOSEST;
p100_div->min_div = min > ((1 << width) - 1) ?
zhihe_div->min_div = min > ((1 << width) - 1) ?
((1 << width) - 1) : min;
p100_div->max_div = max > ((1 << width) - 1) ?
zhihe_div->max_div = max > ((1 << width) - 1) ?
((1 << width) - 1) : max;
hw = &p100_div->divider.hw;
hw = &zhihe_div->divider.hw;
ret = clk_hw_register(NULL, hw);
if (ret) {
kfree(p100_div);
kfree(zhihe_div);
return ERR_PTR(ret);
}
return hw->clk;
}
struct clk *zhihe_clk_p100_divider(const char *name, const char *parent,
struct clk *zhihe_clk_divider(const char *name, const char *parent,
void __iomem *reg, u8 shift, u8 width,
u8 sync, enum p100_div_type div_type,
u8 sync, enum zhihe_div_type div_type,
u16 min, u16 max)
{
return zhihe_clk_p100_divider_internal(name, parent, reg, shift, width,
return zhihe_clk_divider_internal(name, parent, reg, shift, width,
sync, div_type, min, max, false);
}
struct clk *zhihe_clk_p100_divider_closest(const char *name, const char *parent,
struct clk *zhihe_clk_divider_closest(const char *name, const char *parent,
void __iomem *reg, u8 shift, u8 width,
u8 sync, enum p100_div_type div_type,
u8 sync, enum zhihe_div_type div_type,
u16 min, u16 max)
{
return zhihe_clk_p100_divider_internal(name, parent, reg, shift, width,
return zhihe_clk_divider_internal(name, parent, reg, shift, width,
sync, div_type, min, max, true);
}
static inline struct clk_p100gate *to_clk_p100gate(struct clk_hw *hw)
static inline struct clk_zhihegate *to_clk_zhihegate(struct clk_hw *hw)
{
struct clk_gate *gate = to_clk_gate(hw);
return container_of(gate, struct clk_p100gate, gate);
return container_of(gate, struct clk_zhihegate, gate);
}
static int clk_p100_gate_share_is_enabled(struct clk_hw *hw)
static int clk_zhihe_gate_share_is_enabled(struct clk_hw *hw)
{
struct clk_p100gate *p100_gate = to_clk_p100gate(hw);
struct clk_zhihegate *zhihe_gate = to_clk_zhihegate(hw);
return p100_gate->ops->is_enabled(hw);
return zhihe_gate->ops->is_enabled(hw);
}
static int clk_p100_gate_share_enable(struct clk_hw *hw)
static int clk_zhihe_gate_share_enable(struct clk_hw *hw)
{
struct clk_p100gate *p100_gate = to_clk_p100gate(hw);
struct clk_zhihegate *zhihe_gate = to_clk_zhihegate(hw);
if (p100_gate->share_count && (*p100_gate->share_count)++ > 0) {
if (zhihe_gate->share_count && (*zhihe_gate->share_count)++ > 0) {
return 0;
}
return p100_gate->ops->enable(hw);
return zhihe_gate->ops->enable(hw);
}
static void clk_p100_gate_share_disable(struct clk_hw *hw)
static void clk_zhihe_gate_share_disable(struct clk_hw *hw)
{
struct clk_p100gate *p100_gate = to_clk_p100gate(hw);
struct clk_zhihegate *zhihe_gate = to_clk_zhihegate(hw);
if (p100_gate->share_count) {
if (WARN_ON(*p100_gate->share_count == 0))
if (zhihe_gate->share_count) {
if (WARN_ON(*zhihe_gate->share_count == 0))
return;
else if (--(*p100_gate->share_count) > 0) {
else if (--(*zhihe_gate->share_count) > 0) {
return;
}
}
p100_gate->ops->disable(hw);
zhihe_gate->ops->disable(hw);
}
static void clk_p100_gate_share_disable_unused(struct clk_hw *hw)
static void clk_zhihe_gate_share_disable_unused(struct clk_hw *hw)
{
struct clk_p100gate *p100_gate = to_clk_p100gate(hw);
struct clk_zhihegate *zhihe_gate = to_clk_zhihegate(hw);
if (!p100_gate->share_count || *p100_gate->share_count == 0)
return p100_gate->ops->disable(hw);
if (!zhihe_gate->share_count || *zhihe_gate->share_count == 0)
return zhihe_gate->ops->disable(hw);
}
static const struct clk_ops clk_p100gate_share_ops = {
.enable = clk_p100_gate_share_enable,
.disable = clk_p100_gate_share_disable,
.disable_unused = clk_p100_gate_share_disable_unused,
.is_enabled = clk_p100_gate_share_is_enabled,
static const struct clk_ops clk_zhihegate_share_ops = {
.enable = clk_zhihe_gate_share_enable,
.disable = clk_zhihe_gate_share_disable,
.disable_unused = clk_zhihe_gate_share_disable_unused,
.is_enabled = clk_zhihe_gate_share_is_enabled,
};
struct clk *zhihe_clk_p100_register_gate_shared(const char *name, const char *parent,
struct clk *zhihe_clk_register_gate_shared(const char *name, const char *parent,
unsigned long flags, void __iomem *reg,
u8 shift, spinlock_t *lock,
unsigned int *share_count)
{
struct clk_p100gate *p100_gate;
struct clk_zhihegate *zhihe_gate;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
p100_gate = kzalloc(sizeof(*p100_gate), GFP_KERNEL);
if (!p100_gate)
zhihe_gate = kzalloc(sizeof(*zhihe_gate), GFP_KERNEL);
if (!zhihe_gate)
return ERR_PTR(-ENOMEM);
p100_gate->gate.reg = reg;
p100_gate->gate.bit_idx = shift;
p100_gate->gate.flags = 0;
p100_gate->gate.lock = lock;
p100_gate->gate.hw.init = &init;
p100_gate->ops = &clk_gate_ops;
p100_gate->share_count = share_count;
zhihe_gate->gate.reg = reg;
zhihe_gate->gate.bit_idx = shift;
zhihe_gate->gate.flags = 0;
zhihe_gate->gate.lock = lock;
zhihe_gate->gate.hw.init = &init;
zhihe_gate->ops = &clk_gate_ops;
zhihe_gate->share_count = share_count;
init.name = name;
init.ops = &clk_p100gate_share_ops;
init.ops = &clk_zhihegate_share_ops;
init.flags = flags;
init.parent_names = parent ? &parent : NULL;
init.num_parents = parent ? 1 : 0;
hw = &p100_gate->gate.hw;
hw = &zhihe_gate->gate.hw;
ret = clk_hw_register(NULL, hw);
if (ret) {
kfree(p100_gate);
kfree(zhihe_gate);
return ERR_PTR(ret);
}
@@ -708,7 +317,6 @@ static int is_frequency_name(const char *name)
static struct clk *zhihe_clk_match_clk(struct clk **clks, char *name)
{
int i;
for (i = 0; i < CLK_END; i++) {
if (clks[i] == ERR_PTR(-ENOENT))
continue;
@@ -748,10 +356,10 @@ int zhihe_clk_of_bulk_init(struct device *dev, struct clk **clks)
return 0;
}
int p100_parse_regbase(struct platform_device *pdev)
int zhihe_parse_regbase(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct p100_clk_subsys *priv = dev_get_drvdata(dev);
struct zhihe_clk_subsys *priv = dev_get_drvdata(dev);
int ret = 0;
for (int i = 0; i < priv->num_regs; i++) {
@@ -765,12 +373,51 @@ int p100_parse_regbase(struct platform_device *pdev)
return ret;
}
void p100_register_clock(struct platform_device *pdev)
static char *str_die_suffix(struct device *dev, const char *name, int id)
{
char *new_name = devm_kzalloc(dev, ZHIHE_CLK_NAME_SIZE, GFP_KERNEL);
if (new_name)
snprintf(new_name, ZHIHE_CLK_NAME_SIZE, "%s_die%d", name, id);
return new_name;
}
static const char * const * zhihe_add_mux_suffix(struct platform_device *pdev, int i)
{
struct device *dev = &pdev->dev;
struct p100_clk_subsys *priv = dev_get_drvdata(dev);
struct zhihe_clk_subsys *priv = dev_get_drvdata(dev);
const char * const *original_parents = priv->info[i].mux.parents;
u8 num_parents = priv->info[i].mux.num_parents;
const char **new_parents;
if (priv->die_num == 0)
return original_parents;
new_parents = devm_kzalloc(dev, sizeof(char *) * num_parents, GFP_KERNEL);
if (!new_parents) {
dev_err(dev, "Failed to allocate memory for new mux parents\n");
return ERR_PTR(-ENOMEM);
}
for (int j = 0; j < num_parents; j++) {
const char *original_name = original_parents[j];
char *suffix_name = str_die_suffix(dev, original_name, priv->die_num);
if (!suffix_name) {
dev_err(dev, "Failed to allocate memory for suffix_name\n");
return ERR_PTR(-ENOMEM);
}
new_parents[j] = suffix_name;
}
return new_parents;
}
void zhihe_register_clock(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct zhihe_clk_subsys *priv = dev_get_drvdata(dev);
struct device_node *np = dev->of_node;
unsigned int freq;
char *name, *parent;
int ret;
/* update pll freq if defined in dts */
@@ -783,9 +430,14 @@ void p100_register_clock(struct platform_device *pdev)
}
for (int i = 0; i < priv->num_info; i++) {
enum p100_clk_types type = priv->info[i].type;
char *name = priv->info[i].name;
char *parent = priv->info[i].parent;
enum zhihe_clk_types type = priv->info[i].type;
if (priv->die_num != 0) {
name = str_die_suffix(dev, priv->info[i].name, priv->die_num);
parent = str_die_suffix(dev, priv->info[i].parent, priv->die_num);
} else {
name = priv->info[i].name;
parent = priv->info[i].parent;
}
u32 id = priv->info[i].id;
void __iomem *base = priv->regs[priv->info[i].reg].base +
priv->info[i].shift;
@@ -797,32 +449,33 @@ void p100_register_clock(struct platform_device *pdev)
priv->clk_data->clks[id] = zhihe_clk_fixed(name, parent, priv->info[i].fixed.freq);
break;
case CLK_TYPE_FIXED_FACTOR:
priv->clk_data->clks[id] = zhihe_p100_clk_fixed_factor(name, parent,
priv->clk_data->clks[id] = zhihe_clk_fixed_factor(name, parent,
priv->info[i].fixed_factor.mult, priv->info[i].fixed_factor.div);
break;
case CLK_TYPE_PLL:
priv->clk_data->clks[id] = zhihe_p100_pll(name, parent, base, priv->info[i].pll);
priv->clk_data->clks[id] = zhihe_pll(name, parent, base, priv->info[i].pll);
break;
case CLK_TYPE_DIVIDER:
priv->clk_data->clks[id] = zhihe_clk_p100_divider(name, parent, base, bit_idx, width,
priv->clk_data->clks[id] = zhihe_clk_divider(name, parent, base, bit_idx, width,
priv->info[i].divider.sync, priv->info[i].divider.div_type,
priv->info[i].divider.min, priv->info[i].divider.max);
break;
case CLK_TYPE_DIVIDER_CLOSEST:
priv->clk_data->clks[id] = zhihe_clk_p100_divider_closest(name, parent, base, bit_idx, width,
priv->clk_data->clks[id] = zhihe_clk_divider_closest(name, parent, base, bit_idx, width,
priv->info[i].divider.sync, priv->info[i].divider.div_type,
priv->info[i].divider.min, priv->info[i].divider.max);
break;
case CLK_TYPE_GATE:
priv->clk_data->clks[id] = zhihe_clk_p100_gate(name, parent, base, bit_idx);
priv->clk_data->clks[id] = zhihe_clk_gate(name, parent, base, bit_idx);
break;
case CLK_TYPE_GATE_SHARED:
priv->clk_data->clks[id] = zhihe_clk_p100_gate_shared(name, parent, base, bit_idx,
priv->clk_data->clks[id] = zhihe_clk_gate_shared(name, parent, base, bit_idx,
priv->info[i].gate_shared.share_count);
break;
case CLK_TYPE_MUX:
priv->clk_data->clks[id] = zhihe_p100_clk_mux_flags(name, base, bit_idx, width,
priv->info[i].mux.parents, priv->info[i].mux.num_parents,
const char * const *parents = zhihe_add_mux_suffix(pdev, i);
priv->clk_data->clks[id] = zhihe_clk_mux_flags(name, base, bit_idx, width,
parents, priv->info[i].mux.num_parents,
priv->info[i].mux.flags);
break;
default:

View File

@@ -11,45 +11,9 @@
#include <linux/platform_device.h>
#include <dt-bindings/clock/a210-clock.h>
extern spinlock_t zhihe_p100_clk_lock;
extern spinlock_t zhihe_clk_lock;
#define P100_CLK_NAME_SIZE 30
/* top reg idx */
#define PLL_WRAP 0
#define TOP_CRG 1
#define CPU_SS_CLK_SYSREG 2
#define CPU_SS_CPU_PLL 3
#define DDR0_SYSREG 4
#define DDR1_SYSREG 5
#define SLC_DUAL_SYSREG 6
#define TOP_CRG_T 7
#define CPU_SS_CCU 8
/* gpu reg idx */
#define GPU_SS_PWRAP_CLK_EN 0
#define GPU_SS_TOP_CLK_EN 1
/* pcie reg idx */
#define PCIE_CLK_EN 0
/* usb reg idx */
#define USB_CLK_EN 0
/* vi reg idx */
#define VI_CLK 0
/* vp reg idx */
#define VP_CLK 0
/* vo reg idx */
#define VO_CLK 0
#define VO_PATH_CTRL 1
/* npu reg idx */
#define NPU_CLK 0
#define NPU_TOP_CLK 1
/* d2d reg idx */
#define D2D_CRG_REG 0
/* peri reg idx */
#define PERI0_SYSREG 0
#define PERI1_SYSREG 1
#define PERI2_SYSREG 2
#define PERI3_SYSREG 3
#define TEE_CRG 4
#define ZHIHE_CLK_NAME_SIZE 40
#define PLL_RATE(_vco, _rate, _r, _b, _f, _p, _k) \
{ \
@@ -144,7 +108,7 @@ extern spinlock_t zhihe_p100_clk_lock;
.name = (_name), \
}
#define CLK_SUBSYS(_name, _regs, _num_reg, _info, _num_info, _pll, _num_pll, _is_fpga) { \
#define CLK_SUBSYS(_name, _regs, _num_reg, _info, _num_info, _pll, _num_pll, _is_fpga, _die_num) { \
.name = (_name), \
.regs = (_regs), \
.num_regs = (_num_reg), \
@@ -153,38 +117,24 @@ extern spinlock_t zhihe_p100_clk_lock;
.plls = (_pll), \
.num_plls = (_num_pll), \
.is_fpga = (_is_fpga), \
.die_num = (_die_num), \
}
enum p100_pll_outtype {
P100_PLL_VCO,
P100_PLL_DIV,
enum zhihe_pll_outtype {
ZHIHE_PLL_VCO,
ZHIHE_PLL_DIV,
};
enum p100_div_type {
enum zhihe_div_type {
MUX_TYPE_DIV,
MUX_TYPE_CDE,
};
enum p100_div_sync_type {
enum zhihe_div_sync_type {
NO_DIV_EN = 255,
};
enum p100_pll_clktype {
AUDIO0_PLL,
AUDIO1_PLL,
VIDEO_PLL,
GMAC_PLL,
DVFS_PLL,
DPU0_PLL,
DPU1_PLL,
DPU2_PLL,
TEE_PLL,
DDR_PLL,
C920_PLL,
C908_PLL,
};
enum p100_clk_types {
enum zhihe_clk_types {
CLK_TYPE_FIXED,
CLK_TYPE_PLL,
CLK_TYPE_FIXED_FACTOR,
@@ -195,36 +145,37 @@ enum p100_clk_types {
CLK_TYPE_MUX,
};
enum p100_pll_mode {
enum zhihe_pll_mode {
PLL_MODE_FRAC,
PLL_MODE_INT,
};
struct p100_clk_reg {
struct zhihe_clk_reg {
void __iomem *base;
char name[P100_CLK_NAME_SIZE];
char name[ZHIHE_CLK_NAME_SIZE];
};
/* clk summary info at subsys level */
struct p100_clk_subsys {
char name[P100_CLK_NAME_SIZE];
struct p100_clk_reg *regs;
struct zhihe_clk_subsys {
char name[ZHIHE_CLK_NAME_SIZE];
struct zhihe_clk_reg *regs;
u32 num_regs;
struct p100_clk_info *info;
struct zhihe_clk_info *info;
u32 num_info;
struct p100_clk_info_pll *plls;
struct zhihe_clk_info_pll *plls;
u32 num_plls;
bool is_fpga;
struct clk_onecell_data *clk_data;
char die_num;
};
struct clk_p100pll {
struct clk_zhihepll {
struct clk_hw hw;
void __iomem *base;
enum p100_pll_clktype clk_type;
enum p100_pll_outtype out_type;
enum p100_pll_mode pll_mode;
const struct p100_pll_rate_table *rate_table;
unsigned int clk_type;
enum zhihe_pll_outtype out_type;
enum zhihe_pll_mode pll_mode;
const struct zhihe_pll_rate_table *rate_table;
int rate_count;
u32 cfg0_reg_off;
@@ -234,22 +185,22 @@ struct clk_p100pll {
int pll_bypass_bit;
};
struct clk_p100div {
struct clk_zhihediv {
struct clk_divider divider;
enum p100_div_type div_type;
enum zhihe_div_type div_type;
u16 min_div;
u16 max_div;
u8 sync_en;
const struct clk_ops *ops;
};
struct clk_p100gate {
struct clk_zhihegate {
struct clk_gate gate;
unsigned int *share_count;
const struct clk_ops *ops;
};
struct p100_pll_rate_table {
struct zhihe_pll_rate_table {
unsigned long vco_rate;
unsigned long rate;
unsigned int refdiv;
@@ -261,132 +212,133 @@ struct p100_pll_rate_table {
/* detailed clk info for each clk */
struct p100_clk_info_pll {
enum p100_pll_outtype out_type;
enum p100_pll_clktype clk_type;
struct p100_pll_rate_table *rate_table;
struct zhihe_clk_info_pll {
enum zhihe_pll_outtype out_type;
unsigned int clk_type;
struct zhihe_pll_rate_table *rate_table;
int rate_count;
int flags;
char name[P100_CLK_NAME_SIZE];
char name[ZHIHE_CLK_NAME_SIZE];
u32 cfg0_reg_off;
u32 pll_sts_off;
int pll_lock_bit;
int pll_rst_bit;
int pll_bypass_bit;
enum p100_pll_mode pll_mode;
enum zhihe_pll_mode pll_mode;
};
struct p100_clk_info_fixed {
struct zhihe_clk_info_fixed {
unsigned int freq;
};
struct p100_clk_info_fixed_factor {
struct zhihe_clk_info_fixed_factor {
unsigned int mult;
unsigned int div;
};
struct p100_clk_info_divider {
struct zhihe_clk_info_divider {
u8 sync;
enum p100_div_type div_type;
enum zhihe_div_type div_type;
u16 min;
u16 max;
};
struct p100_clk_info_gate_shared {
struct zhihe_clk_info_gate_shared {
unsigned int *share_count;
};
struct p100_clk_info_mux {
struct zhihe_clk_info_mux {
const char * const *parents;
int num_parents;
unsigned long flags;
};
struct p100_clk_info {
enum p100_clk_types type;
struct zhihe_clk_info {
enum zhihe_clk_types type;
u32 id;
char name[P100_CLK_NAME_SIZE];
char parent[P100_CLK_NAME_SIZE];
char name[ZHIHE_CLK_NAME_SIZE];
char parent[ZHIHE_CLK_NAME_SIZE];
u8 reg;
u32 shift;
u8 width;
u8 bit_idx;
union {
struct p100_clk_info_fixed fixed;
struct p100_clk_info_fixed_factor fixed_factor;
struct p100_clk_info_pll *pll;
struct p100_clk_info_divider divider;
struct p100_clk_info_gate_shared gate_shared;
struct p100_clk_info_mux mux;
struct zhihe_clk_info_fixed fixed;
struct zhihe_clk_info_fixed_factor fixed_factor;
struct zhihe_clk_info_pll *pll;
struct zhihe_clk_info_divider divider;
struct zhihe_clk_info_gate_shared gate_shared;
struct zhihe_clk_info_mux mux;
};
};
static inline struct clk *zhihe_p100_clk_fixed_factor(const char *name,
static inline struct clk *zhihe_clk_fixed_factor(const char *name,
const char *parent, unsigned int mult, unsigned int div)
{
return clk_register_fixed_factor(NULL, name, parent,
CLK_SET_RATE_PARENT, mult, div);
}
struct clk *zhihe_p100_pll(const char *name, const char *parent_name,
struct clk *zhihe_pll(const char *name, const char *parent_name,
void __iomem *base,
const struct p100_clk_info_pll *pll_clk);
const struct zhihe_clk_info_pll *pll_clk);
static inline struct clk *zhihe_clk_p100_gate(const char *name, const char *parent,
static inline struct clk *zhihe_clk_gate(const char *name, const char *parent,
void __iomem *reg, u8 shift)
{
return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
shift, 0, &zhihe_p100_clk_lock);
shift, 0, &zhihe_clk_lock);
}
struct clk *zhihe_clk_p100_register_gate_shared(const char *name, const char *parent,
struct clk *zhihe_clk_register_gate_shared(const char *name, const char *parent,
unsigned long flags, void __iomem *reg,
u8 shift, spinlock_t *lock,
unsigned int *share_count);
struct clk *zhihe_clk_p100_divider(const char *name, const char *parent,
struct clk *zhihe_clk_divider(const char *name, const char *parent,
void __iomem *reg, u8 shift, u8 width,
u8 sync, enum p100_div_type div_type,
u8 sync, enum zhihe_div_type div_type,
u16 min, u16 max);
/**
* By default, the clk framework calculates frequency by rounding downwards.
* This function is to achieve closest frequency.
*/
struct clk *zhihe_clk_p100_divider_closest(const char *name, const char *parent,
struct clk *zhihe_clk_divider_closest(const char *name, const char *parent,
void __iomem *reg, u8 shift, u8 width,
u8 sync, enum p100_div_type div_type,
u8 sync, enum zhihe_div_type div_type,
u16 min, u16 max);
void zhihe_unregister_clocks(struct clk *clks[], unsigned int count);
static inline struct clk *zhihe_clk_fixed(const char *name, const char *parent, unsigned long rate)
{
return clk_register_fixed_rate(NULL, name, parent, 0, rate);
}
static inline struct clk *zhihe_clk_p100_gate_shared(const char *name, const char *parent,
static inline struct clk *zhihe_clk_gate_shared(const char *name, const char *parent,
void __iomem *reg, u8 shift,
unsigned int *share_count)
{
return zhihe_clk_p100_register_gate_shared(name, parent, CLK_SET_RATE_PARENT, reg,
shift, &zhihe_p100_clk_lock, share_count);
return zhihe_clk_register_gate_shared(name, parent, CLK_SET_RATE_PARENT, reg,
shift, &zhihe_clk_lock, share_count);
}
static inline struct clk *zhihe_p100_clk_mux_flags(const char *name,
static inline struct clk *zhihe_clk_mux_flags(const char *name,
void __iomem *reg, u8 shift, u8 width,
const char * const *parents, int num_parents,
unsigned long flags)
{
return clk_register_mux(NULL, name, parents, num_parents,
flags , reg, shift, width, 0,
&zhihe_p100_clk_lock);
&zhihe_clk_lock);
}
void zhihe_p100_clk_fake_pll_fixed_ops(void);
void zhihe_clk_fake_pll_fixed_ops(void);
int zhihe_clk_set_round_rate(struct device *dev, struct clk *clk, unsigned int freq);
int zhihe_clk_of_bulk_init(struct device *dev, struct clk **clks);
int p100_parse_regbase(struct platform_device *pdev);
void p100_register_clock(struct platform_device *pdev);
int add_die_suffix(struct platform_device *pdev);
void zhihe_register_clock(struct platform_device *pdev);
void zhihe_unregister_clocks(struct clk *clks[], unsigned int count);
int zhihe_parse_regbase(struct platform_device *pdev);
#endif

408
drivers/clk/zhihe/clk-pll.c Normal file
View File

@@ -0,0 +1,408 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2025 Zhihe Computing Limited.
*/
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/device.h>
#include "clk-helper.h"
#define ZHIHE_PLL_CFG0 0x0
#define ZHIHE_PLL_CFG1 0x04
#define ZHIHE_PLL_CFG2 0x8
#define ZHIHE_POSTDIV2_SHIFT 24
#define ZHIHE_POSTDIV2_MASK GENMASK(26, 24)
#define ZHIHE_POSTDIV1_SHIFT 20
#define ZHIHE_POSTDIV1_MASK GENMASK(22, 20)
#define ZHIHE_FBDIV_SHIFT 8
#define ZHIHE_FBDIV_MASK GENMASK(19, 8)
#define ZHIHE_REFDIV_SHIFT 0
#define ZHIHE_REFDIV_MASK GENMASK(5, 0)
#define ZHIHE_BYPASS_MASK BIT(30)
#define ZHIHE_RST_MASK BIT(29)
#define ZHIHE_DSMPD_MASK BIT(24)
#define ZHIHE_DACPD_MASK BIT(25)
#define ZHIHE_FRAC_MASK GENMASK(23, 0)
#define ZHIHE_FRAC_SHIFT 0
#define ZHIHE_FRAC_DIV BIT(24)
#define LOCK_TIMEOUT_US 10000
#define to_clk_zhihepll(_hw) container_of(_hw, struct clk_zhihepll, hw)
static int clk_zhihe_pll_wait_lock(struct clk_zhihepll *pll)
{
u32 val;
return readl_poll_timeout(pll->base + pll->pll_sts_off, val,
val & pll->pll_lock_bit, 0,
LOCK_TIMEOUT_US);
}
static int clk_zhihe_pll_prepare(struct clk_hw *hw)
{
struct clk_zhihepll *pll = to_clk_zhihepll(hw);
void __iomem *cfg1_off;
u32 val;
int ret;
cfg1_off = pll->base + pll->cfg0_reg_off + ZHIHE_PLL_CFG1;
val = readl_relaxed(cfg1_off);
if (!(val & pll->pll_rst_bit))
return 0;
/* Enable RST */
val |= pll->pll_rst_bit;
writel_relaxed(val, cfg1_off);
udelay(3);
/* Disable RST */
val &= ~pll->pll_rst_bit;
writel_relaxed(val, cfg1_off);
ret = clk_zhihe_pll_wait_lock(pll);
if (ret)
return ret;
return 0;
}
static int clk_zhihe_pll_fake_prepare(struct clk_hw *hw)
{
return 0;
}
static int clk_zhihe_pll_is_prepared(struct clk_hw *hw)
{
struct clk_zhihepll *pll = to_clk_zhihepll(hw);
u32 val;
val = readl_relaxed(pll->base + pll->cfg0_reg_off + ZHIHE_PLL_CFG1);
return (val & pll->pll_rst_bit) ? 0 : 1;
}
static void clk_zhihe_pll_unprepare(struct clk_hw *hw)
{
struct clk_zhihepll *pll = to_clk_zhihepll(hw);
u32 val;
val = readl_relaxed(pll->base + pll->cfg0_reg_off + ZHIHE_PLL_CFG1);
val |= pll->pll_rst_bit;
writel_relaxed(val, pll->base + pll->cfg0_reg_off + ZHIHE_PLL_CFG1);
}
static unsigned long clk_zhihe_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_zhihepll *pll = to_clk_zhihepll(hw);
u32 refdiv, fbdiv, postdiv1, postdiv2, frac;
u32 pll_cfg0, pll_cfg1;
u64 fvco = 0;
pll_cfg0 = readl_relaxed(pll->base + pll->cfg0_reg_off);
pll_cfg1 = readl_relaxed(pll->base + pll->cfg0_reg_off + ZHIHE_PLL_CFG1);
refdiv = (pll_cfg0 & ZHIHE_REFDIV_MASK) >> ZHIHE_REFDIV_SHIFT;
fbdiv = (pll_cfg0 & ZHIHE_FBDIV_MASK) >> ZHIHE_FBDIV_SHIFT;
postdiv1 = (pll_cfg0 & ZHIHE_POSTDIV1_MASK) >> ZHIHE_POSTDIV1_SHIFT;
postdiv2 = (pll_cfg0 & ZHIHE_POSTDIV2_MASK) >> ZHIHE_POSTDIV2_SHIFT;
frac = (pll_cfg1 & ZHIHE_FRAC_MASK) >> ZHIHE_FRAC_SHIFT;
/* rate calculation:
* INT mode: FOUTVCO = FREE * FBDIV / REFDIV
* FRAC mode:FOUTVCO = (FREE * FBDIV + FREE * FRAC/BIT(24)) / REFDIV
*/
if (pll->pll_mode == PLL_MODE_FRAC)
fvco = (parent_rate * frac) / ZHIHE_FRAC_DIV;
fvco += (parent_rate * fbdiv);
do_div(fvco, refdiv);
if (pll->out_type == ZHIHE_PLL_DIV)
do_div(fvco, postdiv1 * postdiv2);
return fvco;
}
/* Zhihe ZHIHE Pll recalc rate bypass for HAPS and EMU*/
static unsigned long clk_zhihe_pll_recalc_rate_fake_pll(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_zhihepll *pll = to_clk_zhihepll(hw);
const struct zhihe_pll_rate_table *rate_table = pll->rate_table;
/* return minimum supported value */
if (pll->out_type == ZHIHE_PLL_DIV)
return rate_table[0].rate;
return rate_table[0].vco_rate;
}
static const struct zhihe_pll_rate_table *zhihe_get_pll_div_settings(
struct clk_zhihepll *pll, unsigned long rate)
{
const struct zhihe_pll_rate_table *rate_table = pll->rate_table;
int i;
for (i = 0; i < pll->rate_count; i++)
if (rate == rate_table[i].rate)
return &rate_table[i];
return NULL;
}
static const struct zhihe_pll_rate_table *zhihe_get_pll_vco_settings(
struct clk_zhihepll *pll, unsigned long rate)
{
const struct zhihe_pll_rate_table *rate_table = pll->rate_table;
int i;
for (i = 0; i < pll->rate_count; i++)
if (rate == rate_table[i].vco_rate)
return &rate_table[i];
return NULL;
}
static inline bool clk_zhihe_pll_change(struct clk_zhihepll *pll,
const struct zhihe_pll_rate_table *rate)
{
u32 refdiv_old, fbdiv_old, postdiv1_old, postdiv2_old, frac_old;
u32 cfg0, cfg1;
bool pll_changed;
cfg0 = readl_relaxed(pll->base + pll->cfg0_reg_off);
cfg1 = readl_relaxed(pll->base + pll->cfg0_reg_off + ZHIHE_PLL_CFG1);
refdiv_old = (cfg0 & ZHIHE_REFDIV_MASK) >> ZHIHE_REFDIV_SHIFT;
fbdiv_old = (cfg0 & ZHIHE_FBDIV_MASK) >> ZHIHE_FBDIV_SHIFT;
postdiv1_old = (cfg0 & ZHIHE_POSTDIV1_MASK) >> ZHIHE_POSTDIV1_SHIFT;
postdiv2_old = (cfg0 & ZHIHE_POSTDIV2_MASK) >> ZHIHE_POSTDIV2_SHIFT;
frac_old = (cfg1 & ZHIHE_FRAC_MASK) >> ZHIHE_FRAC_SHIFT;
pll_changed = rate->refdiv != refdiv_old || rate->fbdiv != fbdiv_old ||
rate->postdiv1 != postdiv1_old || rate->postdiv2 != postdiv2_old;
if (pll->pll_mode == PLL_MODE_FRAC)
pll_changed |= (rate->frac != frac_old);
return pll_changed;
}
static int clk_zhihe_pll_set_rate(struct clk_hw *hw, unsigned long drate,
unsigned long prate)
{
struct clk_zhihepll *pll = to_clk_zhihepll(hw);
const struct zhihe_pll_rate_table *rate;
void __iomem *cfg1_off;
u32 tmp, div_val;
int ret;
if (pll->out_type == ZHIHE_PLL_VCO) {
rate = zhihe_get_pll_vco_settings(pll, drate);
if (!rate) {
pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
drate, clk_hw_get_name(hw));
return -EINVAL;
}
} else {
rate = zhihe_get_pll_div_settings(pll, drate);
if (!rate) {
pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
drate, clk_hw_get_name(hw));
return -EINVAL;
}
}
if (!clk_zhihe_pll_change(pll, rate))
return 0;
/* Enable RST */
cfg1_off = pll->base + pll->cfg0_reg_off + ZHIHE_PLL_CFG1;
tmp = readl_relaxed(cfg1_off);
tmp |= pll->pll_rst_bit;
writel_relaxed(tmp, cfg1_off);
div_val = (rate->refdiv << ZHIHE_REFDIV_SHIFT) |
(rate->fbdiv << ZHIHE_FBDIV_SHIFT) |
(rate->postdiv1 << ZHIHE_POSTDIV1_SHIFT) |
(rate->postdiv2 << ZHIHE_POSTDIV2_SHIFT);
writel_relaxed(div_val, pll->base + pll->cfg0_reg_off);
if (pll->pll_mode == PLL_MODE_FRAC) {
tmp &= ~(ZHIHE_FRAC_MASK << ZHIHE_FRAC_SHIFT);
tmp |= rate->frac;
writel_relaxed(tmp, cfg1_off);
}
udelay(3);
/* Disable RST */
tmp &= ~pll->pll_rst_bit;
writel_relaxed(tmp, cfg1_off);
/* Wait Lock, ~20us cost */
ret = clk_zhihe_pll_wait_lock(pll);
if (ret)
return ret;
/* HW requires 30us for pll stable */
udelay(30);
return 0;
}
static long clk_zhihe_pllvco_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
struct clk_zhihepll *pll = to_clk_zhihepll(hw);
const struct zhihe_pll_rate_table *rate_table = pll->rate_table;
unsigned long best = 0, now = 0;
unsigned int i, best_i = 0;
for (i = 0; i < pll->rate_count; i++) {
now = rate_table[i].vco_rate;
if (rate == now) {
return rate_table[i].vco_rate;
} else if (abs(now - rate) < abs(best - rate)) {
best = now;
best_i = i;
}
}
/* return minimum supported value */
return rate_table[best_i].vco_rate;
}
static long clk_zhihe_plldiv_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
struct clk_zhihepll *pll = to_clk_zhihepll(hw);
const struct zhihe_pll_rate_table *rate_table = pll->rate_table;
unsigned long best = 0, now = 0;
unsigned int i, best_i = 0;
for (i = 0; i < pll->rate_count; i++) {
now = rate_table[i].rate;
if (rate == now) {
return rate_table[i].rate;
} else if (abs(now - rate) < abs(best - rate)) {
best = now;
best_i = i;
}
}
/* return minimum supported value */
return rate_table[best_i].rate;
}
static struct clk_ops clk_zhihe_pll_def_ops = {
.recalc_rate = clk_zhihe_pll_recalc_rate,
};
static struct clk_ops clk_zhihe_pllvco_ops = {
.prepare = clk_zhihe_pll_prepare,
.unprepare = clk_zhihe_pll_unprepare,
.is_prepared = clk_zhihe_pll_is_prepared,
.recalc_rate = clk_zhihe_pll_recalc_rate,
.round_rate = clk_zhihe_pllvco_round_rate,
.set_rate = clk_zhihe_pll_set_rate,
};
static struct clk_ops clk_zhihe_plldiv_ops = {
.prepare = clk_zhihe_pll_prepare,
.unprepare = clk_zhihe_pll_unprepare,
.is_prepared = clk_zhihe_pll_is_prepared,
.recalc_rate = clk_zhihe_pll_recalc_rate,
.round_rate = clk_zhihe_plldiv_round_rate,
.set_rate = clk_zhihe_pll_set_rate,
};
void zhihe_clk_fake_pll_fixed_ops(void)
{
clk_zhihe_pll_def_ops.recalc_rate = clk_zhihe_pll_recalc_rate_fake_pll;
clk_zhihe_pllvco_ops.recalc_rate = clk_zhihe_pll_recalc_rate_fake_pll;
clk_zhihe_pllvco_ops.prepare = clk_zhihe_pll_fake_prepare;
clk_zhihe_plldiv_ops.recalc_rate = clk_zhihe_pll_recalc_rate_fake_pll;
clk_zhihe_plldiv_ops.prepare = clk_zhihe_pll_fake_prepare;
return;
}
struct clk *zhihe_pll(const char *name, const char *parent_name,
void __iomem *base,
const struct zhihe_clk_info_pll *pll_clk)
{
struct clk_zhihepll *pll;
struct clk *clk;
struct clk_init_data init;
u32 val;
pll = kzalloc(sizeof(*pll), GFP_KERNEL);
if (!pll)
return ERR_PTR(-ENOMEM);
init.name = name;
init.flags = pll_clk->flags;
init.parent_names = &parent_name;
init.num_parents = 1;
switch (pll_clk->out_type) {
case ZHIHE_PLL_VCO:
if (pll_clk->rate_table)
init.ops = &clk_zhihe_pllvco_ops;
break;
case ZHIHE_PLL_DIV:
if (pll_clk->rate_table)
init.ops = &clk_zhihe_plldiv_ops;
break;
default:
pr_err("%s: Unknown pll out type for pll clk %s\n",
__func__, name);
};
if (!pll_clk->rate_table)
init.ops = &clk_zhihe_pll_def_ops;
pll->base = base;
pll->hw.init = &init;
pll->out_type = pll_clk->out_type;
pll->clk_type = pll_clk->clk_type;
pll->rate_table = pll_clk->rate_table;
pll->rate_count = pll_clk->rate_count;
pll->cfg0_reg_off = pll_clk->cfg0_reg_off;
pll->pll_sts_off = pll_clk->pll_sts_off;
pll->pll_lock_bit = pll_clk->pll_lock_bit;
pll->pll_bypass_bit = pll_clk->pll_bypass_bit;
pll->pll_rst_bit = pll_clk->pll_rst_bit;
pll->pll_mode = pll_clk->pll_mode;
val = readl_relaxed(pll->base + pll->cfg0_reg_off + ZHIHE_PLL_CFG1);
val &= ~pll->pll_bypass_bit;
val |= ZHIHE_DACPD_MASK;
val |= ZHIHE_DSMPD_MASK;
if (pll->pll_mode == PLL_MODE_FRAC) {
val &= ~ZHIHE_DSMPD_MASK;
val &= ~ZHIHE_DACPD_MASK;
}
writel_relaxed(val, pll->base + pll->cfg0_reg_off + ZHIHE_PLL_CFG1);
clk = clk_register(NULL, &pll->hw);
if (IS_ERR(clk)) {
pr_err("failed to register pll %s %ld\n",
name, PTR_ERR(clk));
kfree(pll);
}
return clk;
}

View File

@@ -1030,14 +1030,18 @@ static int primary_bind(struct dw_mipi_dsi *dsi)
int ret;
ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, &bridge);
if (ret)
if (ret) {
dev_err(dev, "Could not locate any output bridge or panel\n");
return ret;
}
if (panel) {
bridge = drm_panel_bridge_add(panel);
if (IS_ERR(bridge))
if (IS_ERR(bridge)) {
dev_err(dev, "drm panel bridge add failed\n");
return PTR_ERR(bridge);
}
}
primary->panel_bridge = bridge;
@@ -1138,30 +1142,42 @@ static int dsi_probe(struct platform_device *pdev)
funcs = of_device_get_match_data(dev);
dsi = funcs->get_dsi(dev);
if (!dsi)
if (!dsi) {
dev_err(dev, "get dsi failed\n");
return -ENOMEM;
}
dsi->regmap = syscon_regmap_lookup_by_phandle(np, "regmap");
if (IS_ERR(dsi->regmap))
if (IS_ERR(dsi->regmap)) {
dev_err(dev, "Reg map failed\n");
return PTR_ERR(dsi->regmap);
}
dsi->pclk = devm_clk_get_optional(dev, "pclk");
if (IS_ERR(dsi->pclk))
if (IS_ERR(dsi->pclk)) {
dev_err(dev, "Get pclk failed\n");
return PTR_ERR(dsi->pclk);
}
dsi->pixclk = devm_clk_get_optional(dev, "pixclk");
if (IS_ERR(dsi->pixclk))
if (IS_ERR(dsi->pixclk)) {
dev_err(dev, "Get pixclk failed\n");
return PTR_ERR(dsi->pixclk);
}
dsi->dphy = devm_phy_get(dev, "dphy");
if (IS_ERR(dsi->dphy))
if (IS_ERR(dsi->dphy)) {
dev_err(dev, "Get dphy failed\n");
return PTR_ERR(dsi->dphy);
}
dsi->host.ops = &dw_mipi_dsi_host_ops;
dsi->host.dev = dev;
ret = mipi_dsi_host_register(&dsi->host);
if (ret)
if (ret) {
dev_err(dev, "Host register failed\n");
return ret;
}
dsi->funcs = funcs;
dev_set_drvdata(dev, dsi);
@@ -1169,8 +1185,10 @@ static int dsi_probe(struct platform_device *pdev)
pm_runtime_enable(dev);
ret = component_add(dev, &dsi_component_ops);
if (ret)
if (ret) {
dev_err(dev, "Component add failed\n");
goto host_unregister;
}
return 0;

View File

@@ -472,14 +472,18 @@ static int vs_drm_bind(struct device *dev)
/* Now try and bind all our sub-components */
ret = component_bind_all(dev, drm_dev);
if (ret)
if (ret) {
DRM_ERROR("Failed to bind all components\n");
goto err_mode;
}
vs_mode_config_init(drm_dev);
ret = drm_vblank_init(drm_dev, drm_dev->mode_config.num_crtc);
if (ret)
if (ret) {
dev_err(drm_dev->dev, "vblank init failed.\n");
goto err_bind;
}
drm_mode_config_reset(drm_dev);
@@ -490,8 +494,10 @@ static int vs_drm_bind(struct device *dev)
drm_kms_helper_poll_init(drm_dev);
ret = drm_dev_register(drm_dev, 0);
if (ret)
if (ret) {
dev_err(drm_dev->dev, "Failed to register DRM device: %d\n", ret);
goto err_helper;
}
ret = sysfs_create_group(&drm_dev->primary->kdev->kobj, &vs_dev_attr_group);

View File

@@ -115,9 +115,9 @@
/* ---------------------------------- PLL ------------------------------- */
#define FCLKIN_FREQ_MIN 2000UL /* in KHz */
#define FCLKIN_FREQ_MAX 64000UL
#define FCLKIN_FREQ_MAX 297000UL
#define FOUT_FREQ_MIN 40000UL
#define FOUT_FREQ_MAX 1250000UL
#define FOUT_FREQ_MAX 2500000UL
#define CFGCLK_FREQ_MIN 17000UL
#define CFGCLK_FREQ_MAX 27000UL
@@ -455,12 +455,16 @@ static int dw_dphy_get_pll_cfg(struct dw_dphy *dphy,
const struct dw_pll_range *range;
fin = DIV_ROUND_UP_ULL(clk_get_rate(dphy->prefclk), 1000);
if (fin < FCLKIN_FREQ_MIN || fin > FCLKIN_FREQ_MAX)
if (fin < FCLKIN_FREQ_MIN || fin > FCLKIN_FREQ_MAX) {
dev_err(dphy->dev, "Error: fin is out of range, fin =%lu, range is %lu~%lu\n", fin, FCLKIN_FREQ_MIN, FCLKIN_FREQ_MAX);
return -EINVAL;
}
fout = DIV_ROUND_UP_ULL(opts->hs_clk_rate, 1000) >> 1;
if (fout < FOUT_FREQ_MIN || fout > FOUT_FREQ_MAX)
if (fout < FOUT_FREQ_MIN || fout > FOUT_FREQ_MAX) {
dev_err(dphy->dev, "Error: fout is out of range, fout =%lu, range is %lu~%lu\n", fout, FOUT_FREQ_MIN, FOUT_FREQ_MAX);
return -EINVAL;
}
for (i = 0; i < ARRAY_SIZE(pll_range_table); i++) {
range = &pll_range_table[i];
@@ -709,6 +713,7 @@ static int dw_dphy_remove(struct platform_device *pdev)
static const struct of_device_id dw_dphy_of_match[] = {
{ .compatible = "xuantie,th1520-mipi-dphy", .data = NULL, },
{ .compatible = "thead,light-mipi-dphy", .data = NULL, },
{ .compatible = "zhihe,a210-mipi-dphy", .data = NULL, },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, dw_dphy_of_match);

View File

@@ -1673,4 +1673,14 @@ config REGULATOR_TH1520_AON
This driver relies on the IPC interface between host CPU and the AON
firmware runnint on E902.
config REGULATOR_ZHIHE_AON
tristate "Zhihe Aon regulator"
depends on ZHIHE_AON
default y
help
This driver provides support for the Zhihe virtual regulators
that inmplemented on Zhihe Aon system.
This driver relies on the IPC interface between host CPU and the AON
firmware runnint on E902.
endif

View File

@@ -196,5 +196,6 @@ obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o
obj-$(CONFIG_REGULATOR_TH1520_AON) +=th1520-aon-regulator.o
obj-$(CONFIG_REGULATOR_ZHIHE_AON) +=zhihe-aon-regulator.o
ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG

View File

@@ -0,0 +1,457 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2021 Zhihe Group Holding Limited.
*/
#include <linux/debugfs.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/machine.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/firmware/zhihe/ipc.h>
#define MBOX_MAX_MSG_LEN 28
/*
* struct rpc_msg_regu_vol_set - regulator voltage set request descriptor
*
* @regu_id: Virtual regulator id
* @is_daul_rail: Specify if this virtual id contains dual rails
* @dc1: Voltage uint in uv for single rail or the first rail
* @dc2: Voltage uint in uv for the second rail, ignore it if it's not daul rail
*/
struct rpc_msg_regu_vol_set {
u16 regu_id;
u16 is_dual_rail;
u32 dc1;
u32 dc2;
u16 reserved[6];
} __packed __aligned(1);
/*
* struct rpc_msg_regu_vol_get - regulator voltage get request descriptor
*
* @regu_id: Virtual regulator id
* @is_daul_rail: Specify if this virtual id contains dual rails
* @dc1: Voltage uint in uv for single rail or the first rail
* @dc2: Voltage uint in uv for the second rail, ignore it if it's not daul rail
*/
struct rpc_msg_regu_vol_get {
u16 regu_id;
u16 is_dual_rail;
u32 dc1;
u32 dc2;
u16 reserved[6];
} __packed __aligned(1);
/*
* struct rpc_msg_regu_vol_get_ack - regulator voltage get resp descriptor
*
* Dedicated for rpc rx message with transform status and regulator voltage.
*
* @aon_rpc_ack_common: RPC message ack descriptor
* @regu_id: Virtual regulator id
* @is_daul_rail: Specify if this virtual id contains dual rails
* @dc1: Voltage uint in uv for single rail or the first rail
* @dc2: Voltage uint in uv for the second rail, ignore it if it's not daul rail
*/
struct rpc_msg_regu_vol_get_ack {
struct aon_rpc_ack_common ack_hdr;
u16 regu_id;
u16 is_dual_rail;
u32 dc1;
u32 dc2;
u16 reserved[6];
} __packed __aligned(1);
/*
* struct rpc_msg_regu_pwr_set - regulator power status set request descriptor
*
* @regu_id: Virtual regulator id
* @status: Regulator on\off status
*/
struct rpc_msg_regu_pwr_set {
u16 regu_id;
u16 status;
u32 reserved[5];
} __packed __aligned(1);
/*
* struct rpc_msg_regu_pwr_get - regulator power status get request descriptor
*
* @regu_id: Virtual regulator id
*/
struct rpc_msg_regu_pwr_get {
u16 regu_id;
u32 reserved[5];
} __packed __aligned(1);
/*
* struct rpc_msg_regu_pwr_get_ack - regulator power status get resp descriptor
*
* @aon_rpc_ack_common: RPC message ack descriptor
* @regu_id: Virtual regulator id
* @status: Regulator on\off status
*/
struct rpc_msg_regu_pwr_get_ack {
struct aon_rpc_ack_common ack_hdr;
u16 regu_id;
u16 status;
u32 reserved[5];
} __packed __aligned(1);
struct zhihe_aon_msg_regulator_ctrl {
struct aon_rpc_msg_hdr hdr;
union rpc_func_t {
struct rpc_msg_regu_vol_set regu_vol_set;
struct rpc_msg_regu_vol_get regu_vol_get;
struct rpc_msg_regu_pwr_set regu_pwr_set;
struct rpc_msg_regu_pwr_get regu_pwr_get;
} __packed __aligned(1) rpc;
} __packed __aligned(1);
enum a210_pm_resource {
A210_AVDD33_EMMC, /* sy70209: ldo1 */
A210_AVDD33_USB2, /* sy70209: ldo2 */
A210_DVDD08_AON, /* sy70209: ldo3 */
A210_AVDD18_AON, /* sy70209: ldo4 */
A210_AVDD18_EMMC_USB2, /* sy70209: ldo5 */
A210_AVDD18_EMMC_PERI, /* sy70209: ldo7 */
A210_AVDD18_TOP, /* sy70209: ldo8 */
A210_AVDD18_PLL, /* sy70209: ldo9 */
A210_AVDD18, /* sy70209: ldo10 */
A210_DVDD18_DDR_VAA, /* sy70209: vout1 */
A210_P3V3, /* sy70209: vout2 */
A210_DVDD08_TOP, /* sy70209: vout3 */
A210_DVDD06_DDR_VDDQLP, /* sy70209: vout4 */
A210_DVDD08_DDR, /* sy70209: vout5 */
A210_DVDD_CPU, /* sy70209: vout6 */
A210_DVDDM_CPU, /* sy70209: vout7 */
A210_DVDD_VP, /* sy70209: vout8 */
A210_DVDD_NPU_VIP, /* sy70300: vout1 */
A210_DVDD_CPU_P, /* sy70300: vout2 */
A210_DVDD_GPU, /* sy70300: vout3 */
A210_REGU_MAX
};
struct apcpu_vol_set {
u32 vdd; ///< cpu core voltage
u32 vddm; ///< cpu core-mem voltage
};
struct aon_regu_desc {
struct regulator_desc *regu_desc;
u32 regu_num;
};
struct aon_regu_info {
struct device *dev;
const struct apcpu_vol_set *cpu_vol; ///< signed-off voltage of cpu
u32 vddm; ///< cpu-mem voltage
uint8_t cpu_dual_rail_flag; ///< cpu dual rail flag
uint8_t vddm_dual_rail_flag; ///< cpu-mem dual rail flag
struct aon_regu_desc *regu_desc; ///< regu-desc set
struct zhihe_aon_ipc *ipc_handle; ///< handle of mail-box
};
static struct aon_regu_info zhihe_aon_pmic_info;
/* dc2 is valid when is_dual_rail is true
*
* dual-rail regulator means that a virtual regulator involes two hw-regulators
*/
static int aon_set_regulator(struct zhihe_aon_ipc *ipc, u16 regu_id, u32 dc)
{
struct zhihe_aon_msg_regulator_ctrl msg = {0};
struct aon_rpc_ack_common ack_msg = {0};
struct aon_rpc_msg_hdr *hdr = &msg.hdr;
hdr->svc = (uint8_t)AON_RPC_SVC_PM;
hdr->func = (uint8_t)AON_PM_FUNC_SET_RESOURCE_REGULATOR;
hdr->size = AON_RPC_MSG_NUM;
RPC_SET_BE16(&msg.rpc.regu_vol_set.regu_id, 0, regu_id);
RPC_SET_BE32(&msg.rpc.regu_vol_set.regu_id, 4, dc);
return zhihe_aon_call_rpc(ipc, &msg, &ack_msg, true);
}
/* dc2 is valid when is_dual_rail is true
*
* dual-rail regulator means that a virtual regulator involes two hw-regulators
*/
static int aon_get_regulator(struct zhihe_aon_ipc *ipc, u16 regu_id, u32 *dc)
{
struct zhihe_aon_msg_regulator_ctrl msg = {0};
struct rpc_msg_regu_vol_get_ack ack_msg = {0};
struct aon_rpc_msg_hdr *hdr = &msg.hdr;
int ret;
hdr->svc = (uint8_t)AON_RPC_SVC_PM;
hdr->func = (uint8_t)AON_PM_FUNC_GET_RESOURCE_REGULATOR;
hdr->size = AON_RPC_MSG_NUM;
RPC_SET_BE16(&msg.rpc.regu_vol_get.regu_id, 0, regu_id);
ret = zhihe_aon_call_rpc(ipc, &msg, &ack_msg, true);
if (ret)
return ret;
/*fix me:set local */
ack_msg.regu_id = regu_id;
RPC_GET_BE32(&ack_msg.regu_id, 4, &ack_msg.dc1);
if (dc != NULL)
*dc = ack_msg.dc1;
return 0;
}
static int aon_regu_power_ctrl(struct zhihe_aon_ipc *ipc, u32 regu_id, u16 pwr_on)
{
struct zhihe_aon_msg_regulator_ctrl msg = {0};
struct aon_rpc_ack_common ack_msg = {0};
struct aon_rpc_msg_hdr *hdr = &msg.hdr;
hdr->svc = (uint8_t)AON_RPC_SVC_PM;
hdr->func = (uint8_t)AON_PM_FUNC_PWR_SET;
hdr->size = AON_RPC_MSG_NUM;
RPC_SET_BE16(&msg.rpc.regu_pwr_set.regu_id, 0, regu_id);
RPC_SET_BE16(&msg.rpc.regu_pwr_set.regu_id, 2, pwr_on);
return zhihe_aon_call_rpc(ipc, &msg, &ack_msg, true);
}
static int aon_regu_enable(struct regulator_dev *reg)
{
u16 regu_id = (u16) rdev_get_id(reg);
return aon_regu_power_ctrl(zhihe_aon_pmic_info.ipc_handle, regu_id, 1);
}
static int aon_regu_disable(struct regulator_dev *reg)
{
u16 regu_id = (u16) rdev_get_id(reg);
return aon_regu_power_ctrl(zhihe_aon_pmic_info.ipc_handle, regu_id, 0);
}
static int aon_regu_is_enabled(struct regulator_dev *reg)
{
struct zhihe_aon_msg_regulator_ctrl msg = {0};
struct rpc_msg_regu_pwr_get_ack ack_msg = {0};
struct aon_rpc_msg_hdr *hdr = &msg.hdr;
int ret;
u16 regu_id = (u16) rdev_get_id(reg);
hdr->svc = (uint8_t)AON_RPC_SVC_PM;
hdr->func = (uint8_t)AON_PM_FUNC_PWR_GET;
hdr->size = AON_RPC_MSG_NUM;
RPC_SET_BE16(&msg.rpc.regu_pwr_get.regu_id, 0, regu_id);
ret = zhihe_aon_call_rpc(zhihe_aon_pmic_info.ipc_handle,
&msg, &ack_msg, true);
if (ret < 0)
return ret;
RPC_GET_BE16(&ack_msg.regu_id, 2, &ack_msg.status);
return (int) ack_msg.status;
}
static int aon_regu_set_voltage(struct regulator_dev *reg,
int minuV, int max_uV, unsigned int *selector)
{
u16 regu_id = (u16) rdev_get_id(reg);
return aon_set_regulator(zhihe_aon_pmic_info.ipc_handle, regu_id, minuV);
}
static int aon_regu_get_voltage(struct regulator_dev *reg)
{
u16 regu_id = (u16) rdev_get_id(reg);
int voltage, ret;
ret = aon_get_regulator(zhihe_aon_pmic_info.ipc_handle, regu_id, &voltage);
if (ret) {
pr_err("failed to get voltage\n");
return -EINVAL;
}
return voltage;
}
static const struct regulator_ops regu_common_ops = {
.enable = aon_regu_enable,
.disable = aon_regu_disable,
.is_enabled = aon_regu_is_enabled,
.list_voltage = regulator_list_voltage_linear,
.set_voltage = aon_regu_set_voltage,
.get_voltage = aon_regu_get_voltage,
};
/* Macros for voltage DC/DC converters (BUCKs) for cpu */
#define REGU_DSC_DEF(regu_id, of_math_name) { \
.id = regu_id, \
.name = of_match_ptr(of_math_name), \
.of_match = of_match_ptr(of_math_name), \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE \
}
#define REGU_DYN_DSC_DEF(regu_id, of_math_name, min, step, max) { \
.id = regu_id, \
.name = of_match_ptr(of_math_name), \
.of_match = of_match_ptr(of_math_name), \
.min_uV = (min), \
.uV_step = (step), \
.n_voltages = ((max) - (min))/(step) + 1, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE \
}
static struct regulator_desc zhihe_a210_aon_regu_desc[] = {
/*common regu ,no need to adjust vol dynamicaly */
REGU_DSC_DEF(A210_AVDD33_EMMC, "avdd33_emmc"),
REGU_DSC_DEF(A210_AVDD33_USB2, "avdd33_usb2"),
REGU_DSC_DEF(A210_DVDD08_AON, "dvdd08_aon"),
REGU_DSC_DEF(A210_AVDD18_AON, "avdd18_aon"),
REGU_DSC_DEF(A210_AVDD18_EMMC_USB2, "avdd18_emmc_usb2"),
REGU_DSC_DEF(A210_AVDD18_EMMC_PERI, "avdd18_emmc_peri"),
REGU_DSC_DEF(A210_AVDD18_TOP, "avdd18_top"),
REGU_DSC_DEF(A210_AVDD18_PLL, "avdd18_pll"),
REGU_DSC_DEF(A210_AVDD18, "avdd18"),
REGU_DSC_DEF(A210_DVDD18_DDR_VAA, "dvdd18_ddr_vaa"),
REGU_DSC_DEF(A210_P3V3, "p3v3"),
REGU_DSC_DEF(A210_DVDD08_TOP, "dvdd08_top"),
REGU_DSC_DEF(A210_DVDD06_DDR_VDDQLP, "dvdd06_ddr_vddqlp"),
REGU_DYN_DSC_DEF(A210_DVDD08_DDR, "dvdd08_ddr", 750000, 5000, 800000),
REGU_DYN_DSC_DEF(A210_DVDD_CPU, "dvdd_cpu", 600000, 12500, 1000000),
REGU_DYN_DSC_DEF(A210_DVDDM_CPU, "dvddm_cpu", 800000, 12500, 1000000),
REGU_DYN_DSC_DEF(A210_DVDD_VP, "dvdd_vp", 750000, 12500, 800000),
REGU_DYN_DSC_DEF(A210_DVDD_NPU_VIP, "dvdd_npu_vip", 750000, 5000, 1000000),
REGU_DYN_DSC_DEF(A210_DVDD_CPU_P, "dvdd_cpu_p", 800000, 5000, 1000000),
REGU_DYN_DSC_DEF(A210_DVDD_GPU, "dvdd_gpu", 750000, 5000, 800000),
};
static const struct aon_regu_desc zhihe_a210_aon_regus = {
.regu_desc = (struct regulator_desc *) &zhihe_a210_aon_regu_desc,
.regu_num = ARRAY_SIZE(zhihe_a210_aon_regu_desc),
};
int zhihe_match_regulator_name(struct aon_regu_desc *regus_set, const char *string)
{
int index;
const char *item;
for (index = 0; index < regus_set->regu_num; index++) {
item = regus_set->regu_desc[index].name;
if (!item)
break;
if (!strcmp(item, string))
return index;
}
return -EINVAL;
}
static int zhihe_aon_regulator_probe(struct platform_device *pdev)
{
int ret;
int index;
struct device *dev = &pdev->dev;
struct device_node *np = pdev->dev.of_node;
struct device_node *child;
struct regulator_config config = { };
struct regulator_dev *rdev;
struct regulator_desc *desc;
struct aon_regu_desc *regus_set = NULL;
const char *regulator_name;
if (!np)
return -ENODEV;
regus_set = (struct aon_regu_desc *)of_device_get_match_data(&pdev->dev);
if (!regus_set)
return -ENODEV;
/*get ipc handle */
ret = zhihe_aon_get_handle(&(zhihe_aon_pmic_info.ipc_handle), "aon0");
if (ret) {
dev_err(dev, "failed to get ipc_handle\n");
return ret;
}
/*register regulators*/
zhihe_aon_pmic_info.dev = dev;
config.dev = dev;
config.driver_data = &zhihe_aon_pmic_info;
for_each_child_of_node(np, child) {
of_property_read_string(child, "regulator-name", &regulator_name);
if (!regulator_name) {
dev_err(dev, "failed to get a regulator-name\n");
return -EINVAL;
}
index = zhihe_match_regulator_name(regus_set, regulator_name);
if (index < 0) {
dev_err(dev, "no regulator matches %s\n", regulator_name);
return -EINVAL;
}
desc = &regus_set->regu_desc[index];
desc->ops = &regu_common_ops;
config.of_node = child;
rdev = devm_regulator_register(dev, desc, &config);
if (IS_ERR(rdev)) {
dev_err(dev, "Failed to register regulator %s\n", regulator_name);
return PTR_ERR(rdev);
}
}
platform_set_drvdata(pdev, &zhihe_aon_pmic_info);
return 0;
}
static const struct of_device_id zhihe_pmic_dev_id[] = {
{ .compatible = "zhihe,a210-aon-regulator", .data = &zhihe_a210_aon_regus},
{},
};
MODULE_DEVICE_TABLE(of, zhihe_pmic_dev_id);
static struct platform_driver zhihe_aon_regulator_driver = {
.driver = {
.name = "zhihe-aon-reg",
.owner = THIS_MODULE,
.of_match_table = zhihe_pmic_dev_id,
},
.probe = zhihe_aon_regulator_probe,
};
static int __init zhihe_aon_regulator_init(void)
{
return platform_driver_register(&zhihe_aon_regulator_driver);
}
postcore_initcall(zhihe_aon_regulator_init);
static void __exit zhihe_aon_regulator_exit(void)
{
platform_driver_unregister(&zhihe_aon_regulator_driver);
}
module_exit(zhihe_aon_regulator_exit);
MODULE_AUTHOR("hongkun.xu <xuhongkun@zhcomputing.com>");
MODULE_DESCRIPTION("Zhihe Aon regulator driver");
MODULE_LICENSE("GPL");