[PATCH] board: rockchip: add Anbernic RGXX3 Series Devices

From: Chris Morgan macromorgan@hotmail.com
The Anbernic RGxx3 is a "pseudo-device" that encompasses the following devices:
- Anbernic RG353M - Anbernic RG353P - Anbernic RG353V - Anbernic RG353VS - Anbernic RG503
The rk3566-anbernic-rgxx3.dtsi is synced with upstream Linux, but rk3566-anbernic-rgxx3.dts is a U-Boot specific devicetree that is used for all RGxx3 devices.
Via the board.c file, the bootloader automatically sets the correct fdtfile, board, and board_name environment variables so that the correct devicetree can be passed to Linux. It is also possible to simply hard-code a single devicetree in the boot.scr file and use that to load Linux as well.
The common specifications for each device are:
- Rockchip RK3566 SoC - 2 external SDMMC slots - 1 USB-C host port, 1 USB-C peripheral port - 1 mini-HDMI output - MIPI-DSI based display panel - ADC controlled joysticks with a GPIO mux - GPIO buttons - A PWM controlled vibrator - An ADC controlled button
All of the common features are defined in the devicetree synced from upstream Linux.
TODO: DSI panel auto-detection for the RG353 devices (requires porting of DSI controller driver and DSI-DPHY driver to send DSI commands to the panel).
Signed-off-by: Chris Morgan macromorgan@hotmail.com
Changes from V1: - Fixed sphinx error for title underline. - Updated u-boot.dtsi file to support bootph. --- arch/arm/dts/Makefile | 1 + .../arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi | 86 ++ arch/arm/dts/rk3566-anbernic-rgxx3.dts | 18 + arch/arm/dts/rk3566-anbernic-rgxx3.dtsi | 786 ++++++++++++++++++ arch/arm/mach-rockchip/rk3568/Kconfig | 14 + board/anbernic/rgxx3_rk3566/Kconfig | 15 + board/anbernic/rgxx3_rk3566/MAINTAINERS | 6 + board/anbernic/rgxx3_rk3566/Makefile | 6 + board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c | 203 +++++ configs/anbernic-rgxx3_defconfig | 78 ++ doc/board/anbernic/index.rst | 9 + doc/board/anbernic/rgxx3.rst | 47 ++ doc/board/index.rst | 1 + doc/board/rockchip/rockchip.rst | 3 + include/configs/anbernic-rgxx3-rk3566.h | 12 + 15 files changed, 1285 insertions(+) create mode 100644 arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi create mode 100644 arch/arm/dts/rk3566-anbernic-rgxx3.dts create mode 100644 arch/arm/dts/rk3566-anbernic-rgxx3.dtsi create mode 100644 board/anbernic/rgxx3_rk3566/Kconfig create mode 100644 board/anbernic/rgxx3_rk3566/MAINTAINERS create mode 100644 board/anbernic/rgxx3_rk3566/Makefile create mode 100644 board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c create mode 100644 configs/anbernic-rgxx3_defconfig create mode 100644 doc/board/anbernic/index.rst create mode 100644 doc/board/anbernic/rgxx3.rst create mode 100644 include/configs/anbernic-rgxx3-rk3566.h
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 337bee7e1e..22cb5bc3db 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -165,6 +165,7 @@ dtb-$(CONFIG_ROCKCHIP_RK3399) += \ rk3399pro-rock-pi-n10.dtb
dtb-$(CONFIG_ROCKCHIP_RK3568) += \ + rk3566-anbernic-rgxx3.dtb \ rk3568-evb.dtb \ rk3566-radxa-cm3-io.dtb \ rk3568-rock-3a.dtb diff --git a/arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi b/arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi new file mode 100644 index 0000000000..a18e5d1cf7 --- /dev/null +++ b/arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +#include "rk356x-u-boot.dtsi" + +/ { + chosen { + stdout-path = &uart2; + u-boot,spl-boot-order = "same-as-spl", &sdmmc1, &sdmmc0; + }; + + rng: rng@fe388000 { + compatible = "rockchip,cryptov2-rng"; + reg = <0x0 0xfe388000 0x0 0x2000>; + status = "okay"; + }; +}; + +&cru { + assigned-clocks = + <&pmucru CLK_RTC_32K>, + <&pmucru PLL_PPLL>, + <&pmucru PCLK_PMU>, <&cru PLL_CPLL>, + <&cru PLL_GPLL>, + <&cru ACLK_BUS>, <&cru PCLK_BUS>, + <&cru ACLK_TOP_HIGH>, <&cru ACLK_TOP_LOW>, + <&cru HCLK_TOP>, <&cru PCLK_TOP>, + <&cru ACLK_PERIMID>, <&cru HCLK_PERIMID>, + <&cru CPLL_500M>, <&cru CPLL_333M>, + <&cru CPLL_250M>, <&cru CPLL_125M>, + <&cru CPLL_100M>, <&cru CPLL_62P5M>, + <&cru CPLL_50M>, <&cru CPLL_25M>; + assigned-clock-rates = + <32768>, + <200000000>, + <100000000>, <1000000000>, + <1188000000>, + <150000000>, <100000000>, + <500000000>, <400000000>, + <150000000>, <100000000>, + <300000000>, <150000000>, + <500000000>, <333333333>, + <250000000>, <125000000>, + <100000000>, <62500000>, + <50000000>, <25000000>; + assigned-clock-parents = + <&pmucru CLK_RTC32K_FRAC>; +}; + +&i2c2 { + status = "okay"; +}; + +&pmucru { + assigned-clocks = <&pmucru SCLK_32K_IOE>; + assigned-clock-parents = <&pmucru CLK_RTC_32K>; +}; + +/* + * We don't need the clocks, but if they are present they may cause + * probing to fail so we remove them for U-Boot. + */ +&rk817 { + /delete-property/ assigned-clocks; + /delete-property/ assigned-clock-parents; + /delete-property/ clocks; + /delete-property/ clock-names; +}; + +&sdhci { + pinctrl-0 = <&emmc_bus8>, <&emmc_clk>, <&emmc_cmd>, + <&emmc_datastrobe>, <&emmc_rstnout>; + pinctrl-names = "default"; + bus-width = <8>; + max-frequency = <200000000>; + mmc-hs200-1_8v; + non-removable; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&vcc_1v8>; + status = "okay"; +}; + +&uart2 { + clock-frequency = <24000000>; + bootph-all; + status = "okay"; +}; diff --git a/arch/arm/dts/rk3566-anbernic-rgxx3.dts b/arch/arm/dts/rk3566-anbernic-rgxx3.dts new file mode 100644 index 0000000000..404dddfafb --- /dev/null +++ b/arch/arm/dts/rk3566-anbernic-rgxx3.dts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +/dts-v1/; + +#include "rk3566-anbernic-rgxx3.dtsi" + +/ { + +/* + * Note this is a pseudo-model that doesn't exist in mainline Linux. + * This model is used for all RGXX3 devices and the board.c file will + * set the correct dtb name for loading mainline Linux automatically. + */ + model = "RGXX3"; + compatible = "anbernic,rg353m", "anbernic,rg353p", + "anbernic,rg353v", "anbernic,rg353vs", + "anbernic,rg503", "rockchip,rk3566"; +}; diff --git a/arch/arm/dts/rk3566-anbernic-rgxx3.dtsi b/arch/arm/dts/rk3566-anbernic-rgxx3.dtsi new file mode 100644 index 0000000000..ad43fa199c --- /dev/null +++ b/arch/arm/dts/rk3566-anbernic-rgxx3.dtsi @@ -0,0 +1,786 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +/dts-v1/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/pinctrl/rockchip.h> +#include <dt-bindings/soc/rockchip,vop2.h> +#include "rk3566.dtsi" + +/ { + chosen: chosen { + stdout-path = "serial2:1500000n8"; + }; + + adc-joystick { + compatible = "adc-joystick"; + io-channels = <&adc_mux 0>, + <&adc_mux 1>, + <&adc_mux 2>, + <&adc_mux 3>; + pinctrl-0 = <&joy_mux_en>; + pinctrl-names = "default"; + poll-interval = <60>; + #address-cells = <1>; + #size-cells = <0>; + + axis@0 { + reg = <0>; + abs-flat = <32>; + abs-fuzz = <32>; + abs-range = <1023 15>; + linux,code = <ABS_X>; + }; + + axis@1 { + reg = <1>; + abs-flat = <32>; + abs-fuzz = <32>; + abs-range = <15 1023>; + linux,code = <ABS_RX>; + }; + + axis@2 { + reg = <2>; + abs-flat = <32>; + abs-fuzz = <32>; + abs-range = <15 1023>; + linux,code = <ABS_Y>; + }; + + axis@3 { + reg = <3>; + abs-flat = <32>; + abs-fuzz = <32>; + abs-range = <1023 15>; + linux,code = <ABS_RY>; + }; + }; + + adc_keys: adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 0>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <60>; + + /* + * Button is mapped to F key in BSP kernel, but + * according to input guidelines it should be mode. + */ + button-mode { + label = "MODE"; + linux,code = <BTN_MODE>; + press-threshold-microvolt = <1750>; + }; + }; + + adc_mux: adc-mux { + compatible = "io-channel-mux"; + channels = "left_x", "right_x", "left_y", "right_y"; + #io-channel-cells = <1>; + io-channels = <&saradc 3>; + io-channel-names = "parent"; + mux-controls = <&gpio_mux>; + settle-time-us = <100>; + }; + + gpio_keys_control: gpio-keys-control { + compatible = "gpio-keys"; + pinctrl-0 = <&btn_pins_ctrl>; + pinctrl-names = "default"; + + button-b { + gpios = <&gpio3 RK_PC3 GPIO_ACTIVE_LOW>; + label = "SOUTH"; + linux,code = <BTN_SOUTH>; + }; + + button-down { + gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_LOW>; + label = "DPAD-DOWN"; + linux,code = <BTN_DPAD_DOWN>; + }; + + button-l1 { + gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; + label = "TL"; + linux,code = <BTN_TL>; + }; + + button-l2 { + gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>; + label = "TL2"; + linux,code = <BTN_TL2>; + }; + + button-select { + gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>; + label = "SELECT"; + linux,code = <BTN_SELECT>; + }; + + button-start { + gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>; + label = "START"; + linux,code = <BTN_START>; + }; + + button-thumbl { + gpios = <&gpio3 RK_PA1 GPIO_ACTIVE_LOW>; + label = "THUMBL"; + linux,code = <BTN_THUMBL>; + }; + + button-thumbr { + gpios = <&gpio3 RK_PA2 GPIO_ACTIVE_LOW>; + label = "THUMBR"; + linux,code = <BTN_THUMBR>; + }; + + button-up { + gpios = <&gpio3 RK_PA3 GPIO_ACTIVE_LOW>; + label = "DPAD-UP"; + linux,code = <BTN_DPAD_UP>; + }; + + button-x { + gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>; + label = "NORTH"; + linux,code = <BTN_NORTH>; + }; + }; + + gpio_keys_vol: gpio-keys-vol { + compatible = "gpio-keys"; + autorepeat; + pinctrl-0 = <&btn_pins_vol>; + pinctrl-names = "default"; + + button-vol-down { + gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; + label = "VOLUMEDOWN"; + linux,code = <KEY_VOLUMEDOWN>; + }; + + button-vol-up { + gpios = <&gpio3 RK_PA7 GPIO_ACTIVE_LOW>; + label = "VOLUMEUP"; + linux,code = <KEY_VOLUMEUP>; + }; + }; + + gpio_mux: mux-controller { + compatible = "gpio-mux"; + mux-gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_LOW>, + <&gpio0 RK_PB7 GPIO_ACTIVE_LOW>; + #mux-control-cells = <0>; + }; + + hdmi-con { + compatible = "hdmi-connector"; + ddc-i2c-bus = <&i2c5>; + type = "c"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi_out_con>; + }; + }; + }; + + leds: gpio-leds { + compatible = "gpio-leds"; + pinctrl-0 = <&led_pins>; + pinctrl-names = "default"; + + green_led: led-0 { + color = <LED_COLOR_ID_GREEN>; + default-state = "on"; + function = LED_FUNCTION_POWER; + gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; + }; + + amber_led: led-1 { + color = <LED_COLOR_ID_AMBER>; + function = LED_FUNCTION_CHARGING; + gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>; + retain-state-suspended; + }; + + red_led: led-2 { + color = <LED_COLOR_ID_RED>; + default-state = "off"; + function = LED_FUNCTION_STATUS; + gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>; + }; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&rk817 1>; + clock-names = "ext_clock"; + pinctrl-0 = <&wifi_enable_h>; + pinctrl-names = "default"; + post-power-on-delay-ms = <200>; + reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_LOW>; + }; + + vcc3v3_lcd0_n: regulator-vcc3v3-lcd0 { + compatible = "regulator-fixed"; + gpio = <&gpio0 RK_PC2 GPIO_ACTIVE_HIGH>; + enable-active-high; + pinctrl-0 = <&vcc_lcd_h>; + pinctrl-names = "default"; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc3v3_lcd0_n"; + vin-supply = <&vcc_3v3>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_sys: regulator-vcc-sys { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3800000>; + regulator-max-microvolt = <3800000>; + regulator-name = "vcc_sys"; + }; + + vcc_wifi: regulator-vcc-wifi { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&vcc_wifi_h>; + pinctrl-names = "default"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc_wifi"; + }; + + vibrator: pwm-vibrator { + compatible = "pwm-vibrator"; + pwm-names = "enable"; + pwms = <&pwm5 0 1000000000 0>; + }; +}; + +&combphy1 { + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu1 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu2 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu3 { + cpu-supply = <&vdd_cpu>; +}; + +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + +&hdmi { + ddc-i2c-bus = <&i2c5>; + pinctrl-0 = <&hdmitxm0_cec>; + pinctrl-names = "default"; + status = "okay"; +}; + +&hdmi_in { + hdmi_in_vp0: endpoint { + remote-endpoint = <&vp0_out_hdmi>; + }; +}; + +&hdmi_out { + hdmi_out_con: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; +}; + +&hdmi_sound { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + rk817: pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>; + clock-output-names = "rk808-clkout1", "rk808-clkout2"; + clock-names = "mclk"; + clocks = <&cru I2S1_MCLKOUT_TX>; + assigned-clocks = <&cru I2S1_MCLKOUT_TX>; + assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>; + #clock-cells = <1>; + #sound-dai-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&i2s1m0_mclk>, <&pmic_int_l>; + wakeup-source; + + vcc1-supply = <&vcc_sys>; + vcc2-supply = <&vcc_sys>; + vcc3-supply = <&vcc_sys>; + vcc4-supply = <&vcc_sys>; + vcc5-supply = <&vcc_sys>; + vcc6-supply = <&vcc_sys>; + vcc7-supply = <&vcc_sys>; + vcc8-supply = <&vcc_sys>; + vcc9-supply = <&dcdc_boost>; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-init-microvolt = <900000>; + regulator-ramp-delay = <6001>; + regulator-initial-mode = <0x2>; + regulator-name = "vdd_logic"; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <900000>; + }; + }; + + vdd_gpu: DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-init-microvolt = <900000>; + regulator-ramp-delay = <6001>; + regulator-initial-mode = <0x2>; + regulator-name = "vdd_gpu"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + regulator-name = "vcc_ddr"; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v3: DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-initial-mode = <0x2>; + regulator-name = "vcc_3v3"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcca1v8_pmu: LDO_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcca1v8_pmu"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdda_0v9: LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-name = "vdda_0v9"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v9_pmu: LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-name = "vdda0v9_pmu"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <900000>; + }; + }; + + vccio_acodec: LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vccio_acodec"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vccio_sd"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_pmu: LDO_REG6 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc3v3_pmu"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_1v8: LDO_REG7 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc_1v8"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc1v8_dvp: LDO_REG8 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc1v8_dvp"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc2v8_dvp: LDO_REG9 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-name = "vcc2v8_dvp"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + dcdc_boost: BOOST { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <4700000>; + regulator-max-microvolt = <5400000>; + regulator-name = "boost"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + otg_switch: OTG_SWITCH { + regulator-name = "otg_switch"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; + + vdd_cpu: regulator@40 { + compatible = "fcs,fan53555"; + reg = <0x40>; + fcs,suspend-voltage-selector = <1>; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1390000>; + regulator-init-microvolt = <900000>; + regulator-name = "vdd_cpu"; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc_sys>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; +}; + +&i2c1 { + /* Unknown/unused device at 0x3c */ + status = "disabled"; +}; + +&i2c5 { + pinctrl-0 = <&i2c5m1_xfer>; + pinctrl-names = "default"; + status = "okay"; +}; + +&i2s0_8ch { + status = "okay"; +}; + +&i2s1_8ch { + pinctrl-0 = <&i2s1m0_sclktx + &i2s1m0_lrcktx + &i2s1m0_sdi0 + &i2s1m0_sdo0>; + pinctrl-names = "default"; + rockchip,trcm-sync-tx-only; + status = "okay"; +}; + +&pinctrl { + gpio-btns { + btn_pins_ctrl: btn-pins-ctrl { + rockchip,pins = + <3 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB3 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PC3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + btn_pins_vol: btn-pins-vol { + rockchip,pins = + <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, + <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + gpio-led { + led_pins: led-pins { + rockchip,pins = + <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>, + <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>, + <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + joy-mux { + joy_mux_en: joy-mux-en { + rockchip,pins = + <0 RK_PB5 RK_FUNC_GPIO &pcfg_output_low>; + }; + }; + + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = + <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = + <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + vcc3v3-lcd { + vcc_lcd_h: vcc-lcd-h { + rockchip,pins = + <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + vcc-wifi { + vcc_wifi_h: vcc-wifi-h { + rockchip,pins = + <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pmu_io_domains { + status = "okay"; + 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 = <&vcc1v8_dvp>; + vccio7-supply = <&vcc_3v3>; +}; + +&pwm5 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcc_1v8>; + status = "okay"; +}; + +&sdmmc0 { + bus-width = <4>; + cap-sd-highspeed; + cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; + disable-wp; + pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>; + pinctrl-names = "default"; + sd-uhs-sdr104; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&sdmmc1 { + bus-width = <4>; + cap-sd-highspeed; + cd-gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>; + disable-wp; + pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk &sdmmc1_det>; + pinctrl-names = "default"; + sd-uhs-sdr104; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&vcc1v8_dvp>; + status = "okay"; +}; + +&sdmmc2 { + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + keep-power-in-suspend; + mmc-pwrseq = <&sdio_pwrseq>; + non-removable; + pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_cmd &sdmmc2m0_clk>; + pinctrl-names = "default"; + vmmc-supply = <&vcc_wifi>; + vqmmc-supply = <&vcca1v8_pmu>; + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <1>; + rockchip,hw-tshut-polarity = <0>; + status = "okay"; +}; + +&uart1 { + pinctrl-0 = <&uart1m1_xfer &uart1m1_ctsn &uart1m1_rtsn>; + pinctrl-names = "default"; + uart-has-rtscts; + status = "okay"; + + bluetooth { + compatible = "realtek,rtl8821cs-bt", "realtek,rtl8723bs-bt"; + device-wake-gpios = <&gpio4 4 GPIO_ACTIVE_HIGH>; + enable-gpios = <&gpio4 3 GPIO_ACTIVE_HIGH>; + host-wake-gpios = <&gpio4 5 GPIO_ACTIVE_HIGH>; + }; +}; + +&uart2 { + status = "okay"; +}; + +/* + * Lack the schematics to verify, but port works as a peripheral + * (and not a host or OTG port). + */ +&usb_host0_xhci { + dr_mode = "peripheral"; + phys = <&usb2phy0_otg>; + phy-names = "usb2-phy"; + status = "okay"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usb_host1_xhci { + phy-names = "usb2-phy", "usb3-phy"; + phys = <&usb2phy1_host>, <&combphy1 PHY_TYPE_USB3>; + status = "okay"; +}; + +&usb2phy0 { + status = "okay"; +}; + +&usb2phy0_otg { + status = "okay"; +}; + +&usb2phy1 { + status = "okay"; +}; + +&usb2phy1_host { + status = "okay"; +}; + +&vop { + assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; + assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; + status = "okay"; +}; + +&vop_mmu { + status = "okay"; +}; + +&vp0 { + vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { + reg = <ROCKCHIP_VOP2_EP_HDMI0>; + remote-endpoint = <&hdmi_in_vp0>; + }; +}; diff --git a/arch/arm/mach-rockchip/rk3568/Kconfig b/arch/arm/mach-rockchip/rk3568/Kconfig index 4e7c02cce0..94e04b79e7 100644 --- a/arch/arm/mach-rockchip/rk3568/Kconfig +++ b/arch/arm/mach-rockchip/rk3568/Kconfig @@ -1,11 +1,24 @@ if ROCKCHIP_RK3568
+choice + prompt "RK3568/RK3566 board select" + config TARGET_EVB_RK3568 bool "RK3568 evaluation board" select BOARD_LATE_INIT help RK3568 EVB is a evaluation board for Rockchp RK3568.
+config TARGET_ANBERNIC_RGXX3_RK3566 + bool "Anbernic RGXX3" + help + Anbernic RGXX3 gaming device with Rockchip RK3566. This + config can be used with the RG353M, RG353P, RG353V, RG353VS, + and RG503. The correct device tree name will automatically + be selected by the bootloader. + +endchoice + config ROCKCHIP_BOOT_MODE_REG default 0xfdc20200
@@ -19,5 +32,6 @@ config SYS_MALLOC_F_LEN default 0x2000
source "board/rockchip/evb_rk3568/Kconfig" +source "board/anbernic/rgxx3_rk3566/Kconfig"
endif diff --git a/board/anbernic/rgxx3_rk3566/Kconfig b/board/anbernic/rgxx3_rk3566/Kconfig new file mode 100644 index 0000000000..6743a28a2f --- /dev/null +++ b/board/anbernic/rgxx3_rk3566/Kconfig @@ -0,0 +1,15 @@ +if TARGET_ANBERNIC_RGXX3_RK3566 + +config SYS_BOARD + default "rgxx3_rk3566" + +config SYS_VENDOR + default "anbernic" + +config SYS_CONFIG_NAME + default "anbernic-rgxx3-rk3566" + +config BOARD_SPECIFIC_OPTIONS + def_bool y + +endif diff --git a/board/anbernic/rgxx3_rk3566/MAINTAINERS b/board/anbernic/rgxx3_rk3566/MAINTAINERS new file mode 100644 index 0000000000..647e49d28a --- /dev/null +++ b/board/anbernic/rgxx3_rk3566/MAINTAINERS @@ -0,0 +1,6 @@ +RGXX3-RK3566 +M: Chris Morgan macromorgan@hotmail.com +S: Maintained +F: board/anbernic/rgxx3-rk3566 +F: include/configs/anbernic-rgxx3-rk3566 +F: configs/anbernic-rgxx3_defconfig diff --git a/board/anbernic/rgxx3_rk3566/Makefile b/board/anbernic/rgxx3_rk3566/Makefile new file mode 100644 index 0000000000..afd3e0adf6 --- /dev/null +++ b/board/anbernic/rgxx3_rk3566/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (c) 2023 Chris Morgan macromorgan@hotmail.com +# + +obj-y += rgxx3-rk3566.o diff --git a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c new file mode 100644 index 0000000000..decc46db78 --- /dev/null +++ b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c @@ -0,0 +1,203 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2023 Chris Morgan macromorgan@hotmail.com + */ + +#include <abuf.h> +#include <adc.h> +#include <asm/io.h> +#include <dm.h> +#include <linux/delay.h> +#include <pwm.h> +#include <rng.h> +#include <stdlib.h> +#include <mmc.h> +#include <env.h> + +#define GPIO0_BASE 0xfdd60000 +#define GPIO_SWPORT_DR_H 0x0004 +#define GPIO_SWPORT_DDR_H 0x000c +#define GPIO_A5 BIT(5) +#define GPIO_A6 BIT(6) + +#define GPIO_WRITEMASK(bits) ((bits) << 16) + +#define DTB_DIR "rockchip/" + +struct rg3xx_model { + const char *board; + const char *board_name; + const char *fdtfile; +}; + +enum rgxx3_device_id { + RG353M, + RG353P, + RG353V, + RG353VS, + RG503, +}; + +static const struct rg3xx_model rg3xx_model_details[] = { + [RG353M] = { + "rk3566-anbernic-rg353m", + "RG353M", + DTB_DIR "rk3566-anbernic-rg353m.dtb", + }, + [RG353P] = { + "rk3566-anbernic-rg353p", + "RG353P", + DTB_DIR "rk3566-anbernic-rg353p.dtb", + }, + [RG353V] = { + "rk3566-anbernic-rg353v", + "RG353V", + DTB_DIR "rk3566-anbernic-rg353v.dtb", + }, + [RG353VS] = { + "rk3566-anbernic-rg353vs", + "RG353VS", + DTB_DIR "rk3566-anbernic-rg353vs.dtb", + }, + [RG503] = { + "rk3566-anbernic-rg503", + "RG503", + DTB_DIR "rk3566-anbernic-rg503.dtb", + }, +}; + +/* + * Start LED very early so user knows device is on. Set color + * to amber. + */ +void spl_board_init(void) +{ + /* Set GPIO0_A5 and GPIO0_A6 to output. */ + writel(GPIO_WRITEMASK(GPIO_A6 | GPIO_A5) | (GPIO_A6 | GPIO_A5), + (GPIO0_BASE + GPIO_SWPORT_DDR_H)); + /* Set GPIO0_A5 to 0 and GPIO0_A6 to 1. */ + writel(GPIO_WRITEMASK(GPIO_A6 | GPIO_A5) | GPIO_A6, + (GPIO0_BASE + GPIO_SWPORT_DR_H)); +} + +/* Use hardware rng to seed Linux random. */ +int board_rng_seed(struct abuf *buf) +{ + struct udevice *dev; + size_t len = 0x8; + u64 *data; + + data = malloc(len); + if (!data) { + printf("Out of memory\n"); + return -ENOMEM; + } + + if (uclass_get_device(UCLASS_RNG, 0, &dev) || !dev) { + printf("No RNG device\n"); + return -ENODEV; + } + + if (dm_rng_read(dev, data, len)) { + printf("Reading RNG failed\n"); + return -EIO; + } + + abuf_init_set(buf, data, len); + + return 0; +} + +/* + * Buzz the buzzer so the user knows something is going on. Make it + * optional in case PWM is disabled. + */ +void __maybe_unused startup_buzz(void) +{ + struct udevice *dev; + int err; + + err = uclass_get_device(UCLASS_PWM, 0, &dev); + if (err) + printf("pwm not found\n"); + + pwm_set_enable(dev, 0, 1); + mdelay(200); + pwm_set_enable(dev, 0, 0); +} + +/* Detect which Anbernic RGXX3 device we are using so as to load the + * correct devicetree for Linux. Set an environment variable once + * found. The detection depends on the value of ADC channel 1, the + * presence of an eMMC on mmc0, and querying the DSI panel (TODO). + */ +int rgxx3_detect_device(void) +{ + u32 adc_info; + int ret; + int board_id = -ENXIO; + struct mmc *mmc; + + ret = adc_channel_single_shot("saradc@fe720000", 1, &adc_info); + if (ret) { + printf("Read SARADC failed with error %d\n", ret); + return ret; + } + + /* Observed value 517. */ + if (adc_info > 505 && adc_info < 530) + board_id = RG353M; + /* Observed value 695. */ + if (adc_info > 680 && adc_info < 710) + board_id = RG353V; + /* Documented value 860. */ + if (adc_info > 850 && adc_info < 870) + board_id = RG353P; + /* Observed value 1023. */ + if (adc_info > 1010) + board_id = RG503; + + /* + * Try to access the eMMC on an RG353V. If it's missing, it's + * an RG353VS. Note we could also check for a touchscreen at + * 0x1a on i2c2. + */ + if (board_id == RG353V) { + mmc = find_mmc_device(0); + if (mmc) { + ret = mmc_init(mmc); + if (ret) + board_id = RG353VS; + } + } + + if (board_id < 0) + return board_id; + + env_set("board", rg3xx_model_details[board_id].board); + env_set("board_name", + rg3xx_model_details[board_id].board_name); + env_set("fdtfile", rg3xx_model_details[board_id].fdtfile); + + return 0; +} + +int rk_board_late_init(void) +{ + int ret; + + /* Turn off orange LED and turn on green LED. */ + writel(GPIO_WRITEMASK(GPIO_A6 | GPIO_A5) | GPIO_A5, + (GPIO0_BASE + GPIO_SWPORT_DR_H)); + + ret = rgxx3_detect_device(); + if (ret) { + printf("Unable to detect device type: %d\n", ret); + return ret; + } + + if (IS_ENABLED(CONFIG_DM_PWM)) + startup_buzz(); + + return 0; +} diff --git a/configs/anbernic-rgxx3_defconfig b/configs/anbernic-rgxx3_defconfig new file mode 100644 index 0000000000..b17e917914 --- /dev/null +++ b/configs/anbernic-rgxx3_defconfig @@ -0,0 +1,78 @@ +CONFIG_ARM=y +CONFIG_SKIP_LOWLEVEL_INIT=y +CONFIG_COUNTER_FREQUENCY=24000000 +CONFIG_ARCH_ROCKCHIP=y +CONFIG_TEXT_BASE=0x00a00000 +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_NR_DRAM_BANKS=2 +CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc00000 +CONFIG_DEFAULT_DEVICE_TREE="rk3566-anbernic-rgxx3" +CONFIG_ROCKCHIP_RK3568=y +CONFIG_SPL_ROCKCHIP_BACK_TO_BROM=y +CONFIG_SPL_ROCKCHIP_COMMON_BOARD=y +CONFIG_SPL_MMC=y +CONFIG_SPL_SERIAL=y +CONFIG_SPL_STACK_R_ADDR=0x600000 +CONFIG_TARGET_ANBERNIC_RGXX3_RK3566=y +CONFIG_SPL_STACK=0x400000 +CONFIG_DEBUG_UART_BASE=0xFE660000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_SYS_LOAD_ADDR=0xc00800 +CONFIG_DEBUG_UART=y +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_SPL_LOAD_FIT=y +CONFIG_DEFAULT_FDT_FILE="rockchip/rk3566-anbernic-rgxx3.dtb" +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_SPL_MAX_SIZE=0x20000 +CONFIG_SPL_PAD_TO=0x7f8000 +CONFIG_SPL_HAS_BSS_LINKER_SECTION=y +CONFIG_SPL_BSS_START_ADDR=0x4000000 +CONFIG_SPL_BSS_MAX_SIZE=0x4000 +CONFIG_SPL_BOARD_INIT=y +# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set +# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set +CONFIG_SPL_STACK_R=y +CONFIG_SPL_ATF=y +CONFIG_CMD_PWM=y +CONFIG_CMD_GPT=y +CONFIG_CMD_MMC=y +# CONFIG_CMD_SETEXPR is not set +# CONFIG_SPL_DOS_PARTITION is not set +CONFIG_SPL_OF_CONTROL=y +CONFIG_OF_LIVE=y +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +# CONFIG_NET is not set +CONFIG_SPL_REGMAP=y +CONFIG_SPL_SYSCON=y +CONFIG_SPL_CLK=y +CONFIG_ARM_SMCCC_FEATURES=y +CONFIG_SCMI_FIRMWARE=y +CONFIG_ROCKCHIP_GPIO=y +CONFIG_SYS_I2C_ROCKCHIP=y +CONFIG_MISC=y +CONFIG_SUPPORT_EMMC_RPMB=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_ROCKCHIP=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_SDMA=y +CONFIG_MMC_SDHCI_ROCKCHIP=y +CONFIG_DM_PMIC=y +CONFIG_DM_PMIC_FAN53555=y +CONFIG_PMIC_RK8XX=y +CONFIG_REGULATOR_PWM=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_REGULATOR_RK8XX=y +CONFIG_DM_REGULATOR_SCMI=y +CONFIG_PWM_ROCKCHIP=y +CONFIG_SPL_RAM=y +CONFIG_BAUDRATE=1500000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYS_NS16550_MEM32=y +CONFIG_SYSRESET=y +CONFIG_REGEX=y +CONFIG_ERRNO_STR=y +# CONFIG_EFI_LOADER is not set diff --git a/doc/board/anbernic/index.rst b/doc/board/anbernic/index.rst new file mode 100644 index 0000000000..03758d8613 --- /dev/null +++ b/doc/board/anbernic/index.rst @@ -0,0 +1,9 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Anbernic +======== + +.. toctree:: + :maxdepth: 2 + + rgxx3.rst diff --git a/doc/board/anbernic/rgxx3.rst b/doc/board/anbernic/rgxx3.rst new file mode 100644 index 0000000000..afa7538282 --- /dev/null +++ b/doc/board/anbernic/rgxx3.rst @@ -0,0 +1,47 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +U-Boot for Anbernic RGxx3 Devices +================================= + +This allows U-Boot to boot the following Anbernic devices: + + - Anbernic RG353M + - Anbernic RG353P + - Anbernic RG353V + - Anbernic RG353VS + - Anbernic RG503 + +The correct device is detected automatically by comparing ADC values +from ADC channel 1. In the event of an RG353V, an attempt is then made +to probe for an eMMC and if it fails the device is assumed to be an +RG353VS. Based on the detected device, the environment variables +"board", "board_name", and "fdtfile" are set to the correct values +corresponding to the board which can be read by a boot script to boot +with the correct device tree. + +Please note that there are some versions of the RG353 devices with +different panels. Panel auto-detection is planned for a later date. + +Building U-Boot +--------------- + +.. code-block:: bash + + $ export CROSS_COMPILE=aarch64-none-elf- + $ export BL31=../rkbin/bin/rk35/rk3568_bl31_v1.34.elf + $ export ROCKCHIP_TPL=../rkbin/bin/rk35/rk3568_ddr_1056MHz_v1.13.bin + $ make anbernic-rgxx3_defconfig + $ make + +This will build ``u-boot-rockchip.bin`` which can be written to an SD +card. + +Image installation +------------------ + +Write the ``u-boot-rockchip.bin`` to an SD card offset 32kb from the +start. + +.. code-block:: bash + + $ dd if=u-boot-rockchip.bin of=/dev/mmcblk0 bs=512 seek=64 diff --git a/doc/board/index.rst b/doc/board/index.rst index 69e2cd5fb8..820eb71d71 100644 --- a/doc/board/index.rst +++ b/doc/board/index.rst @@ -11,6 +11,7 @@ Board-specific doc AndesTech/index allwinner/index amlogic/index + anbernic/index apple/index armltd/index atmel/index diff --git a/doc/board/rockchip/rockchip.rst b/doc/board/rockchip/rockchip.rst index b5563b8f7f..204cace1e9 100644 --- a/doc/board/rockchip/rockchip.rst +++ b/doc/board/rockchip/rockchip.rst @@ -87,6 +87,9 @@ List of mainline supported Rockchip boards: - Rockchip Evb-RK3399 (evb_rk3399) - Theobroma Systems RK3399-Q7 SoM - Puma (puma_rk3399)
+* rk3566 + - Anbernic RGxx3 (rgxx3-rk3566) + * rk3568 - Rockchip Evb-RK3568 (evb-rk3568)
diff --git a/include/configs/anbernic-rgxx3-rk3566.h b/include/configs/anbernic-rgxx3-rk3566.h new file mode 100644 index 0000000000..3c4ea4e7d8 --- /dev/null +++ b/include/configs/anbernic-rgxx3-rk3566.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef __ANBERNIC_RGXX3_RK3566_H +#define __ANBERNIC_RGXX3_RK3566_H + +#include <configs/rk3568_common.h> + +#define ROCKCHIP_DEVICE_SETTINGS \ + "stdout=serial,vidconsole\0" \ + "stderr=serial,vidconsole\0" + +#endif

