public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2 0/9] rk3399: enable SPL driver
@ 2017-02-13  9:38 Kever Yang
  2017-02-13  9:38 ` [U-Boot] [PATCH v2 1/9] arm64: rk3399: add ddr controller driver Kever Yang
                   ` (9 more replies)
  0 siblings, 10 replies; 23+ messages in thread
From: Kever Yang @ 2017-02-13  9:38 UTC (permalink / raw)
  To: u-boot


This series patch enable basic driver for rk3399 SPL, the ATF support
has been split as a separate patch.

SPL_OF_PLATDATA is consider to be must because the dram driver has much
configuration parameter from dts, but we don't want to do the copy.

Other driver like clock, pinctrl, sdhci has update to support
OF-PLATDATA.


Changes in v2:
- use lower-case hex for input dts data
- using rk3288 like style to encode/decode sys_reg
- gather some parameters as base params in rk3399_sdram_params
- add some missing comment
- split SPL patch into 4 patches

Changes in v1:
- use dts for parameter
- get all controller base address from dts instead of hard code
- gather all controller into dram_info instead of separate global
  variables.
- add return value for error case

Kever Yang (9):
  arm64: rk3399: add ddr controller driver
  arm64: rk3399: move grf register definitions to grf_rk3399.h
  clk: rk3399: update driver for spl
  sdhci: rk3399: update driver to support of-platdata
  pinctrl: rk3399: add the of-platdata support
  arm64: rk3399: syscon addition for rk3399
  dts: rk3399: update for spl require driver
  arm64: rk3399: add SPL support
  config: rk3399: enable SPL config for evb-rk3399

 arch/arm/Kconfig                                  |    1 +
 arch/arm/dts/rk3399-evb.dts                       |    2 +
 arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi    | 1536 +++++++++++++++++++++
 arch/arm/dts/rk3399.dtsi                          |   44 +
 arch/arm/include/asm/arch-rockchip/clock.h        |    9 +
 arch/arm/include/asm/arch-rockchip/cru_rk3399.h   |    5 +
 arch/arm/include/asm/arch-rockchip/grf_rk3399.h   |  118 ++
 arch/arm/include/asm/arch-rockchip/sdram_rk3399.h |  124 ++
 arch/arm/mach-rockchip/Kconfig                    |    2 +
 arch/arm/mach-rockchip/Makefile                   |    1 +
 arch/arm/mach-rockchip/rk3399-board-spl.c         |  158 +++
 arch/arm/mach-rockchip/rk3399/Makefile            |    1 +
 arch/arm/mach-rockchip/rk3399/clk_rk3399.c        |   21 +
 arch/arm/mach-rockchip/rk3399/sdram_rk3399.c      | 1259 +++++++++++++++++
 arch/arm/mach-rockchip/rk3399/syscon_rk3399.c     |   40 +
 configs/evb-rk3399_defconfig                      |   18 +
 drivers/clk/rockchip/clk_rk3399.c                 |   89 +-
 drivers/mmc/rockchip_sdhci.c                      |   17 +-
 drivers/pinctrl/rockchip/pinctrl_rk3399.c         |  111 +-
 include/configs/rk3399_common.h                   |   11 +
 include/dt-bindings/clock/rk3399-cru.h            |   16 +-
 21 files changed, 3460 insertions(+), 123 deletions(-)
 create mode 100644 arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
 create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
 create mode 100644 arch/arm/mach-rockchip/rk3399-board-spl.c
 create mode 100644 arch/arm/mach-rockchip/rk3399/sdram_rk3399.c

-- 
1.9.1

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

* [U-Boot] [PATCH v2 1/9] arm64: rk3399: add ddr controller driver
  2017-02-13  9:38 [U-Boot] [PATCH v2 0/9] rk3399: enable SPL driver Kever Yang
