change rk35xx edge to 5.17.y (#3614)

Co-authored-by: Jianfeng Liu <jfliu@zshield.net>
This commit is contained in:
Jianfeng Liu 2022-04-02 12:11:55 +08:00 committed by GitHub
parent 2274e2658e
commit dad2d913f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 9662 additions and 15 deletions

View File

@ -3352,7 +3352,7 @@ CONFIG_RTL8XXXU=m
# CONFIG_RTL8XXXU_UNTESTED is not set
CONFIG_RTW88=m
# CONFIG_RTW88_8822BE is not set
# CONFIG_RTW88_8822CE is not set
CONFIG_RTW88_8822CE=y
# CONFIG_RTW88_8723DE is not set
# CONFIG_RTW88_8821CE is not set
# CONFIG_RTW89 is not set
@ -3377,16 +3377,16 @@ CONFIG_WLCORE_SPI=m
CONFIG_WLCORE_SDIO=m
CONFIG_WILINK_PLATFORM_DATA=y
# CONFIG_RTL8822BS is not set
CONFIG_RTL8723DU=m
CONFIG_RTL8723DS=m
CONFIG_RTL8822CS=m
CONFIG_RTL8822BU=m
#CONFIG_RTL8723DU=m
#CONFIG_RTL8723DS=m
#CONFIG_RTL8822CS=m
#CONFIG_RTL8822BU=m
CONFIG_RTL8188EU=m
CONFIG_RTL8821CU=m
CONFIG_88XXAU=m
#CONFIG_RTL8821CU=m
#CONFIG_88XXAU=m
# CONFIG_RTL8192EU is not set
CONFIG_RTL8189FS=m
CONFIG_RTL8189ES=m
#CONFIG_RTL8189FS=m
#CONFIG_RTL8189ES=m
CONFIG_WLAN_VENDOR_ZYDAS=y
CONFIG_USB_ZD1201=m
CONFIG_ZD1211RW=m

View File

@ -21,7 +21,7 @@ case $BRANCH in
# temporary until kernel 5.16 is well supported for rockchip64
# it has to be its own family too
edge)
KERNELBRANCH="branch:linux-5.16.y"
KERNELBRANCH="branch:linux-5.17.y"
KERNELPATCHDIR='rk35xx-'$BRANCH
SKIP_BOOTSPLASH="yes"
LINUXFAMILY=rk35xx

View File