On 2023/4/21 23:59, Chris Morgan wrote:
From: Chris Morgan macromorgan@hotmail.com
The Anbernic RGxx3 is a "pseudo-device" that encompasses the following devices:
- Anbernic RG353M
- Anbernic RG353P
- Anbernic RG353V
- Anbernic RG353VS
- Anbernic RG503
The rk3566-anbernic-rgxx3.dtsi is synced with upstream Linux, but rk3566-anbernic-rgxx3.dts is a U-Boot specific devicetree that is used for all RGxx3 devices.
Via the board.c file, the bootloader automatically sets the correct fdtfile, board, and board_name environment variables so that the correct devicetree can be passed to Linux. It is also possible to simply hard-code a single devicetree in the boot.scr file and use that to load Linux as well.
The common specifications for each device are:
- Rockchip RK3566 SoC
- 2 external SDMMC slots
- 1 USB-C host port, 1 USB-C peripheral port
- 1 mini-HDMI output
- MIPI-DSI based display panel
- ADC controlled joysticks with a GPIO mux
- GPIO buttons
- A PWM controlled vibrator
- An ADC controlled button
All of the common features are defined in the devicetree synced from upstream Linux.
TODO: DSI panel auto-detection for the RG353 devices (requires porting of DSI controller driver and DSI-DPHY driver to send DSI commands to the panel).
Signed-off-by: Chris Morgan macromorgan@hotmail.com
Reviewed-by: Kever Yang kever.yang@rock-chips.com
Thanks, - Kever
Changes from V1:
- Fixed sphinx error for title underline.
- Updated u-boot.dtsi file to support bootph.
arch/arm/dts/Makefile | 1 + .../arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi | 86 ++ arch/arm/dts/rk3566-anbernic-rgxx3.dts | 18 + arch/arm/dts/rk3566-anbernic-rgxx3.dtsi | 786 ++++++++++++++++++ arch/arm/mach-rockchip/rk3568/Kconfig | 14 + board/anbernic/rgxx3_rk3566/Kconfig | 15 + board/anbernic/rgxx3_rk3566/MAINTAINERS | 6 + board/anbernic/rgxx3_rk3566/Makefile | 6 + board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c | 203 +++++ configs/anbernic-rgxx3_defconfig | 78 ++ doc/board/anbernic/index.rst | 9 + doc/board/anbernic/rgxx3.rst | 47 ++ doc/board/index.rst | 1 + doc/board/rockchip/rockchip.rst | 3 + include/configs/anbernic-rgxx3-rk3566.h | 12 + 15 files changed, 1285 insertions(+) create mode 100644 arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi create mode 100644 arch/arm/dts/rk3566-anbernic-rgxx3.dts create mode 100644 arch/arm/dts/rk3566-anbernic-rgxx3.dtsi create mode 100644 board/anbernic/rgxx3_rk3566/Kconfig create mode 100644 board/anbernic/rgxx3_rk3566/MAINTAINERS create mode 100644 board/anbernic/rgxx3_rk3566/Makefile create mode 100644 board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c create mode 100644 configs/anbernic-rgxx3_defconfig create mode 100644 doc/board/anbernic/index.rst create mode 100644 doc/board/anbernic/rgxx3.rst create mode 100644 include/configs/anbernic-rgxx3-rk3566.h
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 337bee7e1e..22cb5bc3db 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -165,6 +165,7 @@ dtb-$(CONFIG_ROCKCHIP_RK3399) += \ rk3399pro-rock-pi-n10.dtb
dtb-$(CONFIG_ROCKCHIP_RK3568) += \
- rk3566-anbernic-rgxx3.dtb \ rk3568-evb.dtb \ rk3566-radxa-cm3-io.dtb \ rk3568-rock-3a.dtb
diff --git a/arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi b/arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi new file mode 100644 index 0000000000..a18e5d1cf7 --- /dev/null +++ b/arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+#include "rk356x-u-boot.dtsi"
+/ {
- chosen {
stdout-path = &uart2;
u-boot,spl-boot-order = "same-as-spl", &sdmmc1, &sdmmc0;
- };
- rng: rng@fe388000 {
compatible = "rockchip,cryptov2-rng";
reg = <0x0 0xfe388000 0x0 0x2000>;
status = "okay";
- };
+};
+&cru {
- assigned-clocks =
<&pmucru CLK_RTC_32K>,
<&pmucru PLL_PPLL>,
<&pmucru PCLK_PMU>, <&cru PLL_CPLL>,
<&cru PLL_GPLL>,
<&cru ACLK_BUS>, <&cru PCLK_BUS>,
<&cru ACLK_TOP_HIGH>, <&cru ACLK_TOP_LOW>,
<&cru HCLK_TOP>, <&cru PCLK_TOP>,
<&cru ACLK_PERIMID>, <&cru HCLK_PERIMID>,
<&cru CPLL_500M>, <&cru CPLL_333M>,
<&cru CPLL_250M>, <&cru CPLL_125M>,
<&cru CPLL_100M>, <&cru CPLL_62P5M>,
<&cru CPLL_50M>, <&cru CPLL_25M>;
assigned-clock-rates =
<32768>,
<200000000>,
<100000000>, <1000000000>,
<1188000000>,
<150000000>, <100000000>,
<500000000>, <400000000>,
<150000000>, <100000000>,
<300000000>, <150000000>,
<500000000>, <333333333>,
<250000000>, <125000000>,
<100000000>, <62500000>,
<50000000>, <25000000>;
assigned-clock-parents =
<&pmucru CLK_RTC32K_FRAC>;
+};
+&i2c2 {
- status = "okay";
+};
+&pmucru {
- assigned-clocks = <&pmucru SCLK_32K_IOE>;
- assigned-clock-parents = <&pmucru CLK_RTC_32K>;
+};
+/*
- We don't need the clocks, but if they are present they may cause
- probing to fail so we remove them for U-Boot.
- */
+&rk817 {
- /delete-property/ assigned-clocks;
- /delete-property/ assigned-clock-parents;
- /delete-property/ clocks;
- /delete-property/ clock-names;
+};
+&sdhci {
- pinctrl-0 = <&emmc_bus8>, <&emmc_clk>, <&emmc_cmd>,
<&emmc_datastrobe>, <&emmc_rstnout>;
- pinctrl-names = "default";
- bus-width = <8>;
- max-frequency = <200000000>;
- mmc-hs200-1_8v;
- non-removable;
- vmmc-supply = <&vcc_3v3>;
- vqmmc-supply = <&vcc_1v8>;
- status = "okay";
+};
+&uart2 {
- clock-frequency = <24000000>;
- bootph-all;
- status = "okay";
+}; diff --git a/arch/arm/dts/rk3566-anbernic-rgxx3.dts b/arch/arm/dts/rk3566-anbernic-rgxx3.dts new file mode 100644 index 0000000000..404dddfafb --- /dev/null +++ b/arch/arm/dts/rk3566-anbernic-rgxx3.dts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/dts-v1/;
+#include "rk3566-anbernic-rgxx3.dtsi"
+/ {
+/*
- Note this is a pseudo-model that doesn't exist in mainline Linux.
- This model is used for all RGXX3 devices and the board.c file will
- set the correct dtb name for loading mainline Linux automatically.
- */
- model = "RGXX3";
- compatible = "anbernic,rg353m", "anbernic,rg353p",
"anbernic,rg353v", "anbernic,rg353vs",
"anbernic,rg503", "rockchip,rk3566";
+}; diff --git a/arch/arm/dts/rk3566-anbernic-rgxx3.dtsi b/arch/arm/dts/rk3566-anbernic-rgxx3.dtsi new file mode 100644 index 0000000000..ad43fa199c --- /dev/null +++ b/arch/arm/dts/rk3566-anbernic-rgxx3.dtsi @@ -0,0 +1,786 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/pinctrl/rockchip.h> +#include <dt-bindings/soc/rockchip,vop2.h> +#include "rk3566.dtsi"
+/ {
- chosen: chosen {
stdout-path = "serial2:1500000n8";
- };
- adc-joystick {
compatible = "adc-joystick";
io-channels = <&adc_mux 0>,
<&adc_mux 1>,
<&adc_mux 2>,
<&adc_mux 3>;
pinctrl-0 = <&joy_mux_en>;
pinctrl-names = "default";
poll-interval = <60>;
#address-cells = <1>;
#size-cells = <0>;
axis@0 {
reg = <0>;
abs-flat = <32>;
abs-fuzz = <32>;
abs-range = <1023 15>;
linux,code = <ABS_X>;
};
axis@1 {
reg = <1>;
abs-flat = <32>;
abs-fuzz = <32>;
abs-range = <15 1023>;
linux,code = <ABS_RX>;
};
axis@2 {
reg = <2>;
abs-flat = <32>;
abs-fuzz = <32>;
abs-range = <15 1023>;
linux,code = <ABS_Y>;
};
axis@3 {
reg = <3>;
abs-flat = <32>;
abs-fuzz = <32>;
abs-range = <1023 15>;
linux,code = <ABS_RY>;
};
- };
- adc_keys: adc-keys {
compatible = "adc-keys";
io-channels = <&saradc 0>;
io-channel-names = "buttons";
keyup-threshold-microvolt = <1800000>;
poll-interval = <60>;
/*
* Button is mapped to F key in BSP kernel, but
* according to input guidelines it should be mode.
*/
button-mode {
label = "MODE";
linux,code = <BTN_MODE>;
press-threshold-microvolt = <1750>;
};
- };
- adc_mux: adc-mux {
compatible = "io-channel-mux";
channels = "left_x", "right_x", "left_y", "right_y";
#io-channel-cells = <1>;
io-channels = <&saradc 3>;
io-channel-names = "parent";
mux-controls = <&gpio_mux>;
settle-time-us = <100>;
- };
- gpio_keys_control: gpio-keys-control {
compatible = "gpio-keys";
pinctrl-0 = <&btn_pins_ctrl>;
pinctrl-names = "default";
button-b {
gpios = <&gpio3 RK_PC3 GPIO_ACTIVE_LOW>;
label = "SOUTH";
linux,code = <BTN_SOUTH>;
};
button-down {
gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_LOW>;
label = "DPAD-DOWN";
linux,code = <BTN_DPAD_DOWN>;
};
button-l1 {
gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>;
label = "TL";
linux,code = <BTN_TL>;
};
button-l2 {
gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>;
label = "TL2";
linux,code = <BTN_TL2>;
};
button-select {
gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>;
label = "SELECT";
linux,code = <BTN_SELECT>;
};
button-start {
gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>;
label = "START";
linux,code = <BTN_START>;
};
button-thumbl {
gpios = <&gpio3 RK_PA1 GPIO_ACTIVE_LOW>;
label = "THUMBL";
linux,code = <BTN_THUMBL>;
};
button-thumbr {
gpios = <&gpio3 RK_PA2 GPIO_ACTIVE_LOW>;
label = "THUMBR";
linux,code = <BTN_THUMBR>;
};
button-up {
gpios = <&gpio3 RK_PA3 GPIO_ACTIVE_LOW>;
label = "DPAD-UP";
linux,code = <BTN_DPAD_UP>;
};
button-x {
gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>;
label = "NORTH";
linux,code = <BTN_NORTH>;
};
- };
- gpio_keys_vol: gpio-keys-vol {
compatible = "gpio-keys";
autorepeat;
pinctrl-0 = <&btn_pins_vol>;
pinctrl-names = "default";
button-vol-down {
gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>;
label = "VOLUMEDOWN";
linux,code = <KEY_VOLUMEDOWN>;
};
button-vol-up {
gpios = <&gpio3 RK_PA7 GPIO_ACTIVE_LOW>;
label = "VOLUMEUP";
linux,code = <KEY_VOLUMEUP>;
};
- };
- gpio_mux: mux-controller {
compatible = "gpio-mux";
mux-gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_LOW>,
<&gpio0 RK_PB7 GPIO_ACTIVE_LOW>;
#mux-control-cells = <0>;
- };
- hdmi-con {
compatible = "hdmi-connector";
ddc-i2c-bus = <&i2c5>;
type = "c";
port {
hdmi_con_in: endpoint {
remote-endpoint = <&hdmi_out_con>;
};
};
- };
- leds: gpio-leds {
compatible = "gpio-leds";
pinctrl-0 = <&led_pins>;
pinctrl-names = "default";
green_led: led-0 {
color = <LED_COLOR_ID_GREEN>;
default-state = "on";
function = LED_FUNCTION_POWER;
gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
};
amber_led: led-1 {
color = <LED_COLOR_ID_AMBER>;
function = LED_FUNCTION_CHARGING;
gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>;
retain-state-suspended;
};
red_led: led-2 {
color = <LED_COLOR_ID_RED>;
default-state = "off";
function = LED_FUNCTION_STATUS;
gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
};
- };
- sdio_pwrseq: sdio-pwrseq {
compatible = "mmc-pwrseq-simple";
clocks = <&rk817 1>;
clock-names = "ext_clock";
pinctrl-0 = <&wifi_enable_h>;
pinctrl-names = "default";
post-power-on-delay-ms = <200>;
reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_LOW>;
- };
- vcc3v3_lcd0_n: regulator-vcc3v3-lcd0 {
compatible = "regulator-fixed";
gpio = <&gpio0 RK_PC2 GPIO_ACTIVE_HIGH>;
enable-active-high;
pinctrl-0 = <&vcc_lcd_h>;
pinctrl-names = "default";
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc3v3_lcd0_n";
vin-supply = <&vcc_3v3>;
regulator-state-mem {
regulator-off-in-suspend;
};
- };
- vcc_sys: regulator-vcc-sys {
compatible = "regulator-fixed";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3800000>;
regulator-max-microvolt = <3800000>;
regulator-name = "vcc_sys";
- };
- vcc_wifi: regulator-vcc-wifi {
compatible = "regulator-fixed";
enable-active-high;
gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
pinctrl-0 = <&vcc_wifi_h>;
pinctrl-names = "default";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc_wifi";
- };
- vibrator: pwm-vibrator {
compatible = "pwm-vibrator";
pwm-names = "enable";
pwms = <&pwm5 0 1000000000 0>;
- };
+};
+&combphy1 {
- status = "okay";
+};
+&cpu0 {
- cpu-supply = <&vdd_cpu>;
+};
+&cpu1 {
- cpu-supply = <&vdd_cpu>;
+};
+&cpu2 {
- cpu-supply = <&vdd_cpu>;
+};
+&cpu3 {
- cpu-supply = <&vdd_cpu>;
+};
+&gpu {
- mali-supply = <&vdd_gpu>;
- status = "okay";
+};
+&hdmi {
- ddc-i2c-bus = <&i2c5>;
- pinctrl-0 = <&hdmitxm0_cec>;
- pinctrl-names = "default";
- status = "okay";
+};
+&hdmi_in {
- hdmi_in_vp0: endpoint {
remote-endpoint = <&vp0_out_hdmi>;
- };
+};
+&hdmi_out {
- hdmi_out_con: endpoint {
remote-endpoint = <&hdmi_con_in>;
- };
+};
+&hdmi_sound {
- status = "okay";
+};
+&i2c0 {
- status = "okay";
- rk817: pmic@20 {
compatible = "rockchip,rk817";
reg = <0x20>;
interrupt-parent = <&gpio0>;
interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
clock-output-names = "rk808-clkout1", "rk808-clkout2";
clock-names = "mclk";
clocks = <&cru I2S1_MCLKOUT_TX>;
assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
#clock-cells = <1>;
#sound-dai-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&i2s1m0_mclk>, <&pmic_int_l>;
wakeup-source;
vcc1-supply = <&vcc_sys>;
vcc2-supply = <&vcc_sys>;
vcc3-supply = <&vcc_sys>;
vcc4-supply = <&vcc_sys>;
vcc5-supply = <&vcc_sys>;
vcc6-supply = <&vcc_sys>;
vcc7-supply = <&vcc_sys>;
vcc8-supply = <&vcc_sys>;
vcc9-supply = <&dcdc_boost>;
regulators {
vdd_logic: DCDC_REG1 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1350000>;
regulator-init-microvolt = <900000>;
regulator-ramp-delay = <6001>;
regulator-initial-mode = <0x2>;
regulator-name = "vdd_logic";
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <900000>;
};
};
vdd_gpu: DCDC_REG2 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1350000>;
regulator-init-microvolt = <900000>;
regulator-ramp-delay = <6001>;
regulator-initial-mode = <0x2>;
regulator-name = "vdd_gpu";
regulator-state-mem {
regulator-off-in-suspend;
};
};
vcc_ddr: DCDC_REG3 {
regulator-always-on;
regulator-boot-on;
regulator-initial-mode = <0x2>;
regulator-name = "vcc_ddr";
regulator-state-mem {
regulator-on-in-suspend;
};
};
vcc_3v3: DCDC_REG4 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-initial-mode = <0x2>;
regulator-name = "vcc_3v3";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <3300000>;
};
};
vcca1v8_pmu: LDO_REG1 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "vcca1v8_pmu";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <1800000>;
};
};
vdda_0v9: LDO_REG2 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <900000>;
regulator-name = "vdda_0v9";
regulator-state-mem {
regulator-off-in-suspend;
};
};
vdda0v9_pmu: LDO_REG3 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <900000>;
regulator-name = "vdda0v9_pmu";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <900000>;
};
};
vccio_acodec: LDO_REG4 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vccio_acodec";
regulator-state-mem {
regulator-off-in-suspend;
};
};
vccio_sd: LDO_REG5 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vccio_sd";
regulator-state-mem {
regulator-off-in-suspend;
};
};
vcc3v3_pmu: LDO_REG6 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc3v3_pmu";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <3300000>;
};
};
vcc_1v8: LDO_REG7 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "vcc_1v8";
regulator-state-mem {
regulator-off-in-suspend;
};
};
vcc1v8_dvp: LDO_REG8 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc1v8_dvp";
regulator-state-mem {
regulator-off-in-suspend;
};
};
vcc2v8_dvp: LDO_REG9 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-name = "vcc2v8_dvp";
regulator-state-mem {
regulator-off-in-suspend;
};
};
dcdc_boost: BOOST {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <4700000>;
regulator-max-microvolt = <5400000>;
regulator-name = "boost";
regulator-state-mem {
regulator-off-in-suspend;
};
};
otg_switch: OTG_SWITCH {
regulator-name = "otg_switch";
regulator-state-mem {
regulator-off-in-suspend;
};
};
};
- };
- vdd_cpu: regulator@40 {
compatible = "fcs,fan53555";
reg = <0x40>;
fcs,suspend-voltage-selector = <1>;
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <712500>;
regulator-max-microvolt = <1390000>;
regulator-init-microvolt = <900000>;
regulator-name = "vdd_cpu";
regulator-ramp-delay = <2300>;
vin-supply = <&vcc_sys>;
regulator-state-mem {
regulator-off-in-suspend;
};
- };
+};
+&i2c1 {
- /* Unknown/unused device at 0x3c */
- status = "disabled";
+};
+&i2c5 {
- pinctrl-0 = <&i2c5m1_xfer>;
- pinctrl-names = "default";
- status = "okay";
+};
+&i2s0_8ch {
- status = "okay";
+};
+&i2s1_8ch {
- pinctrl-0 = <&i2s1m0_sclktx
&i2s1m0_lrcktx
&i2s1m0_sdi0
&i2s1m0_sdo0>;
- pinctrl-names = "default";
- rockchip,trcm-sync-tx-only;
- status = "okay";
+};
+&pinctrl {
- gpio-btns {
btn_pins_ctrl: btn-pins-ctrl {
rockchip,pins =
<3 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>,
<3 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>,
<3 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>,
<3 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>,
<3 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>,
<3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>,
<3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>,
<3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>,
<3 RK_PB3 RK_FUNC_GPIO &pcfg_pull_up>,
<3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>,
<3 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>,
<3 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>,
<3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>,
<3 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>,
<3 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>,
<3 RK_PC3 RK_FUNC_GPIO &pcfg_pull_up>;
};
btn_pins_vol: btn-pins-vol {
rockchip,pins =
<3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>,
<3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
};
- };
- gpio-led {
led_pins: led-pins {
rockchip,pins =
<0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>,
<0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>,
<0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
};
- };
- joy-mux {
joy_mux_en: joy-mux-en {
rockchip,pins =
<0 RK_PB5 RK_FUNC_GPIO &pcfg_output_low>;
};
- };
- pmic {
pmic_int_l: pmic-int-l {
rockchip,pins =
<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
};
- };
- sdio-pwrseq {
wifi_enable_h: wifi-enable-h {
rockchip,pins =
<4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
};
- };
- vcc3v3-lcd {
vcc_lcd_h: vcc-lcd-h {
rockchip,pins =
<0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
};
- };
- vcc-wifi {
vcc_wifi_h: vcc-wifi-h {
rockchip,pins =
<0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
};
- };
+};
+&pmu_io_domains {
- status = "okay";
- 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 = <&vcc1v8_dvp>;
- vccio7-supply = <&vcc_3v3>;
+};
+&pwm5 {
- status = "okay";
+};
+&saradc {
- vref-supply = <&vcc_1v8>;
- status = "okay";
+};
+&sdmmc0 {
- bus-width = <4>;
- cap-sd-highspeed;
- cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
- disable-wp;
- pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
- pinctrl-names = "default";
- sd-uhs-sdr104;
- vmmc-supply = <&vcc_3v3>;
- vqmmc-supply = <&vccio_sd>;
- status = "okay";
+};
+&sdmmc1 {
- bus-width = <4>;
- cap-sd-highspeed;
- cd-gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
- disable-wp;
- pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk &sdmmc1_det>;
- pinctrl-names = "default";
- sd-uhs-sdr104;
- vmmc-supply = <&vcc_3v3>;
- vqmmc-supply = <&vcc1v8_dvp>;
- status = "okay";
+};
+&sdmmc2 {
- bus-width = <4>;
- cap-sd-highspeed;
- cap-sdio-irq;
- keep-power-in-suspend;
- mmc-pwrseq = <&sdio_pwrseq>;
- non-removable;
- pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_cmd &sdmmc2m0_clk>;
- pinctrl-names = "default";
- vmmc-supply = <&vcc_wifi>;
- vqmmc-supply = <&vcca1v8_pmu>;
- status = "okay";
+};
+&tsadc {
- rockchip,hw-tshut-mode = <1>;
- rockchip,hw-tshut-polarity = <0>;
- status = "okay";
+};
+&uart1 {
- pinctrl-0 = <&uart1m1_xfer &uart1m1_ctsn &uart1m1_rtsn>;
- pinctrl-names = "default";
- uart-has-rtscts;
- status = "okay";
- bluetooth {
compatible = "realtek,rtl8821cs-bt", "realtek,rtl8723bs-bt";
device-wake-gpios = <&gpio4 4 GPIO_ACTIVE_HIGH>;
enable-gpios = <&gpio4 3 GPIO_ACTIVE_HIGH>;
host-wake-gpios = <&gpio4 5 GPIO_ACTIVE_HIGH>;
- };
+};
+&uart2 {
- status = "okay";
+};
+/*
- Lack the schematics to verify, but port works as a peripheral
- (and not a host or OTG port).
- */
+&usb_host0_xhci {
- dr_mode = "peripheral";
- phys = <&usb2phy0_otg>;
- phy-names = "usb2-phy";
- status = "okay";
+};
+&usb_host1_ehci {
- status = "okay";
+};
+&usb_host1_ohci {
- status = "okay";
+};
+&usb_host1_xhci {
- phy-names = "usb2-phy", "usb3-phy";
- phys = <&usb2phy1_host>, <&combphy1 PHY_TYPE_USB3>;
- status = "okay";
+};
+&usb2phy0 {
- status = "okay";
+};
+&usb2phy0_otg {
- status = "okay";
+};
+&usb2phy1 {
- status = "okay";
+};
+&usb2phy1_host {
- status = "okay";
+};
+&vop {
- assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
- assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
- status = "okay";
+};
+&vop_mmu {
- status = "okay";
+};
+&vp0 {
- vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
reg = <ROCKCHIP_VOP2_EP_HDMI0>;
remote-endpoint = <&hdmi_in_vp0>;
- };
+}; diff --git a/arch/arm/mach-rockchip/rk3568/Kconfig b/arch/arm/mach-rockchip/rk3568/Kconfig index 4e7c02cce0..94e04b79e7 100644 --- a/arch/arm/mach-rockchip/rk3568/Kconfig +++ b/arch/arm/mach-rockchip/rk3568/Kconfig @@ -1,11 +1,24 @@ if ROCKCHIP_RK3568
+choice
- prompt "RK3568/RK3566 board select"
- config TARGET_EVB_RK3568 bool "RK3568 evaluation board" select BOARD_LATE_INIT help RK3568 EVB is a evaluation board for Rockchp RK3568.
+config TARGET_ANBERNIC_RGXX3_RK3566
- bool "Anbernic RGXX3"
- help
Anbernic RGXX3 gaming device with Rockchip RK3566. This
config can be used with the RG353M, RG353P, RG353V, RG353VS,
and RG503. The correct device tree name will automatically
be selected by the bootloader.
+endchoice
- config ROCKCHIP_BOOT_MODE_REG default 0xfdc20200
@@ -19,5 +32,6 @@ config SYS_MALLOC_F_LEN default 0x2000
source "board/rockchip/evb_rk3568/Kconfig" +source "board/anbernic/rgxx3_rk3566/Kconfig"
endif diff --git a/board/anbernic/rgxx3_rk3566/Kconfig b/board/anbernic/rgxx3_rk3566/Kconfig new file mode 100644 index 0000000000..6743a28a2f --- /dev/null +++ b/board/anbernic/rgxx3_rk3566/Kconfig @@ -0,0 +1,15 @@ +if TARGET_ANBERNIC_RGXX3_RK3566
+config SYS_BOARD
- default "rgxx3_rk3566"
+config SYS_VENDOR
- default "anbernic"
+config SYS_CONFIG_NAME
- default "anbernic-rgxx3-rk3566"
+config BOARD_SPECIFIC_OPTIONS
- def_bool y
+endif diff --git a/board/anbernic/rgxx3_rk3566/MAINTAINERS b/board/anbernic/rgxx3_rk3566/MAINTAINERS new file mode 100644 index 0000000000..647e49d28a --- /dev/null +++ b/board/anbernic/rgxx3_rk3566/MAINTAINERS @@ -0,0 +1,6 @@ +RGXX3-RK3566 +M: Chris Morgan macromorgan@hotmail.com +S: Maintained +F: board/anbernic/rgxx3-rk3566 +F: include/configs/anbernic-rgxx3-rk3566 +F: configs/anbernic-rgxx3_defconfig diff --git a/board/anbernic/rgxx3_rk3566/Makefile b/board/anbernic/rgxx3_rk3566/Makefile new file mode 100644 index 0000000000..afd3e0adf6 --- /dev/null +++ b/board/anbernic/rgxx3_rk3566/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (c) 2023 Chris Morgan macromorgan@hotmail.com +#
+obj-y += rgxx3-rk3566.o diff --git a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c new file mode 100644 index 0000000000..decc46db78 --- /dev/null +++ b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c @@ -0,0 +1,203 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (c) 2023 Chris Morgan macromorgan@hotmail.com
- */
+#include <abuf.h> +#include <adc.h> +#include <asm/io.h> +#include <dm.h> +#include <linux/delay.h> +#include <pwm.h> +#include <rng.h> +#include <stdlib.h> +#include <mmc.h> +#include <env.h>
+#define GPIO0_BASE 0xfdd60000 +#define GPIO_SWPORT_DR_H 0x0004 +#define GPIO_SWPORT_DDR_H 0x000c +#define GPIO_A5 BIT(5) +#define GPIO_A6 BIT(6)
+#define GPIO_WRITEMASK(bits) ((bits) << 16)
+#define DTB_DIR "rockchip/"
+struct rg3xx_model {
- const char *board;
- const char *board_name;
- const char *fdtfile;
+};
+enum rgxx3_device_id {
- RG353M,
- RG353P,
- RG353V,
- RG353VS,
- RG503,
+};
+static const struct rg3xx_model rg3xx_model_details[] = {
- [RG353M] = {
"rk3566-anbernic-rg353m",
"RG353M",
DTB_DIR "rk3566-anbernic-rg353m.dtb",
- },
- [RG353P] = {
"rk3566-anbernic-rg353p",
"RG353P",
DTB_DIR "rk3566-anbernic-rg353p.dtb",
- },
- [RG353V] = {
"rk3566-anbernic-rg353v",
"RG353V",
DTB_DIR "rk3566-anbernic-rg353v.dtb",
- },
- [RG353VS] = {
"rk3566-anbernic-rg353vs",
"RG353VS",
DTB_DIR "rk3566-anbernic-rg353vs.dtb",
- },
- [RG503] = {
"rk3566-anbernic-rg503",
"RG503",
DTB_DIR "rk3566-anbernic-rg503.dtb",
- },
+};
+/*
- Start LED very early so user knows device is on. Set color
- to amber.
- */
+void spl_board_init(void) +{
- /* Set GPIO0_A5 and GPIO0_A6 to output. */
- writel(GPIO_WRITEMASK(GPIO_A6 | GPIO_A5) | (GPIO_A6 | GPIO_A5),
(GPIO0_BASE + GPIO_SWPORT_DDR_H));
- /* Set GPIO0_A5 to 0 and GPIO0_A6 to 1. */
- writel(GPIO_WRITEMASK(GPIO_A6 | GPIO_A5) | GPIO_A6,
(GPIO0_BASE + GPIO_SWPORT_DR_H));
+}
+/* Use hardware rng to seed Linux random. */ +int board_rng_seed(struct abuf *buf) +{
- struct udevice *dev;
- size_t len = 0x8;
- u64 *data;
- data = malloc(len);
- if (!data) {
printf("Out of memory\n");
return -ENOMEM;
- }
- if (uclass_get_device(UCLASS_RNG, 0, &dev) || !dev) {
printf("No RNG device\n");
return -ENODEV;
- }
- if (dm_rng_read(dev, data, len)) {
printf("Reading RNG failed\n");
return -EIO;
- }
- abuf_init_set(buf, data, len);
- return 0;
+}
+/*
- Buzz the buzzer so the user knows something is going on. Make it
- optional in case PWM is disabled.
- */
+void __maybe_unused startup_buzz(void) +{
- struct udevice *dev;
- int err;
- err = uclass_get_device(UCLASS_PWM, 0, &dev);
- if (err)
printf("pwm not found\n");
- pwm_set_enable(dev, 0, 1);
- mdelay(200);
- pwm_set_enable(dev, 0, 0);
+}
+/* Detect which Anbernic RGXX3 device we are using so as to load the
- correct devicetree for Linux. Set an environment variable once
- found. The detection depends on the value of ADC channel 1, the
- presence of an eMMC on mmc0, and querying the DSI panel (TODO).
- */
+int rgxx3_detect_device(void) +{
- u32 adc_info;
- int ret;
- int board_id = -ENXIO;
- struct mmc *mmc;
- ret = adc_channel_single_shot("saradc@fe720000", 1, &adc_info);
- if (ret) {
printf("Read SARADC failed with error %d\n", ret);
return ret;
- }
- /* Observed value 517. */
- if (adc_info > 505 && adc_info < 530)
board_id = RG353M;
- /* Observed value 695. */
- if (adc_info > 680 && adc_info < 710)
board_id = RG353V;
- /* Documented value 860. */
- if (adc_info > 850 && adc_info < 870)
board_id = RG353P;
- /* Observed value 1023. */
- if (adc_info > 1010)
board_id = RG503;
- /*
* Try to access the eMMC on an RG353V. If it's missing, it's
* an RG353VS. Note we could also check for a touchscreen at
* 0x1a on i2c2.
*/
- if (board_id == RG353V) {
mmc = find_mmc_device(0);
if (mmc) {
ret = mmc_init(mmc);
if (ret)
board_id = RG353VS;
}
- }
- if (board_id < 0)
return board_id;
- env_set("board", rg3xx_model_details[board_id].board);
- env_set("board_name",
rg3xx_model_details[board_id].board_name);
- env_set("fdtfile", rg3xx_model_details[board_id].fdtfile);
- return 0;
+}
+int rk_board_late_init(void) +{
- int ret;
- /* Turn off orange LED and turn on green LED. */
- writel(GPIO_WRITEMASK(GPIO_A6 | GPIO_A5) | GPIO_A5,
(GPIO0_BASE + GPIO_SWPORT_DR_H));
- ret = rgxx3_detect_device();
- if (ret) {
printf("Unable to detect device type: %d\n", ret);
return ret;
- }
- if (IS_ENABLED(CONFIG_DM_PWM))
startup_buzz();
- return 0;
+} diff --git a/configs/anbernic-rgxx3_defconfig b/configs/anbernic-rgxx3_defconfig new file mode 100644 index 0000000000..b17e917914 --- /dev/null +++ b/configs/anbernic-rgxx3_defconfig @@ -0,0 +1,78 @@ +CONFIG_ARM=y +CONFIG_SKIP_LOWLEVEL_INIT=y +CONFIG_COUNTER_FREQUENCY=24000000 +CONFIG_ARCH_ROCKCHIP=y +CONFIG_TEXT_BASE=0x00a00000 +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_NR_DRAM_BANKS=2 +CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc00000 +CONFIG_DEFAULT_DEVICE_TREE="rk3566-anbernic-rgxx3" +CONFIG_ROCKCHIP_RK3568=y +CONFIG_SPL_ROCKCHIP_BACK_TO_BROM=y +CONFIG_SPL_ROCKCHIP_COMMON_BOARD=y +CONFIG_SPL_MMC=y +CONFIG_SPL_SERIAL=y +CONFIG_SPL_STACK_R_ADDR=0x600000 +CONFIG_TARGET_ANBERNIC_RGXX3_RK3566=y +CONFIG_SPL_STACK=0x400000 +CONFIG_DEBUG_UART_BASE=0xFE660000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_SYS_LOAD_ADDR=0xc00800 +CONFIG_DEBUG_UART=y +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_SPL_LOAD_FIT=y +CONFIG_DEFAULT_FDT_FILE="rockchip/rk3566-anbernic-rgxx3.dtb" +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_SPL_MAX_SIZE=0x20000 +CONFIG_SPL_PAD_TO=0x7f8000 +CONFIG_SPL_HAS_BSS_LINKER_SECTION=y +CONFIG_SPL_BSS_START_ADDR=0x4000000 +CONFIG_SPL_BSS_MAX_SIZE=0x4000 +CONFIG_SPL_BOARD_INIT=y +# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set +# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set +CONFIG_SPL_STACK_R=y +CONFIG_SPL_ATF=y +CONFIG_CMD_PWM=y +CONFIG_CMD_GPT=y +CONFIG_CMD_MMC=y +# CONFIG_CMD_SETEXPR is not set +# CONFIG_SPL_DOS_PARTITION is not set +CONFIG_SPL_OF_CONTROL=y +CONFIG_OF_LIVE=y +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +# CONFIG_NET is not set +CONFIG_SPL_REGMAP=y +CONFIG_SPL_SYSCON=y +CONFIG_SPL_CLK=y +CONFIG_ARM_SMCCC_FEATURES=y +CONFIG_SCMI_FIRMWARE=y +CONFIG_ROCKCHIP_GPIO=y +CONFIG_SYS_I2C_ROCKCHIP=y +CONFIG_MISC=y +CONFIG_SUPPORT_EMMC_RPMB=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_ROCKCHIP=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_SDMA=y +CONFIG_MMC_SDHCI_ROCKCHIP=y +CONFIG_DM_PMIC=y +CONFIG_DM_PMIC_FAN53555=y +CONFIG_PMIC_RK8XX=y +CONFIG_REGULATOR_PWM=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_REGULATOR_RK8XX=y +CONFIG_DM_REGULATOR_SCMI=y +CONFIG_PWM_ROCKCHIP=y +CONFIG_SPL_RAM=y +CONFIG_BAUDRATE=1500000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYS_NS16550_MEM32=y +CONFIG_SYSRESET=y +CONFIG_REGEX=y +CONFIG_ERRNO_STR=y +# CONFIG_EFI_LOADER is not set diff --git a/doc/board/anbernic/index.rst b/doc/board/anbernic/index.rst new file mode 100644 index 0000000000..03758d8613 --- /dev/null +++ b/doc/board/anbernic/index.rst @@ -0,0 +1,9 @@ +.. SPDX-License-Identifier: GPL-2.0+
+Anbernic +========
+.. toctree::
- :maxdepth: 2
- rgxx3.rst
diff --git a/doc/board/anbernic/rgxx3.rst b/doc/board/anbernic/rgxx3.rst new file mode 100644 index 0000000000..afa7538282 --- /dev/null +++ b/doc/board/anbernic/rgxx3.rst @@ -0,0 +1,47 @@ +.. SPDX-License-Identifier: GPL-2.0+
+U-Boot for Anbernic RGxx3 Devices +=================================
+This allows U-Boot to boot the following Anbernic devices:
- Anbernic RG353M
- Anbernic RG353P
- Anbernic RG353V
- Anbernic RG353VS
- Anbernic RG503
+The correct device is detected automatically by comparing ADC values +from ADC channel 1. In the event of an RG353V, an attempt is then made +to probe for an eMMC and if it fails the device is assumed to be an +RG353VS. Based on the detected device, the environment variables +"board", "board_name", and "fdtfile" are set to the correct values +corresponding to the board which can be read by a boot script to boot +with the correct device tree.
+Please note that there are some versions of the RG353 devices with +different panels. Panel auto-detection is planned for a later date.
+Building U-Boot +---------------
+.. code-block:: bash
- $ export CROSS_COMPILE=aarch64-none-elf-
- $ export BL31=../rkbin/bin/rk35/rk3568_bl31_v1.34.elf
- $ export ROCKCHIP_TPL=../rkbin/bin/rk35/rk3568_ddr_1056MHz_v1.13.bin
- $ make anbernic-rgxx3_defconfig
- $ make
+This will build ``u-boot-rockchip.bin`` which can be written to an SD +card.
+Image installation +------------------
+Write the ``u-boot-rockchip.bin`` to an SD card offset 32kb from the +start.
+.. code-block:: bash
- $ dd if=u-boot-rockchip.bin of=/dev/mmcblk0 bs=512 seek=64
diff --git a/doc/board/index.rst b/doc/board/index.rst index 69e2cd5fb8..820eb71d71 100644 --- a/doc/board/index.rst +++ b/doc/board/index.rst @@ -11,6 +11,7 @@ Board-specific doc AndesTech/index allwinner/index amlogic/index
- anbernic/index apple/index armltd/index atmel/index
diff --git a/doc/board/rockchip/rockchip.rst b/doc/board/rockchip/rockchip.rst index b5563b8f7f..204cace1e9 100644 --- a/doc/board/rockchip/rockchip.rst +++ b/doc/board/rockchip/rockchip.rst @@ -87,6 +87,9 @@ List of mainline supported Rockchip boards: - Rockchip Evb-RK3399 (evb_rk3399) - Theobroma Systems RK3399-Q7 SoM - Puma (puma_rk3399)
+* rk3566
- Anbernic RGxx3 (rgxx3-rk3566)
- rk3568
- Rockchip Evb-RK3568 (evb-rk3568)
diff --git a/include/configs/anbernic-rgxx3-rk3566.h b/include/configs/anbernic-rgxx3-rk3566.h new file mode 100644 index 0000000000..3c4ea4e7d8 --- /dev/null +++ b/include/configs/anbernic-rgxx3-rk3566.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0+ */
+#ifndef __ANBERNIC_RGXX3_RK3566_H +#define __ANBERNIC_RGXX3_RK3566_H
+#include <configs/rk3568_common.h>
+#define ROCKCHIP_DEVICE_SETTINGS \
"stdout=serial,vidconsole\0" \
"stderr=serial,vidconsole\0"
+#endif
participants (2)
-
Chris Morgan
-
Kever Yang