@ 2017-02-13  9:38 ` Kever Yang
  2017-02-16 20:43   ` Simon Glass
  2017-02-13  9:38 ` [U-Boot] [PATCH v2 2/9] arm64: rk3399: move grf register definitions to grf_rk3399.h Kever Yang
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Kever Yang @ 2017-02-13  9:38 UTC (permalink / raw)
  To: u-boot

RK3399 support DDR3, LPDDR3, DDR4 sdram, this patch is porting from
coreboot, support 4GB lpddr3 in this version.

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

Changes in v2:
- use lower-case hex for input dts data
- using rk3288 like style to encode/decode sys_reg
- gather some parameters as base params in rk3399_sdram_params
- add some missing comment

Changes in v1:
- use dts for parameter
- get all controller base address from dts instead of hard code
- gather all controller into dram_info instead of separate global
  variables.
- add return value for error case

 arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi    | 1536 +++++++++++++++++++++
 arch/arm/include/asm/arch-rockchip/sdram_rk3399.h |  124 ++
 arch/arm/mach-rockchip/rk3399/Makefile            |    1 +
 arch/arm/mach-rockchip/rk3399/sdram_rk3399.c      | 1259 +++++++++++++++++
 4 files changed, 2920 insertions(+)
 create mode 100644 arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
 create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
 create mode 100644 arch/arm/mach-rockchip/rk3399/sdram_rk3399.c

diff --git a/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi b/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
new file mode 100644
index 0000000..65dfc38
--- /dev/null
+++ b/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
@@ -0,0 +1,1536 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+&dmc {
+	rockchip,sdram-params = <
+		0x2
+		0xa
+		0x3
+		0x2
+		0x2
+		0x0
+		0xf
+		0xf
+		1
+		0x1d191519
+		0x14040808
+		0x00000002
+		0x00006226
+		0x00000054
+		0x00000000
+		0x2
+		0xa
+		0x3
+		0x2
+		0x2
+		0x0
+		0xf
+		0xf
+		1
+		0x1d191519
+		0x14040808
+		0x00000002
+		0x00006226
+		0x00000054
+		0x00000000
+		800
+		6
+		2
+		13
+		1
+		0x00000700
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000050
+		0x00027100
+		0x00000320
+		0x00001f40
+		0x00000050
+		0x00027100
+		0x00000320
+		0x00001f40
+		0x00000050
+		0x00027100
+		0x00000320
+		0x01001f40
+		0x00000000
+		0x00000101
+		0x00020100
+		0x000000a0
+		0x00000190
+		0x00000000
+		0x06180000
+		0x00061800
+		0x04000618
+		0x33080004
+		0x280f0622
+		0x22330800
+		0x00280f06
+		0x06223308
+		0x0600280f
+		0x00000a0a
+		0x0600dac0
+		0x0a0a060c
+		0x0600dac0
+		0x0a0a060c
+		0x0600dac0
+		0x0203000c
+		0x0f0c0f00
+		0x040c0f0c
+		0x14000a0a
+		0x03030a0a
+		0x00010003
+		0x031b1b1b
+		0x00111111
+		0x00000000
+		0x03010000
+		0x0c2800a8
+		0x0c2800a8
+		0x0c2800a8
+		0x00000000
+		0x00060006
+		0x00140006
+		0x00140014
+		0x000f0f0f
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00b00000
+		0x00b000b0
+		0x00b000b0
+		0x000000b0
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000301
+		0x00000001
+		0x00000000
+		0x00000000
+		0x01000000
+		0x80104002
+		0x00040003
+		0x00040005
+		0x00030000
+		0x00050004
+		0x00000004
+		0x00040003
+		0x00040005
+		0x30a00000
+		0x00001850
+		0x185030a0
+		0x30a00000
+		0x00001850
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x02020200
+		0x00020202
+		0x00030200
+		0x00040700
+		0x00000302
+		0x02000407
+		0x00000003
+		0x00030f04
+		0x00070004
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00010000
+		0x20040020
+		0x00200400
+		0x01000400
+		0x00000b80
+		0x00000000
+		0x00000001
+		0x00000002
+		0x0000000e
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00a00000
+		0x00c80050
+		0x00c80000
+		0x005000a0
+		0x000000c8
+		0x00a000c8
+		0x00c80050
+		0x00c80000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00430000
+		0x0000001a
+		0x001a0043
+		0x00430000
+		0x0000001a
+		0x00010001
+		0x07000001
+		0x00000707
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00430000
+		0x0000001a
+		0x001a0043
+		0x00430000
+		0x0000001a
+		0x00010001
+		0x07000001
+		0x00000707
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x01000000
+		0x00000000
+		0x00000000
+		0x18151100
+		0x0000000c
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00032003
+		0x00480120
+		0x00000000
+		0x01200320
+		0x00000048
+		0x00032000
+		0x00480120
+		0x00000000
+		0x00280000
+		0x00280028
+		0x01010100
+		0x01000202
+		0x0a000002
+		0x01000f0f
+		0x00000000
+		0x00000000
+		0x00010003
+		0x00000c03
+		0x00000100
+		0x00010000
+		0x01000000
+		0x00010000
+		0x00000001
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00010000
+		0x03030301
+		0x01010808
+		0x03030001
+		0x0a0a0a03
+		0x02080808
+		0x02050103
+		0x02050103
+		0x00050103
+		0x00020202
+		0x05020500
+		0x00020502
+		0x00000000
+		0x00000000
+		0x0d000001
+		0x00010028
+		0x00010000
+		0x00000003
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00010100
+		0x01000000
+		0x00000001
+		0x00000303
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x000556aa
+		0x000aaaaa
+		0x000aa955
+		0x00055555
+		0x000b3133
+		0x0004cd33
+		0x0004cecc
+		0x000b32cc
+		0x00010300
+		0x03000100
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00ffff00
+		0x1e1e0000
+		0x0800001e
+		0x00001850
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00001850
+		0x0000f320
+		0x1850050a
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00001850
+		0x0000f320
+		0x1850050a
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00001850
+		0x0000f320
+		0x0202050a
+		0x03030202
+		0x00000018
+		0x00000000
+		0x00000000
+		0x00001403
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00030000
+		0x000e0020
+		0x000e0020
+		0x000e0020
+		0x00000000
+		0x00000000
+		0x01000000
+		0x00070007
+		0x00050007
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x01000101
+		0x01010101
+		0x01000101
+		0x01000100
+		0x00010001
+		0x00010002
+		0x00020100
+		0x00000002
+		0x00000700
+		0x00000000
+		0x000030a0
+		0x00001850
+		0x000030a0
+		0x00001850
+		0x000030a0
+		0x18501850
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00001850
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00001850
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00000200
+		0x00010000
+		0x00000007
+		0x81000001
+		0x0f0003f0
+		0x3fffffff
+		0x0f0000a0
+		0x377ff000
+		0x0f000020
+		0x377ff000
+		0x0f000030
+		0x377ff000
+		0x0f0000b0
+		0x377ff000
+		0x0f000100
+		0x377ff000
+		0x0f000110
+		0x377ff000
+		0x0f000010
+		0x377ff000
+		0x03000101
+		0x042e2e2e
+		0x06180006
+		0x00061800
+		0x00000018
+		0x0c2800a8
+		0x0c2800a8
+		0x0c2800a8
+		0x00000500
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x04040000
+		0x0d000004
+		0x00000128
+		0x00000000
+		0x00030003
+		0x00000018
+		0x00000000
+		0x00000000
+		0x03060002
+		0x03010301
+		0x01080801
+		0x04020201
+		0x01080804
+		0x00000000
+		0x03030000
+		0x0a0a0a03
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00030300
+		0x00000014
+		0x00000000
+		0x01010300
+		0x00000000
+		0x00000000
+		0x01000000
+		0x00000101
+		0x55555a5a
+		0x55555a5a
+		0x55555a5a
+		0x55555a5a
+		0x0a0a0001
+		0x0505000a
+		0x00000005
+		0x00000100
+		0x00030000
+		0x17030000
+		0x000e0020
+		0x000e0020
+		0x000e0020
+		0x00000000
+		0x00000000
+		0x00000100
+		0x140a0000
+		0x000a030a
+		0x03000a03
+		0x010a000a
+		0x00000100
+		0x01000000
+		0x00000000
+		0x00000100
+		0x1e1a0000
+		0x10010204
+		0x07070705
+		0x20000202
+		0x00201000
+		0x00201000
+		0x04041000
+		0x10100100
+		0x00010110
+		0x004b004a
+		0x1a030000
+		0x0102041e
+		0x34000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00004300
+		0x0001001a
+		0x004d4d07
+		0x001a0043
+		0x4d070001
+		0x0000434d
+		0x0001001a
+		0x004d4d07
+		0x001a0043
+		0x4d070001
+		0x0000434d
+		0x0001001a
+		0x004d4d07
+		0x001a0043
+		0x4d070001
+		0x0043004d
+		0x0001001a
+		0x004d4d07
+		0x001a0043
+		0x4d070001
+		0x0000434d
+		0x0001001a
+		0x004d4d07
+		0x001a0043
+		0x4d070001
+		0x0000434d
+		0x0001001a
+		0x004d4d07
+		0x001a0043
+		0x4d070001
+		0x0100004d
+		0x00c800c8
+		0x060400c8
+		0x0c060f11
+		0x2200d890
+		0x0a0c2005
+		0x0f11060a
+		0x00000c06
+		0x2200d890
+		0x0a0c2005
+		0x0f11060a
+		0x00000c06
+		0x2200d890
+		0x0a0c2005
+		0x0200020a
+		0x02000200
+		0x02000200
+		0x02000200
+		0x02000200
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x01000300
+		0x00185000
+		0x0000f320
+		0x00001850
+		0x0000f320
+		0x00001850
+		0x0000f320
+		0x08000000
+		0x00000100
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000002
+		0x76543210
+		0x0004c008
+		0x000000b3
+		0x00000000
+		0x00000000
+		0x00010000
+		0x01665555
+		0x00665555
+		0x00010f00
+		0x05010200
+		0x00000003
+		0x001700c0
+		0x00cc0101
+		0x00030066
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x04080000
+		0x04080400
+		0x08000000
+		0x0c00c007
+		0x00000100
+		0x00000100
+		0x55555555
+		0xaaaaaaaa
+		0x55555555
+		0xaaaaaaaa
+		0x00005555
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00200000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x02700270
+		0x02700270
+		0x02700270
+		0x02700270
+		0x00000270
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00800000
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00b30080
+		0x00000003
+		0x00000000
+		0x00020000
+		0x00000200
+		0x00000000
+		0x51315152
+		0xc0013150
+		0x020000c0
+		0x00100001
+		0x07054208
+		0x000f0c18
+		0x01000140
+		0x00000c20
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x76543210
+		0x0004c008
+		0x000000b3
+		0x00000000
+		0x00000000
+		0x00010000
+		0x01665555
+		0x00665555
+		0x00010f00
+		0x05010200
+		0x00000003
+		0x001700c0
+		0x00cc0101
+		0x00030066
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x04080000
+		0x04080400
+		0x08000000
+		0x0c00c007
+		0x00000100
+		0x00000100
+		0x55555555
+		0xaaaaaaaa
+		0x55555555
+		0xaaaaaaaa
+		0x00005555
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00200000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x02700270
+		0x02700270
+		0x02700270
+		0x02700270
+		0x00000270
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00800000
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00b30080
+		0x00000003
+		0x00000000
+		0x00020000
+		0x00000200
+		0x00000000
+		0x51315152
+		0xc0013150
+		0x020000c0
+		0x00100001
+		0x07054208
+		0x000f0c18
+		0x01000140
+		0x00000c20
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x76543210
+		0x0004c008
+		0x000000b3
+		0x00000000
+		0x00000000
+		0x00010000
+		0x01665555
+		0x00665555
+		0x00010f00
+		0x05010200
+		0x00000003
+		0x001700c0
+		0x00cc0101
+		0x00030066
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x04080000
+		0x04080400
+		0x08000000
+		0x0c00c007
+		0x00000100
+		0x00000100
+		0x55555555
+		0xaaaaaaaa
+		0x55555555
+		0xaaaaaaaa
+		0x00005555
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00200000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x02700270
+		0x02700270
+		0x02700270
+		0x02700270
+		0x00000270
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00800000
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00b30080
+		0x00000003
+		0x00000000
+		0x00020000
+		0x00000200
+		0x00000000
+		0x51315152
+		0xc0013150
+		0x020000c0
+		0x00100001
+		0x07054208
+		0x000f0c18
+		0x01000140
+		0x00000c20
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x76543210
+		0x0004c008
+		0x000000b3
+		0x00000000
+		0x00000000
+		0x00010000
+		0x01665555
+		0x00665555
+		0x00010f00
+		0x05010200
+		0x00000003
+		0x001700c0
+		0x00cc0101
+		0x00030066
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x04080000
+		0x04080400
+		0x08000000
+		0x0c00c007
+		0x00000100
+		0x00000100
+		0x55555555
+		0xaaaaaaaa
+		0x55555555
+		0xaaaaaaaa
+		0x00005555
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00200000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x02700270
+		0x02700270
+		0x02700270
+		0x02700270
+		0x00000270
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00800000
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00800080
+		0x00b30080
+		0x00000003
+		0x00000000
+		0x00020000
+		0x00000200
+		0x00000000
+		0x51315152
+		0xc0013150
+		0x020000c0
+		0x00100001
+		0x07054208
+		0x000f0c18
+		0x01000140
+		0x00000c20
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00800000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000001
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00400320
+		0x00000040
+		0x00806420
+		0x00917531
+		0x00806420
+		0x01917531
+		0x00020003
+		0x00000000
+		0x00000000
+		0x00000000
+		0x000556aa
+		0x000aaaaa
+		0x000aa955
+		0x00055555
+		0x000b3133
+		0x0004cd33
+		0x0004cecc
+		0x000b32cc
+		0x0a418820
+		0x103f0000
+		0x0000003f
+		0x00038055
+		0x03800380
+		0x03800380
+		0x00000380
+		0x42080010
+		0x00000003
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00800000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000001
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00400320
+		0x00000040
+		0x00008eca
+		0x00009fdb
+		0x00008eca
+		0x01009fdb
+		0x00020003
+		0x00000000
+		0x00000000
+		0x00000000
+		0x000556aa
+		0x000aaaaa
+		0x000aa955
+		0x00055555
+		0x000b3133
+		0x0004cd33
+		0x0004cecc
+		0x000b32cc
+		0x0004a0e6
+		0x080f0000
+		0x0000000f
+		0x00038055
+		0x03800380
+		0x03800380
+		0x00000380
+		0x42080010
+		0x00000003
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00800000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000001
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00400320
+		0x00000040
+		0x00008eca
+		0x00009fdb
+		0x00008eca
+		0x01009fdb
+		0x00020003
+		0x00000000
+		0x00000000
+		0x00000000
+		0x000556aa
+		0x000aaaaa
+		0x000aa955
+		0x00055555
+		0x000b3133
+		0x0004cd33
+		0x0004cecc
+		0x000b32cc
+		0x1ee6b16a
+		0x10000000
+		0x00000000
+		0x00038055
+		0x03800380
+		0x03800380
+		0x00000380
+		0x42080010
+		0x00000003
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000001
+		0x00000000
+		0x01000005
+		0x04000f00
+		0x00020040
+		0x00020055
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000050
+		0x00000000
+		0x00010100
+		0x00000601
+		0x00000000
+		0x00006400
+		0x01221102
+		0x00000000
+		0x00051f00
+		0x051f051f
+		0x051f051f
+		0x00030003
+		0x03000300
+		0x00000300
+		0x01221102
+		0x00000000
+		0x00000000
+		0x03020000
+		0x00000001
+		0x00000011
+		0x00000011
+		0x00000400
+		0x00000000
+		0x00000011
+		0x00000011
+		0x00004410
+		0x00004410
+		0x00004410
+		0x00004410
+		0x00004410
+		0x00000011
+		0x00004410
+		0x00000011
+		0x00004410
+		0x00000011
+		0x00004410
+		0x00000000
+		0x00000000
+		0x00000000
+		0x04000000
+		0x00000000
+		0x00000000
+		0x00000508
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0x00000000
+		0xe4000000
+		0x00000000
+		0x00000000
+		0x01010000
+		0x00000000
+	>;
+};
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h b/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
new file mode 100644
index 0000000..0b7cb1f
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2015 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef _ASM_ARCH_SDRAM_RK3399_H
+#define _ASM_ARCH_SDRAM_RK3399_H
+
+enum {
+	DDR3 = 0x3,
+	LPDDR2 = 0x5,
+	LPDDR3 = 0x6,
+	LPDDR4 = 0x7,
+	UNUSED = 0xFF
+};
+
+struct rk3399_ddr_pctl_regs {
+	u32 denali_ctl[332];
+};
+
+struct rk3399_ddr_publ_regs {
+	u32 denali_phy[959];
+};
+
+struct rk3399_ddr_pi_regs {
+	u32 denali_pi[200];
+};
+
+struct rk3399_msch_regs {
+	u32 coreid;
+	u32 revisionid;
+	u32 ddrconf;
+	u32 ddrsize;
+	u32 ddrtiminga0;
+	u32 ddrtimingb0;
+	u32 ddrtimingc0;
+	u32 devtodev0;
+	u32 reserved0[(0x110 - 0x20) / 4];
+	u32 ddrmode;
+	u32 reserved1[(0x1000 - 0x114) / 4];
+	u32 agingx0;
+};
+
+struct rk3399_msch_timings {
+	u32 ddrtiminga0;
+	u32 ddrtimingb0;
+	u32 ddrtimingc0;
+	u32 devtodev0;
+	u32 ddrmode;
+	u32 agingx0;
+};
+
+struct rk3399_ddr_cic_regs {
+	u32 cic_ctrl0;
+	u32 cic_ctrl1;
+	u32 cic_idle_th;
+	u32 cic_cg_wait_th;
+	u32 cic_status0;
+	u32 cic_status1;
+	u32 cic_ctrl2;
+	u32 cic_ctrl3;
+	u32 cic_ctrl4;
+};
+
+/* DENALI_CTL_00 */
+#define START		1
+
+/* DENALI_CTL_68 */
+#define PWRUP_SREFRESH_EXIT	(1 << 16)
+
+/* DENALI_CTL_274 */
+#define MEM_RST_VALID	1
+
+struct rk3399_sdram_channel {
+	unsigned int rank;
+	/* dram column number, 0 means this channel is invalid */
+	unsigned int col;
+	/* dram bank number, 3:8bank, 2:4bank */
+	unsigned int bk;
+	/* channel buswidth, 2:32bit, 1:16bit, 0:8bit */
+	unsigned int bw;
+	/* die buswidth, 2:32bit, 1:16bit, 0:8bit */
+	unsigned int dbw;
+	/*
+	 * row_3_4 = 1: 6Gb or 12Gb die
+	 * row_3_4 = 0: normal die, power of 2
+	 */
+	unsigned int row_3_4;
+	unsigned int cs0_row;
+	unsigned int cs1_row;
+	unsigned int ddrconfig;
+	struct rk3399_msch_timings noc_timings;
+};
+
+struct rk3399_base_params {
+	unsigned int ddr_freq;
+	unsigned int dramtype;
+	unsigned int num_channels;
+	unsigned int stride;
+	unsigned int odt;
+};
+
+struct rk3399_sdram_params {
+	struct rk3399_sdram_channel ch[2];
+	struct rk3399_base_params base;
+	/* align 8 byte */
+	struct rk3399_ddr_pctl_regs pctl_regs;
+	/* align 8 byte */
+	struct rk3399_ddr_pi_regs pi_regs;
+	/* align 8 byte */
+	struct rk3399_ddr_publ_regs phy_regs;
+	/* used for align 8byte for next struct */
+	unsigned int align_8;
+};
+
+#define PI_CA_TRAINING	(1 << 0)
+#define PI_WRITE_LEVELING	(1 << 1)
+#define PI_READ_GATE_TRAINING	(1 << 2)
+#define PI_READ_LEVELING	(1 << 3)
+#define PI_WDQ_LEVELING	(1 << 4)
+#define PI_FULL_TRAINING	(0xff)
+
+#endif
diff --git a/arch/arm/mach-rockchip/rk3399/Makefile b/arch/arm/mach-rockchip/rk3399/Makefile
index 98ebeac..437d851 100644
--- a/arch/arm/mach-rockchip/rk3399/Makefile
+++ b/arch/arm/mach-rockchip/rk3399/Makefile
@@ -7,3 +7,4 @@
 obj-y += clk_rk3399.o
 obj-y += rk3399.o
 obj-y += syscon_rk3399.o
+obj-y += sdram_rk3399.o
diff --git a/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c b/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c
new file mode 100644
index 0000000..3989f67
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c
@@ -0,0 +1,1259 @@
+/*
+ * (C) Copyright 2016 Rockchip Inc.
+ *
+ * SPDX-License-Identifier:     GPL-2.0
+ *
+ * Adapted from coreboot.
+ */
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dt-structs.h>
+#include <ram.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sdram_rk3399.h>
+#include <asm/arch/cru_rk3399.h>
+#include <asm/arch/grf_rk3399.h>
+#include <asm/arch/hardware.h>
+#include <linux/err.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+struct chan_info {
+	struct rk3399_ddr_pctl_regs *pctl;
+	struct rk3399_ddr_pi_regs *pi;
+	struct rk3399_ddr_publ_regs *publ;
+	struct rk3399_msch_regs *msch;
+};
+
+struct dram_info {
+#ifdef CONFIG_SPL_BUILD
+	struct chan_info chan[2];
+	struct clk ddr_clk;
+	struct rk3399_cru *cru;
+	struct rk3399_pmucru *pmucru;
+	struct rk3399_pmusgrf_regs *pmusgrf;
+	struct rk3399_ddr_cic_regs *cic;
+#endif
+	struct ram_info info;
+	struct rk3399_pmugrf_regs *pmugrf;
+};
+
+/*
+ * sys_reg bitfield struct
+ * [31]		row_3_4_ch1
+ * [30]		row_3_4_ch0
+ * [29:28]	chinfo
+ * [27]		rank_ch1
+ * [26:25]	col_ch1
+ * [24]		bk_ch1
+ * [23:22]	cs0_row_ch1
+ * [21:20]	cs1_row_ch1
+ * [19:18]	bw_ch1
+ * [17:16]	dbw_ch1;
+ * [15:13]	ddrtype
+ * [12]		channelnum
+ * [11]		rank_ch0
+ * [10:9]	col_ch0
+ * [8]		bk_ch0
+ * [7:6]	cs0_row_ch0
+ * [5:4]	cs1_row_ch0
+ * [3:2]	bw_ch0
+ * [1:0]	dbw_ch0
+*/
+#define SYS_REG_DDRTYPE_SHIFT		13
+#define SYS_REG_DDRTYPE_MASK		7
+#define SYS_REG_NUM_CH_SHIFT		12
+#define SYS_REG_NUM_CH_MASK		1
+#define SYS_REG_ROW_3_4_SHIFT(ch)	(30 + (ch))
+#define SYS_REG_ROW_3_4_MASK		1
+#define SYS_REG_CHINFO_SHIFT(ch)	(28 + (ch))
+#define SYS_REG_RANK_SHIFT(ch)		(11 + (ch) * 16)
+#define SYS_REG_RANK_MASK		1
+#define SYS_REG_COL_SHIFT(ch)		(9 + (ch) * 16)
+#define SYS_REG_COL_MASK		3
+#define SYS_REG_BK_SHIFT(ch)		(8 + (ch) * 16)
+#define SYS_REG_BK_MASK			1
+#define SYS_REG_CS0_ROW_SHIFT(ch)	(6 + (ch) * 16)
+#define SYS_REG_CS0_ROW_MASK		3
+#define SYS_REG_CS1_ROW_SHIFT(ch)	(4 + (ch) * 16)
+#define SYS_REG_CS1_ROW_MASK		3
+#define SYS_REG_BW_SHIFT(ch)		(2 + (ch) * 16)
+#define SYS_REG_BW_MASK			3
+#define SYS_REG_DBW_SHIFT(ch)		((ch) * 16)
+#define SYS_REG_DBW_MASK		3
+
+
+
+#define PRESET_SGRF_HOLD(n)	((0x1 << (6+16)) | ((n) << 6))
+#define PRESET_GPIO0_HOLD(n)	((0x1 << (7+16)) | ((n) << 7))
+#define PRESET_GPIO1_HOLD(n)	((0x1 << (8+16)) | ((n) << 8))
+
+#define PHY_DRV_ODT_Hi_Z	0x0
+#define PHY_DRV_ODT_240		0x1
+#define PHY_DRV_ODT_120		0x8
+#define PHY_DRV_ODT_80		0x9
+#define PHY_DRV_ODT_60		0xc
+#define PHY_DRV_ODT_48		0xd
+#define PHY_DRV_ODT_40		0xe
+#define PHY_DRV_ODT_34_3	0xf
+
+#ifdef CONFIG_SPL_BUILD
+
+struct rockchip_dmc_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	struct dtd_rockchip_rk3399_dmc dtplat;
+#endif
+	struct regmap *map;
+};
+
+static void 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 phy_dll_bypass_set(struct rk3399_ddr_publ_regs *ddr_publ_regs,
+			       u32 freq)
+{
+	u32 *denali_phy = ddr_publ_regs->denali_phy;
+
+	/* From IP spec, only freq small than 125 can enter dll bypass mode */
+	if (freq <= 125) {
+		/* phy_sw_master_mode_X PHY_86/214/342/470 4bits offset_8 */
+		setbits_le32(&denali_phy[86], (0x3 << 2) << 8);
+		setbits_le32(&denali_phy[214], (0x3 << 2) << 8);
+		setbits_le32(&denali_phy[342], (0x3 << 2) << 8);
+		setbits_le32(&denali_phy[470], (0x3 << 2) << 8);
+
+		/* phy_adrctl_sw_master_mode PHY_547/675/803 4bits offset_16 */
+		setbits_le32(&denali_phy[547], (0x3 << 2) << 16);
+		setbits_le32(&denali_phy[675], (0x3 << 2) << 16);
+		setbits_le32(&denali_phy[803], (0x3 << 2) << 16);
+	} else {
+		/* phy_sw_master_mode_X PHY_86/214/342/470 4bits offset_8 */
+		clrbits_le32(&denali_phy[86], (0x3 << 2) << 8);
+		clrbits_le32(&denali_phy[214], (0x3 << 2) << 8);
+		clrbits_le32(&denali_phy[342], (0x3 << 2) << 8);
+		clrbits_le32(&denali_phy[470], (0x3 << 2) << 8);
+
+		/* phy_adrctl_sw_master_mode PHY_547/675/803 4bits offset_16 */
+		clrbits_le32(&denali_phy[547], (0x3 << 2) << 16);
+		clrbits_le32(&denali_phy[675], (0x3 << 2) << 16);
+		clrbits_le32(&denali_phy[803], (0x3 << 2) << 16);
+	}
+}
+
+static void set_memory_map(const struct chan_info *chan, u32 channel,
+			   const struct rk3399_sdram_params *sdram_params)
+{
+	const struct rk3399_sdram_channel *sdram_ch =
+		&sdram_params->ch[channel];
+	u32 *denali_ctl = chan->pctl->denali_ctl;
+	u32 *denali_pi = chan->pi->denali_pi;
+	u32 cs_map;
+	u32 reduc;
+	u32 row;
+
+	/* Get row number from ddrconfig setting */
+	if (sdram_ch->ddrconfig < 2 || sdram_ch->ddrconfig == 4)
+		row = 16;
+	else if (sdram_ch->ddrconfig == 3)
+		row = 14;
+	else
+		row = 15;
+
+	cs_map = (sdram_ch->rank > 1) ? 3 : 1;
+	reduc = (sdram_ch->bw == 2) ? 0 : 1;
+
+	/* Set the dram configuration to ctrl */
+	clrsetbits_le32(&denali_ctl[191], 0xF, (12 - sdram_ch->col));
+	clrsetbits_le32(&denali_ctl[190], (0x3 << 16) | (0x7 << 24),
+			((3 - sdram_ch->bk) << 16) |
+			((16 - row) << 24));
+
+	clrsetbits_le32(&denali_ctl[196], 0x3 | (1 << 16),
+			cs_map | (reduc << 16));
+
+	/* PI_199 PI_COL_DIFF:RW:0:4 */
+	clrsetbits_le32(&denali_pi[199], 0xF, (12 - sdram_ch->col));
+
+	/* PI_155 PI_ROW_DIFF:RW:24:3 PI_BANK_DIFF:RW:16:2 */
+	clrsetbits_le32(&denali_pi[155], (0x3 << 16) | (0x7 << 24),
+			((3 - sdram_ch->bk) << 16) |
+			((16 - row) << 24));
+	/* PI_41 PI_CS_MAP:RW:24:4 */
+	clrsetbits_le32(&denali_pi[41], 0xf << 24, cs_map << 24);
+	if ((sdram_ch->rank == 1) && (sdram_params->base.dramtype == DDR3))
+		writel(0x2EC7FFFF, &denali_pi[34]);
+}
+
+static void set_ds_odt(const struct chan_info *chan,
+		       const struct rk3399_sdram_params *sdram_params)
+{
+	u32 *denali_phy = chan->publ->denali_phy;
+
+	u32 tsel_idle_en, tsel_wr_en, tsel_rd_en;
+	u32 tsel_idle_select_p, tsel_wr_select_p, tsel_rd_select_p;
+	u32 ca_tsel_wr_select_p, ca_tsel_wr_select_n;
+	u32 tsel_idle_select_n, tsel_wr_select_n, tsel_rd_select_n;
+	u32 reg_value;
+
+	if (sdram_params->base.dramtype == LPDDR4) {
+		tsel_rd_select_p = PHY_DRV_ODT_Hi_Z;
+		tsel_wr_select_p = PHY_DRV_ODT_40;
+		ca_tsel_wr_select_p = PHY_DRV_ODT_40;
+		tsel_idle_select_p = PHY_DRV_ODT_Hi_Z;
+
+		tsel_rd_select_n = PHY_DRV_ODT_240;
+		tsel_wr_select_n = PHY_DRV_ODT_40;
+		ca_tsel_wr_select_n = PHY_DRV_ODT_40;
+		tsel_idle_select_n = PHY_DRV_ODT_240;
+	} else if (sdram_params->base.dramtype == LPDDR3) {
+		tsel_rd_select_p = PHY_DRV_ODT_240;
+		tsel_wr_select_p = PHY_DRV_ODT_34_3;
+		ca_tsel_wr_select_p = PHY_DRV_ODT_48;
+		tsel_idle_select_p = PHY_DRV_ODT_240;
+
+		tsel_rd_select_n = PHY_DRV_ODT_Hi_Z;
+		tsel_wr_select_n = PHY_DRV_ODT_34_3;
+		ca_tsel_wr_select_n = PHY_DRV_ODT_48;
+		tsel_idle_select_n = PHY_DRV_ODT_Hi_Z;
+	} else {
+		tsel_rd_select_p = PHY_DRV_ODT_240;
+		tsel_wr_select_p = PHY_DRV_ODT_34_3;
+		ca_tsel_wr_select_p = PHY_DRV_ODT_34_3;
+		tsel_idle_select_p = PHY_DRV_ODT_240;
+
+		tsel_rd_select_n = PHY_DRV_ODT_240;
+		tsel_wr_select_n = PHY_DRV_ODT_34_3;
+		ca_tsel_wr_select_n = PHY_DRV_ODT_34_3;
+		tsel_idle_select_n = PHY_DRV_ODT_240;
+	}
+
+	if (sdram_params->base.odt == 1)
+		tsel_rd_en = 1;
+	else
+		tsel_rd_en = 0;
+
+	tsel_wr_en = 0;
+	tsel_idle_en = 0;
+
+	/*
+	 * phy_dq_tsel_select_X 24bits DENALI_PHY_6/134/262/390 offset_0
+	 * sets termination values for read/idle cycles and drive strength
+	 * for write cycles for DQ/DM
+	 */
+	reg_value = tsel_rd_select_n | (tsel_rd_select_p << 0x4) |
+		    (tsel_wr_select_n << 8) | (tsel_wr_select_p << 12) |
+		    (tsel_idle_select_n << 16) | (tsel_idle_select_p << 20);
+	clrsetbits_le32(&denali_phy[6], 0xffffff, reg_value);
+	clrsetbits_le32(&denali_phy[134], 0xffffff, reg_value);
+	clrsetbits_le32(&denali_phy[262], 0xffffff, reg_value);
+	clrsetbits_le32(&denali_phy[390], 0xffffff, reg_value);
+
+	/*
+	 * phy_dqs_tsel_select_X 24bits DENALI_PHY_7/135/263/391 offset_0
+	 * sets termination values for read/idle cycles and drive strength
+	 * for write cycles for DQS
+	 */
+	clrsetbits_le32(&denali_phy[7], 0xffffff, reg_value);
+	clrsetbits_le32(&denali_phy[135], 0xffffff, reg_value);
+	clrsetbits_le32(&denali_phy[263], 0xffffff, reg_value);
+	clrsetbits_le32(&denali_phy[391], 0xffffff, reg_value);
+
+	/* phy_adr_tsel_select_ 8bits DENALI_PHY_544/672/800 offset_0 */
+	reg_value = ca_tsel_wr_select_n | (ca_tsel_wr_select_p << 0x4);
+	clrsetbits_le32(&denali_phy[544], 0xff, reg_value);
+	clrsetbits_le32(&denali_phy[672], 0xff, reg_value);
+	clrsetbits_le32(&denali_phy[800], 0xff, reg_value);
+
+	/* phy_pad_addr_drive 8bits DENALI_PHY_928 offset_0 */
+	clrsetbits_le32(&denali_phy[928], 0xff, reg_value);
+
+	/* phy_pad_rst_drive 8bits DENALI_PHY_937 offset_0 */
+	clrsetbits_le32(&denali_phy[937], 0xff, reg_value);
+
+	/* phy_pad_cke_drive 8bits DENALI_PHY_935 offset_0 */
+	clrsetbits_le32(&denali_phy[935], 0xff, reg_value);
+
+	/* phy_pad_cs_drive 8bits DENALI_PHY_939 offset_0 */
+	clrsetbits_le32(&denali_phy[939], 0xff, reg_value);
+
+	/* phy_pad_clk_drive 8bits DENALI_PHY_929 offset_0 */
+	clrsetbits_le32(&denali_phy[929], 0xff, reg_value);
+
+	/* phy_pad_fdbk_drive 23bit DENALI_PHY_924/925 */
+	clrsetbits_le32(&denali_phy[924], 0xff,
+			tsel_wr_select_n | (tsel_wr_select_p << 4));
+	clrsetbits_le32(&denali_phy[925], 0xff,
+			tsel_rd_select_n | (tsel_rd_select_p << 4));
+
+	/* phy_dq_tsel_enable_X 3bits DENALI_PHY_5/133/261/389 offset_16 */
+	reg_value = (tsel_rd_en | (tsel_wr_en << 1) | (tsel_idle_en << 2))
+		<< 16;
+	clrsetbits_le32(&denali_phy[5], 0x7 << 16, reg_value);
+	clrsetbits_le32(&denali_phy[133], 0x7 << 16, reg_value);
+	clrsetbits_le32(&denali_phy[261], 0x7 << 16, reg_value);
+	clrsetbits_le32(&denali_phy[389], 0x7 << 16, reg_value);
+
+	/* phy_dqs_tsel_enable_X 3bits DENALI_PHY_6/134/262/390 offset_24 */
+	reg_value = (tsel_rd_en | (tsel_wr_en << 1) | (tsel_idle_en << 2))
+		<< 24;
+	clrsetbits_le32(&denali_phy[6], 0x7 << 24, reg_value);
+	clrsetbits_le32(&denali_phy[134], 0x7 << 24, reg_value);
+	clrsetbits_le32(&denali_phy[262], 0x7 << 24, reg_value);
+	clrsetbits_le32(&denali_phy[390], 0x7 << 24, reg_value);
+
+	/* phy_adr_tsel_enable_ 1bit DENALI_PHY_518/646/774 offset_8 */
+	reg_value = tsel_wr_en << 8;
+	clrsetbits_le32(&denali_phy[518], 0x1 << 8, reg_value);
+	clrsetbits_le32(&denali_phy[646], 0x1 << 8, reg_value);
+	clrsetbits_le32(&denali_phy[774], 0x1 << 8, reg_value);
+
+	/* phy_pad_addr_term tsel 1bit DENALI_PHY_933 offset_17 */
+	reg_value = tsel_wr_en << 17;
+	clrsetbits_le32(&denali_phy[933], 0x1 << 17, reg_value);
+	/*
+	 * pad_rst/cke/cs/clk_term tsel 1bits
+	 * DENALI_PHY_938/936/940/934 offset_17
+	 */
+	clrsetbits_le32(&denali_phy[938], 0x1 << 17, reg_value);
+	clrsetbits_le32(&denali_phy[936], 0x1 << 17, reg_value);
+	clrsetbits_le32(&denali_phy[940], 0x1 << 17, reg_value);
+	clrsetbits_le32(&denali_phy[934], 0x1 << 17, reg_value);
+
+	/* phy_pad_fdbk_term 1bit DENALI_PHY_930 offset_17 */
+	clrsetbits_le32(&denali_phy[930], 0x1 << 17, reg_value);
+}
+
+static int phy_io_config(const struct chan_info *chan,
+			  const struct rk3399_sdram_params *sdram_params)
+{
+	u32 *denali_phy = chan->publ->denali_phy;
+	u32 vref_mode_dq, vref_value_dq, vref_mode_ac, vref_value_ac;
+	u32 mode_sel;
+	u32 reg_value;
+	u32 drv_value, odt_value;
+	u32 speed;
+
+	/* vref setting */
+	if (sdram_params->base.dramtype == LPDDR4) {
+		/* LPDDR4 */
+		vref_mode_dq = 0x6;
+		vref_value_dq = 0x1f;
+		vref_mode_ac = 0x6;
+		vref_value_ac = 0x1f;
+	} else if (sdram_params->base.dramtype == LPDDR3) {
+		if (sdram_params->base.odt == 1) {
+			vref_mode_dq = 0x5;  /* LPDDR3 ODT */
+			drv_value = (readl(&denali_phy[6]) >> 12) & 0xf;
+			odt_value = (readl(&denali_phy[6]) >> 4) & 0xf;
+			if (drv_value == PHY_DRV_ODT_48) {
+				switch (odt_value) {
+				case PHY_DRV_ODT_240:
+					vref_value_dq = 0x16;
+					break;
+				case PHY_DRV_ODT_120:
+					vref_value_dq = 0x26;
+					break;
+				case PHY_DRV_ODT_60:
+					vref_value_dq = 0x36;
+					break;
+				default:
+					debug("Halting: Invalid ODT value.\n");
+					return -EINVAL;
+				}
+			} else if (drv_value == PHY_DRV_ODT_40) {
+				switch (odt_value) {
+				case PHY_DRV_ODT_240:
+					vref_value_dq = 0x19;
+					break;
+				case PHY_DRV_ODT_120:
+					vref_value_dq = 0x23;
+					break;
+				case PHY_DRV_ODT_60:
+					vref_value_dq = 0x31;
+					break;
+				default:
+					debug("Halting: Invalid ODT value.\n");
+					return -EINVAL;
+				}
+			} else if (drv_value == PHY_DRV_ODT_34_3) {
+				switch (odt_value) {
+				case PHY_DRV_ODT_240:
+					vref_value_dq = 0x17;
+					break;
+				case PHY_DRV_ODT_120:
+					vref_value_dq = 0x20;
+					break;
+				case PHY_DRV_ODT_60:
+					vref_value_dq = 0x2e;
+					break;
+				default:
+					debug("Halting: Invalid ODT value.\n");
+					return -EINVAL;
+				}
+			} else {
+				debug("Halting: Invalid DRV value.\n");
+				return -EINVAL;
+			}
+		} else {
+			vref_mode_dq = 0x2;  /* LPDDR3 */
+			vref_value_dq = 0x1f;
+		}
+		vref_mode_ac = 0x2;
+		vref_value_ac = 0x1f;
+	} else if (sdram_params->base.dramtype == DDR3) {
+		/* DDR3L */
+		vref_mode_dq = 0x1;
+		vref_value_dq = 0x1f;
+		vref_mode_ac = 0x1;
+		vref_value_ac = 0x1f;
+	} else {
+		debug("Halting: Unknown DRAM type.\n");
+		return -ENODEV;
+	}
+
+	reg_value = (vref_mode_dq << 9) | (0x1 << 8) | vref_value_dq;
+
+	/* PHY_913 PHY_PAD_VREF_CTRL_DQ_0 12bits offset_8 */
+	clrsetbits_le32(&denali_phy[913], 0xfff << 8, reg_value << 8);
+	/* PHY_914 PHY_PAD_VREF_CTRL_DQ_1 12bits offset_0 */
+	clrsetbits_le32(&denali_phy[914], 0xfff, reg_value);
+	/* PHY_914 PHY_PAD_VREF_CTRL_DQ_2 12bits offset_16 */
+	clrsetbits_le32(&denali_phy[914], 0xfff << 16, reg_value << 16);
+	/* PHY_915 PHY_PAD_VREF_CTRL_DQ_3 12bits offset_0 */
+	clrsetbits_le32(&denali_phy[915], 0xfff, reg_value);
+
+	reg_value = (vref_mode_ac << 9) | (0x1 << 8) | vref_value_ac;
+
+	/* PHY_915 PHY_PAD_VREF_CTRL_AC 12bits offset_16 */
+	clrsetbits_le32(&denali_phy[915], 0xfff << 16, reg_value << 16);
+
+	if (sdram_params->base.dramtype == LPDDR4)
+		mode_sel = 0x6;
+	else if (sdram_params->base.dramtype == LPDDR3)
+		mode_sel = 0x0;
+	else if (sdram_params->base.dramtype == DDR3)
+		mode_sel = 0x1;
+	else
+		return -ENODEV;
+
+	/* PHY_924 PHY_PAD_FDBK_DRIVE */
+	clrsetbits_le32(&denali_phy[924], 0x7 << 15, mode_sel << 15);
+	/* PHY_926 PHY_PAD_DATA_DRIVE */
+	clrsetbits_le32(&denali_phy[926], 0x7 << 6, mode_sel << 6);
+	/* PHY_927 PHY_PAD_DQS_DRIVE */
+	clrsetbits_le32(&denali_phy[927], 0x7 << 6, mode_sel << 6);
+	/* PHY_928 PHY_PAD_ADDR_DRIVE */
+	clrsetbits_le32(&denali_phy[928], 0x7 << 14, mode_sel << 14);
+	/* PHY_929 PHY_PAD_CLK_DRIVE */
+	clrsetbits_le32(&denali_phy[929], 0x7 << 14, mode_sel << 14);
+	/* PHY_935 PHY_PAD_CKE_DRIVE */
+	clrsetbits_le32(&denali_phy[935], 0x7 << 14, mode_sel << 14);
+	/* PHY_937 PHY_PAD_RST_DRIVE */
+	clrsetbits_le32(&denali_phy[937], 0x7 << 14, mode_sel << 14);
+	/* PHY_939 PHY_PAD_CS_DRIVE */
+	clrsetbits_le32(&denali_phy[939], 0x7 << 14, mode_sel << 14);
+
+
+	/* speed setting */
+	if (sdram_params->base.ddr_freq < 400)
+		speed = 0x0;
+	else if (sdram_params->base.ddr_freq < 800)
+		speed = 0x1;
+	else if (sdram_params->base.ddr_freq < 1200)
+		speed = 0x2;
+	else
+		speed = 0x3;
+
+	/* PHY_924 PHY_PAD_FDBK_DRIVE */
+	clrsetbits_le32(&denali_phy[924], 0x3 << 21, speed << 21);
+	/* PHY_926 PHY_PAD_DATA_DRIVE */
+	clrsetbits_le32(&denali_phy[926], 0x3 << 9, speed << 9);
+	/* PHY_927 PHY_PAD_DQS_DRIVE */
+	clrsetbits_le32(&denali_phy[927], 0x3 << 9, speed << 9);
+	/* PHY_928 PHY_PAD_ADDR_DRIVE */
+	clrsetbits_le32(&denali_phy[928], 0x3 << 17, speed << 17);
+	/* PHY_929 PHY_PAD_CLK_DRIVE */
+	clrsetbits_le32(&denali_phy[929], 0x3 << 17, speed << 17);
+	/* PHY_935 PHY_PAD_CKE_DRIVE */
+	clrsetbits_le32(&denali_phy[935], 0x3 << 17, speed << 17);
+	/* PHY_937 PHY_PAD_RST_DRIVE */
+	clrsetbits_le32(&denali_phy[937], 0x3 << 17, speed << 17);
+	/* PHY_939 PHY_PAD_CS_DRIVE */
+	clrsetbits_le32(&denali_phy[939], 0x3 << 17, speed << 17);
+
+	return 0;
+}
+
+static int pctl_cfg(const struct chan_info *chan, u32 channel,
+		    const struct rk3399_sdram_params *sdram_params)
+{
+	u32 *denali_ctl = chan->pctl->denali_ctl;
+	u32 *denali_pi = chan->pi->denali_pi;
+	u32 *denali_phy = chan->publ->denali_phy;
+	const u32 *params_ctl = sdram_params->pctl_regs.denali_ctl;
+	const u32 *params_phy = sdram_params->phy_regs.denali_phy;
+	u32 tmp, tmp1, tmp2;
+	u32 pwrup_srefresh_exit;
+	int ret;
+
+	/*
+	 * work around controller bug:
+	 * Do not program DRAM_CLASS until NO_PHY_IND_TRAIN_INT is programmed
+	 */
+	copy_to_reg(&denali_ctl[1], &params_ctl[1],
+		    sizeof(struct rk3399_ddr_pctl_regs) - 4);
+	writel(params_ctl[0], &denali_ctl[0]);
+	copy_to_reg(denali_pi, &sdram_params->pi_regs.denali_pi[0],
+		    sizeof(struct rk3399_ddr_pi_regs));
+	/* rank count need to set for init */
+	set_memory_map(chan, channel, sdram_params);
+
+	writel(sdram_params->phy_regs.denali_phy[910], &denali_phy[910]);
+	writel(sdram_params->phy_regs.denali_phy[911], &denali_phy[911]);
+	writel(sdram_params->phy_regs.denali_phy[912], &denali_phy[912]);
+
+	pwrup_srefresh_exit = readl(&denali_ctl[68]) & PWRUP_SREFRESH_EXIT;
+	clrbits_le32(&denali_ctl[68], PWRUP_SREFRESH_EXIT);
+
+	/* PHY_DLL_RST_EN */
+	clrsetbits_le32(&denali_phy[957], 0x3 << 24, 1 << 24);
+
+	setbits_le32(&denali_pi[0], START);
+	setbits_le32(&denali_ctl[0], START);
+
+	/* Wating for phy DLL lock */
+	while (1) {
+		tmp = readl(&denali_phy[920]);
+		tmp1 = readl(&denali_phy[921]);
+		tmp2 = readl(&denali_phy[922]);
+		if ((((tmp >> 16) & 0x1) == 0x1) &&
+		    (((tmp1 >> 16) & 0x1) == 0x1) &&
+		    (((tmp1 >> 0) & 0x1) == 0x1) &&
+		    (((tmp2 >> 0) & 0x1) == 0x1))
+			break;
+	}
+
+	copy_to_reg(&denali_phy[896], &params_phy[896], (958 - 895) * 4);
+	copy_to_reg(&denali_phy[0], &params_phy[0], (90 - 0 + 1) * 4);
+	copy_to_reg(&denali_phy[128], &params_phy[128], (218 - 128 + 1) * 4);
+	copy_to_reg(&denali_phy[256], &params_phy[256], (346 - 256 + 1) * 4);
+	copy_to_reg(&denali_phy[384], &params_phy[384], (474 - 384 + 1) * 4);
+	copy_to_reg(&denali_phy[512], &params_phy[512], (549 - 512 + 1) * 4);
+	copy_to_reg(&denali_phy[640], &params_phy[640], (677 - 640 + 1) * 4);
+	copy_to_reg(&denali_phy[768], &params_phy[768], (805 - 768 + 1) * 4);
+	set_ds_odt(chan, sdram_params);
+
+	/*
+	 * phy_dqs_tsel_wr_timing_X 8bits DENALI_PHY_84/212/340/468 offset_8
+	 * dqs_tsel_wr_end[7:4] add Half cycle
+	 */
+	tmp = (readl(&denali_phy[84]) >> 8) & 0xff;
+	clrsetbits_le32(&denali_phy[84], 0xff << 8, (tmp + 0x10) << 8);
+	tmp = (readl(&denali_phy[212]) >> 8) & 0xff;
+	clrsetbits_le32(&denali_phy[212], 0xff << 8, (tmp + 0x10) << 8);
+	tmp = (readl(&denali_phy[340]) >> 8) & 0xff;
+	clrsetbits_le32(&denali_phy[340], 0xff << 8, (tmp + 0x10) << 8);
+	tmp = (readl(&denali_phy[468]) >> 8) & 0xff;
+	clrsetbits_le32(&denali_phy[468], 0xff << 8, (tmp + 0x10) << 8);
+
+	/*
+	 * phy_dqs_tsel_wr_timing_X 8bits DENALI_PHY_83/211/339/467 offset_8
+	 * dq_tsel_wr_end[7:4] add Half cycle
+	 */
+	tmp = (readl(&denali_phy[83]) >> 16) & 0xff;
+	clrsetbits_le32(&denali_phy[83], 0xff << 16, (tmp + 0x10) << 16);
+	tmp = (readl(&denali_phy[211]) >> 16) & 0xff;
+	clrsetbits_le32(&denali_phy[211], 0xff << 16, (tmp + 0x10) << 16);
+	tmp = (readl(&denali_phy[339]) >> 16) & 0xff;
+	clrsetbits_le32(&denali_phy[339], 0xff << 16, (tmp + 0x10) << 16);
+	tmp = (readl(&denali_phy[467]) >> 16) & 0xff;
+	clrsetbits_le32(&denali_phy[467], 0xff << 16, (tmp + 0x10) << 16);
+
+	ret = phy_io_config(chan, sdram_params);
+	if (ret)
+		return ret;
+
+	/* PHY_DLL_RST_EN */
+	clrsetbits_le32(&denali_phy[957], 0x3 << 24, 0x2 << 24);
+
+	/* Wating for PHY and DRAM init complete */
+	tmp = 0;
+	while (!(readl(&denali_ctl[203]) & (1 << 3))) {
+		mdelay(10);
+		tmp++;
+		if (tmp > 10)
+			return -ETIME;
+	}
+
+	clrsetbits_le32(&denali_ctl[68], PWRUP_SREFRESH_EXIT,
+			pwrup_srefresh_exit);
+	return 0;
+}
+
+static void select_per_cs_training_index(const struct chan_info *chan,
+					 u32 rank)
+{
+	u32 *denali_phy = chan->publ->denali_phy;
+
+	/* PHY_84 PHY_PER_CS_TRAINING_EN_0 1bit offset_16 */
+	if ((readl(&denali_phy[84])>>16) & 1) {
+		/*
+		 * PHY_8/136/264/392
+		 * phy_per_cs_training_index_X 1bit offset_24
+		 */
+		clrsetbits_le32(&denali_phy[8], 0x1 << 24, rank << 24);
+		clrsetbits_le32(&denali_phy[136], 0x1 << 24, rank << 24);
+		clrsetbits_le32(&denali_phy[264], 0x1 << 24, rank << 24);
+		clrsetbits_le32(&denali_phy[392], 0x1 << 24, rank << 24);
+	}
+}
+
+static void override_write_leveling_value(const struct chan_info *chan)
+{
+	u32 *denali_ctl = chan->pctl->denali_ctl;
+	u32 *denali_phy = chan->publ->denali_phy;
+	u32 byte;
+
+	/* PHY_896 PHY_FREQ_SEL_MULTICAST_EN 1bit offset_0 */
+	setbits_le32(&denali_phy[896], 1);
+
+	/*
+	 * PHY_8/136/264/392
+	 * phy_per_cs_training_multicast_en_X 1bit offset_16
+	 */
+	clrsetbits_le32(&denali_phy[8], 0x1 << 16, 1 << 16);
+	clrsetbits_le32(&denali_phy[136], 0x1 << 16, 1 << 16);
+	clrsetbits_le32(&denali_phy[264], 0x1 << 16, 1 << 16);
+	clrsetbits_le32(&denali_phy[392], 0x1 << 16, 1 << 16);
+
+	for (byte = 0; byte < 4; byte++)
+		clrsetbits_le32(&denali_phy[63 + (128 * byte)], 0xffff << 16,
+				0x200 << 16);
+
+	/* PHY_896 PHY_FREQ_SEL_MULTICAST_EN 1bit offset_0 */
+	clrbits_le32(&denali_phy[896], 1);
+
+	/* CTL_200 ctrlupd_req 1bit offset_8 */
+	clrsetbits_le32(&denali_ctl[200], 0x1 << 8, 0x1 << 8);
+}
+
+static int data_training_ca(const struct chan_info *chan, u32 channel,
+			    const struct rk3399_sdram_params *sdram_params)
+{
+	u32 *denali_pi = chan->pi->denali_pi;
+	u32 *denali_phy = chan->publ->denali_phy;
+	u32 i, tmp;
+	u32 obs_0, obs_1, obs_2, obs_err = 0;
+	u32 rank = sdram_params->ch[channel].rank;
+
+	for (i = 0; i < rank; i++) {
+		select_per_cs_training_index(chan, i);
+		/* PI_100 PI_CALVL_EN:RW:8:2 */
+		clrsetbits_le32(&denali_pi[100], 0x3 << 8, 0x2 << 8);
+		/* PI_92 PI_CALVL_REQ:WR:16:1,PI_CALVL_CS:RW:24:2 */
+		clrsetbits_le32(&denali_pi[92],
+				(0x1 << 16) | (0x3 << 24),
+				(0x1 << 16) | (i << 24));
+
+		/* Waiting for training complete */
+		while (1) {
+			/* PI_174 PI_INT_STATUS:RD:8:18 */
+			tmp = readl(&denali_pi[174]) >> 8;
+			/*
+			 * check status obs
+			 * PHY_532/660/789 phy_adr_calvl_obs1_:0:32
+			 */
+			obs_0 = readl(&denali_phy[532]);
+			obs_1 = readl(&denali_phy[660]);
+			obs_2 = readl(&denali_phy[788]);
+			if (((obs_0 >> 30) & 0x3) ||
+			    ((obs_1 >> 30) & 0x3) ||
+			    ((obs_2 >> 30) & 0x3))
+				obs_err = 1;
+			if ((((tmp >> 11) & 0x1) == 0x1) &&
+			    (((tmp >> 13) & 0x1) == 0x1) &&
+			    (((tmp >> 5) & 0x1) == 0x0) &&
+			    (obs_err == 0))
+				break;
+			else if ((((tmp >> 5) & 0x1) == 0x1) ||
+				 (obs_err == 1))
+				return -EIO;
+		}
+		/* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
+		writel(0x00003f7c, (&denali_pi[175]));
+	}
+	clrbits_le32(&denali_pi[100], 0x3 << 8);
+
+	return 0;
+}
+
+static int data_training_wl(const struct chan_info *chan, u32 channel,
+			    const struct rk3399_sdram_params *sdram_params)
+{
+	u32 *denali_pi = chan->pi->denali_pi;
+	u32 *denali_phy = chan->publ->denali_phy;
+	u32 i, tmp;
+	u32 obs_0, obs_1, obs_2, obs_3, obs_err = 0;
+	u32 rank = sdram_params->ch[channel].rank;
+
+	for (i = 0; i < rank; i++) {
+		select_per_cs_training_index(chan, i);
+		/* PI_60 PI_WRLVL_EN:RW:8:2 */
+		clrsetbits_le32(&denali_pi[60], 0x3 << 8, 0x2 << 8);
+		/* PI_59 PI_WRLVL_REQ:WR:8:1,PI_WRLVL_CS:RW:16:2 */
+		clrsetbits_le32(&denali_pi[59],
+				(0x1 << 8) | (0x3 << 16),
+				(0x1 << 8) | (i << 16));
+
+		/* Waiting for training complete */
+		while (1) {
+			/* PI_174 PI_INT_STATUS:RD:8:18 */
+			tmp = readl(&denali_pi[174]) >> 8;
+
+			/*
+			 * check status obs, if error maybe can not
+			 * get leveling done PHY_40/168/296/424
+			 * phy_wrlvl_status_obs_X:0:13
+			 */
+			obs_0 = readl(&denali_phy[40]);
+			obs_1 = readl(&denali_phy[168]);
+			obs_2 = readl(&denali_phy[296]);
+			obs_3 = readl(&denali_phy[424]);
+			if (((obs_0 >> 12) & 0x1) ||
+			    ((obs_1 >> 12) & 0x1) ||
+			    ((obs_2 >> 12) & 0x1) ||
+			    ((obs_3 >> 12) & 0x1))
+				obs_err = 1;
+			if ((((tmp >> 10) & 0x1) == 0x1) &&
+			    (((tmp >> 13) & 0x1) == 0x1) &&
+			    (((tmp >> 4) & 0x1) == 0x0) &&
+			    (obs_err == 0))
+				break;
+			else if ((((tmp >> 4) & 0x1) == 0x1) ||
+				 (obs_err == 1))
+				return -EIO;
+		}
+		/* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
+		writel(0x00003f7c, (&denali_pi[175]));
+	}
+
+	override_write_leveling_value(chan);
+	clrbits_le32(&denali_pi[60], 0x3 << 8);
+
+	return 0;
+}
+
+static int data_training_rg(const struct chan_info *chan, u32 channel,
+			    const struct rk3399_sdram_params *sdram_params)
+{
+	u32 *denali_pi = chan->pi->denali_pi;
+	u32 *denali_phy = chan->publ->denali_phy;
+	u32 i, tmp;
+	u32 obs_0, obs_1, obs_2, obs_3, obs_err = 0;
+	u32 rank = sdram_params->ch[channel].rank;
+
+	for (i = 0; i < rank; i++) {
+		select_per_cs_training_index(chan, i);
+		/* PI_80 PI_RDLVL_GATE_EN:RW:24:2 */
+		clrsetbits_le32(&denali_pi[80], 0x3 << 24, 0x2 << 24);
+		/*
+		 * PI_74 PI_RDLVL_GATE_REQ:WR:16:1
+		 * PI_RDLVL_CS:RW:24:2
+		 */
+		clrsetbits_le32(&denali_pi[74],
+				(0x1 << 16) | (0x3 << 24),
+				(0x1 << 16) | (i << 24));
+
+		/* Waiting for training complete */
+		while (1) {
+			/* PI_174 PI_INT_STATUS:RD:8:18 */
+			tmp = readl(&denali_pi[174]) >> 8;
+
+			/*
+			 * check status obs
+			 * PHY_43/171/299/427
+			 *     PHY_GTLVL_STATUS_OBS_x:16:8
+			 */
+			obs_0 = readl(&denali_phy[43]);
+			obs_1 = readl(&denali_phy[171]);
+			obs_2 = readl(&denali_phy[299]);
+			obs_3 = readl(&denali_phy[427]);
+			if (((obs_0 >> (16 + 6)) & 0x3) ||
+			    ((obs_1 >> (16 + 6)) & 0x3) ||
+			    ((obs_2 >> (16 + 6)) & 0x3) ||
+			    ((obs_3 >> (16 + 6)) & 0x3))
+				obs_err = 1;
+			if ((((tmp >> 9) & 0x1) == 0x1) &&
+			    (((tmp >> 13) & 0x1) == 0x1) &&
+			    (((tmp >> 3) & 0x1) == 0x0) &&
+			    (obs_err == 0))
+				break;
+			else if ((((tmp >> 3) & 0x1) == 0x1) ||
+				 (obs_err == 1))
+				return -EIO;
+		}
+		/* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
+		writel(0x00003f7c, (&denali_pi[175]));
+	}
+	clrbits_le32(&denali_pi[80], 0x3 << 24);
+
+	return 0;
+}
+
+static int data_training_rl(const struct chan_info *chan, u32 channel,
+			    const struct rk3399_sdram_params *sdram_params)
+{
+	u32 *denali_pi = chan->pi->denali_pi;
+	u32 i, tmp;
+	u32 rank = sdram_params->ch[channel].rank;
+
+	for (i = 0; i < rank; i++) {
+		select_per_cs_training_index(chan, i);
+		/* PI_80 PI_RDLVL_EN:RW:16:2 */
+		clrsetbits_le32(&denali_pi[80], 0x3 << 16, 0x2 << 16);
+		/* PI_74 PI_RDLVL_REQ:WR:8:1,PI_RDLVL_CS:RW:24:2 */
+		clrsetbits_le32(&denali_pi[74],
+				(0x1 << 8) | (0x3 << 24),
+				(0x1 << 8) | (i << 24));
+
+		/* Waiting for training complete */
+		while (1) {
+			/* PI_174 PI_INT_STATUS:RD:8:18 */
+			tmp = readl(&denali_pi[174]) >> 8;
+
+			/*
+			 * make sure status obs not report error bit
+			 * PHY_46/174/302/430
+			 *     phy_rdlvl_status_obs_X:16:8
+			 */
+			if ((((tmp >> 8) & 0x1) == 0x1) &&
+			    (((tmp >> 13) & 0x1) == 0x1) &&
+			    (((tmp >> 2) & 0x1) == 0x0))
+				break;
+			else if (((tmp >> 2) & 0x1) == 0x1)
+				return -EIO;
+		}
+		/* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
+		writel(0x00003f7c, (&denali_pi[175]));
+	}
+	clrbits_le32(&denali_pi[80], 0x3 << 16);
+
+	return 0;
+}
+
+static int data_training_wdql(const struct chan_info *chan, u32 channel,
+			      const struct rk3399_sdram_params *sdram_params)
+{
+	u32 *denali_pi = chan->pi->denali_pi;
+	u32 i, tmp;
+	u32 rank = sdram_params->ch[channel].rank;
+
+	for (i = 0; i < rank; i++) {
+		select_per_cs_training_index(chan, i);
+		/*
+		 * disable PI_WDQLVL_VREF_EN before wdq leveling?
+		 * PI_181 PI_WDQLVL_VREF_EN:RW:8:1
+		 */
+		clrbits_le32(&denali_pi[181], 0x1 << 8);
+		/* PI_124 PI_WDQLVL_EN:RW:16:2 */
+		clrsetbits_le32(&denali_pi[124], 0x3 << 16, 0x2 << 16);
+		/* PI_121 PI_WDQLVL_REQ:WR:8:1,PI_WDQLVL_CS:RW:16:2 */
+		clrsetbits_le32(&denali_pi[121],
+				(0x1 << 8) | (0x3 << 16),
+				(0x1 << 8) | (i << 16));
+
+		/* Waiting for training complete */
+		while (1) {
+			/* PI_174 PI_INT_STATUS:RD:8:18 */
+			tmp = readl(&denali_pi[174]) >> 8;
+			if ((((tmp >> 12) & 0x1) == 0x1) &&
+			    (((tmp >> 13) & 0x1) == 0x1) &&
+			    (((tmp >> 6) & 0x1) == 0x0))
+				break;
+			else if (((tmp >> 6) & 0x1) == 0x1)
+				return -EIO;
+		}
+		/* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
+		writel(0x00003f7c, (&denali_pi[175]));
+	}
+	clrbits_le32(&denali_pi[124], 0x3 << 16);
+
+	return 0;
+}
+
+static int data_training(const struct chan_info *chan, u32 channel,
+			 const struct rk3399_sdram_params *sdram_params,
+			 u32 training_flag)
+{
+	u32 *denali_phy = chan->publ->denali_phy;
+
+	/* PHY_927 PHY_PAD_DQS_DRIVE  RPULL offset_22 */
+	setbits_le32(&denali_phy[927], (1 << 22));
+
+	if (training_flag == PI_FULL_TRAINING) {
+		if (sdram_params->base.dramtype == LPDDR4) {
+			training_flag = PI_CA_TRAINING | PI_WRITE_LEVELING |
+					PI_READ_GATE_TRAINING |
+					PI_READ_LEVELING | PI_WDQ_LEVELING;
+		} else if (sdram_params->base.dramtype == LPDDR3) {
+			training_flag = PI_CA_TRAINING | PI_WRITE_LEVELING |
+					PI_READ_GATE_TRAINING;
+		} else if (sdram_params->base.dramtype == DDR3) {
+			training_flag = PI_WRITE_LEVELING |
+					PI_READ_GATE_TRAINING |
+					PI_READ_LEVELING;
+		}
+	}
+
+	/* ca training(LPDDR4,LPDDR3 support) */
+	if ((training_flag & PI_CA_TRAINING) == PI_CA_TRAINING)
+		data_training_ca(chan, channel, sdram_params);
+
+	/* write leveling(LPDDR4,LPDDR3,DDR3 support) */
+	if ((training_flag & PI_WRITE_LEVELING) == PI_WRITE_LEVELING)
+		data_training_wl(chan, channel, sdram_params);
+
+	/* read gate training(LPDDR4,LPDDR3,DDR3 support) */
+	if ((training_flag & PI_READ_GATE_TRAINING) == PI_READ_GATE_TRAINING)
+		data_training_rg(chan, channel, sdram_params);
+
+	/* read leveling(LPDDR4,LPDDR3,DDR3 support) */
+	if ((training_flag & PI_READ_LEVELING) == PI_READ_LEVELING)
+		data_training_rl(chan, channel, sdram_params);
+
+	/* wdq leveling(LPDDR4 support) */
+	if ((training_flag & PI_WDQ_LEVELING) == PI_WDQ_LEVELING)
+		data_training_wdql(chan, channel, sdram_params);
+
+	/* PHY_927 PHY_PAD_DQS_DRIVE  RPULL offset_22 */
+	clrbits_le32(&denali_phy[927], (1 << 22));
+
+	return 0;
+}
+
+static void set_ddrconfig(const struct chan_info *chan,
+			  const struct rk3399_sdram_params *sdram_params,
+			  unsigned char channel, u32 ddrconfig)
+{
+	/* only need to set ddrconfig */
+	struct rk3399_msch_regs *ddr_msch_regs = chan->msch;
+	unsigned int cs0_cap = 0;
+	unsigned int cs1_cap = 0;
+
+	cs0_cap = (1 << (sdram_params->ch[channel].cs0_row
+			+ sdram_params->ch[channel].col
+			+ sdram_params->ch[channel].bk
+			+ sdram_params->ch[channel].bw - 20));
+	if (sdram_params->ch[channel].rank > 1)
+		cs1_cap = cs0_cap >> (sdram_params->ch[channel].cs0_row
+				- sdram_params->ch[channel].cs1_row);
+	if (sdram_params->ch[channel].row_3_4) {
+		cs0_cap = cs0_cap * 3 / 4;
+		cs1_cap = cs1_cap * 3 / 4;
+	}
+
+	writel(ddrconfig | (ddrconfig << 8), &ddr_msch_regs->ddrconf);
+	writel(((cs0_cap / 32) & 0xff) | (((cs1_cap / 32) & 0xff) << 8),
+	       &ddr_msch_regs->ddrsize);
+}
+
+static void dram_all_config(struct dram_info *dram,
+			    const struct rk3399_sdram_params *sdram_params)
+{
+	u32 sys_reg = 0;
+	unsigned int channel, idx;
+
+	sys_reg |= sdram_params->base.dramtype << SYS_REG_DDRTYPE_SHIFT;
+	sys_reg |= (sdram_params->base.num_channels - 1)
+		    << SYS_REG_NUM_CH_SHIFT;
+	for (channel = 0, idx = 0;
+	     (idx < sdram_params->base.num_channels) && (channel < 2);
+	     channel++) {
+		const struct rk3399_sdram_channel *info =
+			&sdram_params->ch[channel];
+		struct rk3399_msch_regs *ddr_msch_regs;
+		const struct rk3399_msch_timings *noc_timing;
+
+		if (sdram_params->ch[channel].col == 0)
+			continue;
+		idx++;
+		sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(channel);
+		sys_reg |= 1 << SYS_REG_CHINFO_SHIFT(channel);
+		sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(channel);
+		sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(channel);
+		sys_reg |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(channel);
+		sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(channel);
+		sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(channel);
+		sys_reg |= (2 >> info->bw) << SYS_REG_BW_SHIFT(channel);
+		sys_reg |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(channel);
+
+		ddr_msch_regs = dram->chan[channel].msch;
+		noc_timing = &sdram_params->ch[channel].noc_timings;
+		writel(noc_timing->ddrtiminga0,
+		       &ddr_msch_regs->ddrtiminga0);
+		writel(noc_timing->ddrtimingb0,
+		       &ddr_msch_regs->ddrtimingb0);
+		writel(noc_timing->ddrtimingc0,
+		       &ddr_msch_regs->ddrtimingc0);
+		writel(noc_timing->devtodev0,
+		       &ddr_msch_regs->devtodev0);
+		writel(noc_timing->ddrmode,
+		       &ddr_msch_regs->ddrmode);
+
+		/* rank 1 memory clock disable (dfi_dram_clk_disable = 1) */
+		if (sdram_params->ch[channel].rank == 1)
+			setbits_le32(&dram->chan[channel].pctl->denali_ctl[276],
+				     1 << 17);
+	}
+
+	writel(sys_reg, &dram->pmugrf->os_reg2);
+	rk_clrsetreg(&dram->pmusgrf->soc_con4, 0x1f << 10,
+		     sdram_params->base.stride << 10);
+
+	/* reboot hold register set */
+	writel(PRESET_SGRF_HOLD(0) | PRESET_GPIO0_HOLD(1) |
+		PRESET_GPIO1_HOLD(1),
+		&dram->pmucru->pmucru_rstnhold_con[1]);
+	clrsetbits_le32(&dram->cru->glb_rst_con, 0x3, 0x3);
+}
+
+static int switch_to_phy_index1(struct dram_info *dram,
+				 const struct rk3399_sdram_params *sdram_params)
+{
+	u32 channel;
+	u32 *denali_phy;
+	u32 ch_count = sdram_params->base.num_channels;
+	int i = 0;
+
+	writel(RK_CLRSETBITS(0x03 << 4 | 1 << 2 | 1,
+			     1 << 4 | 1 << 2 | 1),
+			&dram->cic->cic_ctrl0);
+	while (!(readl(&dram->cic->cic_status0) & (1 << 2))) {
+		mdelay(10);
+		i++;
+		if (i > 10) {
+			debug("index1 frequency change overtime, reset\n");
+			return -ETIME;
+		}
+	}
+
+	i = 0;
+	writel(RK_CLRSETBITS(1 << 1, 1 << 1), &dram->cic->cic_ctrl0);
+	while (!(readl(&dram->cic->cic_status0) & (1 << 0))) {
+		mdelay(10);
+		if (i > 10) {
+			debug("index1 frequency done overtime, reset\n");
+			return -ETIME;
+		}
+	}
+
+	for (channel = 0; channel < ch_count; channel++) {
+		denali_phy = dram->chan[channel].publ->denali_phy;
+		clrsetbits_le32(&denali_phy[896], (0x3 << 8) | 1, 1 << 8);
+		if (data_training(&dram->chan[channel], channel,
+				  sdram_params, PI_FULL_TRAINING)) {
+			debug("index1 training failed, reset\n");
+			return -EIO;
+		}
+	}
+
+	return 0;
+}
+
+static int sdram_init(struct dram_info *dram,
+		      const struct rk3399_sdram_params *sdram_params)
+{
+	unsigned char dramtype = sdram_params->base.dramtype;
+	unsigned int ddr_freq = sdram_params->base.ddr_freq;
+	int channel;
+
+	printf("Starting SDRAM initialization...\n");
+
+	if ((dramtype == DDR3 && ddr_freq > 800) ||
+	    (dramtype == LPDDR3 && ddr_freq > 933) ||
+	    (dramtype == LPDDR4 && ddr_freq > 800)) {
+		debug("SDRAM frequency is to high!");
+		return -E2BIG;
+	}
+
+	for (channel = 0; channel < 2; channel++) {
+		const struct chan_info *chan = &dram->chan[channel];
+		struct rk3399_ddr_publ_regs *publ = chan->publ;
+
+		phy_dll_bypass_set(publ, ddr_freq);
+
+		if (channel >= sdram_params->base.num_channels)
+			continue;
+
+		if (pctl_cfg(chan, channel, sdram_params) != 0) {
+			printf("pctl_cfg fail, reset\n");
+			return -EIO;
+		}
+
+		/* LPDDR2/LPDDR3 need to wait DAI complete, max 10us */
+		if (dramtype == LPDDR3)
+			udelay(10);
+
+		if (data_training(chan, channel,
+				  sdram_params, PI_FULL_TRAINING)) {
+			printf("SDRAM initialization failed, reset\n");
+			return -EIO;
+		}
+
+		set_ddrconfig(chan, sdram_params, channel,
+			      sdram_params->ch[channel].ddrconfig);
+	}
+	dram_all_config(dram, sdram_params);
+	switch_to_phy_index1(dram, sdram_params);
+
+	printf("Finish SDRAM initialization...\n");
+	return 0;
+}
+#endif
+
+size_t sdram_size_mb(struct dram_info *dram)
+{
+	u32 rank, col, bk, cs0_row, cs1_row, bw, row_3_4;
+	size_t chipsize_mb = 0;
+	size_t size_mb = 0;
+	u32 ch;
+
+	u32 sys_reg = readl(&dram->pmugrf->os_reg2);
+	u32 ch_num = 1 + ((sys_reg >> SYS_REG_NUM_CH_SHIFT)
+		       & SYS_REG_NUM_CH_MASK);
+
+	for (ch = 0; ch < ch_num; ch++) {
+		rank = 1 + (sys_reg >> SYS_REG_RANK_SHIFT(ch) &
+			SYS_REG_RANK_MASK);
+		col = 9 + (sys_reg >> SYS_REG_COL_SHIFT(ch) & SYS_REG_COL_MASK);
+		bk = 3 - ((sys_reg >> SYS_REG_BK_SHIFT(ch)) & SYS_REG_BK_MASK);
+		cs0_row = 13 + (sys_reg >> SYS_REG_CS0_ROW_SHIFT(ch) &
+				SYS_REG_CS0_ROW_MASK);
+		cs1_row = 13 + (sys_reg >> SYS_REG_CS1_ROW_SHIFT(ch) &
+				SYS_REG_CS1_ROW_MASK);
+		bw = (2 >> ((sys_reg >> SYS_REG_BW_SHIFT(ch)) &
+			SYS_REG_BW_MASK));
+		row_3_4 = sys_reg >> SYS_REG_ROW_3_4_SHIFT(ch) &
+			SYS_REG_ROW_3_4_MASK;
+
+		chipsize_mb = (1 << (cs0_row + col + bk + bw - 20));
+
+		if (rank > 1)
+			chipsize_mb += chipsize_mb >> (cs0_row - cs1_row);
+		if (row_3_4)
+			chipsize_mb = chipsize_mb * 3 / 4;
+		size_mb += chipsize_mb;
+	}
+
+	/*
+	 * we use the 0x00000000~0xf7ffffff space
+	 * since 0xf8000000~0xffffffff is soc register space
+	 * so we reserve it
+	 */
+	size_mb = min_t(size_t, size_mb, 0xf8000000/(1<<20));
+
+	return size_mb;
+}
+
+static int rk3399_dmc_probe(struct udevice *dev)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+#ifdef CONFIG_SPL_BUILD
+	struct rockchip_dmc_plat *plat = dev_get_platdata(dev);
+	struct dtd_rockchip_rk3399_dmc *dtplat = &plat->dtplat;
+	struct rk3399_sdram_params *params =
+					(void *)dtplat->rockchip_sdram_params;
+	int ret;
+
+	priv->cic = syscon_get_first_range(ROCKCHIP_SYSCON_CIC);
+	priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
+	priv->pmusgrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUSGRF);
+	priv->pmucru = rockchip_get_pmucru();
+	priv->cru = rockchip_get_cru();
+	ret = regmap_init_mem_platdata(dev, dtplat->reg,
+				       ARRAY_SIZE(dtplat->reg) / 4,
+				       &plat->map);
+	if (ret)
+		return ret;
+	priv->chan[0].pctl = regmap_get_range(plat->map, 0);
+	priv->chan[0].pi = regmap_get_range(plat->map, 1);
+	priv->chan[0].publ = regmap_get_range(plat->map, 2);
+	priv->chan[0].msch = regmap_get_range(plat->map, 3);
+	priv->chan[1].pctl = regmap_get_range(plat->map, 4);
+	priv->chan[1].pi = regmap_get_range(plat->map, 5);
+	priv->chan[1].publ = regmap_get_range(plat->map, 6);
+	priv->chan[1].msch = regmap_get_range(plat->map, 7);
+
+	debug("con reg %p %p %p %p %p %p %p %p\n",
+	      priv->chan[0].pctl, priv->chan[0].pi,
+	      priv->chan[0].publ, priv->chan[0].msch,
+	      priv->chan[1].pctl, priv->chan[1].pi,
+	      priv->chan[1].publ, priv->chan[1].msch);
+	debug("cru %p, cic %p, grf %p, sgrf %p, pmucru %p\n", priv->cru,
+	      priv->cic, priv->pmugrf, priv->pmusgrf, priv->pmucru);
+
+	ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->ddr_clk);
+	if (ret) {
+		printf("%s clk get failed %d\n", __func__, ret);
+		return ret;
+	}
+	ret = clk_set_rate(&priv->ddr_clk, params->base.ddr_freq * MHz);
+	if (ret < 0) {
+		printf("%s clk set failed %d\n", __func__, ret);
+		return ret;
+	}
+	ret = sdram_init(priv, params);
+	if (ret < 0) {
+		printf("%s DRAM init failed%d\n", __func__, ret);
+		return ret;
+	}
+#else
+	priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
+	debug("%s: pmugrf=%p\n", __func__, priv->pmugrf);
+#endif
+	return 0;
+}
+
+static int rk3399_dmc_get_info(struct udevice *dev, struct ram_info *info)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+
+	info = &priv->info;
+	priv->info.base = 0;
+	priv->info.size = sdram_size_mb(priv) << 20;
+
+	return 0;
+}
+
+static struct ram_ops rk3399_dmc_ops = {
+	.get_info = rk3399_dmc_get_info,
+};
+
+
+static const struct udevice_id rk3399_dmc_ids[] = {
+	{ .compatible = "rockchip,rk3399-dmc" },
+	{ }
+};
+
+U_BOOT_DRIVER(dmc_rk3399) = {
+	.name = "rockchip_rk3399_dmc",
+	.id = UCLASS_RAM,
+	.of_match = rk3399_dmc_ids,
+	.ops = &rk3399_dmc_ops,
+	.probe = rk3399_dmc_probe,
+#ifdef CONFIG_SPL_BUILD
+	.priv_auto_alloc_size = sizeof(struct dram_info),
+	.platdata_auto_alloc_size = sizeof(struct rockchip_dmc_plat),
+#endif
+};
-- 
1.9.1

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

* [U-Boot] [PATCH v2 2/9] arm64: rk3399: move grf register definitions to grf_rk3399.h
  2017-02-13  9:38 [U-Boot] [PATCH v2 0/9] rk3399: enable SPL driver Kever Yang
  2017-02-13  9:38 ` [U-Boot] [PATCH v2 1/9] arm64: rk3399: add ddr controller driver Kever Yang
