1882 lines
50 KiB
Diff
1882 lines
50 KiB
Diff
diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.yaml
|
|
new file mode 100644
|
|
index 000000000000..72b286a1beba
|
|
--- /dev/null
|
|
+++ b/Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.yaml
|
|
@@ -0,0 +1,92 @@
|
|
+# SPDX-License-Identifier: GPL-2.0-only
|
|
+%YAML 1.2
|
|
+---
|
|
+$id: http://devicetree.org/schemas/clock/rockchip,rk3399-cru.yaml#
|
|
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
|
+
|
|
+title: Rockchip RK3399 Clock and Reset Unit
|
|
+
|
|
+maintainers:
|
|
+ - Xing Zheng <zhengxing@rock-chips.com>
|
|
+ - Heiko Stuebner <heiko@sntech.de>
|
|
+
|
|
+description: |
|
|
+ The RK3399 clock controller generates and supplies clock to various
|
|
+ controllers within the SoC and also implements a reset controller for SoC
|
|
+ peripherals.
|
|
+ Each clock is assigned an identifier and client nodes can use this identifier
|
|
+ to specify the clock which they consume. All available clocks are defined as
|
|
+ preprocessor macros in the dt-bindings/clock/rk3399-cru.h headers and can be
|
|
+ used in device tree sources. Similar macros exist for the reset sources in
|
|
+ these files.
|
|
+ There are several clocks that are generated outside the SoC. It is expected
|
|
+ that they are defined using standard clock bindings with following
|
|
+ clock-output-names:
|
|
+ - "xin24m" - crystal input - required,
|
|
+ - "xin32k" - rtc clock - optional,
|
|
+ - "clkin_gmac" - external GMAC clock - optional,
|
|
+ - "clkin_i2s" - external I2S clock - optional,
|
|
+ - "pclkin_cif" - external ISP clock - optional,
|
|
+ - "clk_usbphy0_480m" - output clock of the pll in the usbphy0
|
|
+ - "clk_usbphy1_480m" - output clock of the pll in the usbphy1
|
|
+
|
|
+properties:
|
|
+ compatible:
|
|
+ enum:
|
|
+ - rockchip,rk3399-pmucru
|
|
+ - rockchip,rk3399-cru
|
|
+
|
|
+ reg:
|
|
+ maxItems: 1
|
|
+
|
|
+ "#clock-cells":
|
|
+ const: 1
|
|
+
|
|
+ "#reset-cells":
|
|
+ const: 1
|
|
+
|
|
+ clocks:
|
|
+ minItems: 1
|
|
+
|
|
+ assigned-clocks:
|
|
+ minItems: 1
|
|
+ maxItems: 64
|
|
+
|
|
+ assigned-clock-parents:
|
|
+ minItems: 1
|
|
+ maxItems: 64
|
|
+
|
|
+ assigned-clock-rates:
|
|
+ minItems: 1
|
|
+ maxItems: 64
|
|
+
|
|
+ rockchip,grf:
|
|
+ $ref: /schemas/types.yaml#/definitions/phandle
|
|
+ description: >
|
|
+ phandle to the syscon managing the "general register files". It is used
|
|
+ for GRF muxes, if missing any muxes present in the GRF will not be
|
|
+ available.
|
|
+
|
|
+required:
|
|
+ - compatible
|
|
+ - reg
|
|
+ - "#clock-cells"
|
|
+ - "#reset-cells"
|
|
+
|
|
+additionalProperties: false
|
|
+
|
|
+examples:
|
|
+ - |
|
|
+ pmucru: pmu-clock-controller@ff750000 {
|
|
+ compatible = "rockchip,rk3399-pmucru";
|
|
+ reg = <0xff750000 0x1000>;
|
|
+ #clock-cells = <1>;
|
|
+ #reset-cells = <1>;
|
|
+ };
|
|
+ - |
|
|
+ cru: clock-controller@ff760000 {
|
|
+ compatible = "rockchip,rk3399-cru";
|
|
+ reg = <0xff760000 0x1000>;
|
|
+ #clock-cells = <1>;
|
|
+ #reset-cells = <1>;
|
|
+ };
|
|
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
|
|
index 3871c7fd83b0..aa5d7dca3432 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
|
|
@@ -1240,7 +1240,6 @@ vpu: video-codec@ff650000 {
|
|
reg = <0x0 0xff650000 0x0 0x800>;
|
|
interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH 0>,
|
|
<GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH 0>;
|
|
- interrupt-names = "vepu", "vdpu";
|
|
clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
|
|
clock-names = "aclk", "hclk";
|
|
iommus = <&vpu_mmu>;
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Levin Du <djw@t-chip.com.cn>
|
|
Date: Fri, 9 Jul 2021 16:01:26 +0800
|
|
Subject: [PATCH] arm64: dts: rockchip: add support for Firefly ROC-RK3328-PC
|
|
|
|
ROC-RK3328-PC is the board inside the portable Firefly Station M1
|
|
Geek PC. As a redesign after the ROC-RK3328-CC, it uses TypeC as
|
|
power input and OTG port, embedded with eMMC 5.1 storage and a
|
|
SDIO WiFi/BT chip (RTL8723DS).
|
|
|
|
- Rockchip RK3328 SoC
|
|
- 2/4GB LPDDR3 RAM
|
|
- 16/32/64/128GB eMMC 5.1
|
|
- TF card slot
|
|
- USB 3.0 Port x 1, USB 2.0 Port x 1, TypeC Port x 1 (Power/OTG)
|
|
- HDMI
|
|
- Gigabit Ethernet
|
|
- WiFi: RTL8723DS
|
|
- Audio: RK3328
|
|
- Key: Power, Reset, Recovery
|
|
- LED: POWER, USER
|
|
- IR
|
|
|
|
Signed-off-by: Levin Du <djw@t-chip.com.cn>
|
|
Link: https://lore.kernel.org/r/20210709080126.17045-3-djw@t-chip.com.cn
|
|
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
|
|
---
|
|
arch/arm64/boot/dts/rockchip/Makefile | 1 +
|
|
.../arm64/boot/dts/rockchip/rk3328-roc-pc.dts | 110 ++++++++++++++++++
|
|
2 files changed, 111 insertions(+)
|
|
create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts
|
|
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts
|
|
new file mode 100644
|
|
index 000000000000..e3e3984d01d4
|
|
--- /dev/null
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts
|
|
@@ -0,0 +1,110 @@
|
|
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
|
+// Copyright (c) 2021 T-Chip Intelligent Technology Co., Ltd
|
|
+
|
|
+/dts-v1/;
|
|
+
|
|
+#include <dt-bindings/input/input.h>
|
|
+
|
|
+#include "rk3328-roc-cc.dts"
|
|
+
|
|
+/ {
|
|
+ model = "Firefly ROC-RK3328-PC";
|
|
+ compatible = "firefly,roc-rk3328-pc", "rockchip,rk3328";
|
|
+
|
|
+ adc-keys {
|
|
+ compatible = "adc-keys";
|
|
+ io-channels = <&saradc 0>;
|
|
+ io-channel-names = "buttons";
|
|
+ keyup-threshold-microvolt = <1750000>;
|
|
+
|
|
+ /* This button is unpopulated out of the factory. */
|
|
+ button-recovery {
|
|
+ label = "Recovery";
|
|
+ linux,code = <KEY_VENDOR>;
|
|
+ press-threshold-microvolt = <10000>;
|
|
+ };
|
|
+ };
|
|
+
|
|
+ ir-receiver {
|
|
+ compatible = "gpio-ir-receiver";
|
|
+ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>;
|
|
+ linux,rc-map-name = "rc-khadas";
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&ir_int>;
|
|
+ };
|
|
+
|
|
+ sdio_pwrseq: sdio-pwrseq {
|
|
+ compatible = "mmc-pwrseq-simple";
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&wifi_en>, <&wifi_host_wake>;
|
|
+ reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&codec {
|
|
+ mute-gpios = <&grf_gpio 0 GPIO_ACTIVE_LOW>;
|
|
+};
|
|
+
|
|
+&gpu {
|
|
+ mali-supply = <&vdd_logic>;
|
|
+};
|
|
+
|
|
+&pinctrl {
|
|
+ ir {
|
|
+ ir_int: ir-int {
|
|
+ rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
|
|
+ };
|
|
+ };
|
|
+
|
|
+ sdmmcio {
|
|
+ sdio_per_pin: sdio-per-pin {
|
|
+ rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_down>;
|
|
+ };
|
|
+ };
|
|
+
|
|
+ wifi {
|
|
+ wifi_en: wifi-en {
|
|
+ rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
|
|
+ };
|
|
+
|
|
+ wifi_host_wake: wifi-host-wake {
|
|
+ rockchip,pins = <3 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none_4ma>;
|
|
+ };
|
|
+
|
|
+ bt_rst: bt-rst {
|
|
+ rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
|
|
+ };
|
|
+
|
|
+ bt_en: bt-en {
|
|
+ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
|
|
+ };
|
|
+ };
|
|
+};
|
|
+
|
|
+&pmic_int_l {
|
|
+ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
|
|
+};
|
|
+
|
|
+&rk805 {
|
|
+ interrupt-parent = <&gpio0>;
|
|
+ interrupts = <RK_PA2 IRQ_TYPE_LEVEL_LOW>;
|
|
+};
|
|
+
|
|
+&saradc {
|
|
+ vref-supply = <&vcc_18>;
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&usb20_host_drv {
|
|
+ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>;
|
|
+};
|
|
+
|
|
+&vcc_host1_5v {
|
|
+ gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
|
|
+};
|
|
+
|
|
+&vcc_sdio {
|
|
+ gpios = <&gpio0 RK_PD3 GPIO_ACTIVE_HIGH>;
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&sdio_per_pin>;
|
|
+};
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Levin Du <djw@t-chip.com.cn>
|
|
Date: Mon, 28 Jun 2021 11:54:02 +0800
|
|
Subject: [PATCH] arm64: dts: rockchip: add support for Firefly
|
|
ROC-RK3399-PC-PLUS
|
|
|
|
ROC-RK3399-PC-PLUS is the board inside the portable Firefly Station P1 Geek
|
|
PC. As a redesign after the ROC-RK3399-PC, it uses DC-12V as power input
|
|
and spares a USB 3 host port. It is also equipped with a USB WiFi chip and
|
|
audio codec without the mezzanine board.
|
|
|
|
- Rockchip RK3399 SoC
|
|
- 4GB LPDDR4 RAM
|
|
- 16MB SPI-Flash
|
|
- eMMC slot
|
|
- TF card slot
|
|
- USB 3.0 Port x 1, USB 2.0 Port x 1, TypeC Port x 1
|
|
- HDMI
|
|
- Gigabit Ethernet
|
|
- WiFi: RTL8723DU
|
|
- Audio: ES8388
|
|
- Key: Recovery
|
|
- LED: WORK, DIY
|
|
- IR
|
|
|
|
Signed-off-by: Kongxin Deng <dkx@t-chip.com.cn>
|
|
Signed-off-by: Levin Du <djw@t-chip.com.cn>
|
|
Link: https://lore.kernel.org/r/20210628035402.16812-3-djw@t-chip.com.cn
|
|
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
|
|
---
|
|
arch/arm64/boot/dts/rockchip/Makefile | 1 +
|
|
.../boot/dts/rockchip/rk3399-roc-pc-plus.dts | 218 ++++++++++++++++++
|
|
2 files changed, 219 insertions(+)
|
|
create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-roc-pc-plus.dts
|
|
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-plus.dts b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-plus.dts
|
|
new file mode 100644
|
|
index 000000000000..5a2661ae0131
|
|
--- /dev/null
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-plus.dts
|
|
@@ -0,0 +1,218 @@
|
|
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
|
+/*
|
|
+ * Copyright (c) 2017 T-Chip Intelligent Technology Co., Ltd
|
|
+ */
|
|
+
|
|
+/dts-v1/;
|
|
+#include "rk3399-roc-pc.dtsi"
|
|
+
|
|
+/*
|
|
+ * Notice:
|
|
+ * 1. rk3399-roc-pc-plus is powered by dc_12v directly.
|
|
+ * 2. rk3399-roc-pc-plus has only vcc_bus_typec0 in schematic, which is coresponding
|
|
+ * to vcc_vbus_typec1 in rk3399-roc-pc.
|
|
+ * For simplicity, reserve the node name of vcc_vbus_typec1.
|
|
+ * 3. vcc5v0_host is actually 2 regulators (host0, 1) controlled by the same gpio.
|
|
+ */
|
|
+
|
|
+/delete-node/ &fusb1;
|
|
+/delete-node/ &hub_rst;
|
|
+/delete-node/ &mp8859;
|
|
+/delete-node/ &vcc_sys_en;
|
|
+/delete-node/ &vcc_vbus_typec0;
|
|
+/delete-node/ &yellow_led;
|
|
+
|
|
+/ {
|
|
+ model = "Firefly ROC-RK3399-PC-PLUS Board";
|
|
+ compatible = "firefly,roc-rk3399-pc-plus", "rockchip,rk3399";
|
|
+
|
|
+ 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>;
|
|
+ };
|
|
+
|
|
+ es8388-sound {
|
|
+ compatible = "simple-audio-card";
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&hp_det_pin>;
|
|
+ simple-audio-card,name = "rockchip,es8388-codec";
|
|
+ simple-audio-card,format = "i2s";
|
|
+ simple-audio-card,mclk-fs = <256>;
|
|
+ simple-audio-card,widgets =
|
|
+ "Microphone", "Mic Jack",
|
|
+ "Headphone", "Headphones";
|
|
+ simple-audio-card,routing =
|
|
+ "LINPUT1", "Mic Jack",
|
|
+ "Headphone Amp INL", "LOUT2",
|
|
+ "Headphone Amp INR", "ROUT2",
|
|
+ "Headphones", "Headphone Amp OUTL",
|
|
+ "Headphones", "Headphone Amp OUTR";
|
|
+ simple-audio-card,hp-det-gpio = <&gpio2 RK_PA6 GPIO_ACTIVE_HIGH>;
|
|
+ simple-audio-card,aux-devs = <&headphones_amp>;
|
|
+ simple-audio-card,pin-switches = "Headphones";
|
|
+
|
|
+ simple-audio-card,codec {
|
|
+ sound-dai = <&es8388>;
|
|
+ };
|
|
+
|
|
+ simple-audio-card,cpu {
|
|
+ sound-dai = <&i2s1>;
|
|
+ };
|
|
+ };
|
|
+
|
|
+ gpio-fan {
|
|
+ #cooling-cells = <2>;
|
|
+ compatible = "gpio-fan";
|
|
+ gpio-fan,speed-map = <0 0 3000 1>;
|
|
+ gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_HIGH>;
|
|
+ };
|
|
+
|
|
+ /delete-node/ gpio-keys;
|
|
+
|
|
+ /* not amplifier, used as switcher only */
|
|
+ headphones_amp: headphones-amp {
|
|
+ compatible = "simple-audio-amplifier";
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&ear_ctl_pin>;
|
|
+ enable-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>;
|
|
+ sound-name-prefix = "Headphone Amp";
|
|
+ VCC-supply = <&vcca3v0_codec>;
|
|
+ };
|
|
+
|
|
+ ir-receiver {
|
|
+ linux,rc-map-name = "rc-khadas";
|
|
+ };
|
|
+
|
|
+ leds {
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&work_led_pin>, <&diy_led_pin>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&fusb0 {
|
|
+ vbus-supply = <&vcc_vbus_typec1>;
|
|
+};
|
|
+
|
|
+&i2c0 {
|
|
+ hym8563: hym8563@51 {
|
|
+ compatible = "haoyu,hym8563";
|
|
+ reg = <0x51>;
|
|
+ interrupt-parent = <&gpio0>;
|
|
+ interrupts = <RK_PA5 IRQ_TYPE_EDGE_FALLING>;
|
|
+ #clock-cells = <0>;
|
|
+ clock-frequency = <32768>;
|
|
+ clock-output-names = "xin32k";
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&hym8563_int>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&i2c1 {
|
|
+ es8388: es8388@11 {
|
|
+ compatible = "everest,es8388";
|
|
+ reg = <0x11>;
|
|
+ clock-names = "mclk";
|
|
+ clocks = <&cru SCLK_I2S_8CH_OUT>;
|
|
+ #sound-dai-cells = <0>;
|
|
+ };
|
|
+};
|
|
+
|
|
+/* <4 RK_PA0 1 &pcfg_pull_none> is used as i2s_8ch_mclk_pin */
|
|
+&i2s0_8ch_bus {
|
|
+ rockchip,pins =
|
|
+ <3 RK_PD0 1 &pcfg_pull_none>,
|
|
+ <3 RK_PD1 1 &pcfg_pull_none>,
|
|
+ <3 RK_PD2 1 &pcfg_pull_none>,
|
|
+ <3 RK_PD3 1 &pcfg_pull_none>,
|
|
+ <3 RK_PD4 1 &pcfg_pull_none>,
|
|
+ <3 RK_PD5 1 &pcfg_pull_none>,
|
|
+ <3 RK_PD6 1 &pcfg_pull_none>,
|
|
+ <3 RK_PD7 1 &pcfg_pull_none>;
|
|
+};
|
|
+
|
|
+&i2s1 {
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&i2s_8ch_mclk_pin>, <&i2s1_2ch_bus>;
|
|
+ rockchip,playback-channels = <2>;
|
|
+ rockchip,capture-channels = <2>;
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&pinctrl {
|
|
+ es8388 {
|
|
+ ear_ctl_pin: ear-ctl-pin {
|
|
+ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_output_high>;
|
|
+ };
|
|
+
|
|
+ hp_det_pin: hp-det-pin {
|
|
+ rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_down>;
|
|
+ };
|
|
+ };
|
|
+
|
|
+ hym8563 {
|
|
+ hym8563_int: hym8563-int {
|
|
+ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
|
|
+ };
|
|
+ };
|
|
+
|
|
+ i2s1 {
|
|
+ i2s_8ch_mclk_pin: i2s-8ch-mclk-pin {
|
|
+ rockchip,pins = <4 RK_PA0 1 &pcfg_pull_none>;
|
|
+ };
|
|
+ };
|
|
+};
|
|
+
|
|
+&u2phy0 {
|
|
+ status = "okay";
|
|
+
|
|
+ u2phy0_otg: otg-port {
|
|
+ phy-supply = <&vcc_vbus_typec1>;
|
|
+ status = "okay";
|
|
+ };
|
|
+
|
|
+ u2phy0_host: host-port {
|
|
+ phy-supply = <&vcc5v0_host>;
|
|
+ status = "okay";
|
|
+ };
|
|
+};
|
|
+
|
|
+&u2phy1 {
|
|
+ status = "okay";
|
|
+
|
|
+ u2phy1_otg: otg-port {
|
|
+ phy-supply = <&vcc5v0_host>;
|
|
+ status = "okay";
|
|
+ };
|
|
+
|
|
+ u2phy1_host: host-port {
|
|
+ phy-supply = <&vcc5v0_host>;
|
|
+ status = "okay";
|
|
+ };
|
|
+};
|
|
+
|
|
+&uart0 {
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&usbdrd_dwc3_0 {
|
|
+ dr_mode = "host";
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&vcc_sys {
|
|
+ /* vcc_sys is fixed, not controlled by any gpio */
|
|
+ /delete-property/ gpio;
|
|
+ /delete-property/ pinctrl-names;
|
|
+ /delete-property/ pinctrl-0;
|
|
+};
|
|
+
|
|
+&vcc5v0_host {
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&vcc5v0_host_en>;
|
|
+};
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Dennis Gilmore <dgilmore@redhat.com>
|
|
Date: Wed, 14 Jul 2021 21:56:31 -0500
|
|
Subject: [PATCH] arm64: dts: rockchip: enable tsadc on helios64
|
|
|
|
Enable the tsadc thermal controller on the helios64
|
|
|
|
Signed-off-by: Dennis Gilmore <dgilmore@redhat.com>
|
|
Link: https://lore.kernel.org/r/20210715025635.70452-4-dgilmore@redhat.com
|
|
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
|
|
---
|
|
arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts | 8 ++++++++
|
|
1 file changed, 8 insertions(+)
|
|
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
|
|
index b275b4790211..63c7681843da 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
|
|
@@ -502,6 +502,14 @@ &tcphy1 {
|
|
status = "okay";
|
|
};
|
|
|
|
+&tsadc {
|
|
+ /* tshut mode 0:CRU 1:GPIO */
|
|
+ rockchip,hw-tshut-mode = <1>;
|
|
+ /* tshut polarity 0:LOW 1:HIGH */
|
|
+ rockchip,hw-tshut-polarity = <1>;
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
&u2phy1 {
|
|
status = "okay";
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Alex Bee <knaerzche@gmail.com>
|
|
Date: Fri, 18 Jun 2021 20:12:53 +0200
|
|
Subject: [PATCH] arm64: dts: rockchip: Add RK3399 ROCK Pi 4A+ board
|
|
|
|
ROCK Pi 4A+ board is the successor of ROCK Pi 4A board.
|
|
|
|
Differences to the original version are
|
|
- has RK3399 OP1 SoC revision
|
|
- has eMMC (16 or 32 GB) soldered on board (no changes required,
|
|
since it is enabled in rk3399-rock-pi-4.dtsi)
|
|
- dev boards have SPI flash soldered, but as per manufacturer response,
|
|
this won't be the case for mass production boards
|
|
|
|
Signed-off-by: Alex Bee <knaerzche@gmail.com>
|
|
Link: https://lore.kernel.org/r/20210618181256.27992-3-knaerzche@gmail.com
|
|
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
|
|
---
|
|
arch/arm64/boot/dts/rockchip/Makefile | 1 +
|
|
.../boot/dts/rockchip/rk3399-rock-pi-4a-plus.dts | 14 ++++++++++++++
|
|
2 files changed, 15 insertions(+)
|
|
create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4a-plus.dts
|
|
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4a-plus.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4a-plus.dts
|
|
new file mode 100644
|
|
index 000000000000..281a04b2f5e9
|
|
--- /dev/null
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4a-plus.dts
|
|
@@ -0,0 +1,14 @@
|
|
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
|
+/*
|
|
+ * Copyright (c) 2019 Akash Gajjar <Akash_Gajjar@mentor.com>
|
|
+ * Copyright (c) 2019 Pragnesh Patel <Pragnesh_Patel@mentor.com>
|
|
+ */
|
|
+
|
|
+/dts-v1/;
|
|
+#include "rk3399-rock-pi-4.dtsi"
|
|
+#include "rk3399-op1-opp.dtsi"
|
|
+
|
|
+/ {
|
|
+ model = "Radxa ROCK Pi 4A+";
|
|
+ compatible = "radxa,rockpi4a-plus", "radxa,rockpi4", "rockchip,rk3399";
|
|
+};
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Alex Bee <knaerzche@gmail.com>
|
|
Date: Fri, 18 Jun 2021 20:12:54 +0200
|
|
Subject: [PATCH] arm64: dts: rockchip: Add RK3399 ROCK Pi 4B+ board
|
|
|
|
ROCK Pi 4B+ board is the successor of ROCK Pi 4B board.
|
|
|
|
Differences to the original version are
|
|
- has RK3399 OP1 SoC revision
|
|
- has eMMC (16 or 32 GB) soldered on board (no changes required,
|
|
since it is enabled in rk3399-rock-pi-4.dtsi)
|
|
- dev boards have SPI flash soldered, but as per manufacturer response,
|
|
this won't be the case for mass production boards
|
|
|
|
Signed-off-by: Alex Bee <knaerzche@gmail.com>
|
|
Link: https://lore.kernel.org/r/20210618181256.27992-4-knaerzche@gmail.com
|
|
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
|
|
---
|
|
arch/arm64/boot/dts/rockchip/Makefile | 1 +
|
|
.../dts/rockchip/rk3399-rock-pi-4b-plus.dts | 47 +++++++++++++++++++
|
|
2 files changed, 48 insertions(+)
|
|
create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b-plus.dts
|
|
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b-plus.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b-plus.dts
|
|
new file mode 100644
|
|
index 000000000000..dfad13d2ab24
|
|
--- /dev/null
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b-plus.dts
|
|
@@ -0,0 +1,47 @@
|
|
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
|
+/*
|
|
+ * Copyright (c) 2019 Akash Gajjar <Akash_Gajjar@mentor.com>
|
|
+ * Copyright (c) 2019 Pragnesh Patel <Pragnesh_Patel@mentor.com>
|
|
+ */
|
|
+
|
|
+/dts-v1/;
|
|
+#include "rk3399-rock-pi-4.dtsi"
|
|
+#include "rk3399-op1-opp.dtsi"
|
|
+
|
|
+/ {
|
|
+ model = "Radxa ROCK Pi 4B+";
|
|
+ compatible = "radxa,rockpi4b-plus", "radxa,rockpi4", "rockchip,rk3399";
|
|
+
|
|
+ aliases {
|
|
+ mmc2 = &sdio0;
|
|
+ };
|
|
+};
|
|
+
|
|
+&sdio0 {
|
|
+ status = "okay";
|
|
+
|
|
+ brcmf: wifi@1 {
|
|
+ compatible = "brcm,bcm4329-fmac";
|
|
+ reg = <1>;
|
|
+ interrupt-parent = <&gpio0>;
|
|
+ interrupts = <RK_PA3 GPIO_ACTIVE_HIGH>;
|
|
+ interrupt-names = "host-wake";
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&wifi_host_wake_l>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&uart0 {
|
|
+ status = "okay";
|
|
+
|
|
+ bluetooth {
|
|
+ compatible = "brcm,bcm43438-bt";
|
|
+ clocks = <&rk808 1>;
|
|
+ clock-names = "ext_clock";
|
|
+ device-wakeup-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>;
|
|
+ host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>;
|
|
+ shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>;
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>;
|
|
+ };
|
|
+};
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Alex Bee <knaerzche@gmail.com>
|
|
Date: Fri, 18 Jun 2021 20:12:55 +0200
|
|
Subject: [PATCH] arm64: dts: rockchip: add ES8316 codec for ROCK Pi 4
|
|
|
|
ROCK Pi 4 boards have the codec connected to i2s0 and it is accessible
|
|
via i2c1 address 0x11.
|
|
Add an audio-graph-card for it.
|
|
|
|
Signed-off-by: Alex Bee <knaerzche@gmail.com>
|
|
Link: https://lore.kernel.org/r/20210618181256.27992-5-knaerzche@gmail.com
|
|
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
|
|
---
|
|
.../boot/dts/rockchip/rk3399-rock-pi-4.dtsi | 28 +++++++++++++++++++
|
|
1 file changed, 28 insertions(+)
|
|
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
|
|
index b28888ea9262..b49072af4014 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
|
|
@@ -36,6 +36,12 @@ sdio_pwrseq: sdio-pwrseq {
|
|
reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
|
|
};
|
|
|
|
+ sound {
|
|
+ compatible = "audio-graph-card";
|
|
+ label = "Analog";
|
|
+ dais = <&i2s0_p0>;
|
|
+ };
|
|
+
|
|
vcc12v_dcin: dc-12v {
|
|
compatible = "regulator-fixed";
|
|
regulator-name = "vcc12v_dcin";
|
|
@@ -422,6 +428,20 @@ &i2c1 {
|
|
i2c-scl-rising-time-ns = <300>;
|
|
i2c-scl-falling-time-ns = <15>;
|
|
status = "okay";
|
|
+
|
|
+ es8316: codec@11 {
|
|
+ compatible = "everest,es8316";
|
|
+ reg = <0x11>;
|
|
+ clocks = <&cru SCLK_I2S_8CH_OUT>;
|
|
+ clock-names = "mclk";
|
|
+ #sound-dai-cells = <0>;
|
|
+
|
|
+ port {
|
|
+ es8316_p0_0: endpoint {
|
|
+ remote-endpoint = <&i2s0_p0_0>;
|
|
+ };
|
|
+ };
|
|
+ };
|
|
};
|
|
|
|
&i2c3 {
|
|
@@ -441,6 +461,14 @@ &i2s0 {
|
|
rockchip,capture-channels = <2>;
|
|
rockchip,playback-channels = <2>;
|
|
status = "okay";
|
|
+
|
|
+ i2s0_p0: port {
|
|
+ i2s0_p0_0: endpoint {
|
|
+ dai-format = "i2s";
|
|
+ mclk-fs = <256>;
|
|
+ remote-endpoint = <&es8316_p0_0>;
|
|
+ };
|
|
+ };
|
|
};
|
|
|
|
&i2s1 {
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Alex Bee <knaerzche@gmail.com>
|
|
Date: Fri, 18 Jun 2021 20:12:56 +0200
|
|
Subject: [PATCH] arm64: dts: rockchip: add SPDIF node for ROCK Pi 4
|
|
|
|
Add a SPDIF audio-graph-card to ROCK Pi 4 device tree.
|
|
|
|
It's not enabled by default since all dma channels are used by
|
|
the (already) enabled i2s0/1/2 and the pin is muxed with GPIO4_C5
|
|
which might be in use already.
|
|
If enabled SPDIF_TX will be available at pin #15.
|
|
|
|
Signed-off-by: Alex Bee <knaerzche@gmail.com>
|
|
Link: https://lore.kernel.org/r/20210618181256.27992-6-knaerzche@gmail.com
|
|
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
|
|
---
|
|
.../boot/dts/rockchip/rk3399-rock-pi-4.dtsi | 26 +++++++++++++++++++
|
|
1 file changed, 26 insertions(+)
|
|
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
|
|
index b49072af4014..98136c88fa49 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
|
|
@@ -42,6 +42,23 @@ sound {
|
|
dais = <&i2s0_p0>;
|
|
};
|
|
|
|
+ sound-dit {
|
|
+ compatible = "audio-graph-card";
|
|
+ label = "SPDIF";
|
|
+ dais = <&spdif_p0>;
|
|
+ };
|
|
+
|
|
+ spdif-dit {
|
|
+ compatible = "linux,spdif-dit";
|
|
+ #sound-dai-cells = <0>;
|
|
+
|
|
+ port {
|
|
+ dit_p0_0: endpoint {
|
|
+ remote-endpoint = <&spdif_p0_0>;
|
|
+ };
|
|
+ };
|
|
+ };
|
|
+
|
|
vcc12v_dcin: dc-12v {
|
|
compatible = "regulator-fixed";
|
|
regulator-name = "vcc12v_dcin";
|
|
@@ -631,6 +648,15 @@ &sdhci {
|
|
status = "okay";
|
|
};
|
|
|
|
+&spdif {
|
|
+
|
|
+ spdif_p0: port {
|
|
+ spdif_p0_0: endpoint {
|
|
+ remote-endpoint = <&dit_p0_0>;
|
|
+ };
|
|
+ };
|
|
+};
|
|
+
|
|
&tcphy0 {
|
|
status = "okay";
|
|
};
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
|
|
Date: Thu, 22 Jul 2021 09:39:55 +0200
|
|
Subject: [PATCH] arm64: dts: rockchip: add csi-dphy to px30
|
|
|
|
Add the CSI dphy node to the core px30 devicetree for later use
|
|
with the rkisp.
|
|
|
|
Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
|
|
Link: https://lore.kernel.org/r/20210722073955.1192168-1-heiko@sntech.de
|
|
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
|
|
---
|
|
arch/arm64/boot/dts/rockchip/px30.dtsi | 13 +++++++++++++
|
|
1 file changed, 13 insertions(+)
|
|
|
|
diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi
|
|
index 248ebb61aa79..6e53a4cc75e6 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/px30.dtsi
|
|
+++ b/arch/arm64/boot/dts/rockchip/px30.dtsi
|
|
@@ -864,6 +864,19 @@ dsi_dphy: phy@ff2e0000 {
|
|
status = "disabled";
|
|
};
|
|
|
|
+ csi_dphy: phy@ff2f0000 {
|
|
+ compatible = "rockchip,px30-csi-dphy";
|
|
+ reg = <0x0 0xff2f0000 0x0 0x4000>;
|
|
+ clocks = <&cru PCLK_MIPICSIPHY>;
|
|
+ clock-names = "pclk";
|
|
+ #phy-cells = <0>;
|
|
+ power-domains = <&power PX30_PD_VI>;
|
|
+ resets = <&cru SRST_MIPICSIPHY_P>;
|
|
+ reset-names = "apb";
|
|
+ rockchip,grf = <&grf>;
|
|
+ status = "disabled";
|
|
+ };
|
|
+
|
|
usb20_otg: usb@ff300000 {
|
|
compatible = "rockchip,px30-usb", "rockchip,rk3066-usb",
|
|
"snps,dwc2";
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
|
|
Date: Wed, 10 Feb 2021 12:10:18 +0100
|
|
Subject: [PATCH] arm64: dts: rockchip: add #phy-cells to mipi-dsi1 on rk3399
|
|
|
|
The dsi controller includes access to the dphy which might be used
|
|
not only for dsi output but also for csi input on dsi1, so add the
|
|
necessary #phy-cells to allow it to be used as phy.
|
|
|
|
Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
|
|
Tested-by: Sebastian Fricke <sebastian.fricke@posteo.net>
|
|
Acked-by: Helen Koike <helen.koike@collabora.com>
|
|
Link: https://lore.kernel.org/r/20210210111020.2476369-5-heiko@sntech.de
|
|
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
|
|
---
|
|
arch/arm64/boot/dts/rockchip/rk3399.dtsi | 1 +
|
|
1 file changed, 1 insertion(+)
|
|
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
|
|
index aa5d7dca3432..8d68775365a3 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
|
|
@@ -1870,6 +1870,7 @@ mipi_dsi1: mipi@ff968000 {
|
|
rockchip,grf = <&grf>;
|
|
#address-cells = <1>;
|
|
#size-cells = <0>;
|
|
+ #phy-cells = <0>;
|
|
status = "disabled";
|
|
|
|
ports {
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
|
|
Date: Wed, 10 Feb 2021 12:10:19 +0100
|
|
Subject: [PATCH] arm64: dts: rockchip: add cif clk-control pinctrl for rk3399
|
|
|
|
This enables variant a of the clkout signal for camera applications
|
|
and also the cifclkin pinctrl setting.
|
|
|
|
Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
|
|
Tested-by: Sebastian Fricke <sebastian.fricke@posteo.net>
|
|
Acked-by: Helen Koike <helen.koike@collabora.com>
|
|
Link: https://lore.kernel.org/r/20210210111020.2476369-6-heiko@sntech.de
|
|
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
|
|
---
|
|
arch/arm64/boot/dts/rockchip/rk3399.dtsi | 12 ++++++++++++
|
|
1 file changed, 12 insertions(+)
|
|
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
|
|
index 8d68775365a3..493042bc20c0 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
|
|
@@ -2107,6 +2107,18 @@ clk_32k: clk-32k {
|
|
};
|
|
};
|
|
|
|
+ cif {
|
|
+ cif_clkin: cif-clkin {
|
|
+ rockchip,pins =
|
|
+ <2 RK_PB2 3 &pcfg_pull_none>;
|
|
+ };
|
|
+
|
|
+ cif_clkouta: cif-clkouta {
|
|
+ rockchip,pins =
|
|
+ <2 RK_PB3 3 &pcfg_pull_none>;
|
|
+ };
|
|
+ };
|
|
+
|
|
edp {
|
|
edp_hpd: edp-hpd {
|
|
rockchip,pins =
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Chris Morgan <macromorgan@hotmail.com>
|
|
Date: Thu, 12 Aug 2021 21:45:43 +0800
|
|
Subject: [PATCH] arm64: dts: rockchip: Add SFC to PX30
|
|
|
|
Add a devicetree entry for the Rockchip SFC for the PX30 SOC.
|
|
|
|
Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
|
|
Signed-off-by: Jon Lin <jon.lin@rock-chips.com>
|
|
Link: https://lore.kernel.org/r/20210812134546.31340-4-jon.lin@rock-chips.com
|
|
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
|
|
---
|
|
arch/arm64/boot/dts/rockchip/px30.dtsi | 38 ++++++++++++++++++++++++++
|
|
1 file changed, 38 insertions(+)
|
|
|
|
diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi
|
|
index 185bcc5c16ac..64f643145688 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/px30.dtsi
|
|
+++ b/arch/arm64/boot/dts/rockchip/px30.dtsi
|
|
@@ -987,6 +987,18 @@ emmc: mmc@ff390000 {
|
|
status = "disabled";
|
|
};
|
|
|
|
+ sfc: spi@ff3a0000 {
|
|
+ compatible = "rockchip,sfc";
|
|
+ reg = <0x0 0xff3a0000 0x0 0x4000>;
|
|
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
|
|
+ clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
|
|
+ clock-names = "clk_sfc", "hclk_sfc";
|
|
+ pinctrl-0 = <&sfc_clk &sfc_cs0 &sfc_bus4>;
|
|
+ pinctrl-names = "default";
|
|
+ power-domains = <&power PX30_PD_MMC_NAND>;
|
|
+ status = "disabled";
|
|
+ };
|
|
+
|
|
nfc: nand-controller@ff3b0000 {
|
|
compatible = "rockchip,px30-nfc";
|
|
reg = <0x0 0xff3b0000 0x0 0x4000>;
|
|
@@ -2008,6 +2020,32 @@ flash_bus8: flash-bus8 {
|
|
};
|
|
};
|
|
|
|
+ sfc {
|
|
+ sfc_bus4: sfc-bus4 {
|
|
+ rockchip,pins =
|
|
+ <1 RK_PA0 3 &pcfg_pull_none>,
|
|
+ <1 RK_PA1 3 &pcfg_pull_none>,
|
|
+ <1 RK_PA2 3 &pcfg_pull_none>,
|
|
+ <1 RK_PA3 3 &pcfg_pull_none>;
|
|
+ };
|
|
+
|
|
+ sfc_bus2: sfc-bus2 {
|
|
+ rockchip,pins =
|
|
+ <1 RK_PA0 3 &pcfg_pull_none>,
|
|
+ <1 RK_PA1 3 &pcfg_pull_none>;
|
|
+ };
|
|
+
|
|
+ sfc_cs0: sfc-cs0 {
|
|
+ rockchip,pins =
|
|
+ <1 RK_PA4 3 &pcfg_pull_none>;
|
|
+ };
|
|
+
|
|
+ sfc_clk: sfc-clk {
|
|
+ rockchip,pins =
|
|
+ <1 RK_PB1 3 &pcfg_pull_none>;
|
|
+ };
|
|
+ };
|
|
+
|
|
lcdc {
|
|
lcdc_rgb_dclk_pin: lcdc-rgb-dclk-pin {
|
|
rockchip,pins =
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Chris Morgan <macromorgan@hotmail.com>
|
|
Date: Thu, 12 Aug 2021 21:46:38 +0800
|
|
Subject: [PATCH] arm64: dts: rockchip: Add SFC to RK3308
|
|
|
|
Add a devicetree entry for the Rockchip SFC for the RK3308 SOC.
|
|
|
|
Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
|
|
Signed-off-by: Jon Lin <jon.lin@rock-chips.com>
|
|
Link: https://lore.kernel.org/r/20210812134639.31586-1-jon.lin@rock-chips.com
|
|
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
|
|
---
|
|
arch/arm64/boot/dts/rockchip/rk3308.dtsi | 37 ++++++++++++++++++++++++
|
|
1 file changed, 37 insertions(+)
|
|
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3308.dtsi b/arch/arm64/boot/dts/rockchip/rk3308.dtsi
|
|
index a185901aba9a..ce6f4a28d169 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi
|
|
@@ -731,6 +731,17 @@ gmac: ethernet@ff4e0000 {
|
|
status = "disabled";
|
|
};
|
|
|
|
+ sfc: spi@ff4c0000 {
|
|
+ compatible = "rockchip,sfc";
|
|
+ reg = <0x0 0xff4c0000 0x0 0x4000>;
|
|
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
|
|
+ clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
|
|
+ clock-names = "clk_sfc", "hclk_sfc";
|
|
+ pinctrl-0 = <&sfc_clk &sfc_cs0 &sfc_bus4>;
|
|
+ pinctrl-names = "default";
|
|
+ status = "disabled";
|
|
+ };
|
|
+
|
|
cru: clock-controller@ff500000 {
|
|
compatible = "rockchip,rk3308-cru";
|
|
reg = <0x0 0xff500000 0x0 0x1000>;
|
|
@@ -1004,6 +1015,32 @@ flash_bus8: flash-bus8 {
|
|
};
|
|
};
|
|
|
|
+ sfc {
|
|
+ sfc_bus4: sfc-bus4 {
|
|
+ rockchip,pins =
|
|
+ <3 RK_PA0 3 &pcfg_pull_none>,
|
|
+ <3 RK_PA1 3 &pcfg_pull_none>,
|
|
+ <3 RK_PA2 3 &pcfg_pull_none>,
|
|
+ <3 RK_PA3 3 &pcfg_pull_none>;
|
|
+ };
|
|
+
|
|
+ sfc_bus2: sfc-bus2 {
|
|
+ rockchip,pins =
|
|
+ <3 RK_PA0 3 &pcfg_pull_none>,
|
|
+ <3 RK_PA1 3 &pcfg_pull_none>;
|
|
+ };
|
|
+
|
|
+ sfc_cs0: sfc-cs0 {
|
|
+ rockchip,pins =
|
|
+ <3 RK_PA4 3 &pcfg_pull_none>;
|
|
+ };
|
|
+
|
|
+ sfc_clk: sfc-clk {
|
|
+ rockchip,pins =
|
|
+ <3 RK_PA5 3 &pcfg_pull_none>;
|
|
+ };
|
|
+ };
|
|
+
|
|
gmac {
|
|
rmii_pins: rmii-pins {
|
|
rockchip,pins =
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Chris Morgan <macromorgan@hotmail.com>
|
|
Date: Thu, 12 Aug 2021 21:45:41 +0800
|
|
Subject: [PATCH] spi: rockchip-sfc: Bindings for Rockchip serial flash
|
|
controller
|
|
|
|
Add bindings for the Rockchip serial flash controller. New device
|
|
specific parameter of rockchip,sfc-no-dma included in documentation.
|
|
|
|
Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
|
|
Signed-off-by: Jon Lin <jon.lin@rock-chips.com>
|
|
Tested-by: Peter Geis <pgwipeout@gmail.com>
|
|
Link: https://lore.kernel.org/r/20210812134546.31340-2-jon.lin@rock-chips.com
|
|
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
---
|
|
.../devicetree/bindings/spi/rockchip-sfc.yaml | 91 +++++++++++++++++++
|
|
1 file changed, 91 insertions(+)
|
|
create mode 100644 Documentation/devicetree/bindings/spi/rockchip-sfc.yaml
|
|
|
|
diff --git a/Documentation/devicetree/bindings/spi/rockchip-sfc.yaml b/Documentation/devicetree/bindings/spi/rockchip-sfc.yaml
|
|
new file mode 100644
|
|
index 000000000000..339fb39529f3
|
|
--- /dev/null
|
|
+++ b/Documentation/devicetree/bindings/spi/rockchip-sfc.yaml
|
|
@@ -0,0 +1,91 @@
|
|
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
|
+%YAML 1.2
|
|
+---
|
|
+$id: http://devicetree.org/schemas/spi/rockchip-sfc.yaml#
|
|
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
|
+
|
|
+title: Rockchip Serial Flash Controller (SFC)
|
|
+
|
|
+maintainers:
|
|
+ - Heiko Stuebner <heiko@sntech.de>
|
|
+ - Chris Morgan <macromorgan@hotmail.com>
|
|
+
|
|
+allOf:
|
|
+ - $ref: spi-controller.yaml#
|
|
+
|
|
+properties:
|
|
+ compatible:
|
|
+ const: rockchip,sfc
|
|
+ description:
|
|
+ The rockchip sfc controller is a standalone IP with version register,
|
|
+ and the driver can handle all the feature difference inside the IP
|
|
+ depending on the version register.
|
|
+
|
|
+ reg:
|
|
+ maxItems: 1
|
|
+
|
|
+ interrupts:
|
|
+ maxItems: 1
|
|
+
|
|
+ clocks:
|
|
+ items:
|
|
+ - description: Bus Clock
|
|
+ - description: Module Clock
|
|
+
|
|
+ clock-names:
|
|
+ items:
|
|
+ - const: clk_sfc
|
|
+ - const: hclk_sfc
|
|
+
|
|
+ power-domains:
|
|
+ maxItems: 1
|
|
+
|
|
+ rockchip,sfc-no-dma:
|
|
+ description: Disable DMA and utilize FIFO mode only
|
|
+ type: boolean
|
|
+
|
|
+patternProperties:
|
|
+ "^flash@[0-3]$":
|
|
+ type: object
|
|
+ properties:
|
|
+ reg:
|
|
+ minimum: 0
|
|
+ maximum: 3
|
|
+
|
|
+required:
|
|
+ - compatible
|
|
+ - reg
|
|
+ - interrupts
|
|
+ - clocks
|
|
+ - clock-names
|
|
+
|
|
+unevaluatedProperties: false
|
|
+
|
|
+examples:
|
|
+ - |
|
|
+ #include <dt-bindings/clock/px30-cru.h>
|
|
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
|
|
+ #include <dt-bindings/power/px30-power.h>
|
|
+
|
|
+ sfc: spi@ff3a0000 {
|
|
+ compatible = "rockchip,sfc";
|
|
+ reg = <0xff3a0000 0x4000>;
|
|
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
|
|
+ clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
|
|
+ clock-names = "clk_sfc", "hclk_sfc";
|
|
+ pinctrl-0 = <&sfc_clk &sfc_cs &sfc_bus2>;
|
|
+ pinctrl-names = "default";
|
|
+ power-domains = <&power PX30_PD_MMC_NAND>;
|
|
+ #address-cells = <1>;
|
|
+ #size-cells = <0>;
|
|
+
|
|
+ flash@0 {
|
|
+ compatible = "jedec,spi-nor";
|
|
+ reg = <0>;
|
|
+ spi-max-frequency = <108000000>;
|
|
+ spi-rx-bus-width = <2>;
|
|
+ spi-tx-bus-width = <2>;
|
|
+ };
|
|
+ };
|
|
+
|
|
+...
|
|
|
|
diff --git a/drivers/spi/spi-rockchip-sfc.c b/drivers/spi/spi-rockchip-sfc.c
|
|
new file mode 100644
|
|
index 000000000000..7c4d47fe80c2
|
|
--- /dev/null
|
|
+++ b/drivers/spi/spi-rockchip-sfc.c
|
|
@@ -0,0 +1,694 @@
|
|
+// SPDX-License-Identifier: GPL-2.0-only
|
|
+/*
|
|
+ * Rockchip Serial Flash Controller Driver
|
|
+ *
|
|
+ * Copyright (c) 2017-2021, Rockchip Inc.
|
|
+ * Author: Shawn Lin <shawn.lin@rock-chips.com>
|
|
+ * Chris Morgan <macroalpha82@gmail.com>
|
|
+ * Jon Lin <Jon.lin@rock-chips.com>
|
|
+ */
|
|
+
|
|
+#include <linux/bitops.h>
|
|
+#include <linux/clk.h>
|
|
+#include <linux/completion.h>
|
|
+#include <linux/dma-mapping.h>
|
|
+#include <linux/iopoll.h>
|
|
+#include <linux/mm.h>
|
|
+#include <linux/module.h>
|
|
+#include <linux/of.h>
|
|
+#include <linux/platform_device.h>
|
|
+#include <linux/slab.h>
|
|
+#include <linux/interrupt.h>
|
|
+#include <linux/spi/spi-mem.h>
|
|
+
|
|
+/* System control */
|
|
+#define SFC_CTRL 0x0
|
|
+#define SFC_CTRL_PHASE_SEL_NEGETIVE BIT(1)
|
|
+#define SFC_CTRL_CMD_BITS_SHIFT 8
|
|
+#define SFC_CTRL_ADDR_BITS_SHIFT 10
|
|
+#define SFC_CTRL_DATA_BITS_SHIFT 12
|
|
+
|
|
+/* Interrupt mask */
|
|
+#define SFC_IMR 0x4
|
|
+#define SFC_IMR_RX_FULL BIT(0)
|
|
+#define SFC_IMR_RX_UFLOW BIT(1)
|
|
+#define SFC_IMR_TX_OFLOW BIT(2)
|
|
+#define SFC_IMR_TX_EMPTY BIT(3)
|
|
+#define SFC_IMR_TRAN_FINISH BIT(4)
|
|
+#define SFC_IMR_BUS_ERR BIT(5)
|
|
+#define SFC_IMR_NSPI_ERR BIT(6)
|
|
+#define SFC_IMR_DMA BIT(7)
|
|
+
|
|
+/* Interrupt clear */
|
|
+#define SFC_ICLR 0x8
|
|
+#define SFC_ICLR_RX_FULL BIT(0)
|
|
+#define SFC_ICLR_RX_UFLOW BIT(1)
|
|
+#define SFC_ICLR_TX_OFLOW BIT(2)
|
|
+#define SFC_ICLR_TX_EMPTY BIT(3)
|
|
+#define SFC_ICLR_TRAN_FINISH BIT(4)
|
|
+#define SFC_ICLR_BUS_ERR BIT(5)
|
|
+#define SFC_ICLR_NSPI_ERR BIT(6)
|
|
+#define SFC_ICLR_DMA BIT(7)
|
|
+
|
|
+/* FIFO threshold level */
|
|
+#define SFC_FTLR 0xc
|
|
+#define SFC_FTLR_TX_SHIFT 0
|
|
+#define SFC_FTLR_TX_MASK 0x1f
|
|
+#define SFC_FTLR_RX_SHIFT 8
|
|
+#define SFC_FTLR_RX_MASK 0x1f
|
|
+
|
|
+/* Reset FSM and FIFO */
|
|
+#define SFC_RCVR 0x10
|
|
+#define SFC_RCVR_RESET BIT(0)
|
|
+
|
|
+/* Enhanced mode */
|
|
+#define SFC_AX 0x14
|
|
+
|
|
+/* Address Bit number */
|
|
+#define SFC_ABIT 0x18
|
|
+
|
|
+/* Interrupt status */
|
|
+#define SFC_ISR 0x1c
|
|
+#define SFC_ISR_RX_FULL_SHIFT BIT(0)
|
|
+#define SFC_ISR_RX_UFLOW_SHIFT BIT(1)
|
|
+#define SFC_ISR_TX_OFLOW_SHIFT BIT(2)
|
|
+#define SFC_ISR_TX_EMPTY_SHIFT BIT(3)
|
|
+#define SFC_ISR_TX_FINISH_SHIFT BIT(4)
|
|
+#define SFC_ISR_BUS_ERR_SHIFT BIT(5)
|
|
+#define SFC_ISR_NSPI_ERR_SHIFT BIT(6)
|
|
+#define SFC_ISR_DMA_SHIFT BIT(7)
|
|
+
|
|
+/* FIFO status */
|
|
+#define SFC_FSR 0x20
|
|
+#define SFC_FSR_TX_IS_FULL BIT(0)
|
|
+#define SFC_FSR_TX_IS_EMPTY BIT(1)
|
|
+#define SFC_FSR_RX_IS_EMPTY BIT(2)
|
|
+#define SFC_FSR_RX_IS_FULL BIT(3)
|
|
+#define SFC_FSR_TXLV_MASK GENMASK(12, 8)
|
|
+#define SFC_FSR_TXLV_SHIFT 8
|
|
+#define SFC_FSR_RXLV_MASK GENMASK(20, 16)
|
|
+#define SFC_FSR_RXLV_SHIFT 16
|
|
+
|
|
+/* FSM status */
|
|
+#define SFC_SR 0x24
|
|
+#define SFC_SR_IS_IDLE 0x0
|
|
+#define SFC_SR_IS_BUSY 0x1
|
|
+
|
|
+/* Raw interrupt status */
|
|
+#define SFC_RISR 0x28
|
|
+#define SFC_RISR_RX_FULL BIT(0)
|
|
+#define SFC_RISR_RX_UNDERFLOW BIT(1)
|
|
+#define SFC_RISR_TX_OVERFLOW BIT(2)
|
|
+#define SFC_RISR_TX_EMPTY BIT(3)
|
|
+#define SFC_RISR_TRAN_FINISH BIT(4)
|
|
+#define SFC_RISR_BUS_ERR BIT(5)
|
|
+#define SFC_RISR_NSPI_ERR BIT(6)
|
|
+#define SFC_RISR_DMA BIT(7)
|
|
+
|
|
+/* Version */
|
|
+#define SFC_VER 0x2C
|
|
+#define SFC_VER_3 0x3
|
|
+#define SFC_VER_4 0x4
|
|
+#define SFC_VER_5 0x5
|
|
+
|
|
+/* Delay line controller resiter */
|
|
+#define SFC_DLL_CTRL0 0x3C
|
|
+#define SFC_DLL_CTRL0_SCLK_SMP_DLL BIT(15)
|
|
+#define SFC_DLL_CTRL0_DLL_MAX_VER4 0xFFU
|
|
+#define SFC_DLL_CTRL0_DLL_MAX_VER5 0x1FFU
|
|
+
|
|
+/* Master trigger */
|
|
+#define SFC_DMA_TRIGGER 0x80
|
|
+#define SFC_DMA_TRIGGER_START 1
|
|
+
|
|
+/* Src or Dst addr for master */
|
|
+#define SFC_DMA_ADDR 0x84
|
|
+
|
|
+/* Length control register extension 32GB */
|
|
+#define SFC_LEN_CTRL 0x88
|
|
+#define SFC_LEN_CTRL_TRB_SEL 1
|
|
+#define SFC_LEN_EXT 0x8C
|
|
+
|
|
+/* Command */
|
|
+#define SFC_CMD 0x100
|
|
+#define SFC_CMD_IDX_SHIFT 0
|
|
+#define SFC_CMD_DUMMY_SHIFT 8
|
|
+#define SFC_CMD_DIR_SHIFT 12
|
|
+#define SFC_CMD_DIR_RD 0
|
|
+#define SFC_CMD_DIR_WR 1
|
|
+#define SFC_CMD_ADDR_SHIFT 14
|
|
+#define SFC_CMD_ADDR_0BITS 0
|
|
+#define SFC_CMD_ADDR_24BITS 1
|
|
+#define SFC_CMD_ADDR_32BITS 2
|
|
+#define SFC_CMD_ADDR_XBITS 3
|
|
+#define SFC_CMD_TRAN_BYTES_SHIFT 16
|
|
+#define SFC_CMD_CS_SHIFT 30
|
|
+
|
|
+/* Address */
|
|
+#define SFC_ADDR 0x104
|
|
+
|
|
+/* Data */
|
|
+#define SFC_DATA 0x108
|
|
+
|
|
+/* The controller and documentation reports that it supports up to 4 CS
|
|
+ * devices (0-3), however I have only been able to test a single CS (CS 0)
|
|
+ * due to the configuration of my device.
|
|
+ */
|
|
+#define SFC_MAX_CHIPSELECT_NUM 4
|
|
+
|
|
+/* The SFC can transfer max 16KB - 1 at one time
|
|
+ * we set it to 15.5KB here for alignment.
|
|
+ */
|
|
+#define SFC_MAX_IOSIZE_VER3 (512 * 31)
|
|
+
|
|
+/* DMA is only enabled for large data transmission */
|
|
+#define SFC_DMA_TRANS_THRETHOLD (0x40)
|
|
+
|
|
+/* Maximum clock values from datasheet suggest keeping clock value under
|
|
+ * 150MHz. No minimum or average value is suggested.
|
|
+ */
|
|
+#define SFC_MAX_SPEED (150 * 1000 * 1000)
|
|
+
|
|
+struct rockchip_sfc {
|
|
+ struct device *dev;
|
|
+ void __iomem *regbase;
|
|
+ struct clk *hclk;
|
|
+ struct clk *clk;
|
|
+ u32 frequency;
|
|
+ /* virtual mapped addr for dma_buffer */
|
|
+ void *buffer;
|
|
+ dma_addr_t dma_buffer;
|
|
+ struct completion cp;
|
|
+ bool use_dma;
|
|
+ u32 max_iosize;
|
|
+ u16 version;
|
|
+};
|
|
+
|
|
+static int rockchip_sfc_reset(struct rockchip_sfc *sfc)
|
|
+{
|
|
+ int err;
|
|
+ u32 status;
|
|
+
|
|
+ writel_relaxed(SFC_RCVR_RESET, sfc->regbase + SFC_RCVR);
|
|
+
|
|
+ err = readl_poll_timeout(sfc->regbase + SFC_RCVR, status,
|
|
+ !(status & SFC_RCVR_RESET), 20,
|
|
+ jiffies_to_usecs(HZ));
|
|
+ if (err)
|
|
+ dev_err(sfc->dev, "SFC reset never finished\n");
|
|
+
|
|
+ /* Still need to clear the masked interrupt from RISR */
|
|
+ writel_relaxed(0xFFFFFFFF, sfc->regbase + SFC_ICLR);
|
|
+
|
|
+ dev_dbg(sfc->dev, "reset\n");
|
|
+
|
|
+ return err;
|
|
+}
|
|
+
|
|
+static u16 rockchip_sfc_get_version(struct rockchip_sfc *sfc)
|
|
+{
|
|
+ return (u16)(readl(sfc->regbase + SFC_VER) & 0xffff);
|
|
+}
|
|
+
|
|
+static u32 rockchip_sfc_get_max_iosize(struct rockchip_sfc *sfc)
|
|
+{
|
|
+ return SFC_MAX_IOSIZE_VER3;
|
|
+}
|
|
+
|
|
+static void rockchip_sfc_irq_unmask(struct rockchip_sfc *sfc, u32 mask)
|
|
+{
|
|
+ u32 reg;
|
|
+
|
|
+ /* Enable transfer complete interrupt */
|
|
+ reg = readl(sfc->regbase + SFC_IMR);
|
|
+ reg &= ~mask;
|
|
+ writel(reg, sfc->regbase + SFC_IMR);
|
|
+}
|
|
+
|
|
+static void rockchip_sfc_irq_mask(struct rockchip_sfc *sfc, u32 mask)
|
|
+{
|
|
+ u32 reg;
|
|
+
|
|
+ /* Disable transfer finish interrupt */
|
|
+ reg = readl(sfc->regbase + SFC_IMR);
|
|
+ reg |= mask;
|
|
+ writel(reg, sfc->regbase + SFC_IMR);
|
|
+}
|
|
+
|
|
+static int rockchip_sfc_init(struct rockchip_sfc *sfc)
|
|
+{
|
|
+ writel(0, sfc->regbase + SFC_CTRL);
|
|
+ writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR);
|
|
+ rockchip_sfc_irq_mask(sfc, 0xFFFFFFFF);
|
|
+ if (rockchip_sfc_get_version(sfc) >= SFC_VER_4)
|
|
+ writel(SFC_LEN_CTRL_TRB_SEL, sfc->regbase + SFC_LEN_CTRL);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int rockchip_sfc_wait_txfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us)
|
|
+{
|
|
+ int ret = 0;
|
|
+ u32 status;
|
|
+
|
|
+ ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status,
|
|
+ status & SFC_FSR_TXLV_MASK, 0,
|
|
+ timeout_us);
|
|
+ if (ret) {
|
|
+ dev_dbg(sfc->dev, "sfc wait tx fifo timeout\n");
|
|
+
|
|
+ ret = -ETIMEDOUT;
|
|
+ }
|
|
+
|
|
+ return (status & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT;
|
|
+}
|
|
+
|
|
+static int rockchip_sfc_wait_rxfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us)
|
|
+{
|
|
+ int ret = 0;
|
|
+ u32 status;
|
|
+
|
|
+ ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status,
|
|
+ status & SFC_FSR_RXLV_MASK, 0,
|
|
+ timeout_us);
|
|
+ if (ret) {
|
|
+ dev_dbg(sfc->dev, "sfc wait rx fifo timeout\n");
|
|
+
|
|
+ ret = -ETIMEDOUT;
|
|
+ }
|
|
+
|
|
+ return (status & SFC_FSR_RXLV_MASK) >> SFC_FSR_RXLV_SHIFT;
|
|
+}
|
|
+
|
|
+static void rockchip_sfc_adjust_op_work(struct spi_mem_op *op)
|
|
+{
|
|
+ if (unlikely(op->dummy.nbytes && !op->addr.nbytes)) {
|
|
+ /*
|
|
+ * SFC not support output DUMMY cycles right after CMD cycles, so
|
|
+ * treat it as ADDR cycles.
|
|
+ */
|
|
+ op->addr.nbytes = op->dummy.nbytes;
|
|
+ op->addr.buswidth = op->dummy.buswidth;
|
|
+ op->addr.val = 0xFFFFFFFFF;
|
|
+
|
|
+ op->dummy.nbytes = 0;
|
|
+ }
|
|
+}
|
|
+
|
|
+static int rockchip_sfc_xfer_setup(struct rockchip_sfc *sfc,
|
|
+ struct spi_mem *mem,
|
|
+ const struct spi_mem_op *op,
|
|
+ u32 len)
|
|
+{
|
|
+ u32 ctrl = 0, cmd = 0;
|
|
+
|
|
+ /* set CMD */
|
|
+ cmd = op->cmd.opcode;
|
|
+ ctrl |= ((op->cmd.buswidth >> 1) << SFC_CTRL_CMD_BITS_SHIFT);
|
|
+
|
|
+ /* set ADDR */
|
|
+ if (op->addr.nbytes) {
|
|
+ if (op->addr.nbytes == 4) {
|
|
+ cmd |= SFC_CMD_ADDR_32BITS << SFC_CMD_ADDR_SHIFT;
|
|
+ } else if (op->addr.nbytes == 3) {
|
|
+ cmd |= SFC_CMD_ADDR_24BITS << SFC_CMD_ADDR_SHIFT;
|
|
+ } else {
|
|
+ cmd |= SFC_CMD_ADDR_XBITS << SFC_CMD_ADDR_SHIFT;
|
|
+ writel(op->addr.nbytes * 8 - 1, sfc->regbase + SFC_ABIT);
|
|
+ }
|
|
+
|
|
+ ctrl |= ((op->addr.buswidth >> 1) << SFC_CTRL_ADDR_BITS_SHIFT);
|
|
+ }
|
|
+
|
|
+ /* set DUMMY */
|
|
+ if (op->dummy.nbytes) {
|
|
+ if (op->dummy.buswidth == 4)
|
|
+ cmd |= op->dummy.nbytes * 2 << SFC_CMD_DUMMY_SHIFT;
|
|
+ else if (op->dummy.buswidth == 2)
|
|
+ cmd |= op->dummy.nbytes * 4 << SFC_CMD_DUMMY_SHIFT;
|
|
+ else
|
|
+ cmd |= op->dummy.nbytes * 8 << SFC_CMD_DUMMY_SHIFT;
|
|
+ }
|
|
+
|
|
+ /* set DATA */
|
|
+ if (sfc->version >= SFC_VER_4) /* Clear it if no data to transfer */
|
|
+ writel(len, sfc->regbase + SFC_LEN_EXT);
|
|
+ else
|
|
+ cmd |= len << SFC_CMD_TRAN_BYTES_SHIFT;
|
|
+ if (len) {
|
|
+ if (op->data.dir == SPI_MEM_DATA_OUT)
|
|
+ cmd |= SFC_CMD_DIR_WR << SFC_CMD_DIR_SHIFT;
|
|
+
|
|
+ ctrl |= ((op->data.buswidth >> 1) << SFC_CTRL_DATA_BITS_SHIFT);
|
|
+ }
|
|
+ if (!len && op->addr.nbytes)
|
|
+ cmd |= SFC_CMD_DIR_WR << SFC_CMD_DIR_SHIFT;
|
|
+
|
|
+ /* set the Controller */
|
|
+ ctrl |= SFC_CTRL_PHASE_SEL_NEGETIVE;
|
|
+ cmd |= mem->spi->chip_select << SFC_CMD_CS_SHIFT;
|
|
+
|
|
+ dev_dbg(sfc->dev, "sfc addr.nbytes=%x(x%d) dummy.nbytes=%x(x%d)\n",
|
|
+ op->addr.nbytes, op->addr.buswidth,
|
|
+ op->dummy.nbytes, op->dummy.buswidth);
|
|
+ dev_dbg(sfc->dev, "sfc ctrl=%x cmd=%x addr=%llx len=%x\n",
|
|
+ ctrl, cmd, op->addr.val, len);
|
|
+
|
|
+ writel(ctrl, sfc->regbase + SFC_CTRL);
|
|
+ writel(cmd, sfc->regbase + SFC_CMD);
|
|
+ if (op->addr.nbytes)
|
|
+ writel(op->addr.val, sfc->regbase + SFC_ADDR);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int rockchip_sfc_write_fifo(struct rockchip_sfc *sfc, const u8 *buf, int len)
|
|
+{
|
|
+ u8 bytes = len & 0x3;
|
|
+ u32 dwords;
|
|
+ int tx_level;
|
|
+ u32 write_words;
|
|
+ u32 tmp = 0;
|
|
+
|
|
+ dwords = len >> 2;
|
|
+ while (dwords) {
|
|
+ tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000);
|
|
+ if (tx_level < 0)
|
|
+ return tx_level;
|
|
+ write_words = min_t(u32, tx_level, dwords);
|
|
+ iowrite32_rep(sfc->regbase + SFC_DATA, buf, write_words);
|
|
+ buf += write_words << 2;
|
|
+ dwords -= write_words;
|
|
+ }
|
|
+
|
|
+ /* write the rest non word aligned bytes */
|
|
+ if (bytes) {
|
|
+ tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000);
|
|
+ if (tx_level < 0)
|
|
+ return tx_level;
|
|
+ memcpy(&tmp, buf, bytes);
|
|
+ writel(tmp, sfc->regbase + SFC_DATA);
|
|
+ }
|
|
+
|
|
+ return len;
|
|
+}
|
|
+
|
|
+static int rockchip_sfc_read_fifo(struct rockchip_sfc *sfc, u8 *buf, int len)
|
|
+{
|
|
+ u8 bytes = len & 0x3;
|
|
+ u32 dwords;
|
|
+ u8 read_words;
|
|
+ int rx_level;
|
|
+ int tmp;
|
|
+
|
|
+ /* word aligned access only */
|
|
+ dwords = len >> 2;
|
|
+ while (dwords) {
|
|
+ rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000);
|
|
+ if (rx_level < 0)
|
|
+ return rx_level;
|
|
+ read_words = min_t(u32, rx_level, dwords);
|
|
+ ioread32_rep(sfc->regbase + SFC_DATA, buf, read_words);
|
|
+ buf += read_words << 2;
|
|
+ dwords -= read_words;
|
|
+ }
|
|
+
|
|
+ /* read the rest non word aligned bytes */
|
|
+ if (bytes) {
|
|
+ rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000);
|
|
+ if (rx_level < 0)
|
|
+ return rx_level;
|
|
+ tmp = readl(sfc->regbase + SFC_DATA);
|
|
+ memcpy(buf, &tmp, bytes);
|
|
+ }
|
|
+
|
|
+ return len;
|
|
+}
|
|
+
|
|
+static int rockchip_sfc_fifo_transfer_dma(struct rockchip_sfc *sfc, dma_addr_t dma_buf, size_t len)
|
|
+{
|
|
+ writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR);
|
|
+ writel((u32)dma_buf, sfc->regbase + SFC_DMA_ADDR);
|
|
+ writel(SFC_DMA_TRIGGER_START, sfc->regbase + SFC_DMA_TRIGGER);
|
|
+
|
|
+ return len;
|
|
+}
|
|
+
|
|
+static int rockchip_sfc_xfer_data_poll(struct rockchip_sfc *sfc,
|
|
+ const struct spi_mem_op *op, u32 len)
|
|
+{
|
|
+ dev_dbg(sfc->dev, "sfc xfer_poll len=%x\n", len);
|
|
+
|
|
+ if (op->data.dir == SPI_MEM_DATA_OUT)
|
|
+ return rockchip_sfc_write_fifo(sfc, op->data.buf.out, len);
|
|
+ else
|
|
+ return rockchip_sfc_read_fifo(sfc, op->data.buf.in, len);
|
|
+}
|
|
+
|
|
+static int rockchip_sfc_xfer_data_dma(struct rockchip_sfc *sfc,
|
|
+ const struct spi_mem_op *op, u32 len)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ dev_dbg(sfc->dev, "sfc xfer_dma len=%x\n", len);
|
|
+
|
|
+ if (op->data.dir == SPI_MEM_DATA_OUT)
|
|
+ memcpy_toio(sfc->buffer, op->data.buf.out, len);
|
|
+
|
|
+ ret = rockchip_sfc_fifo_transfer_dma(sfc, sfc->dma_buffer, len);
|
|
+ if (!wait_for_completion_timeout(&sfc->cp, msecs_to_jiffies(2000))) {
|
|
+ dev_err(sfc->dev, "DMA wait for transfer finish timeout\n");
|
|
+ ret = -ETIMEDOUT;
|
|
+ }
|
|
+ rockchip_sfc_irq_mask(sfc, SFC_IMR_DMA);
|
|
+ if (op->data.dir == SPI_MEM_DATA_IN)
|
|
+ memcpy_fromio(op->data.buf.in, sfc->buffer, len);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int rockchip_sfc_xfer_done(struct rockchip_sfc *sfc, u32 timeout_us)
|
|
+{
|
|
+ int ret = 0;
|
|
+ u32 status;
|
|
+
|
|
+ ret = readl_poll_timeout(sfc->regbase + SFC_SR, status,
|
|
+ !(status & SFC_SR_IS_BUSY),
|
|
+ 20, timeout_us);
|
|
+ if (ret) {
|
|
+ dev_err(sfc->dev, "wait sfc idle timeout\n");
|
|
+ rockchip_sfc_reset(sfc);
|
|
+
|
|
+ ret = -EIO;
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int rockchip_sfc_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
|
|
+{
|
|
+ struct rockchip_sfc *sfc = spi_master_get_devdata(mem->spi->master);
|
|
+ u32 len = op->data.nbytes;
|
|
+ int ret;
|
|
+
|
|
+ if (unlikely(mem->spi->max_speed_hz != sfc->frequency)) {
|
|
+ ret = clk_set_rate(sfc->clk, mem->spi->max_speed_hz);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ sfc->frequency = mem->spi->max_speed_hz;
|
|
+ dev_dbg(sfc->dev, "set_freq=%dHz real_freq=%ldHz\n",
|
|
+ sfc->frequency, clk_get_rate(sfc->clk));
|
|
+ }
|
|
+
|
|
+ rockchip_sfc_adjust_op_work((struct spi_mem_op *)op);
|
|
+ rockchip_sfc_xfer_setup(sfc, mem, op, len);
|
|
+ if (len) {
|
|
+ if (likely(sfc->use_dma) && len >= SFC_DMA_TRANS_THRETHOLD) {
|
|
+ init_completion(&sfc->cp);
|
|
+ rockchip_sfc_irq_unmask(sfc, SFC_IMR_DMA);
|
|
+ ret = rockchip_sfc_xfer_data_dma(sfc, op, len);
|
|
+ } else {
|
|
+ ret = rockchip_sfc_xfer_data_poll(sfc, op, len);
|
|
+ }
|
|
+
|
|
+ if (ret != len) {
|
|
+ dev_err(sfc->dev, "xfer data failed ret %d dir %d\n", ret, op->data.dir);
|
|
+
|
|
+ return -EIO;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return rockchip_sfc_xfer_done(sfc, 100000);
|
|
+}
|
|
+
|
|
+static int rockchip_sfc_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
|
|
+{
|
|
+ struct rockchip_sfc *sfc = spi_master_get_devdata(mem->spi->master);
|
|
+
|
|
+ op->data.nbytes = min(op->data.nbytes, sfc->max_iosize);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static const struct spi_controller_mem_ops rockchip_sfc_mem_ops = {
|
|
+ .exec_op = rockchip_sfc_exec_mem_op,
|
|
+ .adjust_op_size = rockchip_sfc_adjust_op_size,
|
|
+};
|
|
+
|
|
+static irqreturn_t rockchip_sfc_irq_handler(int irq, void *dev_id)
|
|
+{
|
|
+ struct rockchip_sfc *sfc = dev_id;
|
|
+ u32 reg;
|
|
+
|
|
+ reg = readl(sfc->regbase + SFC_RISR);
|
|
+
|
|
+ /* Clear interrupt */
|
|
+ writel_relaxed(reg, sfc->regbase + SFC_ICLR);
|
|
+
|
|
+ if (reg & SFC_RISR_DMA) {
|
|
+ complete(&sfc->cp);
|
|
+
|
|
+ return IRQ_HANDLED;
|
|
+ }
|
|
+
|
|
+ return IRQ_NONE;
|
|
+}
|
|
+
|
|
+static int rockchip_sfc_probe(struct platform_device *pdev)
|
|
+{
|
|
+ struct device *dev = &pdev->dev;
|
|
+ struct spi_master *master;
|
|
+ struct resource *res;
|
|
+ struct rockchip_sfc *sfc;
|
|
+ int ret;
|
|
+
|
|
+ master = devm_spi_alloc_master(&pdev->dev, sizeof(*sfc));
|
|
+ if (!master)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ master->flags = SPI_MASTER_HALF_DUPLEX;
|
|
+ master->mem_ops = &rockchip_sfc_mem_ops;
|
|
+ master->dev.of_node = pdev->dev.of_node;
|
|
+ master->mode_bits = SPI_TX_QUAD | SPI_TX_DUAL | SPI_RX_QUAD | SPI_RX_DUAL;
|
|
+ master->max_speed_hz = SFC_MAX_SPEED;
|
|
+ master->num_chipselect = SFC_MAX_CHIPSELECT_NUM;
|
|
+
|
|
+ sfc = spi_master_get_devdata(master);
|
|
+ sfc->dev = dev;
|
|
+
|
|
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
+ sfc->regbase = devm_ioremap_resource(dev, res);
|
|
+ if (IS_ERR(sfc->regbase))
|
|
+ return PTR_ERR(sfc->regbase);
|
|
+
|
|
+ sfc->clk = devm_clk_get(&pdev->dev, "clk_sfc");
|
|
+ if (IS_ERR(sfc->clk)) {
|
|
+ dev_err(&pdev->dev, "Failed to get sfc interface clk\n");
|
|
+ return PTR_ERR(sfc->clk);
|
|
+ }
|
|
+
|
|
+ sfc->hclk = devm_clk_get(&pdev->dev, "hclk_sfc");
|
|
+ if (IS_ERR(sfc->hclk)) {
|
|
+ dev_err(&pdev->dev, "Failed to get sfc ahb clk\n");
|
|
+ return PTR_ERR(sfc->hclk);
|
|
+ }
|
|
+
|
|
+ sfc->use_dma = !of_property_read_bool(sfc->dev->of_node,
|
|
+ "rockchip,sfc-no-dma");
|
|
+
|
|
+ if (sfc->use_dma) {
|
|
+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
|
|
+ if (ret) {
|
|
+ dev_warn(dev, "Unable to set dma mask\n");
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ sfc->buffer = dmam_alloc_coherent(dev, SFC_MAX_IOSIZE_VER3,
|
|
+ &sfc->dma_buffer,
|
|
+ GFP_KERNEL);
|
|
+ if (!sfc->buffer)
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+
|
|
+ ret = clk_prepare_enable(sfc->hclk);
|
|
+ if (ret) {
|
|
+ dev_err(&pdev->dev, "Failed to enable ahb clk\n");
|
|
+ goto err_hclk;
|
|
+ }
|
|
+
|
|
+ ret = clk_prepare_enable(sfc->clk);
|
|
+ if (ret) {
|
|
+ dev_err(&pdev->dev, "Failed to enable interface clk\n");
|
|
+ goto err_clk;
|
|
+ }
|
|
+
|
|
+ /* Find the irq */
|
|
+ ret = platform_get_irq(pdev, 0);
|
|
+ if (ret < 0) {
|
|
+ dev_err(dev, "Failed to get the irq\n");
|
|
+ goto err_irq;
|
|
+ }
|
|
+
|
|
+ ret = devm_request_irq(dev, ret, rockchip_sfc_irq_handler,
|
|
+ 0, pdev->name, sfc);
|
|
+ if (ret) {
|
|
+ dev_err(dev, "Failed to request irq\n");
|
|
+
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ ret = rockchip_sfc_init(sfc);
|
|
+ if (ret)
|
|
+ goto err_irq;
|
|
+
|
|
+ sfc->max_iosize = rockchip_sfc_get_max_iosize(sfc);
|
|
+ sfc->version = rockchip_sfc_get_version(sfc);
|
|
+
|
|
+ ret = spi_register_master(master);
|
|
+ if (ret)
|
|
+ goto err_irq;
|
|
+
|
|
+ return 0;
|
|
+
|
|
+err_irq:
|
|
+ clk_disable_unprepare(sfc->clk);
|
|
+err_clk:
|
|
+ clk_disable_unprepare(sfc->hclk);
|
|
+err_hclk:
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int rockchip_sfc_remove(struct platform_device *pdev)
|
|
+{
|
|
+ struct spi_master *master = platform_get_drvdata(pdev);
|
|
+ struct rockchip_sfc *sfc = platform_get_drvdata(pdev);
|
|
+
|
|
+ spi_unregister_master(master);
|
|
+
|
|
+ clk_disable_unprepare(sfc->clk);
|
|
+ clk_disable_unprepare(sfc->hclk);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static const struct of_device_id rockchip_sfc_dt_ids[] = {
|
|
+ { .compatible = "rockchip,sfc"},
|
|
+ { /* sentinel */ }
|
|
+};
|
|
+MODULE_DEVICE_TABLE(of, rockchip_sfc_dt_ids);
|
|
+
|
|
+static struct platform_driver rockchip_sfc_driver = {
|
|
+ .driver = {
|
|
+ .name = "rockchip-sfc",
|
|
+ .of_match_table = rockchip_sfc_dt_ids,
|
|
+ },
|
|
+ .probe = rockchip_sfc_probe,
|
|
+ .remove = rockchip_sfc_remove,
|
|
+};
|
|
+module_platform_driver(rockchip_sfc_driver);
|
|
+
|
|
+MODULE_LICENSE("GPL v2");
|
|
+MODULE_DESCRIPTION("Rockchip Serial Flash Controller Driver");
|
|
+MODULE_AUTHOR("Shawn Lin <shawn.lin@rock-chips.com>");
|
|
+MODULE_AUTHOR("Chris Morgan <macromorgan@hotmail.com>");
|
|
+MODULE_AUTHOR("Jon Lin <Jon.lin@rock-chips.com>");
|