All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v9 00/16] Add Rikomagic MK808 board
@ 2022-04-04 14:19 Johan Jonker
  2022-04-04 14:19 ` [PATCH v9 01/16] rockchip: rk3066-power: sync power domain dt-binding header from Linux Johan Jonker
                   ` (15 more replies)
  0 siblings, 16 replies; 33+ messages in thread
From: Johan Jonker @ 2022-04-04 14:19 UTC (permalink / raw)
  To: kever.yang; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot

MK808 is a RK3066-based board with 1 USB host and 1 USB OTG port,
HDMI and a micro-SD card slot. It also includes on-board NAND
and 1GB of SDRAM.

Changed V9:
  fix TABs and spaces
  add led config
  enable led gpio
  change pinctrl regmap source
  disable STIMER
  move include
  
Changed V8:
  update clock driver
  update grf header file

Changed V7:
  add board files
  enable boot from SD card
  restyle pinctrl driver
  restyle sdram driver  

===

Boot procedure flow for a Rockchip rk3066 SoC:

1.Read 2K SDRAM initialization image code to internal SRAM
2.Run image code to do SDRAM initialization
3.Transfer boot image code to SDRAM
4.Run boot image code

Supported system boot from the following devices:
Nand Flash
SPI nor Flash
eMMC device
UART interface

If all boot options fail then enter into BootROM mode on the USB OTG port.
Unlike later SoC models the rk3066 BootROM doesn't have SDMMC support.

The size of a full U-boot binary is too large for the internal SDRAM memory.
Of that 64k size only 32kb sram - 2kb bootrom is available for the first stage.

Similar to the already supported rk3188, the BootROM will attempt to load up the first stage
image in two steps: first 1KB to offset 0x800 in the SRAM and
then the remainder to offset 0xc00 in the SRAM.
It always enters at offset 0x804 after a 4 ASCII character "RK30" header.

With CONFIG_TPL_ROCKCHIP_EARLYRETURN_TO_BROM=y this first stage is combined with
the U-boot TPL binary (u-boot-tpl.bin).

For rk3066 with NAND flash and U-boot this gives the following stages:

- TPL: init external SDRAM
- SPL: init SDMMC and read U-boot from SD CARD.
- U-boot: read Linux kernel from SD CARD.
- Kernel

Additionally the rk3066 requires everything the BootROM loads to be
RC4-encrypted.

===

Boot solution with full U-boot stored on SD CARD:

Compile commands(U-boot):

ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make mk808_defconfig
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make menuconfig
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make all

===

Size of SPL and TPL must be aligned to 2kb.
If bricked and no BootROM mode shows up then connect pin 8 and 9 of the NAND flash
with a needle while reconnecting to the USB OTG port to a PC.

===

Show connected devices with:

lsusb

Bus 001 Device 004: ID 2207:300a Fuzhou Rockchip Electronics Company RK3066 in Mask ROM mode

===

Program commands with ./flash.sh:

#!/bin/sh

printf "RK30" > tplspl.bin
dd if=u-boot-tpl.bin >> tplspl.bin
truncate -s %2048 tplspl.bin
truncate -s %2048 u-boot-spl.bin
../tools/boot_merger --verbose config-flash.ini
../tools/upgrade_tool ul ./RK30xxLoader_uboot.bin

===

config-flash.ini:

[CHIP_NAME]
NAME=RK30
[VERSION]
MAJOR=2
MINOR=21
[CODE471_OPTION]
NUM=1
Path1=30_LPDDR2_300MHz_DD.bin
[CODE472_OPTION]
NUM=1
Path1=rk30usbplug.bin
[LOADER_OPTION]
NUM=2
LOADER1=FlashData
LOADER2=FlashBoot
FlashData=tplspl.bin
FlashBoot=u-boot-spl.bin
[OUTPUT]
PATH=RK30xxLoader_uboot.bin

===

Partition Map for MMC device 0  --   Partition Type: EFI

Part	Start LBA	End LBA		Name
	Attributes
	Type GUID
	Partition GUID
  1	0x00000040	0x00001f7f	"loader1"
  2	0x00004000	0x00005fff	"loader2"
  3	0x00006000	0x00007fff	"trust"
  4	0x00008000	0x0003ffff	"boot"
  5	0x00040000	0x00ed7fde	"rootfs"

Make sure boot and esp flag are set for boot partition.
Loader1 not used by Rk3066.

===

Boot partition:

extlinux -- extlinux.conf
zImage
rk3066a-mk808.dtb

===

extlinux.conf:

label kernel
    kernel /zImage
    fdt /rk3066a-mk808.dtb
    append root=LABEL=linuxroot init=/sbin/init rootfstype=ext4 rootwait

===

Program commands (SD CARD with GPT partition):

sudo dd if=u-boot-dtb.img of=/dev/sda seek=16384

===

TODO:
  Better program flow/tools
  USB
  NAND
  etc etc

===

Johan Jonker (12):
  rockchip: rk3066-power: sync power domain dt-binding header from Linux
  arm: dts: rockchip: fix rk3xxx-u-boot.dtsi
  arm: dts: rockchip: fix include rk3xxx-u-boot.dtsi
  arm: dts: rockchip: add rk3066a.dtsi
  arm: dts: rockchip: add rk3066a-mk808.dts
  rockchip: rk3066: add include
  rockchip: rk3066: add rk3066_common.h include
  rockchip: rk3066: add core support
  rockchip: rk3066: add Rikomagic MK808 board
  rockchip: rk3066: add mk808_defconfig
  rockchip: tools: add rk3066 support to rkcommon.c
  doc: rockchip: add rk3066 Rikomagic MK808

Paweł Jarosz (4):
  rockchip: rk3066: add grf header file
  rockchip: rk3066: add clock driver for rk3066 soc
  rockchip: rk3066: add rk3066 pinctrl driver
  rockchip: rk3066: add sdram driver

 arch/arm/dts/Makefile                         |   3 +
 arch/arm/dts/rk3066a-mk808-u-boot.dtsi        |  48 +
 arch/arm/dts/rk3066a-mk808.dts                | 216 +++++
 arch/arm/dts/rk3066a-u-boot.dtsi              |   4 +
 arch/arm/dts/rk3066a.dtsi                     | 879 +++++++++++++++++
 arch/arm/dts/rk3188-u-boot.dtsi               |   1 +
 arch/arm/dts/rk3188.dtsi                      |   1 -
 arch/arm/dts/rk3xxx-u-boot.dtsi               |   8 +-
 arch/arm/include/asm/arch-rk3066/boot0.h      |   8 +
 arch/arm/include/asm/arch-rk3066/gpio.h       |   8 +
 arch/arm/include/asm/arch-rk3066/timer.h      |   6 +
 .../include/asm/arch-rockchip/cru_rk3066.h    | 157 +++
 .../include/asm/arch-rockchip/grf_rk3066.h    | 210 +++++
 arch/arm/mach-rockchip/Kconfig                |  23 +
 arch/arm/mach-rockchip/Makefile               |   1 +
 arch/arm/mach-rockchip/rk3066/Kconfig         |  39 +
 arch/arm/mach-rockchip/rk3066/Makefile        |   5 +
 arch/arm/mach-rockchip/rk3066/clk_rk3066.c    |  33 +
 arch/arm/mach-rockchip/rk3066/rk3066.c        |  49 +
 arch/arm/mach-rockchip/rk3066/syscon_rk3066.c |  55 ++
 board/rikomagic/mk808/Kconfig                 |  15 +
 board/rikomagic/mk808/MAINTAINERS             |   6 +
 board/rikomagic/mk808/Makefile                |   3 +
 board/rikomagic/mk808/mk808.c                 |   3 +
 configs/mk808_defconfig                       | 100 ++
 doc/board/rockchip/rockchip.rst               |   2 +
 drivers/clk/rockchip/Makefile                 |   1 +
 drivers/clk/rockchip/clk_rk3066.c             | 717 ++++++++++++++
 drivers/pinctrl/rockchip/Makefile             |   1 +
 drivers/pinctrl/rockchip/pinctrl-rk3066.c     | 112 +++
 drivers/ram/rockchip/Makefile                 |   1 +
 drivers/ram/rockchip/sdram_rk3066.c           | 892 ++++++++++++++++++
 include/configs/mk808.h                       |   9 +
 include/configs/rk3066_common.h               |  56 ++
 include/dt-bindings/power/rk3066-power.h      |  22 +
 tools/rkcommon.c                              |   1 +
 36 files changed, 3690 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/dts/rk3066a-mk808-u-boot.dtsi
 create mode 100644 arch/arm/dts/rk3066a-mk808.dts
 create mode 100644 arch/arm/dts/rk3066a-u-boot.dtsi
 create mode 100644 arch/arm/dts/rk3066a.dtsi
 create mode 100644 arch/arm/include/asm/arch-rk3066/boot0.h
 create mode 100644 arch/arm/include/asm/arch-rk3066/gpio.h
 create mode 100644 arch/arm/include/asm/arch-rk3066/timer.h
 create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rk3066.h
 create mode 100644 arch/arm/include/asm/arch-rockchip/grf_rk3066.h
 create mode 100644 arch/arm/mach-rockchip/rk3066/Kconfig
 create mode 100644 arch/arm/mach-rockchip/rk3066/Makefile
 create mode 100644 arch/arm/mach-rockchip/rk3066/clk_rk3066.c
 create mode 100644 arch/arm/mach-rockchip/rk3066/rk3066.c
 create mode 100644 arch/arm/mach-rockchip/rk3066/syscon_rk3066.c
 create mode 100644 board/rikomagic/mk808/Kconfig
 create mode 100644 board/rikomagic/mk808/MAINTAINERS
 create mode 100644 board/rikomagic/mk808/Makefile
 create mode 100644 board/rikomagic/mk808/mk808.c
 create mode 100644 configs/mk808_defconfig
 create mode 100644 drivers/clk/rockchip/clk_rk3066.c
 create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3066.c
 create mode 100644 drivers/ram/rockchip/sdram_rk3066.c
 create mode 100644 include/configs/mk808.h
 create mode 100644 include/configs/rk3066_common.h
 create mode 100644 include/dt-bindings/power/rk3066-power.h

-- 
2.20.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH v9 01/16] rockchip: rk3066-power: sync power domain dt-binding header from Linux
  2022-04-04 14:19 [PATCH v9 00/16] Add Rikomagic MK808 board Johan Jonker
@ 2022-04-04 14:19 ` Johan Jonker
  2022-04-06 15:01   ` Kever Yang
  2022-04-04 14:19 ` [PATCH v9 02/16] rockchip: rk3066: add grf header file Johan Jonker
                   ` (14 subsequent siblings)
  15 siblings, 1 reply; 33+ messages in thread
From: Johan Jonker @ 2022-04-04 14:19 UTC (permalink / raw)
  To: kever.yang; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot

In order to update the DT for rk3066
sync the power domain dt-binding header.
This is the state as of v5.12 in Linux.

Signed-off-by: Johan Jonker <jbx6244@gmail.com>
---
 include/dt-bindings/power/rk3066-power.h | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 include/dt-bindings/power/rk3066-power.h

diff --git a/include/dt-bindings/power/rk3066-power.h b/include/dt-bindings/power/rk3066-power.h
new file mode 100644
index 0000000000..acf9f310ac
--- /dev/null
+++ b/include/dt-bindings/power/rk3066-power.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __DT_BINDINGS_POWER_RK3066_POWER_H__
+#define __DT_BINDINGS_POWER_RK3066_POWER_H__
+
+/* VD_CORE */
+#define RK3066_PD_A9_0		0
+#define RK3066_PD_A9_1		1
+#define RK3066_PD_DBG		4
+#define RK3066_PD_SCU		5
+
+/* VD_LOGIC */
+#define RK3066_PD_VIDEO		6
+#define RK3066_PD_VIO		7
+#define RK3066_PD_GPU		8
+#define RK3066_PD_PERI		9
+#define RK3066_PD_CPU		10
+#define RK3066_PD_ALIVE		11
+
+/* VD_PMU */
+#define RK3066_PD_RTC		12
+
+#endif
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v9 02/16] rockchip: rk3066: add grf header file
  2022-04-04 14:19 [PATCH v9 00/16] Add Rikomagic MK808 board Johan Jonker
  2022-04-04 14:19 ` [PATCH v9 01/16] rockchip: rk3066-power: sync power domain dt-binding header from Linux Johan Jonker
@ 2022-04-04 14:19 ` Johan Jonker
  2022-04-09  3:49   ` Kever Yang
  2022-04-04 14:19 ` [PATCH v9 03/16] rockchip: rk3066: add clock driver for rk3066 soc Johan Jonker
                   ` (13 subsequent siblings)
  15 siblings, 1 reply; 33+ messages in thread
From: Johan Jonker @ 2022-04-04 14:19 UTC (permalink / raw)
  To: kever.yang; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot

From: Paweł Jarosz <paweljarosz3691@gmail.com>

grf is needed by various drivers for rk3066 soc.

Signed-off-by: Paweł Jarosz <paweljarosz3691@gmail.com>
Signed-off-by: Johan Jonker <jbx6244@gmail.com>
---

Changed V9:
  fix TAB

Changed V8:
  add GRF_GPIO3B_IOMUX for SDMMC0
  use GENMASK, __bf_shf and REG defines
  add includes
---
 .../include/asm/arch-rockchip/grf_rk3066.h    | 210 ++++++++++++++++++
 1 file changed, 210 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-rockchip/grf_rk3066.h

diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3066.h b/arch/arm/include/asm/arch-rockchip/grf_rk3066.h
new file mode 100644
index 0000000000..d8e0812cee
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3066.h
@@ -0,0 +1,210 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2021 Paweł Jarosz <paweljarosz3691@gmail.com>
+ */
+
+#ifndef _ASM_ARCH_GRF_RK3066_H
+#define _ASM_ARCH_GRF_RK3066_H
+
+#include <linux/bitops.h>
+#include <linux/bitfield.h>
+
+#define REG(name, h, l) \
+	name##_MASK = GENMASK(h, l), \
+	name##_SHIFT = __bf_shf(name##_MASK)
+
+struct rk3066_grf_gpio_lh {
+	u32 l;
+	u32 h;
+};
+
+struct rk3066_grf {
+	struct rk3066_grf_gpio_lh gpio_dir[7];
+	struct rk3066_grf_gpio_lh gpio_do[7];
+	struct rk3066_grf_gpio_lh gpio_en[7];
+
+	u32 gpio0a_iomux;
+	u32 gpio0b_iomux;
+	u32 gpio0c_iomux;
+	u32 gpio0d_iomux;
+
+	u32 gpio1a_iomux;
+	u32 gpio1b_iomux;
+	u32 gpio1c_iomux;
+	u32 gpio1d_iomux;
+
+	u32 gpio2a_iomux;
+	u32 gpio2b_iomux;
+	u32 gpio2c_iomux;
+	u32 gpio2d_iomux;
+
+	u32 gpio3a_iomux;
+	u32 gpio3b_iomux;
+	u32 gpio3c_iomux;
+	u32 gpio3d_iomux;
+
+	u32 gpio4a_iomux;
+	u32 gpio4b_iomux;
+	u32 gpio4c_iomux;
+	u32 gpio4d_iomux;
+
+	u32 reserved0[5];
+
+	u32 gpio6b_iomux;
+
+	u32 reserved1[2];
+
+	struct rk3066_grf_gpio_lh gpio_pull[7];
+
+	u32 soc_con0;
+	u32 soc_con1;
+	u32 soc_con2;
+
+	u32 soc_status0;
+
+	u32 dmac1_con[3];
+	u32 dmac2_con[4];
+
+	u32 uoc0_con[3];
+	u32 uoc1_con[4];
+	u32 ddrc_con;
+	u32 ddrc_stat;
+
+	u32 reserved2[10];
+
+	u32 os_reg[4];
+};
+
+check_member(rk3066_grf, os_reg[3], 0x01d4);
+
+/* GRF_GPIO1B_IOMUX */
+enum {
+	REG(GPIO1B1, 2, 2),
+	GPIO1B1_GPIO		= 0,
+	GPIO1B1_UART2_SOUT,
+
+	REG(GPIO1B0, 0, 0),
+	GPIO1B0_GPIO		= 0,
+	GPIO1B0_UART2_SIN
+};
+
+/* GRF_GPIO3B_IOMUX */
+enum {
+	REG(GPIO3B6, 12, 12),
+	GPIO3B6_GPIO		= 0,
+	GPIO3B6_SDMMC0_DECTN,
+
+	REG(GPIO3B5, 10, 10),
+	GPIO3B5_GPIO		= 0,
+	GPIO3B5_SDMMC0_DATA3,
+
+	REG(GPIO3B4, 8, 8),
+	GPIO3B4_GPIO		= 0,
+	GPIO3B4_SDMMC0_DATA2,
+
+	REG(GPIO3B3, 6, 6),
+	GPIO3B3_GPIO		= 0,
+	GPIO3B3_SDMMC0_DATA1,
+
+	REG(GPIO3B2, 4, 4),
+	GPIO3B2_GPIO		= 0,
+	GPIO3B2_SDMMC0_DATA0,
+
+	REG(GPIO3B1, 2, 2),
+	GPIO3B1_GPIO		= 0,
+	GPIO3B1_SDMMC0_CMD,
+
+	REG(GPIO3B0, 0, 0),
+	GPIO3B0_GPIO		= 0,
+	GPIO3B0_SDMMC0_CLKOUT,
+};
+
+/* GRF_SOC_CON0 */
+enum {
+	REG(SMC_MUX_CON, 13, 13),
+
+	REG(NOC_REMAP, 12, 12),
+
+	REG(EMMC_FLASH_SEL, 11, 11),
+
+	REG(TZPC_REVISION, 10, 7),
+
+	REG(L2CACHE_ACC, 6, 5),
+
+	REG(L2RD_WAIT, 4, 3),
+
+	REG(IMEMRD_WAIT, 2, 1),
+
+	REG(SOC_REMAP, 0, 0),
+};
+
+/* GRF_SOC_CON1 */
+enum {
+	REG(RKI2C4_SEL, 15, 15),
+
+	REG(RKI2C3_SEL, 14, 14),
+
+	REG(RKI2C2_SEL, 13, 13),
+
+	REG(RKI2C1_SEL, 12, 12),
+
+	REG(RKI2C0_SEL, 11, 11),
+
+	REG(VCODEC_SEL, 10, 10),
+
+	REG(PERI_EMEM_PAUSE, 9, 9),
+
+	REG(PERI_USB_PAUSE, 8, 8),
+
+	REG(SMC_MUX_MODE_0, 6, 6),
+
+	REG(SMC_SRAM_MW_0, 5, 4),
+
+	REG(SMC_REMAP_0, 3, 3),
+
+	REG(SMC_A_GT_M0_SYNC, 2, 2),
+
+	REG(EMAC_SPEED, 1, 1),
+
+	REG(EMAC_MODE, 0, 0),
+};
+
+/* GRF_SOC_CON2 */
+enum {
+	REG(MSCH4_MAINDDR3, 7, 7),
+	MSCH4_MAINDDR3_DDR3	= 1,
+
+	REG(EMAC_NEWRCV_EN, 6, 6),
+
+	REG(SW_ADDR15_EN, 5, 5),
+
+	REG(SW_ADDR16_EN, 4, 4),
+
+	REG(SW_ADDR17_EN, 3, 3),
+
+	REG(BANK2_TO_RANK_EN, 2, 2),
+
+	REG(RANK_TO_ROW15_EN, 1, 1),
+
+	REG(UPCTL_C_ACTIVE_IN, 0, 0),
+	UPCTL_C_ACTIVE_IN_MAY	= 0,
+	UPCTL_C_ACTIVE_IN_WILL,
+};
+
+/* GRF_DDRC_CON0 */
+enum {
+	REG(DTO_LB, 12, 11),
+
+	REG(DTO_TE, 10, 9),
+
+	REG(DTO_PDR, 8, 7),
+
+	REG(DTO_PDD, 6, 5),
+
+	REG(DTO_IOM, 4, 3),
+
+	REG(DTO_OE, 2, 1),
+
+	REG(ATO_AE, 0, 0),
+};
+#endif
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v9 03/16] rockchip: rk3066: add clock driver for rk3066 soc
  2022-04-04 14:19 [PATCH v9 00/16] Add Rikomagic MK808 board Johan Jonker
  2022-04-04 14:19 ` [PATCH v9 01/16] rockchip: rk3066-power: sync power domain dt-binding header from Linux Johan Jonker
  2022-04-04 14:19 ` [PATCH v9 02/16] rockchip: rk3066: add grf header file Johan Jonker
@ 2022-04-04 14:19 ` Johan Jonker
  2022-04-09  3:49   ` Kever Yang
  2022-04-04 14:19 ` [PATCH v9 04/16] rockchip: rk3066: add rk3066 pinctrl driver Johan Jonker
                   ` (12 subsequent siblings)
  15 siblings, 1 reply; 33+ messages in thread
From: Johan Jonker @ 2022-04-04 14:19 UTC (permalink / raw)
  To: kever.yang; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot

From: Paweł Jarosz <paweljarosz3691@gmail.com>

Add the clock driver for the rk3066 platform.

Derived from the rk3288 and rk3188 driver it
supports only a bare minimum to bring up the system
to reduce the TPL size for:
  SDRAM clock configuration.
  The boot devices NAND, EMMC, SDMMC, SPI.
  A UART for the debug messages (fixed) at 115200n8.
  A SARADC for the recovery button.
  A TIMER for the delays (fixed).

There's support for two possible frequencies,
the safe 600MHz which will work with default pmic settings and
will be set to get away from the 24MHz default and
the maximum of 1.416Ghz, which boards can set if they
were able to get pmic support for it.

After the clock tree is set during the TPL probe
there's no parent update support.

In OF_REAL mode the drivers ns16550.c and dw-apb-timer.c
obtain the (fixed) clk_get_rate from the clock driver
instead of platdata.

The rk3066 cru node has a number of assigned-clocks properties
that call the .set_rate() function. Add them to the list so that
they return a 0 instead of -ENOENT.

Signed-off-by: Paweł Jarosz <paweljarosz3691@gmail.com>
Signed-off-by: Johan Jonker <jbx6244@gmail.com>
Reviewed-by: Sean Anderson <seanga2@gmail.com>
---

Changed V9:
  fix TAB
  fix space

Changed V8:
  add SCLK_TIMER[0..2]
  add SCLK_UART[0..3]
  fix assigned-clocks
  use GENMASK, __bf_shf and REG defines
  fix clk defines
  add includes
  fix bit position CRU_CLKSEL0_CON rk3066 vs rk3188
  fix comments
  rename PLL_MODE defines
  use dev_bind
  use dev_dbg
  use a different variable name

Changed V7:
  changed function prefix
  changed #if where possible
  restyle U_BOOT_DRIVER structure
---
 .../include/asm/arch-rockchip/cru_rk3066.h    | 157 ++++
 drivers/clk/rockchip/Makefile                 |   1 +
 drivers/clk/rockchip/clk_rk3066.c             | 717 ++++++++++++++++++
 3 files changed, 875 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rk3066.h
 create mode 100644 drivers/clk/rockchip/clk_rk3066.c

diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3066.h b/arch/arm/include/asm/arch-rockchip/cru_rk3066.h
new file mode 100644
index 0000000000..76a715a8e6
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3066.h
@@ -0,0 +1,157 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2021 Paweł Jarosz <paweljarosz3691@gmail.com>
+ */
+
+#ifndef _ASM_ARCH_CRU_RK3066_H
+#define _ASM_ARCH_CRU_RK3066_H
+
+#include <linux/bitops.h>
+#include <linux/bitfield.h>
+
+#define REG(name, h, l) \
+	name##_MASK = GENMASK(h, l), \
+	name##_SHIFT = __bf_shf(name##_MASK)
+
+#define OSC_HZ		(24 * 1000 * 1000)
+
+#define APLL_HZ		(1416 * 1000000)
+#define APLL_SAFE_HZ	(600 * 1000000)
+#define GPLL_HZ		(594 * 1000000)
+#define CPLL_HZ		(384 * 1000000)
+
+/* The SRAM is clocked off aclk_cpu, so we want to max it out for boot speed */
+#define CPU_ACLK_HZ	297000000
+#define CPU_HCLK_HZ	148500000
+#define CPU_PCLK_HZ	74250000
+#define CPU_H2P_HZ	74250000
+
+#define PERI_ACLK_HZ	148500000
+#define PERI_HCLK_HZ	148500000
+#define PERI_PCLK_HZ	74250000
+
+/* Private data for the clock driver - used by rockchip_get_cru() */
+struct rk3066_clk_priv {
+	struct rk3066_grf *grf;
+	struct rk3066_cru *cru;
+	ulong rate;
+	bool has_bwadj;
+};
+
+struct rk3066_cru {
+	struct rk3066_pll {
+		u32 con0;
+		u32 con1;
+		u32 con2;
+		u32 con3;
+	} pll[4];
+	u32 cru_mode_con;
+	u32 cru_clksel_con[35];
+	u32 cru_clkgate_con[10];
+	u32 reserved1[2];
+	u32 cru_glb_srst_fst_value;
+	u32 cru_glb_srst_snd_value;
+	u32 reserved2[2];
+	u32 cru_softrst_con[9];
+	u32 cru_misc_con;
+	u32 reserved3[2];
+	u32 cru_glb_cnt_th;
+};
+
+check_member(rk3066_cru, cru_glb_cnt_th, 0x0140);
+
+/* CRU_CLKSEL0_CON */
+enum {
+	REG(CPU_ACLK_PLL, 8, 8),
+	CPU_ACLK_PLL_SELECT_APLL	= 0,
+	CPU_ACLK_PLL_SELECT_GPLL,
+
+	REG(CORE_PERI_DIV, 7, 6),
+
+	REG(A9_CORE_DIV, 4, 0),
+};
+
+/* CRU_CLKSEL1_CON */
+enum {
+	REG(AHB2APB_DIV, 15, 14),
+
+	REG(CPU_PCLK_DIV, 13, 12),
+
+	REG(CPU_HCLK_DIV, 9, 8),
+
+	REG(CPU_ACLK_DIV, 2, 0),
+};
+
+/* CRU_CLKSEL10_CON */
+enum {
+	REG(PERI_SEL_PLL, 15, 15),
+	PERI_SEL_CPLL		= 0,
+	PERI_SEL_GPLL,
+
+	REG(PERI_PCLK_DIV, 13, 12),
+
+	REG(PERI_HCLK_DIV, 9, 8),
+
+	REG(PERI_ACLK_DIV, 4, 0),
+};
+
+/* CRU_CLKSEL11_CON */
+enum {
+	REG(MMC0_DIV, 5, 0),
+};
+
+/* CRU_CLKSEL12_CON */
+enum {
+	REG(UART_PLL, 15, 15),
+	UART_PLL_SELECT_GENERAL	= 0,
+	UART_PLL_SELECT_CODEC,
+
+	REG(EMMC_DIV, 13, 8),
+
+	REG(SDIO_DIV, 5, 0),
+};
+
+/* CRU_CLKSEL24_CON */
+enum {
+	REG(SARADC_DIV, 15, 8),
+};
+
+/* CRU_CLKSEL25_CON */
+enum {
+	REG(SPI1_DIV, 14, 8),
+
+	REG(SPI0_DIV, 6, 0),
+};
+
+/* CRU_CLKSEL34_CON */
+enum {
+	REG(TSADC_DIV, 15, 0),
+};
+
+/* CRU_MODE_CON */
+enum {
+	REG(GPLL_MODE, 13, 12),
+
+	REG(CPLL_MODE, 9, 8),
+
+	REG(DPLL_MODE, 5, 4),
+
+	REG(APLL_MODE, 1, 0),
+	PLL_MODE_SLOW		= 0,
+	PLL_MODE_NORMAL,
+	PLL_MODE_DEEP,
+};
+
+/* CRU_APLL_CON0 */
+enum {
+	REG(CLKR, 13, 8),
+
+	REG(CLKOD, 3, 0),
+};
+
+/* CRU_APLL_CON1 */
+enum {
+	REG(CLKF, 12, 0),
+};
+
+#endif
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 913f611a0f..a72d8fe58a 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -6,6 +6,7 @@
 obj-y += clk_pll.o
 obj-$(CONFIG_ROCKCHIP_PX30) += clk_px30.o
 obj-$(CONFIG_ROCKCHIP_RK3036) += clk_rk3036.o
+obj-$(CONFIG_ROCKCHIP_RK3066) += clk_rk3066.o
 obj-$(CONFIG_ROCKCHIP_RK3128) += clk_rk3128.o
 obj-$(CONFIG_ROCKCHIP_RK3188) += clk_rk3188.o
 obj-$(CONFIG_ROCKCHIP_RK322X) += clk_rk322x.o
diff --git a/drivers/clk/rockchip/clk_rk3066.c b/drivers/clk/rockchip/clk_rk3066.c
new file mode 100644
index 0000000000..2c12f6e044
--- /dev/null
+++ b/drivers/clk/rockchip/clk_rk3066.c
@@ -0,0 +1,717 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2015 Google, Inc
+ * (C) Copyright 2016 Heiko Stuebner <heiko@sntech.de>
+ */
+
+#include <bitfield.h>
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dt-structs.h>
+#include <errno.h>
+#include <log.h>
+#include <malloc.h>
+#include <mapmem.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3066.h>
+#include <asm/arch-rockchip/grf_rk3066.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <dt-bindings/clock/rk3066a-cru.h>
+#include <dm/device_compat.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/uclass-internal.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/log2.h>
+#include <linux/stringify.h>
+
+struct rk3066_clk_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	struct dtd_rockchip_rk3066a_cru dtd;
+#endif
+};
+
+struct pll_div {
+	u32 nr;
+	u32 nf;
+	u32 no;
+};
+
+enum {
+	VCO_MAX_HZ	= 1416U * 1000000,
+	VCO_MIN_HZ	= 300 * 1000000,
+	OUTPUT_MAX_HZ	= 1416U * 1000000,
+	OUTPUT_MIN_HZ	= 30 * 1000000,
+	FREF_MAX_HZ	= 1416U * 1000000,
+	FREF_MIN_HZ	= 30 * 1000,
+};
+
+enum {
+	/* PLL CON0 */
+	PLL_OD_MASK		= GENMASK(3, 0),
+
+	/* PLL CON1 */
+	PLL_NF_MASK		= GENMASK(12, 0),
+
+	/* PLL CON2 */
+	PLL_BWADJ_MASK		= GENMASK(11, 0),
+
+	/* PLL CON3 */
+	PLL_RESET_SHIFT		= 5,
+
+	/* GRF_SOC_STATUS0 */
+	SOCSTS_DPLL_LOCK	= BIT(4),
+	SOCSTS_APLL_LOCK	= BIT(5),
+	SOCSTS_CPLL_LOCK	= BIT(6),
+	SOCSTS_GPLL_LOCK	= BIT(7),
+};
+
+#define DIV_TO_RATE(input_rate, div)	((input_rate) / ((div) + 1))
+
+#define PLL_DIVISORS(hz, _nr, _no) {\
+	.nr = _nr, .nf = (u32)((u64)hz * _nr * _no / OSC_HZ), .no = _no};\
+	_Static_assert(((u64)hz * _nr * _no / OSC_HZ) * OSC_HZ /\
+		       (_nr * _no) == hz, #hz "Hz cannot be hit with PLL "\
+		       "divisors on line " __stringify(__LINE__))
+
+/* Keep divisors as low as possible to reduce jitter and power usage. */
+static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2);
+static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2);
+
+static int rk3066_clk_set_pll(struct rk3066_cru *cru, enum rk_clk_id clk_id,
+			      const struct pll_div *div)
+{
+	int pll_id = rk_pll_id(clk_id);
+	struct rk3066_pll *pll = &cru->pll[pll_id];
+	/* All PLLs have the same VCO and output frequency range restrictions. */
+	uint vco_hz = OSC_HZ / 1000 * div->nf / div->nr * 1000;
+	uint output_hz = vco_hz / div->no;
+
+	debug("%s: PLL at %x: nf=%d, nr=%d, no=%d, vco=%u Hz, output=%u Hz\n", __func__,
+	      (uint)pll, div->nf, div->nr, div->no, vco_hz, output_hz);
+	assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
+	       output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ &&
+	       (div->no == 1 || !(div->no % 2)));
+
+	/* Enter reset. */
+	rk_setreg(&pll->con3, BIT(PLL_RESET_SHIFT));
+
+	rk_clrsetreg(&pll->con0,
+		     CLKR_MASK | PLL_OD_MASK,
+		     ((div->nr - 1) << CLKR_SHIFT) | (div->no - 1));
+	rk_clrsetreg(&pll->con1, CLKF_MASK, div->nf - 1);
+
+	rk_clrsetreg(&pll->con2, PLL_BWADJ_MASK, (div->nf >> 1) - 1);
+
+	/* Exit reset. */
+	rk_clrreg(&pll->con3, BIT(PLL_RESET_SHIFT));
+
+	return 0;
+}
+
+static int rk3066_clk_configure_ddr(struct rk3066_cru *cru, struct rk3066_grf *grf,
+				    unsigned int hz)
+{
+	static const struct pll_div dpll_cfg[] = {
+		{.nf = 25, .nr = 2, .no = 1},
+		{.nf = 400, .nr = 9, .no = 2},
+		{.nf = 500, .nr = 9, .no = 2},
+		{.nf = 100, .nr = 3, .no = 1},
+	};
+	int cfg;
+
+	switch (hz) {
+	case 300000000:
+		cfg = 0;
+		break;
+	case 533000000:	/* actually 533.3P MHz */
+		cfg = 1;
+		break;
+	case 666000000:	/* actually 666.6P MHz */
+		cfg = 2;
+		break;
+	case 800000000:
+		cfg = 3;
+		break;
+	default:
+		debug("%s: unsupported SDRAM frequency", __func__);
+		return -EINVAL;
+	}
+
+	/* Enter PLL slow mode. */
+	rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK,
+		     PLL_MODE_SLOW << DPLL_MODE_SHIFT);
+
+	rk3066_clk_set_pll(cru, CLK_DDR, &dpll_cfg[cfg]);
+
+	/* Wait for PLL lock. */
+	while (!(readl(&grf->soc_status0) & SOCSTS_DPLL_LOCK))
+		udelay(1);
+
+	/* Enter PLL normal mode. */
+	rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK,
+		     PLL_MODE_NORMAL << DPLL_MODE_SHIFT);
+
+	return 0;
+}
+
+static int rk3066_clk_configure_cpu(struct rk3066_cru *cru, struct rk3066_grf *grf,
+				    unsigned int hz)
+{
+	static const struct pll_div apll_cfg[] = {
+		{.nf = 50, .nr = 1, .no = 2},
+		{.nf = 59, .nr = 1, .no = 1},
+	};
+	int div_core_peri, div_cpu_aclk, cfg;
+
+	/*
+	 * We support two possible frequencies, the safe 600MHz
+	 * which will work with default pmic settings and will
+	 * be set to get away from the 24MHz default and
+	 * the maximum of 1.416Ghz, which boards can set if they
+	 * were able to get pmic support for it.
+	 */
+	switch (hz) {
+	case APLL_SAFE_HZ:
+		cfg = 0;
+		div_core_peri = 1;
+		div_cpu_aclk = 3;
+		break;
+	case APLL_HZ:
+		cfg = 1;
+		div_core_peri = 2;
+		div_cpu_aclk = 3;
+		break;
+	default:
+		debug("unsupported ARMCLK frequency");
+		return -EINVAL;
+	}
+
+	/* Enter PLL slow mode. */
+	rk_clrsetreg(&cru->cru_mode_con, APLL_MODE_MASK,
+		     PLL_MODE_SLOW << APLL_MODE_SHIFT);
+
+	rk3066_clk_set_pll(cru, CLK_ARM, &apll_cfg[cfg]);
+
+	/* Wait for PLL lock. */
+	while (!(readl(&grf->soc_status0) & SOCSTS_APLL_LOCK))
+		udelay(1);
+
+	/* Set divider for peripherals attached to the CPU core. */
+	rk_clrsetreg(&cru->cru_clksel_con[0],
+		     CORE_PERI_DIV_MASK,
+		     div_core_peri << CORE_PERI_DIV_SHIFT);
+
+	/* Set up dependent divisor for cpu_aclk. */
+	rk_clrsetreg(&cru->cru_clksel_con[1],
+		     CPU_ACLK_DIV_MASK,
+		     div_cpu_aclk << CPU_ACLK_DIV_SHIFT);
+
+	/* Enter PLL normal mode. */
+	rk_clrsetreg(&cru->cru_mode_con, APLL_MODE_MASK,
+		     PLL_MODE_NORMAL << APLL_MODE_SHIFT);
+
+	return hz;
+}
+
+static uint32_t rk3066_clk_pll_get_rate(struct rk3066_cru *cru,
+					enum rk_clk_id clk_id)
+{
+	u32 nr, no, nf;
+	u32 con;
+	int pll_id = rk_pll_id(clk_id);
+	struct rk3066_pll *pll = &cru->pll[pll_id];
+	static u8 clk_shift[CLK_COUNT] = {
+		0xff, APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT,
+		GPLL_MODE_SHIFT
+	};
+	uint shift;
+
+	con = readl(&cru->cru_mode_con);
+	shift = clk_shift[clk_id];
+	switch (FIELD_GET(APLL_MODE_MASK, con >> shift)) {
+	case PLL_MODE_SLOW:
+		return OSC_HZ;
+	case PLL_MODE_NORMAL:
+		/* normal mode */
+		con = readl(&pll->con0);
+		no = bitfield_extract_by_mask(con, CLKOD_MASK) + 1;
+		nr = bitfield_extract_by_mask(con, CLKR_MASK) + 1;
+		con = readl(&pll->con1);
+		nf = bitfield_extract_by_mask(con, CLKF_MASK) + 1;
+
+		return (OSC_HZ * nf) / (nr * no);
+	case PLL_MODE_DEEP:
+	default:
+		return 32768;
+	}
+}
+
+static ulong rk3066_clk_mmc_get_clk(struct rk3066_cru *cru, uint gclk_rate,
+				    int periph)
+{
+	uint div;
+	u32 con;
+
+	switch (periph) {
+	case HCLK_EMMC:
+	case SCLK_EMMC:
+		con = readl(&cru->cru_clksel_con[12]);
+		div = bitfield_extract_by_mask(con, EMMC_DIV_MASK);
+		break;
+	case HCLK_SDMMC:
+	case SCLK_SDMMC:
+		con = readl(&cru->cru_clksel_con[11]);
+		div = bitfield_extract_by_mask(con, MMC0_DIV_MASK);
+		break;
+	case HCLK_SDIO:
+	case SCLK_SDIO:
+		con = readl(&cru->cru_clksel_con[12]);
+		div = bitfield_extract_by_mask(con, SDIO_DIV_MASK);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return DIV_TO_RATE(gclk_rate, div) / 2;
+}
+
+static ulong rk3066_clk_mmc_set_clk(struct rk3066_cru *cru, uint gclk_rate,
+				    int  periph, uint freq)
+{
+	int src_clk_div;
+
+	debug("%s: gclk_rate=%u\n", __func__, gclk_rate);
+	/* MMC clock by default divides by 2 internally, so need to provide double in CRU. */
+	src_clk_div = DIV_ROUND_UP(gclk_rate / 2, freq) - 1;
+	assert(src_clk_div <= 0x3f);
+
+	switch (periph) {
+	case HCLK_EMMC:
+	case SCLK_EMMC:
+		rk_clrsetreg(&cru->cru_clksel_con[12],
+			     EMMC_DIV_MASK,
+			     src_clk_div << EMMC_DIV_SHIFT);
+		break;
+	case HCLK_SDMMC:
+	case SCLK_SDMMC:
+		rk_clrsetreg(&cru->cru_clksel_con[11],
+			     MMC0_DIV_MASK,
+			     src_clk_div << MMC0_DIV_SHIFT);
+		break;
+	case HCLK_SDIO:
+	case SCLK_SDIO:
+		rk_clrsetreg(&cru->cru_clksel_con[12],
+			     SDIO_DIV_MASK,
+			     src_clk_div << SDIO_DIV_SHIFT);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return rk3066_clk_mmc_get_clk(cru, gclk_rate, periph);
+}
+
+static ulong rk3066_clk_spi_get_clk(struct rk3066_cru *cru, uint gclk_rate,
+				    int periph)
+{
+	uint div;
+	u32 con;
+
+	switch (periph) {
+	case SCLK_SPI0:
+		con = readl(&cru->cru_clksel_con[25]);
+		div = bitfield_extract_by_mask(con, SPI0_DIV_MASK);
+		break;
+	case SCLK_SPI1:
+		con = readl(&cru->cru_clksel_con[25]);
+		div = bitfield_extract_by_mask(con, SPI1_DIV_MASK);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return DIV_TO_RATE(gclk_rate, div);
+}
+
+static ulong rk3066_clk_spi_set_clk(struct rk3066_cru *cru, uint gclk_rate,
+				    int periph, uint freq)
+{
+	int src_clk_div = DIV_ROUND_UP(gclk_rate, freq) - 1;
+
+	assert(src_clk_div < 128);
+	switch (periph) {
+	case SCLK_SPI0:
+		assert(src_clk_div <= SPI0_DIV_MASK >> SPI0_DIV_SHIFT);
+		rk_clrsetreg(&cru->cru_clksel_con[25],
+			     SPI0_DIV_MASK,
+			     src_clk_div << SPI0_DIV_SHIFT);
+		break;
+	case SCLK_SPI1:
+		assert(src_clk_div <= SPI1_DIV_MASK >> SPI1_DIV_SHIFT);
+		rk_clrsetreg(&cru->cru_clksel_con[25],
+			     SPI1_DIV_MASK,
+			     src_clk_div << SPI1_DIV_SHIFT);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return rk3066_clk_spi_get_clk(cru, gclk_rate, periph);
+}
+
+static ulong rk3066_clk_saradc_get_clk(struct rk3066_cru *cru, int periph)
+{
+	u32 div, con;
+
+	switch (periph) {
+	case SCLK_SARADC:
+		con = readl(&cru->cru_clksel_con[24]);
+		div = bitfield_extract_by_mask(con, SARADC_DIV_MASK);
+		break;
+	case SCLK_TSADC:
+		con = readl(&cru->cru_clksel_con[34]);
+		div = bitfield_extract_by_mask(con, TSADC_DIV_MASK);
+		break;
+	default:
+		return -EINVAL;
+	}
+	return DIV_TO_RATE(PERI_PCLK_HZ, div);
+}
+
+static ulong rk3066_clk_saradc_set_clk(struct rk3066_cru *cru, uint hz,
+				       int periph)
+{
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(PERI_PCLK_HZ, hz) - 1;
+	assert(src_clk_div < 128);
+
+	switch (periph) {
+	case SCLK_SARADC:
+		rk_clrsetreg(&cru->cru_clksel_con[24],
+			     SARADC_DIV_MASK,
+			     src_clk_div << SARADC_DIV_SHIFT);
+		break;
+	case SCLK_TSADC:
+		rk_clrsetreg(&cru->cru_clksel_con[34],
+			     SARADC_DIV_MASK,
+			     src_clk_div << SARADC_DIV_SHIFT);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return rk3066_clk_saradc_get_clk(cru, periph);
+}
+
+static void rk3066_clk_init(struct rk3066_cru *cru, struct rk3066_grf *grf)
+{
+	u32 aclk_div, hclk_div, pclk_div, h2p_div;
+
+	/* Enter PLL slow mode. */
+	rk_clrsetreg(&cru->cru_mode_con,
+		     GPLL_MODE_MASK |
+		     CPLL_MODE_MASK,
+		     PLL_MODE_SLOW << GPLL_MODE_SHIFT |
+		     PLL_MODE_SLOW << CPLL_MODE_SHIFT);
+
+	/* Init PLL. */
+	rk3066_clk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
+	rk3066_clk_set_pll(cru, CLK_CODEC, &cpll_init_cfg);
+
+	/* Wait for PLL lock. */
+	while ((readl(&grf->soc_status0) &
+		(SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK)) !=
+	       (SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK))
+		udelay(1);
+
+	/*
+	 * Select CPU clock PLL source and
+	 * reparent aclk_cpu_pre from APPL to GPLL.
+	 * Set up dependent divisors for PCLK/HCLK and ACLK clocks.
+	 */
+	aclk_div = DIV_ROUND_UP(GPLL_HZ, CPU_ACLK_HZ) - 1;
+	assert((aclk_div + 1) * CPU_ACLK_HZ == GPLL_HZ && aclk_div <= 0x1f);
+
+	rk_clrsetreg(&cru->cru_clksel_con[0],
+		     CPU_ACLK_PLL_MASK |
+		     A9_CORE_DIV_MASK,
+		     CPU_ACLK_PLL_SELECT_GPLL << CPU_ACLK_PLL_SHIFT |
+		     aclk_div << A9_CORE_DIV_SHIFT);
+
+	hclk_div = ilog2(CPU_ACLK_HZ / CPU_HCLK_HZ);
+	assert((1 << hclk_div) * CPU_HCLK_HZ == CPU_ACLK_HZ && hclk_div < 0x3);
+	pclk_div = ilog2(CPU_ACLK_HZ / CPU_PCLK_HZ);
+	assert((1 << pclk_div) * CPU_PCLK_HZ == CPU_ACLK_HZ && pclk_div < 0x4);
+	h2p_div = ilog2(CPU_HCLK_HZ / CPU_H2P_HZ);
+	assert((1 << h2p_div) * CPU_H2P_HZ == CPU_HCLK_HZ && pclk_div < 0x3);
+
+	rk_clrsetreg(&cru->cru_clksel_con[1],
+		     AHB2APB_DIV_MASK |
+		     CPU_PCLK_DIV_MASK |
+		     CPU_HCLK_DIV_MASK,
+		     h2p_div << AHB2APB_DIV_SHIFT |
+		     pclk_div << CPU_PCLK_DIV_SHIFT |
+		     hclk_div << CPU_HCLK_DIV_SHIFT);
+
+	/*
+	 * Select PERI clock PLL source and
+	 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+	 */
+	aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1;
+	assert((aclk_div + 1) * PERI_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
+
+	hclk_div = ilog2(PERI_ACLK_HZ / PERI_HCLK_HZ);
+	assert((1 << hclk_div) * PERI_HCLK_HZ ==
+	       PERI_ACLK_HZ && (hclk_div < 0x4));
+
+	pclk_div = ilog2(PERI_ACLK_HZ / PERI_PCLK_HZ);
+	assert((1 << pclk_div) * PERI_PCLK_HZ ==
+	       PERI_ACLK_HZ && (pclk_div < 0x4));
+
+	rk_clrsetreg(&cru->cru_clksel_con[10],
+		     PERI_PCLK_DIV_MASK |
+		     PERI_HCLK_DIV_MASK |
+		     PERI_ACLK_DIV_MASK,
+		     PERI_SEL_GPLL << PERI_SEL_PLL_SHIFT |
+		     pclk_div << PERI_PCLK_DIV_SHIFT |
+		     hclk_div << PERI_HCLK_DIV_SHIFT |
+		     aclk_div << PERI_ACLK_DIV_SHIFT);
+
+	/* Enter PLL normal mode. */
+	rk_clrsetreg(&cru->cru_mode_con,
+		     GPLL_MODE_MASK |
+		     CPLL_MODE_MASK,
+		     PLL_MODE_NORMAL << GPLL_MODE_SHIFT |
+		     PLL_MODE_NORMAL << CPLL_MODE_SHIFT);
+
+	rk3066_clk_mmc_set_clk(cru, PERI_HCLK_HZ, HCLK_SDMMC, 16000000);
+}
+
+static ulong rk3066_clk_get_rate(struct clk *clk)
+{
+	struct rk3066_clk_priv *priv = dev_get_priv(clk->dev);
+	ulong new_rate, gclk_rate;
+
+	gclk_rate = rk3066_clk_pll_get_rate(priv->cru, CLK_GENERAL);
+	switch (clk->id) {
+	case 1 ... 4:
+		new_rate = rk3066_clk_pll_get_rate(priv->cru, clk->id);
+		break;
+	case HCLK_EMMC:
+	case HCLK_SDMMC:
+	case HCLK_SDIO:
+	case SCLK_EMMC:
+	case SCLK_SDMMC:
+	case SCLK_SDIO:
+		new_rate = rk3066_clk_mmc_get_clk(priv->cru, PERI_HCLK_HZ,
+						  clk->id);
+		break;
+	case SCLK_SPI0:
+	case SCLK_SPI1:
+		new_rate = rk3066_clk_spi_get_clk(priv->cru, PERI_PCLK_HZ,
+						  clk->id);
+		break;
+	case PCLK_I2C0:
+	case PCLK_I2C1:
+	case PCLK_I2C2:
+	case PCLK_I2C3:
+	case PCLK_I2C4:
+		return gclk_rate;
+	case SCLK_SARADC:
+	case SCLK_TSADC:
+		new_rate = rk3066_clk_saradc_get_clk(priv->cru, clk->id);
+		break;
+	case SCLK_TIMER0:
+	case SCLK_TIMER1:
+	case SCLK_TIMER2:
+	case SCLK_UART0:
+	case SCLK_UART1:
+	case SCLK_UART2:
+	case SCLK_UART3:
+		return OSC_HZ;
+	default:
+		return -ENOENT;
+	}
+
+	return new_rate;
+}
+
+static ulong rk3066_clk_set_rate(struct clk *clk, ulong rate)
+{
+	struct rk3066_clk_priv *priv = dev_get_priv(clk->dev);
+	struct rk3066_cru *cru = priv->cru;
+	ulong new_rate;
+
+	switch (clk->id) {
+	case PLL_APLL:
+		new_rate = rk3066_clk_configure_cpu(priv->cru, priv->grf, rate);
+		break;
+	case CLK_DDR:
+		new_rate = rk3066_clk_configure_ddr(priv->cru, priv->grf, rate);
+		break;
+	case HCLK_EMMC:
+	case HCLK_SDMMC:
+	case HCLK_SDIO:
+	case SCLK_EMMC:
+	case SCLK_SDMMC:
+	case SCLK_SDIO:
+		new_rate = rk3066_clk_mmc_set_clk(cru, PERI_HCLK_HZ,
+						  clk->id, rate);
+		break;
+	case SCLK_SPI0:
+	case SCLK_SPI1:
+		new_rate = rk3066_clk_spi_set_clk(cru, PERI_PCLK_HZ,
+						  clk->id, rate);
+		break;
+	case SCLK_SARADC:
+	case SCLK_TSADC:
+		new_rate = rk3066_clk_saradc_set_clk(cru, rate, clk->id);
+		break;
+	case PLL_CPLL:
+	case PLL_GPLL:
+	case ACLK_CPU:
+	case HCLK_CPU:
+	case PCLK_CPU:
+	case ACLK_PERI:
+	case HCLK_PERI:
+	case PCLK_PERI:
+		return 0;
+	default:
+		return -ENOENT;
+	}
+
+	return new_rate;
+}
+
+static int rk3066_clk_enable(struct clk *clk)
+{
+	struct rk3066_clk_priv *priv = dev_get_priv(clk->dev);
+
+	switch (clk->id) {
+	case HCLK_NANDC0:
+		rk_clrreg(&priv->cru->cru_clkgate_con[5], BIT(9));
+		break;
+	case HCLK_SDMMC:
+		rk_clrreg(&priv->cru->cru_clkgate_con[5], BIT(10));
+		break;
+	case HCLK_SDIO:
+		rk_clrreg(&priv->cru->cru_clkgate_con[5], BIT(11));
+		break;
+	}
+
+	return 0;
+}
+
+static int rk3066_clk_disable(struct clk *clk)
+{
+	struct rk3066_clk_priv *priv = dev_get_priv(clk->dev);
+
+	switch (clk->id) {
+	case HCLK_NANDC0:
+		rk_setreg(&priv->cru->cru_clkgate_con[5], BIT(9));
+		break;
+	case HCLK_SDMMC:
+		rk_setreg(&priv->cru->cru_clkgate_con[5], BIT(10));
+		break;
+	case HCLK_SDIO:
+		rk_setreg(&priv->cru->cru_clkgate_con[5], BIT(11));
+		break;
+	}
+
+	return 0;
+}
+
+static struct clk_ops rk3066_clk_ops = {
+	.disable	= rk3066_clk_disable,
+	.enable	= rk3066_clk_enable,
+	.get_rate	= rk3066_clk_get_rate,
+	.set_rate	= rk3066_clk_set_rate,
+};
+
+static int rk3066_clk_of_to_plat(struct udevice *dev)
+{
+	if (CONFIG_IS_ENABLED(OF_REAL)) {
+		struct rk3066_clk_priv *priv = dev_get_priv(dev);
+
+		priv->cru = dev_read_addr_ptr(dev);
+	}
+
+	return 0;
+}
+
+static int rk3066_clk_probe(struct udevice *dev)
+{
+	struct rk3066_clk_priv *priv = dev_get_priv(dev);
+
+	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+	if (IS_ERR(priv->grf))
+		return PTR_ERR(priv->grf);
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	struct rk3066_clk_plat *plat = dev_get_plat(dev);
+
+	priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]);
+#endif
+
+	if (IS_ENABLED(CONFIG_TPL_BUILD)) {
+		rk3066_clk_init(priv->cru, priv->grf);
+
+		/* Init CPU frequency. */
+		rk3066_clk_configure_cpu(priv->cru, priv->grf, APLL_SAFE_HZ);
+	}
+
+	return 0;
+}
+
+static int rk3066_clk_bind(struct udevice *dev)
+{
+	struct udevice *sys_child;
+	struct sysreset_reg *priv;
+	int reg_offset, ret;
+
+	/* The reset driver does not have a device node, so bind it here. */
+	ret = device_bind(dev, DM_DRIVER_GET(sysreset_rockchip), "sysreset",
+			  NULL, ofnode_null(), &sys_child);
+	if (ret) {
+		dev_dbg(dev, "Warning: No sysreset driver: ret=%d\n", ret);
+	} else {
+		priv = malloc(sizeof(struct sysreset_reg));
+		priv->glb_srst_fst_value = offsetof(struct rk3066_cru,
+						    cru_glb_srst_fst_value);
+		priv->glb_srst_snd_value = offsetof(struct rk3066_cru,
+						    cru_glb_srst_snd_value);
+		dev_set_priv(sys_child, priv);
+	}
+
+	if (CONFIG_IS_ENABLED(RESET_ROCKCHIP)) {
+		reg_offset = offsetof(struct rk3066_cru, cru_softrst_con[0]);
+		ret = rockchip_reset_bind(dev, reg_offset, 9);
+		if (ret)
+			dev_dbg(dev, "Warning: software reset driver bind failed\n");
+	}
+
+	return 0;
+}
+
+static const struct udevice_id rk3066_clk_ids[] = {
+	{ .compatible = "rockchip,rk3066a-cru" },
+	{ }
+};
+
+U_BOOT_DRIVER(rockchip_rk3066a_cru) = {
+	.name		= "rockchip_rk3066a_cru",
+	.id		= UCLASS_CLK,
+	.ops		= &rk3066_clk_ops,
+	.probe		= rk3066_clk_probe,
+	.bind		= rk3066_clk_bind,
+	.of_match	= rk3066_clk_ids,
+	.of_to_plat	= rk3066_clk_of_to_plat,
+	.priv_auto	= sizeof(struct rk3066_clk_priv),
+	.plat_auto	= sizeof(struct rk3066_clk_plat),
+};
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v9 04/16] rockchip: rk3066: add rk3066 pinctrl driver
  2022-04-04 14:19 [PATCH v9 00/16] Add Rikomagic MK808 board Johan Jonker
                   ` (2 preceding siblings ...)
  2022-04-04 14:19 ` [PATCH v9 03/16] rockchip: rk3066: add clock driver for rk3066 soc Johan Jonker
@ 2022-04-04 14:19 ` Johan Jonker
  2022-04-09  3:49   ` Kever Yang
  2022-04-04 14:19 ` [PATCH v9 05/16] rockchip: rk3066: add sdram driver Johan Jonker
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 33+ messages in thread
From: Johan Jonker @ 2022-04-04 14:19 UTC (permalink / raw)
  To: kever.yang; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot

From: Paweł Jarosz <paweljarosz3691@gmail.com>

Add driver supporting pin multiplexing on rk3066 platform.

Signed-off-by: Paweł Jarosz <paweljarosz3691@gmail.com>
Signed-off-by: Johan Jonker <jbx6244@gmail.com>
---

Changed V9:
  change regmap source

Changed V7:
  restyle
  changed function prefix.
  restyle U_BOOT_DRIVER structure
  use OF_REAL
  use EOPNOTSUPP
---
 drivers/pinctrl/rockchip/Makefile         |   1 +
 drivers/pinctrl/rockchip/pinctrl-rk3066.c | 112 ++++++++++++++++++++++
 2 files changed, 113 insertions(+)
 create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3066.c

diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
index fcf19f877a..7d03f8101d 100644
--- a/drivers/pinctrl/rockchip/Makefile
+++ b/drivers/pinctrl/rockchip/Makefile
@@ -5,6 +5,7 @@
 obj-y += pinctrl-rockchip-core.o
 obj-$(CONFIG_ROCKCHIP_PX30) += pinctrl-px30.o
 obj-$(CONFIG_ROCKCHIP_RK3036) += pinctrl-rk3036.o
+obj-$(CONFIG_ROCKCHIP_RK3066) += pinctrl-rk3066.o
 obj-$(CONFIG_ROCKCHIP_RK3128) += pinctrl-rk3128.o
 obj-$(CONFIG_ROCKCHIP_RK3188) += pinctrl-rk3188.o
 obj-$(CONFIG_ROCKCHIP_RK322X) += pinctrl-rk322x.o
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3066.c b/drivers/pinctrl/rockchip/pinctrl-rk3066.c
new file mode 100644
index 0000000000..598b63223e
--- /dev/null
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3066.c
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2021 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <linux/bitops.h>
+
+#include "pinctrl-rockchip.h"
+
+static int rk3066_pinctrl_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
+{
+	struct rockchip_pinctrl_priv *priv = bank->priv;
+	int iomux_num = (pin / 8);
+	struct regmap *regmap;
+	int reg, ret, mask, mux_type;
+	u8 bit;
+	u32 data;
+
+	regmap = priv->regmap_base;
+
+	/* get basic quadrupel of mux registers and the correct reg inside */
+	mux_type = bank->iomux[iomux_num].type;
+	reg = bank->iomux[iomux_num].offset;
+	reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
+
+	data = (mask << (bit + 16));
+	data |= (mux & mask) << bit;
+	ret = regmap_write(regmap, reg, data);
+
+	return ret;
+}
+
+#define RK3066_PULL_OFFSET		0x118
+#define RK3066_PULL_PINS_PER_REG	16
+#define RK3066_PULL_BANK_STRIDE		8
+
+static void rk3066_pinctrl_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+						 int pin_num, struct regmap **regmap,
+						 int *reg, u8 *bit)
+{
+	struct rockchip_pinctrl_priv *priv = bank->priv;
+
+	*regmap = priv->regmap_base;
+	*reg = RK3066_PULL_OFFSET;
+	*reg += bank->bank_num * RK3066_PULL_BANK_STRIDE;
+	*reg += (pin_num / RK3066_PULL_PINS_PER_REG) * 4;
+
+	*bit = pin_num % RK3066_PULL_PINS_PER_REG;
+};
+
+static int rk3066_pinctrl_set_pull(struct rockchip_pin_bank *bank,
+				   int pin_num, int pull)
+{
+	struct regmap *regmap;
+	int reg, ret;
+	u8 bit;
+	u32 data;
+
+	if (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT &&
+	    pull != PIN_CONFIG_BIAS_DISABLE)
+		return -EOPNOTSUPP;
+
+	rk3066_pinctrl_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
+	data = BIT(bit + 16);
+	if (pull == PIN_CONFIG_BIAS_DISABLE)
+		data |= BIT(bit);
+	ret = regmap_write(regmap, reg, data);
+
+	return ret;
+}
+
+static struct rockchip_pin_bank rk3066_pin_banks[] = {
+	PIN_BANK(0, 32, "gpio0"),
+	PIN_BANK(1, 32, "gpio1"),
+	PIN_BANK(2, 32, "gpio2"),
+	PIN_BANK(3, 32, "gpio3"),
+	PIN_BANK(4, 32, "gpio4"),
+	PIN_BANK(6, 16, "gpio6"),
+};
+
+static struct rockchip_pin_ctrl rk3066_pin_ctrl = {
+	.pin_banks		= rk3066_pin_banks,
+	.nr_banks		= ARRAY_SIZE(rk3066_pin_banks),
+	.grf_mux_offset		= 0xa8,
+	.set_mux		= rk3066_pinctrl_set_mux,
+	.set_pull		= rk3066_pinctrl_set_pull,
+};
+
+static const struct udevice_id rk3066_pinctrl_ids[] = {
+	{
+		.compatible = "rockchip,rk3066a-pinctrl",
+		.data = (ulong)&rk3066_pin_ctrl
+	},
+	{}
+};
+
+U_BOOT_DRIVER(rockchip_rk3066a_pinctrl) = {
+	.name		= "rockchip_rk3066a_pinctrl",
+	.id		= UCLASS_PINCTRL,
+	.ops		= &rockchip_pinctrl_ops,
+	.probe		= rockchip_pinctrl_probe,
+#if CONFIG_IS_ENABLED(OF_REAL)
+	.bind		= dm_scan_fdt_dev,
+#endif
+	.of_match	= rk3066_pinctrl_ids,
+	.priv_auto	= sizeof(struct rockchip_pinctrl_priv),
+};
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v9 05/16] rockchip: rk3066: add sdram driver
  2022-04-04 14:19 [PATCH v9 00/16] Add Rikomagic MK808 board Johan Jonker
                   ` (3 preceding siblings ...)
  2022-04-04 14:19 ` [PATCH v9 04/16] rockchip: rk3066: add rk3066 pinctrl driver Johan Jonker
@ 2022-04-04 14:19 ` Johan Jonker
  2022-04-09  3:50   ` Kever Yang
  2022-04-04 14:19 ` [PATCH v9 06/16] arm: dts: rockchip: fix rk3xxx-u-boot.dtsi Johan Jonker
                   ` (10 subsequent siblings)
  15 siblings, 1 reply; 33+ messages in thread
From: Johan Jonker @ 2022-04-04 14:19 UTC (permalink / raw)
  To: kever.yang; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot

From: Paweł Jarosz <paweljarosz3691@gmail.com>

Add rockchip rk3066 sdram driver

Signed-off-by: Paweł Jarosz <paweljarosz3691@gmail.com>
Signed-off-by: Johan Jonker <jbx6244@gmail.com>
---

Changed V7:
  restyle
  rename TEST_PATTERN
  changed function prefix
  changed #if where possible
  restyle U_BOOT_DRIVER structure
  remove rk3066_dmc_of_to_plat because dmc DT data
  only used in TPL in combination with OF_PLATDATA
---
 drivers/ram/rockchip/Makefile       |   1 +
 drivers/ram/rockchip/sdram_rk3066.c | 892 ++++++++++++++++++++++++++++
 2 files changed, 893 insertions(+)
 create mode 100644 drivers/ram/rockchip/sdram_rk3066.c

diff --git a/drivers/ram/rockchip/Makefile b/drivers/ram/rockchip/Makefile
index ca1c289b88..6d530c29af 100644
--- a/drivers/ram/rockchip/Makefile
+++ b/drivers/ram/rockchip/Makefile
@@ -5,6 +5,7 @@
 
 obj-$(CONFIG_ROCKCHIP_PX30) += sdram_px30.o sdram_pctl_px30.o sdram_phy_px30.o
 obj-$(CONFIG_ROCKCHIP_RK3368) = dmc-rk3368.o
+obj-$(CONFIG_ROCKCHIP_RK3066) = sdram_rk3066.o
 obj-$(CONFIG_ROCKCHIP_RK3128) = sdram_rk3128.o
 obj-$(CONFIG_ROCKCHIP_RK3188) = sdram_rk3188.o
 obj-$(CONFIG_ROCKCHIP_RK322X) = sdram_rk322x.o
diff --git a/drivers/ram/rockchip/sdram_rk3066.c b/drivers/ram/rockchip/sdram_rk3066.c
new file mode 100644
index 0000000000..832154ee3a
--- /dev/null
+++ b/drivers/ram/rockchip/sdram_rk3066.c
@@ -0,0 +1,892 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * (C) Copyright 2015 Google, Inc
+ * Copyright 2014 Rockchip Inc.
+ *
+ * Adapted from the very similar rk3188 ddr init.
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dt-structs.h>
+#include <errno.h>
+#include <hang.h>
+#include <init.h>
+#include <log.h>
+#include <ram.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3066.h>
+#include <asm/arch-rockchip/ddr_rk3188.h>
+#include <asm/arch-rockchip/grf_rk3066.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/pmu_rk3188.h>
+#include <asm/arch-rockchip/sdram_rk3288.h>
+#include <asm/arch-rockchip/sdram.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+
+struct rk3066_dmc_chan_info {
+	struct rk3288_ddr_pctl *pctl;
+	struct rk3288_ddr_publ *publ;
+	struct rk3188_msch *msch;
+};
+
+struct rk3066_dmc_dram_info {
+	struct rk3066_dmc_chan_info chan[1];
+	struct ram_info info;
+	struct clk ddr_clk;
+	struct rk3066_cru *cru;
+	struct rk3066_grf *grf;
+	struct rk3066_sgrf *sgrf;
+	struct rk3188_pmu *pmu;
+};
+
+struct rk3066_dmc_sdram_params {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	struct dtd_rockchip_rk3066_dmc of_plat;
+#endif
+	struct rk3288_sdram_channel ch[2];
+	struct rk3288_sdram_pctl_timing pctl_timing;
+	struct rk3288_sdram_phy_timing phy_timing;
+	struct rk3288_base_params base;
+	int num_channels;
+	struct regmap *map;
+};
+
+const int rk3066_dmc_ddrconf_table[] = {
+	/*
+	 * [5:4] row(13+n)
+	 * [1:0] col(9+n), assume bw=2
+	 * row	    col,bw
+	 */
+	0,
+	(2 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT,
+	(1 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT,
+	(0 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT,
+	(2 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT,
+	(1 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT,
+	(0 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT,
+	(1 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT,
+	(0 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+};
+
+#define TEST_PATTERN			0x5aa5f00f
+#define DQS_GATE_TRAINING_ERROR_RANK0	BIT(4)
+#define DQS_GATE_TRAINING_ERROR_RANK1	BIT(5)
+
+static void rk3066_dmc_copy_to_reg(u32 *dest, const u32 *src, u32 n)
+{
+	int i;
+
+	for (i = 0; i < n / sizeof(u32); i++) {
+		writel(*src, dest);
+		src++;
+		dest++;
+	}
+}
+
+static void rk3066_dmc_ddr_reset(struct rk3066_cru *cru, u32 ch, u32 ctl, u32 phy)
+{
+	u32 phy_ctl_srstn_shift = 13;
+	u32 ctl_psrstn_shift = 11;
+	u32 ctl_srstn_shift = 10;
+	u32 phy_psrstn_shift = 9;
+	u32 phy_srstn_shift = 8;
+
+	rk_clrsetreg(&cru->cru_softrst_con[5],
+		     1 << phy_ctl_srstn_shift | 1 << ctl_psrstn_shift |
+		     1 << ctl_srstn_shift | 1 << phy_psrstn_shift |
+		     1 << phy_srstn_shift,
+		     phy << phy_ctl_srstn_shift | ctl << ctl_psrstn_shift |
+		     ctl << ctl_srstn_shift | phy << phy_psrstn_shift |
+		     phy << phy_srstn_shift);
+}
+
+static void rk3066_dmc_ddr_phy_ctl_reset(struct rk3066_cru *cru, u32 ch, u32 n)
+{
+	u32 phy_ctl_srstn_shift = 13;
+
+	rk_clrsetreg(&cru->cru_softrst_con[5],
+		     1 << phy_ctl_srstn_shift, n << phy_ctl_srstn_shift);
+}
+
+static void rk3066_dmc_phy_pctrl_reset(struct rk3066_cru *cru,
+				       struct rk3288_ddr_publ *publ,
+				       int channel)
+{
+	int i;
+
+	rk3066_dmc_ddr_reset(cru, channel, 1, 1);
+	udelay(1);
+	clrbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST);
+	for (i = 0; i < 4; i++)
+		clrbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST);
+
+	udelay(10);
+	setbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST);
+	for (i = 0; i < 4; i++)
+		setbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST);
+
+	udelay(10);
+	rk3066_dmc_ddr_reset(cru, channel, 1, 0);
+	udelay(10);
+	rk3066_dmc_ddr_reset(cru, channel, 0, 0);
+	udelay(10);
+}
+
+static void rk3066_dmc_phy_dll_bypass_set(struct rk3288_ddr_publ *publ, u32 freq)
+{
+	int i;
+
+	if (freq <= 250000000) {
+		if (freq <= 150000000)
+			clrbits_le32(&publ->dllgcr, SBIAS_BYPASS);
+		else
+			setbits_le32(&publ->dllgcr, SBIAS_BYPASS);
+		setbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS);
+		for (i = 0; i < 4; i++)
+			setbits_le32(&publ->datx8[i].dxdllcr,
+				     DXDLLCR_DLLDIS);
+
+		setbits_le32(&publ->pir, PIR_DLLBYP);
+	} else {
+		clrbits_le32(&publ->dllgcr, SBIAS_BYPASS);
+		clrbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS);
+		for (i = 0; i < 4; i++) {
+			clrbits_le32(&publ->datx8[i].dxdllcr,
+				     DXDLLCR_DLLDIS);
+		}
+
+		clrbits_le32(&publ->pir, PIR_DLLBYP);
+	}
+}
+
+static void rk3066_dmc_dfi_cfg(struct rk3288_ddr_pctl *pctl, u32 dramtype)
+{
+	writel(DFI_INIT_START, &pctl->dfistcfg0);
+	writel(DFI_DRAM_CLK_SR_EN | DFI_DRAM_CLK_DPD_EN,
+	       &pctl->dfistcfg1);
+	writel(DFI_PARITY_INTR_EN | DFI_PARITY_EN, &pctl->dfistcfg2);
+	writel(7 << TLP_RESP_TIME_SHIFT | LP_SR_EN | LP_PD_EN,
+	       &pctl->dfilpcfg0);
+
+	writel(2 << TCTRL_DELAY_TIME_SHIFT, &pctl->dfitctrldelay);
+	writel(1 << TPHY_WRDATA_TIME_SHIFT, &pctl->dfitphywrdata);
+	writel(0xf << TPHY_RDLAT_TIME_SHIFT, &pctl->dfitphyrdlat);
+	writel(2 << TDRAM_CLK_DIS_TIME_SHIFT, &pctl->dfitdramclkdis);
+	writel(2 << TDRAM_CLK_EN_TIME_SHIFT, &pctl->dfitdramclken);
+	writel(1, &pctl->dfitphyupdtype0);
+
+	/* CS0 and CS1 write ODT enable. */
+	writel((RANK0_ODT_WRITE_SEL | RANK1_ODT_WRITE_SEL),
+	       &pctl->dfiodtcfg);
+	/* Write ODT length. */
+	writel(7 << ODT_LEN_BL8_W_SHIFT, &pctl->dfiodtcfg1);
+	/* Disable phyupd and ctrlupd. */
+	writel(0, &pctl->dfiupdcfg);
+}
+
+static void rk3066_dmc_ddr_set_ddr3_mode(struct rk3066_grf *grf, uint channel,
+					 bool ddr3_mode)
+{
+	uint mask, val;
+
+	mask = MSCH4_MAINDDR3_MASK << MSCH4_MAINDDR3_SHIFT;
+	val = ddr3_mode << MSCH4_MAINDDR3_SHIFT;
+	rk_clrsetreg(&grf->soc_con2, mask, val);
+}
+
+static void rk3066_dmc_ddr_rank_2_row15en(struct rk3066_grf *grf, bool enable)
+{
+	uint mask, val;
+
+	mask = RANK_TO_ROW15_EN_MASK << RANK_TO_ROW15_EN_SHIFT;
+	val = enable << RANK_TO_ROW15_EN_SHIFT;
+	rk_clrsetreg(&grf->soc_con2, mask, val);
+}
+
+static void rk3066_dmc_pctl_cfg(int channel, struct rk3288_ddr_pctl *pctl,
+				struct rk3066_dmc_sdram_params *sdram_params,
+				struct rk3066_grf *grf)
+{
+	rk3066_dmc_copy_to_reg(&pctl->togcnt1u, &sdram_params->pctl_timing.togcnt1u,
+			       sizeof(sdram_params->pctl_timing));
+	switch (sdram_params->base.dramtype) {
+	case DDR3:
+		if (sdram_params->phy_timing.mr[1] & DDR3_DLL_DISABLE) {
+			writel(sdram_params->pctl_timing.tcl - 3,
+			       &pctl->dfitrddataen);
+		} else {
+			writel(sdram_params->pctl_timing.tcl - 2,
+			       &pctl->dfitrddataen);
+		}
+		writel(sdram_params->pctl_timing.tcwl - 1,
+		       &pctl->dfitphywrlat);
+		writel(0 << MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT | DDR3_EN |
+		       DDR2_DDR3_BL_8 | (6 - 4) << TFAW_SHIFT | PD_EXIT_SLOW |
+		       1 << PD_TYPE_SHIFT | 0 << PD_IDLE_SHIFT,
+		       &pctl->mcfg);
+		rk3066_dmc_ddr_set_ddr3_mode(grf, channel, true);
+		break;
+	}
+
+	setbits_le32(&pctl->scfg, 1);
+}
+
+static void rk3066_dmc_phy_cfg(const struct rk3066_dmc_chan_info *chan, int channel,
+			       struct rk3066_dmc_sdram_params *sdram_params)
+{
+	struct rk3288_ddr_publ *publ = chan->publ;
+	struct rk3188_msch *msch = chan->msch;
+	uint ddr_freq_mhz = sdram_params->base.ddr_freq / 1000000;
+	u32 dinit2;
+	int i;
+
+	dinit2 = DIV_ROUND_UP(ddr_freq_mhz * 200000, 1000);
+	/* Set DDR PHY timing. */
+	rk3066_dmc_copy_to_reg(&publ->dtpr[0], &sdram_params->phy_timing.dtpr0,
+			       sizeof(sdram_params->phy_timing));
+	writel(sdram_params->base.noc_timing, &msch->ddrtiming);
+	writel(0x3f, &msch->readlatency);
+	writel(DIV_ROUND_UP(ddr_freq_mhz * 5120, 1000) << PRT_DLLLOCK_SHIFT |
+	       DIV_ROUND_UP(ddr_freq_mhz * 50, 1000) << PRT_DLLSRST_SHIFT |
+	       8 << PRT_ITMSRST_SHIFT, &publ->ptr[0]);
+	writel(DIV_ROUND_UP(ddr_freq_mhz * 500000, 1000) << PRT_DINIT0_SHIFT |
+	       DIV_ROUND_UP(ddr_freq_mhz * 400, 1000) << PRT_DINIT1_SHIFT,
+	       &publ->ptr[1]);
+	writel(min(dinit2, 0x1ffffU) << PRT_DINIT2_SHIFT |
+	       DIV_ROUND_UP(ddr_freq_mhz * 1000, 1000) << PRT_DINIT3_SHIFT,
+	       &publ->ptr[2]);
+
+	switch (sdram_params->base.dramtype) {
+	case DDR3:
+		clrbits_le32(&publ->pgcr, 0x1f);
+		clrsetbits_le32(&publ->dcr, DDRMD_MASK << DDRMD_SHIFT,
+				DDRMD_DDR3 << DDRMD_SHIFT);
+		break;
+	}
+	if (sdram_params->base.odt) {
+		/* Enable dynamic RTT. */
+		for (i = 0; i < 4; i++)
+			setbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT);
+	} else {
+		/* Disable dynamic RTT. */
+		for (i = 0; i < 4; i++)
+			clrbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT);
+	}
+}
+
+static void rk3066_dmc_phy_init(struct rk3288_ddr_publ *publ)
+{
+	setbits_le32(&publ->pir, PIR_INIT | PIR_DLLSRST
+		     | PIR_DLLLOCK | PIR_ZCAL | PIR_ITMSRST | PIR_CLRSR);
+	udelay(1);
+	while ((readl(&publ->pgsr) &
+		(PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE)) !=
+	       (PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE))
+		;
+}
+
+static void rk3066_dmc_send_command(struct rk3288_ddr_pctl *pctl, u32 rank,
+				    u32 cmd, u32 arg)
+{
+	writel((START_CMD | (rank << 20) | arg | cmd), &pctl->mcmd);
+	udelay(1);
+	while (readl(&pctl->mcmd) & START_CMD)
+		;
+}
+
+static inline void rk3066_dmc_send_command_op(struct rk3288_ddr_pctl *pctl,
+					      u32 rank, u32 cmd, u32 ma, u32 op)
+{
+	rk3066_dmc_send_command(pctl, rank, cmd, (ma & LPDDR2_MA_MASK) << LPDDR2_MA_SHIFT |
+				(op & LPDDR2_OP_MASK) << LPDDR2_OP_SHIFT);
+}
+
+static void rk3066_dmc_memory_init(struct rk3288_ddr_publ *publ,
+				   u32 dramtype)
+{
+	setbits_le32(&publ->pir,
+		     (PIR_INIT | PIR_DRAMINIT | PIR_LOCKBYP
+		      | PIR_ZCALBYP | PIR_CLRSR | PIR_ICPC
+		      | (dramtype == DDR3 ? PIR_DRAMRST : 0)));
+	udelay(1);
+	while ((readl(&publ->pgsr) & (PGSR_IDONE | PGSR_DLDONE))
+	       != (PGSR_IDONE | PGSR_DLDONE))
+		;
+}
+
+static void rk3066_dmc_move_to_config_state(struct rk3288_ddr_publ *publ,
+					    struct rk3288_ddr_pctl *pctl)
+{
+	unsigned int state;
+
+	while (1) {
+		state = readl(&pctl->stat) & PCTL_STAT_MSK;
+
+		switch (state) {
+		case LOW_POWER:
+			writel(WAKEUP_STATE, &pctl->sctl);
+			while ((readl(&pctl->stat) & PCTL_STAT_MSK)
+			       != ACCESS)
+				;
+			/* Wait DLL lock. */
+			while ((readl(&publ->pgsr) & PGSR_DLDONE)
+			       != PGSR_DLDONE)
+				;
+			/*
+			 * If at low power state we need to wakeup first
+			 * and then enter the config.
+			 */
+			fallthrough;
+		case ACCESS:
+			fallthrough;
+		case INIT_MEM:
+			writel(CFG_STATE, &pctl->sctl);
+			while ((readl(&pctl->stat) & PCTL_STAT_MSK) != CONFIG)
+				;
+			break;
+		case CONFIG:
+			return;
+		default:
+			break;
+		}
+	}
+}
+
+static void rk3066_dmc_set_bandwidth_ratio(const struct rk3066_dmc_chan_info *chan, int channel,
+					   u32 n, struct rk3066_grf *grf)
+{
+	struct rk3288_ddr_pctl *pctl = chan->pctl;
+	struct rk3288_ddr_publ *publ = chan->publ;
+	struct rk3188_msch *msch = chan->msch;
+
+	if (n == 1) {
+		setbits_le32(&pctl->ppcfg, 1);
+		setbits_le32(&msch->ddrtiming, 1 << 31);
+		/* Data byte disable. */
+		clrbits_le32(&publ->datx8[2].dxgcr, 1);
+		clrbits_le32(&publ->datx8[3].dxgcr, 1);
+		/* Disable DLL. */
+		setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS);
+		setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS);
+	} else {
+		clrbits_le32(&pctl->ppcfg, 1);
+		clrbits_le32(&msch->ddrtiming, 1 << 31);
+		/* Data byte enable.*/
+		setbits_le32(&publ->datx8[2].dxgcr, 1);
+		setbits_le32(&publ->datx8[3].dxgcr, 1);
+
+		/* Enable DLL. */
+		clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS);
+		clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS);
+		/* Reset DLL. */
+		clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST);
+		clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST);
+		udelay(10);
+		setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST);
+		setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST);
+	}
+	setbits_le32(&pctl->dfistcfg0, 1 << 2);
+}
+
+static int rk3066_dmc_data_training(const struct rk3066_dmc_chan_info *chan, int channel,
+				    struct rk3066_dmc_sdram_params *sdram_params)
+{
+	unsigned int j;
+	int ret = 0;
+	u32 rank;
+	int i;
+	u32 step[2] = { PIR_QSTRN, PIR_RVTRN };
+	struct rk3288_ddr_publ *publ = chan->publ;
+	struct rk3288_ddr_pctl *pctl = chan->pctl;
+
+	/* Disable auto refresh. */
+	writel(0, &pctl->trefi);
+
+	if (sdram_params->base.dramtype != LPDDR3)
+		setbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT);
+	rank = sdram_params->ch[channel].rank | 1;
+	for (j = 0; j < ARRAY_SIZE(step); j++) {
+		/*
+		 * Trigger QSTRN and RVTRN.
+		 * Clear DTDONE status.
+		 */
+		setbits_le32(&publ->pir, PIR_CLRSR);
+
+		/* Trigger DTT. */
+		setbits_le32(&publ->pir,
+			     PIR_INIT | step[j] | PIR_LOCKBYP | PIR_ZCALBYP |
+			     PIR_CLRSR);
+		udelay(1);
+		/* Wait echo byte DTDONE. */
+		while ((readl(&publ->datx8[0].dxgsr[0]) & rank)
+		       != rank)
+			;
+		while ((readl(&publ->datx8[1].dxgsr[0]) & rank)
+		       != rank)
+			;
+		if (!(readl(&pctl->ppcfg) & 1)) {
+			while ((readl(&publ->datx8[2].dxgsr[0])
+				& rank) != rank)
+				;
+			while ((readl(&publ->datx8[3].dxgsr[0])
+				& rank) != rank)
+				;
+		}
+		if (readl(&publ->pgsr) &
+		    (PGSR_DTERR | PGSR_RVERR | PGSR_RVEIRR)) {
+			ret = -1;
+			break;
+		}
+	}
+	/* Send some auto refresh to complement the lost while DTT. */
+	for (i = 0; i < (rank > 1 ? 8 : 4); i++)
+		rk3066_dmc_send_command(pctl, rank, REF_CMD, 0);
+
+	if (sdram_params->base.dramtype != LPDDR3)
+		clrbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT);
+
+	/* Resume auto refresh. */
+	writel(sdram_params->pctl_timing.trefi, &pctl->trefi);
+
+	return ret;
+}
+
+static void rk3066_dmc_move_to_access_state(const struct rk3066_dmc_chan_info *chan)
+{
+	struct rk3288_ddr_publ *publ = chan->publ;
+	struct rk3288_ddr_pctl *pctl = chan->pctl;
+	unsigned int state;
+
+	while (1) {
+		state = readl(&pctl->stat) & PCTL_STAT_MSK;
+
+		switch (state) {
+		case LOW_POWER:
+			if (((readl(&pctl->stat) >> LP_TRIG_SHIFT) &
+			     LP_TRIG_MASK) == 1)
+				return;
+
+			writel(WAKEUP_STATE, &pctl->sctl);
+			while ((readl(&pctl->stat) & PCTL_STAT_MSK) != ACCESS)
+				;
+			/* Wait DLL lock. */
+			while ((readl(&publ->pgsr) & PGSR_DLDONE)
+			       != PGSR_DLDONE)
+				;
+			break;
+		case INIT_MEM:
+			writel(CFG_STATE, &pctl->sctl);
+			while ((readl(&pctl->stat) & PCTL_STAT_MSK) != CONFIG)
+				;
+			fallthrough;
+		case CONFIG:
+			writel(GO_STATE, &pctl->sctl);
+			while ((readl(&pctl->stat) & PCTL_STAT_MSK) == CONFIG)
+				;
+			break;
+		case ACCESS:
+			return;
+		default:
+			break;
+		}
+	}
+}
+
+static void rk3066_dmc_dram_cfg_rbc(const struct rk3066_dmc_chan_info *chan, u32 chnum,
+				    struct rk3066_dmc_sdram_params *sdram_params)
+{
+	struct rk3288_ddr_publ *publ = chan->publ;
+
+	if (sdram_params->ch[chnum].bk == 3)
+		clrsetbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT,
+				1 << PDQ_SHIFT);
+	else
+		clrbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT);
+
+	writel(sdram_params->base.ddrconfig, &chan->msch->ddrconf);
+}
+
+static void rk3066_dmc_dram_all_config(const struct rk3066_dmc_dram_info *dram,
+				       struct rk3066_dmc_sdram_params *sdram_params)
+{
+	unsigned int chan;
+	u32 sys_reg = 0;
+
+	sys_reg |= sdram_params->base.dramtype << SYS_REG_DDRTYPE_SHIFT;
+	sys_reg |= (sdram_params->num_channels - 1) << SYS_REG_NUM_CH_SHIFT;
+	for (chan = 0; chan < sdram_params->num_channels; chan++) {
+		const struct rk3288_sdram_channel *info =
+				&sdram_params->ch[chan];
+
+		sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(chan);
+		sys_reg |= 1 << SYS_REG_CHINFO_SHIFT(chan);
+		sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(chan);
+		sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(chan);
+		sys_reg |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(chan);
+		sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(chan);
+		sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(chan);
+		sys_reg |= (2 >> info->bw) << SYS_REG_BW_SHIFT(chan);
+		sys_reg |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(chan);
+
+		rk3066_dmc_dram_cfg_rbc(&dram->chan[chan], chan, sdram_params);
+	}
+	if (sdram_params->ch[0].rank == 2)
+		rk3066_dmc_ddr_rank_2_row15en(dram->grf, 0);
+	else
+		rk3066_dmc_ddr_rank_2_row15en(dram->grf, 1);
+
+	writel(sys_reg, &dram->pmu->sys_reg[2]);
+}
+
+static int rk3066_dmc_sdram_rank_bw_detect(struct rk3066_dmc_dram_info *dram, int channel,
+					   struct rk3066_dmc_sdram_params *sdram_params)
+{
+	int reg;
+	int need_trainig = 0;
+	const struct rk3066_dmc_chan_info *chan = &dram->chan[channel];
+	struct rk3288_ddr_publ *publ = chan->publ;
+
+	rk3066_dmc_ddr_rank_2_row15en(dram->grf, 0);
+
+	if (rk3066_dmc_data_training(chan, channel, sdram_params) < 0) {
+		debug("first data training fail!\n");
+		reg = readl(&publ->datx8[0].dxgsr[0]);
+		/* Check the result for rank 0. */
+		if (channel == 0 && (reg & DQS_GATE_TRAINING_ERROR_RANK0)) {
+			debug("data training fail!\n");
+			return -EIO;
+		}
+
+		/* Check the result for rank 1. */
+		if (reg & DQS_GATE_TRAINING_ERROR_RANK1) {
+			sdram_params->ch[channel].rank = 1;
+			clrsetbits_le32(&publ->pgcr, 0xF << 18,
+					sdram_params->ch[channel].rank << 18);
+			need_trainig = 1;
+		}
+		reg = readl(&publ->datx8[2].dxgsr[0]);
+		if (reg & (1 << 4)) {
+			sdram_params->ch[channel].bw = 1;
+			rk3066_dmc_set_bandwidth_ratio(chan, channel,
+						       sdram_params->ch[channel].bw,
+						       dram->grf);
+			need_trainig = 1;
+		}
+	}
+	/* Assume that the die bit width is equel to the chip bit width. */
+	sdram_params->ch[channel].dbw = sdram_params->ch[channel].bw;
+
+	if (need_trainig &&
+	    (rk3066_dmc_data_training(chan, channel, sdram_params) < 0)) {
+		if (sdram_params->base.dramtype == LPDDR3) {
+			rk3066_dmc_ddr_phy_ctl_reset(dram->cru, channel, 1);
+			udelay(10);
+			rk3066_dmc_ddr_phy_ctl_reset(dram->cru, channel, 0);
+			udelay(10);
+		}
+		debug("2nd data training failed!");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int rk3066_dmc_sdram_col_row_detect(struct rk3066_dmc_dram_info *dram, int channel,
+					   struct rk3066_dmc_sdram_params *sdram_params)
+{
+	int row, col;
+	unsigned int addr;
+	const struct rk3066_dmc_chan_info *chan = &dram->chan[channel];
+	struct rk3288_ddr_pctl *pctl = chan->pctl;
+	struct rk3288_ddr_publ *publ = chan->publ;
+	int ret = 0;
+
+	/* Detect col. */
+	for (col = 11; col >= 9; col--) {
+		writel(0, CONFIG_SYS_SDRAM_BASE);
+		addr = CONFIG_SYS_SDRAM_BASE +
+		       (1 << (col + sdram_params->ch[channel].bw - 1));
+		writel(TEST_PATTERN, addr);
+		if ((readl(addr) == TEST_PATTERN) &&
+		    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+			break;
+	}
+	if (col == 8) {
+		debug("Col detect error\n");
+		ret = -EINVAL;
+		goto out;
+	} else {
+		sdram_params->ch[channel].col = col;
+	}
+
+	rk3066_dmc_ddr_rank_2_row15en(dram->grf, 1);
+	rk3066_dmc_move_to_config_state(publ, pctl);
+	writel(1, &chan->msch->ddrconf);
+	rk3066_dmc_move_to_access_state(chan);
+	/* Detect row, max 15, min13 for rk3066 */
+	for (row = 16; row >= 13; row--) {
+		writel(0, CONFIG_SYS_SDRAM_BASE);
+		addr = CONFIG_SYS_SDRAM_BASE + (1 << (row + 15 - 1));
+		writel(TEST_PATTERN, addr);
+		if ((readl(addr) == TEST_PATTERN) &&
+		    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+			break;
+	}
+	if (row == 12) {
+		debug("Row detect error\n");
+		ret = -EINVAL;
+	} else {
+		sdram_params->ch[channel].cs1_row = row;
+		sdram_params->ch[channel].row_3_4 = 0;
+		debug("chn %d col %d, row %d\n", channel, col, row);
+		sdram_params->ch[channel].cs0_row = row;
+	}
+
+out:
+	return ret;
+}
+
+static int rk3066_dmc_sdram_get_niu_config(struct rk3066_dmc_sdram_params *sdram_params)
+{
+	int i, tmp, size, ret = 0;
+
+	tmp = sdram_params->ch[0].col - 9;
+	tmp -= (sdram_params->ch[0].bw == 2) ? 0 : 1;
+	tmp |= ((sdram_params->ch[0].cs0_row - 13) << 4);
+	size = ARRAY_SIZE(rk3066_dmc_ddrconf_table) / sizeof(rk3066_dmc_ddrconf_table[0]);
+	for (i = 0; i < size; i++)
+		if (tmp == rk3066_dmc_ddrconf_table[i])
+			break;
+	if (i >= size) {
+		debug("niu config not found\n");
+		ret = -EINVAL;
+	} else {
+		debug("niu config %d\n", i);
+		sdram_params->base.ddrconfig = i;
+	}
+
+	return ret;
+}
+
+static int rk3066_dmc_sdram_init(struct rk3066_dmc_dram_info *dram,
+				 struct rk3066_dmc_sdram_params *sdram_params)
+{
+	int channel;
+	int zqcr;
+	int ret;
+
+	if ((sdram_params->base.dramtype == DDR3 &&
+	     sdram_params->base.ddr_freq > 800000000)) {
+		debug("SDRAM frequency is too high!");
+		return -E2BIG;
+	}
+
+	ret = clk_set_rate(&dram->ddr_clk, sdram_params->base.ddr_freq);
+	if (ret) {
+		debug("Could not set DDR clock\n");
+		return ret;
+	}
+
+	for (channel = 0; channel < 1; channel++) {
+		const struct rk3066_dmc_chan_info *chan = &dram->chan[channel];
+		struct rk3288_ddr_pctl *pctl = chan->pctl;
+		struct rk3288_ddr_publ *publ = chan->publ;
+
+		rk3066_dmc_phy_pctrl_reset(dram->cru, publ, channel);
+		rk3066_dmc_phy_dll_bypass_set(publ, sdram_params->base.ddr_freq);
+
+		rk3066_dmc_dfi_cfg(pctl, sdram_params->base.dramtype);
+
+		rk3066_dmc_pctl_cfg(channel, pctl, sdram_params, dram->grf);
+
+		rk3066_dmc_phy_cfg(chan, channel, sdram_params);
+
+		rk3066_dmc_phy_init(publ);
+
+		writel(POWER_UP_START, &pctl->powctl);
+		while (!(readl(&pctl->powstat) & POWER_UP_DONE))
+			;
+
+		rk3066_dmc_memory_init(publ, sdram_params->base.dramtype);
+		rk3066_dmc_move_to_config_state(publ, pctl);
+
+		/* Use 32bit bus width for detection. */
+		sdram_params->ch[channel].bw = 2;
+		rk3066_dmc_set_bandwidth_ratio(chan, channel,
+					       sdram_params->ch[channel].bw, dram->grf);
+		/*
+		 * set cs, using n=3 for detect
+		 * CS0, n=1
+		 * CS1, n=2
+		 * CS0 & CS1, n = 3
+		 */
+		sdram_params->ch[channel].rank = 2;
+		clrsetbits_le32(&publ->pgcr, 0xF << 18,
+				(sdram_params->ch[channel].rank | 1) << 18);
+
+		/* DS=40ohm,ODT=155ohm */
+		zqcr = 1 << ZDEN_SHIFT | 2 << PU_ONDIE_SHIFT |
+		       2 << PD_ONDIE_SHIFT | 0x19 << PU_OUTPUT_SHIFT |
+		       0x19 << PD_OUTPUT_SHIFT;
+		writel(zqcr, &publ->zq1cr[0]);
+		writel(zqcr, &publ->zq0cr[0]);
+
+		/* Detect the rank and bit-width with data-training. */
+		writel(1, &chan->msch->ddrconf);
+		rk3066_dmc_sdram_rank_bw_detect(dram, channel, sdram_params);
+
+		if (sdram_params->base.dramtype == LPDDR3) {
+			u32 i;
+
+			writel(0, &pctl->mrrcfg0);
+
+			for (i = 0; i < 17; i++)
+				rk3066_dmc_send_command_op(pctl, 1, MRR_CMD, i, 0);
+		}
+		writel(4, &chan->msch->ddrconf);
+		rk3066_dmc_move_to_access_state(chan);
+		/* DDR3 and LPDDR3 are always 8 bank, no need to detect. */
+		sdram_params->ch[channel].bk = 3;
+		/* Detect Col and Row number. */
+		ret = rk3066_dmc_sdram_col_row_detect(dram, channel, sdram_params);
+		if (ret)
+			goto error;
+	}
+	/* Find NIU DDR configuration. */
+	ret = rk3066_dmc_sdram_get_niu_config(sdram_params);
+	if (ret)
+		goto error;
+
+	rk3066_dmc_dram_all_config(dram, sdram_params);
+	debug("SDRAM init OK!\n");
+
+	return 0;
+error:
+	debug("SDRAM init failed!\n");
+	hang();
+}
+
+static int rk3066_dmc_setup_sdram(struct udevice *dev)
+{
+	struct rk3066_dmc_dram_info *priv = dev_get_priv(dev);
+	struct rk3066_dmc_sdram_params *params = dev_get_plat(dev);
+
+	return rk3066_dmc_sdram_init(priv, params);
+}
+
+static int rk3066_dmc_conv_of_plat(struct udevice *dev)
+{
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	struct rk3066_dmc_sdram_params *plat = dev_get_plat(dev);
+	struct dtd_rockchip_rk3066_dmc *of_plat = &plat->of_plat;
+	int ret;
+
+	memcpy(&plat->pctl_timing, of_plat->rockchip_pctl_timing,
+	       sizeof(plat->pctl_timing));
+	memcpy(&plat->phy_timing, of_plat->rockchip_phy_timing,
+	       sizeof(plat->phy_timing));
+	memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base));
+	/* RK3066 supports dual-channel, set default channel num to 2. */
+	plat->num_channels = 1;
+	ret = regmap_init_mem_plat(dev, of_plat->reg,
+				   ARRAY_SIZE(of_plat->reg) / 2, &plat->map);
+	if (ret)
+		return ret;
+
+	return 0;
+#else
+	return -EINVAL;
+#endif
+}
+
+static int rk3066_dmc_probe(struct udevice *dev)
+{
+	struct rk3066_dmc_dram_info *priv = dev_get_priv(dev);
+
+	priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
+
+	if (IS_ENABLED(CONFIG_TPL_BUILD)) {
+		struct rk3066_dmc_sdram_params *plat = dev_get_plat(dev);
+		struct regmap *map;
+		struct udevice *dev_clk;
+		int ret;
+
+		ret = rk3066_dmc_conv_of_plat(dev);
+		if (ret)
+			return ret;
+
+		map = syscon_get_regmap_by_driver_data(ROCKCHIP_SYSCON_NOC);
+		if (IS_ERR(map))
+			return PTR_ERR(map);
+		priv->chan[0].msch = regmap_get_range(map, 0);
+		priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+
+		priv->chan[0].pctl = regmap_get_range(plat->map, 0);
+		priv->chan[0].publ = regmap_get_range(plat->map, 1);
+
+		ret = rockchip_get_clk(&dev_clk);
+		if (ret)
+			return ret;
+
+		priv->ddr_clk.id = CLK_DDR;
+		ret = clk_request(dev_clk, &priv->ddr_clk);
+		if (ret)
+			return ret;
+
+		priv->cru = rockchip_get_cru();
+		if (IS_ERR(priv->cru))
+			return PTR_ERR(priv->cru);
+
+		ret = rk3066_dmc_setup_sdram(dev);
+		if (ret)
+			return ret;
+	} else {
+		priv->info.base = CONFIG_SYS_SDRAM_BASE;
+		priv->info.size = rockchip_sdram_size((phys_addr_t)&priv->pmu->sys_reg[2]);
+	}
+
+	return 0;
+}
+
+static int rk3066_dmc_get_info(struct udevice *dev, struct ram_info *info)
+{
+	struct rk3066_dmc_dram_info *priv = dev_get_priv(dev);
+
+	*info = priv->info;
+
+	return 0;
+}
+
+static struct ram_ops rk3066_dmc_ops = {
+	.get_info = rk3066_dmc_get_info,
+};
+
+static const struct udevice_id rk3066_dmc_ids[] = {
+	{ .compatible = "rockchip,rk3066-dmc" },
+	{ }
+};
+
+U_BOOT_DRIVER(rockchip_rk3066_dmc) = {
+	.name		= "rockchip_rk3066_dmc",
+	.id		= UCLASS_RAM,
+	.ops		= &rk3066_dmc_ops,
+	.probe		= rk3066_dmc_probe,
+	.of_match	= rk3066_dmc_ids,
+	.priv_auto	= sizeof(struct rk3066_dmc_dram_info),
+#if IS_ENABLED(CONFIG_TPL_BUILD)
+	.plat_auto	= sizeof(struct rk3066_dmc_sdram_params),
+#endif
+};
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v9 06/16] arm: dts: rockchip: fix rk3xxx-u-boot.dtsi
  2022-04-04 14:19 [PATCH v9 00/16] Add Rikomagic MK808 board Johan Jonker
                   ` (4 preceding siblings ...)
  2022-04-04 14:19 ` [PATCH v9 05/16] rockchip: rk3066: add sdram driver Johan Jonker
@ 2022-04-04 14:19 ` Johan Jonker
  2022-04-09  3:50   ` Kever Yang
  2022-04-04 14:19 ` [PATCH v9 07/16] arm: dts: rockchip: fix include rk3xxx-u-boot.dtsi Johan Jonker
                   ` (9 subsequent siblings)
  15 siblings, 1 reply; 33+ messages in thread
From: Johan Jonker @ 2022-04-04 14:19 UTC (permalink / raw)
  To: kever.yang; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot

The file rk3xxx-u-boot.dtsi was original only for rk3188 and SPL.
With rk3066 added some nodes are also needed in TPL,
so change them to u-boot,dm-pre-reloc

Signed-off-by: Johan Jonker <jbx6244@gmail.com>
---
 arch/arm/dts/rk3xxx-u-boot.dtsi | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/dts/rk3xxx-u-boot.dtsi b/arch/arm/dts/rk3xxx-u-boot.dtsi
index 581594c35d..e67432fb39 100644
--- a/arch/arm/dts/rk3xxx-u-boot.dtsi
+++ b/arch/arm/dts/rk3xxx-u-boot.dtsi
@@ -4,7 +4,7 @@
 	noc: syscon@10128000 {
 		compatible = "rockchip,rk3188-noc", "syscon";
 		reg = <0x10128000 0x2000>;
-		u-boot,dm-spl;
+		u-boot,dm-pre-reloc;
 	};
 
 	dmc: dmc@20020000 {
@@ -18,16 +18,16 @@
 		rockchip,grf = <&grf>;
 		rockchip,pmu = <&pmu>;
 		rockchip,noc = <&noc>;
-		u-boot,dm-spl;
+		u-boot,dm-pre-reloc;
 	};
 };
 
 &grf {
-	u-boot,dm-spl;
+	u-boot,dm-pre-reloc;
 };
 
 &pmu {
-	u-boot,dm-spl;
+	u-boot,dm-pre-reloc;
 };
 
 &uart2 {
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v9 07/16] arm: dts: rockchip: fix include rk3xxx-u-boot.dtsi
  2022-04-04 14:19 [PATCH v9 00/16] Add Rikomagic MK808 board Johan Jonker
                   ` (5 preceding siblings ...)
  2022-04-04 14:19 ` [PATCH v9 06/16] arm: dts: rockchip: fix rk3xxx-u-boot.dtsi Johan Jonker
@ 2022-04-04 14:19 ` Johan Jonker
  2022-04-09  3:50   ` Kever Yang
  2022-04-04 14:19 ` [PATCH v9 08/16] arm: dts: rockchip: add rk3066a.dtsi Johan Jonker
                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 33+ messages in thread
From: Johan Jonker @ 2022-04-04 14:19 UTC (permalink / raw)
  To: kever.yang; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot

Move the include for rk3xxx-u-boot.dtsi to rk3188-u-boot.dtsi
to stay in line with U-boot dtsi files.

Signed-off-by: Johan Jonker <jbx6244@gmail.com>
---
 arch/arm/dts/rk3188-u-boot.dtsi | 1 +
 arch/arm/dts/rk3188.dtsi        | 1 -
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/dts/rk3188-u-boot.dtsi b/arch/arm/dts/rk3188-u-boot.dtsi
index 43f05b9876..735776c16b 100644
--- a/arch/arm/dts/rk3188-u-boot.dtsi
+++ b/arch/arm/dts/rk3188-u-boot.dtsi
@@ -4,6 +4,7 @@
  */
 
 #include "rockchip-u-boot.dtsi"
+#include "rk3xxx-u-boot.dtsi"
 
 &global_timer {
 	status = "okay";
diff --git a/arch/arm/dts/rk3188.dtsi b/arch/arm/dts/rk3188.dtsi
index 6c1c2ff533..6764776cce 100644
--- a/arch/arm/dts/rk3188.dtsi
+++ b/arch/arm/dts/rk3188.dtsi
@@ -9,7 +9,6 @@
 #include <dt-bindings/clock/rk3188-cru.h>
 #include <dt-bindings/power/rk3188-power.h>
 #include "rk3xxx.dtsi"
-#include "rk3xxx-u-boot.dtsi"
 
 / {
 	compatible = "rockchip,rk3188";
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v9 08/16] arm: dts: rockchip: add rk3066a.dtsi
  2022-04-04 14:19 [PATCH v9 00/16] Add Rikomagic MK808 board Johan Jonker
                   ` (6 preceding siblings ...)
  2022-04-04 14:19 ` [PATCH v9 07/16] arm: dts: rockchip: fix include rk3xxx-u-boot.dtsi Johan Jonker
@ 2022-04-04 14:19 ` Johan Jonker
  2022-04-09  3:52   ` Kever Yang
  2022-04-04 14:19 ` [PATCH v9 09/16] arm: dts: rockchip: add rk3066a-mk808.dts Johan Jonker
                   ` (7 subsequent siblings)
  15 siblings, 1 reply; 33+ messages in thread
From: Johan Jonker @ 2022-04-04 14:19 UTC (permalink / raw)
  To: kever.yang; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot

In the Linux DT the file rk3xxx.dtsi is shared between
rk3066 and rk3188. Add rk3066a.dtsi. Move U-boot specific
things in a rk3066a-u-boot.dtsi file.

Signed-off-by: Johan Jonker <jbx6244@gmail.com>
---

Changed V9:
  fix include rk3066a-u-boot.dtsi

Changed V8:
  update dtsi
---
 arch/arm/dts/rk3066a-u-boot.dtsi |   4 +
 arch/arm/dts/rk3066a.dtsi        | 879 +++++++++++++++++++++++++++++++
 2 files changed, 883 insertions(+)
 create mode 100644 arch/arm/dts/rk3066a-u-boot.dtsi
 create mode 100644 arch/arm/dts/rk3066a.dtsi

diff --git a/arch/arm/dts/rk3066a-u-boot.dtsi b/arch/arm/dts/rk3066a-u-boot.dtsi
new file mode 100644
index 0000000000..bc6e609d02
--- /dev/null
+++ b/arch/arm/dts/rk3066a-u-boot.dtsi
@@ -0,0 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include "rockchip-u-boot.dtsi"
+#include "rk3xxx-u-boot.dtsi"
diff --git a/arch/arm/dts/rk3066a.dtsi b/arch/arm/dts/rk3066a.dtsi
new file mode 100644
index 0000000000..c25b9695db
--- /dev/null
+++ b/arch/arm/dts/rk3066a.dtsi
@@ -0,0 +1,879 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/clock/rk3066a-cru.h>
+#include <dt-bindings/power/rk3066-power.h>
+#include "rk3xxx.dtsi"
+
+/ {
+	compatible = "rockchip,rk3066a";
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		enable-method = "rockchip,rk3066-smp";
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			next-level-cache = <&L2>;
+			reg = <0x0>;
+			operating-points =
+				/* kHz    uV */
+				<1416000 1300000>,
+				<1200000 1175000>,
+				<1008000 1125000>,
+				<816000  1125000>,
+				<600000  1100000>,
+				<504000  1100000>,
+				<312000  1075000>;
+			clock-latency = <40000>;
+			clocks = <&cru ARMCLK>;
+		};
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			next-level-cache = <&L2>;
+			reg = <0x1>;
+		};
+	};
+
+	display-subsystem {
+		compatible = "rockchip,display-subsystem";
+		ports = <&vop0_out>, <&vop1_out>;
+	};
+
+	sram: sram@10080000 {
+		compatible = "mmio-sram";
+		reg = <0x10080000 0x10000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0x10080000 0x10000>;
+
+		smp-sram@0 {
+			compatible = "rockchip,rk3066-smp-sram";
+			reg = <0x0 0x50>;
+		};
+	};
+
+	vop0: vop@1010c000 {
+		compatible = "rockchip,rk3066-vop";
+		reg = <0x1010c000 0x19c>;
+		interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_LCDC0>,
+			 <&cru DCLK_LCDC0>,
+			 <&cru HCLK_LCDC0>;
+		clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+		power-domains = <&power RK3066_PD_VIO>;
+		resets = <&cru SRST_LCDC0_AXI>,
+			 <&cru SRST_LCDC0_AHB>,
+			 <&cru SRST_LCDC0_DCLK>;
+		reset-names = "axi", "ahb", "dclk";
+		status = "disabled";
+
+		vop0_out: port {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			vop0_out_hdmi: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&hdmi_in_vop0>;
+			};
+		};
+	};
+
+	vop1: vop@1010e000 {
+		compatible = "rockchip,rk3066-vop";
+		reg = <0x1010e000 0x19c>;
+		interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_LCDC1>,
+			 <&cru DCLK_LCDC1>,
+			 <&cru HCLK_LCDC1>;
+		clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+		power-domains = <&power RK3066_PD_VIO>;
+		resets = <&cru SRST_LCDC1_AXI>,
+			 <&cru SRST_LCDC1_AHB>,
+			 <&cru SRST_LCDC1_DCLK>;
+		reset-names = "axi", "ahb", "dclk";
+		status = "disabled";
+
+		vop1_out: port {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			vop1_out_hdmi: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&hdmi_in_vop1>;
+			};
+		};
+	};
+
+	hdmi: hdmi@10116000 {
+		compatible = "rockchip,rk3066-hdmi";
+		reg = <0x10116000 0x2000>;
+		interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_HDMI>;
+		clock-names = "hclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&hdmii2c_xfer>, <&hdmi_hpd>;
+		power-domains = <&power RK3066_PD_VIO>;
+		rockchip,grf = <&grf>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			hdmi_in: port@0 {
+				reg = <0>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				hdmi_in_vop0: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&vop0_out_hdmi>;
+				};
+
+				hdmi_in_vop1: endpoint@1 {
+					reg = <1>;
+					remote-endpoint = <&vop1_out_hdmi>;
+				};
+			};
+
+			hdmi_out: port@1 {
+				reg = <1>;
+			};
+		};
+	};
+
+	i2s0: i2s@10118000 {
+		compatible = "rockchip,rk3066-i2s";
+		reg = <0x10118000 0x2000>;
+		interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2s0_bus>;
+		clocks = <&cru SCLK_I2S0>, <&cru HCLK_I2S0>;
+		clock-names = "i2s_clk", "i2s_hclk";
+		dmas = <&dmac1_s 4>, <&dmac1_s 5>;
+		dma-names = "tx", "rx";
+		rockchip,playback-channels = <8>;
+		rockchip,capture-channels = <2>;
+		#sound-dai-cells = <0>;
+		status = "disabled";
+	};
+
+	i2s1: i2s@1011a000 {
+		compatible = "rockchip,rk3066-i2s";
+		reg = <0x1011a000 0x2000>;
+		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2s1_bus>;
+		clocks = <&cru SCLK_I2S1>, <&cru HCLK_I2S1>;
+		clock-names = "i2s_clk", "i2s_hclk";
+		dmas = <&dmac1_s 6>, <&dmac1_s 7>;
+		dma-names = "tx", "rx";
+		rockchip,playback-channels = <2>;
+		rockchip,capture-channels = <2>;
+		#sound-dai-cells = <0>;
+		status = "disabled";
+	};
+
+	i2s2: i2s@1011c000 {
+		compatible = "rockchip,rk3066-i2s";
+		reg = <0x1011c000 0x2000>;
+		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2s2_bus>;
+		clocks = <&cru SCLK_I2S2>, <&cru HCLK_I2S2>;
+		clock-names = "i2s_clk", "i2s_hclk";
+		dmas = <&dmac1_s 9>, <&dmac1_s 10>;
+		dma-names = "tx", "rx";
+		rockchip,playback-channels = <2>;
+		rockchip,capture-channels = <2>;
+		#sound-dai-cells = <0>;
+		status = "disabled";
+	};
+
+	cru: clock-controller@20000000 {
+		compatible = "rockchip,rk3066a-cru";
+		reg = <0x20000000 0x1000>;
+		rockchip,grf = <&grf>;
+
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+		assigned-clocks = <&cru PLL_CPLL>, <&cru PLL_GPLL>,
+				  <&cru ACLK_CPU>, <&cru HCLK_CPU>,
+				  <&cru PCLK_CPU>, <&cru ACLK_PERI>,
+				  <&cru HCLK_PERI>, <&cru PCLK_PERI>;
+		assigned-clock-rates = <400000000>, <594000000>,
+				       <300000000>, <150000000>,
+				       <75000000>, <300000000>,
+				       <150000000>, <75000000>;
+	};
+
+	timer2: timer@2000e000 {
+		compatible = "snps,dw-apb-timer";
+		reg = <0x2000e000 0x100>;
+		interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_TIMER2>, <&cru PCLK_TIMER2>;
+		clock-names = "timer", "pclk";
+	};
+
+	efuse: efuse@20010000 {
+		compatible = "rockchip,rk3066a-efuse";
+		reg = <0x20010000 0x4000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		clocks = <&cru PCLK_EFUSE>;
+		clock-names = "pclk_efuse";
+
+		cpu_leakage: cpu_leakage@17 {
+			reg = <0x17 0x1>;
+		};
+	};
+
+	timer0: timer@20038000 {
+		compatible = "snps,dw-apb-timer";
+		reg = <0x20038000 0x100>;
+		interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_TIMER0>, <&cru PCLK_TIMER0>;
+		clock-names = "timer", "pclk";
+	};
+
+	timer1: timer@2003a000 {
+		compatible = "snps,dw-apb-timer";
+		reg = <0x2003a000 0x100>;
+		interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_TIMER1>, <&cru PCLK_TIMER1>;
+		clock-names = "timer", "pclk";
+	};
+
+	tsadc: tsadc@20060000 {
+		compatible = "rockchip,rk3066-tsadc";
+		reg = <0x20060000 0x100>;
+		clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>;
+		clock-names = "saradc", "apb_pclk";
+		interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+		#io-channel-cells = <1>;
+		resets = <&cru SRST_TSADC>;
+		reset-names = "saradc-apb";
+		status = "disabled";
+	};
+
+	pinctrl: pinctrl {
+		compatible = "rockchip,rk3066a-pinctrl";
+		rockchip,grf = <&grf>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		gpio0: gpio@20034000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x20034000 0x100>;
+			interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO0>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio1: gpio@2003c000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x2003c000 0x100>;
+			interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO1>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio2: gpio@2003e000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x2003e000 0x100>;
+			interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO2>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio3: gpio@20080000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x20080000 0x100>;
+			interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO3>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio4: gpio@20084000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x20084000 0x100>;
+			interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO4>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio6: gpio@2000a000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x2000a000 0x100>;
+			interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO6>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		pcfg_pull_default: pcfg-pull-default {
+			bias-pull-pin-default;
+		};
+
+		pcfg_pull_none: pcfg-pull-none {
+			bias-disable;
+		};
+
+		emac {
+			emac_xfer: emac-xfer {
+				rockchip,pins = <1 RK_PC0 2 &pcfg_pull_none>, /* mac_clk */
+						<1 RK_PC1 2 &pcfg_pull_none>, /* tx_en */
+						<1 RK_PC2 2 &pcfg_pull_none>, /* txd1 */
+						<1 RK_PC3 2 &pcfg_pull_none>, /* txd0 */
+						<1 RK_PC4 2 &pcfg_pull_none>, /* rx_err */
+						<1 RK_PC5 2 &pcfg_pull_none>, /* crs_dvalid */
+						<1 RK_PC6 2 &pcfg_pull_none>, /* rxd1 */
+						<1 RK_PC7 2 &pcfg_pull_none>; /* rxd0 */
+			};
+
+			emac_mdio: emac-mdio {
+				rockchip,pins = <1 RK_PD0 2 &pcfg_pull_none>, /* mac_md */
+						<1 RK_PD1 2 &pcfg_pull_none>; /* mac_mdclk */
+			};
+		};
+
+		emmc {
+			emmc_clk: emmc-clk {
+				rockchip,pins = <3 RK_PD7 2 &pcfg_pull_default>;
+			};
+
+			emmc_cmd: emmc-cmd {
+				rockchip,pins = <4 RK_PB1 2 &pcfg_pull_default>;
+			};
+
+			emmc_rst: emmc-rst {
+				rockchip,pins = <4 RK_PB2 2 &pcfg_pull_default>;
+			};
+
+			/*
+			 * The data pins are shared between nandc and emmc and
+			 * not accessible through pinctrl. Also they should've
+			 * been already set correctly by firmware, as
+			 * flash/emmc is the boot-device.
+			 */
+		};
+
+		hdmi {
+			hdmi_hpd: hdmi-hpd {
+				rockchip,pins = <0 RK_PA0 1 &pcfg_pull_default>;
+			};
+
+			hdmii2c_xfer: hdmii2c-xfer {
+				rockchip,pins = <0 RK_PA1 1 &pcfg_pull_none>,
+						<0 RK_PA2 1 &pcfg_pull_none>;
+			};
+		};
+
+		i2c0 {
+			i2c0_xfer: i2c0-xfer {
+				rockchip,pins = <2 RK_PD4 1 &pcfg_pull_none>,
+						<2 RK_PD5 1 &pcfg_pull_none>;
+			};
+		};
+
+		i2c1 {
+			i2c1_xfer: i2c1-xfer {
+				rockchip,pins = <2 RK_PD6 1 &pcfg_pull_none>,
+						<2 RK_PD7 1 &pcfg_pull_none>;
+			};
+		};
+
+		i2c2 {
+			i2c2_xfer: i2c2-xfer {
+				rockchip,pins = <3 RK_PA0 1 &pcfg_pull_none>,
+						<3 RK_PA1 1 &pcfg_pull_none>;
+			};
+		};
+
+		i2c3 {
+			i2c3_xfer: i2c3-xfer {
+				rockchip,pins = <3 RK_PA2 2 &pcfg_pull_none>,
+						<3 RK_PA3 2 &pcfg_pull_none>;
+			};
+		};
+
+		i2c4 {
+			i2c4_xfer: i2c4-xfer {
+				rockchip,pins = <3 RK_PA4 1 &pcfg_pull_none>,
+						<3 RK_PA5 1 &pcfg_pull_none>;
+			};
+		};
+
+		pwm0 {
+			pwm0_out: pwm0-out {
+				rockchip,pins = <0 RK_PA3 1 &pcfg_pull_none>;
+			};
+		};
+
+		pwm1 {
+			pwm1_out: pwm1-out {
+				rockchip,pins = <0 RK_PA4 1 &pcfg_pull_none>;
+			};
+		};
+
+		pwm2 {
+			pwm2_out: pwm2-out {
+				rockchip,pins = <0 RK_PD6 1 &pcfg_pull_none>;
+			};
+		};
+
+		pwm3 {
+			pwm3_out: pwm3-out {
+				rockchip,pins = <0 RK_PD7 1 &pcfg_pull_none>;
+			};
+		};
+
+		spi0 {
+			spi0_clk: spi0-clk {
+				rockchip,pins = <1 RK_PA5 2 &pcfg_pull_default>;
+			};
+			spi0_cs0: spi0-cs0 {
+				rockchip,pins = <1 RK_PA4 2 &pcfg_pull_default>;
+			};
+			spi0_tx: spi0-tx {
+				rockchip,pins = <1 RK_PA7 2 &pcfg_pull_default>;
+			};
+			spi0_rx: spi0-rx {
+				rockchip,pins = <1 RK_PA6 2 &pcfg_pull_default>;
+			};
+			spi0_cs1: spi0-cs1 {
+				rockchip,pins = <4 RK_PB7 1 &pcfg_pull_default>;
+			};
+		};
+
+		spi1 {
+			spi1_clk: spi1-clk {
+				rockchip,pins = <2 RK_PC3 2 &pcfg_pull_default>;
+			};
+			spi1_cs0: spi1-cs0 {
+				rockchip,pins = <2 RK_PC4 2 &pcfg_pull_default>;
+			};
+			spi1_rx: spi1-rx {
+				rockchip,pins = <2 RK_PC6 2 &pcfg_pull_default>;
+			};
+			spi1_tx: spi1-tx {
+				rockchip,pins = <2 RK_PC5 2 &pcfg_pull_default>;
+			};
+			spi1_cs1: spi1-cs1 {
+				rockchip,pins = <2 RK_PC7 2 &pcfg_pull_default>;
+			};
+		};
+
+		uart0 {
+			uart0_xfer: uart0-xfer {
+				rockchip,pins = <1 RK_PA0 1 &pcfg_pull_default>,
+						<1 RK_PA1 1 &pcfg_pull_default>;
+			};
+
+			uart0_cts: uart0-cts {
+				rockchip,pins = <1 RK_PA2 1 &pcfg_pull_default>;
+			};
+
+			uart0_rts: uart0-rts {
+				rockchip,pins = <1 RK_PA3 1 &pcfg_pull_default>;
+			};
+		};
+
+		uart1 {
+			uart1_xfer: uart1-xfer {
+				rockchip,pins = <1 RK_PA4 1 &pcfg_pull_default>,
+						<1 RK_PA5 1 &pcfg_pull_default>;
+			};
+
+			uart1_cts: uart1-cts {
+				rockchip,pins = <1 RK_PA6 1 &pcfg_pull_default>;
+			};
+
+			uart1_rts: uart1-rts {
+				rockchip,pins = <1 RK_PA7 1 &pcfg_pull_default>;
+			};
+		};
+
+		uart2 {
+			uart2_xfer: uart2-xfer {
+				rockchip,pins = <1 RK_PB0 1 &pcfg_pull_default>,
+						<1 RK_PB1 1 &pcfg_pull_default>;
+			};
+			/* no rts / cts for uart2 */
+		};
+
+		uart3 {
+			uart3_xfer: uart3-xfer {
+				rockchip,pins = <3 RK_PD3 1 &pcfg_pull_default>,
+						<3 RK_PD4 1 &pcfg_pull_default>;
+			};
+
+			uart3_cts: uart3-cts {
+				rockchip,pins = <3 RK_PD5 1 &pcfg_pull_default>;
+			};
+
+			uart3_rts: uart3-rts {
+				rockchip,pins = <3 RK_PD6 1 &pcfg_pull_default>;
+			};
+		};
+
+		sd0 {
+			sd0_clk: sd0-clk {
+				rockchip,pins = <3 RK_PB0 1 &pcfg_pull_default>;
+			};
+
+			sd0_cmd: sd0-cmd {
+				rockchip,pins = <3 RK_PB1 1 &pcfg_pull_default>;
+			};
+
+			sd0_cd: sd0-cd {
+				rockchip,pins = <3 RK_PB6 1 &pcfg_pull_default>;
+			};
+
+			sd0_wp: sd0-wp {
+				rockchip,pins = <3 RK_PB7 1 &pcfg_pull_default>;
+			};
+
+			sd0_bus1: sd0-bus-width1 {
+				rockchip,pins = <3 RK_PB2 1 &pcfg_pull_default>;
+			};
+
+			sd0_bus4: sd0-bus-width4 {
+				rockchip,pins = <3 RK_PB2 1 &pcfg_pull_default>,
+						<3 RK_PB3 1 &pcfg_pull_default>,
+						<3 RK_PB4 1 &pcfg_pull_default>,
+						<3 RK_PB5 1 &pcfg_pull_default>;
+			};
+		};
+
+		sd1 {
+			sd1_clk: sd1-clk {
+				rockchip,pins = <3 RK_PC5 1 &pcfg_pull_default>;
+			};
+
+			sd1_cmd: sd1-cmd {
+				rockchip,pins = <3 RK_PC0 1 &pcfg_pull_default>;
+			};
+
+			sd1_cd: sd1-cd {
+				rockchip,pins = <3 RK_PC6 1 &pcfg_pull_default>;
+			};
+
+			sd1_wp: sd1-wp {
+				rockchip,pins = <3 RK_PC7 1 &pcfg_pull_default>;
+			};
+
+			sd1_bus1: sd1-bus-width1 {
+				rockchip,pins = <3 RK_PC1 1 &pcfg_pull_default>;
+			};
+
+			sd1_bus4: sd1-bus-width4 {
+				rockchip,pins = <3 RK_PC1 1 &pcfg_pull_default>,
+						<3 RK_PC2 1 &pcfg_pull_default>,
+						<3 RK_PC3 1 &pcfg_pull_default>,
+						<3 RK_PC4 1 &pcfg_pull_default>;
+			};
+		};
+
+		i2s0 {
+			i2s0_bus: i2s0-bus {
+				rockchip,pins = <0 RK_PA7 1 &pcfg_pull_default>,
+						<0 RK_PB0 1 &pcfg_pull_default>,
+						<0 RK_PB1 1 &pcfg_pull_default>,
+						<0 RK_PB2 1 &pcfg_pull_default>,
+						<0 RK_PB3 1 &pcfg_pull_default>,
+						<0 RK_PB4 1 &pcfg_pull_default>,
+						<0 RK_PB5 1 &pcfg_pull_default>,
+						<0 RK_PB6 1 &pcfg_pull_default>,
+						<0 RK_PB7 1 &pcfg_pull_default>;
+			};
+		};
+
+		i2s1 {
+			i2s1_bus: i2s1-bus {
+				rockchip,pins = <0 RK_PC0 1 &pcfg_pull_default>,
+						<0 RK_PC1 1 &pcfg_pull_default>,
+						<0 RK_PC2 1 &pcfg_pull_default>,
+						<0 RK_PC3 1 &pcfg_pull_default>,
+						<0 RK_PC4 1 &pcfg_pull_default>,
+						<0 RK_PC5 1 &pcfg_pull_default>;
+			};
+		};
+
+		i2s2 {
+			i2s2_bus: i2s2-bus {
+				rockchip,pins = <0 RK_PD0 1 &pcfg_pull_default>,
+						<0 RK_PD1 1 &pcfg_pull_default>,
+						<0 RK_PD2 1 &pcfg_pull_default>,
+						<0 RK_PD3 1 &pcfg_pull_default>,
+						<0 RK_PD4 1 &pcfg_pull_default>,
+						<0 RK_PD5 1 &pcfg_pull_default>;
+			};
+		};
+	};
+};
+
+&gpu {
+	compatible = "rockchip,rk3066-mali", "arm,mali-400";
+	interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+	interrupt-names = "gp",
+			  "gpmmu",
+			  "pp0",
+			  "ppmmu0",
+			  "pp1",
+			  "ppmmu1",
+			  "pp2",
+			  "ppmmu2",
+			  "pp3",
+			  "ppmmu3";
+	power-domains = <&power RK3066_PD_GPU>;
+};
+
+&grf {
+	compatible = "rockchip,rk3066-grf", "syscon", "simple-mfd";
+
+	usbphy: usbphy {
+		compatible = "rockchip,rk3066a-usb-phy";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+
+		usbphy0: usb-phy@17c {
+			reg = <0x17c>;
+			clocks = <&cru SCLK_OTGPHY0>;
+			clock-names = "phyclk";
+			#clock-cells = <0>;
+			#phy-cells = <0>;
+		};
+
+		usbphy1: usb-phy@188 {
+			reg = <0x188>;
+			clocks = <&cru SCLK_OTGPHY1>;
+			clock-names = "phyclk";
+			#clock-cells = <0>;
+			#phy-cells = <0>;
+		};
+	};
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_xfer>;
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_xfer>;
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2_xfer>;
+};
+
+&i2c3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c3_xfer>;
+};
+
+&i2c4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c4_xfer>;
+};
+
+&mmc0 {
+	clock-frequency = <50000000>;
+	dmas = <&dmac2 1>;
+	dma-names = "rx-tx";
+	max-frequency = <50000000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_bus4>;
+};
+
+&mmc1 {
+	dmas = <&dmac2 3>;
+	dma-names = "rx-tx";
+	pinctrl-names = "default";
+	pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_cd &sd1_bus4>;
+};
+
+&emmc {
+	dmas = <&dmac2 4>;
+	dma-names = "rx-tx";
+};
+
+&pmu {
+	power: power-controller {
+		compatible = "rockchip,rk3066-power-controller";
+		#power-domain-cells = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		power-domain@RK3066_PD_VIO {
+			reg = <RK3066_PD_VIO>;
+			clocks = <&cru ACLK_LCDC0>,
+				 <&cru ACLK_LCDC1>,
+				 <&cru DCLK_LCDC0>,
+				 <&cru DCLK_LCDC1>,
+				 <&cru HCLK_LCDC0>,
+				 <&cru HCLK_LCDC1>,
+				 <&cru SCLK_CIF1>,
+				 <&cru ACLK_CIF1>,
+				 <&cru HCLK_CIF1>,
+				 <&cru SCLK_CIF0>,
+				 <&cru ACLK_CIF0>,
+				 <&cru HCLK_CIF0>,
+				 <&cru HCLK_HDMI>,
+				 <&cru ACLK_IPP>,
+				 <&cru HCLK_IPP>,
+				 <&cru ACLK_RGA>,
+				 <&cru HCLK_RGA>;
+			pm_qos = <&qos_lcdc0>,
+				 <&qos_lcdc1>,
+				 <&qos_cif0>,
+				 <&qos_cif1>,
+				 <&qos_ipp>,
+				 <&qos_rga>;
+			#power-domain-cells = <0>;
+		};
+
+		power-domain@RK3066_PD_VIDEO {
+			reg = <RK3066_PD_VIDEO>;
+			clocks = <&cru ACLK_VDPU>,
+				 <&cru ACLK_VEPU>,
+				 <&cru HCLK_VDPU>,
+				 <&cru HCLK_VEPU>;
+			pm_qos = <&qos_vpu>;
+			#power-domain-cells = <0>;
+		};
+
+		power-domain@RK3066_PD_GPU {
+			reg = <RK3066_PD_GPU>;
+			clocks = <&cru ACLK_GPU>;
+			pm_qos = <&qos_gpu>;
+			#power-domain-cells = <0>;
+		};
+	};
+};
+
+&pwm0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm0_out>;
+};
+
+&pwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm1_out>;
+};
+
+&pwm2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm2_out>;
+};
+
+&pwm3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm3_out>;
+};
+
+&spi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0>;
+};
+
+&spi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi1_clk &spi1_tx &spi1_rx &spi1_cs0>;
+};
+
+&uart0 {
+	compatible = "rockchip,rk3066-uart", "snps,dw-apb-uart";
+	dmas = <&dmac1_s 0>, <&dmac1_s 1>;
+	dma-names = "tx", "rx";
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_xfer>;
+};
+
+&uart1 {
+	compatible = "rockchip,rk3066-uart", "snps,dw-apb-uart";
+	dmas = <&dmac1_s 2>, <&dmac1_s 3>;
+	dma-names = "tx", "rx";
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_xfer>;
+};
+
+&uart2 {
+	compatible = "rockchip,rk3066-uart", "snps,dw-apb-uart";
+	dmas = <&dmac2 6>, <&dmac2 7>;
+	dma-names = "tx", "rx";
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2_xfer>;
+};
+
+&uart3 {
+	compatible = "rockchip,rk3066-uart", "snps,dw-apb-uart";
+	dmas = <&dmac2 8>, <&dmac2 9>;
+	dma-names = "tx", "rx";
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart3_xfer>;
+};
+
+&vpu {
+	power-domains = <&power RK3066_PD_VIDEO>;
+};
+
+&wdt {
+	compatible = "rockchip,rk3066-wdt", "snps,dw-wdt";
+};
+
+&emac {
+	compatible = "rockchip,rk3066-emac";
+};
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v9 09/16] arm: dts: rockchip: add rk3066a-mk808.dts
  2022-04-04 14:19 [PATCH v9 00/16] Add Rikomagic MK808 board Johan Jonker
                   ` (7 preceding siblings ...)
  2022-04-04 14:19 ` [PATCH v9 08/16] arm: dts: rockchip: add rk3066a.dtsi Johan Jonker
@ 2022-04-04 14:19 ` Johan Jonker
  2022-04-09  3:52   ` Kever Yang
  2022-04-04 14:19 ` [PATCH v9 10/16] rockchip: rk3066: add include Johan Jonker
                   ` (6 subsequent siblings)
  15 siblings, 1 reply; 33+ messages in thread
From: Johan Jonker @ 2022-04-04 14:19 UTC (permalink / raw)
  To: kever.yang; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot

MK808 is a RK3066-based board with 1 USB host and 1 USB OTG port,
HDMI and a micro-SD card slot. It also includes on-board NAND
and 1GB of SDRAM. Add rk3066a-mk808.dts. Move U-boot specific
things in a rk3066a-mk808-u-boot.dtsi file.

Signed-off-by: Johan Jonker <jbx6244@gmail.com>
---

Changed V9:
  add led config
  move dtb-$() in Makefile

Changed V8:
  update dts
---
 arch/arm/dts/Makefile                  |   3 +
 arch/arm/dts/rk3066a-mk808-u-boot.dtsi |  48 ++++++
 arch/arm/dts/rk3066a-mk808.dts         | 216 +++++++++++++++++++++++++
 3 files changed, 267 insertions(+)
 create mode 100644 arch/arm/dts/rk3066a-mk808-u-boot.dtsi
 create mode 100644 arch/arm/dts/rk3066a-mk808.dts

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 99dc7bc777..e8657bed09 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -90,6 +90,9 @@ dtb-$(CONFIG_ROCKCHIP_PX30) += \
 dtb-$(CONFIG_ROCKCHIP_RK3036) += \
 	rk3036-sdk.dtb
 
+dtb-$(CONFIG_ROCKCHIP_RK3066) += \
+	rk3066a-mk808.dtb
+
 dtb-$(CONFIG_ROCKCHIP_RK3128) += \
 	rk3128-evb.dtb
 
diff --git a/arch/arm/dts/rk3066a-mk808-u-boot.dtsi b/arch/arm/dts/rk3066a-mk808-u-boot.dtsi
new file mode 100644
index 0000000000..3ea5fd9511
--- /dev/null
+++ b/arch/arm/dts/rk3066a-mk808-u-boot.dtsi
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+#include "rk3066a-u-boot.dtsi"
+
+/ {
+	config {
+		u-boot,boot-led = "mk808:blue:power";
+	};
+};
+
+&cru {
+	u-boot,dm-pre-reloc;
+};
+
+&dmc {
+	compatible = "rockchip,rk3066-dmc", "syscon";
+	rockchip,pctl-timing = <0x12c 0xc8 0x1f4 0x1e 0x4e 0x4 0x69 0x6
+				0x3 0x0 0x6 0x5 0xc 0x10 0x6 0x4
+				0x4 0x5 0x4 0x200 0x3 0xa 0x40 0x0
+				0x1 0x5 0x5 0x3 0xc 0x1e 0x100 0x0
+				0x4 0x0>;
+	rockchip,phy-timing = <0x208c6690 0x690878 0x10022a00
+			       0x220 0x40 0x0 0x0>;
+	rockchip,sdram-params = <0x24716310 0 2 300000000 3 9 0>;
+};
+
+&mmc0 {
+	fifo-mode;
+	max-frequency = <4000000>;
+	u-boot,dm-spl;
+};
+
+&mmc1 {
+	status = "disabled";
+};
+
+&noc {
+	compatible = "rockchip,rk3066-noc", "syscon";
+};
+
+&timer2 {
+	clock-frequency = <24000000>;
+	u-boot,dm-pre-reloc;
+};
+
+&uart2 {
+	u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/rk3066a-mk808.dts b/arch/arm/dts/rk3066a-mk808.dts
new file mode 100644
index 0000000000..667d57a4ff
--- /dev/null
+++ b/arch/arm/dts/rk3066a-mk808.dts
@@ -0,0 +1,216 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2016 Paweł Jarosz <paweljarosz3691@gmail.com>
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include "rk3066a.dtsi"
+
+/ {
+	model = "Rikomagic MK808";
+	compatible = "rikomagic,mk808", "rockchip,rk3066a";
+
+	aliases {
+		mmc0 = &mmc0;
+		mmc1 = &mmc1;
+	};
+
+	chosen {
+		stdout-path = "serial2:115200n8";
+	};
+
+	memory@60000000 {
+		reg = <0x60000000 0x40000000>;
+		device_type = "memory";
+	};
+
+	adc-keys {
+		compatible = "adc-keys";
+		io-channels = <&saradc 1>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <2500000>;
+		poll-interval = <100>;
+
+		recovery {
+			label = "recovery";
+			linux,code = <KEY_VENDOR>;
+			press-threshold-microvolt = <0>;
+		};
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+
+		blue_led: led-0 {
+			label = "mk808:blue:power";
+			gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+			linux,default-trigger = "default-on";
+		};
+	};
+
+	hdmi_con {
+		compatible = "hdmi-connector";
+		type = "c";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
+	vcc_2v5: vcc-2v5 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_2v5";
+		regulator-min-microvolt = <2500000>;
+		regulator-max-microvolt = <2500000>;
+	};
+
+	vcc_io: vcc-io {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_io";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	vcc_host: usb-host-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+		pinctrl-0 = <&host_drv>;
+		pinctrl-names = "default";
+		regulator-always-on;
+		regulator-name = "host-pwr";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		startup-delay-us = <100000>;
+		vin-supply = <&vcc_io>;
+	};
+
+	vcc_otg: usb-otg-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
+		pinctrl-0 = <&otg_drv>;
+		pinctrl-names = "default";
+		regulator-always-on;
+		regulator-name = "vcc_otg";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		startup-delay-us = <100000>;
+		vin-supply = <&vcc_io>;
+	};
+
+	vcc_sd: sdmmc-regulator {
+		compatible = "regulator-fixed";
+		gpio = <&gpio3 RK_PA7 GPIO_ACTIVE_LOW>;
+		pinctrl-0 = <&sdmmc_pwr>;
+		pinctrl-names = "default";
+		regulator-name = "vcc_sd";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		startup-delay-us = <100000>;
+		vin-supply = <&vcc_io>;
+	};
+
+	vcc_wifi: sdio-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio3 RK_PD0 GPIO_ACTIVE_HIGH>;
+		pinctrl-0 = <&wifi_pwr>;
+		pinctrl-names = "default";
+		regulator-name = "vcc_wifi";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		startup-delay-us = <100000>;
+		vin-supply = <&vcc_io>;
+	};
+};
+
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_in_vop1 {
+	status = "disabled";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
+&mmc0 {
+	bus-width = <4>;
+	cap-mmc-highspeed;
+	cap-sd-highspeed;
+	vmmc-supply = <&vcc_sd>;
+	status = "okay";
+};
+
+&mmc1 {
+	bus-width = <4>;
+	non-removable;
+	pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_bus4>;
+	pinctrl-names = "default";
+	vmmc-supply = <&vcc_wifi>;
+	status = "okay";
+};
+
+&pinctrl {
+	usb-host {
+		host_drv: host-drv {
+			rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_default>;
+		};
+	};
+
+	usb-otg {
+		otg_drv: otg-drv {
+			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_default>;
+		};
+	};
+
+	sdmmc {
+		sdmmc_pwr: sdmmc-pwr {
+			rockchip,pins = <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_default>;
+		};
+	};
+
+	sdio {
+		wifi_pwr: wifi-pwr {
+			rockchip,pins = <3 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&saradc {
+	vref-supply = <&vcc_2v5>;
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&usb_host {
+	status = "okay";
+};
+
+&usb_otg {
+	status = "okay";
+};
+
+&usbphy {
+	status = "okay";
+};
+
+&vop0 {
+	status = "okay";
+};
+
+&wdt {
+	status = "okay";
+};
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v9 10/16] rockchip: rk3066: add include
  2022-04-04 14:19 [PATCH v9 00/16] Add Rikomagic MK808 board Johan Jonker
                   ` (8 preceding siblings ...)
  2022-04-04 14:19 ` [PATCH v9 09/16] arm: dts: rockchip: add rk3066a-mk808.dts Johan Jonker
@ 2022-04-04 14:19 ` Johan Jonker
  2022-04-04 14:19 ` [PATCH v9 11/16] rockchip: rk3066: add rk3066_common.h include Johan Jonker
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 33+ messages in thread
From: Johan Jonker @ 2022-04-04 14:19 UTC (permalink / raw)
  To: kever.yang; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot

Add include for rk3066.

Signed-off-by: Johan Jonker <jbx6244@gmail.com>
---
 arch/arm/include/asm/arch-rk3066/boot0.h | 8 ++++++++
 arch/arm/include/asm/arch-rk3066/gpio.h  | 8 ++++++++
 arch/arm/include/asm/arch-rk3066/timer.h | 6 ++++++
 3 files changed, 22 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-rk3066/boot0.h
 create mode 100644 arch/arm/include/asm/arch-rk3066/gpio.h
 create mode 100644 arch/arm/include/asm/arch-rk3066/timer.h

diff --git a/arch/arm/include/asm/arch-rk3066/boot0.h b/arch/arm/include/asm/arch-rk3066/boot0.h
new file mode 100644
index 0000000000..28c0fb9a4c
--- /dev/null
+++ b/arch/arm/include/asm/arch-rk3066/boot0.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __ASM_ARCH_BOOT0_H__
+#define __ASM_ARCH_BOOT0_H__
+
+#include <asm/arch-rockchip/boot0.h>
+
+#endif
diff --git a/arch/arm/include/asm/arch-rk3066/gpio.h b/arch/arm/include/asm/arch-rk3066/gpio.h
new file mode 100644
index 0000000000..a4a3b3289c
--- /dev/null
+++ b/arch/arm/include/asm/arch-rk3066/gpio.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __ASM_ARCH_GPIO_H__
+#define __ASM_ARCH_GPIO_H__
+
+#include <asm/arch-rockchip/gpio.h>
+
+#endif
diff --git a/arch/arm/include/asm/arch-rk3066/timer.h b/arch/arm/include/asm/arch-rk3066/timer.h
new file mode 100644
index 0000000000..3bb39428cd
--- /dev/null
+++ b/arch/arm/include/asm/arch-rk3066/timer.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __ASM_ARCH_TIMER_H__
+#define __ASM_ARCH_TIMER_H__
+
+#endif
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v9 11/16] rockchip: rk3066: add rk3066_common.h include
  2022-04-04 14:19 [PATCH v9 00/16] Add Rikomagic MK808 board Johan Jonker
                   ` (9 preceding siblings ...)
  2022-04-04 14:19 ` [PATCH v9 10/16] rockchip: rk3066: add include Johan Jonker
@ 2022-04-04 14:19 ` Johan Jonker
  2022-04-04 14:19 ` [PATCH v9 12/16] rockchip: rk3066: add core support Johan Jonker
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 33+ messages in thread
From: Johan Jonker @ 2022-04-04 14:19 UTC (permalink / raw)
  To: kever.yang; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot

Add rk3066_common.h include.

Signed-off-by: Johan Jonker <jbx6244@gmail.com>
---
 include/configs/mk808.h         |  9 ++++++
 include/configs/rk3066_common.h | 56 +++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)
 create mode 100644 include/configs/mk808.h
 create mode 100644 include/configs/rk3066_common.h

diff --git a/include/configs/mk808.h b/include/configs/mk808.h
new file mode 100644
index 0000000000..e2ab2b512c
--- /dev/null
+++ b/include/configs/mk808.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define ROCKCHIP_DEVICE_SETTINGS
+#include <configs/rk3066_common.h>
+
+#endif
diff --git a/include/configs/rk3066_common.h b/include/configs/rk3066_common.h
new file mode 100644
index 0000000000..b8dc024286
--- /dev/null
+++ b/include/configs/rk3066_common.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2015 Google, Inc
+ */
+
+#ifndef __CONFIG_RK3066_COMMON_H
+#define __CONFIG_RK3066_COMMON_H
+
+#define CONFIG_SYS_CACHELINE_SIZE	64
+
+#include <asm/arch-rockchip/hardware.h>
+#include "rockchip-common.h"
+
+#define CONFIG_SKIP_LOWLEVEL_INIT_ONLY
+#define CONFIG_SYS_CBSIZE		256
+
+#define CONFIG_SYS_INIT_SP_ADDR		0x78000000
+
+#define CONFIG_ROCKCHIP_MAX_INIT_SIZE	(0x10000 - 0xC00)
+
+#define CONFIG_IRAM_BASE		0x10080000
+
+/* spl size max 200k */
+#define CONFIG_SPL_MAX_SIZE		0x32000
+
+#define CONFIG_SPL_STACK		0x1008FFFF
+
+#define CONFIG_SYS_SDRAM_BASE		0x60000000
+#define CONFIG_NR_DRAM_BANKS		1
+#define SDRAM_BANK_SIZE			(1024UL << 20UL)
+#define SDRAM_MAX_SIZE			CONFIG_NR_DRAM_BANKS * SDRAM_BANK_SIZE
+
+#ifndef CONFIG_SPL_BUILD
+/* usb otg */
+
+/* usb host support */
+#define ENV_MEM_LAYOUT_SETTINGS \
+	"scriptaddr=0x60000000\0" \
+	"pxefile_addr_r=0x60100000\0" \
+	"fdt_addr_r=0x61f00000\0" \
+	"kernel_addr_r=0x62000000\0" \
+	"ramdisk_addr_r=0x64000000\0"
+
+#include <config_distro_bootcmd.h>
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"fdt_high=0x6fffffff\0" \
+	"initrd_high=0x6fffffff\0" \
+	"partitions=" PARTS_DEFAULT \
+	ENV_MEM_LAYOUT_SETTINGS \
+	ROCKCHIP_DEVICE_SETTINGS \
+	BOOTENV
+
+#endif /* CONFIG_SPL_BUILD */
+
+#endif
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v9 12/16] rockchip: rk3066: add core support
  2022-04-04 14:19 [PATCH v9 00/16] Add Rikomagic MK808 board Johan Jonker
                   ` (10 preceding siblings ...)
  2022-04-04 14:19 ` [PATCH v9 11/16] rockchip: rk3066: add rk3066_common.h include Johan Jonker
@ 2022-04-04 14:19 ` Johan Jonker
  2022-04-09  3:55   ` Kever Yang
  2022-04-04 14:19 ` [PATCH v9 13/16] rockchip: rk3066: add Rikomagic MK808 board Johan Jonker
                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 33+ messages in thread
From: Johan Jonker @ 2022-04-04 14:19 UTC (permalink / raw)
  To: kever.yang; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot

Add the core architecture code for the rk3066.

Signed-off-by: Johan Jonker <jbx6244@gmail.com>
---
 arch/arm/mach-rockchip/Kconfig                | 23 ++++++++
 arch/arm/mach-rockchip/Makefile               |  1 +
 arch/arm/mach-rockchip/rk3066/Kconfig         | 30 ++++++++++
 arch/arm/mach-rockchip/rk3066/Makefile        |  5 ++
 arch/arm/mach-rockchip/rk3066/clk_rk3066.c    | 33 +++++++++++
 arch/arm/mach-rockchip/rk3066/rk3066.c        | 49 +++++++++++++++++
 arch/arm/mach-rockchip/rk3066/syscon_rk3066.c | 55 +++++++++++++++++++
 7 files changed, 196 insertions(+)
 create mode 100644 arch/arm/mach-rockchip/rk3066/Kconfig
 create mode 100644 arch/arm/mach-rockchip/rk3066/Makefile
 create mode 100644 arch/arm/mach-rockchip/rk3066/clk_rk3066.c
 create mode 100644 arch/arm/mach-rockchip/rk3066/rk3066.c
 create mode 100644 arch/arm/mach-rockchip/rk3066/syscon_rk3066.c

diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 811964973a..18aff5480b 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -35,6 +35,28 @@ config ROCKCHIP_RK3036
 	  and video codec support. Peripherals include Gigabit Ethernet,
 	  USB2 host and OTG, SDIO, I2S, UART, SPI, I2C and PWMs.
 
+config ROCKCHIP_RK3066
+	bool "Support Rockchip RK3066"
+	select CPU_V7A
+	select SPL_BOARD_INIT if SPL
+	select SUPPORT_SPL
+	select SUPPORT_TPL
+	select SPL
+	select TPL
+	select TPL_ROCKCHIP_BACK_TO_BROM
+	select TPL_ROCKCHIP_EARLYRETURN_TO_BROM
+	imply ROCKCHIP_COMMON_BOARD
+	imply SPL_ROCKCHIP_COMMON_BOARD
+	imply SPL_SERIAL
+	imply TPL_ROCKCHIP_COMMON_BOARD
+	imply TPL_SERIAL
+	help
+	  The Rockchip RK3066 is a ARM-based SoC with a dual-core Cortex-A9
+	  including NEON and GPU, 512KB L2 cache, Mali-400 graphics, two
+	  video interfaces, several memory options and video codec support.
+	  Peripherals include Fast Ethernet, USB2 host and OTG, SDIO, I2S,
+	  UART, SPI, I2C and PWMs.
+
 config ROCKCHIP_RK3128
 	bool "Support Rockchip RK3128"
 	select CPU_V7A
@@ -405,6 +427,7 @@ config LNX_KRNL_IMG_TEXT_OFFSET_BASE
 
 source "arch/arm/mach-rockchip/px30/Kconfig"
 source "arch/arm/mach-rockchip/rk3036/Kconfig"
+source "arch/arm/mach-rockchip/rk3066/Kconfig"
 source "arch/arm/mach-rockchip/rk3128/Kconfig"
 source "arch/arm/mach-rockchip/rk3188/Kconfig"
 source "arch/arm/mach-rockchip/rk322x/Kconfig"
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 00aef0ecee..6c1c7b8a10 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_$(SPL_TPL_)RAM) += sdram.o
 
 obj-$(CONFIG_ROCKCHIP_PX30) += px30/
 obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/
+obj-$(CONFIG_ROCKCHIP_RK3066) += rk3066/
 obj-$(CONFIG_ROCKCHIP_RK3128) += rk3128/
 obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188/
 obj-$(CONFIG_ROCKCHIP_RK322X) += rk322x/
diff --git a/arch/arm/mach-rockchip/rk3066/Kconfig b/arch/arm/mach-rockchip/rk3066/Kconfig
new file mode 100644
index 0000000000..335f49bc55
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3066/Kconfig
@@ -0,0 +1,30 @@
+if ROCKCHIP_RK3066
+
+config ROCKCHIP_BOOT_MODE_REG
+	default 0x20004040
+
+config SYS_SOC
+	default "rk3066"
+
+config SYS_MALLOC_F_LEN
+	default 0x0800
+
+config SPL_LIBCOMMON_SUPPORT
+	default y
+
+config SPL_LIBGENERIC_SUPPORT
+	default y
+
+config SPL_SERIAL
+	default y
+
+config TPL_LIBCOMMON_SUPPORT
+	default y
+
+config TPL_LIBGENERIC_SUPPORT
+	default y
+
+config TPL_SERIAL
+	default y
+
+endif
diff --git a/arch/arm/mach-rockchip/rk3066/Makefile b/arch/arm/mach-rockchip/rk3066/Makefile
new file mode 100644
index 0000000000..9e2a9d4b0a
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3066/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y += clk_rk3066.o
+obj-y += rk3066.o
+obj-y += syscon_rk3066.o
diff --git a/arch/arm/mach-rockchip/rk3066/clk_rk3066.c b/arch/arm/mach-rockchip/rk3066/clk_rk3066.c
new file mode 100644
index 0000000000..c47526dca5
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3066/clk_rk3066.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3066.h>
+#include <linux/err.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+	return uclass_get_device_by_driver(UCLASS_CLK,
+			DM_DRIVER_GET(rockchip_rk3066a_cru), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+	struct rk3066_clk_priv *priv;
+	struct udevice *dev;
+	int ret;
+
+	ret = rockchip_get_clk(&dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	priv = dev_get_priv(dev);
+
+	return priv->cru;
+}
diff --git a/arch/arm/mach-rockchip/rk3066/rk3066.c b/arch/arm/mach-rockchip/rk3066/rk3066.c
new file mode 100644
index 0000000000..78c7d894f9
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3066/rk3066.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/bootrom.h>
+#include <asm/arch-rockchip/grf_rk3066.h>
+
+#define GRF_BASE	0x20008000
+
+const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+	[BROM_BOOTSOURCE_EMMC] = "/mmc@1021c000",
+	[BROM_BOOTSOURCE_SD] = "/mmc@10214000",
+};
+
+void board_debug_uart_init(void)
+{
+	struct rk3066_grf * const grf = (void *)GRF_BASE;
+
+	/* Enable early UART on the RK3066 */
+	rk_clrsetreg(&grf->gpio1b_iomux,
+		     GPIO1B1_MASK | GPIO1B0_MASK,
+		     GPIO1B1_UART2_SOUT << GPIO1B1_SHIFT |
+		     GPIO1B0_UART2_SIN << GPIO1B0_SHIFT);
+}
+
+void spl_board_init(void)
+{
+	if (!IS_ENABLED(CONFIG_SPL_BUILD))
+		return;
+
+	if (IS_ENABLED(CONFIG_SPL_DM_MMC)) {
+		struct rk3066_grf * const grf = (void *)GRF_BASE;
+
+		rk_clrsetreg(&grf->gpio3b_iomux,
+			     GPIO3B0_MASK | GPIO3B1_MASK | GPIO3B2_MASK |
+			     GPIO3B3_MASK | GPIO3B4_MASK | GPIO3B5_MASK |
+			     GPIO3B6_MASK,
+			     GPIO3B0_SDMMC0_CLKOUT << GPIO3B0_SHIFT |
+			     GPIO3B1_SDMMC0_CMD    << GPIO3B1_SHIFT |
+			     GPIO3B2_SDMMC0_DATA0  << GPIO3B2_SHIFT |
+			     GPIO3B3_SDMMC0_DATA1  << GPIO3B3_SHIFT |
+			     GPIO3B4_SDMMC0_DATA2  << GPIO3B4_SHIFT |
+			     GPIO3B5_SDMMC0_DATA3  << GPIO3B5_SHIFT |
+			     GPIO3B6_SDMMC0_DECTN  << GPIO3B6_SHIFT);
+	}
+}
diff --git a/arch/arm/mach-rockchip/rk3066/syscon_rk3066.c b/arch/arm/mach-rockchip/rk3066/syscon_rk3066.c
new file mode 100644
index 0000000000..a598f6400d
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3066/syscon_rk3066.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+
+static const struct udevice_id rk3066_syscon_ids[] = {
+	{ .compatible = "rockchip,rk3066-noc", .data = ROCKCHIP_SYSCON_NOC },
+	{ .compatible = "rockchip,rk3066-grf", .data = ROCKCHIP_SYSCON_GRF },
+	{ .compatible = "rockchip,rk3066-pmu", .data = ROCKCHIP_SYSCON_PMU },
+	{ }
+};
+
+U_BOOT_DRIVER(syscon_rk3066) = {
+	.name = "rk3066_syscon",
+	.id = UCLASS_SYSCON,
+	.of_match = rk3066_syscon_ids,
+};
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+static int rk3066_syscon_bind_of_plat(struct udevice *dev)
+{
+	dev->driver_data = dev->driver->of_match->data;
+	debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
+
+	return 0;
+}
+
+U_BOOT_DRIVER(rockchip_rk3066_noc) = {
+	.name = "rockchip_rk3066_noc",
+	.id = UCLASS_SYSCON,
+	.of_match = rk3066_syscon_ids,
+	.bind = rk3066_syscon_bind_of_plat,
+};
+
+U_BOOT_DRIVER(rockchip_rk3066_grf) = {
+	.name = "rockchip_rk3066_grf",
+	.id = UCLASS_SYSCON,
+	.of_match = rk3066_syscon_ids + 1,
+	.bind = rk3066_syscon_bind_of_plat,
+};
+
+U_BOOT_DRIVER(rockchip_rk3066_pmu) = {
+	.name = "rockchip_rk3066_pmu",
+	.id = UCLASS_SYSCON,
+	.of_match = rk3066_syscon_ids + 2,
+	.bind = rk3066_syscon_bind_of_plat,
+};
+#endif
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v9 13/16] rockchip: rk3066: add Rikomagic MK808 board
  2022-04-04 14:19 [PATCH v9 00/16] Add Rikomagic MK808 board Johan Jonker
                   ` (11 preceding siblings ...)
  2022-04-04 14:19 ` [PATCH v9 12/16] rockchip: rk3066: add core support Johan Jonker
@ 2022-04-04 14:19 ` Johan Jonker
  2022-04-09  3:57   ` Kever Yang
  2022-04-04 14:19 ` [PATCH v9 14/16] rockchip: rk3066: add mk808_defconfig Johan Jonker
                   ` (2 subsequent siblings)
  15 siblings, 1 reply; 33+ messages in thread
From: Johan Jonker @ 2022-04-04 14:19 UTC (permalink / raw)
  To: kever.yang; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot

MK808 is a RK3066-based board with 1 USB host and 1 USB OTG port,
HDMI and a micro-SD card slot. It also includes on-board NAND
and 1GB of SDRAM.

Signed-off-by: Johan Jonker <jbx6244@gmail.com>
---
 arch/arm/mach-rockchip/rk3066/Kconfig |  9 +++++++++
 board/rikomagic/mk808/Kconfig         | 15 +++++++++++++++
 board/rikomagic/mk808/MAINTAINERS     |  6 ++++++
 board/rikomagic/mk808/Makefile        |  3 +++
 board/rikomagic/mk808/mk808.c         |  3 +++
 5 files changed, 36 insertions(+)
 create mode 100644 board/rikomagic/mk808/Kconfig
 create mode 100644 board/rikomagic/mk808/MAINTAINERS
 create mode 100644 board/rikomagic/mk808/Makefile
 create mode 100644 board/rikomagic/mk808/mk808.c

diff --git a/arch/arm/mach-rockchip/rk3066/Kconfig b/arch/arm/mach-rockchip/rk3066/Kconfig
index 335f49bc55..95d7fc8a29 100644
--- a/arch/arm/mach-rockchip/rk3066/Kconfig
+++ b/arch/arm/mach-rockchip/rk3066/Kconfig
@@ -1,5 +1,12 @@
 if ROCKCHIP_RK3066
 
+config TARGET_MK808
+	bool "MK808"
+	help
+	  MK808 is a RK3066-based board with 1 USB host and 1 USB OTG port,
+	  HDMI and a micro-SD card slot. It also includes on-board NAND
+	  and 1GB of SDRAM.
+
 config ROCKCHIP_BOOT_MODE_REG
 	default 0x20004040
 
@@ -27,4 +34,6 @@ config TPL_LIBGENERIC_SUPPORT
 config TPL_SERIAL
 	default y
 
+source "board/rikomagic/mk808/Kconfig"
+
 endif
diff --git a/board/rikomagic/mk808/Kconfig b/board/rikomagic/mk808/Kconfig
new file mode 100644
index 0000000000..4abad7e750
--- /dev/null
+++ b/board/rikomagic/mk808/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_MK808
+
+config SYS_BOARD
+	default "mk808"
+
+config SYS_VENDOR
+	default "rikomagic"
+
+config SYS_CONFIG_NAME
+	default "mk808"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+	def_bool y
+
+endif
diff --git a/board/rikomagic/mk808/MAINTAINERS b/board/rikomagic/mk808/MAINTAINERS
new file mode 100644
index 0000000000..b3ef6adb91
--- /dev/null
+++ b/board/rikomagic/mk808/MAINTAINERS
@@ -0,0 +1,6 @@
+MK808
+M:	Johan Jonker <jbx6244@gmail.com>
+S:	Maintained
+F:	board/rikomagic/mk808
+F:	configs/mk808_defconfig
+F:	include/configs/mk808.h
diff --git a/board/rikomagic/mk808/Makefile b/board/rikomagic/mk808/Makefile
new file mode 100644
index 0000000000..a4d16884df
--- /dev/null
+++ b/board/rikomagic/mk808/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y	+= mk808.o
diff --git a/board/rikomagic/mk808/mk808.c b/board/rikomagic/mk808/mk808.c
new file mode 100644
index 0000000000..e0bfc6f331
--- /dev/null
+++ b/board/rikomagic/mk808/mk808.c
@@ -0,0 +1,3 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <common.h>
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v9 14/16] rockchip: rk3066: add mk808_defconfig
  2022-04-04 14:19 [PATCH v9 00/16] Add Rikomagic MK808 board Johan Jonker
                   ` (12 preceding siblings ...)
  2022-04-04 14:19 ` [PATCH v9 13/16] rockchip: rk3066: add Rikomagic MK808 board Johan Jonker
@ 2022-04-04 14:19 ` Johan Jonker
  2022-04-09  3:57   ` Kever Yang
  2022-04-04 14:19 ` [PATCH v9 15/16] rockchip: tools: add rk3066 support to rkcommon.c Johan Jonker
  2022-04-04 14:19 ` [PATCH v9 16/16] doc: rockchip: add rk3066 Rikomagic MK808 Johan Jonker
  15 siblings, 1 reply; 33+ messages in thread
From: Johan Jonker @ 2022-04-04 14:19 UTC (permalink / raw)
  To: kever.yang; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot

This commit adds the default configuration file and
relevant description for a MK808 board.

Signed-off-by: Johan Jonker <jbx6244@gmail.com>
---

changed V9:
  enable led gpio
  disable STIMER

Changed V8:
  use default log level
  ENV_IS_NOWHERE
---
 configs/mk808_defconfig | 100 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 100 insertions(+)
 create mode 100644 configs/mk808_defconfig

diff --git a/configs/mk808_defconfig b/configs/mk808_defconfig
new file mode 100644
index 0000000000..b475e73540
--- /dev/null
+++ b/configs/mk808_defconfig
@@ -0,0 +1,100 @@
+CONFIG_ARM=y
+# CONFIG_SPL_SYS_THUMB_BUILD is not set
+# CONFIG_TPL_SYS_THUMB_BUILD is not set
+# CONFIG_SPL_USE_ARCH_MEMCPY is not set
+# CONFIG_SPL_USE_ARCH_MEMSET is not set
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_SYS_TEXT_BASE=0x60408000
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x8000
+CONFIG_DEFAULT_DEVICE_TREE="rk3066a-mk808"
+CONFIG_SPL_TEXT_BASE=0x60000000
+CONFIG_ROCKCHIP_RK3066=y
+# CONFIG_ROCKCHIP_STIMER is not set
+CONFIG_TPL_TEXT_BASE=0x10080C04
+CONFIG_TPL_MAX_SIZE=32764
+CONFIG_TPL_STACK=0x1008FFFF
+CONFIG_TARGET_MK808=y
+CONFIG_SPL_STACK_R_ADDR=0x70000000
+CONFIG_DEBUG_UART_BASE=0x20064000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_SPL_FS_FAT=y
+CONFIG_SYS_LOAD_ADDR=0x70800800
+CONFIG_SPL_PAYLOAD="u-boot.bin"
+CONFIG_DEBUG_UART=y
+CONFIG_SD_BOOT=y
+CONFIG_USE_PREBOOT=y
+CONFIG_DEFAULT_FDT_FILE="rk3066a-mk808.dtb"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_BOARD_LATE_INIT=y
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x200000
+CONFIG_SPL_SEPARATE_BSS=y
+CONFIG_SPL_FS_EXT4=y
+CONFIG_SYS_MMCSD_FS_BOOT_PARTITION=2
+CONFIG_TPL_NEEDS_SEPARATE_STACK=y
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+CONFIG_CMD_GPT=y
+CONFIG_CMD_MMC=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_TPL_OF_CONTROL=y
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_OF_DTB_PROPS_REMOVE=y
+CONFIG_SPL_OF_PLATDATA=y
+CONFIG_TPL_OF_PLATDATA=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+# CONFIG_NET is not set
+CONFIG_TPL_DM=y
+# CONFIG_DM_WARN is not set
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_TPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_TPL_SYSCON=y
+# CONFIG_SIMPLE_BUS is not set
+# CONFIG_SPL_SIMPLE_BUS is not set
+# CONFIG_TPL_BLK is not set
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_TPL_CLK=y
+CONFIG_ROCKCHIP_GPIO=y
+# CONFIG_SPL_DM_I2C is not set
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_MMC_IO_VOLTAGE=y
+CONFIG_SPL_MMC_IO_VOLTAGE=y
+CONFIG_MMC_UHS_SUPPORT=y
+CONFIG_SPL_MMC_UHS_SUPPORT=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_SF_DEFAULT_SPEED=20000000
+CONFIG_PINCTRL=y
+CONFIG_DM_PMIC=y
+# CONFIG_SPL_PMIC_CHILDREN is not set
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_RAM=y
+CONFIG_SPL_RAM=y
+CONFIG_TPL_RAM=y
+CONFIG_DM_RESET=y
+# CONFIG_REQUIRE_SERIAL_CONSOLE is not set
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_ROCKCHIP_SERIAL=y
+CONFIG_SYSRESET=y
+CONFIG_TIMER=y
+CONFIG_SPL_TIMER=y
+CONFIG_TPL_TIMER=y
+CONFIG_DESIGNWARE_APB_TIMER=y
+CONFIG_SPL_TINY_MEMSET=y
+CONFIG_ERRNO_STR=y
+# CONFIG_TPL_OF_LIBFDT is not set
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v9 15/16] rockchip: tools: add rk3066 support to rkcommon.c
  2022-04-04 14:19 [PATCH v9 00/16] Add Rikomagic MK808 board Johan Jonker
                   ` (13 preceding siblings ...)
  2022-04-04 14:19 ` [PATCH v9 14/16] rockchip: rk3066: add mk808_defconfig Johan Jonker
@ 2022-04-04 14:19 ` Johan Jonker
  2022-04-09  3:56   ` Kever Yang
  2022-04-04 14:19 ` [PATCH v9 16/16] doc: rockchip: add rk3066 Rikomagic MK808 Johan Jonker
  15 siblings, 1 reply; 33+ messages in thread
From: Johan Jonker @ 2022-04-04 14:19 UTC (permalink / raw)
  To: kever.yang; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot

Add rk3066 support to rkcommon.c

Signed-off-by: Johan Jonker <jbx6244@gmail.com>
---
 tools/rkcommon.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/rkcommon.c b/tools/rkcommon.c
index 29f2676c19..860785f839 100644
--- a/tools/rkcommon.c
+++ b/tools/rkcommon.c
@@ -123,6 +123,7 @@ struct spl_info {
 static struct spl_info spl_infos[] = {
 	{ "px30", "RK33", 0x2800, false, RK_HEADER_V1 },
 	{ "rk3036", "RK30", 0x1000, false, RK_HEADER_V1 },
+	{ "rk3066", "RK30", 0x8000 - 0x800, true, RK_HEADER_V1 },
 	{ "rk3128", "RK31", 0x1800, false, RK_HEADER_V1 },
 	{ "rk3188", "RK31", 0x8000 - 0x800, true, RK_HEADER_V1 },
 	{ "rk322x", "RK32", 0x8000 - 0x1000, false, RK_HEADER_V1 },
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v9 16/16] doc: rockchip: add rk3066 Rikomagic MK808
  2022-04-04 14:19 [PATCH v9 00/16] Add Rikomagic MK808 board Johan Jonker
                   ` (14 preceding siblings ...)
  2022-04-04 14:19 ` [PATCH v9 15/16] rockchip: tools: add rk3066 support to rkcommon.c Johan Jonker
@ 2022-04-04 14:19 ` Johan Jonker
  2022-04-09  4:00   ` Kever Yang
  15 siblings, 1 reply; 33+ messages in thread
From: Johan Jonker @ 2022-04-04 14:19 UTC (permalink / raw)
  To: kever.yang; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot

Add rk3066 Rikomagic MK808 to the list of
mainline supported Rockchip boards.

Signed-off-by: Johan Jonker <jbx6244@gmail.com>
---
 doc/board/rockchip/rockchip.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/doc/board/rockchip/rockchip.rst b/doc/board/rockchip/rockchip.rst
index a75e60b9fa..ed2792d414 100644
--- a/doc/board/rockchip/rockchip.rst
+++ b/doc/board/rockchip/rockchip.rst
@@ -24,6 +24,8 @@ List of mainline supported Rockchip boards:
 * rk3036
      - Rockchip Evb-RK3036 (evb-rk3036)
      - Kylin (kylin_rk3036)
+* rk3066
+     - Rikomagic MK808 (mk808)
 * rk3128
      - Rockchip Evb-RK3128 (evb-rk3128)
 * rk3188
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* Re: [PATCH v9 01/16] rockchip: rk3066-power: sync power domain dt-binding header from Linux
  2022-04-04 14:19 ` [PATCH v9 01/16] rockchip: rk3066-power: sync power domain dt-binding header from Linux Johan Jonker
@ 2022-04-06 15:01   ` Kever Yang
  0 siblings, 0 replies; 33+ messages in thread
From: Kever Yang @ 2022-04-06 15:01 UTC (permalink / raw)
  To: Johan Jonker; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot


On 2022/4/4 22:19, Johan Jonker wrote:
> In order to update the DT for rk3066
> sync the power domain dt-binding header.
> This is the state as of v5.12 in Linux.
>
> Signed-off-by: Johan Jonker <jbx6244@gmail.com>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>

Thanks,
- Kever
> ---
>   include/dt-bindings/power/rk3066-power.h | 22 ++++++++++++++++++++++
>   1 file changed, 22 insertions(+)
>   create mode 100644 include/dt-bindings/power/rk3066-power.h
>
> diff --git a/include/dt-bindings/power/rk3066-power.h b/include/dt-bindings/power/rk3066-power.h
> new file mode 100644
> index 0000000000..acf9f310ac
> --- /dev/null
> +++ b/include/dt-bindings/power/rk3066-power.h
> @@ -0,0 +1,22 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __DT_BINDINGS_POWER_RK3066_POWER_H__
> +#define __DT_BINDINGS_POWER_RK3066_POWER_H__
> +
> +/* VD_CORE */
> +#define RK3066_PD_A9_0		0
> +#define RK3066_PD_A9_1		1
> +#define RK3066_PD_DBG		4
> +#define RK3066_PD_SCU		5
> +
> +/* VD_LOGIC */
> +#define RK3066_PD_VIDEO		6
> +#define RK3066_PD_VIO		7
> +#define RK3066_PD_GPU		8
> +#define RK3066_PD_PERI		9
> +#define RK3066_PD_CPU		10
> +#define RK3066_PD_ALIVE		11
> +
> +/* VD_PMU */
> +#define RK3066_PD_RTC		12
> +
> +#endif

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v9 02/16] rockchip: rk3066: add grf header file
  2022-04-04 14:19 ` [PATCH v9 02/16] rockchip: rk3066: add grf header file Johan Jonker
@ 2022-04-09  3:49   ` Kever Yang
  0 siblings, 0 replies; 33+ messages in thread
From: Kever Yang @ 2022-04-09  3:49 UTC (permalink / raw)
  To: Johan Jonker; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot


On 2022/4/4 22:19, Johan Jonker wrote:
> From: Paweł Jarosz <paweljarosz3691@gmail.com>
>
> grf is needed by various drivers for rk3066 soc.
>
> Signed-off-by: Paweł Jarosz <paweljarosz3691@gmail.com>
> Signed-off-by: Johan Jonker <jbx6244@gmail.com>

Reviewed-by: Kever Yang <kever.yang@rock-chips.com>

Thanks,
- Kever
> ---
>
> Changed V9:
>    fix TAB
>
> Changed V8:
>    add GRF_GPIO3B_IOMUX for SDMMC0
>    use GENMASK, __bf_shf and REG defines
>    add includes
> ---
>   .../include/asm/arch-rockchip/grf_rk3066.h    | 210 ++++++++++++++++++
>   1 file changed, 210 insertions(+)
>   create mode 100644 arch/arm/include/asm/arch-rockchip/grf_rk3066.h
>
> diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3066.h b/arch/arm/include/asm/arch-rockchip/grf_rk3066.h
> new file mode 100644
> index 0000000000..d8e0812cee
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-rockchip/grf_rk3066.h
> @@ -0,0 +1,210 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2021 Paweł Jarosz <paweljarosz3691@gmail.com>
> + */
> +
> +#ifndef _ASM_ARCH_GRF_RK3066_H
> +#define _ASM_ARCH_GRF_RK3066_H
> +
> +#include <linux/bitops.h>
> +#include <linux/bitfield.h>
> +
> +#define REG(name, h, l) \
> +	name##_MASK = GENMASK(h, l), \
> +	name##_SHIFT = __bf_shf(name##_MASK)
> +
> +struct rk3066_grf_gpio_lh {
> +	u32 l;
> +	u32 h;
> +};
> +
> +struct rk3066_grf {
> +	struct rk3066_grf_gpio_lh gpio_dir[7];
> +	struct rk3066_grf_gpio_lh gpio_do[7];
> +	struct rk3066_grf_gpio_lh gpio_en[7];
> +
> +	u32 gpio0a_iomux;
> +	u32 gpio0b_iomux;
> +	u32 gpio0c_iomux;
> +	u32 gpio0d_iomux;
> +
> +	u32 gpio1a_iomux;
> +	u32 gpio1b_iomux;
> +	u32 gpio1c_iomux;
> +	u32 gpio1d_iomux;
> +
> +	u32 gpio2a_iomux;
> +	u32 gpio2b_iomux;
> +	u32 gpio2c_iomux;
> +	u32 gpio2d_iomux;
> +
> +	u32 gpio3a_iomux;
> +	u32 gpio3b_iomux;
> +	u32 gpio3c_iomux;
> +	u32 gpio3d_iomux;
> +
> +	u32 gpio4a_iomux;
> +	u32 gpio4b_iomux;
> +	u32 gpio4c_iomux;
> +	u32 gpio4d_iomux;
> +
> +	u32 reserved0[5];
> +
> +	u32 gpio6b_iomux;
> +
> +	u32 reserved1[2];
> +
> +	struct rk3066_grf_gpio_lh gpio_pull[7];
> +
> +	u32 soc_con0;
> +	u32 soc_con1;
> +	u32 soc_con2;
> +
> +	u32 soc_status0;
> +
> +	u32 dmac1_con[3];
> +	u32 dmac2_con[4];
> +
> +	u32 uoc0_con[3];
> +	u32 uoc1_con[4];
> +	u32 ddrc_con;
> +	u32 ddrc_stat;
> +
> +	u32 reserved2[10];
> +
> +	u32 os_reg[4];
> +};
> +
> +check_member(rk3066_grf, os_reg[3], 0x01d4);
> +
> +/* GRF_GPIO1B_IOMUX */
> +enum {
> +	REG(GPIO1B1, 2, 2),
> +	GPIO1B1_GPIO		= 0,
> +	GPIO1B1_UART2_SOUT,
> +
> +	REG(GPIO1B0, 0, 0),
> +	GPIO1B0_GPIO		= 0,
> +	GPIO1B0_UART2_SIN
> +};
> +
> +/* GRF_GPIO3B_IOMUX */
> +enum {
> +	REG(GPIO3B6, 12, 12),
> +	GPIO3B6_GPIO		= 0,
> +	GPIO3B6_SDMMC0_DECTN,
> +
> +	REG(GPIO3B5, 10, 10),
> +	GPIO3B5_GPIO		= 0,
> +	GPIO3B5_SDMMC0_DATA3,
> +
> +	REG(GPIO3B4, 8, 8),
> +	GPIO3B4_GPIO		= 0,
> +	GPIO3B4_SDMMC0_DATA2,
> +
> +	REG(GPIO3B3, 6, 6),
> +	GPIO3B3_GPIO		= 0,
> +	GPIO3B3_SDMMC0_DATA1,
> +
> +	REG(GPIO3B2, 4, 4),
> +	GPIO3B2_GPIO		= 0,
> +	GPIO3B2_SDMMC0_DATA0,
> +
> +	REG(GPIO3B1, 2, 2),
> +	GPIO3B1_GPIO		= 0,
> +	GPIO3B1_SDMMC0_CMD,
> +
> +	REG(GPIO3B0, 0, 0),
> +	GPIO3B0_GPIO		= 0,
> +	GPIO3B0_SDMMC0_CLKOUT,
> +};
> +
> +/* GRF_SOC_CON0 */
> +enum {
> +	REG(SMC_MUX_CON, 13, 13),
> +
> +	REG(NOC_REMAP, 12, 12),
> +
> +	REG(EMMC_FLASH_SEL, 11, 11),
> +
> +	REG(TZPC_REVISION, 10, 7),
> +
> +	REG(L2CACHE_ACC, 6, 5),
> +
> +	REG(L2RD_WAIT, 4, 3),
> +
> +	REG(IMEMRD_WAIT, 2, 1),
> +
> +	REG(SOC_REMAP, 0, 0),
> +};
> +
> +/* GRF_SOC_CON1 */
> +enum {
> +	REG(RKI2C4_SEL, 15, 15),
> +
> +	REG(RKI2C3_SEL, 14, 14),
> +
> +	REG(RKI2C2_SEL, 13, 13),
> +
> +	REG(RKI2C1_SEL, 12, 12),
> +
> +	REG(RKI2C0_SEL, 11, 11),
> +
> +	REG(VCODEC_SEL, 10, 10),
> +
> +	REG(PERI_EMEM_PAUSE, 9, 9),
> +
> +	REG(PERI_USB_PAUSE, 8, 8),
> +
> +	REG(SMC_MUX_MODE_0, 6, 6),
> +
> +	REG(SMC_SRAM_MW_0, 5, 4),
> +
> +	REG(SMC_REMAP_0, 3, 3),
> +
> +	REG(SMC_A_GT_M0_SYNC, 2, 2),
> +
> +	REG(EMAC_SPEED, 1, 1),
> +
> +	REG(EMAC_MODE, 0, 0),
> +};
> +
> +/* GRF_SOC_CON2 */
> +enum {
> +	REG(MSCH4_MAINDDR3, 7, 7),
> +	MSCH4_MAINDDR3_DDR3	= 1,
> +
> +	REG(EMAC_NEWRCV_EN, 6, 6),
> +
> +	REG(SW_ADDR15_EN, 5, 5),
> +
> +	REG(SW_ADDR16_EN, 4, 4),
> +
> +	REG(SW_ADDR17_EN, 3, 3),
> +
> +	REG(BANK2_TO_RANK_EN, 2, 2),
> +
> +	REG(RANK_TO_ROW15_EN, 1, 1),
> +
> +	REG(UPCTL_C_ACTIVE_IN, 0, 0),
> +	UPCTL_C_ACTIVE_IN_MAY	= 0,
> +	UPCTL_C_ACTIVE_IN_WILL,
> +};
> +
> +/* GRF_DDRC_CON0 */
> +enum {
> +	REG(DTO_LB, 12, 11),
> +
> +	REG(DTO_TE, 10, 9),
> +
> +	REG(DTO_PDR, 8, 7),
> +
> +	REG(DTO_PDD, 6, 5),
> +
> +	REG(DTO_IOM, 4, 3),
> +
> +	REG(DTO_OE, 2, 1),
> +
> +	REG(ATO_AE, 0, 0),
> +};
> +#endif

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v9 03/16] rockchip: rk3066: add clock driver for rk3066 soc
  2022-04-04 14:19 ` [PATCH v9 03/16] rockchip: rk3066: add clock driver for rk3066 soc Johan Jonker
@ 2022-04-09  3:49   ` Kever Yang
  0 siblings, 0 replies; 33+ messages in thread
From: Kever Yang @ 2022-04-09  3:49 UTC (permalink / raw)
  To: Johan Jonker; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot


On 2022/4/4 22:19, Johan Jonker wrote:
> From: Paweł Jarosz <paweljarosz3691@gmail.com>
>
> Add the clock driver for the rk3066 platform.
>
> Derived from the rk3288 and rk3188 driver it
> supports only a bare minimum to bring up the system
> to reduce the TPL size for:
>    SDRAM clock configuration.
>    The boot devices NAND, EMMC, SDMMC, SPI.
>    A UART for the debug messages (fixed) at 115200n8.
>    A SARADC for the recovery button.
>    A TIMER for the delays (fixed).
>
> There's support for two possible frequencies,
> the safe 600MHz which will work with default pmic settings and
> will be set to get away from the 24MHz default and
> the maximum of 1.416Ghz, which boards can set if they
> were able to get pmic support for it.
>
> After the clock tree is set during the TPL probe
> there's no parent update support.
>
> In OF_REAL mode the drivers ns16550.c and dw-apb-timer.c
> obtain the (fixed) clk_get_rate from the clock driver
> instead of platdata.
>
> The rk3066 cru node has a number of assigned-clocks properties
> that call the .set_rate() function. Add them to the list so that
> they return a 0 instead of -ENOENT.
>
> Signed-off-by: Paweł Jarosz <paweljarosz3691@gmail.com>
> Signed-off-by: Johan Jonker <jbx6244@gmail.com>
> Reviewed-by: Sean Anderson <seanga2@gmail.com>

Reviewed-by: Kever Yang <kever.yang@rock-chips.com>

Thanks,
- Kever
> ---
>
> Changed V9:
>    fix TAB
>    fix space
>
> Changed V8:
>    add SCLK_TIMER[0..2]
>    add SCLK_UART[0..3]
>    fix assigned-clocks
>    use GENMASK, __bf_shf and REG defines
>    fix clk defines
>    add includes
>    fix bit position CRU_CLKSEL0_CON rk3066 vs rk3188
>    fix comments
>    rename PLL_MODE defines
>    use dev_bind
>    use dev_dbg
>    use a different variable name
>
> Changed V7:
>    changed function prefix
>    changed #if where possible
>    restyle U_BOOT_DRIVER structure
> ---
>   .../include/asm/arch-rockchip/cru_rk3066.h    | 157 ++++
>   drivers/clk/rockchip/Makefile                 |   1 +
>   drivers/clk/rockchip/clk_rk3066.c             | 717 ++++++++++++++++++
>   3 files changed, 875 insertions(+)
>   create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rk3066.h
>   create mode 100644 drivers/clk/rockchip/clk_rk3066.c
>
> diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3066.h b/arch/arm/include/asm/arch-rockchip/cru_rk3066.h
> new file mode 100644
> index 0000000000..76a715a8e6
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-rockchip/cru_rk3066.h
> @@ -0,0 +1,157 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * (C) Copyright 2021 Paweł Jarosz <paweljarosz3691@gmail.com>
> + */
> +
> +#ifndef _ASM_ARCH_CRU_RK3066_H
> +#define _ASM_ARCH_CRU_RK3066_H
> +
> +#include <linux/bitops.h>
> +#include <linux/bitfield.h>
> +
> +#define REG(name, h, l) \
> +	name##_MASK = GENMASK(h, l), \
> +	name##_SHIFT = __bf_shf(name##_MASK)
> +
> +#define OSC_HZ		(24 * 1000 * 1000)
> +
> +#define APLL_HZ		(1416 * 1000000)
> +#define APLL_SAFE_HZ	(600 * 1000000)
> +#define GPLL_HZ		(594 * 1000000)
> +#define CPLL_HZ		(384 * 1000000)
> +
> +/* The SRAM is clocked off aclk_cpu, so we want to max it out for boot speed */
> +#define CPU_ACLK_HZ	297000000
> +#define CPU_HCLK_HZ	148500000
> +#define CPU_PCLK_HZ	74250000
> +#define CPU_H2P_HZ	74250000
> +
> +#define PERI_ACLK_HZ	148500000
> +#define PERI_HCLK_HZ	148500000
> +#define PERI_PCLK_HZ	74250000
> +
> +/* Private data for the clock driver - used by rockchip_get_cru() */
> +struct rk3066_clk_priv {
> +	struct rk3066_grf *grf;
> +	struct rk3066_cru *cru;
> +	ulong rate;
> +	bool has_bwadj;
> +};
> +
> +struct rk3066_cru {
> +	struct rk3066_pll {
> +		u32 con0;
> +		u32 con1;
> +		u32 con2;
> +		u32 con3;
> +	} pll[4];
> +	u32 cru_mode_con;
> +	u32 cru_clksel_con[35];
> +	u32 cru_clkgate_con[10];
> +	u32 reserved1[2];
> +	u32 cru_glb_srst_fst_value;
> +	u32 cru_glb_srst_snd_value;
> +	u32 reserved2[2];
> +	u32 cru_softrst_con[9];
> +	u32 cru_misc_con;
> +	u32 reserved3[2];
> +	u32 cru_glb_cnt_th;
> +};
> +
> +check_member(rk3066_cru, cru_glb_cnt_th, 0x0140);
> +
> +/* CRU_CLKSEL0_CON */
> +enum {
> +	REG(CPU_ACLK_PLL, 8, 8),
> +	CPU_ACLK_PLL_SELECT_APLL	= 0,
> +	CPU_ACLK_PLL_SELECT_GPLL,
> +
> +	REG(CORE_PERI_DIV, 7, 6),
> +
> +	REG(A9_CORE_DIV, 4, 0),
> +};
> +
> +/* CRU_CLKSEL1_CON */
> +enum {
> +	REG(AHB2APB_DIV, 15, 14),
> +
> +	REG(CPU_PCLK_DIV, 13, 12),
> +
> +	REG(CPU_HCLK_DIV, 9, 8),
> +
> +	REG(CPU_ACLK_DIV, 2, 0),
> +};
> +
> +/* CRU_CLKSEL10_CON */
> +enum {
> +	REG(PERI_SEL_PLL, 15, 15),
> +	PERI_SEL_CPLL		= 0,
> +	PERI_SEL_GPLL,
> +
> +	REG(PERI_PCLK_DIV, 13, 12),
> +
> +	REG(PERI_HCLK_DIV, 9, 8),
> +
> +	REG(PERI_ACLK_DIV, 4, 0),
> +};
> +
> +/* CRU_CLKSEL11_CON */
> +enum {
> +	REG(MMC0_DIV, 5, 0),
> +};
> +
> +/* CRU_CLKSEL12_CON */
> +enum {
> +	REG(UART_PLL, 15, 15),
> +	UART_PLL_SELECT_GENERAL	= 0,
> +	UART_PLL_SELECT_CODEC,
> +
> +	REG(EMMC_DIV, 13, 8),
> +
> +	REG(SDIO_DIV, 5, 0),
> +};
> +
> +/* CRU_CLKSEL24_CON */
> +enum {
> +	REG(SARADC_DIV, 15, 8),
> +};
> +
> +/* CRU_CLKSEL25_CON */
> +enum {
> +	REG(SPI1_DIV, 14, 8),
> +
> +	REG(SPI0_DIV, 6, 0),
> +};
> +
> +/* CRU_CLKSEL34_CON */
> +enum {
> +	REG(TSADC_DIV, 15, 0),
> +};
> +
> +/* CRU_MODE_CON */
> +enum {
> +	REG(GPLL_MODE, 13, 12),
> +
> +	REG(CPLL_MODE, 9, 8),
> +
> +	REG(DPLL_MODE, 5, 4),
> +
> +	REG(APLL_MODE, 1, 0),
> +	PLL_MODE_SLOW		= 0,
> +	PLL_MODE_NORMAL,
> +	PLL_MODE_DEEP,
> +};
> +
> +/* CRU_APLL_CON0 */
> +enum {
> +	REG(CLKR, 13, 8),
> +
> +	REG(CLKOD, 3, 0),
> +};
> +
> +/* CRU_APLL_CON1 */
> +enum {
> +	REG(CLKF, 12, 0),
> +};
> +
> +#endif
> diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
> index 913f611a0f..a72d8fe58a 100644
> --- a/drivers/clk/rockchip/Makefile
> +++ b/drivers/clk/rockchip/Makefile
> @@ -6,6 +6,7 @@
>   obj-y += clk_pll.o
>   obj-$(CONFIG_ROCKCHIP_PX30) += clk_px30.o
>   obj-$(CONFIG_ROCKCHIP_RK3036) += clk_rk3036.o
> +obj-$(CONFIG_ROCKCHIP_RK3066) += clk_rk3066.o
>   obj-$(CONFIG_ROCKCHIP_RK3128) += clk_rk3128.o
>   obj-$(CONFIG_ROCKCHIP_RK3188) += clk_rk3188.o
>   obj-$(CONFIG_ROCKCHIP_RK322X) += clk_rk322x.o
> diff --git a/drivers/clk/rockchip/clk_rk3066.c b/drivers/clk/rockchip/clk_rk3066.c
> new file mode 100644
> index 0000000000..2c12f6e044
> --- /dev/null
> +++ b/drivers/clk/rockchip/clk_rk3066.c
> @@ -0,0 +1,717 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * (C) Copyright 2015 Google, Inc
> + * (C) Copyright 2016 Heiko Stuebner <heiko@sntech.de>
> + */
> +
> +#include <bitfield.h>
> +#include <common.h>
> +#include <clk-uclass.h>
> +#include <dm.h>
> +#include <dt-structs.h>
> +#include <errno.h>
> +#include <log.h>
> +#include <malloc.h>
> +#include <mapmem.h>
> +#include <syscon.h>
> +#include <asm/io.h>
> +#include <asm/arch-rockchip/clock.h>
> +#include <asm/arch-rockchip/cru_rk3066.h>
> +#include <asm/arch-rockchip/grf_rk3066.h>
> +#include <asm/arch-rockchip/hardware.h>
> +#include <dt-bindings/clock/rk3066a-cru.h>
> +#include <dm/device_compat.h>
> +#include <dm/device-internal.h>
> +#include <dm/lists.h>
> +#include <dm/uclass-internal.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/log2.h>
> +#include <linux/stringify.h>
> +
> +struct rk3066_clk_plat {
> +#if CONFIG_IS_ENABLED(OF_PLATDATA)
> +	struct dtd_rockchip_rk3066a_cru dtd;
> +#endif
> +};
> +
> +struct pll_div {
> +	u32 nr;
> +	u32 nf;
> +	u32 no;
> +};
> +
> +enum {
> +	VCO_MAX_HZ	= 1416U * 1000000,
> +	VCO_MIN_HZ	= 300 * 1000000,
> +	OUTPUT_MAX_HZ	= 1416U * 1000000,
> +	OUTPUT_MIN_HZ	= 30 * 1000000,
> +	FREF_MAX_HZ	= 1416U * 1000000,
> +	FREF_MIN_HZ	= 30 * 1000,
> +};
> +
> +enum {
> +	/* PLL CON0 */
> +	PLL_OD_MASK		= GENMASK(3, 0),
> +
> +	/* PLL CON1 */
> +	PLL_NF_MASK		= GENMASK(12, 0),
> +
> +	/* PLL CON2 */
> +	PLL_BWADJ_MASK		= GENMASK(11, 0),
> +
> +	/* PLL CON3 */
> +	PLL_RESET_SHIFT		= 5,
> +
> +	/* GRF_SOC_STATUS0 */
> +	SOCSTS_DPLL_LOCK	= BIT(4),
> +	SOCSTS_APLL_LOCK	= BIT(5),
> +	SOCSTS_CPLL_LOCK	= BIT(6),
> +	SOCSTS_GPLL_LOCK	= BIT(7),
> +};
> +
> +#define DIV_TO_RATE(input_rate, div)	((input_rate) / ((div) + 1))
> +
> +#define PLL_DIVISORS(hz, _nr, _no) {\
> +	.nr = _nr, .nf = (u32)((u64)hz * _nr * _no / OSC_HZ), .no = _no};\
> +	_Static_assert(((u64)hz * _nr * _no / OSC_HZ) * OSC_HZ /\
> +		       (_nr * _no) == hz, #hz "Hz cannot be hit with PLL "\
> +		       "divisors on line " __stringify(__LINE__))
> +
> +/* Keep divisors as low as possible to reduce jitter and power usage. */
> +static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2);
> +static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2);
> +
> +static int rk3066_clk_set_pll(struct rk3066_cru *cru, enum rk_clk_id clk_id,
> +			      const struct pll_div *div)
> +{
> +	int pll_id = rk_pll_id(clk_id);
> +	struct rk3066_pll *pll = &cru->pll[pll_id];
> +	/* All PLLs have the same VCO and output frequency range restrictions. */
> +	uint vco_hz = OSC_HZ / 1000 * div->nf / div->nr * 1000;
> +	uint output_hz = vco_hz / div->no;
> +
> +	debug("%s: PLL at %x: nf=%d, nr=%d, no=%d, vco=%u Hz, output=%u Hz\n", __func__,
> +	      (uint)pll, div->nf, div->nr, div->no, vco_hz, output_hz);
> +	assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
> +	       output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ &&
> +	       (div->no == 1 || !(div->no % 2)));
> +
> +	/* Enter reset. */
> +	rk_setreg(&pll->con3, BIT(PLL_RESET_SHIFT));
> +
> +	rk_clrsetreg(&pll->con0,
> +		     CLKR_MASK | PLL_OD_MASK,
> +		     ((div->nr - 1) << CLKR_SHIFT) | (div->no - 1));
> +	rk_clrsetreg(&pll->con1, CLKF_MASK, div->nf - 1);
> +
> +	rk_clrsetreg(&pll->con2, PLL_BWADJ_MASK, (div->nf >> 1) - 1);
> +
> +	/* Exit reset. */
> +	rk_clrreg(&pll->con3, BIT(PLL_RESET_SHIFT));
> +
> +	return 0;
> +}
> +
> +static int rk3066_clk_configure_ddr(struct rk3066_cru *cru, struct rk3066_grf *grf,
> +				    unsigned int hz)
> +{
> +	static const struct pll_div dpll_cfg[] = {
> +		{.nf = 25, .nr = 2, .no = 1},
> +		{.nf = 400, .nr = 9, .no = 2},
> +		{.nf = 500, .nr = 9, .no = 2},
> +		{.nf = 100, .nr = 3, .no = 1},
> +	};
> +	int cfg;
> +
> +	switch (hz) {
> +	case 300000000:
> +		cfg = 0;
> +		break;
> +	case 533000000:	/* actually 533.3P MHz */
> +		cfg = 1;
> +		break;
> +	case 666000000:	/* actually 666.6P MHz */
> +		cfg = 2;
> +		break;
> +	case 800000000:
> +		cfg = 3;
> +		break;
> +	default:
> +		debug("%s: unsupported SDRAM frequency", __func__);
> +		return -EINVAL;
> +	}
> +
> +	/* Enter PLL slow mode. */
> +	rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK,
> +		     PLL_MODE_SLOW << DPLL_MODE_SHIFT);
> +
> +	rk3066_clk_set_pll(cru, CLK_DDR, &dpll_cfg[cfg]);
> +
> +	/* Wait for PLL lock. */
> +	while (!(readl(&grf->soc_status0) & SOCSTS_DPLL_LOCK))
> +		udelay(1);
> +
> +	/* Enter PLL normal mode. */
> +	rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK,
> +		     PLL_MODE_NORMAL << DPLL_MODE_SHIFT);
> +
> +	return 0;
> +}
> +
> +static int rk3066_clk_configure_cpu(struct rk3066_cru *cru, struct rk3066_grf *grf,
> +				    unsigned int hz)
> +{
> +	static const struct pll_div apll_cfg[] = {
> +		{.nf = 50, .nr = 1, .no = 2},
> +		{.nf = 59, .nr = 1, .no = 1},
> +	};
> +	int div_core_peri, div_cpu_aclk, cfg;
> +
> +	/*
> +	 * We support two possible frequencies, the safe 600MHz
> +	 * which will work with default pmic settings and will
> +	 * be set to get away from the 24MHz default and
> +	 * the maximum of 1.416Ghz, which boards can set if they
> +	 * were able to get pmic support for it.
> +	 */
> +	switch (hz) {
> +	case APLL_SAFE_HZ:
> +		cfg = 0;
> +		div_core_peri = 1;
> +		div_cpu_aclk = 3;
> +		break;
> +	case APLL_HZ:
> +		cfg = 1;
> +		div_core_peri = 2;
> +		div_cpu_aclk = 3;
> +		break;
> +	default:
> +		debug("unsupported ARMCLK frequency");
> +		return -EINVAL;
> +	}
> +
> +	/* Enter PLL slow mode. */
> +	rk_clrsetreg(&cru->cru_mode_con, APLL_MODE_MASK,
> +		     PLL_MODE_SLOW << APLL_MODE_SHIFT);
> +
> +	rk3066_clk_set_pll(cru, CLK_ARM, &apll_cfg[cfg]);
> +
> +	/* Wait for PLL lock. */
> +	while (!(readl(&grf->soc_status0) & SOCSTS_APLL_LOCK))
> +		udelay(1);
> +
> +	/* Set divider for peripherals attached to the CPU core. */
> +	rk_clrsetreg(&cru->cru_clksel_con[0],
> +		     CORE_PERI_DIV_MASK,
> +		     div_core_peri << CORE_PERI_DIV_SHIFT);
> +
> +	/* Set up dependent divisor for cpu_aclk. */
> +	rk_clrsetreg(&cru->cru_clksel_con[1],
> +		     CPU_ACLK_DIV_MASK,
> +		     div_cpu_aclk << CPU_ACLK_DIV_SHIFT);
> +
> +	/* Enter PLL normal mode. */
> +	rk_clrsetreg(&cru->cru_mode_con, APLL_MODE_MASK,
> +		     PLL_MODE_NORMAL << APLL_MODE_SHIFT);
> +
> +	return hz;
> +}
> +
> +static uint32_t rk3066_clk_pll_get_rate(struct rk3066_cru *cru,
> +					enum rk_clk_id clk_id)
> +{
> +	u32 nr, no, nf;
> +	u32 con;
> +	int pll_id = rk_pll_id(clk_id);
> +	struct rk3066_pll *pll = &cru->pll[pll_id];
> +	static u8 clk_shift[CLK_COUNT] = {
> +		0xff, APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT,
> +		GPLL_MODE_SHIFT
> +	};
> +	uint shift;
> +
> +	con = readl(&cru->cru_mode_con);
> +	shift = clk_shift[clk_id];
> +	switch (FIELD_GET(APLL_MODE_MASK, con >> shift)) {
> +	case PLL_MODE_SLOW:
> +		return OSC_HZ;
> +	case PLL_MODE_NORMAL:
> +		/* normal mode */
> +		con = readl(&pll->con0);
> +		no = bitfield_extract_by_mask(con, CLKOD_MASK) + 1;
> +		nr = bitfield_extract_by_mask(con, CLKR_MASK) + 1;
> +		con = readl(&pll->con1);
> +		nf = bitfield_extract_by_mask(con, CLKF_MASK) + 1;
> +
> +		return (OSC_HZ * nf) / (nr * no);
> +	case PLL_MODE_DEEP:
> +	default:
> +		return 32768;
> +	}
> +}
> +
> +static ulong rk3066_clk_mmc_get_clk(struct rk3066_cru *cru, uint gclk_rate,
> +				    int periph)
> +{
> +	uint div;
> +	u32 con;
> +
> +	switch (periph) {
> +	case HCLK_EMMC:
> +	case SCLK_EMMC:
> +		con = readl(&cru->cru_clksel_con[12]);
> +		div = bitfield_extract_by_mask(con, EMMC_DIV_MASK);
> +		break;
> +	case HCLK_SDMMC:
> +	case SCLK_SDMMC:
> +		con = readl(&cru->cru_clksel_con[11]);
> +		div = bitfield_extract_by_mask(con, MMC0_DIV_MASK);
> +		break;
> +	case HCLK_SDIO:
> +	case SCLK_SDIO:
> +		con = readl(&cru->cru_clksel_con[12]);
> +		div = bitfield_extract_by_mask(con, SDIO_DIV_MASK);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return DIV_TO_RATE(gclk_rate, div) / 2;
> +}
> +
> +static ulong rk3066_clk_mmc_set_clk(struct rk3066_cru *cru, uint gclk_rate,
> +				    int  periph, uint freq)
> +{
> +	int src_clk_div;
> +
> +	debug("%s: gclk_rate=%u\n", __func__, gclk_rate);
> +	/* MMC clock by default divides by 2 internally, so need to provide double in CRU. */
> +	src_clk_div = DIV_ROUND_UP(gclk_rate / 2, freq) - 1;
> +	assert(src_clk_div <= 0x3f);
> +
> +	switch (periph) {
> +	case HCLK_EMMC:
> +	case SCLK_EMMC:
> +		rk_clrsetreg(&cru->cru_clksel_con[12],
> +			     EMMC_DIV_MASK,
> +			     src_clk_div << EMMC_DIV_SHIFT);
> +		break;
> +	case HCLK_SDMMC:
> +	case SCLK_SDMMC:
> +		rk_clrsetreg(&cru->cru_clksel_con[11],
> +			     MMC0_DIV_MASK,
> +			     src_clk_div << MMC0_DIV_SHIFT);
> +		break;
> +	case HCLK_SDIO:
> +	case SCLK_SDIO:
> +		rk_clrsetreg(&cru->cru_clksel_con[12],
> +			     SDIO_DIV_MASK,
> +			     src_clk_div << SDIO_DIV_SHIFT);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return rk3066_clk_mmc_get_clk(cru, gclk_rate, periph);
> +}
> +
> +static ulong rk3066_clk_spi_get_clk(struct rk3066_cru *cru, uint gclk_rate,
> +				    int periph)
> +{
> +	uint div;
> +	u32 con;
> +
> +	switch (periph) {
> +	case SCLK_SPI0:
> +		con = readl(&cru->cru_clksel_con[25]);
> +		div = bitfield_extract_by_mask(con, SPI0_DIV_MASK);
> +		break;
> +	case SCLK_SPI1:
> +		con = readl(&cru->cru_clksel_con[25]);
> +		div = bitfield_extract_by_mask(con, SPI1_DIV_MASK);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return DIV_TO_RATE(gclk_rate, div);
> +}
> +
> +static ulong rk3066_clk_spi_set_clk(struct rk3066_cru *cru, uint gclk_rate,
> +				    int periph, uint freq)
> +{
> +	int src_clk_div = DIV_ROUND_UP(gclk_rate, freq) - 1;
> +
> +	assert(src_clk_div < 128);
> +	switch (periph) {
> +	case SCLK_SPI0:
> +		assert(src_clk_div <= SPI0_DIV_MASK >> SPI0_DIV_SHIFT);
> +		rk_clrsetreg(&cru->cru_clksel_con[25],
> +			     SPI0_DIV_MASK,
> +			     src_clk_div << SPI0_DIV_SHIFT);
> +		break;
> +	case SCLK_SPI1:
> +		assert(src_clk_div <= SPI1_DIV_MASK >> SPI1_DIV_SHIFT);
> +		rk_clrsetreg(&cru->cru_clksel_con[25],
> +			     SPI1_DIV_MASK,
> +			     src_clk_div << SPI1_DIV_SHIFT);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return rk3066_clk_spi_get_clk(cru, gclk_rate, periph);
> +}
> +
> +static ulong rk3066_clk_saradc_get_clk(struct rk3066_cru *cru, int periph)
> +{
> +	u32 div, con;
> +
> +	switch (periph) {
> +	case SCLK_SARADC:
> +		con = readl(&cru->cru_clksel_con[24]);
> +		div = bitfield_extract_by_mask(con, SARADC_DIV_MASK);
> +		break;
> +	case SCLK_TSADC:
> +		con = readl(&cru->cru_clksel_con[34]);
> +		div = bitfield_extract_by_mask(con, TSADC_DIV_MASK);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +	return DIV_TO_RATE(PERI_PCLK_HZ, div);
> +}
> +
> +static ulong rk3066_clk_saradc_set_clk(struct rk3066_cru *cru, uint hz,
> +				       int periph)
> +{
> +	int src_clk_div;
> +
> +	src_clk_div = DIV_ROUND_UP(PERI_PCLK_HZ, hz) - 1;
> +	assert(src_clk_div < 128);
> +
> +	switch (periph) {
> +	case SCLK_SARADC:
> +		rk_clrsetreg(&cru->cru_clksel_con[24],
> +			     SARADC_DIV_MASK,
> +			     src_clk_div << SARADC_DIV_SHIFT);
> +		break;
> +	case SCLK_TSADC:
> +		rk_clrsetreg(&cru->cru_clksel_con[34],
> +			     SARADC_DIV_MASK,
> +			     src_clk_div << SARADC_DIV_SHIFT);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return rk3066_clk_saradc_get_clk(cru, periph);
> +}
> +
> +static void rk3066_clk_init(struct rk3066_cru *cru, struct rk3066_grf *grf)
> +{
> +	u32 aclk_div, hclk_div, pclk_div, h2p_div;
> +
> +	/* Enter PLL slow mode. */
> +	rk_clrsetreg(&cru->cru_mode_con,
> +		     GPLL_MODE_MASK |
> +		     CPLL_MODE_MASK,
> +		     PLL_MODE_SLOW << GPLL_MODE_SHIFT |
> +		     PLL_MODE_SLOW << CPLL_MODE_SHIFT);
> +
> +	/* Init PLL. */
> +	rk3066_clk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
> +	rk3066_clk_set_pll(cru, CLK_CODEC, &cpll_init_cfg);
> +
> +	/* Wait for PLL lock. */
> +	while ((readl(&grf->soc_status0) &
> +		(SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK)) !=
> +	       (SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK))
> +		udelay(1);
> +
> +	/*
> +	 * Select CPU clock PLL source and
> +	 * reparent aclk_cpu_pre from APPL to GPLL.
> +	 * Set up dependent divisors for PCLK/HCLK and ACLK clocks.
> +	 */
> +	aclk_div = DIV_ROUND_UP(GPLL_HZ, CPU_ACLK_HZ) - 1;
> +	assert((aclk_div + 1) * CPU_ACLK_HZ == GPLL_HZ && aclk_div <= 0x1f);
> +
> +	rk_clrsetreg(&cru->cru_clksel_con[0],
> +		     CPU_ACLK_PLL_MASK |
> +		     A9_CORE_DIV_MASK,
> +		     CPU_ACLK_PLL_SELECT_GPLL << CPU_ACLK_PLL_SHIFT |
> +		     aclk_div << A9_CORE_DIV_SHIFT);
> +
> +	hclk_div = ilog2(CPU_ACLK_HZ / CPU_HCLK_HZ);
> +	assert((1 << hclk_div) * CPU_HCLK_HZ == CPU_ACLK_HZ && hclk_div < 0x3);
> +	pclk_div = ilog2(CPU_ACLK_HZ / CPU_PCLK_HZ);
> +	assert((1 << pclk_div) * CPU_PCLK_HZ == CPU_ACLK_HZ && pclk_div < 0x4);
> +	h2p_div = ilog2(CPU_HCLK_HZ / CPU_H2P_HZ);
> +	assert((1 << h2p_div) * CPU_H2P_HZ == CPU_HCLK_HZ && pclk_div < 0x3);
> +
> +	rk_clrsetreg(&cru->cru_clksel_con[1],
> +		     AHB2APB_DIV_MASK |
> +		     CPU_PCLK_DIV_MASK |
> +		     CPU_HCLK_DIV_MASK,
> +		     h2p_div << AHB2APB_DIV_SHIFT |
> +		     pclk_div << CPU_PCLK_DIV_SHIFT |
> +		     hclk_div << CPU_HCLK_DIV_SHIFT);
> +
> +	/*
> +	 * Select PERI clock PLL source and
> +	 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
> +	 */
> +	aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1;
> +	assert((aclk_div + 1) * PERI_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
> +
> +	hclk_div = ilog2(PERI_ACLK_HZ / PERI_HCLK_HZ);
> +	assert((1 << hclk_div) * PERI_HCLK_HZ ==
> +	       PERI_ACLK_HZ && (hclk_div < 0x4));
> +
> +	pclk_div = ilog2(PERI_ACLK_HZ / PERI_PCLK_HZ);
> +	assert((1 << pclk_div) * PERI_PCLK_HZ ==
> +	       PERI_ACLK_HZ && (pclk_div < 0x4));
> +
> +	rk_clrsetreg(&cru->cru_clksel_con[10],
> +		     PERI_PCLK_DIV_MASK |
> +		     PERI_HCLK_DIV_MASK |
> +		     PERI_ACLK_DIV_MASK,
> +		     PERI_SEL_GPLL << PERI_SEL_PLL_SHIFT |
> +		     pclk_div << PERI_PCLK_DIV_SHIFT |
> +		     hclk_div << PERI_HCLK_DIV_SHIFT |
> +		     aclk_div << PERI_ACLK_DIV_SHIFT);
> +
> +	/* Enter PLL normal mode. */
> +	rk_clrsetreg(&cru->cru_mode_con,
> +		     GPLL_MODE_MASK |
> +		     CPLL_MODE_MASK,
> +		     PLL_MODE_NORMAL << GPLL_MODE_SHIFT |
> +		     PLL_MODE_NORMAL << CPLL_MODE_SHIFT);
> +
> +	rk3066_clk_mmc_set_clk(cru, PERI_HCLK_HZ, HCLK_SDMMC, 16000000);
> +}
> +
> +static ulong rk3066_clk_get_rate(struct clk *clk)
> +{
> +	struct rk3066_clk_priv *priv = dev_get_priv(clk->dev);
> +	ulong new_rate, gclk_rate;
> +
> +	gclk_rate = rk3066_clk_pll_get_rate(priv->cru, CLK_GENERAL);
> +	switch (clk->id) {
> +	case 1 ... 4:
> +		new_rate = rk3066_clk_pll_get_rate(priv->cru, clk->id);
> +		break;
> +	case HCLK_EMMC:
> +	case HCLK_SDMMC:
> +	case HCLK_SDIO:
> +	case SCLK_EMMC:
> +	case SCLK_SDMMC:
> +	case SCLK_SDIO:
> +		new_rate = rk3066_clk_mmc_get_clk(priv->cru, PERI_HCLK_HZ,
> +						  clk->id);
> +		break;
> +	case SCLK_SPI0:
> +	case SCLK_SPI1:
> +		new_rate = rk3066_clk_spi_get_clk(priv->cru, PERI_PCLK_HZ,
> +						  clk->id);
> +		break;
> +	case PCLK_I2C0:
> +	case PCLK_I2C1:
> +	case PCLK_I2C2:
> +	case PCLK_I2C3:
> +	case PCLK_I2C4:
> +		return gclk_rate;
> +	case SCLK_SARADC:
> +	case SCLK_TSADC:
> +		new_rate = rk3066_clk_saradc_get_clk(priv->cru, clk->id);
> +		break;
> +	case SCLK_TIMER0:
> +	case SCLK_TIMER1:
> +	case SCLK_TIMER2:
> +	case SCLK_UART0:
> +	case SCLK_UART1:
> +	case SCLK_UART2:
> +	case SCLK_UART3:
> +		return OSC_HZ;
> +	default:
> +		return -ENOENT;
> +	}
> +
> +	return new_rate;
> +}
> +
> +static ulong rk3066_clk_set_rate(struct clk *clk, ulong rate)
> +{
> +	struct rk3066_clk_priv *priv = dev_get_priv(clk->dev);
> +	struct rk3066_cru *cru = priv->cru;
> +	ulong new_rate;
> +
> +	switch (clk->id) {
> +	case PLL_APLL:
> +		new_rate = rk3066_clk_configure_cpu(priv->cru, priv->grf, rate);
> +		break;
> +	case CLK_DDR:
> +		new_rate = rk3066_clk_configure_ddr(priv->cru, priv->grf, rate);
> +		break;
> +	case HCLK_EMMC:
> +	case HCLK_SDMMC:
> +	case HCLK_SDIO:
> +	case SCLK_EMMC:
> +	case SCLK_SDMMC:
> +	case SCLK_SDIO:
> +		new_rate = rk3066_clk_mmc_set_clk(cru, PERI_HCLK_HZ,
> +						  clk->id, rate);
> +		break;
> +	case SCLK_SPI0:
> +	case SCLK_SPI1:
> +		new_rate = rk3066_clk_spi_set_clk(cru, PERI_PCLK_HZ,
> +						  clk->id, rate);
> +		break;
> +	case SCLK_SARADC:
> +	case SCLK_TSADC:
> +		new_rate = rk3066_clk_saradc_set_clk(cru, rate, clk->id);
> +		break;
> +	case PLL_CPLL:
> +	case PLL_GPLL:
> +	case ACLK_CPU:
> +	case HCLK_CPU:
> +	case PCLK_CPU:
> +	case ACLK_PERI:
> +	case HCLK_PERI:
> +	case PCLK_PERI:
> +		return 0;
> +	default:
> +		return -ENOENT;
> +	}
> +
> +	return new_rate;
> +}
> +
> +static int rk3066_clk_enable(struct clk *clk)
> +{
> +	struct rk3066_clk_priv *priv = dev_get_priv(clk->dev);
> +
> +	switch (clk->id) {
> +	case HCLK_NANDC0:
> +		rk_clrreg(&priv->cru->cru_clkgate_con[5], BIT(9));
> +		break;
> +	case HCLK_SDMMC:
> +		rk_clrreg(&priv->cru->cru_clkgate_con[5], BIT(10));
> +		break;
> +	case HCLK_SDIO:
> +		rk_clrreg(&priv->cru->cru_clkgate_con[5], BIT(11));
> +		break;
> +	}
> +
> +	return 0;
> +}
> +
> +static int rk3066_clk_disable(struct clk *clk)
> +{
> +	struct rk3066_clk_priv *priv = dev_get_priv(clk->dev);
> +
> +	switch (clk->id) {
> +	case HCLK_NANDC0:
> +		rk_setreg(&priv->cru->cru_clkgate_con[5], BIT(9));
> +		break;
> +	case HCLK_SDMMC:
> +		rk_setreg(&priv->cru->cru_clkgate_con[5], BIT(10));
> +		break;
> +	case HCLK_SDIO:
> +		rk_setreg(&priv->cru->cru_clkgate_con[5], BIT(11));
> +		break;
> +	}
> +
> +	return 0;
> +}
> +
> +static struct clk_ops rk3066_clk_ops = {
> +	.disable	= rk3066_clk_disable,
> +	.enable	= rk3066_clk_enable,
> +	.get_rate	= rk3066_clk_get_rate,
> +	.set_rate	= rk3066_clk_set_rate,
> +};
> +
> +static int rk3066_clk_of_to_plat(struct udevice *dev)
> +{
> +	if (CONFIG_IS_ENABLED(OF_REAL)) {
> +		struct rk3066_clk_priv *priv = dev_get_priv(dev);
> +
> +		priv->cru = dev_read_addr_ptr(dev);
> +	}
> +
> +	return 0;
> +}
> +
> +static int rk3066_clk_probe(struct udevice *dev)
> +{
> +	struct rk3066_clk_priv *priv = dev_get_priv(dev);
> +
> +	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
> +	if (IS_ERR(priv->grf))
> +		return PTR_ERR(priv->grf);
> +
> +#if CONFIG_IS_ENABLED(OF_PLATDATA)
> +	struct rk3066_clk_plat *plat = dev_get_plat(dev);
> +
> +	priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]);
> +#endif
> +
> +	if (IS_ENABLED(CONFIG_TPL_BUILD)) {
> +		rk3066_clk_init(priv->cru, priv->grf);
> +
> +		/* Init CPU frequency. */
> +		rk3066_clk_configure_cpu(priv->cru, priv->grf, APLL_SAFE_HZ);
> +	}
> +
> +	return 0;
> +}
> +
> +static int rk3066_clk_bind(struct udevice *dev)
> +{
> +	struct udevice *sys_child;
> +	struct sysreset_reg *priv;
> +	int reg_offset, ret;
> +
> +	/* The reset driver does not have a device node, so bind it here. */
> +	ret = device_bind(dev, DM_DRIVER_GET(sysreset_rockchip), "sysreset",
> +			  NULL, ofnode_null(), &sys_child);
> +	if (ret) {
> +		dev_dbg(dev, "Warning: No sysreset driver: ret=%d\n", ret);
> +	} else {
> +		priv = malloc(sizeof(struct sysreset_reg));
> +		priv->glb_srst_fst_value = offsetof(struct rk3066_cru,
> +						    cru_glb_srst_fst_value);
> +		priv->glb_srst_snd_value = offsetof(struct rk3066_cru,
> +						    cru_glb_srst_snd_value);
> +		dev_set_priv(sys_child, priv);
> +	}
> +
> +	if (CONFIG_IS_ENABLED(RESET_ROCKCHIP)) {
> +		reg_offset = offsetof(struct rk3066_cru, cru_softrst_con[0]);
> +		ret = rockchip_reset_bind(dev, reg_offset, 9);
> +		if (ret)
> +			dev_dbg(dev, "Warning: software reset driver bind failed\n");
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct udevice_id rk3066_clk_ids[] = {
> +	{ .compatible = "rockchip,rk3066a-cru" },
> +	{ }
> +};
> +
> +U_BOOT_DRIVER(rockchip_rk3066a_cru) = {
> +	.name		= "rockchip_rk3066a_cru",
> +	.id		= UCLASS_CLK,
> +	.ops		= &rk3066_clk_ops,
> +	.probe		= rk3066_clk_probe,
> +	.bind		= rk3066_clk_bind,
> +	.of_match	= rk3066_clk_ids,
> +	.of_to_plat	= rk3066_clk_of_to_plat,
> +	.priv_auto	= sizeof(struct rk3066_clk_priv),
> +	.plat_auto	= sizeof(struct rk3066_clk_plat),
> +};

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v9 04/16] rockchip: rk3066: add rk3066 pinctrl driver
  2022-04-04 14:19 ` [PATCH v9 04/16] rockchip: rk3066: add rk3066 pinctrl driver Johan Jonker
@ 2022-04-09  3:49   ` Kever Yang
  0 siblings, 0 replies; 33+ messages in thread
From: Kever Yang @ 2022-04-09  3:49 UTC (permalink / raw)
  To: Johan Jonker; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot


On 2022/4/4 22:19, Johan Jonker wrote:
> From: Paweł Jarosz <paweljarosz3691@gmail.com>
>
> Add driver supporting pin multiplexing on rk3066 platform.
>
> Signed-off-by: Paweł Jarosz <paweljarosz3691@gmail.com>
> Signed-off-by: Johan Jonker <jbx6244@gmail.com>

Reviewed-by: Kever Yang <kever.yang@rock-chips.com>

Thanks,
- Kever
> ---
>
> Changed V9:
>    change regmap source
>
> Changed V7:
>    restyle
>    changed function prefix.
>    restyle U_BOOT_DRIVER structure
>    use OF_REAL
>    use EOPNOTSUPP
> ---
>   drivers/pinctrl/rockchip/Makefile         |   1 +
>   drivers/pinctrl/rockchip/pinctrl-rk3066.c | 112 ++++++++++++++++++++++
>   2 files changed, 113 insertions(+)
>   create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3066.c
>
> diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
> index fcf19f877a..7d03f8101d 100644
> --- a/drivers/pinctrl/rockchip/Makefile
> +++ b/drivers/pinctrl/rockchip/Makefile
> @@ -5,6 +5,7 @@
>   obj-y += pinctrl-rockchip-core.o
>   obj-$(CONFIG_ROCKCHIP_PX30) += pinctrl-px30.o
>   obj-$(CONFIG_ROCKCHIP_RK3036) += pinctrl-rk3036.o
> +obj-$(CONFIG_ROCKCHIP_RK3066) += pinctrl-rk3066.o
>   obj-$(CONFIG_ROCKCHIP_RK3128) += pinctrl-rk3128.o
>   obj-$(CONFIG_ROCKCHIP_RK3188) += pinctrl-rk3188.o
>   obj-$(CONFIG_ROCKCHIP_RK322X) += pinctrl-rk322x.o
> diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3066.c b/drivers/pinctrl/rockchip/pinctrl-rk3066.c
> new file mode 100644
> index 0000000000..598b63223e
> --- /dev/null
> +++ b/drivers/pinctrl/rockchip/pinctrl-rk3066.c
> @@ -0,0 +1,112 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * (C) Copyright 2021 Rockchip Electronics Co., Ltd
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <dm/pinctrl.h>
> +#include <regmap.h>
> +#include <syscon.h>
> +#include <linux/bitops.h>
> +
> +#include "pinctrl-rockchip.h"
> +
> +static int rk3066_pinctrl_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
> +{
> +	struct rockchip_pinctrl_priv *priv = bank->priv;
> +	int iomux_num = (pin / 8);
> +	struct regmap *regmap;
> +	int reg, ret, mask, mux_type;
> +	u8 bit;
> +	u32 data;
> +
> +	regmap = priv->regmap_base;
> +
> +	/* get basic quadrupel of mux registers and the correct reg inside */
> +	mux_type = bank->iomux[iomux_num].type;
> +	reg = bank->iomux[iomux_num].offset;
> +	reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
> +
> +	data = (mask << (bit + 16));
> +	data |= (mux & mask) << bit;
> +	ret = regmap_write(regmap, reg, data);
> +
> +	return ret;
> +}
> +
> +#define RK3066_PULL_OFFSET		0x118
> +#define RK3066_PULL_PINS_PER_REG	16
> +#define RK3066_PULL_BANK_STRIDE		8
> +
> +static void rk3066_pinctrl_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
> +						 int pin_num, struct regmap **regmap,
> +						 int *reg, u8 *bit)
> +{
> +	struct rockchip_pinctrl_priv *priv = bank->priv;
> +
> +	*regmap = priv->regmap_base;
> +	*reg = RK3066_PULL_OFFSET;
> +	*reg += bank->bank_num * RK3066_PULL_BANK_STRIDE;
> +	*reg += (pin_num / RK3066_PULL_PINS_PER_REG) * 4;
> +
> +	*bit = pin_num % RK3066_PULL_PINS_PER_REG;
> +};
> +
> +static int rk3066_pinctrl_set_pull(struct rockchip_pin_bank *bank,
> +				   int pin_num, int pull)
> +{
> +	struct regmap *regmap;
> +	int reg, ret;
> +	u8 bit;
> +	u32 data;
> +
> +	if (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT &&
> +	    pull != PIN_CONFIG_BIAS_DISABLE)
> +		return -EOPNOTSUPP;
> +
> +	rk3066_pinctrl_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
> +	data = BIT(bit + 16);
> +	if (pull == PIN_CONFIG_BIAS_DISABLE)
> +		data |= BIT(bit);
> +	ret = regmap_write(regmap, reg, data);
> +
> +	return ret;
> +}
> +
> +static struct rockchip_pin_bank rk3066_pin_banks[] = {
> +	PIN_BANK(0, 32, "gpio0"),
> +	PIN_BANK(1, 32, "gpio1"),
> +	PIN_BANK(2, 32, "gpio2"),
> +	PIN_BANK(3, 32, "gpio3"),
> +	PIN_BANK(4, 32, "gpio4"),
> +	PIN_BANK(6, 16, "gpio6"),
> +};
> +
> +static struct rockchip_pin_ctrl rk3066_pin_ctrl = {
> +	.pin_banks		= rk3066_pin_banks,
> +	.nr_banks		= ARRAY_SIZE(rk3066_pin_banks),
> +	.grf_mux_offset		= 0xa8,
> +	.set_mux		= rk3066_pinctrl_set_mux,
> +	.set_pull		= rk3066_pinctrl_set_pull,
> +};
> +
> +static const struct udevice_id rk3066_pinctrl_ids[] = {
> +	{
> +		.compatible = "rockchip,rk3066a-pinctrl",
> +		.data = (ulong)&rk3066_pin_ctrl
> +	},
> +	{}
> +};
> +
> +U_BOOT_DRIVER(rockchip_rk3066a_pinctrl) = {
> +	.name		= "rockchip_rk3066a_pinctrl",
> +	.id		= UCLASS_PINCTRL,
> +	.ops		= &rockchip_pinctrl_ops,
> +	.probe		= rockchip_pinctrl_probe,
> +#if CONFIG_IS_ENABLED(OF_REAL)
> +	.bind		= dm_scan_fdt_dev,
> +#endif
> +	.of_match	= rk3066_pinctrl_ids,
> +	.priv_auto	= sizeof(struct rockchip_pinctrl_priv),
> +};

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v9 05/16] rockchip: rk3066: add sdram driver
  2022-04-04 14:19 ` [PATCH v9 05/16] rockchip: rk3066: add sdram driver Johan Jonker
@ 2022-04-09  3:50   ` Kever Yang
  0 siblings, 0 replies; 33+ messages in thread
From: Kever Yang @ 2022-04-09  3:50 UTC (permalink / raw)
  To: Johan Jonker; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot


On 2022/4/4 22:19, Johan Jonker wrote:
> From: Paweł Jarosz <paweljarosz3691@gmail.com>
>
> Add rockchip rk3066 sdram driver
>
> Signed-off-by: Paweł Jarosz <paweljarosz3691@gmail.com>
> Signed-off-by: Johan Jonker <jbx6244@gmail.com>

Reviewed-by: Kever Yang <kever.yang@rock-chips.com>

Thanks,
- Kever
> ---
>
> Changed V7:
>    restyle
>    rename TEST_PATTERN
>    changed function prefix
>    changed #if where possible
>    restyle U_BOOT_DRIVER structure
>    remove rk3066_dmc_of_to_plat because dmc DT data
>    only used in TPL in combination with OF_PLATDATA
> ---
>   drivers/ram/rockchip/Makefile       |   1 +
>   drivers/ram/rockchip/sdram_rk3066.c | 892 ++++++++++++++++++++++++++++
>   2 files changed, 893 insertions(+)
>   create mode 100644 drivers/ram/rockchip/sdram_rk3066.c
>
> diff --git a/drivers/ram/rockchip/Makefile b/drivers/ram/rockchip/Makefile
> index ca1c289b88..6d530c29af 100644
> --- a/drivers/ram/rockchip/Makefile
> +++ b/drivers/ram/rockchip/Makefile
> @@ -5,6 +5,7 @@
>   
>   obj-$(CONFIG_ROCKCHIP_PX30) += sdram_px30.o sdram_pctl_px30.o sdram_phy_px30.o
>   obj-$(CONFIG_ROCKCHIP_RK3368) = dmc-rk3368.o
> +obj-$(CONFIG_ROCKCHIP_RK3066) = sdram_rk3066.o
>   obj-$(CONFIG_ROCKCHIP_RK3128) = sdram_rk3128.o
>   obj-$(CONFIG_ROCKCHIP_RK3188) = sdram_rk3188.o
>   obj-$(CONFIG_ROCKCHIP_RK322X) = sdram_rk322x.o
> diff --git a/drivers/ram/rockchip/sdram_rk3066.c b/drivers/ram/rockchip/sdram_rk3066.c
> new file mode 100644
> index 0000000000..832154ee3a
> --- /dev/null
> +++ b/drivers/ram/rockchip/sdram_rk3066.c
> @@ -0,0 +1,892 @@
> +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
> +/*
> + * (C) Copyright 2015 Google, Inc
> + * Copyright 2014 Rockchip Inc.
> + *
> + * Adapted from the very similar rk3188 ddr init.
> + */
> +
> +#include <common.h>
> +#include <clk.h>
> +#include <dm.h>
> +#include <dt-structs.h>
> +#include <errno.h>
> +#include <hang.h>
> +#include <init.h>
> +#include <log.h>
> +#include <ram.h>
> +#include <regmap.h>
> +#include <syscon.h>
> +#include <asm/io.h>
> +#include <asm/arch-rockchip/clock.h>
> +#include <asm/arch-rockchip/cru_rk3066.h>
> +#include <asm/arch-rockchip/ddr_rk3188.h>
> +#include <asm/arch-rockchip/grf_rk3066.h>
> +#include <asm/arch-rockchip/hardware.h>
> +#include <asm/arch-rockchip/pmu_rk3188.h>
> +#include <asm/arch-rockchip/sdram_rk3288.h>
> +#include <asm/arch-rockchip/sdram.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +
> +struct rk3066_dmc_chan_info {
> +	struct rk3288_ddr_pctl *pctl;
> +	struct rk3288_ddr_publ *publ;
> +	struct rk3188_msch *msch;
> +};
> +
> +struct rk3066_dmc_dram_info {
> +	struct rk3066_dmc_chan_info chan[1];
> +	struct ram_info info;
> +	struct clk ddr_clk;
> +	struct rk3066_cru *cru;
> +	struct rk3066_grf *grf;
> +	struct rk3066_sgrf *sgrf;
> +	struct rk3188_pmu *pmu;
> +};
> +
> +struct rk3066_dmc_sdram_params {
> +#if CONFIG_IS_ENABLED(OF_PLATDATA)
> +	struct dtd_rockchip_rk3066_dmc of_plat;
> +#endif
> +	struct rk3288_sdram_channel ch[2];
> +	struct rk3288_sdram_pctl_timing pctl_timing;
> +	struct rk3288_sdram_phy_timing phy_timing;
> +	struct rk3288_base_params base;
> +	int num_channels;
> +	struct regmap *map;
> +};
> +
> +const int rk3066_dmc_ddrconf_table[] = {
> +	/*
> +	 * [5:4] row(13+n)
> +	 * [1:0] col(9+n), assume bw=2
> +	 * row	    col,bw
> +	 */
> +	0,
> +	(2 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT,
> +	(1 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT,
> +	(0 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT,
> +	(2 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT,
> +	(1 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT,
> +	(0 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT,
> +	(1 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT,
> +	(0 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +};
> +
> +#define TEST_PATTERN			0x5aa5f00f
> +#define DQS_GATE_TRAINING_ERROR_RANK0	BIT(4)
> +#define DQS_GATE_TRAINING_ERROR_RANK1	BIT(5)
> +
> +static void rk3066_dmc_copy_to_reg(u32 *dest, const u32 *src, u32 n)
> +{
> +	int i;
> +
> +	for (i = 0; i < n / sizeof(u32); i++) {
> +		writel(*src, dest);
> +		src++;
> +		dest++;
> +	}
> +}
> +
> +static void rk3066_dmc_ddr_reset(struct rk3066_cru *cru, u32 ch, u32 ctl, u32 phy)
> +{
> +	u32 phy_ctl_srstn_shift = 13;
> +	u32 ctl_psrstn_shift = 11;
> +	u32 ctl_srstn_shift = 10;
> +	u32 phy_psrstn_shift = 9;
> +	u32 phy_srstn_shift = 8;
> +
> +	rk_clrsetreg(&cru->cru_softrst_con[5],
> +		     1 << phy_ctl_srstn_shift | 1 << ctl_psrstn_shift |
> +		     1 << ctl_srstn_shift | 1 << phy_psrstn_shift |
> +		     1 << phy_srstn_shift,
> +		     phy << phy_ctl_srstn_shift | ctl << ctl_psrstn_shift |
> +		     ctl << ctl_srstn_shift | phy << phy_psrstn_shift |
> +		     phy << phy_srstn_shift);
> +}
> +
> +static void rk3066_dmc_ddr_phy_ctl_reset(struct rk3066_cru *cru, u32 ch, u32 n)
> +{
> +	u32 phy_ctl_srstn_shift = 13;
> +
> +	rk_clrsetreg(&cru->cru_softrst_con[5],
> +		     1 << phy_ctl_srstn_shift, n << phy_ctl_srstn_shift);
> +}
> +
> +static void rk3066_dmc_phy_pctrl_reset(struct rk3066_cru *cru,
> +				       struct rk3288_ddr_publ *publ,
> +				       int channel)
> +{
> +	int i;
> +
> +	rk3066_dmc_ddr_reset(cru, channel, 1, 1);
> +	udelay(1);
> +	clrbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST);
> +	for (i = 0; i < 4; i++)
> +		clrbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST);
> +
> +	udelay(10);
> +	setbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST);
> +	for (i = 0; i < 4; i++)
> +		setbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST);
> +
> +	udelay(10);
> +	rk3066_dmc_ddr_reset(cru, channel, 1, 0);
> +	udelay(10);
> +	rk3066_dmc_ddr_reset(cru, channel, 0, 0);
> +	udelay(10);
> +}
> +
> +static void rk3066_dmc_phy_dll_bypass_set(struct rk3288_ddr_publ *publ, u32 freq)
> +{
> +	int i;
> +
> +	if (freq <= 250000000) {
> +		if (freq <= 150000000)
> +			clrbits_le32(&publ->dllgcr, SBIAS_BYPASS);
> +		else
> +			setbits_le32(&publ->dllgcr, SBIAS_BYPASS);
> +		setbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS);
> +		for (i = 0; i < 4; i++)
> +			setbits_le32(&publ->datx8[i].dxdllcr,
> +				     DXDLLCR_DLLDIS);
> +
> +		setbits_le32(&publ->pir, PIR_DLLBYP);
> +	} else {
> +		clrbits_le32(&publ->dllgcr, SBIAS_BYPASS);
> +		clrbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS);
> +		for (i = 0; i < 4; i++) {
> +			clrbits_le32(&publ->datx8[i].dxdllcr,
> +				     DXDLLCR_DLLDIS);
> +		}
> +
> +		clrbits_le32(&publ->pir, PIR_DLLBYP);
> +	}
> +}
> +
> +static void rk3066_dmc_dfi_cfg(struct rk3288_ddr_pctl *pctl, u32 dramtype)
> +{
> +	writel(DFI_INIT_START, &pctl->dfistcfg0);
> +	writel(DFI_DRAM_CLK_SR_EN | DFI_DRAM_CLK_DPD_EN,
> +	       &pctl->dfistcfg1);
> +	writel(DFI_PARITY_INTR_EN | DFI_PARITY_EN, &pctl->dfistcfg2);
> +	writel(7 << TLP_RESP_TIME_SHIFT | LP_SR_EN | LP_PD_EN,
> +	       &pctl->dfilpcfg0);
> +
> +	writel(2 << TCTRL_DELAY_TIME_SHIFT, &pctl->dfitctrldelay);
> +	writel(1 << TPHY_WRDATA_TIME_SHIFT, &pctl->dfitphywrdata);
> +	writel(0xf << TPHY_RDLAT_TIME_SHIFT, &pctl->dfitphyrdlat);
> +	writel(2 << TDRAM_CLK_DIS_TIME_SHIFT, &pctl->dfitdramclkdis);
> +	writel(2 << TDRAM_CLK_EN_TIME_SHIFT, &pctl->dfitdramclken);
> +	writel(1, &pctl->dfitphyupdtype0);
> +
> +	/* CS0 and CS1 write ODT enable. */
> +	writel((RANK0_ODT_WRITE_SEL | RANK1_ODT_WRITE_SEL),
> +	       &pctl->dfiodtcfg);
> +	/* Write ODT length. */
> +	writel(7 << ODT_LEN_BL8_W_SHIFT, &pctl->dfiodtcfg1);
> +	/* Disable phyupd and ctrlupd. */
> +	writel(0, &pctl->dfiupdcfg);
> +}
> +
> +static void rk3066_dmc_ddr_set_ddr3_mode(struct rk3066_grf *grf, uint channel,
> +					 bool ddr3_mode)
> +{
> +	uint mask, val;
> +
> +	mask = MSCH4_MAINDDR3_MASK << MSCH4_MAINDDR3_SHIFT;
> +	val = ddr3_mode << MSCH4_MAINDDR3_SHIFT;
> +	rk_clrsetreg(&grf->soc_con2, mask, val);
> +}
> +
> +static void rk3066_dmc_ddr_rank_2_row15en(struct rk3066_grf *grf, bool enable)
> +{
> +	uint mask, val;
> +
> +	mask = RANK_TO_ROW15_EN_MASK << RANK_TO_ROW15_EN_SHIFT;
> +	val = enable << RANK_TO_ROW15_EN_SHIFT;
> +	rk_clrsetreg(&grf->soc_con2, mask, val);
> +}
> +
> +static void rk3066_dmc_pctl_cfg(int channel, struct rk3288_ddr_pctl *pctl,
> +				struct rk3066_dmc_sdram_params *sdram_params,
> +				struct rk3066_grf *grf)
> +{
> +	rk3066_dmc_copy_to_reg(&pctl->togcnt1u, &sdram_params->pctl_timing.togcnt1u,
> +			       sizeof(sdram_params->pctl_timing));
> +	switch (sdram_params->base.dramtype) {
> +	case DDR3:
> +		if (sdram_params->phy_timing.mr[1] & DDR3_DLL_DISABLE) {
> +			writel(sdram_params->pctl_timing.tcl - 3,
> +			       &pctl->dfitrddataen);
> +		} else {
> +			writel(sdram_params->pctl_timing.tcl - 2,
> +			       &pctl->dfitrddataen);
> +		}
> +		writel(sdram_params->pctl_timing.tcwl - 1,
> +		       &pctl->dfitphywrlat);
> +		writel(0 << MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT | DDR3_EN |
> +		       DDR2_DDR3_BL_8 | (6 - 4) << TFAW_SHIFT | PD_EXIT_SLOW |
> +		       1 << PD_TYPE_SHIFT | 0 << PD_IDLE_SHIFT,
> +		       &pctl->mcfg);
> +		rk3066_dmc_ddr_set_ddr3_mode(grf, channel, true);
> +		break;
> +	}
> +
> +	setbits_le32(&pctl->scfg, 1);
> +}
> +
> +static void rk3066_dmc_phy_cfg(const struct rk3066_dmc_chan_info *chan, int channel,
> +			       struct rk3066_dmc_sdram_params *sdram_params)
> +{
> +	struct rk3288_ddr_publ *publ = chan->publ;
> +	struct rk3188_msch *msch = chan->msch;
> +	uint ddr_freq_mhz = sdram_params->base.ddr_freq / 1000000;
> +	u32 dinit2;
> +	int i;
> +
> +	dinit2 = DIV_ROUND_UP(ddr_freq_mhz * 200000, 1000);
> +	/* Set DDR PHY timing. */
> +	rk3066_dmc_copy_to_reg(&publ->dtpr[0], &sdram_params->phy_timing.dtpr0,
> +			       sizeof(sdram_params->phy_timing));
> +	writel(sdram_params->base.noc_timing, &msch->ddrtiming);
> +	writel(0x3f, &msch->readlatency);
> +	writel(DIV_ROUND_UP(ddr_freq_mhz * 5120, 1000) << PRT_DLLLOCK_SHIFT |
> +	       DIV_ROUND_UP(ddr_freq_mhz * 50, 1000) << PRT_DLLSRST_SHIFT |
> +	       8 << PRT_ITMSRST_SHIFT, &publ->ptr[0]);
> +	writel(DIV_ROUND_UP(ddr_freq_mhz * 500000, 1000) << PRT_DINIT0_SHIFT |
> +	       DIV_ROUND_UP(ddr_freq_mhz * 400, 1000) << PRT_DINIT1_SHIFT,
> +	       &publ->ptr[1]);
> +	writel(min(dinit2, 0x1ffffU) << PRT_DINIT2_SHIFT |
> +	       DIV_ROUND_UP(ddr_freq_mhz * 1000, 1000) << PRT_DINIT3_SHIFT,
> +	       &publ->ptr[2]);
> +
> +	switch (sdram_params->base.dramtype) {
> +	case DDR3:
> +		clrbits_le32(&publ->pgcr, 0x1f);
> +		clrsetbits_le32(&publ->dcr, DDRMD_MASK << DDRMD_SHIFT,
> +				DDRMD_DDR3 << DDRMD_SHIFT);
> +		break;
> +	}
> +	if (sdram_params->base.odt) {
> +		/* Enable dynamic RTT. */
> +		for (i = 0; i < 4; i++)
> +			setbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT);
> +	} else {
> +		/* Disable dynamic RTT. */
> +		for (i = 0; i < 4; i++)
> +			clrbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT);
> +	}
> +}
> +
> +static void rk3066_dmc_phy_init(struct rk3288_ddr_publ *publ)
> +{
> +	setbits_le32(&publ->pir, PIR_INIT | PIR_DLLSRST
> +		     | PIR_DLLLOCK | PIR_ZCAL | PIR_ITMSRST | PIR_CLRSR);
> +	udelay(1);
> +	while ((readl(&publ->pgsr) &
> +		(PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE)) !=
> +	       (PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE))
> +		;
> +}
> +
> +static void rk3066_dmc_send_command(struct rk3288_ddr_pctl *pctl, u32 rank,
> +				    u32 cmd, u32 arg)
> +{
> +	writel((START_CMD | (rank << 20) | arg | cmd), &pctl->mcmd);
> +	udelay(1);
> +	while (readl(&pctl->mcmd) & START_CMD)
> +		;
> +}
> +
> +static inline void rk3066_dmc_send_command_op(struct rk3288_ddr_pctl *pctl,
> +					      u32 rank, u32 cmd, u32 ma, u32 op)
> +{
> +	rk3066_dmc_send_command(pctl, rank, cmd, (ma & LPDDR2_MA_MASK) << LPDDR2_MA_SHIFT |
> +				(op & LPDDR2_OP_MASK) << LPDDR2_OP_SHIFT);
> +}
> +
> +static void rk3066_dmc_memory_init(struct rk3288_ddr_publ *publ,
> +				   u32 dramtype)
> +{
> +	setbits_le32(&publ->pir,
> +		     (PIR_INIT | PIR_DRAMINIT | PIR_LOCKBYP
> +		      | PIR_ZCALBYP | PIR_CLRSR | PIR_ICPC
> +		      | (dramtype == DDR3 ? PIR_DRAMRST : 0)));
> +	udelay(1);
> +	while ((readl(&publ->pgsr) & (PGSR_IDONE | PGSR_DLDONE))
> +	       != (PGSR_IDONE | PGSR_DLDONE))
> +		;
> +}
> +
> +static void rk3066_dmc_move_to_config_state(struct rk3288_ddr_publ *publ,
> +					    struct rk3288_ddr_pctl *pctl)
> +{
> +	unsigned int state;
> +
> +	while (1) {
> +		state = readl(&pctl->stat) & PCTL_STAT_MSK;
> +
> +		switch (state) {
> +		case LOW_POWER:
> +			writel(WAKEUP_STATE, &pctl->sctl);
> +			while ((readl(&pctl->stat) & PCTL_STAT_MSK)
> +			       != ACCESS)
> +				;
> +			/* Wait DLL lock. */
> +			while ((readl(&publ->pgsr) & PGSR_DLDONE)
> +			       != PGSR_DLDONE)
> +				;
> +			/*
> +			 * If at low power state we need to wakeup first
> +			 * and then enter the config.
> +			 */
> +			fallthrough;
> +		case ACCESS:
> +			fallthrough;
> +		case INIT_MEM:
> +			writel(CFG_STATE, &pctl->sctl);
> +			while ((readl(&pctl->stat) & PCTL_STAT_MSK) != CONFIG)
> +				;
> +			break;
> +		case CONFIG:
> +			return;
> +		default:
> +			break;
> +		}
> +	}
> +}
> +
> +static void rk3066_dmc_set_bandwidth_ratio(const struct rk3066_dmc_chan_info *chan, int channel,
> +					   u32 n, struct rk3066_grf *grf)
> +{
> +	struct rk3288_ddr_pctl *pctl = chan->pctl;
> +	struct rk3288_ddr_publ *publ = chan->publ;
> +	struct rk3188_msch *msch = chan->msch;
> +
> +	if (n == 1) {
> +		setbits_le32(&pctl->ppcfg, 1);
> +		setbits_le32(&msch->ddrtiming, 1 << 31);
> +		/* Data byte disable. */
> +		clrbits_le32(&publ->datx8[2].dxgcr, 1);
> +		clrbits_le32(&publ->datx8[3].dxgcr, 1);
> +		/* Disable DLL. */
> +		setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS);
> +		setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS);
> +	} else {
> +		clrbits_le32(&pctl->ppcfg, 1);
> +		clrbits_le32(&msch->ddrtiming, 1 << 31);
> +		/* Data byte enable.*/
> +		setbits_le32(&publ->datx8[2].dxgcr, 1);
> +		setbits_le32(&publ->datx8[3].dxgcr, 1);
> +
> +		/* Enable DLL. */
> +		clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS);
> +		clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS);
> +		/* Reset DLL. */
> +		clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST);
> +		clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST);
> +		udelay(10);
> +		setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST);
> +		setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST);
> +	}
> +	setbits_le32(&pctl->dfistcfg0, 1 << 2);
> +}
> +
> +static int rk3066_dmc_data_training(const struct rk3066_dmc_chan_info *chan, int channel,
> +				    struct rk3066_dmc_sdram_params *sdram_params)
> +{
> +	unsigned int j;
> +	int ret = 0;
> +	u32 rank;
> +	int i;
> +	u32 step[2] = { PIR_QSTRN, PIR_RVTRN };
> +	struct rk3288_ddr_publ *publ = chan->publ;
> +	struct rk3288_ddr_pctl *pctl = chan->pctl;
> +
> +	/* Disable auto refresh. */
> +	writel(0, &pctl->trefi);
> +
> +	if (sdram_params->base.dramtype != LPDDR3)
> +		setbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT);
> +	rank = sdram_params->ch[channel].rank | 1;
> +	for (j = 0; j < ARRAY_SIZE(step); j++) {
> +		/*
> +		 * Trigger QSTRN and RVTRN.
> +		 * Clear DTDONE status.
> +		 */
> +		setbits_le32(&publ->pir, PIR_CLRSR);
> +
> +		/* Trigger DTT. */
> +		setbits_le32(&publ->pir,
> +			     PIR_INIT | step[j] | PIR_LOCKBYP | PIR_ZCALBYP |
> +			     PIR_CLRSR);
> +		udelay(1);
> +		/* Wait echo byte DTDONE. */
> +		while ((readl(&publ->datx8[0].dxgsr[0]) & rank)
> +		       != rank)
> +			;
> +		while ((readl(&publ->datx8[1].dxgsr[0]) & rank)
> +		       != rank)
> +			;
> +		if (!(readl(&pctl->ppcfg) & 1)) {
> +			while ((readl(&publ->datx8[2].dxgsr[0])
> +				& rank) != rank)
> +				;
> +			while ((readl(&publ->datx8[3].dxgsr[0])
> +				& rank) != rank)
> +				;
> +		}
> +		if (readl(&publ->pgsr) &
> +		    (PGSR_DTERR | PGSR_RVERR | PGSR_RVEIRR)) {
> +			ret = -1;
> +			break;
> +		}
> +	}
> +	/* Send some auto refresh to complement the lost while DTT. */
> +	for (i = 0; i < (rank > 1 ? 8 : 4); i++)
> +		rk3066_dmc_send_command(pctl, rank, REF_CMD, 0);
> +
> +	if (sdram_params->base.dramtype != LPDDR3)
> +		clrbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT);
> +
> +	/* Resume auto refresh. */
> +	writel(sdram_params->pctl_timing.trefi, &pctl->trefi);
> +
> +	return ret;
> +}
> +
> +static void rk3066_dmc_move_to_access_state(const struct rk3066_dmc_chan_info *chan)
> +{
> +	struct rk3288_ddr_publ *publ = chan->publ;
> +	struct rk3288_ddr_pctl *pctl = chan->pctl;
> +	unsigned int state;
> +
> +	while (1) {
> +		state = readl(&pctl->stat) & PCTL_STAT_MSK;
> +
> +		switch (state) {
> +		case LOW_POWER:
> +			if (((readl(&pctl->stat) >> LP_TRIG_SHIFT) &
> +			     LP_TRIG_MASK) == 1)
> +				return;
> +
> +			writel(WAKEUP_STATE, &pctl->sctl);
> +			while ((readl(&pctl->stat) & PCTL_STAT_MSK) != ACCESS)
> +				;
> +			/* Wait DLL lock. */
> +			while ((readl(&publ->pgsr) & PGSR_DLDONE)
> +			       != PGSR_DLDONE)
> +				;
> +			break;
> +		case INIT_MEM:
> +			writel(CFG_STATE, &pctl->sctl);
> +			while ((readl(&pctl->stat) & PCTL_STAT_MSK) != CONFIG)
> +				;
> +			fallthrough;
> +		case CONFIG:
> +			writel(GO_STATE, &pctl->sctl);
> +			while ((readl(&pctl->stat) & PCTL_STAT_MSK) == CONFIG)
> +				;
> +			break;
> +		case ACCESS:
> +			return;
> +		default:
> +			break;
> +		}
> +	}
> +}
> +
> +static void rk3066_dmc_dram_cfg_rbc(const struct rk3066_dmc_chan_info *chan, u32 chnum,
> +				    struct rk3066_dmc_sdram_params *sdram_params)
> +{
> +	struct rk3288_ddr_publ *publ = chan->publ;
> +
> +	if (sdram_params->ch[chnum].bk == 3)
> +		clrsetbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT,
> +				1 << PDQ_SHIFT);
> +	else
> +		clrbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT);
> +
> +	writel(sdram_params->base.ddrconfig, &chan->msch->ddrconf);
> +}
> +
> +static void rk3066_dmc_dram_all_config(const struct rk3066_dmc_dram_info *dram,
> +				       struct rk3066_dmc_sdram_params *sdram_params)
> +{
> +	unsigned int chan;
> +	u32 sys_reg = 0;
> +
> +	sys_reg |= sdram_params->base.dramtype << SYS_REG_DDRTYPE_SHIFT;
> +	sys_reg |= (sdram_params->num_channels - 1) << SYS_REG_NUM_CH_SHIFT;
> +	for (chan = 0; chan < sdram_params->num_channels; chan++) {
> +		const struct rk3288_sdram_channel *info =
> +				&sdram_params->ch[chan];
> +
> +		sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(chan);
> +		sys_reg |= 1 << SYS_REG_CHINFO_SHIFT(chan);
> +		sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(chan);
> +		sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(chan);
> +		sys_reg |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(chan);
> +		sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(chan);
> +		sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(chan);
> +		sys_reg |= (2 >> info->bw) << SYS_REG_BW_SHIFT(chan);
> +		sys_reg |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(chan);
> +
> +		rk3066_dmc_dram_cfg_rbc(&dram->chan[chan], chan, sdram_params);
> +	}
> +	if (sdram_params->ch[0].rank == 2)
> +		rk3066_dmc_ddr_rank_2_row15en(dram->grf, 0);
> +	else
> +		rk3066_dmc_ddr_rank_2_row15en(dram->grf, 1);
> +
> +	writel(sys_reg, &dram->pmu->sys_reg[2]);
> +}
> +
> +static int rk3066_dmc_sdram_rank_bw_detect(struct rk3066_dmc_dram_info *dram, int channel,
> +					   struct rk3066_dmc_sdram_params *sdram_params)
> +{
> +	int reg;
> +	int need_trainig = 0;
> +	const struct rk3066_dmc_chan_info *chan = &dram->chan[channel];
> +	struct rk3288_ddr_publ *publ = chan->publ;
> +
> +	rk3066_dmc_ddr_rank_2_row15en(dram->grf, 0);
> +
> +	if (rk3066_dmc_data_training(chan, channel, sdram_params) < 0) {
> +		debug("first data training fail!\n");
> +		reg = readl(&publ->datx8[0].dxgsr[0]);
> +		/* Check the result for rank 0. */
> +		if (channel == 0 && (reg & DQS_GATE_TRAINING_ERROR_RANK0)) {
> +			debug("data training fail!\n");
> +			return -EIO;
> +		}
> +
> +		/* Check the result for rank 1. */
> +		if (reg & DQS_GATE_TRAINING_ERROR_RANK1) {
> +			sdram_params->ch[channel].rank = 1;
> +			clrsetbits_le32(&publ->pgcr, 0xF << 18,
> +					sdram_params->ch[channel].rank << 18);
> +			need_trainig = 1;
> +		}
> +		reg = readl(&publ->datx8[2].dxgsr[0]);
> +		if (reg & (1 << 4)) {
> +			sdram_params->ch[channel].bw = 1;
> +			rk3066_dmc_set_bandwidth_ratio(chan, channel,
> +						       sdram_params->ch[channel].bw,
> +						       dram->grf);
> +			need_trainig = 1;
> +		}
> +	}
> +	/* Assume that the die bit width is equel to the chip bit width. */
> +	sdram_params->ch[channel].dbw = sdram_params->ch[channel].bw;
> +
> +	if (need_trainig &&
> +	    (rk3066_dmc_data_training(chan, channel, sdram_params) < 0)) {
> +		if (sdram_params->base.dramtype == LPDDR3) {
> +			rk3066_dmc_ddr_phy_ctl_reset(dram->cru, channel, 1);
> +			udelay(10);
> +			rk3066_dmc_ddr_phy_ctl_reset(dram->cru, channel, 0);
> +			udelay(10);
> +		}
> +		debug("2nd data training failed!");
> +		return -EIO;
> +	}
> +
> +	return 0;
> +}
> +
> +static int rk3066_dmc_sdram_col_row_detect(struct rk3066_dmc_dram_info *dram, int channel,
> +					   struct rk3066_dmc_sdram_params *sdram_params)
> +{
> +	int row, col;
> +	unsigned int addr;
> +	const struct rk3066_dmc_chan_info *chan = &dram->chan[channel];
> +	struct rk3288_ddr_pctl *pctl = chan->pctl;
> +	struct rk3288_ddr_publ *publ = chan->publ;
> +	int ret = 0;
> +
> +	/* Detect col. */
> +	for (col = 11; col >= 9; col--) {
> +		writel(0, CONFIG_SYS_SDRAM_BASE);
> +		addr = CONFIG_SYS_SDRAM_BASE +
> +		       (1 << (col + sdram_params->ch[channel].bw - 1));
> +		writel(TEST_PATTERN, addr);
> +		if ((readl(addr) == TEST_PATTERN) &&
> +		    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
> +			break;
> +	}
> +	if (col == 8) {
> +		debug("Col detect error\n");
> +		ret = -EINVAL;
> +		goto out;
> +	} else {
> +		sdram_params->ch[channel].col = col;
> +	}
> +
> +	rk3066_dmc_ddr_rank_2_row15en(dram->grf, 1);
> +	rk3066_dmc_move_to_config_state(publ, pctl);
> +	writel(1, &chan->msch->ddrconf);
> +	rk3066_dmc_move_to_access_state(chan);
> +	/* Detect row, max 15, min13 for rk3066 */
> +	for (row = 16; row >= 13; row--) {
> +		writel(0, CONFIG_SYS_SDRAM_BASE);
> +		addr = CONFIG_SYS_SDRAM_BASE + (1 << (row + 15 - 1));
> +		writel(TEST_PATTERN, addr);
> +		if ((readl(addr) == TEST_PATTERN) &&
> +		    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
> +			break;
> +	}
> +	if (row == 12) {
> +		debug("Row detect error\n");
> +		ret = -EINVAL;
> +	} else {
> +		sdram_params->ch[channel].cs1_row = row;
> +		sdram_params->ch[channel].row_3_4 = 0;
> +		debug("chn %d col %d, row %d\n", channel, col, row);
> +		sdram_params->ch[channel].cs0_row = row;
> +	}
> +
> +out:
> +	return ret;
> +}
> +
> +static int rk3066_dmc_sdram_get_niu_config(struct rk3066_dmc_sdram_params *sdram_params)
> +{
> +	int i, tmp, size, ret = 0;
> +
> +	tmp = sdram_params->ch[0].col - 9;
> +	tmp -= (sdram_params->ch[0].bw == 2) ? 0 : 1;
> +	tmp |= ((sdram_params->ch[0].cs0_row - 13) << 4);
> +	size = ARRAY_SIZE(rk3066_dmc_ddrconf_table) / sizeof(rk3066_dmc_ddrconf_table[0]);
> +	for (i = 0; i < size; i++)
> +		if (tmp == rk3066_dmc_ddrconf_table[i])
> +			break;
> +	if (i >= size) {
> +		debug("niu config not found\n");
> +		ret = -EINVAL;
> +	} else {
> +		debug("niu config %d\n", i);
> +		sdram_params->base.ddrconfig = i;
> +	}
> +
> +	return ret;
> +}
> +
> +static int rk3066_dmc_sdram_init(struct rk3066_dmc_dram_info *dram,
> +				 struct rk3066_dmc_sdram_params *sdram_params)
> +{
> +	int channel;
> +	int zqcr;
> +	int ret;
> +
> +	if ((sdram_params->base.dramtype == DDR3 &&
> +	     sdram_params->base.ddr_freq > 800000000)) {
> +		debug("SDRAM frequency is too high!");
> +		return -E2BIG;
> +	}
> +
> +	ret = clk_set_rate(&dram->ddr_clk, sdram_params->base.ddr_freq);
> +	if (ret) {
> +		debug("Could not set DDR clock\n");
> +		return ret;
> +	}
> +
> +	for (channel = 0; channel < 1; channel++) {
> +		const struct rk3066_dmc_chan_info *chan = &dram->chan[channel];
> +		struct rk3288_ddr_pctl *pctl = chan->pctl;
> +		struct rk3288_ddr_publ *publ = chan->publ;
> +
> +		rk3066_dmc_phy_pctrl_reset(dram->cru, publ, channel);
> +		rk3066_dmc_phy_dll_bypass_set(publ, sdram_params->base.ddr_freq);
> +
> +		rk3066_dmc_dfi_cfg(pctl, sdram_params->base.dramtype);
> +
> +		rk3066_dmc_pctl_cfg(channel, pctl, sdram_params, dram->grf);
> +
> +		rk3066_dmc_phy_cfg(chan, channel, sdram_params);
> +
> +		rk3066_dmc_phy_init(publ);
> +
> +		writel(POWER_UP_START, &pctl->powctl);
> +		while (!(readl(&pctl->powstat) & POWER_UP_DONE))
> +			;
> +
> +		rk3066_dmc_memory_init(publ, sdram_params->base.dramtype);
> +		rk3066_dmc_move_to_config_state(publ, pctl);
> +
> +		/* Use 32bit bus width for detection. */
> +		sdram_params->ch[channel].bw = 2;
> +		rk3066_dmc_set_bandwidth_ratio(chan, channel,
> +					       sdram_params->ch[channel].bw, dram->grf);
> +		/*
> +		 * set cs, using n=3 for detect
> +		 * CS0, n=1
> +		 * CS1, n=2
> +		 * CS0 & CS1, n = 3
> +		 */
> +		sdram_params->ch[channel].rank = 2;
> +		clrsetbits_le32(&publ->pgcr, 0xF << 18,
> +				(sdram_params->ch[channel].rank | 1) << 18);
> +
> +		/* DS=40ohm,ODT=155ohm */
> +		zqcr = 1 << ZDEN_SHIFT | 2 << PU_ONDIE_SHIFT |
> +		       2 << PD_ONDIE_SHIFT | 0x19 << PU_OUTPUT_SHIFT |
> +		       0x19 << PD_OUTPUT_SHIFT;
> +		writel(zqcr, &publ->zq1cr[0]);
> +		writel(zqcr, &publ->zq0cr[0]);
> +
> +		/* Detect the rank and bit-width with data-training. */
> +		writel(1, &chan->msch->ddrconf);
> +		rk3066_dmc_sdram_rank_bw_detect(dram, channel, sdram_params);
> +
> +		if (sdram_params->base.dramtype == LPDDR3) {
> +			u32 i;
> +
> +			writel(0, &pctl->mrrcfg0);
> +
> +			for (i = 0; i < 17; i++)
> +				rk3066_dmc_send_command_op(pctl, 1, MRR_CMD, i, 0);
> +		}
> +		writel(4, &chan->msch->ddrconf);
> +		rk3066_dmc_move_to_access_state(chan);
> +		/* DDR3 and LPDDR3 are always 8 bank, no need to detect. */
> +		sdram_params->ch[channel].bk = 3;
> +		/* Detect Col and Row number. */
> +		ret = rk3066_dmc_sdram_col_row_detect(dram, channel, sdram_params);
> +		if (ret)
> +			goto error;
> +	}
> +	/* Find NIU DDR configuration. */
> +	ret = rk3066_dmc_sdram_get_niu_config(sdram_params);
> +	if (ret)
> +		goto error;
> +
> +	rk3066_dmc_dram_all_config(dram, sdram_params);
> +	debug("SDRAM init OK!\n");
> +
> +	return 0;
> +error:
> +	debug("SDRAM init failed!\n");
> +	hang();
> +}
> +
> +static int rk3066_dmc_setup_sdram(struct udevice *dev)
> +{
> +	struct rk3066_dmc_dram_info *priv = dev_get_priv(dev);
> +	struct rk3066_dmc_sdram_params *params = dev_get_plat(dev);
> +
> +	return rk3066_dmc_sdram_init(priv, params);
> +}
> +
> +static int rk3066_dmc_conv_of_plat(struct udevice *dev)
> +{
> +#if CONFIG_IS_ENABLED(OF_PLATDATA)
> +	struct rk3066_dmc_sdram_params *plat = dev_get_plat(dev);
> +	struct dtd_rockchip_rk3066_dmc *of_plat = &plat->of_plat;
> +	int ret;
> +
> +	memcpy(&plat->pctl_timing, of_plat->rockchip_pctl_timing,
> +	       sizeof(plat->pctl_timing));
> +	memcpy(&plat->phy_timing, of_plat->rockchip_phy_timing,
> +	       sizeof(plat->phy_timing));
> +	memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base));
> +	/* RK3066 supports dual-channel, set default channel num to 2. */
> +	plat->num_channels = 1;
> +	ret = regmap_init_mem_plat(dev, of_plat->reg,
> +				   ARRAY_SIZE(of_plat->reg) / 2, &plat->map);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +#else
> +	return -EINVAL;
> +#endif
> +}
> +
> +static int rk3066_dmc_probe(struct udevice *dev)
> +{
> +	struct rk3066_dmc_dram_info *priv = dev_get_priv(dev);
> +
> +	priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
> +
> +	if (IS_ENABLED(CONFIG_TPL_BUILD)) {
> +		struct rk3066_dmc_sdram_params *plat = dev_get_plat(dev);
> +		struct regmap *map;
> +		struct udevice *dev_clk;
> +		int ret;
> +
> +		ret = rk3066_dmc_conv_of_plat(dev);
> +		if (ret)
> +			return ret;
> +
> +		map = syscon_get_regmap_by_driver_data(ROCKCHIP_SYSCON_NOC);
> +		if (IS_ERR(map))
> +			return PTR_ERR(map);
> +		priv->chan[0].msch = regmap_get_range(map, 0);
> +		priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
> +
> +		priv->chan[0].pctl = regmap_get_range(plat->map, 0);
> +		priv->chan[0].publ = regmap_get_range(plat->map, 1);
> +
> +		ret = rockchip_get_clk(&dev_clk);
> +		if (ret)
> +			return ret;
> +
> +		priv->ddr_clk.id = CLK_DDR;
> +		ret = clk_request(dev_clk, &priv->ddr_clk);
> +		if (ret)
> +			return ret;
> +
> +		priv->cru = rockchip_get_cru();
> +		if (IS_ERR(priv->cru))
> +			return PTR_ERR(priv->cru);
> +
> +		ret = rk3066_dmc_setup_sdram(dev);
> +		if (ret)
> +			return ret;
> +	} else {
> +		priv->info.base = CONFIG_SYS_SDRAM_BASE;
> +		priv->info.size = rockchip_sdram_size((phys_addr_t)&priv->pmu->sys_reg[2]);
> +	}
> +
> +	return 0;
> +}
> +
> +static int rk3066_dmc_get_info(struct udevice *dev, struct ram_info *info)
> +{
> +	struct rk3066_dmc_dram_info *priv = dev_get_priv(dev);
> +
> +	*info = priv->info;
> +
> +	return 0;
> +}
> +
> +static struct ram_ops rk3066_dmc_ops = {
> +	.get_info = rk3066_dmc_get_info,
> +};
> +
> +static const struct udevice_id rk3066_dmc_ids[] = {
> +	{ .compatible = "rockchip,rk3066-dmc" },
> +	{ }
> +};
> +
> +U_BOOT_DRIVER(rockchip_rk3066_dmc) = {
> +	.name		= "rockchip_rk3066_dmc",
> +	.id		= UCLASS_RAM,
> +	.ops		= &rk3066_dmc_ops,
> +	.probe		= rk3066_dmc_probe,
> +	.of_match	= rk3066_dmc_ids,
> +	.priv_auto	= sizeof(struct rk3066_dmc_dram_info),
> +#if IS_ENABLED(CONFIG_TPL_BUILD)
> +	.plat_auto	= sizeof(struct rk3066_dmc_sdram_params),
> +#endif
> +};

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v9 06/16] arm: dts: rockchip: fix rk3xxx-u-boot.dtsi
  2022-04-04 14:19 ` [PATCH v9 06/16] arm: dts: rockchip: fix rk3xxx-u-boot.dtsi Johan Jonker
@ 2022-04-09  3:50   ` Kever Yang
  0 siblings, 0 replies; 33+ messages in thread
From: Kever Yang @ 2022-04-09  3:50 UTC (permalink / raw)
  To: Johan Jonker; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot


On 2022/4/4 22:19, Johan Jonker wrote:
> The file rk3xxx-u-boot.dtsi was original only for rk3188 and SPL.
> With rk3066 added some nodes are also needed in TPL,
> so change them to u-boot,dm-pre-reloc
>
> Signed-off-by: Johan Jonker <jbx6244@gmail.com>

Reviewed-by: Kever Yang <kever.yang@rock-chips.com>

Thanks,
- Kever
> ---
>   arch/arm/dts/rk3xxx-u-boot.dtsi | 8 ++++----
>   1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/dts/rk3xxx-u-boot.dtsi b/arch/arm/dts/rk3xxx-u-boot.dtsi
> index 581594c35d..e67432fb39 100644
> --- a/arch/arm/dts/rk3xxx-u-boot.dtsi
> +++ b/arch/arm/dts/rk3xxx-u-boot.dtsi
> @@ -4,7 +4,7 @@
>   	noc: syscon@10128000 {
>   		compatible = "rockchip,rk3188-noc", "syscon";
>   		reg = <0x10128000 0x2000>;
> -		u-boot,dm-spl;
> +		u-boot,dm-pre-reloc;
>   	};
>   
>   	dmc: dmc@20020000 {
> @@ -18,16 +18,16 @@
>   		rockchip,grf = <&grf>;
>   		rockchip,pmu = <&pmu>;
>   		rockchip,noc = <&noc>;
> -		u-boot,dm-spl;
> +		u-boot,dm-pre-reloc;
>   	};
>   };
>   
>   &grf {
> -	u-boot,dm-spl;
> +	u-boot,dm-pre-reloc;
>   };
>   
>   &pmu {
> -	u-boot,dm-spl;
> +	u-boot,dm-pre-reloc;
>   };
>   
>   &uart2 {

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v9 07/16] arm: dts: rockchip: fix include rk3xxx-u-boot.dtsi
  2022-04-04 14:19 ` [PATCH v9 07/16] arm: dts: rockchip: fix include rk3xxx-u-boot.dtsi Johan Jonker
@ 2022-04-09  3:50   ` Kever Yang
  0 siblings, 0 replies; 33+ messages in thread
From: Kever Yang @ 2022-04-09  3:50 UTC (permalink / raw)
  To: Johan Jonker; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot


On 2022/4/4 22:19, Johan Jonker wrote:
> Move the include for rk3xxx-u-boot.dtsi to rk3188-u-boot.dtsi
> to stay in line with U-boot dtsi files.
>
> Signed-off-by: Johan Jonker <jbx6244@gmail.com>

Reviewed-by: Kever Yang <kever.yang@rock-chips.com>

Thanks,
- Kever
> ---
>   arch/arm/dts/rk3188-u-boot.dtsi | 1 +
>   arch/arm/dts/rk3188.dtsi        | 1 -
>   2 files changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/dts/rk3188-u-boot.dtsi b/arch/arm/dts/rk3188-u-boot.dtsi
> index 43f05b9876..735776c16b 100644
> --- a/arch/arm/dts/rk3188-u-boot.dtsi
> +++ b/arch/arm/dts/rk3188-u-boot.dtsi
> @@ -4,6 +4,7 @@
>    */
>   
>   #include "rockchip-u-boot.dtsi"
> +#include "rk3xxx-u-boot.dtsi"
>   
>   &global_timer {
>   	status = "okay";
> diff --git a/arch/arm/dts/rk3188.dtsi b/arch/arm/dts/rk3188.dtsi
> index 6c1c2ff533..6764776cce 100644
> --- a/arch/arm/dts/rk3188.dtsi
> +++ b/arch/arm/dts/rk3188.dtsi
> @@ -9,7 +9,6 @@
>   #include <dt-bindings/clock/rk3188-cru.h>
>   #include <dt-bindings/power/rk3188-power.h>
>   #include "rk3xxx.dtsi"
> -#include "rk3xxx-u-boot.dtsi"
>   
>   / {
>   	compatible = "rockchip,rk3188";

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v9 08/16] arm: dts: rockchip: add rk3066a.dtsi
  2022-04-04 14:19 ` [PATCH v9 08/16] arm: dts: rockchip: add rk3066a.dtsi Johan Jonker
@ 2022-04-09  3:52   ` Kever Yang
  0 siblings, 0 replies; 33+ messages in thread
From: Kever Yang @ 2022-04-09  3:52 UTC (permalink / raw)
  To: Johan Jonker; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot


On 2022/4/4 22:19, Johan Jonker wrote:
> In the Linux DT the file rk3xxx.dtsi is shared between
> rk3066 and rk3188. Add rk3066a.dtsi. Move U-boot specific
> things in a rk3066a-u-boot.dtsi file.
>
> Signed-off-by: Johan Jonker <jbx6244@gmail.com>

Reviewed-by: Kever Yang <kever.yang@rock-chips.com>

Thanks,
- Kever
> ---
>
> Changed V9:
>    fix include rk3066a-u-boot.dtsi
>
> Changed V8:
>    update dtsi
> ---
>   arch/arm/dts/rk3066a-u-boot.dtsi |   4 +
>   arch/arm/dts/rk3066a.dtsi        | 879 +++++++++++++++++++++++++++++++
>   2 files changed, 883 insertions(+)
>   create mode 100644 arch/arm/dts/rk3066a-u-boot.dtsi
>   create mode 100644 arch/arm/dts/rk3066a.dtsi
>
> diff --git a/arch/arm/dts/rk3066a-u-boot.dtsi b/arch/arm/dts/rk3066a-u-boot.dtsi
> new file mode 100644
> index 0000000000..bc6e609d02
> --- /dev/null
> +++ b/arch/arm/dts/rk3066a-u-boot.dtsi
> @@ -0,0 +1,4 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +#include "rockchip-u-boot.dtsi"
> +#include "rk3xxx-u-boot.dtsi"
> diff --git a/arch/arm/dts/rk3066a.dtsi b/arch/arm/dts/rk3066a.dtsi
> new file mode 100644
> index 0000000000..c25b9695db
> --- /dev/null
> +++ b/arch/arm/dts/rk3066a.dtsi
> @@ -0,0 +1,879 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2013 MundoReader S.L.
> + * Author: Heiko Stuebner <heiko@sntech.de>
> + */
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/pinctrl/rockchip.h>
> +#include <dt-bindings/clock/rk3066a-cru.h>
> +#include <dt-bindings/power/rk3066-power.h>
> +#include "rk3xxx.dtsi"
> +
> +/ {
> +	compatible = "rockchip,rk3066a";
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		enable-method = "rockchip,rk3066-smp";
> +
> +		cpu0: cpu@0 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a9";
> +			next-level-cache = <&L2>;
> +			reg = <0x0>;
> +			operating-points =
> +				/* kHz    uV */
> +				<1416000 1300000>,
> +				<1200000 1175000>,
> +				<1008000 1125000>,
> +				<816000  1125000>,
> +				<600000  1100000>,
> +				<504000  1100000>,
> +				<312000  1075000>;
> +			clock-latency = <40000>;
> +			clocks = <&cru ARMCLK>;
> +		};
> +		cpu1: cpu@1 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a9";
> +			next-level-cache = <&L2>;
> +			reg = <0x1>;
> +		};
> +	};
> +
> +	display-subsystem {
> +		compatible = "rockchip,display-subsystem";
> +		ports = <&vop0_out>, <&vop1_out>;
> +	};
> +
> +	sram: sram@10080000 {
> +		compatible = "mmio-sram";
> +		reg = <0x10080000 0x10000>;
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges = <0 0x10080000 0x10000>;
> +
> +		smp-sram@0 {
> +			compatible = "rockchip,rk3066-smp-sram";
> +			reg = <0x0 0x50>;
> +		};
> +	};
> +
> +	vop0: vop@1010c000 {
> +		compatible = "rockchip,rk3066-vop";
> +		reg = <0x1010c000 0x19c>;
> +		interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru ACLK_LCDC0>,
> +			 <&cru DCLK_LCDC0>,
> +			 <&cru HCLK_LCDC0>;
> +		clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
> +		power-domains = <&power RK3066_PD_VIO>;
> +		resets = <&cru SRST_LCDC0_AXI>,
> +			 <&cru SRST_LCDC0_AHB>,
> +			 <&cru SRST_LCDC0_DCLK>;
> +		reset-names = "axi", "ahb", "dclk";
> +		status = "disabled";
> +
> +		vop0_out: port {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			vop0_out_hdmi: endpoint@0 {
> +				reg = <0>;
> +				remote-endpoint = <&hdmi_in_vop0>;
> +			};
> +		};
> +	};
> +
> +	vop1: vop@1010e000 {
> +		compatible = "rockchip,rk3066-vop";
> +		reg = <0x1010e000 0x19c>;
> +		interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru ACLK_LCDC1>,
> +			 <&cru DCLK_LCDC1>,
> +			 <&cru HCLK_LCDC1>;
> +		clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
> +		power-domains = <&power RK3066_PD_VIO>;
> +		resets = <&cru SRST_LCDC1_AXI>,
> +			 <&cru SRST_LCDC1_AHB>,
> +			 <&cru SRST_LCDC1_DCLK>;
> +		reset-names = "axi", "ahb", "dclk";
> +		status = "disabled";
> +
> +		vop1_out: port {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			vop1_out_hdmi: endpoint@0 {
> +				reg = <0>;
> +				remote-endpoint = <&hdmi_in_vop1>;
> +			};
> +		};
> +	};
> +
> +	hdmi: hdmi@10116000 {
> +		compatible = "rockchip,rk3066-hdmi";
> +		reg = <0x10116000 0x2000>;
> +		interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru HCLK_HDMI>;
> +		clock-names = "hclk";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&hdmii2c_xfer>, <&hdmi_hpd>;
> +		power-domains = <&power RK3066_PD_VIO>;
> +		rockchip,grf = <&grf>;
> +		status = "disabled";
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			hdmi_in: port@0 {
> +				reg = <0>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +
> +				hdmi_in_vop0: endpoint@0 {
> +					reg = <0>;
> +					remote-endpoint = <&vop0_out_hdmi>;
> +				};
> +
> +				hdmi_in_vop1: endpoint@1 {
> +					reg = <1>;
> +					remote-endpoint = <&vop1_out_hdmi>;
> +				};
> +			};
> +
> +			hdmi_out: port@1 {
> +				reg = <1>;
> +			};
> +		};
> +	};
> +
> +	i2s0: i2s@10118000 {
> +		compatible = "rockchip,rk3066-i2s";
> +		reg = <0x10118000 0x2000>;
> +		interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&i2s0_bus>;
> +		clocks = <&cru SCLK_I2S0>, <&cru HCLK_I2S0>;
> +		clock-names = "i2s_clk", "i2s_hclk";
> +		dmas = <&dmac1_s 4>, <&dmac1_s 5>;
> +		dma-names = "tx", "rx";
> +		rockchip,playback-channels = <8>;
> +		rockchip,capture-channels = <2>;
> +		#sound-dai-cells = <0>;
> +		status = "disabled";
> +	};
> +
> +	i2s1: i2s@1011a000 {
> +		compatible = "rockchip,rk3066-i2s";
> +		reg = <0x1011a000 0x2000>;
> +		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&i2s1_bus>;
> +		clocks = <&cru SCLK_I2S1>, <&cru HCLK_I2S1>;
> +		clock-names = "i2s_clk", "i2s_hclk";
> +		dmas = <&dmac1_s 6>, <&dmac1_s 7>;
> +		dma-names = "tx", "rx";
> +		rockchip,playback-channels = <2>;
> +		rockchip,capture-channels = <2>;
> +		#sound-dai-cells = <0>;
> +		status = "disabled";
> +	};
> +
> +	i2s2: i2s@1011c000 {
> +		compatible = "rockchip,rk3066-i2s";
> +		reg = <0x1011c000 0x2000>;
> +		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&i2s2_bus>;
> +		clocks = <&cru SCLK_I2S2>, <&cru HCLK_I2S2>;
> +		clock-names = "i2s_clk", "i2s_hclk";
> +		dmas = <&dmac1_s 9>, <&dmac1_s 10>;
> +		dma-names = "tx", "rx";
> +		rockchip,playback-channels = <2>;
> +		rockchip,capture-channels = <2>;
> +		#sound-dai-cells = <0>;
> +		status = "disabled";
> +	};
> +
> +	cru: clock-controller@20000000 {
> +		compatible = "rockchip,rk3066a-cru";
> +		reg = <0x20000000 0x1000>;
> +		rockchip,grf = <&grf>;
> +
> +		#clock-cells = <1>;
> +		#reset-cells = <1>;
> +		assigned-clocks = <&cru PLL_CPLL>, <&cru PLL_GPLL>,
> +				  <&cru ACLK_CPU>, <&cru HCLK_CPU>,
> +				  <&cru PCLK_CPU>, <&cru ACLK_PERI>,
> +				  <&cru HCLK_PERI>, <&cru PCLK_PERI>;
> +		assigned-clock-rates = <400000000>, <594000000>,
> +				       <300000000>, <150000000>,
> +				       <75000000>, <300000000>,
> +				       <150000000>, <75000000>;
> +	};
> +
> +	timer2: timer@2000e000 {
> +		compatible = "snps,dw-apb-timer";
> +		reg = <0x2000e000 0x100>;
> +		interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru SCLK_TIMER2>, <&cru PCLK_TIMER2>;
> +		clock-names = "timer", "pclk";
> +	};
> +
> +	efuse: efuse@20010000 {
> +		compatible = "rockchip,rk3066a-efuse";
> +		reg = <0x20010000 0x4000>;
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		clocks = <&cru PCLK_EFUSE>;
> +		clock-names = "pclk_efuse";
> +
> +		cpu_leakage: cpu_leakage@17 {
> +			reg = <0x17 0x1>;
> +		};
> +	};
> +
> +	timer0: timer@20038000 {
> +		compatible = "snps,dw-apb-timer";
> +		reg = <0x20038000 0x100>;
> +		interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru SCLK_TIMER0>, <&cru PCLK_TIMER0>;
> +		clock-names = "timer", "pclk";
> +	};
> +
> +	timer1: timer@2003a000 {
> +		compatible = "snps,dw-apb-timer";
> +		reg = <0x2003a000 0x100>;
> +		interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru SCLK_TIMER1>, <&cru PCLK_TIMER1>;
> +		clock-names = "timer", "pclk";
> +	};
> +
> +	tsadc: tsadc@20060000 {
> +		compatible = "rockchip,rk3066-tsadc";
> +		reg = <0x20060000 0x100>;
> +		clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>;
> +		clock-names = "saradc", "apb_pclk";
> +		interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
> +		#io-channel-cells = <1>;
> +		resets = <&cru SRST_TSADC>;
> +		reset-names = "saradc-apb";
> +		status = "disabled";
> +	};
> +
> +	pinctrl: pinctrl {
> +		compatible = "rockchip,rk3066a-pinctrl";
> +		rockchip,grf = <&grf>;
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		gpio0: gpio@20034000 {
> +			compatible = "rockchip,gpio-bank";
> +			reg = <0x20034000 0x100>;
> +			interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cru PCLK_GPIO0>;
> +
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +		};
> +
> +		gpio1: gpio@2003c000 {
> +			compatible = "rockchip,gpio-bank";
> +			reg = <0x2003c000 0x100>;
> +			interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cru PCLK_GPIO1>;
> +
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +		};
> +
> +		gpio2: gpio@2003e000 {
> +			compatible = "rockchip,gpio-bank";
> +			reg = <0x2003e000 0x100>;
> +			interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cru PCLK_GPIO2>;
> +
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +		};
> +
> +		gpio3: gpio@20080000 {
> +			compatible = "rockchip,gpio-bank";
> +			reg = <0x20080000 0x100>;
> +			interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cru PCLK_GPIO3>;
> +
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +		};
> +
> +		gpio4: gpio@20084000 {
> +			compatible = "rockchip,gpio-bank";
> +			reg = <0x20084000 0x100>;
> +			interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cru PCLK_GPIO4>;
> +
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +		};
> +
> +		gpio6: gpio@2000a000 {
> +			compatible = "rockchip,gpio-bank";
> +			reg = <0x2000a000 0x100>;
> +			interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cru PCLK_GPIO6>;
> +
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +		};
> +
> +		pcfg_pull_default: pcfg-pull-default {
> +			bias-pull-pin-default;
> +		};
> +
> +		pcfg_pull_none: pcfg-pull-none {
> +			bias-disable;
> +		};
> +
> +		emac {
> +			emac_xfer: emac-xfer {
> +				rockchip,pins = <1 RK_PC0 2 &pcfg_pull_none>, /* mac_clk */
> +						<1 RK_PC1 2 &pcfg_pull_none>, /* tx_en */
> +						<1 RK_PC2 2 &pcfg_pull_none>, /* txd1 */
> +						<1 RK_PC3 2 &pcfg_pull_none>, /* txd0 */
> +						<1 RK_PC4 2 &pcfg_pull_none>, /* rx_err */
> +						<1 RK_PC5 2 &pcfg_pull_none>, /* crs_dvalid */
> +						<1 RK_PC6 2 &pcfg_pull_none>, /* rxd1 */
> +						<1 RK_PC7 2 &pcfg_pull_none>; /* rxd0 */
> +			};
> +
> +			emac_mdio: emac-mdio {
> +				rockchip,pins = <1 RK_PD0 2 &pcfg_pull_none>, /* mac_md */
> +						<1 RK_PD1 2 &pcfg_pull_none>; /* mac_mdclk */
> +			};
> +		};
> +
> +		emmc {
> +			emmc_clk: emmc-clk {
> +				rockchip,pins = <3 RK_PD7 2 &pcfg_pull_default>;
> +			};
> +
> +			emmc_cmd: emmc-cmd {
> +				rockchip,pins = <4 RK_PB1 2 &pcfg_pull_default>;
> +			};
> +
> +			emmc_rst: emmc-rst {
> +				rockchip,pins = <4 RK_PB2 2 &pcfg_pull_default>;
> +			};
> +
> +			/*
> +			 * The data pins are shared between nandc and emmc and
> +			 * not accessible through pinctrl. Also they should've
> +			 * been already set correctly by firmware, as
> +			 * flash/emmc is the boot-device.
> +			 */
> +		};
> +
> +		hdmi {
> +			hdmi_hpd: hdmi-hpd {
> +				rockchip,pins = <0 RK_PA0 1 &pcfg_pull_default>;
> +			};
> +
> +			hdmii2c_xfer: hdmii2c-xfer {
> +				rockchip,pins = <0 RK_PA1 1 &pcfg_pull_none>,
> +						<0 RK_PA2 1 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		i2c0 {
> +			i2c0_xfer: i2c0-xfer {
> +				rockchip,pins = <2 RK_PD4 1 &pcfg_pull_none>,
> +						<2 RK_PD5 1 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		i2c1 {
> +			i2c1_xfer: i2c1-xfer {
> +				rockchip,pins = <2 RK_PD6 1 &pcfg_pull_none>,
> +						<2 RK_PD7 1 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		i2c2 {
> +			i2c2_xfer: i2c2-xfer {
> +				rockchip,pins = <3 RK_PA0 1 &pcfg_pull_none>,
> +						<3 RK_PA1 1 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		i2c3 {
> +			i2c3_xfer: i2c3-xfer {
> +				rockchip,pins = <3 RK_PA2 2 &pcfg_pull_none>,
> +						<3 RK_PA3 2 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		i2c4 {
> +			i2c4_xfer: i2c4-xfer {
> +				rockchip,pins = <3 RK_PA4 1 &pcfg_pull_none>,
> +						<3 RK_PA5 1 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		pwm0 {
> +			pwm0_out: pwm0-out {
> +				rockchip,pins = <0 RK_PA3 1 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		pwm1 {
> +			pwm1_out: pwm1-out {
> +				rockchip,pins = <0 RK_PA4 1 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		pwm2 {
> +			pwm2_out: pwm2-out {
> +				rockchip,pins = <0 RK_PD6 1 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		pwm3 {
> +			pwm3_out: pwm3-out {
> +				rockchip,pins = <0 RK_PD7 1 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		spi0 {
> +			spi0_clk: spi0-clk {
> +				rockchip,pins = <1 RK_PA5 2 &pcfg_pull_default>;
> +			};
> +			spi0_cs0: spi0-cs0 {
> +				rockchip,pins = <1 RK_PA4 2 &pcfg_pull_default>;
> +			};
> +			spi0_tx: spi0-tx {
> +				rockchip,pins = <1 RK_PA7 2 &pcfg_pull_default>;
> +			};
> +			spi0_rx: spi0-rx {
> +				rockchip,pins = <1 RK_PA6 2 &pcfg_pull_default>;
> +			};
> +			spi0_cs1: spi0-cs1 {
> +				rockchip,pins = <4 RK_PB7 1 &pcfg_pull_default>;
> +			};
> +		};
> +
> +		spi1 {
> +			spi1_clk: spi1-clk {
> +				rockchip,pins = <2 RK_PC3 2 &pcfg_pull_default>;
> +			};
> +			spi1_cs0: spi1-cs0 {
> +				rockchip,pins = <2 RK_PC4 2 &pcfg_pull_default>;
> +			};
> +			spi1_rx: spi1-rx {
> +				rockchip,pins = <2 RK_PC6 2 &pcfg_pull_default>;
> +			};
> +			spi1_tx: spi1-tx {
> +				rockchip,pins = <2 RK_PC5 2 &pcfg_pull_default>;
> +			};
> +			spi1_cs1: spi1-cs1 {
> +				rockchip,pins = <2 RK_PC7 2 &pcfg_pull_default>;
> +			};
> +		};
> +
> +		uart0 {
> +			uart0_xfer: uart0-xfer {
> +				rockchip,pins = <1 RK_PA0 1 &pcfg_pull_default>,
> +						<1 RK_PA1 1 &pcfg_pull_default>;
> +			};
> +
> +			uart0_cts: uart0-cts {
> +				rockchip,pins = <1 RK_PA2 1 &pcfg_pull_default>;
> +			};
> +
> +			uart0_rts: uart0-rts {
> +				rockchip,pins = <1 RK_PA3 1 &pcfg_pull_default>;
> +			};
> +		};
> +
> +		uart1 {
> +			uart1_xfer: uart1-xfer {
> +				rockchip,pins = <1 RK_PA4 1 &pcfg_pull_default>,
> +						<1 RK_PA5 1 &pcfg_pull_default>;
> +			};
> +
> +			uart1_cts: uart1-cts {
> +				rockchip,pins = <1 RK_PA6 1 &pcfg_pull_default>;
> +			};
> +
> +			uart1_rts: uart1-rts {
> +				rockchip,pins = <1 RK_PA7 1 &pcfg_pull_default>;
> +			};
> +		};
> +
> +		uart2 {
> +			uart2_xfer: uart2-xfer {
> +				rockchip,pins = <1 RK_PB0 1 &pcfg_pull_default>,
> +						<1 RK_PB1 1 &pcfg_pull_default>;
> +			};
> +			/* no rts / cts for uart2 */
> +		};
> +
> +		uart3 {
> +			uart3_xfer: uart3-xfer {
> +				rockchip,pins = <3 RK_PD3 1 &pcfg_pull_default>,
> +						<3 RK_PD4 1 &pcfg_pull_default>;
> +			};
> +
> +			uart3_cts: uart3-cts {
> +				rockchip,pins = <3 RK_PD5 1 &pcfg_pull_default>;
> +			};
> +
> +			uart3_rts: uart3-rts {
> +				rockchip,pins = <3 RK_PD6 1 &pcfg_pull_default>;
> +			};
> +		};
> +
> +		sd0 {
> +			sd0_clk: sd0-clk {
> +				rockchip,pins = <3 RK_PB0 1 &pcfg_pull_default>;
> +			};
> +
> +			sd0_cmd: sd0-cmd {
> +				rockchip,pins = <3 RK_PB1 1 &pcfg_pull_default>;
> +			};
> +
> +			sd0_cd: sd0-cd {
> +				rockchip,pins = <3 RK_PB6 1 &pcfg_pull_default>;
> +			};
> +
> +			sd0_wp: sd0-wp {
> +				rockchip,pins = <3 RK_PB7 1 &pcfg_pull_default>;
> +			};
> +
> +			sd0_bus1: sd0-bus-width1 {
> +				rockchip,pins = <3 RK_PB2 1 &pcfg_pull_default>;
> +			};
> +
> +			sd0_bus4: sd0-bus-width4 {
> +				rockchip,pins = <3 RK_PB2 1 &pcfg_pull_default>,
> +						<3 RK_PB3 1 &pcfg_pull_default>,
> +						<3 RK_PB4 1 &pcfg_pull_default>,
> +						<3 RK_PB5 1 &pcfg_pull_default>;
> +			};
> +		};
> +
> +		sd1 {
> +			sd1_clk: sd1-clk {
> +				rockchip,pins = <3 RK_PC5 1 &pcfg_pull_default>;
> +			};
> +
> +			sd1_cmd: sd1-cmd {
> +				rockchip,pins = <3 RK_PC0 1 &pcfg_pull_default>;
> +			};
> +
> +			sd1_cd: sd1-cd {
> +				rockchip,pins = <3 RK_PC6 1 &pcfg_pull_default>;
> +			};
> +
> +			sd1_wp: sd1-wp {
> +				rockchip,pins = <3 RK_PC7 1 &pcfg_pull_default>;
> +			};
> +
> +			sd1_bus1: sd1-bus-width1 {
> +				rockchip,pins = <3 RK_PC1 1 &pcfg_pull_default>;
> +			};
> +
> +			sd1_bus4: sd1-bus-width4 {
> +				rockchip,pins = <3 RK_PC1 1 &pcfg_pull_default>,
> +						<3 RK_PC2 1 &pcfg_pull_default>,
> +						<3 RK_PC3 1 &pcfg_pull_default>,
> +						<3 RK_PC4 1 &pcfg_pull_default>;
> +			};
> +		};
> +
> +		i2s0 {
> +			i2s0_bus: i2s0-bus {
> +				rockchip,pins = <0 RK_PA7 1 &pcfg_pull_default>,
> +						<0 RK_PB0 1 &pcfg_pull_default>,
> +						<0 RK_PB1 1 &pcfg_pull_default>,
> +						<0 RK_PB2 1 &pcfg_pull_default>,
> +						<0 RK_PB3 1 &pcfg_pull_default>,
> +						<0 RK_PB4 1 &pcfg_pull_default>,
> +						<0 RK_PB5 1 &pcfg_pull_default>,
> +						<0 RK_PB6 1 &pcfg_pull_default>,
> +						<0 RK_PB7 1 &pcfg_pull_default>;
> +			};
> +		};
> +
> +		i2s1 {
> +			i2s1_bus: i2s1-bus {
> +				rockchip,pins = <0 RK_PC0 1 &pcfg_pull_default>,
> +						<0 RK_PC1 1 &pcfg_pull_default>,
> +						<0 RK_PC2 1 &pcfg_pull_default>,
> +						<0 RK_PC3 1 &pcfg_pull_default>,
> +						<0 RK_PC4 1 &pcfg_pull_default>,
> +						<0 RK_PC5 1 &pcfg_pull_default>;
> +			};
> +		};
> +
> +		i2s2 {
> +			i2s2_bus: i2s2-bus {
> +				rockchip,pins = <0 RK_PD0 1 &pcfg_pull_default>,
> +						<0 RK_PD1 1 &pcfg_pull_default>,
> +						<0 RK_PD2 1 &pcfg_pull_default>,
> +						<0 RK_PD3 1 &pcfg_pull_default>,
> +						<0 RK_PD4 1 &pcfg_pull_default>,
> +						<0 RK_PD5 1 &pcfg_pull_default>;
> +			};
> +		};
> +	};
> +};
> +
> +&gpu {
> +	compatible = "rockchip,rk3066-mali", "arm,mali-400";
> +	interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
> +		     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
> +		     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
> +		     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
> +		     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
> +		     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
> +		     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
> +		     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
> +		     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
> +		     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
> +	interrupt-names = "gp",
> +			  "gpmmu",
> +			  "pp0",
> +			  "ppmmu0",
> +			  "pp1",
> +			  "ppmmu1",
> +			  "pp2",
> +			  "ppmmu2",
> +			  "pp3",
> +			  "ppmmu3";
> +	power-domains = <&power RK3066_PD_GPU>;
> +};
> +
> +&grf {
> +	compatible = "rockchip,rk3066-grf", "syscon", "simple-mfd";
> +
> +	usbphy: usbphy {
> +		compatible = "rockchip,rk3066a-usb-phy";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		status = "disabled";
> +
> +		usbphy0: usb-phy@17c {
> +			reg = <0x17c>;
> +			clocks = <&cru SCLK_OTGPHY0>;
> +			clock-names = "phyclk";
> +			#clock-cells = <0>;
> +			#phy-cells = <0>;
> +		};
> +
> +		usbphy1: usb-phy@188 {
> +			reg = <0x188>;
> +			clocks = <&cru SCLK_OTGPHY1>;
> +			clock-names = "phyclk";
> +			#clock-cells = <0>;
> +			#phy-cells = <0>;
> +		};
> +	};
> +};
> +
> +&i2c0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c0_xfer>;
> +};
> +
> +&i2c1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c1_xfer>;
> +};
> +
> +&i2c2 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c2_xfer>;
> +};
> +
> +&i2c3 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c3_xfer>;
> +};
> +
> +&i2c4 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c4_xfer>;
> +};
> +
> +&mmc0 {
> +	clock-frequency = <50000000>;
> +	dmas = <&dmac2 1>;
> +	dma-names = "rx-tx";
> +	max-frequency = <50000000>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_bus4>;
> +};
> +
> +&mmc1 {
> +	dmas = <&dmac2 3>;
> +	dma-names = "rx-tx";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_cd &sd1_bus4>;
> +};
> +
> +&emmc {
> +	dmas = <&dmac2 4>;
> +	dma-names = "rx-tx";
> +};
> +
> +&pmu {
> +	power: power-controller {
> +		compatible = "rockchip,rk3066-power-controller";
> +		#power-domain-cells = <1>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		power-domain@RK3066_PD_VIO {
> +			reg = <RK3066_PD_VIO>;
> +			clocks = <&cru ACLK_LCDC0>,
> +				 <&cru ACLK_LCDC1>,
> +				 <&cru DCLK_LCDC0>,
> +				 <&cru DCLK_LCDC1>,
> +				 <&cru HCLK_LCDC0>,
> +				 <&cru HCLK_LCDC1>,
> +				 <&cru SCLK_CIF1>,
> +				 <&cru ACLK_CIF1>,
> +				 <&cru HCLK_CIF1>,
> +				 <&cru SCLK_CIF0>,
> +				 <&cru ACLK_CIF0>,
> +				 <&cru HCLK_CIF0>,
> +				 <&cru HCLK_HDMI>,
> +				 <&cru ACLK_IPP>,
> +				 <&cru HCLK_IPP>,
> +				 <&cru ACLK_RGA>,
> +				 <&cru HCLK_RGA>;
> +			pm_qos = <&qos_lcdc0>,
> +				 <&qos_lcdc1>,
> +				 <&qos_cif0>,
> +				 <&qos_cif1>,
> +				 <&qos_ipp>,
> +				 <&qos_rga>;
> +			#power-domain-cells = <0>;
> +		};
> +
> +		power-domain@RK3066_PD_VIDEO {
> +			reg = <RK3066_PD_VIDEO>;
> +			clocks = <&cru ACLK_VDPU>,
> +				 <&cru ACLK_VEPU>,
> +				 <&cru HCLK_VDPU>,
> +				 <&cru HCLK_VEPU>;
> +			pm_qos = <&qos_vpu>;
> +			#power-domain-cells = <0>;
> +		};
> +
> +		power-domain@RK3066_PD_GPU {
> +			reg = <RK3066_PD_GPU>;
> +			clocks = <&cru ACLK_GPU>;
> +			pm_qos = <&qos_gpu>;
> +			#power-domain-cells = <0>;
> +		};
> +	};
> +};
> +
> +&pwm0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pwm0_out>;
> +};
> +
> +&pwm1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pwm1_out>;
> +};
> +
> +&pwm2 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pwm2_out>;
> +};
> +
> +&pwm3 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pwm3_out>;
> +};
> +
> +&spi0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0>;
> +};
> +
> +&spi1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&spi1_clk &spi1_tx &spi1_rx &spi1_cs0>;
> +};
> +
> +&uart0 {
> +	compatible = "rockchip,rk3066-uart", "snps,dw-apb-uart";
> +	dmas = <&dmac1_s 0>, <&dmac1_s 1>;
> +	dma-names = "tx", "rx";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart0_xfer>;
> +};
> +
> +&uart1 {
> +	compatible = "rockchip,rk3066-uart", "snps,dw-apb-uart";
> +	dmas = <&dmac1_s 2>, <&dmac1_s 3>;
> +	dma-names = "tx", "rx";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart1_xfer>;
> +};
> +
> +&uart2 {
> +	compatible = "rockchip,rk3066-uart", "snps,dw-apb-uart";
> +	dmas = <&dmac2 6>, <&dmac2 7>;
> +	dma-names = "tx", "rx";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart2_xfer>;
> +};
> +
> +&uart3 {
> +	compatible = "rockchip,rk3066-uart", "snps,dw-apb-uart";
> +	dmas = <&dmac2 8>, <&dmac2 9>;
> +	dma-names = "tx", "rx";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart3_xfer>;
> +};
> +
> +&vpu {
> +	power-domains = <&power RK3066_PD_VIDEO>;
> +};
> +
> +&wdt {
> +	compatible = "rockchip,rk3066-wdt", "snps,dw-wdt";
> +};
> +
> +&emac {
> +	compatible = "rockchip,rk3066-emac";
> +};

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v9 09/16] arm: dts: rockchip: add rk3066a-mk808.dts
  2022-04-04 14:19 ` [PATCH v9 09/16] arm: dts: rockchip: add rk3066a-mk808.dts Johan Jonker
@ 2022-04-09  3:52   ` Kever Yang
  0 siblings, 0 replies; 33+ messages in thread
From: Kever Yang @ 2022-04-09  3:52 UTC (permalink / raw)
  To: Johan Jonker; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot


On 2022/4/4 22:19, Johan Jonker wrote:
> MK808 is a RK3066-based board with 1 USB host and 1 USB OTG port,
> HDMI and a micro-SD card slot. It also includes on-board NAND
> and 1GB of SDRAM. Add rk3066a-mk808.dts. Move U-boot specific
> things in a rk3066a-mk808-u-boot.dtsi file.
>
> Signed-off-by: Johan Jonker <jbx6244@gmail.com>

Reviewed-by: Kever Yang <kever.yang@rock-chips.com>

Thanks,
- Kever
> ---
>
> Changed V9:
>    add led config
>    move dtb-$() in Makefile
>
> Changed V8:
>    update dts
> ---
>   arch/arm/dts/Makefile                  |   3 +
>   arch/arm/dts/rk3066a-mk808-u-boot.dtsi |  48 ++++++
>   arch/arm/dts/rk3066a-mk808.dts         | 216 +++++++++++++++++++++++++
>   3 files changed, 267 insertions(+)
>   create mode 100644 arch/arm/dts/rk3066a-mk808-u-boot.dtsi
>   create mode 100644 arch/arm/dts/rk3066a-mk808.dts
>
> diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
> index 99dc7bc777..e8657bed09 100644
> --- a/arch/arm/dts/Makefile
> +++ b/arch/arm/dts/Makefile
> @@ -90,6 +90,9 @@ dtb-$(CONFIG_ROCKCHIP_PX30) += \
>   dtb-$(CONFIG_ROCKCHIP_RK3036) += \
>   	rk3036-sdk.dtb
>   
> +dtb-$(CONFIG_ROCKCHIP_RK3066) += \
> +	rk3066a-mk808.dtb
> +
>   dtb-$(CONFIG_ROCKCHIP_RK3128) += \
>   	rk3128-evb.dtb
>   
> diff --git a/arch/arm/dts/rk3066a-mk808-u-boot.dtsi b/arch/arm/dts/rk3066a-mk808-u-boot.dtsi
> new file mode 100644
> index 0000000000..3ea5fd9511
> --- /dev/null
> +++ b/arch/arm/dts/rk3066a-mk808-u-boot.dtsi
> @@ -0,0 +1,48 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +
> +#include "rk3066a-u-boot.dtsi"
> +
> +/ {
> +	config {
> +		u-boot,boot-led = "mk808:blue:power";
> +	};
> +};
> +
> +&cru {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&dmc {
> +	compatible = "rockchip,rk3066-dmc", "syscon";
> +	rockchip,pctl-timing = <0x12c 0xc8 0x1f4 0x1e 0x4e 0x4 0x69 0x6
> +				0x3 0x0 0x6 0x5 0xc 0x10 0x6 0x4
> +				0x4 0x5 0x4 0x200 0x3 0xa 0x40 0x0
> +				0x1 0x5 0x5 0x3 0xc 0x1e 0x100 0x0
> +				0x4 0x0>;
> +	rockchip,phy-timing = <0x208c6690 0x690878 0x10022a00
> +			       0x220 0x40 0x0 0x0>;
> +	rockchip,sdram-params = <0x24716310 0 2 300000000 3 9 0>;
> +};
> +
> +&mmc0 {
> +	fifo-mode;
> +	max-frequency = <4000000>;
> +	u-boot,dm-spl;
> +};
> +
> +&mmc1 {
> +	status = "disabled";
> +};
> +
> +&noc {
> +	compatible = "rockchip,rk3066-noc", "syscon";
> +};
> +
> +&timer2 {
> +	clock-frequency = <24000000>;
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&uart2 {
> +	u-boot,dm-pre-reloc;
> +};
> diff --git a/arch/arm/dts/rk3066a-mk808.dts b/arch/arm/dts/rk3066a-mk808.dts
> new file mode 100644
> index 0000000000..667d57a4ff
> --- /dev/null
> +++ b/arch/arm/dts/rk3066a-mk808.dts
> @@ -0,0 +1,216 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2016 Paweł Jarosz <paweljarosz3691@gmail.com>
> + */
> +
> +/dts-v1/;
> +#include <dt-bindings/input/input.h>
> +#include "rk3066a.dtsi"
> +
> +/ {
> +	model = "Rikomagic MK808";
> +	compatible = "rikomagic,mk808", "rockchip,rk3066a";
> +
> +	aliases {
> +		mmc0 = &mmc0;
> +		mmc1 = &mmc1;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial2:115200n8";
> +	};
> +
> +	memory@60000000 {
> +		reg = <0x60000000 0x40000000>;
> +		device_type = "memory";
> +	};
> +
> +	adc-keys {
> +		compatible = "adc-keys";
> +		io-channels = <&saradc 1>;
> +		io-channel-names = "buttons";
> +		keyup-threshold-microvolt = <2500000>;
> +		poll-interval = <100>;
> +
> +		recovery {
> +			label = "recovery";
> +			linux,code = <KEY_VENDOR>;
> +			press-threshold-microvolt = <0>;
> +		};
> +	};
> +
> +	gpio-leds {
> +		compatible = "gpio-leds";
> +
> +		blue_led: led-0 {
> +			label = "mk808:blue:power";
> +			gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>;
> +			default-state = "off";
> +			linux,default-trigger = "default-on";
> +		};
> +	};
> +
> +	hdmi_con {
> +		compatible = "hdmi-connector";
> +		type = "c";
> +
> +		port {
> +			hdmi_con_in: endpoint {
> +				remote-endpoint = <&hdmi_out_con>;
> +			};
> +		};
> +	};
> +
> +	vcc_2v5: vcc-2v5 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc_2v5";
> +		regulator-min-microvolt = <2500000>;
> +		regulator-max-microvolt = <2500000>;
> +	};
> +
> +	vcc_io: vcc-io {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc_io";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +	};
> +
> +	vcc_host: usb-host-regulator {
> +		compatible = "regulator-fixed";
> +		enable-active-high;
> +		gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
> +		pinctrl-0 = <&host_drv>;
> +		pinctrl-names = "default";
> +		regulator-always-on;
> +		regulator-name = "host-pwr";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		startup-delay-us = <100000>;
> +		vin-supply = <&vcc_io>;
> +	};
> +
> +	vcc_otg: usb-otg-regulator {
> +		compatible = "regulator-fixed";
> +		enable-active-high;
> +		gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
> +		pinctrl-0 = <&otg_drv>;
> +		pinctrl-names = "default";
> +		regulator-always-on;
> +		regulator-name = "vcc_otg";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		startup-delay-us = <100000>;
> +		vin-supply = <&vcc_io>;
> +	};
> +
> +	vcc_sd: sdmmc-regulator {
> +		compatible = "regulator-fixed";
> +		gpio = <&gpio3 RK_PA7 GPIO_ACTIVE_LOW>;
> +		pinctrl-0 = <&sdmmc_pwr>;
> +		pinctrl-names = "default";
> +		regulator-name = "vcc_sd";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		startup-delay-us = <100000>;
> +		vin-supply = <&vcc_io>;
> +	};
> +
> +	vcc_wifi: sdio-regulator {
> +		compatible = "regulator-fixed";
> +		enable-active-high;
> +		gpio = <&gpio3 RK_PD0 GPIO_ACTIVE_HIGH>;
> +		pinctrl-0 = <&wifi_pwr>;
> +		pinctrl-names = "default";
> +		regulator-name = "vcc_wifi";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		startup-delay-us = <100000>;
> +		vin-supply = <&vcc_io>;
> +	};
> +};
> +
> +&hdmi {
> +	status = "okay";
> +};
> +
> +&hdmi_in_vop1 {
> +	status = "disabled";
> +};
> +
> +&hdmi_out {
> +	hdmi_out_con: endpoint {
> +		remote-endpoint = <&hdmi_con_in>;
> +	};
> +};
> +
> +&mmc0 {
> +	bus-width = <4>;
> +	cap-mmc-highspeed;
> +	cap-sd-highspeed;
> +	vmmc-supply = <&vcc_sd>;
> +	status = "okay";
> +};
> +
> +&mmc1 {
> +	bus-width = <4>;
> +	non-removable;
> +	pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_bus4>;
> +	pinctrl-names = "default";
> +	vmmc-supply = <&vcc_wifi>;
> +	status = "okay";
> +};
> +
> +&pinctrl {
> +	usb-host {
> +		host_drv: host-drv {
> +			rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_default>;
> +		};
> +	};
> +
> +	usb-otg {
> +		otg_drv: otg-drv {
> +			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_default>;
> +		};
> +	};
> +
> +	sdmmc {
> +		sdmmc_pwr: sdmmc-pwr {
> +			rockchip,pins = <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_default>;
> +		};
> +	};
> +
> +	sdio {
> +		wifi_pwr: wifi-pwr {
> +			rockchip,pins = <3 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +	};
> +};
> +
> +&saradc {
> +	vref-supply = <&vcc_2v5>;
> +	status = "okay";
> +};
> +
> +&uart2 {
> +	status = "okay";
> +};
> +
> +&usb_host {
> +	status = "okay";
> +};
> +
> +&usb_otg {
> +	status = "okay";
> +};
> +
> +&usbphy {
> +	status = "okay";
> +};
> +
> +&vop0 {
> +	status = "okay";
> +};
> +
> +&wdt {
> +	status = "okay";
> +};

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v9 12/16] rockchip: rk3066: add core support
  2022-04-04 14:19 ` [PATCH v9 12/16] rockchip: rk3066: add core support Johan Jonker
@ 2022-04-09  3:55   ` Kever Yang
  0 siblings, 0 replies; 33+ messages in thread
From: Kever Yang @ 2022-04-09  3:55 UTC (permalink / raw)
  To: Johan Jonker; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot

Hi Johan,

Please squash patch 10~12 into one patch.


Thanks,

- Kever

On 2022/4/4 22:19, Johan Jonker wrote:
> Add the core architecture code for the rk3066.
>
> Signed-off-by: Johan Jonker <jbx6244@gmail.com>
> ---
>   arch/arm/mach-rockchip/Kconfig                | 23 ++++++++
>   arch/arm/mach-rockchip/Makefile               |  1 +
>   arch/arm/mach-rockchip/rk3066/Kconfig         | 30 ++++++++++
>   arch/arm/mach-rockchip/rk3066/Makefile        |  5 ++
>   arch/arm/mach-rockchip/rk3066/clk_rk3066.c    | 33 +++++++++++
>   arch/arm/mach-rockchip/rk3066/rk3066.c        | 49 +++++++++++++++++
>   arch/arm/mach-rockchip/rk3066/syscon_rk3066.c | 55 +++++++++++++++++++
>   7 files changed, 196 insertions(+)
>   create mode 100644 arch/arm/mach-rockchip/rk3066/Kconfig
>   create mode 100644 arch/arm/mach-rockchip/rk3066/Makefile
>   create mode 100644 arch/arm/mach-rockchip/rk3066/clk_rk3066.c
>   create mode 100644 arch/arm/mach-rockchip/rk3066/rk3066.c
>   create mode 100644 arch/arm/mach-rockchip/rk3066/syscon_rk3066.c
>
> diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
> index 811964973a..18aff5480b 100644
> --- a/arch/arm/mach-rockchip/Kconfig
> +++ b/arch/arm/mach-rockchip/Kconfig
> @@ -35,6 +35,28 @@ config ROCKCHIP_RK3036
>   	  and video codec support. Peripherals include Gigabit Ethernet,
>   	  USB2 host and OTG, SDIO, I2S, UART, SPI, I2C and PWMs.
>   
> +config ROCKCHIP_RK3066
> +	bool "Support Rockchip RK3066"
> +	select CPU_V7A
> +	select SPL_BOARD_INIT if SPL
> +	select SUPPORT_SPL
> +	select SUPPORT_TPL
> +	select SPL
> +	select TPL
> +	select TPL_ROCKCHIP_BACK_TO_BROM
> +	select TPL_ROCKCHIP_EARLYRETURN_TO_BROM
> +	imply ROCKCHIP_COMMON_BOARD
> +	imply SPL_ROCKCHIP_COMMON_BOARD
> +	imply SPL_SERIAL
> +	imply TPL_ROCKCHIP_COMMON_BOARD
> +	imply TPL_SERIAL
> +	help
> +	  The Rockchip RK3066 is a ARM-based SoC with a dual-core Cortex-A9
> +	  including NEON and GPU, 512KB L2 cache, Mali-400 graphics, two
> +	  video interfaces, several memory options and video codec support.
> +	  Peripherals include Fast Ethernet, USB2 host and OTG, SDIO, I2S,
> +	  UART, SPI, I2C and PWMs.
> +
>   config ROCKCHIP_RK3128
>   	bool "Support Rockchip RK3128"
>   	select CPU_V7A
> @@ -405,6 +427,7 @@ config LNX_KRNL_IMG_TEXT_OFFSET_BASE
>   
>   source "arch/arm/mach-rockchip/px30/Kconfig"
>   source "arch/arm/mach-rockchip/rk3036/Kconfig"
> +source "arch/arm/mach-rockchip/rk3066/Kconfig"
>   source "arch/arm/mach-rockchip/rk3128/Kconfig"
>   source "arch/arm/mach-rockchip/rk3188/Kconfig"
>   source "arch/arm/mach-rockchip/rk322x/Kconfig"
> diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
> index 00aef0ecee..6c1c7b8a10 100644
> --- a/arch/arm/mach-rockchip/Makefile
> +++ b/arch/arm/mach-rockchip/Makefile
> @@ -34,6 +34,7 @@ obj-$(CONFIG_$(SPL_TPL_)RAM) += sdram.o
>   
>   obj-$(CONFIG_ROCKCHIP_PX30) += px30/
>   obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/
> +obj-$(CONFIG_ROCKCHIP_RK3066) += rk3066/
>   obj-$(CONFIG_ROCKCHIP_RK3128) += rk3128/
>   obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188/
>   obj-$(CONFIG_ROCKCHIP_RK322X) += rk322x/
> diff --git a/arch/arm/mach-rockchip/rk3066/Kconfig b/arch/arm/mach-rockchip/rk3066/Kconfig
> new file mode 100644
> index 0000000000..335f49bc55
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/rk3066/Kconfig
> @@ -0,0 +1,30 @@
> +if ROCKCHIP_RK3066
> +
> +config ROCKCHIP_BOOT_MODE_REG
> +	default 0x20004040
> +
> +config SYS_SOC
> +	default "rk3066"
> +
> +config SYS_MALLOC_F_LEN
> +	default 0x0800
> +
> +config SPL_LIBCOMMON_SUPPORT
> +	default y
> +
> +config SPL_LIBGENERIC_SUPPORT
> +	default y
> +
> +config SPL_SERIAL
> +	default y
> +
> +config TPL_LIBCOMMON_SUPPORT
> +	default y
> +
> +config TPL_LIBGENERIC_SUPPORT
> +	default y
> +
> +config TPL_SERIAL
> +	default y
> +
> +endif
> diff --git a/arch/arm/mach-rockchip/rk3066/Makefile b/arch/arm/mach-rockchip/rk3066/Makefile
> new file mode 100644
> index 0000000000..9e2a9d4b0a
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/rk3066/Makefile
> @@ -0,0 +1,5 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +
> +obj-y += clk_rk3066.o
> +obj-y += rk3066.o
> +obj-y += syscon_rk3066.o
> diff --git a/arch/arm/mach-rockchip/rk3066/clk_rk3066.c b/arch/arm/mach-rockchip/rk3066/clk_rk3066.c
> new file mode 100644
> index 0000000000..c47526dca5
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/rk3066/clk_rk3066.c
> @@ -0,0 +1,33 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2015 Google, Inc
> + * Written by Simon Glass <sjg@chromium.org>
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <syscon.h>
> +#include <asm/arch-rockchip/clock.h>
> +#include <asm/arch-rockchip/cru_rk3066.h>
> +#include <linux/err.h>
> +
> +int rockchip_get_clk(struct udevice **devp)
> +{
> +	return uclass_get_device_by_driver(UCLASS_CLK,
> +			DM_DRIVER_GET(rockchip_rk3066a_cru), devp);
> +}
> +
> +void *rockchip_get_cru(void)
> +{
> +	struct rk3066_clk_priv *priv;
> +	struct udevice *dev;
> +	int ret;
> +
> +	ret = rockchip_get_clk(&dev);
> +	if (ret)
> +		return ERR_PTR(ret);
> +
> +	priv = dev_get_priv(dev);
> +
> +	return priv->cru;
> +}
> diff --git a/arch/arm/mach-rockchip/rk3066/rk3066.c b/arch/arm/mach-rockchip/rk3066/rk3066.c
> new file mode 100644
> index 0000000000..78c7d894f9
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/rk3066/rk3066.c
> @@ -0,0 +1,49 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * (C) Copyright 2016 Rockchip Electronics Co., Ltd
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/arch-rockchip/bootrom.h>
> +#include <asm/arch-rockchip/grf_rk3066.h>
> +
> +#define GRF_BASE	0x20008000
> +
> +const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
> +	[BROM_BOOTSOURCE_EMMC] = "/mmc@1021c000",
> +	[BROM_BOOTSOURCE_SD] = "/mmc@10214000",
> +};
> +
> +void board_debug_uart_init(void)
> +{
> +	struct rk3066_grf * const grf = (void *)GRF_BASE;
> +
> +	/* Enable early UART on the RK3066 */
> +	rk_clrsetreg(&grf->gpio1b_iomux,
> +		     GPIO1B1_MASK | GPIO1B0_MASK,
> +		     GPIO1B1_UART2_SOUT << GPIO1B1_SHIFT |
> +		     GPIO1B0_UART2_SIN << GPIO1B0_SHIFT);
> +}
> +
> +void spl_board_init(void)
> +{
> +	if (!IS_ENABLED(CONFIG_SPL_BUILD))
> +		return;
> +
> +	if (IS_ENABLED(CONFIG_SPL_DM_MMC)) {
> +		struct rk3066_grf * const grf = (void *)GRF_BASE;
> +
> +		rk_clrsetreg(&grf->gpio3b_iomux,
> +			     GPIO3B0_MASK | GPIO3B1_MASK | GPIO3B2_MASK |
> +			     GPIO3B3_MASK | GPIO3B4_MASK | GPIO3B5_MASK |
> +			     GPIO3B6_MASK,
> +			     GPIO3B0_SDMMC0_CLKOUT << GPIO3B0_SHIFT |
> +			     GPIO3B1_SDMMC0_CMD    << GPIO3B1_SHIFT |
> +			     GPIO3B2_SDMMC0_DATA0  << GPIO3B2_SHIFT |
> +			     GPIO3B3_SDMMC0_DATA1  << GPIO3B3_SHIFT |
> +			     GPIO3B4_SDMMC0_DATA2  << GPIO3B4_SHIFT |
> +			     GPIO3B5_SDMMC0_DATA3  << GPIO3B5_SHIFT |
> +			     GPIO3B6_SDMMC0_DECTN  << GPIO3B6_SHIFT);
> +	}
> +}
> diff --git a/arch/arm/mach-rockchip/rk3066/syscon_rk3066.c b/arch/arm/mach-rockchip/rk3066/syscon_rk3066.c
> new file mode 100644
> index 0000000000..a598f6400d
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/rk3066/syscon_rk3066.c
> @@ -0,0 +1,55 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2015 Google, Inc
> + * Written by Simon Glass <sjg@chromium.org>
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <log.h>
> +#include <syscon.h>
> +#include <asm/arch-rockchip/clock.h>
> +
> +static const struct udevice_id rk3066_syscon_ids[] = {
> +	{ .compatible = "rockchip,rk3066-noc", .data = ROCKCHIP_SYSCON_NOC },
> +	{ .compatible = "rockchip,rk3066-grf", .data = ROCKCHIP_SYSCON_GRF },
> +	{ .compatible = "rockchip,rk3066-pmu", .data = ROCKCHIP_SYSCON_PMU },
> +	{ }
> +};
> +
> +U_BOOT_DRIVER(syscon_rk3066) = {
> +	.name = "rk3066_syscon",
> +	.id = UCLASS_SYSCON,
> +	.of_match = rk3066_syscon_ids,
> +};
> +
> +#if CONFIG_IS_ENABLED(OF_PLATDATA)
> +static int rk3066_syscon_bind_of_plat(struct udevice *dev)
> +{
> +	dev->driver_data = dev->driver->of_match->data;
> +	debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
> +
> +	return 0;
> +}
> +
> +U_BOOT_DRIVER(rockchip_rk3066_noc) = {
> +	.name = "rockchip_rk3066_noc",
> +	.id = UCLASS_SYSCON,
> +	.of_match = rk3066_syscon_ids,
> +	.bind = rk3066_syscon_bind_of_plat,
> +};
> +
> +U_BOOT_DRIVER(rockchip_rk3066_grf) = {
> +	.name = "rockchip_rk3066_grf",
> +	.id = UCLASS_SYSCON,
> +	.of_match = rk3066_syscon_ids + 1,
> +	.bind = rk3066_syscon_bind_of_plat,
> +};
> +
> +U_BOOT_DRIVER(rockchip_rk3066_pmu) = {
> +	.name = "rockchip_rk3066_pmu",
> +	.id = UCLASS_SYSCON,
> +	.of_match = rk3066_syscon_ids + 2,
> +	.bind = rk3066_syscon_bind_of_plat,
> +};
> +#endif

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v9 15/16] rockchip: tools: add rk3066 support to rkcommon.c
  2022-04-04 14:19 ` [PATCH v9 15/16] rockchip: tools: add rk3066 support to rkcommon.c Johan Jonker
@ 2022-04-09  3:56   ` Kever Yang
  0 siblings, 0 replies; 33+ messages in thread
From: Kever Yang @ 2022-04-09  3:56 UTC (permalink / raw)
  To: Johan Jonker; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot


On 2022/4/4 22:19, Johan Jonker wrote:
> Add rk3066 support to rkcommon.c
>
> Signed-off-by: Johan Jonker <jbx6244@gmail.com>


This patch should be before the patch add board and defconfig suuport.

For the change:

Reviewed-by: Kever Yang <kever.yang@rock-chips.com>

Thanks,
- Kever
> ---
>   tools/rkcommon.c | 1 +
>   1 file changed, 1 insertion(+)
>
> diff --git a/tools/rkcommon.c b/tools/rkcommon.c
> index 29f2676c19..860785f839 100644
> --- a/tools/rkcommon.c
> +++ b/tools/rkcommon.c
> @@ -123,6 +123,7 @@ struct spl_info {
>   static struct spl_info spl_infos[] = {
>   	{ "px30", "RK33", 0x2800, false, RK_HEADER_V1 },
>   	{ "rk3036", "RK30", 0x1000, false, RK_HEADER_V1 },
> +	{ "rk3066", "RK30", 0x8000 - 0x800, true, RK_HEADER_V1 },
>   	{ "rk3128", "RK31", 0x1800, false, RK_HEADER_V1 },
>   	{ "rk3188", "RK31", 0x8000 - 0x800, true, RK_HEADER_V1 },
>   	{ "rk322x", "RK32", 0x8000 - 0x1000, false, RK_HEADER_V1 },

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v9 13/16] rockchip: rk3066: add Rikomagic MK808 board
  2022-04-04 14:19 ` [PATCH v9 13/16] rockchip: rk3066: add Rikomagic MK808 board Johan Jonker
@ 2022-04-09  3:57   ` Kever Yang
  0 siblings, 0 replies; 33+ messages in thread
From: Kever Yang @ 2022-04-09  3:57 UTC (permalink / raw)
  To: Johan Jonker; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot


On 2022/4/4 22:19, Johan Jonker wrote:
> MK808 is a RK3066-based board with 1 USB host and 1 USB OTG port,
> HDMI and a micro-SD card slot. It also includes on-board NAND
> and 1GB of SDRAM.
>
> Signed-off-by: Johan Jonker <jbx6244@gmail.com>

Reviewed-by: Kever Yang <kever.yang@rock-chips.com>

Thanks,
- Kever
> ---
>   arch/arm/mach-rockchip/rk3066/Kconfig |  9 +++++++++
>   board/rikomagic/mk808/Kconfig         | 15 +++++++++++++++
>   board/rikomagic/mk808/MAINTAINERS     |  6 ++++++
>   board/rikomagic/mk808/Makefile        |  3 +++
>   board/rikomagic/mk808/mk808.c         |  3 +++
>   5 files changed, 36 insertions(+)
>   create mode 100644 board/rikomagic/mk808/Kconfig
>   create mode 100644 board/rikomagic/mk808/MAINTAINERS
>   create mode 100644 board/rikomagic/mk808/Makefile
>   create mode 100644 board/rikomagic/mk808/mk808.c
>
> diff --git a/arch/arm/mach-rockchip/rk3066/Kconfig b/arch/arm/mach-rockchip/rk3066/Kconfig
> index 335f49bc55..95d7fc8a29 100644
> --- a/arch/arm/mach-rockchip/rk3066/Kconfig
> +++ b/arch/arm/mach-rockchip/rk3066/Kconfig
> @@ -1,5 +1,12 @@
>   if ROCKCHIP_RK3066
>   
> +config TARGET_MK808
> +	bool "MK808"
> +	help
> +	  MK808 is a RK3066-based board with 1 USB host and 1 USB OTG port,
> +	  HDMI and a micro-SD card slot. It also includes on-board NAND
> +	  and 1GB of SDRAM.
> +
>   config ROCKCHIP_BOOT_MODE_REG
>   	default 0x20004040
>   
> @@ -27,4 +34,6 @@ config TPL_LIBGENERIC_SUPPORT
>   config TPL_SERIAL
>   	default y
>   
> +source "board/rikomagic/mk808/Kconfig"
> +
>   endif
> diff --git a/board/rikomagic/mk808/Kconfig b/board/rikomagic/mk808/Kconfig
> new file mode 100644
> index 0000000000..4abad7e750
> --- /dev/null
> +++ b/board/rikomagic/mk808/Kconfig
> @@ -0,0 +1,15 @@
> +if TARGET_MK808
> +
> +config SYS_BOARD
> +	default "mk808"
> +
> +config SYS_VENDOR
> +	default "rikomagic"
> +
> +config SYS_CONFIG_NAME
> +	default "mk808"
> +
> +config BOARD_SPECIFIC_OPTIONS # dummy
> +	def_bool y
> +
> +endif
> diff --git a/board/rikomagic/mk808/MAINTAINERS b/board/rikomagic/mk808/MAINTAINERS
> new file mode 100644
> index 0000000000..b3ef6adb91
> --- /dev/null
> +++ b/board/rikomagic/mk808/MAINTAINERS
> @@ -0,0 +1,6 @@
> +MK808
> +M:	Johan Jonker <jbx6244@gmail.com>
> +S:	Maintained
> +F:	board/rikomagic/mk808
> +F:	configs/mk808_defconfig
> +F:	include/configs/mk808.h
> diff --git a/board/rikomagic/mk808/Makefile b/board/rikomagic/mk808/Makefile
> new file mode 100644
> index 0000000000..a4d16884df
> --- /dev/null
> +++ b/board/rikomagic/mk808/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +
> +obj-y	+= mk808.o
> diff --git a/board/rikomagic/mk808/mk808.c b/board/rikomagic/mk808/mk808.c
> new file mode 100644
> index 0000000000..e0bfc6f331
> --- /dev/null
> +++ b/board/rikomagic/mk808/mk808.c
> @@ -0,0 +1,3 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +#include <common.h>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v9 14/16] rockchip: rk3066: add mk808_defconfig
  2022-04-04 14:19 ` [PATCH v9 14/16] rockchip: rk3066: add mk808_defconfig Johan Jonker
@ 2022-04-09  3:57   ` Kever Yang
  0 siblings, 0 replies; 33+ messages in thread
From: Kever Yang @ 2022-04-09  3:57 UTC (permalink / raw)
  To: Johan Jonker; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot


On 2022/4/4 22:19, Johan Jonker wrote:
> This commit adds the default configuration file and
> relevant description for a MK808 board.
>
> Signed-off-by: Johan Jonker <jbx6244@gmail.com>

Reviewed-by: Kever Yang <kever.yang@rock-chips.com>

Thanks,
- Kever
> ---
>
> changed V9:
>    enable led gpio
>    disable STIMER
>
> Changed V8:
>    use default log level
>    ENV_IS_NOWHERE
> ---
>   configs/mk808_defconfig | 100 ++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 100 insertions(+)
>   create mode 100644 configs/mk808_defconfig
>
> diff --git a/configs/mk808_defconfig b/configs/mk808_defconfig
> new file mode 100644
> index 0000000000..b475e73540
> --- /dev/null
> +++ b/configs/mk808_defconfig
> @@ -0,0 +1,100 @@
> +CONFIG_ARM=y
> +# CONFIG_SPL_SYS_THUMB_BUILD is not set
> +# CONFIG_TPL_SYS_THUMB_BUILD is not set
> +# CONFIG_SPL_USE_ARCH_MEMCPY is not set
> +# CONFIG_SPL_USE_ARCH_MEMSET is not set
> +CONFIG_ARCH_ROCKCHIP=y
> +CONFIG_SYS_TEXT_BASE=0x60408000
> +CONFIG_SYS_MALLOC_F_LEN=0x2000
> +CONFIG_NR_DRAM_BANKS=1
> +CONFIG_ENV_SIZE=0x8000
> +CONFIG_DEFAULT_DEVICE_TREE="rk3066a-mk808"
> +CONFIG_SPL_TEXT_BASE=0x60000000
> +CONFIG_ROCKCHIP_RK3066=y
> +# CONFIG_ROCKCHIP_STIMER is not set
> +CONFIG_TPL_TEXT_BASE=0x10080C04
> +CONFIG_TPL_MAX_SIZE=32764
> +CONFIG_TPL_STACK=0x1008FFFF
> +CONFIG_TARGET_MK808=y
> +CONFIG_SPL_STACK_R_ADDR=0x70000000
> +CONFIG_DEBUG_UART_BASE=0x20064000
> +CONFIG_DEBUG_UART_CLOCK=24000000
> +CONFIG_SPL_FS_FAT=y
> +CONFIG_SYS_LOAD_ADDR=0x70800800
> +CONFIG_SPL_PAYLOAD="u-boot.bin"
> +CONFIG_DEBUG_UART=y
> +CONFIG_SD_BOOT=y
> +CONFIG_USE_PREBOOT=y
> +CONFIG_DEFAULT_FDT_FILE="rk3066a-mk808.dtb"
> +# CONFIG_DISPLAY_CPUINFO is not set
> +CONFIG_DISPLAY_BOARDINFO_LATE=y
> +CONFIG_BOARD_LATE_INIT=y
> +CONFIG_SPL_STACK_R=y
> +CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x200000
> +CONFIG_SPL_SEPARATE_BSS=y
> +CONFIG_SPL_FS_EXT4=y
> +CONFIG_SYS_MMCSD_FS_BOOT_PARTITION=2
> +CONFIG_TPL_NEEDS_SEPARATE_STACK=y
> +# CONFIG_BOOTM_PLAN9 is not set
> +# CONFIG_BOOTM_RTEMS is not set
> +# CONFIG_BOOTM_VXWORKS is not set
> +CONFIG_CMD_GPT=y
> +CONFIG_CMD_MMC=y
> +# CONFIG_CMD_SETEXPR is not set
> +CONFIG_CMD_CACHE=y
> +CONFIG_CMD_TIME=y
> +CONFIG_CMD_REGULATOR=y
> +CONFIG_SPL_OF_CONTROL=y
> +CONFIG_TPL_OF_CONTROL=y
> +CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
> +CONFIG_OF_DTB_PROPS_REMOVE=y
> +CONFIG_SPL_OF_PLATDATA=y
> +CONFIG_TPL_OF_PLATDATA=y
> +CONFIG_SYS_RELOC_GD_ENV_ADDR=y
> +# CONFIG_NET is not set
> +CONFIG_TPL_DM=y
> +# CONFIG_DM_WARN is not set
> +CONFIG_REGMAP=y
> +CONFIG_SPL_REGMAP=y
> +CONFIG_TPL_REGMAP=y
> +CONFIG_SYSCON=y
> +CONFIG_SPL_SYSCON=y
> +CONFIG_TPL_SYSCON=y
> +# CONFIG_SIMPLE_BUS is not set
> +# CONFIG_SPL_SIMPLE_BUS is not set
> +# CONFIG_TPL_BLK is not set
> +CONFIG_CLK=y
> +CONFIG_SPL_CLK=y
> +CONFIG_TPL_CLK=y
> +CONFIG_ROCKCHIP_GPIO=y
> +# CONFIG_SPL_DM_I2C is not set
> +CONFIG_LED=y
> +CONFIG_LED_GPIO=y
> +CONFIG_MMC_IO_VOLTAGE=y
> +CONFIG_SPL_MMC_IO_VOLTAGE=y
> +CONFIG_MMC_UHS_SUPPORT=y
> +CONFIG_SPL_MMC_UHS_SUPPORT=y
> +CONFIG_MMC_DW=y
> +CONFIG_MMC_DW_ROCKCHIP=y
> +CONFIG_SF_DEFAULT_SPEED=20000000
> +CONFIG_PINCTRL=y
> +CONFIG_DM_PMIC=y
> +# CONFIG_SPL_PMIC_CHILDREN is not set
> +CONFIG_DM_REGULATOR_FIXED=y
> +CONFIG_DM_REGULATOR_GPIO=y
> +CONFIG_RAM=y
> +CONFIG_SPL_RAM=y
> +CONFIG_TPL_RAM=y
> +CONFIG_DM_RESET=y
> +# CONFIG_REQUIRE_SERIAL_CONSOLE is not set
> +CONFIG_DEBUG_UART_SHIFT=2
> +CONFIG_DEBUG_UART_ANNOUNCE=y
> +CONFIG_ROCKCHIP_SERIAL=y
> +CONFIG_SYSRESET=y
> +CONFIG_TIMER=y
> +CONFIG_SPL_TIMER=y
> +CONFIG_TPL_TIMER=y
> +CONFIG_DESIGNWARE_APB_TIMER=y
> +CONFIG_SPL_TINY_MEMSET=y
> +CONFIG_ERRNO_STR=y
> +# CONFIG_TPL_OF_LIBFDT is not set

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v9 16/16] doc: rockchip: add rk3066 Rikomagic MK808
  2022-04-04 14:19 ` [PATCH v9 16/16] doc: rockchip: add rk3066 Rikomagic MK808 Johan Jonker
@ 2022-04-09  4:00   ` Kever Yang
  2022-04-10  9:08     ` Johan Jonker
  0 siblings, 1 reply; 33+ messages in thread
From: Kever Yang @ 2022-04-09  4:00 UTC (permalink / raw)
  To: Johan Jonker; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot


On 2022/4/4 22:19, Johan Jonker wrote:
> Add rk3066 Rikomagic MK808 to the list of
> mainline supported Rockchip boards.
>
> Signed-off-by: Johan Jonker <jbx6244@gmail.com>

Is there any document need for setup build/flash firmware environment 
for rk3066?


Thanks,
- Kever
> ---
>   doc/board/rockchip/rockchip.rst | 2 ++
>   1 file changed, 2 insertions(+)
>
> diff --git a/doc/board/rockchip/rockchip.rst b/doc/board/rockchip/rockchip.rst
> index a75e60b9fa..ed2792d414 100644
> --- a/doc/board/rockchip/rockchip.rst
> +++ b/doc/board/rockchip/rockchip.rst
> @@ -24,6 +24,8 @@ List of mainline supported Rockchip boards:
>   * rk3036
>        - Rockchip Evb-RK3036 (evb-rk3036)
>        - Kylin (kylin_rk3036)
> +* rk3066
> +     - Rikomagic MK808 (mk808)
>   * rk3128
>        - Rockchip Evb-RK3128 (evb-rk3128)
>   * rk3188

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v9 16/16] doc: rockchip: add rk3066 Rikomagic MK808
  2022-04-09  4:00   ` Kever Yang
@ 2022-04-10  9:08     ` Johan Jonker
  2022-04-11 10:06       ` Kever Yang
  0 siblings, 1 reply; 33+ messages in thread
From: Johan Jonker @ 2022-04-10  9:08 UTC (permalink / raw)
  To: Kever Yang; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot



On 4/9/22 06:00, Kever Yang wrote:
> 
> On 2022/4/4 22:19, Johan Jonker wrote:
>> Add rk3066 Rikomagic MK808 to the list of
>> mainline supported Rockchip boards.
>>
>> Signed-off-by: Johan Jonker <jbx6244@gmail.com>
> 
> Is there any document need for setup build/flash firmware environment
> for rk3066?

How much text would you like.
In which files and in what format?

rockchip.rst vs. README.rockchip  ??

Given an example text for a boot solution with full U-boot stored on SD
CARD in the cover letter. Does that contain useful info for use in a
document.

Please advise.

Johan


>
> 
> Thanks,
> - Kever
>> ---
>>   doc/board/rockchip/rockchip.rst | 2 ++
>>   1 file changed, 2 insertions(+)
>>
>> diff --git a/doc/board/rockchip/rockchip.rst
>> b/doc/board/rockchip/rockchip.rst
>> index a75e60b9fa..ed2792d414 100644
>> --- a/doc/board/rockchip/rockchip.rst
>> +++ b/doc/board/rockchip/rockchip.rst
>> @@ -24,6 +24,8 @@ List of mainline supported Rockchip boards:
>>   * rk3036
>>        - Rockchip Evb-RK3036 (evb-rk3036)
>>        - Kylin (kylin_rk3036)
>> +* rk3066
>> +     - Rikomagic MK808 (mk808)
>>   * rk3128
>>        - Rockchip Evb-RK3128 (evb-rk3128)
>>   * rk3188

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v9 16/16] doc: rockchip: add rk3066 Rikomagic MK808
  2022-04-10  9:08     ` Johan Jonker
@ 2022-04-11 10:06       ` Kever Yang
  0 siblings, 0 replies; 33+ messages in thread
From: Kever Yang @ 2022-04-11 10:06 UTC (permalink / raw)
  To: Johan Jonker; +Cc: sjg, philipp.tomsich, lukma, seanga2, u-boot

Hi Johan,

On 2022/4/10 17:08, Johan Jonker wrote:
>
> On 4/9/22 06:00, Kever Yang wrote:
>> On 2022/4/4 22:19, Johan Jonker wrote:
>>> Add rk3066 Rikomagic MK808 to the list of
>>> mainline supported Rockchip boards.
>>>
>>> Signed-off-by: Johan Jonker <jbx6244@gmail.com>
>> Is there any document need for setup build/flash firmware environment
>> for rk3066?
> How much text would you like.
> In which files and in what format?
>
> rockchip.rst vs. README.rockchip  ??

For legacy boards, there is README in board/rockchip/board-name which 
contain how to

bringup boards, and right now, we need to put this kind of document into 
doc/board/ in

.rst format.

>
> Given an example text for a boot solution with full U-boot stored on SD
> CARD in the cover letter. Does that contain useful info for use in a
> document.

The contain in the cover letter is enough.


Thanks,

- Kever

>
> Please advise.
>
> Johan
>
>
>>
>> Thanks,
>> - Kever
>>> ---
>>>    doc/board/rockchip/rockchip.rst | 2 ++
>>>    1 file changed, 2 insertions(+)
>>>
>>> diff --git a/doc/board/rockchip/rockchip.rst
>>> b/doc/board/rockchip/rockchip.rst
>>> index a75e60b9fa..ed2792d414 100644
>>> --- a/doc/board/rockchip/rockchip.rst
>>> +++ b/doc/board/rockchip/rockchip.rst
>>> @@ -24,6 +24,8 @@ List of mainline supported Rockchip boards:
>>>    * rk3036
>>>         - Rockchip Evb-RK3036 (evb-rk3036)
>>>         - Kylin (kylin_rk3036)
>>> +* rk3066
>>> +     - Rikomagic MK808 (mk808)
>>>    * rk3128
>>>         - Rockchip Evb-RK3128 (evb-rk3128)
>>>    * rk3188

^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2022-04-11 10:06 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-04 14:19 [PATCH v9 00/16] Add Rikomagic MK808 board Johan Jonker
2022-04-04 14:19 ` [PATCH v9 01/16] rockchip: rk3066-power: sync power domain dt-binding header from Linux Johan Jonker
2022-04-06 15:01   ` Kever Yang
2022-04-04 14:19 ` [PATCH v9 02/16] rockchip: rk3066: add grf header file Johan Jonker
2022-04-09  3:49   ` Kever Yang
2022-04-04 14:19 ` [PATCH v9 03/16] rockchip: rk3066: add clock driver for rk3066 soc Johan Jonker
2022-04-09  3:49   ` Kever Yang
2022-04-04 14:19 ` [PATCH v9 04/16] rockchip: rk3066: add rk3066 pinctrl driver Johan Jonker
2022-04-09  3:49   ` Kever Yang
2022-04-04 14:19 ` [PATCH v9 05/16] rockchip: rk3066: add sdram driver Johan Jonker
2022-04-09  3:50   ` Kever Yang
2022-04-04 14:19 ` [PATCH v9 06/16] arm: dts: rockchip: fix rk3xxx-u-boot.dtsi Johan Jonker
2022-04-09  3:50   ` Kever Yang
2022-04-04 14:19 ` [PATCH v9 07/16] arm: dts: rockchip: fix include rk3xxx-u-boot.dtsi Johan Jonker
2022-04-09  3:50   ` Kever Yang
2022-04-04 14:19 ` [PATCH v9 08/16] arm: dts: rockchip: add rk3066a.dtsi Johan Jonker
2022-04-09  3:52   ` Kever Yang
2022-04-04 14:19 ` [PATCH v9 09/16] arm: dts: rockchip: add rk3066a-mk808.dts Johan Jonker
2022-04-09  3:52   ` Kever Yang
2022-04-04 14:19 ` [PATCH v9 10/16] rockchip: rk3066: add include Johan Jonker
2022-04-04 14:19 ` [PATCH v9 11/16] rockchip: rk3066: add rk3066_common.h include Johan Jonker
2022-04-04 14:19 ` [PATCH v9 12/16] rockchip: rk3066: add core support Johan Jonker
2022-04-09  3:55   ` Kever Yang
2022-04-04 14:19 ` [PATCH v9 13/16] rockchip: rk3066: add Rikomagic MK808 board Johan Jonker
2022-04-09  3:57   ` Kever Yang
2022-04-04 14:19 ` [PATCH v9 14/16] rockchip: rk3066: add mk808_defconfig Johan Jonker
2022-04-09  3:57   ` Kever Yang
2022-04-04 14:19 ` [PATCH v9 15/16] rockchip: tools: add rk3066 support to rkcommon.c Johan Jonker
2022-04-09  3:56   ` Kever Yang
2022-04-04 14:19 ` [PATCH v9 16/16] doc: rockchip: add rk3066 Rikomagic MK808 Johan Jonker
2022-04-09  4:00   ` Kever Yang
2022-04-10  9:08     ` Johan Jonker
2022-04-11 10:06       ` Kever Yang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.