@ 2017-02-13  9:38 ` Kever Yang
  2017-02-21 20:33   ` Simon Glass
  2017-02-13  9:38 ` [U-Boot] [PATCH v2 3/9] clk: rk3399: update driver for spl Kever Yang
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Kever Yang @ 2017-02-13  9:38 UTC (permalink / raw)
  To: u-boot

rk3399 grf register bit defenitions should locate in header
file, so that not only pinctrl can use it.

Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None
Changes in v1: None

 arch/arm/include/asm/arch-rockchip/grf_rk3399.h | 118 ++++++++++++++++++++++++
 drivers/pinctrl/rockchip/pinctrl_rk3399.c       | 106 ---------------------
 2 files changed, 118 insertions(+), 106 deletions(-)

diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3399.h b/arch/arm/include/asm/arch-rockchip/grf_rk3399.h
index d3d1467..62d8496 100644
--- a/arch/arm/include/asm/arch-rockchip/grf_rk3399.h
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3399.h
@@ -318,4 +318,122 @@ struct rk3399_pmusgrf_regs {
 };
 check_member(rk3399_pmusgrf_regs, slv_secure_con4, 0xe3d4);
 
+enum {
+	/* GRF_GPIO2B_IOMUX */
+	GRF_GPIO2B1_SEL_SHIFT	= 0,
+	GRF_GPIO2B1_SEL_MASK	= 3 << GRF_GPIO2B1_SEL_SHIFT,
+	GRF_SPI2TPM_RXD		= 1,
+	GRF_GPIO2B2_SEL_SHIFT	= 2,
+	GRF_GPIO2B2_SEL_MASK	= 3 << GRF_GPIO2B2_SEL_SHIFT,
+	GRF_SPI2TPM_TXD		= 1,
+	GRF_GPIO2B3_SEL_SHIFT	= 6,
+	GRF_GPIO2B3_SEL_MASK	= 3 << GRF_GPIO2B3_SEL_SHIFT,
+	GRF_SPI2TPM_CLK		= 1,
+	GRF_GPIO2B4_SEL_SHIFT	= 8,
+	GRF_GPIO2B4_SEL_MASK	= 3 << GRF_GPIO2B4_SEL_SHIFT,
+	GRF_SPI2TPM_CSN0	= 1,
+
+	/* GRF_GPIO3A_IOMUX */
+	GRF_GPIO3A4_SEL_SHIFT	= 8,
+	GRF_GPIO3A4_SEL_MASK	= 3 << GRF_GPIO3A4_SEL_SHIFT,
+	GRF_SPI0NORCODEC_RXD	= 2,
+	GRF_GPIO3A5_SEL_SHIFT	= 10,
+	GRF_GPIO3A5_SEL_MASK	= 3 << GRF_GPIO3A5_SEL_SHIFT,
+	GRF_SPI0NORCODEC_TXD	= 2,
+	GRF_GPIO3A6_SEL_SHIFT	= 12,
+	GRF_GPIO3A6_SEL_MASK	= 3 << GRF_GPIO3A6_SEL_SHIFT,
+	GRF_SPI0NORCODEC_CLK	= 2,
+	GRF_GPIO3A7_SEL_SHIFT	= 14,
+	GRF_GPIO3A7_SEL_MASK	= 3 << GRF_GPIO3A7_SEL_SHIFT,
+	GRF_SPI0NORCODEC_CSN0	= 2,
+
+	/* GRF_GPIO3B_IOMUX */
+	GRF_GPIO3B0_SEL_SHIFT	= 0,
+	GRF_GPIO3B0_SEL_MASK	= 3 << GRF_GPIO3B0_SEL_SHIFT,
+	GRF_SPI0NORCODEC_CSN1	= 2,
+
+	/* GRF_GPIO4B_IOMUX */
+	GRF_GPIO4B0_SEL_SHIFT	= 0,
+	GRF_GPIO4B0_SEL_MASK	= 3 << GRF_GPIO4B0_SEL_SHIFT,
+	GRF_SDMMC_DATA0		= 1,
+	GRF_UART2DBGA_SIN	= 2,
+	GRF_GPIO4B1_SEL_SHIFT	= 2,
+	GRF_GPIO4B1_SEL_MASK	= 3 << GRF_GPIO4B1_SEL_SHIFT,
+	GRF_SDMMC_DATA1		= 1,
+	GRF_UART2DBGA_SOUT	= 2,
+	GRF_GPIO4B2_SEL_SHIFT	= 4,
+	GRF_GPIO4B2_SEL_MASK	= 3 << GRF_GPIO4B2_SEL_SHIFT,
+	GRF_SDMMC_DATA2		= 1,
+	GRF_GPIO4B3_SEL_SHIFT	= 6,
+	GRF_GPIO4B3_SEL_MASK	= 3 << GRF_GPIO4B3_SEL_SHIFT,
+	GRF_SDMMC_DATA3		= 1,
+	GRF_GPIO4B4_SEL_SHIFT	= 8,
+	GRF_GPIO4B4_SEL_MASK    = 3 << GRF_GPIO4B4_SEL_SHIFT,
+	GRF_SDMMC_CLKOUT        = 1,
+	GRF_GPIO4B5_SEL_SHIFT   = 10,
+	GRF_GPIO4B5_SEL_MASK    = 3 << GRF_GPIO4B5_SEL_SHIFT,
+	GRF_SDMMC_CMD           = 1,
+
+	/*  GRF_GPIO4C_IOMUX */
+	GRF_GPIO4C0_SEL_SHIFT   = 0,
+	GRF_GPIO4C0_SEL_MASK    = 3 << GRF_GPIO4C0_SEL_SHIFT,
+	GRF_UART2DGBB_SIN       = 2,
+	GRF_GPIO4C1_SEL_SHIFT   = 2,
+	GRF_GPIO4C1_SEL_MASK    = 3 << GRF_GPIO4C1_SEL_SHIFT,
+	GRF_UART2DGBB_SOUT      = 2,
+	GRF_GPIO4C2_SEL_SHIFT   = 4,
+	GRF_GPIO4C2_SEL_MASK    = 3 << GRF_GPIO4C2_SEL_SHIFT,
+	GRF_PWM_0               = 1,
+	GRF_GPIO4C3_SEL_SHIFT   = 6,
+	GRF_GPIO4C3_SEL_MASK    = 3 << GRF_GPIO4C3_SEL_SHIFT,
+	GRF_UART2DGBC_SIN       = 1,
+	GRF_GPIO4C4_SEL_SHIFT   = 8,
+	GRF_GPIO4C4_SEL_MASK    = 3 << GRF_GPIO4C4_SEL_SHIFT,
+	GRF_UART2DBGC_SOUT      = 1,
+	GRF_GPIO4C6_SEL_SHIFT   = 12,
+	GRF_GPIO4C6_SEL_MASK    = 3 << GRF_GPIO4C6_SEL_SHIFT,
+	GRF_PWM_1               = 1,
+
+	/* GRF_SOC_CON7 */
+	GRF_UART_DBG_SEL_SHIFT	= 10,
+	GRF_UART_DBG_SEL_MASK	= 3 << GRF_UART_DBG_SEL_SHIFT,
+	GRF_UART_DBG_SEL_C	= 2,
+
+	/*  PMUGRF_GPIO0A_IOMUX */
+	PMUGRF_GPIO0A6_SEL_SHIFT        = 12,
+	PMUGRF_GPIO0A6_SEL_MASK = 3 << PMUGRF_GPIO0A6_SEL_SHIFT,
+	PMUGRF_PWM_3A           = 1,
+
+	/*  PMUGRF_GPIO1A_IOMUX */
+	PMUGRF_GPIO1A7_SEL_SHIFT        = 14,
+	PMUGRF_GPIO1A7_SEL_MASK = 3 << PMUGRF_GPIO1A7_SEL_SHIFT,
+	PMUGRF_SPI1EC_RXD       = 2,
+
+	/*  PMUGRF_GPIO1B_IOMUX */
+	PMUGRF_GPIO1B0_SEL_SHIFT        = 0,
+	PMUGRF_GPIO1B0_SEL_MASK = 3 << PMUGRF_GPIO1B0_SEL_SHIFT,
+	PMUGRF_SPI1EC_TXD       = 2,
+	PMUGRF_GPIO1B1_SEL_SHIFT        = 2,
+	PMUGRF_GPIO1B1_SEL_MASK = 3 << PMUGRF_GPIO1B1_SEL_SHIFT,
+	PMUGRF_SPI1EC_CLK       = 2,
+	PMUGRF_GPIO1B2_SEL_SHIFT        = 4,
+	PMUGRF_GPIO1B2_SEL_MASK = 3 << PMUGRF_GPIO1B2_SEL_SHIFT,
+	PMUGRF_SPI1EC_CSN0      = 2,
+	PMUGRF_GPIO1B6_SEL_SHIFT        = 12,
+	PMUGRF_GPIO1B6_SEL_MASK = 3 << PMUGRF_GPIO1B6_SEL_SHIFT,
+	PMUGRF_PWM_3B           = 1,
+	PMUGRF_GPIO1B7_SEL_SHIFT        = 14,
+	PMUGRF_GPIO1B7_SEL_MASK = 3 << PMUGRF_GPIO1B7_SEL_SHIFT,
+	PMUGRF_I2C0PMU_SDA      = 2,
+
+	/*  PMUGRF_GPIO1C_IOMUX */
+	PMUGRF_GPIO1C0_SEL_SHIFT        = 0,
+	PMUGRF_GPIO1C0_SEL_MASK = 3 << PMUGRF_GPIO1C0_SEL_SHIFT,
+	PMUGRF_I2C0PMU_SCL      = 2,
+	PMUGRF_GPIO1C3_SEL_SHIFT        = 6,
+	PMUGRF_GPIO1C3_SEL_MASK = 3 << PMUGRF_GPIO1C3_SEL_SHIFT,
+	PMUGRF_PWM_2            = 1,
+
+};
+
 #endif	/* __SOC_ROCKCHIP_RK3399_GRF_H__ */
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3399.c b/drivers/pinctrl/rockchip/pinctrl_rk3399.c
index 17ea165..2f8aa64 100644
--- a/drivers/pinctrl/rockchip/pinctrl_rk3399.c
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3399.c
@@ -22,112 +22,6 @@ struct rk3399_pinctrl_priv {
 	struct rk3399_pmugrf_regs *pmugrf;
 };
 
-enum {
-	/* GRF_GPIO2B_IOMUX */
-	GRF_GPIO2B1_SEL_SHIFT	= 0,
-	GRF_GPIO2B1_SEL_MASK	= 3 << GRF_GPIO2B1_SEL_SHIFT,
-	GRF_SPI2TPM_RXD		= 1,
-	GRF_GPIO2B2_SEL_SHIFT	= 2,
-	GRF_GPIO2B2_SEL_MASK	= 3 << GRF_GPIO2B2_SEL_SHIFT,
-	GRF_SPI2TPM_TXD		= 1,
-	GRF_GPIO2B3_SEL_SHIFT	= 6,
-	GRF_GPIO2B3_SEL_MASK	= 3 << GRF_GPIO2B3_SEL_SHIFT,
-	GRF_SPI2TPM_CLK		= 1,
-	GRF_GPIO2B4_SEL_SHIFT	= 8,
-	GRF_GPIO2B4_SEL_MASK	= 3 << GRF_GPIO2B4_SEL_SHIFT,
-	GRF_SPI2TPM_CSN0	= 1,
-
-	/* GRF_GPIO3A_IOMUX */
-	GRF_GPIO3A4_SEL_SHIFT	= 8,
-	GRF_GPIO3A4_SEL_MASK	= 3 << GRF_GPIO3A4_SEL_SHIFT,
-	GRF_SPI0NORCODEC_RXD	= 2,
-	GRF_GPIO3A5_SEL_SHIFT	= 10,
-	GRF_GPIO3A5_SEL_MASK	= 3 << GRF_GPIO3A5_SEL_SHIFT,
-	GRF_SPI0NORCODEC_TXD	= 2,
-	GRF_GPIO3A6_SEL_SHIFT	= 12,
-	GRF_GPIO3A6_SEL_MASK	= 3 << GRF_GPIO3A6_SEL_SHIFT,
-	GRF_SPI0NORCODEC_CLK	= 2,
-	GRF_GPIO3A7_SEL_SHIFT	= 14,
-	GRF_GPIO3A7_SEL_MASK	= 3 << GRF_GPIO3A7_SEL_SHIFT,
-	GRF_SPI0NORCODEC_CSN0	= 2,
-
-	/* GRF_GPIO3B_IOMUX */
-	GRF_GPIO3B0_SEL_SHIFT	= 0,
-	GRF_GPIO3B0_SEL_MASK	= 3 << GRF_GPIO3B0_SEL_SHIFT,
-	GRF_SPI0NORCODEC_CSN1	= 2,
-
-	/* GRF_GPIO4B_IOMUX */
-	GRF_GPIO4B0_SEL_SHIFT	= 0,
-	GRF_GPIO4B0_SEL_MASK	= 3 << GRF_GPIO4B0_SEL_SHIFT,
-	GRF_SDMMC_DATA0		= 1,
-	GRF_UART2DBGA_SIN	= 2,
-	GRF_GPIO4B1_SEL_SHIFT	= 2,
-	GRF_GPIO4B1_SEL_MASK	= 3 << GRF_GPIO4B1_SEL_SHIFT,
-	GRF_SDMMC_DATA1		= 1,
-	GRF_UART2DBGA_SOUT	= 2,
-	GRF_GPIO4B2_SEL_SHIFT	= 4,
-	GRF_GPIO4B2_SEL_MASK	= 3 << GRF_GPIO4B2_SEL_SHIFT,
-	GRF_SDMMC_DATA2		= 1,
-	GRF_GPIO4B3_SEL_SHIFT	= 6,
-	GRF_GPIO4B3_SEL_MASK	= 3 << GRF_GPIO4B3_SEL_SHIFT,
-	GRF_SDMMC_DATA3		= 1,
-	GRF_GPIO4B4_SEL_SHIFT	= 8,
-	GRF_GPIO4B4_SEL_MASK	= 3 << GRF_GPIO4B4_SEL_SHIFT,
-	GRF_SDMMC_CLKOUT	= 1,
-	GRF_GPIO4B5_SEL_SHIFT	= 10,
-	GRF_GPIO4B5_SEL_MASK	= 3 << GRF_GPIO4B5_SEL_SHIFT,
-	GRF_SDMMC_CMD		= 1,
-
-	/* GRF_GPIO4C_IOMUX */
-	GRF_GPIO4C2_SEL_SHIFT	= 4,
-	GRF_GPIO4C2_SEL_MASK	= 3 << GRF_GPIO4C2_SEL_SHIFT,
-	GRF_PWM_0		= 1,
-	GRF_GPIO4C3_SEL_SHIFT	= 6,
-	GRF_GPIO4C3_SEL_MASK	= 3 << GRF_GPIO4C3_SEL_SHIFT,
-	GRF_UART2DGBC_SIN	= 1,
-	GRF_GPIO4C4_SEL_SHIFT	= 8,
-	GRF_GPIO4C4_SEL_MASK	= 3 << GRF_GPIO4C4_SEL_SHIFT,
-	GRF_UART2DBGC_SOUT	= 1,
-	GRF_GPIO4C6_SEL_SHIFT	= 12,
-	GRF_GPIO4C6_SEL_MASK	= 3 << GRF_GPIO4C6_SEL_SHIFT,
-	GRF_PWM_1		= 1,
-
-	/* PMUGRF_GPIO0A_IOMUX */
-	PMUGRF_GPIO0A6_SEL_SHIFT	= 12,
-	PMUGRF_GPIO0A6_SEL_MASK	= 3 << PMUGRF_GPIO0A6_SEL_SHIFT,
-	PMUGRF_PWM_3A		= 1,
-
-	/* PMUGRF_GPIO1A_IOMUX */
-	PMUGRF_GPIO1A7_SEL_SHIFT	= 14,
-	PMUGRF_GPIO1A7_SEL_MASK	= 3 << PMUGRF_GPIO1A7_SEL_SHIFT,
-	PMUGRF_SPI1EC_RXD	= 2,
-
-	/* PMUGRF_GPIO1B_IOMUX */
-	PMUGRF_GPIO1B0_SEL_SHIFT	= 0,
-	PMUGRF_GPIO1B0_SEL_MASK = 3 << PMUGRF_GPIO1B0_SEL_SHIFT,
-	PMUGRF_SPI1EC_TXD	= 2,
-	PMUGRF_GPIO1B1_SEL_SHIFT	= 2,
-	PMUGRF_GPIO1B1_SEL_MASK = 3 << PMUGRF_GPIO1B1_SEL_SHIFT,
-	PMUGRF_SPI1EC_CLK	= 2,
-	PMUGRF_GPIO1B2_SEL_SHIFT	= 4,
-	PMUGRF_GPIO1B2_SEL_MASK = 3 << PMUGRF_GPIO1B2_SEL_SHIFT,
-	PMUGRF_SPI1EC_CSN0	= 2,
-	PMUGRF_GPIO1B6_SEL_SHIFT	= 12,
-	PMUGRF_GPIO1B6_SEL_MASK	= 3 << PMUGRF_GPIO1B6_SEL_SHIFT,
-	PMUGRF_PWM_3B		= 1,
-	PMUGRF_GPIO1B7_SEL_SHIFT	= 14,
-	PMUGRF_GPIO1B7_SEL_MASK	= 3 << PMUGRF_GPIO1B7_SEL_SHIFT,
-	PMUGRF_I2C0PMU_SDA	= 2,
-
-	/* PMUGRF_GPIO1C_IOMUX */
-	PMUGRF_GPIO1C0_SEL_SHIFT	= 0,
-	PMUGRF_GPIO1C0_SEL_MASK	= 3 << PMUGRF_GPIO1C0_SEL_SHIFT,
-	PMUGRF_I2C0PMU_SCL	= 2,
-	PMUGRF_GPIO1C3_SEL_SHIFT	= 6,
-	PMUGRF_GPIO1C3_SEL_MASK	= 3 << PMUGRF_GPIO1C3_SEL_SHIFT,
-	PMUGRF_PWM_2		= 1,
-
-};
 static void pinctrl_rk3399_pwm_config(struct rk3399_grf_regs *grf,
 		struct rk3399_pmugrf_regs *pmugrf, int pwm_id)
 {
-- 
1.9.1

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

* [U-Boot] [PATCH v2 3/9] clk: rk3399: update driver for spl
  2017-02-13  9:38 [U-Boot] [PATCH v2 0/9] rk3399: enable SPL driver Kever Yang
  2017-02-13  9:38 ` [U-Boot] [PATCH v2 1/9] arm64: rk3399: add ddr controller driver Kever Yang
  2017-02-13  9:38 ` [U-Boot] [PATCH v2 2/9] arm64: rk3399: move grf register definitions to grf_rk3399.h Kever Yang
@ 2017-02-13  9:38 ` Kever Yang
  2017-02-21 20:33   ` Simon Glass
  2017-02-13  9:38 ` [U-Boot] [PATCH v2 4/9] sdhci: rk3399: update driver to support of-platdata Kever Yang
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Kever Yang @ 2017-02-13  9:38 UTC (permalink / raw)
  To: u-boot