@ -0,0 +1,104 @@
diff --git a/arch/arm64/boot/dts/rockchip/rk3568.dtsi b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
index d91df1cde736..75fbf7992a6a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
@@ -23,6 +23,76 @@ qos_sata0: qos@fe190200 {
reg = <0x0 0xfe190200 0x0 0x20>;
};
+ pcie3x2: pcie@fe280000 {
+ compatible = "rockchip,rk3568-pcie", "snps,dw-pcie";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ bus-range = <0x20 0x2f>;
+ clocks = <&cru ACLK_PCIE30X2_MST>, <&cru ACLK_PCIE30X2_SLV>,
+ <&cru ACLK_PCIE30X2_DBI>, <&cru PCLK_PCIE30X2>,
+ <&cru CLK_PCIE30X2_AUX_NDFT>;
+ clock-names = "aclk_mst", "aclk_slv",
+ "aclk_dbi", "pclk", "aux";
+ device_type = "pci";
+ interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie3x2_intc 0>,
+ <0 0 0 2 &pcie3x2_intc 1>,
+ <0 0 0 3 &pcie3x2_intc 2>,
+ <0 0 0 4 &pcie3x2_intc 3>;
+ linux,pci-domain = <2>;
+ num-ib-windows = <6>;
+ num-ob-windows = <2>;
+ max-link-speed = <3>;
+ msi-map = <0x2000 &its 0x2000 0x1000>;
+ num-lanes = <2>;
+ phys = <&pcie30phy>;
+ phy-names = "pcie-phy";
+ power-domains = <&power RK3568_PD_PIPE>;
+ ranges = <0x00000800 0x0 0x80000000 0x3 0x80000000 0x0 0x800000
+ 0x81000000 0x0 0x80800000 0x3 0x80800000 0x0 0x100000
+ 0x83000000 0x0 0x80900000 0x3 0x80900000 0x0 0x3f700000>;
+ reg = <0x3 0xc0800000 0x0 0x400000>,
+ <0x0 0xfe280000 0x0 0x10000>;
+ reg-names = "pcie-dbi", "pcie-apb";
+ resets = <&cru SRST_PCIE30X2_POWERUP>;
+ reset-names = "pipe";
+ /* rockchip,bifurcation; lane0 when using 1+1 */
+ status = "disabled";
+
+ pcie3x2_intc: legacy-interrupt-controller {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 162 IRQ_TYPE_EDGE_RISING>;
+ };
+ };
+
+ pcie30phy: phy@fe8c0000 {
+ compatible = "rockchip,rk3568-pcie3-phy";
+ reg = <0x0 0xfe8c0000 0x0 0x20000>;
+ #phy-cells = <0>;
+ clocks = <&pmucru CLK_PCIE30PHY_REF_M>, <&pmucru CLK_PCIE30PHY_REF_N>,
+ <&cru PCLK_PCIE30PHY>;
+ clock-names = "refclk_m", "refclk_n", "pclk";
+ resets = <&cru SRST_PCIE30PHY>;
+ reset-names = "phy";
+ rockchip,phy-grf = <&pcie30_phy_grf>;
+ status = "disabled";
+ };
+
+ pcie30_phy_grf: syscon@fdcb8000 {
+ compatible = "rockchip,pcie30-phy-grf", "syscon";
+ reg = <0x0 0xfdcb8000 0x0 0x10000>;
+ };
+
gmac0: ethernet@fe2a0000 {
compatible = "rockchip,rk3568-gmac", "snps,dwmac-4.20a";
reg = <0x0 0xfe2a0000 0x0 0x10000>;
diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index 688e3585525a..5274a34c0fbf 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -199,9 +199,18 @@ gic: interrupt-controller@fd400000 {
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <3>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
mbi-alias = <0x0 0xfd410000>;
mbi-ranges = <296 24>;
msi-controller;
+ its: interrupt-controller@fd440000 {
+ compatible = "arm,gic-v3-its";
+ msi-controller;
+ #msi-cells = <1>;
+ reg = <0x0 0xfd440000 0x0 0x20000>;
+ };
};
pmugrf: syscon@fdc20000 {

View File

@ -9,10 +9,10 @@ index 479906f3ad7b..bf2a58e3a871 100644
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3-a.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3-a.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3-a.dts
new file mode 100644
index 000000000000..04da5128dff6
index 000000000000..9e9124dc6c59
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3-a.dts
@@ -0,0 +1,651 @@
@@ -0,0 +1,809 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
@ -70,6 +70,36 @@ index 000000000000..04da5128dff6
+ pinctrl-0 = <&user_led_enable_h>;
+ retain-state-suspended;
+ };
+
+ wifi-led {
+ gpios = <&gpio2 RK_PB0 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "rfkill2";
+ default-state = "on";
+ pinctrl-0 = <&wifi_led>;
+ };
+ };
+
+ rk809_sound: rk809-sound {
+ status = "okay";
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,name = "rockchip,rk809-codec";
+ simple-audio-card,mclk-fs = <256>;
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s1_8ch>;
+ };
+ simple-audio-card,codec {
+ sound-dai = <&rk809_codec>;
+ };
+ };
+
+ rk_headset: rk-headset {
+ compatible = "rockchip_headset";
+ headset_gpio = <&gpio2 RK_PD2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hp_det>;
+ io-channels = <&saradc 2>; //HP_HOOK pin
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
@ -262,6 +292,7 @@ index 000000000000..04da5128dff6
+ compatible = "tcs,tcs4525";
+ reg = <0x1c>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-compatible = "fan53555-reg";
+ regulator-name = "vdd_cpu";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1150000>;
@ -282,9 +313,21 @@ index 000000000000..04da5128dff6
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+ #clock-cells = <1>;
+ pinctrl-names = "default";
+ pinctrl-names = "default", "pmic-sleep",
+ "pmic-power-off", "pmic-reset";
+ pinctrl-0 = <&pmic_int>;
+ pinctrl-1 = <&soc_slppin_slp>, <&rk817_slppin_slp>;
+ pinctrl-2 = <&soc_slppin_gpio>, <&rk817_slppin_pwrdn>;
+ pinctrl-3 = <&soc_slppin_gpio>, <&rk817_slppin_rst>;
+
+ rockchip,system-power-controller;
+ clock-output-names = "rk808-clkout1", "rk808-clkout2";
+ //fb-inner-reg-idxs = <2>;
+ /* 1: rst regs (default in codes), 0: rst the pmic */
+ pmic-reset-func = <0>;
+ /* not save the PMIC_POWER_EN register in uboot */
+ not-save-power-en = <1>;
+
+ vcc1-supply = <&vcc3v3_sys>;
+ vcc2-supply = <&vcc3v3_sys>;
+ vcc3-supply = <&vcc3v3_sys>;
@ -296,6 +339,35 @@ index 000000000000..04da5128dff6
+ vcc9-supply = <&vcc3v3_sys>;
+ wakeup-source;
+
+ pwrkey {
+ status = "okay";
+ };
+
+ pinctrl_rk8xx: pinctrl_rk8xx {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ rk817_slppin_null: rk817_slppin_null {
+ pins = "gpio_slp";
+ function = "pin_fun0";
+ };
+
+ rk817_slppin_slp: rk817_slppin_slp {
+ pins = "gpio_slp";
+ function = "pin_fun1";
+ };
+
+ rk817_slppin_pwrdn: rk817_slppin_pwrdn {
+ pins = "gpio_slp";
+ function = "pin_fun2";
+ };
+
+ rk817_slppin_rst: rk817_slppin_rst {
+ pins = "gpio_slp";
+ function = "pin_fun3";
+ };
+ };
+
+ regulators {
+ vdd_logic: DCDC_REG1 {
+ regulator-name = "vdd_logic";
@ -316,6 +388,8 @@ index 000000000000..04da5128dff6
+ regulator-name = "vdd_gpu";
+ regulator-init-microvolt = <900000>;
+ regulator-initial-mode = <0x2>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
@ -338,6 +412,8 @@ index 000000000000..04da5128dff6
+
+ vdd_npu: DCDC_REG4 {
+ regulator-name = "vdd_npu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-init-microvolt = <900000>;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <500000>;
@ -363,6 +439,8 @@ index 000000000000..04da5128dff6
+
+ vdda0v9_image: LDO_REG1 {
+ regulator-name = "vdda0v9_image";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
@ -398,6 +476,8 @@ index 000000000000..04da5128dff6
+
+ vccio_acodec: LDO_REG4 {
+ regulator-name = "vccio_acodec";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
@ -408,6 +488,8 @@ index 000000000000..04da5128dff6
+
+ vccio_sd: LDO_REG5 {
+ regulator-name = "vccio_sd";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
@ -456,6 +538,8 @@ index 000000000000..04da5128dff6
+
+ vcca1v8_image: LDO_REG9 {
+ regulator-name = "vcca1v8_image";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
@ -476,12 +560,29 @@ index 000000000000..04da5128dff6
+
+ vcc3v3_sd: SWITCH_REG2 {
+ regulator-name = "vcc3v3_sd";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+
+ rk809_codec: codec {
+ #sound-dai-cells = <0>;
+ compatible = "rockchip,rk809-codec", "rockchip,rk817-codec";
+ clocks = <&cru I2S1_MCLKOUT_TX>;
+ clock-names = "mclk";
+ assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
+ assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s1m0_mclk>;
+ hp-volume = <20>;
+ spk-volume = <3>;
+ mic-in-differential;
+ status = "okay";
+ };
+ };
+};
+
@ -498,6 +599,10 @@ index 000000000000..04da5128dff6
+ user_led_enable_h: user-led-enable-h {
+ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ wifi_led: wifi-led {
+ rockchip,pins = <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ sdio-pwrseq {
@ -523,6 +628,39 @@ index 000000000000..04da5128dff6
+ rockchip,pins =
+ <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ soc_slppin_gpio: soc_slppin_gpio {
+ rockchip,pins =
+ <0 RK_PA2 RK_FUNC_GPIO &pcfg_output_low>;
+ };
+
+ soc_slppin_slp: soc_slppin_slp {
+ rockchip,pins =
+ <0 RK_PA2 1 &pcfg_pull_none>;
+ };
+
+ soc_slppin_rst: soc_slppin_rst {
+ rockchip,pins =
+ <0 RK_PA2 2 &pcfg_pull_none>;
+ };
+ };
+
+ wireless-wlan {
+ wifi_host_wake_irq: wifi-host-wake-irq {
+ rockchip,pins = <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ };
+
+ wireless-bluetooth {
+ uart1_gpios: uart1-gpios {
+ rockchip,pins = <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ headphone {
+ hp_det: hp-det {
+ rockchip,pins = <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
@ -534,7 +672,6 @@ index 000000000000..04da5128dff6
+ pmuio1-supply = <&vcc3v3_pmu>;
+ pmuio2-supply = <&vcc3v3_pmu>;
+ vccio1-supply = <&vccio_acodec>;
+ vccio2-supply = <&vcc_1v8>;
+ vccio3-supply = <&vccio_sd>;
+ vccio4-supply = <&vcc_1v8>;
+ vccio5-supply = <&vcc_3v3>;
@ -664,3 +801,24 @@ index 000000000000..04da5128dff6
+&usb_host1_ohci {
+ status = "okay";
+};
+
+&pcie30phy {
+ status = "okay";
+};
+
+&pcie3x2 {
+ reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&pcie30_3v3>;
+ //num-lanes = <2>;
+ pinctrl-0 = <&pcie30x2m1_pins>;
+ bus-scan-delay-ms = <1000>;
+ status = "okay";
+};
+
+&pcie2x1 {
+ reset-gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&pcie30_3v3>;
+ pinctrl-0 = <&pcie20m1_pins>;
+ bus-scan-delay-ms = <1000>;
+ status = "okay";
+};

View File

@ -0,0 +1,428 @@
diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index f3647b317152..7905deaf7055 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -1,9 +1,12 @@
-// SPDX-License-Identifier: GPL-2.0-only
/*
* PWM driver for Rockchip SoCs
*
* Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
* Copyright (C) 2014 ROCKCHIP, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
*/
#include <linux/clk.h>
@@ -11,6 +14,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
#include <linux/time.h>
@@ -26,15 +30,25 @@
#define PWM_INACTIVE_POSITIVE (1 << 4)
#define PWM_POLARITY_MASK (PWM_DUTY_POSITIVE | PWM_INACTIVE_POSITIVE)
#define PWM_OUTPUT_LEFT (0 << 5)
+#define PWM_OUTPUT_CENTER (1 << 5)
#define PWM_LOCK_EN (1 << 6)
#define PWM_LP_DISABLE (0 << 8)
+#define PWM_ONESHOT_COUNT_SHIFT 24
+#define PWM_ONESHOT_COUNT_MAX 256
+
struct rockchip_pwm_chip {
struct pwm_chip chip;
struct clk *clk;
struct clk *pclk;
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *active_state;
const struct rockchip_pwm_data *data;
void __iomem *base;
+ unsigned long clk_rate;
+ bool vop_pwm_en; /* indicate voppwm mirror register state */
+ bool center_aligned;
+ bool oneshot;
};
struct rockchip_pwm_regs {
@@ -49,7 +63,9 @@ struct rockchip_pwm_data {
unsigned int prescaler;
bool supports_polarity;
bool supports_lock;
+ bool vop_pwm;
u32 enable_conf;
+ u32 enable_conf_mask;
};
static inline struct rockchip_pwm_chip *to_rockchip_pwm_chip(struct pwm_chip *c)
@@ -63,7 +79,6 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
{
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
u32 enable_conf = pc->data->enable_conf;
- unsigned long clk_rate;
u64 tmp;
u32 val;
int ret;
@@ -72,59 +87,77 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
if (ret)
return;
- ret = clk_enable(pc->clk);
- if (ret)
- return;
-
- clk_rate = clk_get_rate(pc->clk);
-
tmp = readl_relaxed(pc->base + pc->data->regs.period);
tmp *= pc->data->prescaler * NSEC_PER_SEC;
- state->period = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
+ state->period = DIV_ROUND_CLOSEST_ULL(tmp, pc->clk_rate);
tmp = readl_relaxed(pc->base + pc->data->regs.duty);
tmp *= pc->data->prescaler * NSEC_PER_SEC;
- state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
+ state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, pc->clk_rate);
val = readl_relaxed(pc->base + pc->data->regs.ctrl);
- state->enabled = (val & enable_conf) == enable_conf;
-
- if (pc->data->supports_polarity && !(val & PWM_DUTY_POSITIVE))
- state->polarity = PWM_POLARITY_INVERSED;
+ if (pc->data->supports_polarity)
+ state->enabled = ((val & enable_conf) != enable_conf) ?
+ false : true;
else
- state->polarity = PWM_POLARITY_NORMAL;
+ state->enabled = ((val & enable_conf) == enable_conf) ?
+ true : false;
+
+ if (pc->data->supports_polarity) {
+ if (!(val & PWM_DUTY_POSITIVE))
+ state->polarity = PWM_POLARITY_INVERSED;
+ }
- clk_disable(pc->clk);
clk_disable(pc->pclk);
}
static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
- const struct pwm_state *state)
+ struct pwm_state *state)
{
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
unsigned long period, duty;
- u64 clk_rate, div;
+ unsigned long flags;
+ u64 div;
u32 ctrl;
- clk_rate = clk_get_rate(pc->clk);
-
/*
* Since period and duty cycle registers have a width of 32
* bits, every possible input period can be obtained using the
* default prescaler value for all practical clock rate values.
*/
- div = clk_rate * state->period;
+ div = (u64)pc->clk_rate * state->period;
period = DIV_ROUND_CLOSEST_ULL(div,
pc->data->prescaler * NSEC_PER_SEC);
- div = clk_rate * state->duty_cycle;
+ div = (u64)pc->clk_rate * state->duty_cycle;
duty = DIV_ROUND_CLOSEST_ULL(div, pc->data->prescaler * NSEC_PER_SEC);
+ local_irq_save(flags);
/*
* Lock the period and duty of previous configuration, then
* change the duty and period, that would not be effective.
*/
ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl);
+ if (pc->data->vop_pwm) {
+ if (pc->vop_pwm_en)
+ ctrl |= PWM_ENABLE;
+ else
+ ctrl &= ~PWM_ENABLE;
+ }
+
+#ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
+ if (state->oneshot_count > PWM_ONESHOT_COUNT_MAX) {
+ pc->oneshot = false;
+ dev_err(chip->dev, "Oneshot_count value overflow.\n");
+ } else if (state->oneshot_count > 0) {
+ pc->oneshot = true;
+ ctrl |= (state->oneshot_count - 1) << PWM_ONESHOT_COUNT_SHIFT;
+ } else {
+ pc->oneshot = false;
+ ctrl |= PWM_CONTINUOUS;
+ }
+#endif
+
if (pc->data->supports_lock) {
ctrl |= PWM_LOCK_EN;
writel_relaxed(ctrl, pc->base + pc->data->regs.ctrl);
@@ -150,6 +183,7 @@ static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
ctrl &= ~PWM_LOCK_EN;
writel(ctrl, pc->base + pc->data->regs.ctrl);
+ local_irq_restore(flags);
}
static int rockchip_pwm_enable(struct pwm_chip *chip,
@@ -168,13 +202,24 @@ static int rockchip_pwm_enable(struct pwm_chip *chip,
}
val = readl_relaxed(pc->base + pc->data->regs.ctrl);
+ val &= ~pc->data->enable_conf_mask;
+
+ if (PWM_OUTPUT_CENTER & pc->data->enable_conf_mask) {
+ if (pc->center_aligned)
+ val |= PWM_OUTPUT_CENTER;
+ }
- if (enable)
+ if (enable) {
val |= enable_conf;
- else
+ if (pc->oneshot)
+ val &= ~PWM_CONTINUOUS;
+ } else {
val &= ~enable_conf;
+ }
writel_relaxed(val, pc->base + pc->data->regs.ctrl);
+ if (pc->data->vop_pwm)
+ pc->vop_pwm_en = enable;
if (!enable)
clk_disable(pc->clk);
@@ -194,10 +239,6 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
if (ret)
return ret;
- ret = clk_enable(pc->clk);
- if (ret)
- return ret;
-
pwm_get_state(pwm, &curstate);
enabled = curstate.enabled;
@@ -216,8 +257,15 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
goto out;
}
+ /*
+ * Update the state with the real hardware, which can differ a bit
+ * because of period/duty_cycle approximation.
+ */
+ rockchip_pwm_get_state(chip, pwm, state);
+
+ if (state->enabled || pc->oneshot)
+ ret = pinctrl_select_state(pc->pinctrl, pc->active_state);
out:
- clk_disable(pc->clk);
clk_disable(pc->pclk);
return ret;
@@ -239,7 +287,9 @@ static const struct rockchip_pwm_data pwm_data_v1 = {
.prescaler = 2,
.supports_polarity = false,
.supports_lock = false,
+ .vop_pwm = false,
.enable_conf = PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN,
+ .enable_conf_mask = BIT(1) | BIT(3),
};
static const struct rockchip_pwm_data pwm_data_v2 = {
@@ -252,8 +302,10 @@ static const struct rockchip_pwm_data pwm_data_v2 = {
.prescaler = 1,
.supports_polarity = true,
.supports_lock = false,
+ .vop_pwm = false,
.enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
PWM_CONTINUOUS,
+ .enable_conf_mask = GENMASK(2, 0) | BIT(5) | BIT(8),
};
static const struct rockchip_pwm_data pwm_data_vop = {
@@ -266,8 +318,10 @@ static const struct rockchip_pwm_data pwm_data_vop = {
.prescaler = 1,
.supports_polarity = true,
.supports_lock = false,
+ .vop_pwm = true,
.enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
PWM_CONTINUOUS,
+ .enable_conf_mask = GENMASK(2, 0) | BIT(5) | BIT(8),
};
static const struct rockchip_pwm_data pwm_data_v3 = {
@@ -280,8 +334,10 @@ static const struct rockchip_pwm_data pwm_data_v3 = {
.prescaler = 1,
.supports_polarity = true,
.supports_lock = true,
+ .vop_pwm = false,
.enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
PWM_CONTINUOUS,
+ .enable_conf_mask = GENMASK(2, 0) | BIT(5) | BIT(8),
};
static const struct of_device_id rockchip_pwm_dt_ids[] = {
@@ -297,8 +353,7 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
{
const struct of_device_id *id;
struct rockchip_pwm_chip *pc;
- u32 enable_conf, ctrl;
- bool enabled;
+ struct resource *r;
int ret, count;
id = of_match_device(rockchip_pwm_dt_ids, &pdev->dev);
@@ -309,16 +364,22 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
if (!pc)
return -ENOMEM;
- pc->base = devm_platform_ioremap_resource(pdev, 0);
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ pc->base = devm_ioremap(&pdev->dev, r->start,
+ resource_size(r));
if (IS_ERR(pc->base))
return PTR_ERR(pc->base);
pc->clk = devm_clk_get(&pdev->dev, "pwm");
if (IS_ERR(pc->clk)) {
pc->clk = devm_clk_get(&pdev->dev, NULL);
- if (IS_ERR(pc->clk))
- return dev_err_probe(&pdev->dev, PTR_ERR(pc->clk),
- "Can't get PWM clk\n");
+ if (IS_ERR(pc->clk)) {
+ ret = PTR_ERR(pc->clk);
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "Can't get bus clk: %d\n",
+ ret);
+ return ret;
+ }
}
count = of_count_phandle_with_args(pdev->dev.of_node,
@@ -337,26 +398,44 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
ret = clk_prepare_enable(pc->clk);
if (ret) {
- dev_err(&pdev->dev, "Can't prepare enable PWM clk: %d\n", ret);
+ dev_err(&pdev->dev, "Can't prepare enable bus clk: %d\n", ret);
return ret;
}
- ret = clk_prepare_enable(pc->pclk);
+ ret = clk_prepare(pc->pclk);
if (ret) {
- dev_err(&pdev->dev, "Can't prepare enable APB clk: %d\n", ret);
+ dev_err(&pdev->dev, "Can't prepare APB clk: %d\n", ret);
goto err_clk;
}
+ pc->pinctrl = devm_pinctrl_get(&pdev->dev);
+ if (IS_ERR(pc->pinctrl)) {
+ dev_err(&pdev->dev, "Get pinctrl failed!\n");
+ return PTR_ERR(pc->pinctrl);
+ }
+
+ pc->active_state = pinctrl_lookup_state(pc->pinctrl, "active");
+ if (IS_ERR(pc->active_state)) {
+ dev_err(&pdev->dev, "No active pinctrl state\n");
+ return PTR_ERR(pc->active_state);
+ }
+
platform_set_drvdata(pdev, pc);
pc->data = id->data;
pc->chip.dev = &pdev->dev;
pc->chip.ops = &rockchip_pwm_ops;
+ pc->chip.base = -1;
pc->chip.npwm = 1;
+ pc->clk_rate = clk_get_rate(pc->clk);
- enable_conf = pc->data->enable_conf;
- ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl);
- enabled = (ctrl & enable_conf) == enable_conf;
+ if (pc->data->supports_polarity) {
+ pc->chip.of_xlate = of_pwm_xlate_with_flags;
+ pc->chip.of_pwm_n_cells = 3;
+ }
+
+ pc->center_aligned =
+ device_property_read_bool(&pdev->dev, "center-aligned");
ret = pwmchip_add(&pc->chip);
if (ret < 0) {
@@ -365,15 +444,13 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
}
/* Keep the PWM clk enabled if the PWM appears to be up and running. */
- if (!enabled)
+ if (!pwm_is_enabled(pc->chip.pwms))
clk_disable(pc->clk);
- clk_disable(pc->pclk);
-
return 0;
err_pclk:
- clk_disable_unprepare(pc->pclk);
+ clk_unprepare(pc->pclk);
err_clk:
clk_disable_unprepare(pc->clk);
@@ -384,11 +461,24 @@ static int rockchip_pwm_remove(struct platform_device *pdev)
{
struct rockchip_pwm_chip *pc = platform_get_drvdata(pdev);
- pwmchip_remove(&pc->chip);
+ /*
+ * Disable the PWM clk before unpreparing it if the PWM device is still
+ * running. This should only happen when the last PWM user left it
+ * enabled, or when nobody requested a PWM that was previously enabled
+ * by the bootloader.
+ *
+ * FIXME: Maybe the core should disable all PWM devices in
+ * pwmchip_remove(). In this case we'd only have to call
+ * clk_unprepare() after pwmchip_remove().
+ *
+ */
+ if (pwm_is_enabled(pc->chip.pwms))
+ clk_disable(pc->clk);
clk_unprepare(pc->pclk);
clk_unprepare(pc->clk);
+ pwmchip_remove(&pc->chip);
return 0;
}
@@ -400,7 +490,21 @@ static struct platform_driver rockchip_pwm_driver = {
.probe = rockchip_pwm_probe,
.remove = rockchip_pwm_remove,
};
+#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT
+static int __init rockchip_pwm_driver_init(void)
+{
+ return platform_driver_register(&rockchip_pwm_driver);
+}
+subsys_initcall(rockchip_pwm_driver_init);
+
+static void __exit rockchip_pwm_driver_exit(void)
+{
+ platform_driver_unregister(&rockchip_pwm_driver);
+}
+module_exit(rockchip_pwm_driver_exit);
+#else
module_platform_driver(rockchip_pwm_driver);
+#endif
MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>");
MODULE_DESCRIPTION("Rockchip SoC PWM driver");

View File

@ -0,0 +1,12 @@
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index d1f865b8c0cb..998845187686 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -295,6 +295,7 @@ quiet_cmd_gzip = GZIP $@
# ---------------------------------------------------------------------------
DTC ?= $(objtree)/scripts/dtc/dtc
DTC_FLAGS += -Wno-interrupt_provider
+DTC_FLAGS += -@
# Disable noisy checks by default
ifeq ($(findstring 1,$(KBUILD_EXTRA_WARN)),)

View File

@ -0,0 +1,287 @@
From 3ec70749ae3cb072f19d886981a217121f776415 Mon Sep 17 00:00:00 2001
From: Igor Pecovnik <igor.pecovnik@gmail.com>
Date: Sat, 6 Nov 2021 19:15:23 +0100
Subject: [PATCH] Revert "net: Remove net/ipx.h and uapi/linux/ipx.h header
files"
This reverts commit 6c9b40844751ea30c72f7a2f92f4d704bc6b2927.
---
include/net/ipx.h | 171 +++++++++++++++++++++++++++++++++++++++
include/uapi/linux/ipx.h | 87 ++++++++++++++++++++
2 files changed, 258 insertions(+)
create mode 100644 include/net/ipx.h
create mode 100644 include/uapi/linux/ipx.h
diff --git a/include/net/ipx.h b/include/net/ipx.h
new file mode 100644
index 000000000000..9d1342807b59
--- /dev/null
+++ b/include/net/ipx.h
@@ -0,0 +1,171 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _NET_INET_IPX_H_
+#define _NET_INET_IPX_H_
+/*
+ * The following information is in its entirety obtained from:
+ *
+ * Novell 'IPX Router Specification' Version 1.10
+ * Part No. 107-000029-001
+ *
+ * Which is available from ftp.novell.com
+ */
+
+#include <linux/netdevice.h>
+#include <net/datalink.h>
+#include <linux/ipx.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/refcount.h>
+
+struct ipx_address {
+ __be32 net;
+ __u8 node[IPX_NODE_LEN];
+ __be16 sock;
+};
+
+#define ipx_broadcast_node "\377\377\377\377\377\377"
+#define ipx_this_node "\0\0\0\0\0\0"
+
+#define IPX_MAX_PPROP_HOPS 8
+
+struct ipxhdr {
+ __be16 ipx_checksum __packed;
+#define IPX_NO_CHECKSUM cpu_to_be16(0xFFFF)
+ __be16 ipx_pktsize __packed;
+ __u8 ipx_tctrl;
+ __u8 ipx_type;
+#define IPX_TYPE_UNKNOWN 0x00
+#define IPX_TYPE_RIP 0x01 /* may also be 0 */
+#define IPX_TYPE_SAP 0x04 /* may also be 0 */
+#define IPX_TYPE_SPX 0x05 /* SPX protocol */
+#define IPX_TYPE_NCP 0x11 /* $lots for docs on this (SPIT) */
+#define IPX_TYPE_PPROP 0x14 /* complicated flood fill brdcast */
+ struct ipx_address ipx_dest __packed;
+ struct ipx_address ipx_source __packed;
+};
+
+/* From af_ipx.c */
+extern int sysctl_ipx_pprop_broadcasting;
+
+struct ipx_interface {
+ /* IPX address */
+ __be32 if_netnum;
+ unsigned char if_node[IPX_NODE_LEN];
+ refcount_t refcnt;
+
+ /* physical device info */
+ struct net_device *if_dev;
+ struct datalink_proto *if_dlink;
+ __be16 if_dlink_type;
+
+ /* socket support */
+ unsigned short if_sknum;
+ struct hlist_head if_sklist;
+ spinlock_t if_sklist_lock;
+
+ /* administrative overhead */
+ int if_ipx_offset;
+ unsigned char if_internal;
+ unsigned char if_primary;
+
+ struct list_head node; /* node in ipx_interfaces list */
+};
+
+struct ipx_route {
+ __be32 ir_net;
+ struct ipx_interface *ir_intrfc;
+ unsigned char ir_routed;
+ unsigned char ir_router_node[IPX_NODE_LEN];
+ struct list_head node; /* node in ipx_routes list */
+ refcount_t refcnt;
+};
+
+struct ipx_cb {
+ u8 ipx_tctrl;
+ __be32 ipx_dest_net;
+ __be32 ipx_source_net;
+ struct {
+ __be32 netnum;
+ int index;
+ } last_hop;
+};
+
+#include <net/sock.h>
+
+struct ipx_sock {
+ /* struct sock has to be the first member of ipx_sock */
+ struct sock sk;
+ struct ipx_address dest_addr;
+ struct ipx_interface *intrfc;
+ __be16 port;
+#ifdef CONFIG_IPX_INTERN
+ unsigned char node[IPX_NODE_LEN];
+#endif
+ unsigned short type;
+ /*
+ * To handle special ncp connection-handling sockets for mars_nwe,
+ * the connection number must be stored in the socket.
+ */
+ unsigned short ipx_ncp_conn;
+};
+
+static inline struct ipx_sock *ipx_sk(struct sock *sk)
+{
+ return (struct ipx_sock *)sk;
+}
+
+#define IPX_SKB_CB(__skb) ((struct ipx_cb *)&((__skb)->cb[0]))
+
+#define IPX_MIN_EPHEMERAL_SOCKET 0x4000
+#define IPX_MAX_EPHEMERAL_SOCKET 0x7fff
+
+extern struct list_head ipx_routes;
+extern rwlock_t ipx_routes_lock;
+
+extern struct list_head ipx_interfaces;
+struct ipx_interface *ipx_interfaces_head(void);
+extern spinlock_t ipx_interfaces_lock;
+
+extern struct ipx_interface *ipx_primary_net;
+
+int ipx_proc_init(void);
+void ipx_proc_exit(void);
+
+const char *ipx_frame_name(__be16);
+const char *ipx_device_name(struct ipx_interface *intrfc);
+
+static __inline__ void ipxitf_hold(struct ipx_interface *intrfc)
+{
+ refcount_inc(&intrfc->refcnt);
+}
+
+void ipxitf_down(struct ipx_interface *intrfc);
+struct ipx_interface *ipxitf_find_using_net(__be32 net);
+int ipxitf_send(struct ipx_interface *intrfc, struct sk_buff *skb, char *node);
+__be16 ipx_cksum(struct ipxhdr *packet, int length);
+int ipxrtr_add_route(__be32 network, struct ipx_interface *intrfc,
+ unsigned char *node);
+void ipxrtr_del_routes(struct ipx_interface *intrfc);
+int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx,
+ struct msghdr *msg, size_t len, int noblock);
+int ipxrtr_route_skb(struct sk_buff *skb);
+struct ipx_route *ipxrtr_lookup(__be32 net);
+int ipxrtr_ioctl(unsigned int cmd, void __user *arg);
+
+static __inline__ void ipxitf_put(struct ipx_interface *intrfc)
+{
+ if (refcount_dec_and_test(&intrfc->refcnt))
+ ipxitf_down(intrfc);
+}
+
+static __inline__ void ipxrtr_hold(struct ipx_route *rt)
+{
+ refcount_inc(&rt->refcnt);
+}
+
+static __inline__ void ipxrtr_put(struct ipx_route *rt)
+{
+ if (refcount_dec_and_test(&rt->refcnt))
+ kfree(rt);
+}
+#endif /* _NET_INET_IPX_H_ */
diff --git a/include/uapi/linux/ipx.h b/include/uapi/linux/ipx.h
new file mode 100644
index 000000000000..3168137adae8
--- /dev/null
+++ b/include/uapi/linux/ipx.h
@@ -0,0 +1,87 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _IPX_H_
+#define _IPX_H_
+#include <linux/libc-compat.h> /* for compatibility with glibc netipx/ipx.h */
+#include <linux/types.h>
+#include <linux/sockios.h>
+#include <linux/socket.h>
+#define IPX_NODE_LEN 6
+#define IPX_MTU 576
+
+#if __UAPI_DEF_SOCKADDR_IPX
+struct sockaddr_ipx {
+ __kernel_sa_family_t sipx_family;
+ __be16 sipx_port;
+ __be32 sipx_network;
+ unsigned char sipx_node[IPX_NODE_LEN];
+ __u8 sipx_type;
+ unsigned char sipx_zero; /* 16 byte fill */
+};
+#endif /* __UAPI_DEF_SOCKADDR_IPX */
+
+/*
+ * So we can fit the extra info for SIOCSIFADDR into the address nicely
+ */
+#define sipx_special sipx_port
+#define sipx_action sipx_zero
+#define IPX_DLTITF 0
+#define IPX_CRTITF 1
+
+#if __UAPI_DEF_IPX_ROUTE_DEFINITION
+struct ipx_route_definition {
+ __be32 ipx_network;
+ __be32 ipx_router_network;
+ unsigned char ipx_router_node[IPX_NODE_LEN];
+};
+#endif /* __UAPI_DEF_IPX_ROUTE_DEFINITION */
+
+#if __UAPI_DEF_IPX_INTERFACE_DEFINITION
+struct ipx_interface_definition {
+ __be32 ipx_network;
+ unsigned char ipx_device[16];
+ unsigned char ipx_dlink_type;
+#define IPX_FRAME_NONE 0
+#define IPX_FRAME_SNAP 1
+#define IPX_FRAME_8022 2
+#define IPX_FRAME_ETHERII 3
+#define IPX_FRAME_8023 4
+#define IPX_FRAME_TR_8022 5 /* obsolete */
+ unsigned char ipx_special;
+#define IPX_SPECIAL_NONE 0
+#define IPX_PRIMARY 1
+#define IPX_INTERNAL 2
+ unsigned char ipx_node[IPX_NODE_LEN];
+};
+#endif /* __UAPI_DEF_IPX_INTERFACE_DEFINITION */
+
+#if __UAPI_DEF_IPX_CONFIG_DATA
+struct ipx_config_data {
+ unsigned char ipxcfg_auto_select_primary;
+ unsigned char ipxcfg_auto_create_interfaces;
+};
+#endif /* __UAPI_DEF_IPX_CONFIG_DATA */
+
+/*
+ * OLD Route Definition for backward compatibility.
+ */
+
+#if __UAPI_DEF_IPX_ROUTE_DEF
+struct ipx_route_def {
+ __be32 ipx_network;
+ __be32 ipx_router_network;
+#define IPX_ROUTE_NO_ROUTER 0
+ unsigned char ipx_router_node[IPX_NODE_LEN];
+ unsigned char ipx_device[16];
+ unsigned short ipx_flags;
+#define IPX_RT_SNAP 8
+#define IPX_RT_8022 4
+#define IPX_RT_BLUEBOOK 2
+#define IPX_RT_ROUTED 1
+};
+#endif /* __UAPI_DEF_IPX_ROUTE_DEF */
+
+#define SIOCAIPXITFCRT (SIOCPROTOPRIVATE)
+#define SIOCAIPXPRISLT (SIOCPROTOPRIVATE + 1)
+#define SIOCIPXCFGDATA (SIOCPROTOPRIVATE + 2)
+#define SIOCIPXNCPCONN (SIOCPROTOPRIVATE + 3)
+#endif /* _IPX_H_ */
--
2.25.1

View File

@ -0,0 +1,104 @@
diff --git a/arch/arm64/boot/dts/rockchip/rk3568.dtsi b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
index d91df1cde736..75fbf7992a6a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
@@ -23,6 +23,76 @@ qos_sata0: qos@fe190200 {
reg = <0x0 0xfe190200 0x0 0x20>;
};
+ pcie3x2: pcie@fe280000 {
+ compatible = "rockchip,rk3568-pcie", "snps,dw-pcie";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ bus-range = <0x20 0x2f>;
+ clocks = <&cru ACLK_PCIE30X2_MST>, <&cru ACLK_PCIE30X2_SLV>,
+ <&cru ACLK_PCIE30X2_DBI>, <&cru PCLK_PCIE30X2>,
+ <&cru CLK_PCIE30X2_AUX_NDFT>;
+ clock-names = "aclk_mst", "aclk_slv",
+ "aclk_dbi", "pclk", "aux";
+ device_type = "pci";
+ interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie3x2_intc 0>,
+ <0 0 0 2 &pcie3x2_intc 1>,
+ <0 0 0 3 &pcie3x2_intc 2>,
+ <0 0 0 4 &pcie3x2_intc 3>;
+ linux,pci-domain = <2>;
+ num-ib-windows = <6>;
+ num-ob-windows = <2>;
+ max-link-speed = <3>;
+ msi-map = <0x2000 &its 0x2000 0x1000>;
+ num-lanes = <2>;
+ phys = <&pcie30phy>;
+ phy-names = "pcie-phy";
+ power-domains = <&power RK3568_PD_PIPE>;
+ ranges = <0x00000800 0x0 0x80000000 0x3 0x80000000 0x0 0x800000
+ 0x81000000 0x0 0x80800000 0x3 0x80800000 0x0 0x100000
+ 0x83000000 0x0 0x80900000 0x3 0x80900000 0x0 0x3f700000>;
+ reg = <0x3 0xc0800000 0x0 0x400000>,
+ <0x0 0xfe280000 0x0 0x10000>;
+ reg-names = "pcie-dbi", "pcie-apb";
+ resets = <&cru SRST_PCIE30X2_POWERUP>;
+ reset-names = "pipe";
+ /* rockchip,bifurcation; lane0 when using 1+1 */
+ status = "disabled";
+
+ pcie3x2_intc: legacy-interrupt-controller {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 162 IRQ_TYPE_EDGE_RISING>;
+ };
+ };
+
+ pcie30phy: phy@fe8c0000 {
+ compatible = "rockchip,rk3568-pcie3-phy";
+ reg = <0x0 0xfe8c0000 0x0 0x20000>;
+ #phy-cells = <0>;
+ clocks = <&pmucru CLK_PCIE30PHY_REF_M>, <&pmucru CLK_PCIE30PHY_REF_N>,
+ <&cru PCLK_PCIE30PHY>;
+ clock-names = "refclk_m", "refclk_n", "pclk";
+ resets = <&cru SRST_PCIE30PHY>;
+ reset-names = "phy";
+ rockchip,phy-grf = <&pcie30_phy_grf>;
+ status = "disabled";
+ };
+
+ pcie30_phy_grf: syscon@fdcb8000 {
+ compatible = "rockchip,pcie30-phy-grf", "syscon";
+ reg = <0x0 0xfdcb8000 0x0 0x10000>;
+ };
+
gmac0: ethernet@fe2a0000 {
compatible = "rockchip,rk3568-gmac", "snps,dwmac-4.20a";
reg = <0x0 0xfe2a0000 0x0 0x10000>;
diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index 688e3585525a..5274a34c0fbf 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -199,9 +199,18 @@ gic: interrupt-controller@fd400000 {
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <3>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
mbi-alias = <0x0 0xfd410000>;
mbi-ranges = <296 24>;
msi-controller;
+ its: interrupt-controller@fd440000 {
+ compatible = "arm,gic-v3-its";
+ msi-controller;
+ #msi-cells = <1>;
+ reg = <0x0 0xfd440000 0x0 0x20000>;
+ };
};
pmugrf: syscon@fdc20000 {

View File

@ -0,0 +1,824 @@
diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index 479906f3ad7b..bf2a58e3a871 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -58,3 +58,4 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire-excavator.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399pro-rock-pi-n10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-a.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3-a.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3-a.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3-a.dts
new file mode 100644
index 000000000000..9e9124dc6c59
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3-a.dts
@@ -0,0 +1,809 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include "rk3568.dtsi"
+
+/ {
+ model = "Radxa Rock3A";
+ compatible = "radxa,rk3568-rock-3a", "rockchip,rk3568";
+
+ aliases {
+ ethernet1 = &gmac1;
+ mmc0 = &sdmmc0;
+ mmc1 = &sdhci;
+ };
+
+ chosen: chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ gmac1_clkin: external-gmac1-clock {
+ compatible = "fixed-clock";
+ clock-frequency = <125000000>;
+ clock-output-names = "gmac1_clkin";
+ #clock-cells = <0>;
+ };
+
+ hdmi-con {
+ compatible = "hdmi-connector";
+ type = "c";
+
+ port {
+ hdmi_con_in: endpoint {
+ remote-endpoint = <&hdmi_out_con>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-user {
+ label = "user-led";
+ default-state = "on";
+ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ pinctrl-names = "default";
+ pinctrl-0 = <&user_led_enable_h>;
+ retain-state-suspended;
+ };
+
+ wifi-led {
+ gpios = <&gpio2 RK_PB0 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "rfkill2";
+ default-state = "on";
+ pinctrl-0 = <&wifi_led>;
+ };
+ };
+
+ rk809_sound: rk809-sound {
+ status = "okay";
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,name = "rockchip,rk809-codec";
+ simple-audio-card,mclk-fs = <256>;
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s1_8ch>;
+ };
+ simple-audio-card,codec {
+ sound-dai = <&rk809_codec>;
+ };
+ };
+
+ rk_headset: rk-headset {
+ compatible = "rockchip_headset";
+ headset_gpio = <&gpio2 RK_PD2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hp_det>;
+ io-channels = <&saradc 2>; //HP_HOOK pin
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ status = "okay";
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&rk809 1>;
+ clock-names = "ext_clock";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_enable_h>;
+ reset-gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_LOW>;
+ };
+
+ dc_12v: dc-12v {
+ compatible = "regulator-fixed";
+ regulator-name = "dc_12v";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ };
+
+ vcc3v3_sys: vcc3v3-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&dc_12v>;
+ };
+
+ vcc5v0_sys: vcc5v0-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&dc_12v>;
+ };
+
+ vcc5v0_host: vcc5v0-host {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_host";
+ enable-active-high;
+ gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_host_en>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc5v0_otg: vcc5v0-otg {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_otg";
+ enable-active-high;
+ gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_otg_en>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc5v0_hub: vcc5v0-hub {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_hub";
+ enable-active-high;
+ gpio = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_hub_en>;
+ regulator-always-on;
+ };
+
+ pcie30_avdd0v9: pcie30-avdd0v9 {
+ compatible = "regulator-fixed";
+ regulator-name = "pcie30_avdd0v9";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+ vin-supply = <&vcc3v3_sys>;
+ };
+
+ pcie30_avdd1v8: pcie30-avdd1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "pcie30_avdd1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc3v3_sys>;
+ };
+
+ pcie30_3v3: gpio-regulator {
+ compatible = "regulator-gpio";
+ regulator-name = "pcie30_3v3";
+ regulator-min-microvolt = <100000>;
+ regulator-max-microvolt = <3300000>;
+ gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;
+ gpios-states = <0x1>;
+ states = <100000 0x0
+ 3300000 0x1>;
+ };
+
+ vcc3v3_lcd0_n: vcc3v3-lcd0-n {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_lcd0_n";
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc3v3_lcd1_n: vcc3v3-lcd1-n {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_lcd1_n";
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+
+};
+
+&combphy0 {
+ status = "okay";
+};
+
+&combphy1 {
+ status = "okay";
+};
+
+&combphy2 {
+ status = "okay";
+};
+
+&gmac1 {
+ phy-mode = "rgmii";
+ clock_in_out = "input";
+
+ snps,reset-gpio = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>;
+ snps,reset-active-low;
+ /* Reset time is 20ms, 100ms for rtl8211f */
+ snps,reset-delays-us = <0 20000 100000>;
+
+ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
+ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&gmac1_clkin>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac1m1_miim
+ &gmac1m1_tx_bus2
+ &gmac1m1_rx_bus2
+ &gmac1m1_rgmii_clk
+ &gmac1m1_rgmii_bus
+ &gmac1m1_clkinout>;
+
+ tx_delay = <0x4f>;
+ rx_delay = <0x26>;
+
+ phy-handle = <&rgmii_phy1>;
+ status = "okay";
+};
+
+&hdmi {
+ avdd-0v9-supply = <&vdda0v9_image>;
+ avdd-1v8-supply = <&vcca1v8_image>;
+ status = "okay";
+};
+
+&hdmi_in {
+ hdmi_in_vp0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&vp0_out_hdmi>;
+ };
+};
+
+&hdmi_out {
+ hdmi_out_con: endpoint {
+ remote-endpoint = <&hdmi_con_in>;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+
+ vdd_cpu: regulator@1c {
+ compatible = "tcs,tcs4525";
+ reg = <0x1c>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-compatible = "fan53555-reg";
+ regulator-name = "vdd_cpu";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-ramp-delay = <2300>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+
+ rk809: pmic@20 {
+ compatible = "rockchip,rk809";
+ reg = <0x20>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+ #clock-cells = <1>;
+ pinctrl-names = "default", "pmic-sleep",
+ "pmic-power-off", "pmic-reset";
+ pinctrl-0 = <&pmic_int>;
+ pinctrl-1 = <&soc_slppin_slp>, <&rk817_slppin_slp>;
+ pinctrl-2 = <&soc_slppin_gpio>, <&rk817_slppin_pwrdn>;
+ pinctrl-3 = <&soc_slppin_gpio>, <&rk817_slppin_rst>;
+
+ rockchip,system-power-controller;
+ clock-output-names = "rk808-clkout1", "rk808-clkout2";
+ //fb-inner-reg-idxs = <2>;
+ /* 1: rst regs (default in codes), 0: rst the pmic */
+ pmic-reset-func = <0>;
+ /* not save the PMIC_POWER_EN register in uboot */
+ not-save-power-en = <1>;
+
+ vcc1-supply = <&vcc3v3_sys>;
+ vcc2-supply = <&vcc3v3_sys>;
+ vcc3-supply = <&vcc3v3_sys>;
+ vcc4-supply = <&vcc3v3_sys>;
+ vcc5-supply = <&vcc3v3_sys>;
+ vcc6-supply = <&vcc3v3_sys>;
+ vcc7-supply = <&vcc3v3_sys>;
+ vcc8-supply = <&vcc3v3_sys>;
+ vcc9-supply = <&vcc3v3_sys>;
+ wakeup-source;
+
+ pwrkey {
+ status = "okay";
+ };
+
+ pinctrl_rk8xx: pinctrl_rk8xx {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ rk817_slppin_null: rk817_slppin_null {
+ pins = "gpio_slp";
+ function = "pin_fun0";
+ };
+
+ rk817_slppin_slp: rk817_slppin_slp {
+ pins = "gpio_slp";
+ function = "pin_fun1";
+ };
+
+ rk817_slppin_pwrdn: rk817_slppin_pwrdn {
+ pins = "gpio_slp";
+ function = "pin_fun2";
+ };
+
+ rk817_slppin_rst: rk817_slppin_rst {
+ pins = "gpio_slp";
+ function = "pin_fun3";
+ };
+ };
+
+ regulators {
+ vdd_logic: DCDC_REG1 {
+ regulator-name = "vdd_logic";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-init-microvolt = <900000>;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_gpu: DCDC_REG2 {
+ regulator-name = "vdd_gpu";
+ regulator-init-microvolt = <900000>;
+ regulator-initial-mode = <0x2>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_ddr: DCDC_REG3 {
+ regulator-name = "vcc_ddr";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vdd_npu: DCDC_REG4 {
+ regulator-name = "vdd_npu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-init-microvolt = <900000>;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8: DCDC_REG5 {
+ regulator-name = "vcc_1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda0v9_image: LDO_REG1 {
+ regulator-name = "vdda0v9_image";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda_0v9: LDO_REG2 {
+ regulator-name = "vdda_0v9";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda0v9_pmu: LDO_REG3 {
+ regulator-name = "vdda0v9_pmu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <900000>;
+ };
+ };
+
+ vccio_acodec: LDO_REG4 {
+ regulator-name = "vccio_acodec";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd: LDO_REG5 {
+ regulator-name = "vccio_sd";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc3v3_pmu: LDO_REG6 {
+ regulator-name = "vcc3v3_pmu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcca_1v8: LDO_REG7 {
+ regulator-name = "vcca_1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcca1v8_pmu: LDO_REG8 {
+ regulator-name = "vcca1v8_pmu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vcca1v8_image: LDO_REG9 {
+ regulator-name = "vcca1v8_image";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3: SWITCH_REG1 {
+ regulator-name = "vcc_3v3";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc3v3_sd: SWITCH_REG2 {
+ regulator-name = "vcc3v3_sd";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+
+ rk809_codec: codec {
+ #sound-dai-cells = <0>;
+ compatible = "rockchip,rk809-codec", "rockchip,rk817-codec";
+ clocks = <&cru I2S1_MCLKOUT_TX>;
+ clock-names = "mclk";
+ assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
+ assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s1m0_mclk>;
+ hp-volume = <20>;
+ spk-volume = <3>;
+ mic-in-differential;
+ status = "okay";
+ };
+ };
+};
+
+
+&mdio1 {
+ rgmii_phy1: phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x0>;
+ };
+};
+
+&pinctrl {
+ leds {
+ user_led_enable_h: user-led-enable-h {
+ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ wifi_led: wifi-led {
+ rockchip,pins = <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ sdio-pwrseq {
+ wifi_enable_h: wifi-enable-h {
+ rockchip,pins = <3 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb {
+ vcc5v0_host_en: vcc5v0-host-en {
+ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ vcc5v0_otg_en: vcc5v0-otg-en {
+ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ vcc5v0_hub_en: vcc5v0-hub-en {
+ rockchip,pins = <0 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pmic {
+ pmic_int: pmic_int {
+ rockchip,pins =
+ <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ soc_slppin_gpio: soc_slppin_gpio {
+ rockchip,pins =
+ <0 RK_PA2 RK_FUNC_GPIO &pcfg_output_low>;
+ };
+
+ soc_slppin_slp: soc_slppin_slp {
+ rockchip,pins =
+ <0 RK_PA2 1 &pcfg_pull_none>;
+ };
+
+ soc_slppin_rst: soc_slppin_rst {
+ rockchip,pins =
+ <0 RK_PA2 2 &pcfg_pull_none>;
+ };
+ };
+
+ wireless-wlan {
+ wifi_host_wake_irq: wifi-host-wake-irq {
+ rockchip,pins = <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ };
+
+ wireless-bluetooth {
+ uart1_gpios: uart1-gpios {
+ rockchip,pins = <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ headphone {
+ hp_det: hp-det {
+ rockchip,pins = <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
+&i2s0_8ch {
+ status = "okay";
+};
+
+&pmu_io_domains {
+ pmuio1-supply = <&vcc3v3_pmu>;
+ pmuio2-supply = <&vcc3v3_pmu>;
+ vccio1-supply = <&vccio_acodec>;
+ vccio3-supply = <&vccio_sd>;
+ vccio4-supply = <&vcc_1v8>;
+ vccio5-supply = <&vcc_3v3>;
+ vccio6-supply = <&vcc_1v8>;
+ vccio7-supply = <&vcc_3v3>;
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&vcca_1v8>;
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ max-frequency = <200000000>;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
+ status = "okay";
+};
+
+&sdmmc0 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc3v3_sd>;
+ vqmmc-supply = <&vccio_sd>;
+ status = "okay";
+};
+
+&tsadc {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&vop {
+ status = "okay";
+ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
+ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
+};
+
+&vop_mmu {
+ status = "okay";
+};
+
+&vp0 {
+ vp0_out_hdmi: endpoint@RK3568_VOP2_EP_HDMI {
+ reg = <RK3568_VOP2_EP_HDMI>;
+ remote-endpoint = <&hdmi_in_vp0>;
+ };
+};
+
+&hdmi_sound {
+ status = "okay";
+};
+
+&gpu {
+ mali-supply = <&vdd_gpu>;
+ status = "okay";
+};
+
+&u2phy0_host {
+ phy-supply = <&vcc5v0_host>;
+ status = "okay";
+};
+
+&u2phy0_otg {
+ vbus-supply = <&vcc5v0_otg>;
+ status = "okay";
+};
+
+&u2phy1_host {
+ phy-supply = <&vcc5v0_host>;
+ status = "okay";
+};
+
+&u2phy1_otg {
+ phy-supply = <&vcc5v0_host>;
+ status = "okay";
+};
+
+&u2phy0 {
+ status = "okay";
+};
+
+&u2phy1 {
+ status = "okay";
+};
+
+&usbdrd_dwc3 {
+ status = "okay";
+ extcon = <&u2phy0>;
+};
+
+&usbdrd30 {
+ status = "okay";
+};
+
+&usbhost_dwc3 {
+ status = "okay";
+};
+
+&usbhost30 {
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
+
+&pcie30phy {
+ status = "okay";
+};
+
+&pcie3x2 {
+ reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&pcie30_3v3>;
+ //num-lanes = <2>;
+ pinctrl-0 = <&pcie30x2m1_pins>;
+ bus-scan-delay-ms = <1000>;
+ status = "okay";
+};
+
+&pcie2x1 {
+ reset-gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&pcie30_3v3>;
+ pinctrl-0 = <&pcie20m1_pins>;
+ bus-scan-delay-ms = <1000>;
+ status = "okay";
+};

View File

@ -0,0 +1,428 @@
diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index f3647b317152..7905deaf7055 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -1,9 +1,12 @@
-// SPDX-License-Identifier: GPL-2.0-only
/*
* PWM driver for Rockchip SoCs
*
* Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
* Copyright (C) 2014 ROCKCHIP, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
*/
#include <linux/clk.h>
@@ -11,6 +14,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
#include <linux/time.h>
@@ -26,15 +30,25 @@
#define PWM_INACTIVE_POSITIVE (1 << 4)
#define PWM_POLARITY_MASK (PWM_DUTY_POSITIVE | PWM_INACTIVE_POSITIVE)
#define PWM_OUTPUT_LEFT (0 << 5)
+#define PWM_OUTPUT_CENTER (1 << 5)
#define PWM_LOCK_EN (1 << 6)
#define PWM_LP_DISABLE (0 << 8)
+#define PWM_ONESHOT_COUNT_SHIFT 24
+#define PWM_ONESHOT_COUNT_MAX 256
+
struct rockchip_pwm_chip {
struct pwm_chip chip;
struct clk *clk;
struct clk *pclk;
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *active_state;
const struct rockchip_pwm_data *data;
void __iomem *base;
+ unsigned long clk_rate;
+ bool vop_pwm_en; /* indicate voppwm mirror register state */
+ bool center_aligned;
+ bool oneshot;
};
struct rockchip_pwm_regs {
@@ -49,7 +63,9 @@ struct rockchip_pwm_data {
unsigned int prescaler;
bool supports_polarity;
bool supports_lock;
+ bool vop_pwm;
u32 enable_conf;
+ u32 enable_conf_mask;
};
static inline struct rockchip_pwm_chip *to_rockchip_pwm_chip(struct pwm_chip *c)
@@ -63,7 +79,6 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
{
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
u32 enable_conf = pc->data->enable_conf;
- unsigned long clk_rate;
u64 tmp;
u32 val;
int ret;
@@ -72,59 +87,77 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
if (ret)
return;
- ret = clk_enable(pc->clk);
- if (ret)
- return;
-
- clk_rate = clk_get_rate(pc->clk);
-
tmp = readl_relaxed(pc->base + pc->data->regs.period);
tmp *= pc->data->prescaler * NSEC_PER_SEC;
- state->period = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
+ state->period = DIV_ROUND_CLOSEST_ULL(tmp, pc->clk_rate);
tmp = readl_relaxed(pc->base + pc->data->regs.duty);
tmp *= pc->data->prescaler * NSEC_PER_SEC;
- state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
+ state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, pc->clk_rate);
val = readl_relaxed(pc->base + pc->data->regs.ctrl);
- state->enabled = (val & enable_conf) == enable_conf;
-
- if (pc->data->supports_polarity && !(val & PWM_DUTY_POSITIVE))
- state->polarity = PWM_POLARITY_INVERSED;
+ if (pc->data->supports_polarity)
+ state->enabled = ((val & enable_conf) != enable_conf) ?
+ false : true;
else
- state->polarity = PWM_POLARITY_NORMAL;
+ state->enabled = ((val & enable_conf) == enable_conf) ?
+ true : false;
+
+ if (pc->data->supports_polarity) {
+ if (!(val & PWM_DUTY_POSITIVE))
+ state->polarity = PWM_POLARITY_INVERSED;
+ }
- clk_disable(pc->clk);
clk_disable(pc->pclk);
}
static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
- const struct pwm_state *state)
+ struct pwm_state *state)
{
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
unsigned long period, duty;
- u64 clk_rate, div;
+ unsigned long flags;
+ u64 div;
u32 ctrl;
- clk_rate = clk_get_rate(pc->clk);
-
/*
* Since period and duty cycle registers have a width of 32
* bits, every possible input period can be obtained using the
* default prescaler value for all practical clock rate values.
*/
- div = clk_rate * state->period;
+ div = (u64)pc->clk_rate * state->period;
period = DIV_ROUND_CLOSEST_ULL(div,
pc->data->prescaler * NSEC_PER_SEC);
- div = clk_rate * state->duty_cycle;
+ div = (u64)pc->clk_rate * state->duty_cycle;
duty = DIV_ROUND_CLOSEST_ULL(div, pc->data->prescaler * NSEC_PER_SEC);
+ local_irq_save(flags);
/*
* Lock the period and duty of previous configuration, then
* change the duty and period, that would not be effective.
*/
ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl);
+ if (pc->data->vop_pwm) {
+ if (pc->vop_pwm_en)
+ ctrl |= PWM_ENABLE;
+ else
+ ctrl &= ~PWM_ENABLE;
+ }
+
+#ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
+ if (state->oneshot_count > PWM_ONESHOT_COUNT_MAX) {
+ pc->oneshot = false;
+ dev_err(chip->dev, "Oneshot_count value overflow.\n");
+ } else if (state->oneshot_count > 0) {
+ pc->oneshot = true;
+ ctrl |= (state->oneshot_count - 1) << PWM_ONESHOT_COUNT_SHIFT;
+ } else {
+ pc->oneshot = false;
+ ctrl |= PWM_CONTINUOUS;
+ }
+#endif
+
if (pc->data->supports_lock) {
ctrl |= PWM_LOCK_EN;
writel_relaxed(ctrl, pc->base + pc->data->regs.ctrl);
@@ -150,6 +183,7 @@ static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
ctrl &= ~PWM_LOCK_EN;
writel(ctrl, pc->base + pc->data->regs.ctrl);
+ local_irq_restore(flags);
}
static int rockchip_pwm_enable(struct pwm_chip *chip,
@@ -168,13 +202,24 @@ static int rockchip_pwm_enable(struct pwm_chip *chip,
}
val = readl_relaxed(pc->base + pc->data->regs.ctrl);
+ val &= ~pc->data->enable_conf_mask;
+
+ if (PWM_OUTPUT_CENTER & pc->data->enable_conf_mask) {
+ if (pc->center_aligned)
+ val |= PWM_OUTPUT_CENTER;
+ }
- if (enable)
+ if (enable) {
val |= enable_conf;
- else
+ if (pc->oneshot)
+ val &= ~PWM_CONTINUOUS;
+ } else {
val &= ~enable_conf;
+ }
writel_relaxed(val, pc->base + pc->data->regs.ctrl);
+ if (pc->data->vop_pwm)
+ pc->vop_pwm_en = enable;
if (!enable)
clk_disable(pc->clk);
@@ -194,10 +239,6 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
if (ret)
return ret;
- ret = clk_enable(pc->clk);
- if (ret)
- return ret;
-
pwm_get_state(pwm, &curstate);
enabled = curstate.enabled;
@@ -216,8 +257,15 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
goto out;
}
+ /*
+ * Update the state with the real hardware, which can differ a bit
+ * because of period/duty_cycle approximation.
+ */
+ rockchip_pwm_get_state(chip, pwm, state);
+
+ if (state->enabled || pc->oneshot)
+ ret = pinctrl_select_state(pc->pinctrl, pc->active_state);
out:
- clk_disable(pc->clk);
clk_disable(pc->pclk);
return ret;
@@ -239,7 +287,9 @@ static const struct rockchip_pwm_data pwm_data_v1 = {
.prescaler = 2,
.supports_polarity = false,
.supports_lock = false,
+ .vop_pwm = false,
.enable_conf = PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN,
+ .enable_conf_mask = BIT(1) | BIT(3),
};
static const struct rockchip_pwm_data pwm_data_v2 = {
@@ -252,8 +302,10 @@ static const struct rockchip_pwm_data pwm_data_v2 = {
.prescaler = 1,
.supports_polarity = true,
.supports_lock = false,
+ .vop_pwm = false,
.enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
PWM_CONTINUOUS,
+ .enable_conf_mask = GENMASK(2, 0) | BIT(5) | BIT(8),
};
static const struct rockchip_pwm_data pwm_data_vop = {
@@ -266,8 +318,10 @@ static const struct rockchip_pwm_data pwm_data_vop = {
.prescaler = 1,
.supports_polarity = true,
.supports_lock = false,
+ .vop_pwm = true,
.enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
PWM_CONTINUOUS,
+ .enable_conf_mask = GENMASK(2, 0) | BIT(5) | BIT(8),
};
static const struct rockchip_pwm_data pwm_data_v3 = {
@@ -280,8 +334,10 @@ static const struct rockchip_pwm_data pwm_data_v3 = {
.prescaler = 1,
.supports_polarity = true,
.supports_lock = true,
+ .vop_pwm = false,
.enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
PWM_CONTINUOUS,
+ .enable_conf_mask = GENMASK(2, 0) | BIT(5) | BIT(8),
};
static const struct of_device_id rockchip_pwm_dt_ids[] = {
@@ -297,8 +353,7 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
{
const struct of_device_id *id;
struct rockchip_pwm_chip *pc;
- u32 enable_conf, ctrl;
- bool enabled;
+ struct resource *r;
int ret, count;
id = of_match_device(rockchip_pwm_dt_ids, &pdev->dev);
@@ -309,16 +364,22 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
if (!pc)
return -ENOMEM;
- pc->base = devm_platform_ioremap_resource(pdev, 0);
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ pc->base = devm_ioremap(&pdev->dev, r->start,
+ resource_size(r));
if (IS_ERR(pc->base))
return PTR_ERR(pc->base);
pc->clk = devm_clk_get(&pdev->dev, "pwm");
if (IS_ERR(pc->clk)) {
pc->clk = devm_clk_get(&pdev->dev, NULL);
- if (IS_ERR(pc->clk))
- return dev_err_probe(&pdev->dev, PTR_ERR(pc->clk),
- "Can't get PWM clk\n");
+ if (IS_ERR(pc->clk)) {
+ ret = PTR_ERR(pc->clk);
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "Can't get bus clk: %d\n",
+ ret);
+ return ret;
+ }
}
count = of_count_phandle_with_args(pdev->dev.of_node,
@@ -337,26 +398,44 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
ret = clk_prepare_enable(pc->clk);
if (ret) {
- dev_err(&pdev->dev, "Can't prepare enable PWM clk: %d\n", ret);
+ dev_err(&pdev->dev, "Can't prepare enable bus clk: %d\n", ret);
return ret;
}
- ret = clk_prepare_enable(pc->pclk);
+ ret = clk_prepare(pc->pclk);
if (ret) {
- dev_err(&pdev->dev, "Can't prepare enable APB clk: %d\n", ret);
+ dev_err(&pdev->dev, "Can't prepare APB clk: %d\n", ret);
goto err_clk;
}
+ pc->pinctrl = devm_pinctrl_get(&pdev->dev);
+ if (IS_ERR(pc->pinctrl)) {
+ dev_err(&pdev->dev, "Get pinctrl failed!\n");
+ return PTR_ERR(pc->pinctrl);
+ }
+
+ pc->active_state = pinctrl_lookup_state(pc->pinctrl, "active");
+ if (IS_ERR(pc->active_state)) {
+ dev_err(&pdev->dev, "No active pinctrl state\n");
+ return PTR_ERR(pc->active_state);
+ }
+
platform_set_drvdata(pdev, pc);
pc->data = id->data;
pc->chip.dev = &pdev->dev;
pc->chip.ops = &rockchip_pwm_ops;
+ pc->chip.base = -1;
pc->chip.npwm = 1;
+ pc->clk_rate = clk_get_rate(pc->clk);
- enable_conf = pc->data->enable_conf;
- ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl);
- enabled = (ctrl & enable_conf) == enable_conf;
+ if (pc->data->supports_polarity) {
+ pc->chip.of_xlate = of_pwm_xlate_with_flags;
+ pc->chip.of_pwm_n_cells = 3;
+ }
+
+ pc->center_aligned =
+ device_property_read_bool(&pdev->dev, "center-aligned");
ret = pwmchip_add(&pc->chip);
if (ret < 0) {
@@ -365,15 +444,13 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
}
/* Keep the PWM clk enabled if the PWM appears to be up and running. */
- if (!enabled)
+ if (!pwm_is_enabled(pc->chip.pwms))
clk_disable(pc->clk);
- clk_disable(pc->pclk);
-
return 0;
err_pclk:
- clk_disable_unprepare(pc->pclk);
+ clk_unprepare(pc->pclk);
err_clk:
clk_disable_unprepare(pc->clk);
@@ -384,11 +461,24 @@ static int rockchip_pwm_remove(struct platform_device *pdev)
{
struct rockchip_pwm_chip *pc = platform_get_drvdata(pdev);
- pwmchip_remove(&pc->chip);
+ /*
+ * Disable the PWM clk before unpreparing it if the PWM device is still
+ * running. This should only happen when the last PWM user left it
+ * enabled, or when nobody requested a PWM that was previously enabled
+ * by the bootloader.
+ *
+ * FIXME: Maybe the core should disable all PWM devices in
+ * pwmchip_remove(). In this case we'd only have to call
+ * clk_unprepare() after pwmchip_remove().
+ *
+ */
+ if (pwm_is_enabled(pc->chip.pwms))
+ clk_disable(pc->clk);
clk_unprepare(pc->pclk);
clk_unprepare(pc->clk);
+ pwmchip_remove(&pc->chip);
return 0;
}
@@ -400,7 +490,21 @@ static struct platform_driver rockchip_pwm_driver = {
.probe = rockchip_pwm_probe,
.remove = rockchip_pwm_remove,
};
+#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT
+static int __init rockchip_pwm_driver_init(void)
+{
+ return platform_driver_register(&rockchip_pwm_driver);
+}
+subsys_initcall(rockchip_pwm_driver_init);
+
+static void __exit rockchip_pwm_driver_exit(void)
+{
+ platform_driver_unregister(&rockchip_pwm_driver);
+}
+module_exit(rockchip_pwm_driver_exit);
+#else
module_platform_driver(rockchip_pwm_driver);
+#endif
MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>");
MODULE_DESCRIPTION("Rockchip SoC PWM driver");

View File

@ -0,0 +1,12 @@
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index d1f865b8c0cb..998845187686 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -295,6 +295,7 @@ quiet_cmd_gzip = GZIP $@
# ---------------------------------------------------------------------------
DTC ?= $(objtree)/scripts/dtc/dtc
DTC_FLAGS += -Wno-interrupt_provider
+DTC_FLAGS += -@
# Disable noisy checks by default
ifeq ($(findstring 1,$(KBUILD_EXTRA_WARN)),)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,180 @@
diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml b/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml
index 63a08f3f321d..4d6bfae0653c 100644
--- a/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml
+++ b/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml
@@ -159,6 +159,21 @@ allOf:
power-domains:
maxItems: 1
sram-supply: false
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: rockchip,rk3568-mali
+ then:
+ properties:
+ clocks:
+ minItems: 2
+ clock-names:
+ items:
+ - const: gpu
+ - const: bus
+ required:
+ - clock-names
examples:
- |
diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index ff1689283996..50bbea862a6a 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -144,6 +144,40 @@ scmi_clk: protocol@14 {
};
};
+ gpu_opp_table: opp-table-1 {
+ compatible = "operating-points-v2";
+
+ opp-200000000 {
+ opp-hz = /bits/ 64 <200000000>;
+ opp-microvolt = <825000>;
+ };
+
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ opp-microvolt = <825000>;
+ };
+
+ opp-400000000 {
+ opp-hz = /bits/ 64 <400000000>;
+ opp-microvolt = <825000>;
+ };
+
+ opp-600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ opp-microvolt = <825000>;
+ };
+
+ opp-700000000 {
+ opp-hz = /bits/ 64 <700000000>;
+ opp-microvolt = <900000>;
+ };
+
+ opp-800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-microvolt = <1000000>;
+ };
+ };
+
pmu {
compatible = "arm,cortex-a55-pmu";
interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>,
@@ -444,6 +478,21 @@ power-domain@RK3568_PD_RKVENC {
};
};
+ gpu: gpu@fde60000 {
+ compatible = "rockchip,rk3568-mali", "arm,mali-bifrost";
+ reg = <0x0 0xfde60000 0x0 0x4000>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "job", "mmu", "gpu";
+ clocks = <&scmi_clk 1>, <&cru CLK_GPU>;
+ clock-names = "gpu", "bus";
+ #cooling-cells = <2>;
+ operating-points-v2 = <&gpu_opp_table>;
+ power-domains = <&power RK3568_PD_GPU>;
+ status = "disabled";
+ };
+
sdmmc2: mmc@fe000000 {
compatible = "rockchip,rk3568-dw-mshc", "rockchip,rk3288-dw-mshc";
reg = <0x0 0xfe000000 0x0 0x4000>;
diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index 50bbea862a6a..37194d735028 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -1093,6 +1093,33 @@ gpu_thermal: gpu-thermal {
polling-delay = <1000>; /* milliseconds */
thermal-sensors = <&tsadc 1>;
+
+ trips {
+ gpu_threshold: gpu-threshold {
+ temperature = <70000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ gpu_target: gpu-target {
+ temperature = <75000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ gpu_crit: gpu-crit {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&gpu_target>;
+ cooling-device =
+ <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
};
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
index 3e65465ac7d5..b048db6cff3a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
@@ -221,6 +221,11 @@ &gmac1m0_clkinout
status = "okay";
};
+&gpu {
+ mali-supply = <&vdd_gpu>;
+ status = "okay";
+};
+
&i2c0 {
status = "okay";
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
index d8a4f7a9f562..39c495ff0157 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -140,6 +140,11 @@ &gmac1m1_rgmii_clk
status = "okay";
};
+&gpu {
+ mali-supply = <&vdd_gpu>;
+ status = "okay";
+};
+
&i2c0 {
status = "okay";
@@ -462,6 +467,12 @@ &sdmmc0 {
status = "okay";
};
+&tsadc {
+ rockchip,hw-tshut-mode = <1>;
+ rockchip,hw-tshut-polarity = <0>;
+ status = "okay";
+};
+
&uart2 {
status = "okay";
};

View File

@ -0,0 +1,103 @@
This adds the i2s0 node and an hdmi-sound sound device to the
rk356x device tree. On the rk356[68], the i2s0 controller is
connected to HDMI audio.
Tested-by: Michael Riesch <michael.riesch@wolfvision.net>
Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas@gmail.com>
---
Changes in v2:
- reordered nodes to conform
- reordered properties to conform
- add Michael Riesch's Tested-by
arch/arm64/boot/dts/rockchip/rk356x.dtsi | 33 ++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index 3c09cf6d4c37..aafb622dfa83 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -174,6 +174,22 @@ scmi_clk: protocol@14 {
};
};
+ hdmi_sound: hdmi-sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "HDMI";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,mclk-fs = <256>;
+ status = "disabled";
+
+ simple-audio-card,codec {
+ sound-dai = <&hdmi>;
+ };
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s0_8ch>;
+ };
+ };
+
pmu {
compatible = "arm,cortex-a55-pmu";
interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>,
@@ -789,6 +805,23 @@ spdif: spdif@fe460000 {
status = "disabled";
};
+ i2s0_8ch: i2s@fe400000 {
+ compatible = "rockchip,rk3568-i2s-tdm";
+ reg = <0x0 0xfe400000 0x0 0x1000>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ assigned-clocks = <&cru CLK_I2S0_8CH_TX_SRC>, <&cru CLK_I2S0_8CH_RX_SRC>;
+ assigned-clock-rates = <1188000000>, <1188000000>;
+ clocks = <&cru MCLK_I2S0_8CH_TX>, <&cru MCLK_I2S0_8CH_RX>, <&cru HCLK_I2S0_8CH>;
+ clock-names = "mclk_tx", "mclk_rx", "hclk";
+ dmas = <&dmac1 0>;
+ dma-names = "tx";
+ resets = <&cru SRST_M_I2S0_8CH_TX>, <&cru SRST_M_I2S0_8CH_RX>;
+ reset-names = "tx-m", "rx-m";
+ rockchip,grf = <&grf>;
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
i2s1_8ch: i2s@fe410000 {
compatible = "rockchip,rk3568-i2s-tdm";
reg = <0x0 0xfe410000 0x0 0x1000>;
This enables the i2s0 controller and the hdmi-sound node on
the PINE64 Quartz64 Model A single-board computer.
Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas@gmail.com>
---
arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
index a4453c82b03d..0598510dce58 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
@@ -215,6 +215,10 @@ &hdmi_in_vp0 {
status = "okay";
};
+&hdmi_sound {
+ status = "okay";
+};
+
&gpu {
mali-supply = <&vdd_gpu>;
status = "okay";
@@ -444,6 +448,10 @@ regulator-state-mem {
};
};
+&i2s0_8ch {
+ status = "okay";
+};
+
&i2s1_8ch {
pinctrl-names = "default";
pinctrl-0 = <&i2s1m0_sclktx

View File

@ -0,0 +1,95 @@
diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
index b181fe401330..874d461dda44 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
+#include <linux/reboot.h>
struct rk808_reg_data {
int addr;
@@ -543,6 +544,7 @@ static void rk808_pm_power_off(void)
reg = RK808_DEVCTRL_REG,
bit = DEV_OFF_RST;
break;
+ case RK809_ID:
case RK817_ID:
reg = RK817_SYS_CFG(3);
bit = DEV_OFF;
@@ -559,6 +561,34 @@ static void rk808_pm_power_off(void)
dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n");
}
+static int rk808_restart_notify(struct notifier_block *this, unsigned long mode, void *cmd)
+{
+ struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
+ unsigned int reg, bit;
+ int ret;
+
+ switch (rk808->variant) {
+ case RK809_ID:
+ case RK817_ID:
+ reg = RK817_SYS_CFG(3);
+ bit = DEV_RST;
+ break;
+
+ default:
+ return NOTIFY_DONE;
+ }
+ ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
+ if (ret)
+ dev_err(&rk808_i2c_client->dev, "Failed to restart device!\n");
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block rk808_restart_handler = {
+ .notifier_call = rk808_restart_notify,
+ .priority = 192,
+};
+
static void rk8xx_shutdown(struct i2c_client *client)
{
struct rk808 *rk808 = i2c_get_clientdata(client);
@@ -727,6 +757,18 @@ static int rk808_probe(struct i2c_client *client,
if (of_property_read_bool(np, "rockchip,system-power-controller")) {
rk808_i2c_client = client;
pm_power_off = rk808_pm_power_off;
+
+ switch (rk808->variant) {
+ case RK809_ID:
+ case RK817_ID:
+ ret = register_restart_handler(&rk808_restart_handler);
+ if (ret)
+ dev_warn(&client->dev, "failed to register restart handler, %d\n", ret);
+ break;
+ default:
+ dev_dbg(&client->dev, "pmic controlled board reset not supported\n");
+ break;
+ }
}
return 0;
@@ -749,6 +791,8 @@ static int rk808_remove(struct i2c_client *client)
if (pm_power_off == rk808_pm_power_off)
pm_power_off = NULL;
+ unregister_restart_handler(&rk808_restart_handler);
+
return 0;
}
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index a96e6d43ca06..58602032e642 100644
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -373,6 +373,7 @@ enum rk805_reg {
#define SWITCH2_EN BIT(6)
#define SWITCH1_EN BIT(5)
#define DEV_OFF_RST BIT(3)
+#define DEV_RST BIT(2)
#define DEV_OFF BIT(0)
#define RTC_STOP BIT(0)

View File

@ -0,0 +1,987 @@
From: Johan Jonker <jbx6244@gmail.com>
Add naneng combo phy register compatible.
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Johan Jonker <jbx6244@gmail.com>
Signed-off-by: Yifeng Zhao <yifeng.zhao@rock-chips.com>
---
Changes in v7: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None
Documentation/devicetree/bindings/mfd/syscon.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
index fdd96e378df0..e9bb96ab9446 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.yaml
+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
@@ -52,6 +52,8 @@ properties:
- rockchip,rk3288-qos
- rockchip,rk3368-qos
- rockchip,rk3399-qos
+ - rockchip,rk3568-pipe-grf
+ - rockchip,rk3568-pipe-phy-grf
- rockchip,rk3568-qos
- samsung,exynos3-sysreg
- samsung,exynos4-sysreg
Add the compatible strings for the Naneng combo PHY found on rockchip SoC.
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Yifeng Zhao <yifeng.zhao@rock-chips.com>
Signed-off-by: Johan Jonker <jbx6244@gmail.com>
---
Changes in v7:
- remove u3otg0_port_en, u3otg1_port_en and pipe_sgmii_mac_sel
Changes in v5:
- modify description for ssc and ext-refclk
- remove apb reset
Changes in v4:
- restyle
- remove some minItems
- add more properties
- remove reset-names
- move #phy-cells
- add rockchip,rk3568-pipe-grf
- add rockchip,rk3568-pipe-phy-grf
Changes in v3: None
Changes in v2:
- Fix dtschema/dtc warnings/errors
.../phy/phy-rockchip-naneng-combphy.yaml | 109 ++++++++++++++++++
1 file changed, 109 insertions(+)
create mode 100644 Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml
diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml
new file mode 100644
index 000000000000..f14454401419
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml
@@ -0,0 +1,109 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/phy-rockchip-naneng-combphy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip SoC Naneng Combo Phy Device Tree Bindings
+
+maintainers:
+ - Heiko Stuebner <heiko@sntech.de>
+
+properties:
+ compatible:
+ enum:
+ - rockchip,rk3568-naneng-combphy
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: reference clock
+ - description: apb clock
+ - description: pipe clock
+
+ clock-names:
+ items:
+ - const: ref
+ - const: apb
+ - const: pipe
+
+ resets:
+ items:
+ - description: exclusive PHY reset line
+
+ rockchip,enable-ssc:
+ type: boolean
+ description:
+ The option SSC can be enabled for U3, SATA and PCIE.
+ Most commercially available platforms use SSC to reduce EMI.
+
+ rockchip,ext-refclk:
+ type: boolean
+ description:
+ Many PCIe connections, especially backplane connections,
+ require a synchronous reference clock between the two link partners.
+ To achieve this a common clock source, referred to as REFCLK in
+ the PCI Express Card Electromechanical Specification,
+ should be used by both ends of the PCIe link.
+ In PCIe mode one can choose to use an internal or an external reference
+ clock.
+ By default the internal clock is selected. The PCIe PHY provides a 100MHz
+ differential clock output(optional with SSC) for system applications.
+ When selecting this option an externally 100MHz differential
+ reference clock needs to be provided to the PCIe PHY.
+
+ rockchip,pipe-grf:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description:
+ Some additional phy settings are accessed through GRF regs.
+
+ rockchip,pipe-phy-grf:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description:
+ Some additional pipe settings are accessed through GRF regs.
+
+ "#phy-cells":
+ const: 1
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - resets
+ - rockchip,pipe-grf
+ - rockchip,pipe-phy-grf
+ - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/rk3568-cru.h>
+
+ pipegrf: syscon@fdc50000 {
+ compatible = "rockchip,rk3568-pipe-grf", "syscon";
+ reg = <0xfdc50000 0x1000>;
+ };
+
+ pipe_phy_grf0: syscon@fdc70000 {
+ compatible = "rockchip,rk3568-pipe-phy-grf", "syscon";
+ reg = <0xfdc70000 0x1000>;
+ };
+
+ combphy0: phy@fe820000 {
+ compatible = "rockchip,rk3568-naneng-combphy";
+ reg = <0xfe820000 0x100>;
+ clocks = <&pmucru CLK_PCIEPHY0_REF>,
+ <&cru PCLK_PIPEPHY0>,
+ <&cru PCLK_PIPE>;
+ clock-names = "ref", "apb", "pipe";
+ assigned-clocks = <&pmucru CLK_PCIEPHY0_REF>;
+ assigned-clock-rates = <100000000>;
+ resets = <&cru SRST_PIPEPHY0>;
+ rockchip,pipe-grf = <&pipegrf>;
+ rockchip,pipe-phy-grf = <&pipe_phy_grf0>;
+ #phy-cells = <1>;
+ };
This patch implements a combo phy driver for Rockchip SoCs
with NaNeng IP block. This phy can be used as pcie-phy, usb3-phy,
sata-phy or sgmii-phy.
Signed-off-by: Yifeng Zhao <yifeng.zhao@rock-chips.com>
Signed-off-by: Johan Jonker <jbx6244@gmail.com>
---
Changes in v7:
- rename regs
- remove pipe_sgmii_mac_sel, u3otg0_port_en and u3otg1_port_en
Changes in v5:
- add rockchip_combphy_updatel()
- restyle
Changes in v4:
- restyle
- add devm_reset_control_array_get()
- remove clk structure
- change refclk DT parse
- change dev_err message
- add dot to phrase
- add ext_refclk variable
- add enable_ssc variable
- rename rockchip_combphy_param_write
- remove param_read
- replace rockchip-naneng-combphy driver name
Changes in v3:
- Using api devm_reset_control_get_optional_exclusive and dev_err_probe.
- Remove apb_rst.
- Redefine registers address.
Changes in v2:
- Using api devm_platform_get_and_ioremap_resource.
- Modify rockchip_combphy_set_Mode.
- Add some PHY registers definition.
drivers/phy/rockchip/Kconfig | 8 +
drivers/phy/rockchip/Makefile | 1 +
.../rockchip/phy-rockchip-naneng-combphy.c | 589 ++++++++++++++++++
3 files changed, 598 insertions(+)
create mode 100644 drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
index e812adad7242..9022e395c056 100644
--- a/drivers/phy/rockchip/Kconfig
+++ b/drivers/phy/rockchip/Kconfig
@@ -66,6 +66,14 @@ config PHY_ROCKCHIP_INNO_DSIDPHY
Enable this to support the Rockchip MIPI/LVDS/TTL PHY with
Innosilicon IP block.
+config PHY_ROCKCHIP_NANENG_COMBO_PHY
+ tristate "Rockchip NANENG COMBO PHY Driver"
+ depends on ARCH_ROCKCHIP && OF
+ select GENERIC_PHY
+ help
+ Enable this to support the Rockchip PCIe/USB3.0/SATA/QSGMII
+ combo PHY with NaNeng IP block.
+
config PHY_ROCKCHIP_PCIE
tristate "Rockchip PCIe PHY Driver"
depends on (ARCH_ROCKCHIP && OF) || COMPILE_TEST
diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile
index f0eec212b2aa..a5041efb5b8f 100644
--- a/drivers/phy/rockchip/Makefile
+++ b/drivers/phy/rockchip/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY) += phy-rockchip-inno-csidphy.o
obj-$(CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY) += phy-rockchip-inno-dsidphy.o
obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += phy-rockchip-inno-hdmi.o
obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o
+obj-$(CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY) += phy-rockchip-naneng-combphy.o
obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o
obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o
obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o
diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
new file mode 100644
index 000000000000..47137a5c448a
--- /dev/null
+++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
@@ -0,0 +1,589 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip PIPE USB3.0 PCIE SATA Combo Phy driver
+ *
+ * Copyright (C) 2021 Rockchip Electronics Co., Ltd.
+ */
+
+#include <dt-bindings/phy/phy.h>
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of_device.h>
+#include <linux/phy/phy.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/units.h>
+
+#define BIT_WRITEABLE_SHIFT 16
+#define REF_CLOCK_24MHz (24 * HZ_PER_MHZ)
+#define REF_CLOCK_25MHz (25 * HZ_PER_MHZ)
+#define REF_CLOCK_100MHz (100 * HZ_PER_MHZ)
+
+/* COMBO PHY REG */
+#define PHYREG6 0x14
+#define PHYREG6_PLL_DIV_MASK GENMASK(7, 6)
+#define PHYREG6_PLL_DIV_SHIFT 6
+#define PHYREG6_PLL_DIV_2 1
+
+#define PHYREG7 0x18
+#define PHYREG7_TX_RTERM_MASK GENMASK(7, 4)
+#define PHYREG7_TX_RTERM_SHIFT 4
+#define PHYREG7_TX_RTERM_50OHM 8
+#define PHYREG7_RX_RTERM_MASK GENMASK(3, 0)
+#define PHYREG7_RX_RTERM_SHIFT 0
+#define PHYREG7_RX_RTERM_44OHM 15
+
+#define PHYREG8 0x1C
+#define PHYREG8_SSC_EN BIT(4)
+
+#define PHYREG11 0x28
+#define PHYREG11_SU_TRIM_0_7 0xF0
+
+#define PHYREG12 0x2C
+#define PHYREG12_PLL_LPF_ADJ_VALUE 4
+
+#define PHYREG13 0x30
+#define PHYREG13_RESISTER_MASK GENMASK(5, 4)
+#define PHYREG13_RESISTER_SHIFT 0x4
+#define PHYREG13_RESISTER_HIGH_Z 3
+#define PHYREG13_CKRCV_AMP0 BIT(7)
+
+#define PHYREG14 0x34
+#define PHYREG14_CKRCV_AMP1 BIT(0)
+
+#define PHYREG15 0x38
+#define PHYREG15_CTLE_EN BIT(0)
+#define PHYREG15_SSC_CNT_MASK GENMASK(7, 6)
+#define PHYREG15_SSC_CNT_SHIFT 6
+#define PHYREG15_SSC_CNT_VALUE 1
+
+#define PHYREG16 0x3C
+#define PHYREG16_SSC_CNT_VALUE 0x5f
+
+#define PHYREG18 0x44
+#define PHYREG18_PLL_LOOP 0x32
+
+#define PHYREG32 0x7C
+#define PHYREG32_SSC_MASK GENMASK(7, 4)
+#define PHYREG32_SSC_DIR_SHIFT 4
+#define PHYREG32_SSC_UPWARD 0
+#define PHYREG32_SSC_DOWNWARD 1
+#define PHYREG32_SSC_OFFSET_SHIFT 6
+#define PHYREG32_SSC_OFFSET_500PPM 1
+
+#define PHYREG33 0x80
+#define PHYREG33_PLL_KVCO_MASK GENMASK(4, 2)
+#define PHYREG33_PLL_KVCO_SHIFT 2
+#define PHYREG33_PLL_KVCO_VALUE 2
+
+struct rockchip_combphy_priv;
+
+struct combphy_reg {
+ u16 offset;
+ u16 bitend;
+ u16 bitstart;
+ u16 disable;
+ u16 enable;
+};
+
+struct rockchip_combphy_grfcfg {
+ struct combphy_reg pcie_mode_set;
+ struct combphy_reg usb_mode_set;
+ struct combphy_reg sgmii_mode_set;
+ struct combphy_reg qsgmii_mode_set;
+ struct combphy_reg pipe_rxterm_set;
+ struct combphy_reg pipe_txelec_set;
+ struct combphy_reg pipe_txcomp_set;
+ struct combphy_reg pipe_clk_25m;
+ struct combphy_reg pipe_clk_100m;
+ struct combphy_reg pipe_phymode_sel;
+ struct combphy_reg pipe_rate_sel;
+ struct combphy_reg pipe_rxterm_sel;
+ struct combphy_reg pipe_txelec_sel;
+ struct combphy_reg pipe_txcomp_sel;
+ struct combphy_reg pipe_clk_ext;
+ struct combphy_reg pipe_sel_usb;
+ struct combphy_reg pipe_sel_qsgmii;
+ struct combphy_reg pipe_phy_status;
+ struct combphy_reg con0_for_pcie;
+ struct combphy_reg con1_for_pcie;
+ struct combphy_reg con2_for_pcie;
+ struct combphy_reg con3_for_pcie;
+ struct combphy_reg con0_for_sata;
+ struct combphy_reg con1_for_sata;
+ struct combphy_reg con2_for_sata;
+ struct combphy_reg con3_for_sata;
+ struct combphy_reg pipe_con0_for_sata;
+ struct combphy_reg pipe_xpcs_phy_ready;
+};
+
+struct rockchip_combphy_cfg {
+ const struct rockchip_combphy_grfcfg *grfcfg;
+ int (*combphy_cfg)(struct rockchip_combphy_priv *priv);
+};
+
+struct rockchip_combphy_priv {
+ u8 mode;
+ void __iomem *mmio;
+ int num_clks;
+ struct clk_bulk_data *clks;
+ struct device *dev;
+ struct regmap *pipe_grf;
+ struct regmap *phy_grf;
+ struct phy *phy;
+ struct reset_control *phy_rst;
+ const struct rockchip_combphy_cfg *cfg;
+ bool enable_ssc;
+ bool ext_refclk;
+ struct clk *refclk;
+};
+
+static void rockchip_combphy_updatel(struct rockchip_combphy_priv *priv,
+ int mask, int val, int reg)
+{
+ unsigned int temp;
+
+ temp = readl(priv->mmio + reg);
+ temp = (temp & ~(mask)) | val;
+ writel(temp, priv->mmio + reg);
+}
+
+static int rockchip_combphy_param_write(struct regmap *base,
+ const struct combphy_reg *reg, bool en)
+{
+ u32 val, mask, tmp;
+
+ tmp = en ? reg->enable : reg->disable;
+ mask = GENMASK(reg->bitend, reg->bitstart);
+ val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);
+
+ return regmap_write(base, reg->offset, val);
+}
+
+static u32 rockchip_combphy_is_ready(struct rockchip_combphy_priv *priv)
+{
+ const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
+ u32 mask, val;
+
+ mask = GENMASK(cfg->pipe_phy_status.bitend,
+ cfg->pipe_phy_status.bitstart);
+
+ regmap_read(priv->phy_grf, cfg->pipe_phy_status.offset, &val);
+ val = (val & mask) >> cfg->pipe_phy_status.bitstart;
+
+ return val;
+}
+
+static int rockchip_combphy_set_mode(struct rockchip_combphy_priv *priv)
+{
+ int ret = 0;
+
+ switch (priv->mode) {
+ case PHY_TYPE_PCIE:
+ case PHY_TYPE_USB3:
+ case PHY_TYPE_SATA:
+ case PHY_TYPE_SGMII:
+ case PHY_TYPE_QSGMII:
+ if (priv->cfg->combphy_cfg)
+ ret = priv->cfg->combphy_cfg(priv);
+ break;
+ default:
+ dev_err(priv->dev, "incompatible PHY type\n");
+ return -EINVAL;
+ }
+
+ if (ret)
+ dev_err(priv->dev, "failed to init phy for phy mode %x\n", priv->mode);
+
+ return ret;
+}
+
+static int rockchip_combphy_init(struct phy *phy)
+{
+ struct rockchip_combphy_priv *priv = phy_get_drvdata(phy);
+ const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
+ u32 val;
+ int ret;
+
+ ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks);
+ if (ret) {
+ dev_err(priv->dev, "failed to enable clks\n");
+ return ret;
+ }
+
+ ret = rockchip_combphy_set_mode(priv);
+ if (ret)
+ goto err_clk;
+
+ ret = reset_control_deassert(priv->phy_rst);
+ if (ret)
+ goto err_clk;
+
+ if (priv->mode == PHY_TYPE_USB3) {
+ ret = readx_poll_timeout_atomic(rockchip_combphy_is_ready,
+ priv, val,
+ val == cfg->pipe_phy_status.enable,
+ 10, 1000);
+ if (ret)
+ dev_warn(priv->dev, "wait phy status ready timeout\n");
+ }
+
+ return 0;
+
+err_clk:
+ clk_bulk_disable_unprepare(priv->num_clks, priv->clks);
+
+ return ret;
+}
+
+static int rockchip_combphy_exit(struct phy *phy)
+{
+ struct rockchip_combphy_priv *priv = phy_get_drvdata(phy);
+
+ clk_bulk_disable_unprepare(priv->num_clks, priv->clks);
+ reset_control_assert(priv->phy_rst);
+
+ return 0;
+}
+
+static const struct phy_ops rochchip_combphy_ops = {
+ .init = rockchip_combphy_init,
+ .exit = rockchip_combphy_exit,
+ .owner = THIS_MODULE,
+};
+
+static struct phy *rockchip_combphy_xlate(struct device *dev, struct of_phandle_args *args)
+{
+ struct rockchip_combphy_priv *priv = dev_get_drvdata(dev);
+
+ if (args->args_count != 1) {
+ dev_err(dev, "invalid number of arguments\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (priv->mode != PHY_NONE && priv->mode != args->args[0])
+ dev_warn(dev, "phy type select %d overwriting type %d\n",
+ args->args[0], priv->mode);
+
+ priv->mode = args->args[0];
+
+ return priv->phy;
+}
+
+static int rockchip_combphy_parse_dt(struct device *dev, struct rockchip_combphy_priv *priv)
+{
+ int i;
+
+ priv->num_clks = devm_clk_bulk_get_all(dev, &priv->clks);
+ if (priv->num_clks < 1)
+ return -EINVAL;
+
+ priv->refclk = NULL;
+ for (i = 0; i < priv->num_clks; i++) {
+ if (!strncmp(priv->clks[i].id, "ref", 3)) {
+ priv->refclk = priv->clks[i].clk;
+ break;
+ }
+ }
+
+ if (!priv->refclk) {
+ dev_err(dev, "no refclk found\n");
+ return -EINVAL;
+ }
+
+ priv->pipe_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pipe-grf");
+ if (IS_ERR(priv->pipe_grf)) {
+ dev_err(dev, "failed to find peri_ctrl pipe-grf regmap\n");
+ return PTR_ERR(priv->pipe_grf);
+ }
+
+ priv->phy_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pipe-phy-grf");
+ if (IS_ERR(priv->phy_grf)) {
+ dev_err(dev, "failed to find peri_ctrl pipe-phy-grf regmap\n");
+ return PTR_ERR(priv->phy_grf);
+ }
+
+ priv->enable_ssc = device_property_present(dev, "rockchip,enable-ssc");
+
+ priv->ext_refclk = device_property_present(dev, "rockchip,ext-refclk");
+
+ priv->phy_rst = devm_reset_control_array_get(dev, false, false);
+ if (IS_ERR(priv->phy_rst))
+ return dev_err_probe(dev, PTR_ERR(priv->phy_rst), "failed to get phy reset\n");
+
+ return 0;
+}
+
+static int rockchip_combphy_probe(struct platform_device *pdev)
+{
+ struct phy_provider *phy_provider;
+ struct device *dev = &pdev->dev;
+ struct rockchip_combphy_priv *priv;
+ const struct rockchip_combphy_cfg *phy_cfg;
+ struct resource *res;
+ int ret;
+
+ phy_cfg = of_device_get_match_data(dev);
+ if (!phy_cfg) {
+ dev_err(dev, "no OF match data provided\n");
+ return -EINVAL;
+ }
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->mmio = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+ if (IS_ERR(priv->mmio)) {
+ ret = PTR_ERR(priv->mmio);
+ return ret;
+ }
+
+ priv->dev = dev;
+ priv->mode = PHY_NONE;
+ priv->cfg = phy_cfg;
+
+ ret = rockchip_combphy_parse_dt(dev, priv);
+ if (ret)
+ return ret;
+
+ ret = reset_control_assert(priv->phy_rst);
+ if (ret) {
+ dev_err(dev, "failed to reset phy\n");
+ return ret;
+ }
+
+ priv->phy = devm_phy_create(dev, NULL, &rochchip_combphy_ops);
+ if (IS_ERR(priv->phy)) {
+ dev_err(dev, "failed to create combphy\n");
+ return PTR_ERR(priv->phy);
+ }
+
+ dev_set_drvdata(dev, priv);
+ phy_set_drvdata(priv->phy, priv);
+
+ phy_provider = devm_of_phy_provider_register(dev, rockchip_combphy_xlate);
+
+ return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv)
+{
+ const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
+ unsigned long rate;
+ u32 val;
+
+ switch (priv->mode) {
+ case PHY_TYPE_PCIE:
+ /* Set SSC downward spread spectrum. */
+ rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK,
+ PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT,
+ PHYREG32);
+
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
+ break;
+
+ case PHY_TYPE_USB3:
+ /* Set SSC downward spread spectrum. */
+ rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK,
+ PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT,
+ PHYREG32);
+
+ /* Enable adaptive CTLE for USB3.0 Rx. */
+ val = readl(priv->mmio + PHYREG15);
+ val |= PHYREG15_CTLE_EN;
+ writel(val, priv->mmio + PHYREG15);
+
+ /* Set PLL KVCO fine tuning signals. */
+ rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
+ PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT,
+ PHYREG33);
+
+ /* Enable controlling random jitter. */
+ writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
+
+ /* Set PLL input clock divider 1/2. */
+ rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK,
+ PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT,
+ PHYREG6);
+
+ writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
+ writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
+
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_usb, true);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true);
+ break;
+
+ case PHY_TYPE_SATA:
+ /* Enable adaptive CTLE for SATA Rx. */
+ val = readl(priv->mmio + PHYREG15);
+ val |= PHYREG15_CTLE_EN;
+ writel(val, priv->mmio + PHYREG15);
+ /*
+ * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA.
+ * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm)
+ */
+ val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT;
+ val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT;
+ writel(val, priv->mmio + PHYREG7);
+
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_sata, true);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_sata, true);
+ rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
+ break;
+
+ case PHY_TYPE_SGMII:
+ rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->sgmii_mode_set, true);
+ break;
+
+ case PHY_TYPE_QSGMII:
+ rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_rate_sel, true);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true);
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->qsgmii_mode_set, true);
+ break;
+
+ default:
+ dev_err(priv->dev, "incompatible PHY type\n");
+ return -EINVAL;
+ }
+
+ rate = clk_get_rate(priv->refclk);
+
+ switch (rate) {
+ case REF_CLOCK_24MHz:
+ if (priv->mode == PHY_TYPE_USB3 || priv->mode == PHY_TYPE_SATA) {
+ /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */
+ val = PHYREG15_SSC_CNT_VALUE << PHYREG15_SSC_CNT_SHIFT;
+ rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK,
+ val, PHYREG15);
+
+ writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
+ }
+ break;
+
+ case REF_CLOCK_25MHz:
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
+ break;
+
+ case REF_CLOCK_100MHz:
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
+ if (priv->mode == PHY_TYPE_PCIE) {
+ /* PLL KVCO fine tuning. */
+ val = PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT;
+ rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
+ val, PHYREG33);
+
+ /* Enable controlling random jitter. */
+ writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
+
+ val = PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT;
+ rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK,
+ val, PHYREG6);
+
+ writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
+ writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
+ } else if (priv->mode == PHY_TYPE_SATA) {
+ /* downward spread spectrum +500ppm */
+ val = PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT;
+ val |= PHYREG32_SSC_OFFSET_500PPM << PHYREG32_SSC_OFFSET_SHIFT;
+ rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
+ }
+ break;
+
+ default:
+ dev_err(priv->dev, "unsupported rate: %lu\n", rate);
+ return -EINVAL;
+ }
+
+ if (priv->ext_refclk) {
+ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true);
+ if (priv->mode == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) {
+ val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT;
+ val |= PHYREG13_CKRCV_AMP0;
+ rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13);
+
+ val = readl(priv->mmio + PHYREG14);
+ val |= PHYREG14_CKRCV_AMP1;
+ writel(val, priv->mmio + PHYREG14);
+ }
+ }
+
+ if (priv->enable_ssc) {
+ val = readl(priv->mmio + PHYREG8);
+ val |= PHYREG8_SSC_EN;
+ writel(val, priv->mmio + PHYREG8);
+ }
+
+ return 0;
+}
+
+static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = {
+ /* pipe-phy-grf */
+ .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 },
+ .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 },
+ .sgmii_mode_set = { 0x0000, 5, 0, 0x00, 0x01 },
+ .qsgmii_mode_set = { 0x0000, 5, 0, 0x00, 0x21 },
+ .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 },
+ .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 },
+ .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 },
+ .pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x01 },
+ .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 },
+ .pipe_phymode_sel = { 0x0008, 1, 1, 0x00, 0x01 },
+ .pipe_rate_sel = { 0x0008, 2, 2, 0x00, 0x01 },
+ .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 },
+ .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 },
+ .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 },
+ .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 },
+ .pipe_sel_usb = { 0x000c, 14, 13, 0x00, 0x01 },
+ .pipe_sel_qsgmii = { 0x000c, 15, 13, 0x00, 0x07 },
+ .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 },
+ .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 },
+ .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 },
+ .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 },
+ .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 },
+ .con0_for_sata = { 0x0000, 15, 0, 0x00, 0x0119 },
+ .con1_for_sata = { 0x0004, 15, 0, 0x00, 0x0040 },
+ .con2_for_sata = { 0x0008, 15, 0, 0x00, 0x80c3 },
+ .con3_for_sata = { 0x000c, 15, 0, 0x00, 0x4407 },
+ /* pipe-grf */
+ .pipe_con0_for_sata = { 0x0000, 15, 0, 0x00, 0x2220 },
+ .pipe_xpcs_phy_ready = { 0x0040, 2, 2, 0x00, 0x01 },
+};
+
+static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = {
+ .grfcfg = &rk3568_combphy_grfcfgs,
+ .combphy_cfg = rk3568_combphy_cfg,
+};
+
+static const struct of_device_id rockchip_combphy_of_match[] = {
+ {
+ .compatible = "rockchip,rk3568-naneng-combphy",
+ .data = &rk3568_combphy_cfgs,
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(of, rockchip_combphy_of_match);
+
+static struct platform_driver rockchip_combphy_driver = {
+ .probe = rockchip_combphy_probe,
+ .driver = {
+ .name = "rockchip-naneng-combphy",
+ .of_match_table = rockchip_combphy_of_match,
+ },
+};
+module_platform_driver(rockchip_combphy_driver);
+
+MODULE_DESCRIPTION("Rockchip NANENG COMBPHY driver");
+MODULE_LICENSE("GPL v2");
Add the core dt-node for the rk3568's naneng combo phys.
Signed-off-by: Yifeng Zhao <yifeng.zhao@rock-chips.com>
Signed-off-by: Johan Jonker <jbx6244@gmail.com>
---
Changes in v7: None
Changes in v5:
- remove apb reset
Changes in v4:
- rename node name
- remove reset-names
- move #phy-cells
- add rockchip,rk3568-pipe-grf
- add rockchip,rk3568-pipe-phy-grf
Changes in v3:
- Move pipe_phy_grf0 to rk3568.dtsi
Changes in v2:
- Move phy0 to rk3568.dtsi
arch/arm64/boot/dts/rockchip/rk3568.dtsi | 21 +++++++++++
arch/arm64/boot/dts/rockchip/rk356x.dtsi | 47 ++++++++++++++++++++++++
2 files changed, 68 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3568.dtsi b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
index 2fd313a295f8..91a0b798b857 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
@@ -8,6 +8,11 @@
/ {
compatible = "rockchip,rk3568";
+ pipe_phy_grf0: syscon@fdc70000 {
+ compatible = "rockchip,rk3568-pipe-phy-grf", "syscon";
+ reg = <0x0 0xfdc70000 0x0 0x1000>;
+ };
+
qos_pcie3x1: qos@fe190080 {
compatible = "rockchip,rk3568-qos", "syscon";
reg = <0x0 0xfe190080 0x0 0x20>;
@@ -71,6 +76,22 @@
queue0 {};
};
};
+
+ combphy0: phy@fe820000 {
+ compatible = "rockchip,rk3568-naneng-combphy";
+ reg = <0x0 0xfe820000 0x0 0x100>;
+ clocks = <&pmucru CLK_PCIEPHY0_REF>,
+ <&cru PCLK_PIPEPHY0>,
+ <&cru PCLK_PIPE>;
+ clock-names = "ref", "apb", "pipe";
+ assigned-clocks = <&pmucru CLK_PCIEPHY0_REF>;
+ assigned-clock-rates = <100000000>;
+ resets = <&cru SRST_PIPEPHY0>;
+ rockchip,pipe-grf = <&pipegrf>;
+ rockchip,pipe-phy-grf = <&pipe_phy_grf0>;
+ #phy-cells = <1>;
+ status = "disabled";
+ };
};
&cpu0_opp_table {
diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index a68033a23975..93f230f799f1 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -218,11 +218,26 @@
};
};
+ pipegrf: syscon@fdc50000 {
+ compatible = "rockchip,rk3568-pipe-grf", "syscon";
+ reg = <0x0 0xfdc50000 0x0 0x1000>;
+ };
+
grf: syscon@fdc60000 {
compatible = "rockchip,rk3568-grf", "syscon", "simple-mfd";
reg = <0x0 0xfdc60000 0x0 0x10000>;
};
+ pipe_phy_grf1: syscon@fdc80000 {
+ compatible = "rockchip,rk3568-pipe-phy-grf", "syscon";
+ reg = <0x0 0xfdc80000 0x0 0x1000>;
+ };
+
+ pipe_phy_grf2: syscon@fdc90000 {
+ compatible = "rockchip,rk3568-pipe-phy-grf", "syscon";
+ reg = <0x0 0xfdc90000 0x0 0x1000>;
+ };
+
pmucru: clock-controller@fdd00000 {
compatible = "rockchip,rk3568-pmucru";
reg = <0x0 0xfdd00000 0x0 0x1000>;
@@ -1141,6 +1156,38 @@
status = "disabled";
};
+ combphy1: phy@fe830000 {
+ compatible = "rockchip,rk3568-naneng-combphy";
+ reg = <0x0 0xfe830000 0x0 0x100>;
+ clocks = <&pmucru CLK_PCIEPHY1_REF>,
+ <&cru PCLK_PIPEPHY1>,
+ <&cru PCLK_PIPE>;
+ clock-names = "ref", "apb", "pipe";
+ assigned-clocks = <&pmucru CLK_PCIEPHY1_REF>;
+ assigned-clock-rates = <100000000>;
+ resets = <&cru SRST_PIPEPHY1>;
+ rockchip,pipe-grf = <&pipegrf>;
+ rockchip,pipe-phy-grf = <&pipe_phy_grf1>;
+ #phy-cells = <1>;
+ status = "disabled";
+ };
+
+ combphy2: phy@fe840000 {
+ compatible = "rockchip,rk3568-naneng-combphy";
+ reg = <0x0 0xfe840000 0x0 0x100>;
+ clocks = <&pmucru CLK_PCIEPHY2_REF>,
+ <&cru PCLK_PIPEPHY2>,
+ <&cru PCLK_PIPE>;
+ clock-names = "ref", "apb", "pipe";
+ assigned-clocks = <&pmucru CLK_PCIEPHY2_REF>;
+ assigned-clock-rates = <100000000>;
+ resets = <&cru SRST_PIPEPHY2>;
+ rockchip,pipe-grf = <&pipegrf>;
+ rockchip,pipe-phy-grf = <&pipe_phy_grf2>;
+ #phy-cells = <1>;
+ status = "disabled";
+ };
+
pinctrl: pinctrl {
compatible = "rockchip,rk3568-pinctrl";
rockchip,grf = <&grf>;

View File

@ -0,0 +1,230 @@
Add the documentation for the rk3568-usb2phy-grf node, which is separate
from the usb2phy node on this chip.
Signed-off-by: Peter Geis <pgwipeout@gmail.com>
Acked-by: Rob Herring <robh@kernel.org>
---
Documentation/devicetree/bindings/soc/rockchip/grf.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/soc/rockchip/grf.yaml b/Documentation/devicetree/bindings/soc/rockchip/grf.yaml
index dfebf425ca49..b2ba7bed89b2 100644
--- a/Documentation/devicetree/bindings/soc/rockchip/grf.yaml
+++ b/Documentation/devicetree/bindings/soc/rockchip/grf.yaml
@@ -15,6 +15,7 @@ properties:
- items:
- enum:
- rockchip,rk3288-sgrf
+ - rockchip,rk3568-usb2phy-grf
- rockchip,rv1108-usbgrf
- const: syscon
- items:
diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index 46d9552f6028..2c2b1014e53b 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -204,6 +204,50 @@ gic: interrupt-controller@fd400000 {
msi-controller;
};
+ usb_host0_ehci: usb@fd800000 {
+ compatible = "generic-ehci";
+ reg = <0x0 0xfd800000 0x0 0x40000>;
+ interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_USB2HOST0>, <&cru HCLK_USB2HOST0_ARB>,
+ <&cru PCLK_USB>;
+ phys = <&u2phy1_otg>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ usb_host0_ohci: usb@fd840000 {
+ compatible = "generic-ohci";
+ reg = <0x0 0xfd840000 0x0 0x40000>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_USB2HOST0>, <&cru HCLK_USB2HOST0_ARB>,
+ <&cru PCLK_USB>;
+ phys = <&u2phy1_otg>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ usb_host1_ehci: usb@fd880000 {
+ compatible = "generic-ehci";
+ reg = <0x0 0xfd880000 0x0 0x40000>;
+ interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_USB2HOST1>, <&cru HCLK_USB2HOST1_ARB>,
+ <&cru PCLK_USB>;
+ phys = <&u2phy1_host>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ usb_host1_ohci: usb@fd8c0000 {
+ compatible = "generic-ohci";
+ reg = <0x0 0xfd8c0000 0x0 0x40000>;
+ interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_USB2HOST1>, <&cru HCLK_USB2HOST1_ARB>,
+ <&cru PCLK_USB>;
+ phys = <&u2phy1_host>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
pmugrf: syscon@fdc20000 {
compatible = "rockchip,rk3568-pmugrf", "syscon", "simple-mfd";
reg = <0x0 0xfdc20000 0x0 0x10000>;
@@ -219,6 +263,16 @@ grf: syscon@fdc60000 {
reg = <0x0 0xfdc60000 0x0 0x10000>;
};
+ usb2phy0_grf: syscon@fdca0000 {
+ compatible = "rockchip,rk3568-usb2phy-grf", "syscon";
+ reg = <0x0 0xfdca0000 0x0 0x8000>;
+ };
+
+ usb2phy1_grf: syscon@fdca8000 {
+ compatible = "rockchip,rk3568-usb2phy-grf", "syscon";
+ reg = <0x0 0xfdca8000 0x0 0x8000>;
+ };
+
pmucru: clock-controller@fdd00000 {
compatible = "rockchip,rk3568-pmucru";
reg = <0x0 0xfdd00000 0x0 0x1000>;
@@ -1077,6 +1131,50 @@ pwm15: pwm@fe700030 {
status = "disabled";
};
+ u2phy0: usb2phy@fe8a0000 {
+ compatible = "rockchip,rk3568-usb2phy";
+ reg = <0x0 0xfe8a0000 0x0 0x10000>;
+ clocks = <&pmucru CLK_USBPHY0_REF>;
+ clock-names = "phyclk";
+ clock-output-names = "clk_usbphy0_480m";
+ interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>;
+ rockchip,usbgrf = <&usb2phy0_grf>;
+ #clock-cells = <0>;
+ status = "disabled";
+
+ u2phy0_host: host-port {
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
+ u2phy0_otg: otg-port {
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+ };
+
+ u2phy1: usb2phy@fe8b0000 {
+ compatible = "rockchip,rk3568-usb2phy";
+ reg = <0x0 0xfe8b0000 0x0 0x10000>;
+ clocks = <&pmucru CLK_USBPHY1_REF>;
+ clock-names = "phyclk";
+ clock-output-names = "clk_usbphy1_480m";
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+ rockchip,usbgrf = <&usb2phy1_grf>;
+ #clock-cells = <0>;
+ status = "disabled";
+
+ u2phy1_host: host-port {
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
+ u2phy1_otg: otg-port {
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+ };
+
pinctrl: pinctrl {
compatible = "rockchip,rk3568-pinctrl";
rockchip,grf = <&grf>;
Add the nodes and regulators to enable usb2 support on the Quartz64
Model A.
Signed-off-by: Peter Geis <pgwipeout@gmail.com>
Tested-by: Michael Riesch <michael.riesch@wolfvision.net>
---
.../boot/dts/rockchip/rk3566-quartz64-a.dts | 52 +++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
index 4d4b2a301b1a..e5a70ff4e920 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
@@ -124,6 +124,22 @@ vcc5v0_usb: vcc5v0_usb {
vin-supply = <&vcc12v_dcin>;
};
+ /* all four ports are controlled by one gpio
+ * the host ports are sourced from vcc5v0_usb
+ * the otg port is sourced from vcc5v0_midu
+ */
+ vcc5v0_usb20_host: vcc5v0_usb20_host {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_usb20_host";
+ enable-active-high;
+ gpio = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_usb20_host_en>;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_usb>;
+ };
+
vcc3v3_sd: vcc3v3_sd {
compatible = "regulator-fixed";
enable-active-low;
@@ -477,6 +493,12 @@ pmic_int_l: pmic-int-l {
};
};
+ usb2 {
+ vcc5v0_usb20_host_en: vcc5v0-usb20-host-en {
+ rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
vcc_sd {
vcc_sd_h: vcc-sd-h {
rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -546,3 +568,33 @@ bluetooth {
&uart2 {
status = "okay";
};
+
+&u2phy1_host {
+ phy-supply = <&vcc5v0_usb20_host>;
+ status = "okay";
+};
+
+&u2phy1_otg {
+ phy-supply = <&vcc5v0_usb20_host>;
+ status = "okay";
+};
+
+&u2phy1 {
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};

View File

@ -0,0 +1,506 @@
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -247,6 +247,98 @@
};
};
+ sata1: sata@fc400000 {
+ compatible = "snps,dwc-ahci";
+ reg = <0 0xfc400000 0 0x1000>;
+ clocks = <&cru ACLK_SATA1>, <&cru CLK_SATA1_PMALIVE>,
+ <&cru CLK_SATA1_RXOOB>;
+ clock-names = "sata", "pmalive", "rxoob";
+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "hostc";
+ phys = <&combphy1 PHY_TYPE_SATA>;
+ phy-names = "sata-phy";
+ ports-implemented = <0x1>;
+ power-domains = <&power RK3568_PD_PIPE>;
+ status = "disabled";
+ };
+
+ sata2: sata@fc800000 {
+ compatible = "snps,dwc-ahci";
+ reg = <0 0xfc800000 0 0x1000>;
+ clocks = <&cru ACLK_SATA2>, <&cru CLK_SATA2_PMALIVE>,
+ <&cru CLK_SATA2_RXOOB>;
+ clock-names = "sata", "pmalive", "rxoob";
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "hostc";
+ phys = <&combphy2 PHY_TYPE_SATA>;
+ phy-names = "sata-phy";
+ ports-implemented = <0x1>;
+ power-domains = <&power RK3568_PD_PIPE>;
+ status = "disabled";
+ };
+
+ usbdrd30: usbdrd {
+ compatible = "rockchip,rk3399-dwc3", "snps,dwc3";
+ clocks = <&cru CLK_USB3OTG0_REF>, <&cru CLK_USB3OTG0_SUSPEND>,
+ <&cru ACLK_USB3OTG0>, <&cru PCLK_PIPE>;
+ clock-names = "ref_clk", "suspend_clk",
+ "bus_clk", "pipe_clk";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ status = "disabled";
+
+ usbdrd_dwc3: dwc3@fcc00000 {
+ compatible = "snps,dwc3";
+ reg = <0x0 0xfcc00000 0x0 0x400000>;
+ interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
+ dr_mode = "host";
+ phy_type = "utmi_wide";
+ power-domains = <&power RK3568_PD_PIPE>;
+ resets = <&cru SRST_USB3OTG0>;
+ reset-names = "usb3-otg";
+ snps,dis_enblslpm_quirk;
+ snps,dis-u2-freeclk-exists-quirk;
+ snps,dis-del-phy-power-chg-quirk;
+ snps,dis-tx-ipgap-linecheck-quirk;
+ snps,xhci-trb-ent-quirk;
+ status = "disabled";
+ };
+ };
+
+ usbhost30: usbhost {
+ compatible = "rockchip,rk3399-dwc3", "snps,dwc3";
+ clocks = <&cru CLK_USB3OTG1_REF>, <&cru CLK_USB3OTG1_SUSPEND>,
+ <&cru ACLK_USB3OTG1>, <&cru PCLK_PIPE>;
+ clock-names = "ref_clk", "suspend_clk",
+ "bus_clk", "pipe_clk";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ assigned-clocks = <&cru CLK_PCIEPHY1_REF>;
+ assigned-clock-rates = <25000000>;
+ ranges;
+ status = "disabled";
+
+ usbhost_dwc3: dwc3@fd000000 {
+ compatible = "snps,dwc3";
+ reg = <0x0 0xfd000000 0x0 0x400000>;
+ interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
+ dr_mode = "host";
+ phys = <&u2phy0_host>, <&combphy1 PHY_TYPE_USB3>;
+ phy-names = "usb2-phy", "usb3-phy";
+ phy_type = "utmi_wide";
+ power-domains = <&power RK3568_PD_PIPE>;
+ resets = <&cru SRST_USB3OTG1>;
+ reset-names = "usb3-host";
+ snps,dis_enblslpm_quirk;
+ snps,dis-u2-freeclk-exists-quirk;
+ snps,dis_u2_susphy_quirk;
+ snps,dis-del-phy-power-chg-quirk;
+ snps,dis-tx-ipgap-linecheck-quirk;
+ status = "disabled";
+ };
+ };
+
gic: interrupt-controller@fd400000 {
compatible = "arm,gic-v3";
reg = <0x0 0xfd400000 0 0x10000>, /* GICD */
@@ -365,6 +472,7 @@
clocks = <&pmucru SCLK_UART0>, <&pmucru PCLK_UART0>;
clock-names = "baudclk", "apb_pclk";
dmas = <&dmac0 0>, <&dmac0 1>;
+ dma-names = "tx", "rx";
pinctrl-0 = <&uart0_xfer>;
pinctrl-names = "default";
reg-io-width = <4>;
@@ -770,6 +879,61 @@
qos_vop_m1: qos@fe1a8100 {
compatible = "rockchip,rk3568-qos", "syscon";
reg = <0x0 0xfe1a8100 0x0 0x20>;
+ };
+
+ pcie2x1: pcie@fe260000 {
+ compatible = "rockchip,rk3568-pcie";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ bus-range = <0x0 0xf>;
+ assigned-clocks = <&cru ACLK_PCIE20_MST>, <&cru ACLK_PCIE20_SLV>,
+ <&cru ACLK_PCIE20_DBI>, <&cru PCLK_PCIE20>,
+ <&cru CLK_PCIE20_AUX_NDFT>;
+ clocks = <&cru ACLK_PCIE20_MST>, <&cru ACLK_PCIE20_SLV>,
+ <&cru ACLK_PCIE20_DBI>, <&cru PCLK_PCIE20>,
+ <&cru CLK_PCIE20_AUX_NDFT>;
+ clock-names = "aclk_mst", "aclk_slv",
+ "aclk_dbi", "pclk", "aux";
+ device_type = "pci";
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "sys", "pmc", "msi", "legacy", "err";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie_intc 0>,
+ <0 0 0 2 &pcie_intc 1>,
+ <0 0 0 3 &pcie_intc 2>,
+ <0 0 0 4 &pcie_intc 3>;
+ linux,pci-domain = <0>;
+ num-ib-windows = <6>;
+ num-ob-windows = <2>;
+ max-link-speed = <2>;
+ msi-map = <0x0 &gic 0x0 0x1000>;
+ num-lanes = <1>;
+ phys = <&combphy2 PHY_TYPE_PCIE>;
+ phy-names = "pcie-phy";
+ power-domains = <&power RK3568_PD_PIPE>;
+ reg = <0x3 0xc0000000 0x0 0x400000>,
+ <0x0 0xfe260000 0x0 0x10000>,
+ <0x3 0x3f800000 0x0 0x800000>;
+ ranges = <0x1000000 0x0 0x7f700000 0x3 0x3f700000 0x0 0x00100000
+ 0x2000000 0x0 0x40000000 0x3 0x00000000 0x0 0x3f700000>;
+ reg-names = "dbi", "apb", "config";
+ resets = <&cru SRST_PCIE20_POWERUP>;
+ reset-names = "pipe";
+ status = "disabled";
+
+ pcie_intc: legacy-interrupt-controller {
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_EDGE_RISING>;
+ };
+
};
sdmmc0: mmc@fe2b0000 {
@@ -797,6 +961,17 @@
max-frequency = <150000000>;
resets = <&cru SRST_SDMMC1>;
reset-names = "reset";
+ status = "disabled";
+ };
+
+ sfc: spi@fe300000 {
+ compatible = "rockchip,sfc";
+ reg = <0x0 0xfe300000 0x0 0x4000>;
+ interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
+ clock-names = "clk_sfc", "hclk_sfc";
+ pinctrl-0 = <&fspi_pins>;
+ pinctrl-names = "default";
status = "disabled";
};
@@ -971,6 +1146,7 @@
clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
clock-names = "baudclk", "apb_pclk";
dmas = <&dmac0 2>, <&dmac0 3>;
+ dma-names = "tx", "rx";
pinctrl-0 = <&uart1m0_xfer>;
pinctrl-names = "default";
reg-io-width = <4>;
@@ -985,6 +1161,7 @@
clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
clock-names = "baudclk", "apb_pclk";
dmas = <&dmac0 4>, <&dmac0 5>;
+ dma-names = "tx", "rx";
pinctrl-0 = <&uart2m0_xfer>;
pinctrl-names = "default";
reg-io-width = <4>;
@@ -999,6 +1176,7 @@
clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
clock-names = "baudclk", "apb_pclk";
dmas = <&dmac0 6>, <&dmac0 7>;
+ dma-names = "tx", "rx";
pinctrl-0 = <&uart3m0_xfer>;
pinctrl-names = "default";
reg-io-width = <4>;
@@ -1013,6 +1191,7 @@
clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>;
clock-names = "baudclk", "apb_pclk";
dmas = <&dmac0 8>, <&dmac0 9>;
+ dma-names = "tx", "rx";
pinctrl-0 = <&uart4m0_xfer>;
pinctrl-names = "default";
reg-io-width = <4>;
@@ -1027,6 +1206,7 @@
clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>;
clock-names = "baudclk", "apb_pclk";
dmas = <&dmac0 10>, <&dmac0 11>;
+ dma-names = "tx", "rx";
pinctrl-0 = <&uart5m0_xfer>;
pinctrl-names = "default";
reg-io-width = <4>;
@@ -1041,6 +1221,7 @@
clocks = <&cru SCLK_UART6>, <&cru PCLK_UART6>;
clock-names = "baudclk", "apb_pclk";
dmas = <&dmac0 12>, <&dmac0 13>;
+ dma-names = "tx", "rx";
pinctrl-0 = <&uart6m0_xfer>;
pinctrl-names = "default";
reg-io-width = <4>;
@@ -1055,6 +1236,7 @@
clocks = <&cru SCLK_UART7>, <&cru PCLK_UART7>;
clock-names = "baudclk", "apb_pclk";
dmas = <&dmac0 14>, <&dmac0 15>;
+ dma-names = "tx", "rx";
pinctrl-0 = <&uart7m0_xfer>;
pinctrl-names = "default";
reg-io-width = <4>;
@@ -1069,6 +1251,7 @@
clocks = <&cru SCLK_UART8>, <&cru PCLK_UART8>;
clock-names = "baudclk", "apb_pclk";
dmas = <&dmac0 16>, <&dmac0 17>;
+ dma-names = "tx", "rx";
pinctrl-0 = <&uart8m0_xfer>;
pinctrl-names = "default";
reg-io-width = <4>;
@@ -1083,6 +1266,7 @@
clocks = <&cru SCLK_UART9>, <&cru PCLK_UART9>;
clock-names = "baudclk", "apb_pclk";
dmas = <&dmac0 18>, <&dmac0 19>;
+ dma-names = "tx", "rx";
pinctrl-0 = <&uart9m0_xfer>;
pinctrl-names = "default";
reg-io-width = <4>;
--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
@@ -7,6 +7,21 @@
/ {
compatible = "rockchip,rk3568";
+
+ sata0: sata@fc000000 {
+ compatible = "snps,dwc-ahci";
+ reg = <0 0xfc000000 0 0x1000>;
+ clocks = <&cru ACLK_SATA0>, <&cru CLK_SATA0_PMALIVE>,
+ <&cru CLK_SATA0_RXOOB>;
+ clock-names = "sata", "pmalive", "rxoob";
+ interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "hostc";
+ phys = <&combphy0 PHY_TYPE_SATA>;
+ phy-names = "sata-phy";
+ ports-implemented = <0x1>;
+ power-domains = <&power RK3568_PD_PIPE>;
+ status = "disabled";
+ };
qos_pcie3x1: qos@fe190080 {
compatible = "rockchip,rk3568-qos", "syscon";
@@ -78,6 +109,10 @@
opp-hz = /bits/ 64 <1992000000>;
opp-microvolt = <1150000 1150000 1150000>;
};
+};
+
+&pipegrf {
+ compatible = "rockchip,rk3568-pipegrf", "syscon";
};
&power {
@@ -95,3 +130,8 @@
#power-domain-cells = <0>;
};
};
+
+&usbdrd_dwc3 {
+ phys = <&u2phy0_otg>, <&combphy0 PHY_TYPE_USB3>;
+ phy-names = "usb2-phy", "usb3-phy";
+};
--- a/arch/arm64/boot/dts/rockchip/rk3566.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3566.dtsi
@@ -4,6 +4,10 @@
/ {
compatible = "rockchip,rk3566";
+};
+
+&pipegrf {
+ compatible = "rockchip,rk3566-pipegrf", "syscon";
};
&power {
@@ -18,3 +22,11 @@
#power-domain-cells = <0>;
};
};
+
+&usbdrd_dwc3 {
+ phys = <&u2phy0_otg>;
+ phy-names = "usb2-phy";
+ extcon = <&u2phy0>;
+ maximum-speed = "high-speed";
+ snps,dis_u2_susphy_quirk;
+};
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -258,6 +258,7 @@
/* Global User Control 1 Register */
#define DWC3_GUCTL1_DEV_DECOUPLE_L1L2_EVT BIT(31)
#define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS BIT(28)
+#define DWC3_GUCTL1_DEV_FORCE_20_CLK_FOR_30_CLK BIT(26)
#define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW BIT(24)
#define DWC3_GUCTL1_PARKMODE_DISABLE_SS BIT(17)
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1087,6 +1087,10 @@
if (dwc->parkmode_disable_ss_quirk)
reg |= DWC3_GUCTL1_PARKMODE_DISABLE_SS;
+
+ if (dwc->maximum_speed == USB_SPEED_HIGH ||
+ dwc->maximum_speed == USB_SPEED_FULL)
+ reg |= DWC3_GUCTL1_DEV_FORCE_20_CLK_FOR_30_CLK;
dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
}
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -10,9 +10,12 @@
#include <linux/clk.h>
#include <linux/gpio/consumer.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of_device.h>
+#include <linux/of_irq.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
@@ -36,10 +39,12 @@
#define PCIE_LINKUP (PCIE_SMLH_LINKUP | PCIE_RDLH_LINKUP)
#define PCIE_L0S_ENTRY 0x11
#define PCIE_CLIENT_GENERAL_CONTROL 0x0
+#define PCIE_CLIENT_INTR_MASK_LEGACY 0x1c
#define PCIE_CLIENT_GENERAL_DEBUG 0x104
-#define PCIE_CLIENT_HOT_RESET_CTRL 0x180
+#define PCIE_CLIENT_HOT_RESET_CTRL 0x180
#define PCIE_CLIENT_LTSSM_STATUS 0x300
-#define PCIE_LTSSM_ENABLE_ENHANCE BIT(4)
+#define PCIE_LEGACY_INT_ENABLE GENMASK(7, 0)
+#define PCIE_LTSSM_ENABLE_ENHANCE BIT(4)
#define PCIE_LTSSM_STATUS_MASK GENMASK(5, 0)
struct rockchip_pcie {
@@ -51,6 +56,7 @@
struct reset_control *rst;
struct gpio_desc *rst_gpio;
struct regulator *vpcie3v3;
+ struct irq_domain *irq_domain;
};
static int rockchip_pcie_readl_apb(struct rockchip_pcie *rockchip,
@@ -63,6 +69,68 @@
u32 val, u32 reg)
{
writel_relaxed(val, rockchip->apb_base + reg);
+}
+
+static void rockchip_pcie_legacy_int_handler(struct irq_desc *desc)
+{
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct rockchip_pcie *rockchip = irq_desc_get_handler_data(desc);
+ struct device *dev = rockchip->pci.dev;
+ u32 reg;
+ u32 hwirq;
+ u32 virq;
+
+ chained_irq_enter(chip, desc);
+
+ reg = rockchip_pcie_readl_apb(rockchip, 0x8);
+
+ while (reg) {
+ hwirq = ffs(reg) - 1;
+ reg &= ~BIT(hwirq);
+
+ virq = irq_find_mapping(rockchip->irq_domain, hwirq);
+ if (virq)
+ generic_handle_irq(virq);
+ else
+ dev_err(dev, "unexpected IRQ, INT%d\n", hwirq);
+ }
+
+ chained_irq_exit(chip, desc);
+}
+
+static int rockchip_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
+ irq_hw_number_t hwirq)
+{
+ irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
+ irq_set_chip_data(irq, domain->host_data);
+
+ return 0;
+}
+
+static const struct irq_domain_ops intx_domain_ops = {
+ .map = rockchip_pcie_intx_map,
+};
+
+static int rockchip_pcie_init_irq_domain(struct rockchip_pcie *rockchip)
+{
+ struct device *dev = rockchip->pci.dev;
+ struct device_node *intc;
+
+ intc = of_get_child_by_name(dev->of_node, "legacy-interrupt-controller");
+ if (!intc) {
+ dev_err(dev, "missing child interrupt-controller node\n");
+ return -EINVAL;
+ }
+
+ rockchip->irq_domain = irq_domain_add_linear(intc, PCI_NUM_INTX,
+ &intx_domain_ops, rockchip);
+ of_node_put(intc);
+ if (!rockchip->irq_domain) {
+ dev_err(dev, "failed to get a INTx IRQ domain\n");
+ return -EINVAL;
+ }
+
+ return 0;
}
static void rockchip_pcie_enable_ltssm(struct rockchip_pcie *rockchip)
@@ -111,9 +179,27 @@
{
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct rockchip_pcie *rockchip = to_rockchip_pcie(pci);
- u32 val = HIWORD_UPDATE_BIT(PCIE_LTSSM_ENABLE_ENHANCE);
+ struct device *dev = rockchip->pci.dev;
+ int irq, ret;
+ u32 val;
+
+ irq = of_irq_get_byname(dev->of_node, "legacy");
+ if (irq < 0)
+ return irq;
+
+ irq_set_chained_handler_and_data(irq, rockchip_pcie_legacy_int_handler, rockchip);
+
+ ret = rockchip_pcie_init_irq_domain(rockchip);
+ if (ret < 0)
+ dev_err(dev, "failed to init irq domain\n");
+
+ /* enable legacy interrupts */
+ val = HIWORD_UPDATE_BIT(PCIE_LEGACY_INT_ENABLE);
+ val &= ~PCIE_LEGACY_INT_ENABLE;
+ rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_INTR_MASK_LEGACY);
/* LTSSM enable control mode */
+ val = HIWORD_UPDATE_BIT(PCIE_LTSSM_ENABLE_ENHANCE);
rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_HOT_RESET_CTRL);
rockchip_pcie_writel_apb(rockchip, PCIE_CLIENT_RC_MODE,
@@ -214,6 +300,10 @@
rockchip->pci.dev = dev;
rockchip->pci.ops = &dw_pcie_ops;
+
+ ret = dma_set_mask(rockchip->pci.dev, DMA_BIT_MASK(32));
+ if (ret)
+ dev_warn(rockchip->pci.dev, "Failed to set DMA mask to 32-bit. Devices with only 32-bit MSI support may not work properly\n");
pp = &rockchip->pci.pp;
pp->ops = &rockchip_pcie_host_ops;

View File

@ -0,0 +1,32 @@
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -617,6 +617,28 @@
#cooling-cells = <2>;
power-domains = <&power RK3568_PD_GPU>;
status = "disabled";
+ };
+
+ vpu: video-codec@fdea0400 {
+ compatible = "rockchip,rk3328-vpu";
+ reg = <0x0 0xfdea0000 0x0 0x800>;
+ interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "vdpu";
+ clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
+ clock-names = "aclk", "hclk";
+ iommus = <&vdpu_mmu>;
+ power-domains = <&power RK3568_PD_VPU>;
+ };
+
+ vdpu_mmu: iommu@fdea0800 {
+ compatible = "rockchip,rk3568-iommu";
+ reg = <0x0 0xfdea0800 0x0 0x40>;
+ interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "vdpu_mmu";
+ clock-names = "aclk", "iface";
+ clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
+ power-domains = <&power RK3568_PD_VPU>;
+ #iommu-cells = <0>;
};
sdmmc2: mmc@fe000000 {

View File

@ -1 +1 @@
archive/rk35xx-5.16
archive/rk35xx-5.17