Add ddr clock setting, add rockchip_get_pmucru API,
and enable of-platdata support.

Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None
Changes in v1: None

 arch/arm/include/asm/arch-rockchip/clock.h      |  7 ++
 arch/arm/include/asm/arch-rockchip/cru_rk3399.h |  5 ++
 arch/arm/mach-rockchip/rk3399/clk_rk3399.c      | 21 ++++++
 drivers/clk/rockchip/clk_rk3399.c               | 89 ++++++++++++++++++++++---
 include/dt-bindings/clock/rk3399-cru.h          | 16 +++--
 5 files changed, 123 insertions(+), 15 deletions(-)

diff --git a/arch/arm/include/asm/arch-rockchip/clock.h b/arch/arm/include/asm/arch-rockchip/clock.h
index 804c77b..6f7e755 100644
--- a/arch/arm/include/asm/arch-rockchip/clock.h
+++ b/arch/arm/include/asm/arch-rockchip/clock.h
@@ -63,6 +63,13 @@ static inline u32 clk_get_divisor(ulong input_rate, uint output_rate)
  */
 void *rockchip_get_cru(void);
 
+/**
+ * rockchip_get_pmucru() - get a pointer to the clock/reset unit registers
+ *
+ * @return pointer to registers, or -ve error on error
+ */
+void *rockchip_get_pmucru(void);
+
 struct rk3288_cru;
 struct rk3288_grf;
 
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3399.h b/arch/arm/include/asm/arch-rockchip/cru_rk3399.h
index 98fba2b..cf830d0 100644
--- a/arch/arm/include/asm/arch-rockchip/cru_rk3399.h
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3399.h
@@ -15,6 +15,11 @@ struct rk3399_clk_priv {
 	ulong rate;
 };
 
+struct rk3399_pmuclk_priv {
+	struct rk3399_pmucru *pmucru;
+	ulong rate;
+};
+
 struct rk3399_pmucru {
 	u32 ppll_con[6];
 	u32 reserved[0x1a];
diff --git a/arch/arm/mach-rockchip/rk3399/clk_rk3399.c b/arch/arm/mach-rockchip/rk3399/clk_rk3399.c
index ce706a6..cf5b8c9 100644
--- a/arch/arm/mach-rockchip/rk3399/clk_rk3399.c
+++ b/arch/arm/mach-rockchip/rk3399/clk_rk3399.c
@@ -31,3 +31,24 @@ void *rockchip_get_cru(void)
 
 	return priv->cru;
 }
+
+static int rockchip_get_pmucruclk(struct udevice **devp)
+{
+	return uclass_get_device_by_driver(UCLASS_CLK,
+			DM_GET_DRIVER(rockchip_rk3399_pmuclk), devp);
+}
+
+void *rockchip_get_pmucru(void)
+{
+	struct rk3399_pmuclk_priv *priv;
+	struct udevice *dev;
+	int ret;
+
+	ret = rockchip_get_pmucruclk(&dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	priv = dev_get_priv(dev);
+
+	return priv->pmucru;
+}
diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c
index 2e87e4b..8e3860b 100644
--- a/drivers/clk/rockchip/clk_rk3399.c
+++ b/drivers/clk/rockchip/clk_rk3399.c
@@ -7,7 +7,9 @@
 #include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
+#include <dt-structs.h>
 #include <errno.h>
+#include <mapmem.h>
 #include <syscon.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
@@ -18,10 +20,16 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-struct rk3399_pmuclk_priv {
-	struct rk3399_pmucru *pmucru;
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+struct rk3399_clk_plat {
+	struct dtd_rockchip_rk3399_cru dtd;
 };
 
+struct rk3399_pmuclk_plat {
+	struct dtd_rockchip_rk3399_pmucru dtd;
+};
+#endif
+
 struct pll_div {
 	u32 refdiv;
 	u32 fbdiv;
@@ -381,6 +389,7 @@ static int pll_para_config(u32 freq_hz, struct pll_div *div)
 	return 0;
 }
 
+#ifdef CONFIG_SPL_BUILD
 static void rkclk_init(struct rk3399_cru *cru)
 {
 	u32 aclk_div;
@@ -456,6 +465,7 @@ static void rkclk_init(struct rk3399_cru *cru)
 		     hclk_div << HCLK_PERILP1_DIV_CON_SHIFT |
 		     HCLK_PERILP1_PLL_SEL_GPLL << HCLK_PERILP1_PLL_SEL_SHIFT);
 }
+#endif
 
 void rk3399_configure_cpu(struct rk3399_cru *cru,
 			  enum apll_l_frequencies apll_l_freq)
@@ -709,6 +719,44 @@ static ulong rk3399_mmc_set_clk(struct rk3399_cru *cru,
 	return rk3399_mmc_get_clk(cru, clk_id);
 }
 
+#define PMUSGRF_DDR_RGN_CON16 0xff330040
+static ulong rk3399_ddr_set_clk(struct rk3399_cru *cru,
+				ulong set_rate)
+{
+	struct pll_div dpll_cfg;
+
+	/*  IC ECO bug, need to set this register */
+	writel(0xc000c000, PMUSGRF_DDR_RGN_CON16);
+
+	/*  clk_ddrc == DPLL = 24MHz / refdiv * fbdiv / postdiv1 / postdiv2 */
+	switch (set_rate) {
+	case 200*MHz:
+		dpll_cfg = (struct pll_div)
+		{.refdiv = 1, .fbdiv = 50, .postdiv1 = 6, .postdiv2 = 1};
+		break;
+	case 300*MHz:
+		dpll_cfg = (struct pll_div)
+		{.refdiv = 2, .fbdiv = 100, .postdiv1 = 4, .postdiv2 = 1};
+		break;
+	case 666*MHz:
+		dpll_cfg = (struct pll_div)
+		{.refdiv = 2, .fbdiv = 111, .postdiv1 = 2, .postdiv2 = 1};
+		break;
+	case 800*MHz:
+		dpll_cfg = (struct pll_div)
+		{.refdiv = 1, .fbdiv = 100, .postdiv1 = 3, .postdiv2 = 1};
+		break;
+	case 933*MHz:
+		dpll_cfg = (struct pll_div)
+		{.refdiv = 1, .fbdiv = 116, .postdiv1 = 3, .postdiv2 = 1};
+		break;
+	default:
+		error("Unsupported SDRAM frequency!,%ld\n", set_rate);
+	}
+	rkclk_set_pll(&cru->dpll_con[0], &dpll_cfg);
+
+	return set_rate;
+}
 static ulong rk3399_clk_get_rate(struct clk *clk)
 {
 	struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
@@ -763,6 +811,9 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate)
 	case DCLK_VOP1:
 		ret = rk3399_vop_set_clk(priv->cru, clk->id, rate);
 		break;
+	case SCLK_DDRCLK:
+		ret = rk3399_ddr_set_clk(priv->cru, rate);
+		break;
 	default:
 		return -ENOENT;
 	}
@@ -777,19 +828,26 @@ static struct clk_ops rk3399_clk_ops = {
 
 static int rk3399_clk_probe(struct udevice *dev)
 {
+#ifdef CONFIG_SPL_BUILD
 	struct rk3399_clk_priv *priv = dev_get_priv(dev);
 
-	rkclk_init(priv->cru);
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	struct rk3399_clk_plat *plat = dev_get_platdata(dev);
 
+	priv->cru = map_sysmem(plat->dtd.reg[1], plat->dtd.reg[3]);
+#endif
+	rkclk_init(priv->cru);
+#endif
 	return 0;
 }
 
 static int rk3399_clk_ofdata_to_platdata(struct udevice *dev)
 {
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 	struct rk3399_clk_priv *priv = dev_get_priv(dev);
 
 	priv->cru = (struct rk3399_cru *)dev_get_addr(dev);
-
+#endif
 	return 0;
 }
 
@@ -811,7 +869,7 @@ static const struct udevice_id rk3399_clk_ids[] = {
 };
 
 U_BOOT_DRIVER(clk_rk3399) = {
-	.name		= "clk_rk3399",
+	.name		= "rockchip_rk3399_cru",
 	.id		= UCLASS_CLK,
 	.of_match	= rk3399_clk_ids,
 	.priv_auto_alloc_size = sizeof(struct rk3399_clk_priv),
@@ -819,6 +877,9 @@ U_BOOT_DRIVER(clk_rk3399) = {
 	.ops		= &rk3399_clk_ops,
 	.bind		= rk3399_clk_bind,
 	.probe		= rk3399_clk_probe,
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	.platdata_auto_alloc_size = sizeof(struct rk3399_clk_plat),
+#endif
 };
 
 static ulong rk3399_i2c_get_pmuclk(struct rk3399_pmucru *pmucru, ulong clk_id)
@@ -939,7 +1000,6 @@ static void pmuclk_init(struct rk3399_pmucru *pmucru)
 
 	/*  configure pmu pclk */
 	pclk_div = PPLL_HZ / PMU_PCLK_HZ - 1;
-	assert((pclk_div + 1) * PMU_PCLK_HZ == PPLL_HZ && pclk_div < 0x1f);
 	rk_clrsetreg(&pmucru->pmucru_clksel[0],
 		     PMU_PCLK_DIV_CON_MASK,
 		     pclk_div << PMU_PCLK_DIV_CON_SHIFT);
@@ -949,17 +1009,25 @@ static int rk3399_pmuclk_probe(struct udevice *dev)
 {
 	struct rk3399_pmuclk_priv *priv = dev_get_priv(dev);
 
-	pmuclk_init(priv->pmucru);
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	struct rk3399_pmuclk_plat *plat = dev_get_platdata(dev);
+
+	priv->pmucru = map_sysmem(plat->dtd.reg[1], plat->dtd.reg[3]);
+#endif
 
+#ifndef CONFIG_SPL_BUILD
+	pmuclk_init(priv->pmucru);
+#endif
 	return 0;
 }
 
 static int rk3399_pmuclk_ofdata_to_platdata(struct udevice *dev)
 {
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 	struct rk3399_pmuclk_priv *priv = dev_get_priv(dev);
 
 	priv->pmucru = (struct rk3399_pmucru *)dev_get_addr(dev);
-
+#endif
 	return 0;
 }
 
@@ -969,11 +1037,14 @@ static const struct udevice_id rk3399_pmuclk_ids[] = {
 };
 
 U_BOOT_DRIVER(rockchip_rk3399_pmuclk) = {
-	.name		= "pmuclk_rk3399",
+	.name		= "rockchip_rk3399_pmucru",
 	.id		= UCLASS_CLK,
 	.of_match	= rk3399_pmuclk_ids,
 	.priv_auto_alloc_size = sizeof(struct rk3399_pmuclk_priv),
 	.ofdata_to_platdata = rk3399_pmuclk_ofdata_to_platdata,
 	.ops		= &rk3399_pmuclk_ops,
 	.probe		= rk3399_pmuclk_probe,
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	.platdata_auto_alloc_size = sizeof(struct rk3399_pmuclk_plat),
+#endif
 };
diff --git a/include/dt-bindings/clock/rk3399-cru.h b/include/dt-bindings/clock/rk3399-cru.h
index 0a86aec..d4bdcc6 100644
--- a/include/dt-bindings/clock/rk3399-cru.h
+++ b/include/dt-bindings/clock/rk3399-cru.h
@@ -122,6 +122,10 @@
 #define SCLK_DPHY_RX0_CFG		165
 #define SCLK_RMII_SRC			166
 #define SCLK_PCIEPHY_REF100M		167
+#define SCLK_USBPHY0_480M_SRC		168
+#define SCLK_USBPHY1_480M_SRC		169
+#define SCLK_DDRCLK			170
+#define SCLK_TESTOUT2			171
 
 #define DCLK_VOP0			180
 #define DCLK_VOP1			181
@@ -589,13 +593,13 @@
 #define SRST_P_SPI0			214
 #define SRST_P_SPI1			215
 #define SRST_P_SPI2			216
-#define SRST_P_SPI3			217
-#define SRST_P_SPI4			218
+#define SRST_P_SPI4			217
+#define SRST_P_SPI5			218
 #define SRST_SPI0			219
 #define SRST_SPI1			220
 #define SRST_SPI2			221
-#define SRST_SPI3			222
-#define SRST_SPI4			223
+#define SRST_SPI4			222
+#define SRST_SPI5			223
 
 /* cru_softrst_con14 */
 #define SRST_I2S0_8CH			224
@@ -717,8 +721,8 @@
 #define SRST_H_CM0S_NOC			3
 #define SRST_DBG_CM0S			4
 #define SRST_PO_CM0S			5
-#define SRST_P_SPI6			6
-#define SRST_SPI6			7
+#define SRST_P_SPI3			6
+#define SRST_SPI3			7
 #define SRST_P_TIMER_0_1		8
 #define SRST_P_TIMER_0			9
 #define SRST_P_TIMER_1			10
-- 
1.9.1

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

* [U-Boot] [PATCH v2 4/9] sdhci: rk3399: update driver to support of-platdata
  2017-02-13  9:38 [U-Boot] [PATCH v2 0/9] rk3399: enable SPL driver Kever Yang
                   ` (2 preceding siblings ...)
  2017-02-13  9:38 ` [U-Boot] [PATCH v2 3/9] clk: rk3399: update driver for spl Kever Yang
@ 2017-02-13  9:38 ` Kever Yang
  2017-02-21 20:34   ` Simon Glass
  2017-02-13  9:38 ` [U-Boot] [PATCH v2 5/9] pinctrl: rk3399: add the of-platdata support Kever Yang
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Kever Yang @ 2017-02-13  9:38 UTC (permalink / raw)
  To: u-boot

Change some API in order to enable of-platdata.

Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None
Changes in v1: None

 drivers/mmc/rockchip_sdhci.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c
index e33e35e..1ea5db4 100644
--- a/drivers/mmc/rockchip_sdhci.c
+++ b/drivers/mmc/rockchip_sdhci.c
@@ -8,9 +8,11 @@
 
 #include <common.h>
 #include <dm.h>
+#include <dt-structs.h>
 #include <fdtdec.h>
 #include <libfdt.h>
 #include <malloc.h>
+#include <mapmem.h>
 #include <sdhci.h>
 #include <clk.h>
 
@@ -19,6 +21,9 @@ DECLARE_GLOBAL_DATA_PTR;
 #define EMMC_MIN_FREQ	400000
 
 struct rockchip_sdhc_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	struct dtd_rockchip_rk3399_sdhci_5_1 dtplat;
+#endif
 	struct mmc_config cfg;
 	struct mmc mmc;
 };
@@ -37,10 +42,18 @@ static int arasan_sdhci_probe(struct udevice *dev)
 	int max_frequency, ret;
 	struct clk clk;
 
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	struct dtd_rockchip_rk3399_sdhci_5_1 *dtplat = &plat->dtplat;
 
+	host->name = dev->name;
+	host->ioaddr = map_sysmem(dtplat->reg[1], dtplat->reg[3]);
+	max_frequency = dtplat->max_frequency;
+	ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &clk);
+#else
 	max_frequency = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
 			"max-frequency", 0);
 	ret = clk_get_by_index(dev, 0, &clk);
+#endif
 	if (!ret) {
 		ret = clk_set_rate(&clk, max_frequency);
 		if (IS_ERR_VALUE(ret))
@@ -66,10 +79,12 @@ static int arasan_sdhci_probe(struct udevice *dev)
 
 static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
 {
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 	struct sdhci_host *host = dev_get_priv(dev);
 
 	host->name = dev->name;
 	host->ioaddr = dev_get_addr_ptr(dev);
+#endif
 
 	return 0;
 }
@@ -87,7 +102,7 @@ static const struct udevice_id arasan_sdhci_ids[] = {
 };
 
 U_BOOT_DRIVER(arasan_sdhci_drv) = {
-	.name		= "arasan_sdhci",
+	.name		= "rockchip_rk3399_sdhci_5_1",
 	.id		= UCLASS_MMC,
 	.of_match	= arasan_sdhci_ids,
 	.ofdata_to_platdata = arasan_sdhci_ofdata_to_platdata,
-- 
1.9.1

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

* [U-Boot] [PATCH v2 5/9] pinctrl: rk3399: add the of-platdata support
  2017-02-13  9:38 [U-Boot] [PATCH v2 0/9] rk3399: enable SPL driver Kever Yang
                   ` (3 preceding siblings ...)
  2017-02-13  9:38 ` [U-Boot] [PATCH v2 4/9] sdhci: rk3399: update driver to support of-platdata Kever Yang
@ 2017-02-13  9:38 ` Kever Yang
  2017-02-21 20:34   ` Simon Glass
  2017-02-13  9:38 ` [U-Boot] [PATCH v2 6/9] arm64: rk3399: syscon addition for rk3399 Kever Yang
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Kever Yang @ 2017-02-13  9:38 UTC (permalink / raw)
  To: u-boot

Do not use the API which of-platdata not support.

Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None
Changes in v1: None

 drivers/pinctrl/rockchip/pinctrl_rk3399.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3399.c b/drivers/pinctrl/rockchip/pinctrl_rk3399.c
index 2f8aa64..f7417d5 100644
--- a/drivers/pinctrl/rockchip/pinctrl_rk3399.c
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3399.c
@@ -253,6 +253,7 @@ static int rk3399_pinctrl_request(struct udevice *dev, int func, int flags)
 static int rk3399_pinctrl_get_periph_id(struct udevice *dev,
 					struct udevice *periph)
 {
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 	u32 cell[3];
 	int ret;
 
@@ -283,7 +284,7 @@ static int rk3399_pinctrl_get_periph_id(struct udevice *dev,
 	case 65:
 		return PERIPH_ID_SDMMC1;
 	}
-
+#endif
 	return -ENOENT;
 }
 
@@ -328,6 +329,8 @@ U_BOOT_DRIVER(pinctrl_rk3399) = {
 	.of_match	= rk3399_pinctrl_ids,
 	.priv_auto_alloc_size = sizeof(struct rk3399_pinctrl_priv),
 	.ops		= &rk3399_pinctrl_ops,
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 	.bind		= dm_scan_fdt_dev,
+#endif
 	.probe		= rk3399_pinctrl_probe,
 };
-- 
1.9.1

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

* [U-Boot] [PATCH v2 6/9] arm64: rk3399: syscon addition for rk3399
  2017-02-13  9:38 [U-Boot] [PATCH v2 0/9] rk3399: enable SPL driver Kever Yang
                   ` (4 preceding siblings ...)
  2017-02-13  9:38 ` [U-Boot] [PATCH v2 5/9] pinctrl: rk3399: add the of-platdata support Kever Yang
@ 2017-02-13  9:38 ` Kever Yang
  2017-02-16 20:43   ` Simon Glass
  2017-02-21 20:34   ` Simon Glass
  2017-02-13  9:39 ` [U-Boot] [PATCH v2 7/9] dts: rk3399: update for spl require driver Kever Yang
                   ` (3 subsequent siblings)
  9 siblings, 2 replies; 23+ messages in thread
From: Kever Yang @ 2017-02-13  9:38 UTC (permalink / raw)
  To: u-boot

rk3399 has different syscon registers which may used in spl,
add to support rk3399 spl.

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

Changes in v2: None
Changes in v1: None

 arch/arm/include/asm/arch-rockchip/clock.h    |  2 ++
 arch/arm/mach-rockchip/rk3399/syscon_rk3399.c | 40 +++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/arch/arm/include/asm/arch-rockchip/clock.h b/arch/arm/include/asm/arch-rockchip/clock.h
index 6f7e755..b06bb6c 100644
--- a/arch/arm/include/asm/arch-rockchip/clock.h
+++ b/arch/arm/include/asm/arch-rockchip/clock.h
@@ -17,6 +17,8 @@ enum {
 	ROCKCHIP_SYSCON_SGRF,
 	ROCKCHIP_SYSCON_PMU,
 	ROCKCHIP_SYSCON_PMUGRF,
+	ROCKCHIP_SYSCON_PMUSGRF,
+	ROCKCHIP_SYSCON_CIC,
 };
 
 /* Standard Rockchip clock numbers */
diff --git a/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c b/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c
index 2cef68b..d32985b 100644
--- a/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c
+++ b/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c
@@ -12,6 +12,8 @@
 static const struct udevice_id rk3399_syscon_ids[] = {
 	{ .compatible = "rockchip,rk3399-grf", .data = ROCKCHIP_SYSCON_GRF },
 	{ .compatible = "rockchip,rk3399-pmugrf", .data = ROCKCHIP_SYSCON_PMUGRF },
+	{ .compatible = "rockchip,rk3399-pmusgrf", .data = ROCKCHIP_SYSCON_PMUSGRF },
+	{ .compatible = "rockchip,rk3399-cic", .data = ROCKCHIP_SYSCON_CIC },
 };
 
 U_BOOT_DRIVER(syscon_rk3399) = {
@@ -19,3 +21,41 @@ U_BOOT_DRIVER(syscon_rk3399) = {
 	.id = UCLASS_SYSCON,
 	.of_match = rk3399_syscon_ids,
 };
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+static int rk3399_syscon_bind_of_platdata(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_rk3399_grf) = {
+	.name = "rockchip_rk3399_grf",
+	.id = UCLASS_SYSCON,
+	.of_match = rk3399_syscon_ids,
+	.bind = rk3399_syscon_bind_of_platdata,
+};
+
+U_BOOT_DRIVER(rockchip_rk3399_pmugrf) = {
+	.name = "rockchip_rk3399_pmugrf",
+	.id = UCLASS_SYSCON,
+	.of_match = rk3399_syscon_ids + 1,
+	.bind = rk3399_syscon_bind_of_platdata,
+};
+
+U_BOOT_DRIVER(rockchip_rk3399_pmusgrf) = {
+	.name = "rockchip_rk3399_pmusgrf",
+	.id = UCLASS_SYSCON,
+	.of_match = rk3399_syscon_ids + 2,
+	.bind = rk3399_syscon_bind_of_platdata,
+};
+
+U_BOOT_DRIVER(rockchip_rk3399_cic) = {
+	.name = "rockchip_rk3399_cic",
+	.id = UCLASS_SYSCON,
+	.of_match = rk3399_syscon_ids + 3,
+	.bind = rk3399_syscon_bind_of_platdata,
+};
+#endif
-- 
1.9.1

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

* [U-Boot] [PATCH v2 7/9] dts: rk3399: update for spl require driver
  2017-02-13  9:38 [U-Boot] [PATCH v2 0/9] rk3399: enable SPL driver Kever Yang
                   ` (5 preceding siblings ...)
  2017-02-13  9:38 ` [U-Boot] [PATCH v2 6/9] arm64: rk3399: syscon addition for rk3399 Kever Yang
@ 2017-02-13  9:39 ` Kever Yang
  2017-02-16 20:43   ` Simon Glass
  2017-02-13  9:39 ` [U-Boot] [PATCH v2 8/9] arm64: rk3399: add SPL support Kever Yang
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Kever Yang @ 2017-02-13  9:39 UTC (permalink / raw)
  To: u-boot

Add syscon and dmc node, and 'u-boot,dm-pre-reloc' option for
required driver.

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

Changes in v2: None
Changes in v1: None

 arch/arm/dts/rk3399-evb.dts |  2 ++
 arch/arm/dts/rk3399.dtsi    | 44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+)

diff --git a/arch/arm/dts/rk3399-evb.dts b/arch/arm/dts/rk3399-evb.dts
index fa60e19..a959989 100644
--- a/arch/arm/dts/rk3399-evb.dts
+++ b/arch/arm/dts/rk3399-evb.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 #include <dt-bindings/pwm/pwm.h>
 #include "rk3399.dtsi"
+#include "rk3399-sdram-lpddr3-4GB-1600.dtsi"
 
 / {
 	model = "Rockchip RK3399 Evaluation Board";
@@ -69,6 +70,7 @@
 };
 
 &sdmmc {
+	bus-width = <4>;
 	status = "okay";
 };
 
diff --git a/arch/arm/dts/rk3399.dtsi b/arch/arm/dts/rk3399.dtsi
index 22277ff..379e04b 100644
--- a/arch/arm/dts/rk3399.dtsi
+++ b/arch/arm/dts/rk3399.dtsi
@@ -183,6 +183,7 @@
 	};
 
 	sdhci: sdhci at fe330000 {
+		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-sdhci-5.1", "arasan,sdhci-5.1";
 		reg = <0x0 0xfe330000 0x0 0x10000>;
 		interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
@@ -416,6 +417,7 @@
 	};
 
 	pmugrf: syscon at ff320000 {
+		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-pmugrf", "syscon", "simple-mfd";
 		reg = <0x0 0xff320000 0x0 0x1000>;
 		#address-cells = <1>;
@@ -427,6 +429,12 @@
 		};
 	};
 
+	pmusgrf: syscon at ff330000 {
+		u-boot,dm-pre-reloc;
+		compatible = "rockchip,rk3399-pmusgrf", "syscon";
+		reg = <0x0 0xff330000 0x0 0xe3d4>;
+	};
+
 	spi3: spi at ff350000 {
 		compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi";
 		reg = <0x0 0xff350000 0x0 0x1000>;
@@ -497,7 +505,40 @@
 		status = "disabled";
 	};
 
+	cic: syscon at ff620000 {
+		u-boot,dm-pre-reloc;
+		compatible = "rockchip,rk3399-cic", "syscon";
+		reg = <0x0 0xff620000 0x0 0x100>;
+	};
+
+	dfi: dfi at ff630000 {
+		reg = <0x00 0xff630000 0x00 0x4000>;
+		compatible = "rockchip,rk3399-dfi";
+		rockchip,pmu = <&pmugrf>;
+		clocks = <&cru PCLK_DDR_MON>;
+		clock-names = "pclk_ddr_mon";
+		status = "disabled";
+	};
+
+	dmc: dmc {
+		u-boot,dm-pre-reloc;
+		compatible = "rockchip,rk3399-dmc";
+		devfreq-events = <&dfi>;
+		interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru SCLK_DDRCLK>;
+		clock-names = "dmc_clk";
+		reg = <0x0 0xffa80000 0x0 0x0800
+		       0x0 0xffa80800 0x0 0x1800
+		       0x0 0xffa82000 0x0 0x2000
+		       0x0 0xffa84000 0x0 0x1000
+		       0x0 0xffa88000 0x0 0x0800
+		       0x0 0xffa88800 0x0 0x1800
+		       0x0 0xffa8a000 0x0 0x2000
+		       0x0 0xffa8c000 0x0 0x1000>;
+	};
+
 	pmucru: pmu-clock-controller at ff750000 {
+		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-pmucru";
 		reg = <0x0 0xff750000 0x0 0x1000>;
 		#clock-cells = <1>;
@@ -507,6 +548,7 @@
 	};
 
 	cru: clock-controller at ff760000 {
+		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-cru";
 		reg = <0x0 0xff760000 0x0 0x1000>;
 		#clock-cells = <1>;
@@ -530,6 +572,7 @@
 	};
 
 	grf: syscon at ff770000 {
+		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-grf", "syscon", "simple-mfd";
 		reg = <0x0 0xff770000 0x0 0x10000>;
 		#address-cells = <1>;
@@ -607,6 +650,7 @@
 	};
 
 	pinctrl: pinctrl {
+		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-pinctrl";
 		rockchip,grf = <&grf>;
 		rockchip,pmu = <&pmugrf>;
-- 
1.9.1

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

* [U-Boot] [PATCH v2 8/9] arm64: rk3399: add SPL support
  2017-02-13  9:38 [U-Boot] [PATCH v2 0/9] rk3399: enable SPL driver Kever Yang
                   ` (6 preceding siblings ...)
  2017-02-13  9:39 ` [U-Boot] [PATCH v2 7/9] dts: rk3399: update for spl require driver Kever Yang
@ 2017-02-13  9:39 ` Kever Yang
  2017-02-16 20:43   ` Simon Glass
  2017-02-23  4:16   ` Simon Glass
  2017-02-13  9:39 ` [U-Boot] [PATCH v2 9/9] config: rk3399: enable SPL config for evb-rk3399 Kever Yang
  2017-02-16 20:43 ` [U-Boot] [PATCH v2 0/9] rk3399: enable SPL driver Simon Glass
  9 siblings, 2 replies; 23+ messages in thread
From: Kever Yang @ 2017-02-13  9:39 UTC (permalink / raw)
  To: u-boot

Add SPL support for rk3399, default with of-platdata enabled.

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

Changes in v2:
- split SPL patch into 4 patches

Changes in v1: None

 arch/arm/Kconfig                          |   1 +
 arch/arm/mach-rockchip/Kconfig            |   2 +
 arch/arm/mach-rockchip/Makefile           |   1 +
 arch/arm/mach-rockchip/rk3399-board-spl.c | 158 ++++++++++++++++++++++++++++++
 include/configs/rk3399_common.h           |   6 ++
 5 files changed, 168 insertions(+)
 create mode 100644 arch/arm/mach-rockchip/rk3399-board-spl.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index d871a45..9a0efe4 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -882,6 +882,7 @@ config ARCH_ROCKCHIP
 	select DM
 	select SPL_DM if SPL
 	select SYS_MALLOC_F
+	select SPL_SEPARATE_BSS if SPL
 	select SPL_SYS_MALLOC_SIMPLE if SPL
 	select DM_GPIO
 	select DM_I2C
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 5c4a4c2..cd8fef8 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -26,6 +26,8 @@ config ROCKCHIP_RK3288
 config ROCKCHIP_RK3399
 	bool "Support Rockchip RK3399"
 	select ARM64
+	select SUPPORT_SPL
+	select SPL
 	help
 	  The Rockchip RK3399 is a ARM-based SoC with a dual-core Cortex-A72
 	  and quad-core Cortex-A53.
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 6e79fed..b58c02d 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -7,6 +7,7 @@
 ifdef CONFIG_SPL_BUILD
 obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board-spl.o
 obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-spl.o
+obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399-board-spl.o
 obj-$(CONFIG_ROCKCHIP_SPL_BACK_TO_BROM) += save_boot_param.o
 else
 obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board.o
diff --git a/arch/arm/mach-rockchip/rk3399-board-spl.c b/arch/arm/mach-rockchip/rk3399-board-spl.c
new file mode 100644
index 0000000..8ae3055
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3399-board-spl.c
@@ -0,0 +1,158 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <led.h>
+#include <malloc.h>
+#include <ram.h>
+#include <spl.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/periph.h>
+#include <asm/arch/sdram.h>
+#include <asm/arch/timer.h>
+#include <dm/pinctrl.h>
+#include <dm/root.h>
+#include <dm/test.h>
+#include <dm/util.h>
+#include <power/regulator.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+u32 spl_boot_device(void)
+{
+	return BOOT_DEVICE_MMC1;
+}
+
+u32 spl_boot_mode(const u32 boot_device)
+{
+	return MMCSD_MODE_RAW;
+}
+
+#define TIMER_CHN10_BASE	0xff8680a0
+#define TIMER_END_COUNT_L	0x00
+#define TIMER_END_COUNT_H	0x04
+#define TIMER_INIT_COUNT_L	0x10
+#define TIMER_INIT_COUNT_H	0x14
+#define TIMER_CONTROL_REG	0x1c
+
+#define TIMER_EN	0x1
+#define	TIMER_FMODE	(0 << 1)
+#define	TIMER_RMODE	(1 << 1)
+
+void secure_timer_init(void)
+{
+	writel(0xffffffff, TIMER_CHN10_BASE + TIMER_END_COUNT_L);
+	writel(0xffffffff, TIMER_CHN10_BASE + TIMER_END_COUNT_H);
+	writel(0, TIMER_CHN10_BASE + TIMER_INIT_COUNT_L);
+	writel(0, TIMER_CHN10_BASE + TIMER_INIT_COUNT_H);
+	writel(TIMER_EN | TIMER_FMODE, TIMER_CHN10_BASE + TIMER_CONTROL_REG);
+}
+
+#define GRF_EMMCCORE_CON11 0xff77f02c
+void board_init_f(ulong dummy)
+{
+	struct udevice *pinctrl;
+	struct udevice *dev;
+	int ret;
+
+	/* Example code showing how to enable the debug UART on RK3288 */
+#include <asm/arch/grf_rk3399.h>
+	/* Enable early UART2 channel C on the RK3399 */
+#define GRF_BASE	0xff770000
+	struct rk3399_grf_regs * const grf = (void *)GRF_BASE;
+
+	rk_clrsetreg(&grf->gpio4c_iomux,
+		     GRF_GPIO4C3_SEL_MASK,
+		     GRF_UART2DGBC_SIN << GRF_GPIO4C3_SEL_SHIFT);
+	rk_clrsetreg(&grf->gpio4c_iomux,
+		     GRF_GPIO4C4_SEL_MASK,
+		     GRF_UART2DBGC_SOUT << GRF_GPIO4C4_SEL_SHIFT);
+	/* Set channel C as UART2 input */
+	rk_clrsetreg(&grf->soc_con7,
+		     GRF_UART_DBG_SEL_MASK,
+		     GRF_UART_DBG_SEL_C << GRF_UART_DBG_SEL_SHIFT);
+#define EARLY_UART
+#ifdef EARLY_UART
+	/*
+	 * Debug UART can be used from here if required:
+	 *
+	 * debug_uart_init();
+	 * printch('a');
+	 * printhex8(0x1234);
+	 * printascii("string");
+	 */
+	debug_uart_init();
+	printascii("U-Boot SPL board init");
+#endif
+	/*  Emmc clock generator: disable the clock multipilier */
+	rk_clrreg(GRF_EMMCCORE_CON11, 0x0ff);
+
+	ret = spl_init();
+	if (ret) {
+		debug("spl_init() failed: %d\n", ret);
+		hang();
+	}
+
+	secure_timer_init();
+
+	ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
+	if (ret) {
+		debug("Pinctrl init failed: %d\n", ret);
+		return;
+	}
+
+	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+	if (ret) {
+		debug("DRAM init failed: %d\n", ret);
+		return;
+	}
+}
+
+void spl_board_init(void)
+{
+	struct udevice *pinctrl;
+	int ret;
+
+	ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
+	if (ret) {
+		debug("%s: Cannot find pinctrl device\n", __func__);
+		goto err;
+	}
+
+	/* Enable debug UART */
+	ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_UART_DBG);
+	if (ret) {
+		debug("%s: Failed to set up console UART\n", __func__);
+		goto err;
+	}
+
+	preloader_console_init();
+#ifdef CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
+	back_to_bootrom();
+#endif
+	return;
+err:
+	printf("spl_board_init: Error %d\n", ret);
+
+	/* No way to report error here */
+	hang();
+}
+
+#ifdef CONFIG_SPL_LOAD_FIT
+int board_fit_config_name_match(const char *name)
+{
+	/* Just empty function now - can't decide what to choose */
+	debug("%s: %s\n", __func__, name);
+
+	return 0;
+}
+#endif
diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h
index aa646c6..66b4fbc 100644
--- a/include/configs/rk3399_common.h
+++ b/include/configs/rk3399_common.h
@@ -23,6 +23,12 @@
 #define CONFIG_SYS_TEXT_BASE		0x00200000
 #define CONFIG_SYS_INIT_SP_ADDR		0x00300000
 #define CONFIG_SYS_LOAD_ADDR		0x00800800
+#define CONFIG_SPL_STACK		0xff8effff
+#define CONFIG_SPL_TEXT_BASE		0xff8c2008
+#define CONFIG_SPL_MAX_SIZE		0x30000
+/*  BSS setup */
+#define CONFIG_SPL_BSS_START_ADDR       0xff8e0000
+#define CONFIG_SPL_BSS_MAX_SIZE         0x10000
 
 #define CONFIG_SYS_BOOTM_LEN	(64 << 20)	/* 64M */
 
-- 
1.9.1

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

* [U-Boot] [PATCH v2 9/9] config: rk3399: enable SPL config for evb-rk3399
  2017-02-13  9:38 [U-Boot] [PATCH v2 0/9] rk3399: enable SPL driver Kever Yang
                   ` (7 preceding siblings ...)
  2017-02-13  9:39 ` [U-Boot] [PATCH v2 8/9] arm64: rk3399: add SPL support Kever Yang
@ 2017-02-13  9:39 ` Kever Yang
  2017-02-16 20:43   ` Simon Glass
  2017-02-16 20:43 ` [U-Boot] [PATCH v2 0/9] rk3399: enable SPL driver Simon Glass
  9 siblings, 1 reply; 23+ messages in thread
From: Kever Yang @ 2017-02-13  9:39 UTC (permalink / raw)
  To: u-boot

Enable all the CONFIGs which need by SPL.

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

Changes in v2: None
Changes in v1: None

 configs/evb-rk3399_defconfig    | 18 ++++++++++++++++++
 include/configs/rk3399_common.h |  5 +++++
 2 files changed, 23 insertions(+)

diff --git a/configs/evb-rk3399_defconfig b/configs/evb-rk3399_defconfig
index 40a8295..abfabc5 100644
--- a/configs/evb-rk3399_defconfig
+++ b/configs/evb-rk3399_defconfig
@@ -3,7 +3,16 @@ CONFIG_ARCH_ROCKCHIP=y
 CONFIG_ROCKCHIP_RK3399=y
 CONFIG_DEFAULT_DEVICE_TREE="rk3399-evb"
 CONFIG_FIT=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_OF_LIBFDT=y
+CONFIG_SPL_ATF_SUPPORT=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x200
+CONFIG_SPL_ATF_TEXT_BASE=0x00010000
 # CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_STACK_R_ADDR=0x80000
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x4000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
 CONFIG_HUSH_PARSER=y
 CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMLS is not set
@@ -16,18 +25,27 @@ CONFIG_CMD_EXT2=y
 CONFIG_CMD_EXT4=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+CONFIG_CMD_PXE=y
+CONFIG_SPL_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_SPL_OF_PLATDATA=y
 CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
 CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
 CONFIG_CLK=y
+CONFIG_SPL_CLK=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_ROCKCHIP_DWMMC=y
 CONFIG_ROCKCHIP_SDHCI=y
 CONFIG_PINCTRL=y
+CONFIG_SPL_PINCTRL=y
 CONFIG_ROCKCHIP_RK3399_PINCTRL=y
 CONFIG_PWM_ROCKCHIP=y
 CONFIG_REGULATOR_PWM=y
 CONFIG_DM_REGULATOR_FIXED=y
 CONFIG_RAM=y
+CONFIG_SPL_RAM=y
 CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART_BASE=0xFF1A0000
 CONFIG_DEBUG_UART_CLOCK=24000000
diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h
index 66b4fbc..3699a9d 100644
--- a/include/configs/rk3399_common.h
+++ b/include/configs/rk3399_common.h
@@ -17,6 +17,11 @@
 #define CONFIG_SYS_MALLOC_LEN		(32 << 20)
 #define CONFIG_SYS_CBSIZE		1024
 #define CONFIG_SKIP_LOWLEVEL_INIT
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_DRIVERS_MISC_SUPPORT
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
 
 #define CONFIG_SYS_NS16550_MEM32
 
-- 
1.9.1

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

* [U-Boot] [PATCH v2 6/9] arm64: rk3399: syscon addition for rk3399
  2017-02-13  9:38 ` [U-Boot] [PATCH v2 6/9] arm64: rk3399: syscon addition for rk3399 Kever Yang
@ 2017-02-16 20:43   ` Simon Glass
  2017-02-21 20:34   ` Simon Glass
  1 sibling, 0 replies; 23+ messages in thread
From: Simon Glass @ 2017-02-16 20:43 UTC (permalink / raw)
  To: u-boot

On 13 February 2017 at 02:38, Kever Yang <kever.yang@rock-chips.com> wrote:
> rk3399 has different syscon registers which may used in spl,
> add to support rk3399 spl.
>
> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
> ---
>
> Changes in v2: None
> Changes in v1: None
>
>  arch/arm/include/asm/arch-rockchip/clock.h    |  2 ++
>  arch/arm/mach-rockchip/rk3399/syscon_rk3399.c | 40 +++++++++++++++++++++++++++
>  2 files changed, 42 insertions(+)

Reviewed-by: Simon Glass <sjg@chromium.org>

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

* [U-Boot] [PATCH v2 7/9] dts: rk3399: update for spl require driver
  2017-02-13  9:39 ` [U-Boot] [PATCH v2 7/9] dts: rk3399: update for spl require driver Kever Yang
@ 2017-02-16 20:43   ` Simon Glass
  0 siblings, 0 replies; 23+ messages in thread
From: Simon Glass @ 2017-02-16 20:43 UTC (permalink / raw)
  To: u-boot

On 13 February 2017 at 02:39, Kever Yang <kever.yang@rock-chips.com> wrote:
> Add syscon and dmc node, and 'u-boot,dm-pre-reloc' option for
> required driver.
>
> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
> ---
>
> Changes in v2: None
> Changes in v1: None
>
>  arch/arm/dts/rk3399-evb.dts |  2 ++
>  arch/arm/dts/rk3399.dtsi    | 44 ++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 46 insertions(+)

Reviewed-by: Simon Glass <sjg@chromium.org>

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

* [U-Boot] [PATCH v2 8/9] arm64: rk3399: add SPL support
  2017-02-13  9:39 ` [U-Boot] [PATCH v2 8/9] arm64: rk3399: add SPL support Kever Yang
@ 2017-02-16 20:43   ` Simon Glass
  2017-02-23  4:16   ` Simon Glass
  1 sibling, 0 replies; 23+ messages in thread
From: Simon Glass @ 2017-02-16 20:43 UTC (permalink / raw)
  To: u-boot

On 13 February 2017 at 02:39, Kever Yang <kever.yang@rock-chips.com> wrote:
> Add SPL support for rk3399, default with of-platdata enabled.
>
> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
> ---
>
> Changes in v2:
> - split SPL patch into 4 patches
>
> Changes in v1: None
>
>  arch/arm/Kconfig                          |   1 +
>  arch/arm/mach-rockchip/Kconfig            |   2 +
>  arch/arm/mach-rockchip/Makefile           |   1 +
>  arch/arm/mach-rockchip/rk3399-board-spl.c | 158 ++++++++++++++++++++++++++++++
>  include/configs/rk3399_common.h           |   6 ++
>  5 files changed, 168 insertions(+)
>  create mode 100644 arch/arm/mach-rockchip/rk3399-board-spl.c

Reviewed-by: Simon Glass <sjg@chromium.org>

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

* [U-Boot] [PATCH v2 9/9] config: rk3399: enable SPL config for evb-rk3399
  2017-02-13  9:39 ` [U-Boot] [PATCH v2 9/9] config: rk3399: enable SPL config for evb-rk3399 Kever Yang
@ 2017-02-16 20:43   ` Simon Glass
  0 siblings, 0 replies; 23+ messages in thread
From: Simon Glass @ 2017-02-16 20:43 UTC (permalink / raw)
  To: u-boot

On 13 February 2017 at 02:39, Kever Yang <kever.yang@rock-chips.com> wrote:
> Enable all the CONFIGs which need by SPL.
>
> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
> ---
>
> Changes in v2: None
> Changes in v1: None
>
>  configs/evb-rk3399_defconfig    | 18 ++++++++++++++++++
>  include/configs/rk3399_common.h |  5 +++++
>  2 files changed, 23 insertions(+)

Reviewed-by: Simon Glass <sjg@chromium.org>

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

* [U-Boot] [PATCH v2 0/9] rk3399: enable SPL driver
  2017-02-13  9:38 [U-Boot] [PATCH v2 0/9] rk3399: enable SPL driver Kever Yang
                   ` (8 preceding siblings ...)
  2017-02-13  9:39 ` [U-Boot] [PATCH v2 9/9] config: rk3399: enable SPL config for evb-rk3399 Kever Yang
@ 2017-02-16 20:43 ` Simon Glass
  9 siblings, 0 replies; 23+ messages in thread
From: Simon Glass @ 2017-02-16 20:43 UTC (permalink / raw)
  To: u-boot

Hi Kever,

On 13 February 2017 at 02:38, Kever Yang <kever.yang@rock-chips.com> wrote:
>
> This series patch enable basic driver for rk3399 SPL, the ATF support
> has been split as a separate patch.
>
> SPL_OF_PLATDATA is consider to be must because the dram driver has much
> configuration parameter from dts, but we don't want to do the copy.

I still don't think we should be using it on devices which don't need it.

For the copy I think you are referring to fdtdec_get_int_array(). I
showed you some code that avoids copying and I suspect is just as fast
as what you have.

Anyway let's compare the two options when you have them.

>
> Other driver like clock, pinctrl, sdhci has update to support
> OF-PLATDATA.
>
>
> Changes in v2:
> - use lower-case hex for input dts data
> - using rk3288 like style to encode/decode sys_reg
> - gather some parameters as base params in rk3399_sdram_params
> - add some missing comment
> - split SPL patch into 4 patches
>
> Changes in v1:
> - use dts for parameter
> - get all controller base address from dts instead of hard code
> - gather all controller into dram_info instead of separate global
>   variables.
> - add return value for error case
>
> Kever Yang (9):
>   arm64: rk3399: add ddr controller driver
>   arm64: rk3399: move grf register definitions to grf_rk3399.h
>   clk: rk3399: update driver for spl
>   sdhci: rk3399: update driver to support of-platdata
>   pinctrl: rk3399: add the of-platdata support
>   arm64: rk3399: syscon addition for rk3399
>   dts: rk3399: update for spl require driver
>   arm64: rk3399: add SPL support
>   config: rk3399: enable SPL config for evb-rk3399
>
>  arch/arm/Kconfig                                  |    1 +
>  arch/arm/dts/rk3399-evb.dts                       |    2 +
>  arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi    | 1536 +++++++++++++++++++++
>  arch/arm/dts/rk3399.dtsi                          |   44 +
>  arch/arm/include/asm/arch-rockchip/clock.h        |    9 +
>  arch/arm/include/asm/arch-rockchip/cru_rk3399.h   |    5 +
>  arch/arm/include/asm/arch-rockchip/grf_rk3399.h   |  118 ++
>  arch/arm/include/asm/arch-rockchip/sdram_rk3399.h |  124 ++
>  arch/arm/mach-rockchip/Kconfig                    |    2 +
>  arch/arm/mach-rockchip/Makefile                   |    1 +
>  arch/arm/mach-rockchip/rk3399-board-spl.c         |  158 +++
>  arch/arm/mach-rockchip/rk3399/Makefile            |    1 +
>  arch/arm/mach-rockchip/rk3399/clk_rk3399.c        |   21 +
>  arch/arm/mach-rockchip/rk3399/sdram_rk3399.c      | 1259 +++++++++++++++++
>  arch/arm/mach-rockchip/rk3399/syscon_rk3399.c     |   40 +
>  configs/evb-rk3399_defconfig                      |   18 +
>  drivers/clk/rockchip/clk_rk3399.c                 |   89 +-
>  drivers/mmc/rockchip_sdhci.c                      |   17 +-
>  drivers/pinctrl/rockchip/pinctrl_rk3399.c         |  111 +-
>  include/configs/rk3399_common.h                   |   11 +
>  include/dt-bindings/clock/rk3399-cru.h            |   16 +-
>  21 files changed, 3460 insertions(+), 123 deletions(-)
>  create mode 100644 arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
>  create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
>  create mode 100644 arch/arm/mach-rockchip/rk3399-board-spl.c
>  create mode 100644 arch/arm/mach-rockchip/rk3399/sdram_rk3399.c
>
> --
> 1.9.1
>

Regards,
Simon

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

* [U-Boot] [PATCH v2 1/9] arm64: rk3399: add ddr controller driver
  2017-02-13  9:38 ` [U-Boot] [PATCH v2 1/9] arm64: rk3399: add ddr controller driver Kever Yang
@ 2017-02-16 20:43   ` Simon Glass
  0 siblings, 0 replies; 23+ messages in thread
From: Simon Glass @ 2017-02-16 20:43 UTC (permalink / raw)
  To: u-boot

Hi Kever,

On 13 February 2017 at 02:38, Kever Yang <kever.yang@rock-chips.com> wrote:
> RK3399 support DDR3, LPDDR3, DDR4 sdram, this patch is porting from
> coreboot, support 4GB lpddr3 in this version.
>
> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
> ---
>
> Changes in v2:
> - use lower-case hex for input dts data
> - using rk3288 like style to encode/decode sys_reg
> - gather some parameters as base params in rk3399_sdram_params
> - add some missing comment
>
> Changes in v1:
> - use dts for parameter
> - get all controller base address from dts instead of hard code
> - gather all controller into dram_info instead of separate global
>   variables.
> - add return value for error case
>
>  arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi    | 1536 +++++++++++++++++++++
>  arch/arm/include/asm/arch-rockchip/sdram_rk3399.h |  124 ++
>  arch/arm/mach-rockchip/rk3399/Makefile            |    1 +
>  arch/arm/mach-rockchip/rk3399/sdram_rk3399.c      | 1259 +++++++++++++++++
>  4 files changed, 2920 insertions(+)
>  create mode 100644 arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
>  create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
>  create mode 100644 arch/arm/mach-rockchip/rk3399/sdram_rk3399.c

Looks good, one more thing to do, plus some nits below.

>
> diff --git a/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi b/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
> new file mode 100644
> index 0000000..65dfc38
> --- /dev/null
> +++ b/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
> @@ -0,0 +1,1536 @@
> +/*
> + * (C) Copyright 2016 Rockchip Electronics Co., Ltd
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +&dmc {
> +       rockchip,sdram-params = <
> +               0x2
> +               0xa
> +               0x3

[...]

> +       >;
> +}

Please can you add a binding file with the meaning of this, like
doc/device-tree-bindings/clock/rockchip,rk3288-dmc.txt:.

;
> diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h b/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
> new file mode 100644
> index 0000000..0b7cb1f
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
> @@ -0,0 +1,124 @@
> +/*
> + * Copyright (C) 2015 Rockchip Electronics Co., Ltd

Is 2015 correct?

> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#ifndef _ASM_ARCH_SDRAM_RK3399_H
> +#define _ASM_ARCH_SDRAM_RK3399_H
> +
> +enum {
> +       DDR3 = 0x3,
> +       LPDDR2 = 0x5,
> +       LPDDR3 = 0x6,
> +       LPDDR4 = 0x7,
> +       UNUSED = 0xFF
> +};
> +
> +struct rk3399_ddr_pctl_regs {
> +       u32 denali_ctl[332];
> +};
> +
> +struct rk3399_ddr_publ_regs {
> +       u32 denali_phy[959];
> +};
> +
> +struct rk3399_ddr_pi_regs {
> +       u32 denali_pi[200];
> +};
> +
> +struct rk3399_msch_regs {
> +       u32 coreid;
> +       u32 revisionid;
> +       u32 ddrconf;
> +       u32 ddrsize;
> +       u32 ddrtiminga0;
> +       u32 ddrtimingb0;
> +       u32 ddrtimingc0;
> +       u32 devtodev0;
> +       u32 reserved0[(0x110 - 0x20) / 4];
> +       u32 ddrmode;
> +       u32 reserved1[(0x1000 - 0x114) / 4];
> +       u32 agingx0;
> +};
> +
> +struct rk3399_msch_timings {
> +       u32 ddrtiminga0;
> +       u32 ddrtimingb0;
> +       u32 ddrtimingc0;
> +       u32 devtodev0;
> +       u32 ddrmode;
> +       u32 agingx0;
> +};
> +
> +struct rk3399_ddr_cic_regs {
> +       u32 cic_ctrl0;
> +       u32 cic_ctrl1;
> +       u32 cic_idle_th;
> +       u32 cic_cg_wait_th;
> +       u32 cic_status0;
> +       u32 cic_status1;
> +       u32 cic_ctrl2;
> +       u32 cic_ctrl3;
> +       u32 cic_ctrl4;
> +};
> +
> +/* DENALI_CTL_00 */
> +#define START          1
> +
> +/* DENALI_CTL_68 */
> +#define PWRUP_SREFRESH_EXIT    (1 << 16)
> +
> +/* DENALI_CTL_274 */
> +#define MEM_RST_VALID  1
> +
> +struct rk3399_sdram_channel {
> +       unsigned int rank;
> +       /* dram column number, 0 means this channel is invalid */
> +       unsigned int col;
> +       /* dram bank number, 3:8bank, 2:4bank */
> +       unsigned int bk;
> +       /* channel buswidth, 2:32bit, 1:16bit, 0:8bit */
> +       unsigned int bw;
> +       /* die buswidth, 2:32bit, 1:16bit, 0:8bit */
> +       unsigned int dbw;
> +       /*
> +        * row_3_4 = 1: 6Gb or 12Gb die
> +        * row_3_4 = 0: normal die, power of 2
> +        */
> +       unsigned int row_3_4;
> +       unsigned int cs0_row;
> +       unsigned int cs1_row;
> +       unsigned int ddrconfig;
> +       struct rk3399_msch_timings noc_timings;
> +};
> +
> +struct rk3399_base_params {
> +       unsigned int ddr_freq;
> +       unsigned int dramtype;
> +       unsigned int num_channels;
> +       unsigned int stride;
> +       unsigned int odt;
> +};
> +
> +struct rk3399_sdram_params {
> +       struct rk3399_sdram_channel ch[2];
> +       struct rk3399_base_params base;
> +       /* align 8 byte */
> +       struct rk3399_ddr_pctl_regs pctl_regs;
> +       /* align 8 byte */
> +       struct rk3399_ddr_pi_regs pi_regs;
> +       /* align 8 byte */
> +       struct rk3399_ddr_publ_regs phy_regs;
> +       /* used for align 8byte for next struct */
> +       unsigned int align_8;
> +};
> +
> +#define PI_CA_TRAINING (1 << 0)
> +#define PI_WRITE_LEVELING      (1 << 1)
> +#define PI_READ_GATE_TRAINING  (1 << 2)
> +#define PI_READ_LEVELING       (1 << 3)
> +#define PI_WDQ_LEVELING        (1 << 4)
> +#define PI_FULL_TRAINING       (0xff)

No brackets on this last one. Also can you line these values up with tabs?

> +
> +#endif
> diff --git a/arch/arm/mach-rockchip/rk3399/Makefile b/arch/arm/mach-rockchip/rk3399/Makefile
> index 98ebeac..437d851 100644
> --- a/arch/arm/mach-rockchip/rk3399/Makefile
> +++ b/arch/arm/mach-rockchip/rk3399/Makefile
> @@ -7,3 +7,4 @@
>  obj-y += clk_rk3399.o
>  obj-y += rk3399.o
>  obj-y += syscon_rk3399.o
> +obj-y += sdram_rk3399.o

Should move up one line to preserve order.

> diff --git a/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c b/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c
> new file mode 100644
> index 0000000..3989f67
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c
> @@ -0,0 +1,1259 @@
> +/*
> + * (C) Copyright 2016 Rockchip Inc.
> + *
> + * SPDX-License-Identifier:     GPL-2.0
> + *
> + * Adapted from coreboot.
> + */
> +#include <common.h>
> +#include <clk.h>
> +#include <dm.h>
> +#include <dt-structs.h>
> +#include <ram.h>
> +#include <regmap.h>
> +#include <syscon.h>
> +#include <asm/io.h>
> +#include <asm/arch/clock.h>
> +#include <asm/arch/sdram_rk3399.h>
> +#include <asm/arch/cru_rk3399.h>
> +#include <asm/arch/grf_rk3399.h>
> +#include <asm/arch/hardware.h>
> +#include <linux/err.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +struct chan_info {
> +       struct rk3399_ddr_pctl_regs *pctl;
> +       struct rk3399_ddr_pi_regs *pi;
> +       struct rk3399_ddr_publ_regs *publ;
> +       struct rk3399_msch_regs *msch;
> +};
> +
> +struct dram_info {
> +#ifdef CONFIG_SPL_BUILD
> +       struct chan_info chan[2];
> +       struct clk ddr_clk;
> +       struct rk3399_cru *cru;
> +       struct rk3399_pmucru *pmucru;
> +       struct rk3399_pmusgrf_regs *pmusgrf;
> +       struct rk3399_ddr_cic_regs *cic;
> +#endif
> +       struct ram_info info;
> +       struct rk3399_pmugrf_regs *pmugrf;
> +};
> +
> +/*
> + * sys_reg bitfield struct
> + * [31]                row_3_4_ch1
> + * [30]                row_3_4_ch0
> + * [29:28]     chinfo
> + * [27]                rank_ch1
> + * [26:25]     col_ch1
> + * [24]                bk_ch1
> + * [23:22]     cs0_row_ch1
> + * [21:20]     cs1_row_ch1
> + * [19:18]     bw_ch1
> + * [17:16]     dbw_ch1;
> + * [15:13]     ddrtype
> + * [12]                channelnum
> + * [11]                rank_ch0
> + * [10:9]      col_ch0
> + * [8]         bk_ch0
> + * [7:6]       cs0_row_ch0
> + * [5:4]       cs1_row_ch0
> + * [3:2]       bw_ch0
> + * [1:0]       dbw_ch0
> +*/
> +#define SYS_REG_DDRTYPE_SHIFT          13
> +#define SYS_REG_DDRTYPE_MASK           7
> +#define SYS_REG_NUM_CH_SHIFT           12
> +#define SYS_REG_NUM_CH_MASK            1
> +#define SYS_REG_ROW_3_4_SHIFT(ch)      (30 + (ch))
> +#define SYS_REG_ROW_3_4_MASK           1
> +#define SYS_REG_CHINFO_SHIFT(ch)       (28 + (ch))
> +#define SYS_REG_RANK_SHIFT(ch)         (11 + (ch) * 16)
> +#define SYS_REG_RANK_MASK              1
> +#define SYS_REG_COL_SHIFT(ch)          (9 + (ch) * 16)
> +#define SYS_REG_COL_MASK               3
> +#define SYS_REG_BK_SHIFT(ch)           (8 + (ch) * 16)
> +#define SYS_REG_BK_MASK                        1
> +#define SYS_REG_CS0_ROW_SHIFT(ch)      (6 + (ch) * 16)
> +#define SYS_REG_CS0_ROW_MASK           3
> +#define SYS_REG_CS1_ROW_SHIFT(ch)      (4 + (ch) * 16)
> +#define SYS_REG_CS1_ROW_MASK           3
> +#define SYS_REG_BW_SHIFT(ch)           (2 + (ch) * 16)
> +#define SYS_REG_BW_MASK                        3
> +#define SYS_REG_DBW_SHIFT(ch)          ((ch) * 16)
> +#define SYS_REG_DBW_MASK               3
> +
> +
> +

Drop two extra blank lines

> +#define PRESET_SGRF_HOLD(n)    ((0x1 << (6+16)) | ((n) << 6))
> +#define PRESET_GPIO0_HOLD(n)   ((0x1 << (7+16)) | ((n) << 7))
> +#define PRESET_GPIO1_HOLD(n)   ((0x1 << (8+16)) | ((n) << 8))

Spaces around the + in those three.

[..]

> +static int phy_io_config(const struct chan_info *chan,
> +                         const struct rk3399_sdram_params *sdram_params)
> +{
> +       u32 *denali_phy = chan->publ->denali_phy;
> +       u32 vref_mode_dq, vref_value_dq, vref_mode_ac, vref_value_ac;
> +       u32 mode_sel;
> +       u32 reg_value;
> +       u32 drv_value, odt_value;
> +       u32 speed;
> +
> +       /* vref setting */
> +       if (sdram_params->base.dramtype == LPDDR4) {
> +               /* LPDDR4 */
> +               vref_mode_dq = 0x6;
> +               vref_value_dq = 0x1f;
> +               vref_mode_ac = 0x6;
> +               vref_value_ac = 0x1f;
> +       } else if (sdram_params->base.dramtype == LPDDR3) {
> +               if (sdram_params->base.odt == 1) {
> +                       vref_mode_dq = 0x5;  /* LPDDR3 ODT */
> +                       drv_value = (readl(&denali_phy[6]) >> 12) & 0xf;
> +                       odt_value = (readl(&denali_phy[6]) >> 4) & 0xf;
> +                       if (drv_value == PHY_DRV_ODT_48) {
> +                               switch (odt_value) {
> +                               case PHY_DRV_ODT_240:
> +                                       vref_value_dq = 0x16;
> +                                       break;
> +                               case PHY_DRV_ODT_120:
> +                                       vref_value_dq = 0x26;
> +                                       break;
> +                               case PHY_DRV_ODT_60:
> +                                       vref_value_dq = 0x36;
> +                                       break;
> +                               default:
> +                                       debug("Halting: Invalid ODT value.\n");

You probably shouldn't have 'Halting' here. This function is reporting
the error, but it its caller that halts. Up to you though.

> +                                       return -EINVAL;
> +                               }
> +                       } else if (drv_value == PHY_DRV_ODT_40) {
> +                               switch (odt_value) {
> +                               case PHY_DRV_ODT_240:
> +                                       vref_value_dq = 0x19;
> +                                       break;
> +                               case PHY_DRV_ODT_120:
> +                                       vref_value_dq = 0x23;
> +                                       break;
> +                               case PHY_DRV_ODT_60:
> +                                       vref_value_dq = 0x31;
> +                                       break;
> +                               default:
> +                                       debug("Halting: Invalid ODT value.\n");
> +                                       return -EINVAL;
> +                               }
> +                       } else if (drv_value == PHY_DRV_ODT_34_3) {
> +                               switch (odt_value) {
> +                               case PHY_DRV_ODT_240:
> +                                       vref_value_dq = 0x17;
> +                                       break;
> +                               case PHY_DRV_ODT_120:
> +                                       vref_value_dq = 0x20;
> +                                       break;
> +                               case PHY_DRV_ODT_60:
> +                                       vref_value_dq = 0x2e;
> +                                       break;
> +                               default:
> +                                       debug("Halting: Invalid ODT value.\n");
> +                                       return -EINVAL;
> +                               }
> +                       } else {
> +                               debug("Halting: Invalid DRV value.\n");
> +                               return -EINVAL;
> +                       }
> +               } else {
> +                       vref_mode_dq = 0x2;  /* LPDDR3 */
> +                       vref_value_dq = 0x1f;
> +               }
> +               vref_mode_ac = 0x2;
> +               vref_value_ac = 0x1f;
> +       } else if (sdram_params->base.dramtype == DDR3) {
> +               /* DDR3L */
> +               vref_mode_dq = 0x1;
> +               vref_value_dq = 0x1f;
> +               vref_mode_ac = 0x1;
> +               vref_value_ac = 0x1f;
> +       } else {
> +               debug("Halting: Unknown DRAM type.\n");
> +               return -ENODEV;

-EINVAL for consistency?

> +       }
> +
> +       reg_value = (vref_mode_dq << 9) | (0x1 << 8) | vref_value_dq;
> +

[..]

> +static int switch_to_phy_index1(struct dram_info *dram,
> +                                const struct rk3399_sdram_params *sdram_params)
> +{
> +       u32 channel;
> +       u32 *denali_phy;
> +       u32 ch_count = sdram_params->base.num_channels;
> +       int i = 0;
> +
> +       writel(RK_CLRSETBITS(0x03 << 4 | 1 << 2 | 1,
> +                            1 << 4 | 1 << 2 | 1),
> +                       &dram->cic->cic_ctrl0);
> +       while (!(readl(&dram->cic->cic_status0) & (1 << 2))) {
> +               mdelay(10);
> +               i++;
> +               if (i > 10) {
> +                       debug("index1 frequency change overtime, reset\n");
> +                       return -ETIME;
> +               }
> +       }
> +
> +       i = 0;
> +       writel(RK_CLRSETBITS(1 << 1, 1 << 1), &dram->cic->cic_ctrl0);
> +       while (!(readl(&dram->cic->cic_status0) & (1 << 0))) {
> +               mdelay(10);
> +               if (i > 10) {
> +                       debug("index1 frequency done overtime, reset\n");
> +                       return -ETIME;
> +               }
> +       }
> +
> +       for (channel = 0; channel < ch_count; channel++) {
> +               denali_phy = dram->chan[channel].publ->denali_phy;
> +               clrsetbits_le32(&denali_phy[896], (0x3 << 8) | 1, 1 << 8);
> +               if (data_training(&dram->chan[channel], channel,
> +                                 sdram_params, PI_FULL_TRAINING)) {
> +                       debug("index1 training failed, reset\n");
> +                       return -EIO;

Can you return the value of data_training() in this case, or do you
want to change it to -EIO?

> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +static int sdram_init(struct dram_info *dram,
> +                     const struct rk3399_sdram_params *sdram_params)
> +{
> +       unsigned char dramtype = sdram_params->base.dramtype;
> +       unsigned int ddr_freq = sdram_params->base.ddr_freq;
> +       int channel;
> +
> +       printf("Starting SDRAM initialization...\n");

debug()?

> +
> +       if ((dramtype == DDR3 && ddr_freq > 800) ||
> +           (dramtype == LPDDR3 && ddr_freq > 933) ||
> +           (dramtype == LPDDR4 && ddr_freq > 800)) {
> +               debug("SDRAM frequency is to high!");
> +               return -E2BIG;
> +       }
> +
> +       for (channel = 0; channel < 2; channel++) {
> +               const struct chan_info *chan = &dram->chan[channel];
> +               struct rk3399_ddr_publ_regs *publ = chan->publ;
> +
> +               phy_dll_bypass_set(publ, ddr_freq);
> +
> +               if (channel >= sdram_params->base.num_channels)
> +                       continue;
> +
> +               if (pctl_cfg(chan, channel, sdram_params) != 0) {
> +                       printf("pctl_cfg fail, reset\n");
> +                       return -EIO;
> +               }
> +
> +               /* LPDDR2/LPDDR3 need to wait DAI complete, max 10us */
> +               if (dramtype == LPDDR3)
> +                       udelay(10);
> +
> +               if (data_training(chan, channel,
> +                                 sdram_params, PI_FULL_TRAINING)) {
> +                       printf("SDRAM initialization failed, reset\n");
> +                       return -EIO;
> +               }
> +
> +               set_ddrconfig(chan, sdram_params, channel,
> +                             sdram_params->ch[channel].ddrconfig);
> +       }
> +       dram_all_config(dram, sdram_params);
> +       switch_to_phy_index1(dram, sdram_params);
> +
> +       printf("Finish SDRAM initialization...\n");

debug()?

> +       return 0;
> +}
> +#endif
> +
> +size_t sdram_size_mb(struct dram_info *dram)
> +{
> +       u32 rank, col, bk, cs0_row, cs1_row, bw, row_3_4;
> +       size_t chipsize_mb = 0;
> +       size_t size_mb = 0;
> +       u32 ch;
> +
> +       u32 sys_reg = readl(&dram->pmugrf->os_reg2);
> +       u32 ch_num = 1 + ((sys_reg >> SYS_REG_NUM_CH_SHIFT)
> +                      & SYS_REG_NUM_CH_MASK);
> +
> +       for (ch = 0; ch < ch_num; ch++) {
> +               rank = 1 + (sys_reg >> SYS_REG_RANK_SHIFT(ch) &
> +                       SYS_REG_RANK_MASK);
> +               col = 9 + (sys_reg >> SYS_REG_COL_SHIFT(ch) & SYS_REG_COL_MASK);
> +               bk = 3 - ((sys_reg >> SYS_REG_BK_SHIFT(ch)) & SYS_REG_BK_MASK);
> +               cs0_row = 13 + (sys_reg >> SYS_REG_CS0_ROW_SHIFT(ch) &
> +                               SYS_REG_CS0_ROW_MASK);
> +               cs1_row = 13 + (sys_reg >> SYS_REG_CS1_ROW_SHIFT(ch) &
> +                               SYS_REG_CS1_ROW_MASK);
> +               bw = (2 >> ((sys_reg >> SYS_REG_BW_SHIFT(ch)) &
> +                       SYS_REG_BW_MASK));
> +               row_3_4 = sys_reg >> SYS_REG_ROW_3_4_SHIFT(ch) &
> +                       SYS_REG_ROW_3_4_MASK;
> +
> +               chipsize_mb = (1 << (cs0_row + col + bk + bw - 20));
> +
> +               if (rank > 1)
> +                       chipsize_mb += chipsize_mb >> (cs0_row - cs1_row);
> +               if (row_3_4)
> +                       chipsize_mb = chipsize_mb * 3 / 4;
> +               size_mb += chipsize_mb;
> +       }
> +
> +       /*
> +        * we use the 0x00000000~0xf7ffffff space
> +        * since 0xf8000000~0xffffffff is soc register space
> +        * so we reserve it
> +        */
> +       size_mb = min_t(size_t, size_mb, 0xf8000000/(1<<20));
> +
> +       return size_mb;
> +}
> +
> +static int rk3399_dmc_probe(struct udevice *dev)
> +{
> +       struct dram_info *priv = dev_get_priv(dev);
> +#ifdef CONFIG_SPL_BUILD

Can you put all of this code within #ifdef in a separate function,
something like rk3399_dmc_init()?

Also you should be able to build without of-platdata - i.e. you still
need the code which reads from device tree. See for example how rk3288
does it. I think you just need to add two versions of the code in this
#ifdef. See the of-platdata docs:

"Drivers should always support device tree as an option. The of-platdata
feature is intended as a add-on to existing drivers."


> +       struct rockchip_dmc_plat *plat = dev_get_platdata(dev);
> +       struct dtd_rockchip_rk3399_dmc *dtplat = &plat->dtplat;
> +       struct rk3399_sdram_params *params =
> +                                       (void *)dtplat->rockchip_sdram_params;
> +       int ret;
> +
> +       priv->cic = syscon_get_first_range(ROCKCHIP_SYSCON_CIC);
> +       priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
> +       priv->pmusgrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUSGRF);
> +       priv->pmucru = rockchip_get_pmucru();
> +       priv->cru = rockchip_get_cru();
> +       ret = regmap_init_mem_platdata(dev, dtplat->reg,
> +                                      ARRAY_SIZE(dtplat->reg) / 4,
> +                                      &plat->map);
> +       if (ret)
> +               return ret;
> +       priv->chan[0].pctl = regmap_get_range(plat->map, 0);
> +       priv->chan[0].pi = regmap_get_range(plat->map, 1);
> +       priv->chan[0].publ = regmap_get_range(plat->map, 2);
> +       priv->chan[0].msch = regmap_get_range(plat->map, 3);
> +       priv->chan[1].pctl = regmap_get_range(plat->map, 4);
> +       priv->chan[1].pi = regmap_get_range(plat->map, 5);
> +       priv->chan[1].publ = regmap_get_range(plat->map, 6);
> +       priv->chan[1].msch = regmap_get_range(plat->map, 7);
> +
> +       debug("con reg %p %p %p %p %p %p %p %p\n",
> +             priv->chan[0].pctl, priv->chan[0].pi,
> +             priv->chan[0].publ, priv->chan[0].msch,
> +             priv->chan[1].pctl, priv->chan[1].pi,
> +             priv->chan[1].publ, priv->chan[1].msch);
> +       debug("cru %p, cic %p, grf %p, sgrf %p, pmucru %p\n", priv->cru,
> +             priv->cic, priv->pmugrf, priv->pmusgrf, priv->pmucru);
> +
> +       ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->ddr_clk);
> +       if (ret) {
> +               printf("%s clk get failed %d\n", __func__, ret);
> +               return ret;
> +       }
> +       ret = clk_set_rate(&priv->ddr_clk, params->base.ddr_freq * MHz);
> +       if (ret < 0) {
> +               printf("%s clk set failed %d\n", __func__, ret);
> +               return ret;
> +       }
> +       ret = sdram_init(priv, params);
> +       if (ret < 0) {
> +               printf("%s DRAM init failed%d\n", __func__, ret);
> +               return ret;
> +       }
> +#else
> +       priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
> +       debug("%s: pmugrf=%p\n", __func__, priv->pmugrf);
> +#endif
> +       return 0;
> +}
> +

[..]

Regards,
Simon

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

* [U-Boot] [PATCH v2 2/9] arm64: rk3399: move grf register definitions to grf_rk3399.h
  2017-02-13  9:38 ` [U-Boot] [PATCH v2 2/9] arm64: rk3399: move grf register definitions to grf_rk3399.h Kever Yang
@ 2017-02-21 20:33   ` Simon Glass
  0 siblings, 0 replies; 23+ messages in thread
From: Simon Glass @ 2017-02-21 20:33 UTC (permalink / raw)
  To: u-boot

On 13 February 2017 at 02:38, Kever Yang <kever.yang@rock-chips.com> wrote:
> rk3399 grf register bit defenitions should locate in header
> file, so that not only pinctrl can use it.
>
> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
> Changes in v1: None
>
>  arch/arm/include/asm/arch-rockchip/grf_rk3399.h | 118 ++++++++++++++++++++++++
>  drivers/pinctrl/rockchip/pinctrl_rk3399.c       | 106 ---------------------
>  2 files changed, 118 insertions(+), 106 deletions(-)

Applied to u-boot-rockchip, thanks!

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

* [U-Boot] [PATCH v2 3/9] clk: rk3399: update driver for spl
  2017-02-13  9:38 ` [U-Boot] [PATCH v2 3/9] clk: rk3399: update driver for spl Kever Yang
@ 2017-02-21 20:33   ` Simon Glass
  0 siblings, 0 replies; 23+ messages in thread
From: Simon Glass @ 2017-02-21 20:33 UTC (permalink / raw)
  To: u-boot

On 13 February 2017 at 02:38, Kever Yang <kever.yang@rock-chips.com> wrote:
> Add ddr clock setting, add rockchip_get_pmucru API,
> and enable of-platdata support.
>
> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
> Changes in v1: None
>
>  arch/arm/include/asm/arch-rockchip/clock.h      |  7 ++
>  arch/arm/include/asm/arch-rockchip/cru_rk3399.h |  5 ++
>  arch/arm/mach-rockchip/rk3399/clk_rk3399.c      | 21 ++++++
>  drivers/clk/rockchip/clk_rk3399.c               | 89 ++++++++++++++++++++++---
>  include/dt-bindings/clock/rk3399-cru.h          | 16 +++--
>  5 files changed, 123 insertions(+), 15 deletions(-)

Applied to u-boot-rockchip, thanks!

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

* [U-Boot] [PATCH v2 4/9] sdhci: rk3399: update driver to support of-platdata
  2017-02-13  9:38 ` [U-Boot] [PATCH v2 4/9] sdhci: rk3399: update driver to support of-platdata Kever Yang
@ 2017-02-21 20:34   ` Simon Glass
  0 siblings, 0 replies; 23+ messages in thread
From: Simon Glass @ 2017-02-21 20:34 UTC (permalink / raw)
  To: u-boot

On 13 February 2017 at 02:38, Kever Yang <kever.yang@rock-chips.com> wrote:
> Change some API in order to enable of-platdata.
>
> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
> Changes in v1: None
>
>  drivers/mmc/rockchip_sdhci.c | 17 ++++++++++++++++-
>  1 file changed, 16 insertions(+), 1 deletion(-)

Applied to u-boot-rockchip, thanks!

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

* [U-Boot] [PATCH v2 5/9] pinctrl: rk3399: add the of-platdata support
  2017-02-13  9:38 ` [U-Boot] [PATCH v2 5/9] pinctrl: rk3399: add the of-platdata support Kever Yang
@ 2017-02-21 20:34   ` Simon Glass
  0 siblings, 0 replies; 23+ messages in thread
From: Simon Glass @ 2017-02-21 20:34 UTC (permalink / raw)
  To: u-boot

On 13 February 2017 at 02:38, Kever Yang <kever.yang@rock-chips.com> wrote:
> Do not use the API which of-platdata not support.
>
> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
> Changes in v1: None
>
>  drivers/pinctrl/rockchip/pinctrl_rk3399.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)

Applied to u-boot-rockchip, thanks!

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

* [U-Boot] [PATCH v2 6/9] arm64: rk3399: syscon addition for rk3399
  2017-02-13  9:38 ` [U-Boot] [PATCH v2 6/9] arm64: rk3399: syscon addition for rk3399 Kever Yang
  2017-02-16 20:43   ` Simon Glass
@ 2017-02-21 20:34   ` Simon Glass
  1 sibling, 0 replies; 23+ messages in thread
From: Simon Glass @ 2017-02-21 20:34 UTC (permalink / raw)
  To: u-boot

On 13 February 2017 at 02:38, Kever Yang <kever.yang@rock-chips.com> wrote:
> rk3399 has different syscon registers which may used in spl,
> add to support rk3399 spl.
>
> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
> ---
>
> Changes in v2: None
> Changes in v1: None
>
>  arch/arm/include/asm/arch-rockchip/clock.h    |  2 ++
>  arch/arm/mach-rockchip/rk3399/syscon_rk3399.c | 40 +++++++++++++++++++++++++++
>  2 files changed, 42 insertions(+)

Applied to u-boot-rockchip, thanks!

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

* [U-Boot] [PATCH v2 8/9] arm64: rk3399: add SPL support
  2017-02-13  9:39 ` [U-Boot] [PATCH v2 8/9] arm64: rk3399: add SPL support Kever Yang
  2017-02-16 20:43   ` Simon Glass
@ 2017-02-23  4:16   ` Simon Glass
  2017-02-23  7:44     ` Kever Yang
  1 sibling, 1 reply; 23+ messages in thread
From: Simon Glass @ 2017-02-23  4:16 UTC (permalink / raw)
  To: u-boot

Hi Kever,

On 13 February 2017 at 02:39, Kever Yang <kever.yang@rock-chips.com> wrote:
> Add SPL support for rk3399, default with of-platdata enabled.
>
> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
> ---
>
> Changes in v2:
> - split SPL patch into 4 patches
>
> Changes in v1: None
>
>  arch/arm/Kconfig                          |   1 +
>  arch/arm/mach-rockchip/Kconfig            |   2 +
>  arch/arm/mach-rockchip/Makefile           |   1 +
>  arch/arm/mach-rockchip/rk3399-board-spl.c | 158 ++++++++++++++++++++++++++++++
>  include/configs/rk3399_common.h           |   6 ++
>  5 files changed, 168 insertions(+)
>  create mode 100644 arch/arm/mach-rockchip/rk3399-board-spl.c
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index d871a45..9a0efe4 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -882,6 +882,7 @@ config ARCH_ROCKCHIP
>         select DM
>         select SPL_DM if SPL
>         select SYS_MALLOC_F
> +       select SPL_SEPARATE_BSS if SPL

Unfortunately this line seems to break firefly-rk3288, for example.

Can you perhaps move it to RK3399 only?

Regards,
Simon

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

* [U-Boot] [PATCH v2 8/9] arm64: rk3399: add SPL support
  2017-02-23  4:16   ` Simon Glass
@ 2017-02-23  7:44     ` Kever Yang
  0 siblings, 0 replies; 23+ messages in thread
From: Kever Yang @ 2017-02-23  7:44 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On 02/23/2017 12:16 PM, Simon Glass wrote:
> Hi Kever,
>
> On 13 February 2017 at 02:39, Kever Yang <kever.yang@rock-chips.com> wrote:
>> Add SPL support for rk3399, default with of-platdata enabled.
>>
>> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
>> ---
>>
>> Changes in v2:
>> - split SPL patch into 4 patches
>>
>> Changes in v1: None
>>
>>   arch/arm/Kconfig                          |   1 +
>>   arch/arm/mach-rockchip/Kconfig            |   2 +
>>   arch/arm/mach-rockchip/Makefile           |   1 +
>>   arch/arm/mach-rockchip/rk3399-board-spl.c | 158 ++++++++++++++++++++++++++++++
>>   include/configs/rk3399_common.h           |   6 ++
>>   5 files changed, 168 insertions(+)
>>   create mode 100644 arch/arm/mach-rockchip/rk3399-board-spl.c
>>
>> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
>> index d871a45..9a0efe4 100644
>> --- a/arch/arm/Kconfig
>> +++ b/arch/arm/Kconfig
>> @@ -882,6 +882,7 @@ config ARCH_ROCKCHIP
>>          select DM
>>          select SPL_DM if SPL
>>          select SYS_MALLOC_F
>> +       select SPL_SEPARATE_BSS if SPL
> Unfortunately this line seems to break firefly-rk3288, for example.
>
> Can you perhaps move it to RK3399 only?

Yes, I can move it to RK3399, can I send v4 patch only for this one, because
the patch is too big.

Thanks,
- Kever
>
> Regards,
> Simon
>
>
>

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

end of thread, other threads:[~2017-02-23  7:44 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-02-13  9:38 [U-Boot] [PATCH v2 0/9] rk3399: enable SPL driver Kever Yang
2017-02-13  9:38 ` [U-Boot] [PATCH v2 1/9] arm64: rk3399: add ddr controller driver Kever Yang
2017-02-16 20:43   ` Simon Glass
2017-02-13  9:38 ` [U-Boot] [PATCH v2 2/9] arm64: rk3399: move grf register definitions to grf_rk3399.h Kever Yang
2017-02-21 20:33   ` Simon Glass
2017-02-13  9:38 ` [U-Boot] [PATCH v2 3/9] clk: rk3399: update driver for spl Kever Yang
2017-02-21 20:33   ` Simon Glass
2017-02-13  9:38 ` [U-Boot] [PATCH v2 4/9] sdhci: rk3399: update driver to support of-platdata Kever Yang
2017-02-21 20:34   ` Simon Glass
2017-02-13  9:38 ` [U-Boot] [PATCH v2 5/9] pinctrl: rk3399: add the of-platdata support Kever Yang
2017-02-21 20:34   ` Simon Glass
2017-02-13  9:38 ` [U-Boot] [PATCH v2 6/9] arm64: rk3399: syscon addition for rk3399 Kever Yang
2017-02-16 20:43   ` Simon Glass
2017-02-21 20:34   ` Simon Glass
2017-02-13  9:39 ` [U-Boot] [PATCH v2 7/9] dts: rk3399: update for spl require driver Kever Yang
2017-02-16 20:43   ` Simon Glass
2017-02-13  9:39 ` [U-Boot] [PATCH v2 8/9] arm64: rk3399: add SPL support Kever Yang
2017-02-16 20:43   ` Simon Glass
2017-02-23  4:16   ` Simon Glass
2017-02-23  7:44     ` Kever Yang
2017-02-13  9:39 ` [U-Boot] [PATCH v2 9/9] config: rk3399: enable SPL config for evb-rk3399 Kever Yang
2017-02-16 20:43   ` Simon Glass
2017-02-16 20:43 ` [U-Boot] [PATCH v2 0/9] rk3399: enable SPL driver Simon Glass

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox