All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support
@ 2015-08-30 22:55 Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 01/41] pinctrl: Add help text to Kconfig Simon Glass
                   ` (40 more replies)
  0 siblings, 41 replies; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

The Rockchip RK3288 is based on a quad-core Cortex-A17 CPU and has a good
set of peripherals. Various full-featured U-Boot ports are available and
this is an attempt to bring those features into mainline. With this series
the Firefly RK3288 can boot to a prompt from an SD card.

Since much of the code is generic, this also supports the Radxa Rock 2.
Since there is no device tree available for that yet, it uses the same
config and device tree as the Firefly. This works because not all
peripherals are supported, so the differences don't matter.

Support for booting from USB OTG is also provided, using the on-chip boot
ROM and the rkflashtool utility. This can boot as far as SPL, but there is
no support for reading U-Boot proper from USB as yet. This requires
implementing a suitable protocol (perhaps DFU or Rockchip's proprietary
one) in SPL.

Support is also provided for the Hisense Chromebook, which is based on the
same SoC. In this case it boots from SPI rather than an SD card.

This seriea makes use of driver model including a number of recently added
uclasses:

- Clocks - setting and getting PLL and peripheral clocks
- Pinctrl - adjusting pin multiplexing settings
- Reset - reseting the board or SoC
- RAM - setting up RAM controllers and detecting the available RAM
- MMC - MMC controllers (using the existing block device framework)
- LEDs - turning LEDs on and off, with only a GPIO driver so far

This series avoids hard-coding RK3288-specific code into the build. There
is a CONFIG_ROCKCHIP_RK3288 but it only *adds* support for RK3288. In
principle another CONFIG could add support for a different Rockchip SoC
with only the device tree selecting which one U-Boot works on.

Support is provided in mkimage to build these image types:

- rkimage - suitable for packaging up SPL to be sent to the boot ROM over
            USB OTG
- rksd    - suitable for writing to an SD card

Much of the source and ideas for this series came from downstream Rockchip
U-Boot trees. SDRAM init came from Coreboot. In most cases it has been
pretty heavily cleaned up / rewritten to meet U-Boot style and remove
hard-coding of things.

Drivers are provided for:

- Clocks
- Pinctrl
- SoC reset
- DDR3 SDRAM
- I2C
- SPI
- GPIOs
- LEDs using GPIOS
- MMC
- Firefly main PMIC (ACT8846) and included regulators

These are lightly tested and doubtless some problems exist with some,
particularly I2C.

One problem with device tree is that U-Boot has no way of dropping features
it does not need or use. For SPL this problem needs to be solved and this
series uses a new 'fdtgrep' tool for this. The 45KB Firefly device tree
reduces to a 6KB bytes when unused material is removed. SDRAM timings are
also in the device tree.

There is a large amount of additional work to bring other Rockchip drivers
and features into mainline U-Boot, so this is only a start.

Note: This series sits on top of Masahiro's RFC pinctrl series. I wanted to
get a new version out while we wait for this to make it to mainline. You can
find this series at u-boot-dm/rockchip-working.

Changes in v5:
- Add new patch to put README image creation commands on one line
- Add new patch to tidy up SPL options for the led and led-gpio
- Adjust Kconfig help to indicate the MMC device may support newer spec versions
- Bring in Sjoerd's series so that everything is in one place
- Drop BSS memset() as it is not needed
- Drop CONFIG_ROCKCHIP_MMC from rk_common.h
- Drop CONFIG_SPL_LED_SUPPORT from header file and move to Kconfig
- Drop unnecessary 'depends on DM_SPI' in Kconfig
- Fix comment in IH_TYPE_RKSPI
- Fix comment on orig_file_size
- Fix priv_auto_alloc_size to use correct struct (rockchip_dwmmc_priv)
- Merge with Masahiro's v5 patch
- Rebase on top of Masahiro's v5 series
- Rename driver and Kconfig to indicate it uses designware
- Rename driver functions, etc. from rockchip_mmc to rockchip_dwmmc
- Tidy up rkspi_dump_regs() debug output
- Tidy up the delay in rkspi_wait_till_not_busy()
- Use CONFIG_ROCKCHIP_DWMMC instead of CONFIG_ROCKCHIP_MMC
- Use CONFIG_SPL_LED instead of CONFIG_SPL_LED_SUPPORT

Changes in v4:
- Add a set_state_simple() method
- Adjust the defconfig file to suit mainline
- Rename pinctrl.h to dm/pinctrl.h
- Tweak the cover letter a little, drop mention of patches already applied

Changes in v3:
- Add device tree bindings for CRU and DMC
- Add various new patches to get RK3288 booting to a prompt
- Make use of additional features since version 2
- Update README to mention available drivers
- Update clock rate to always be 24MHz

Changes in v2:
- Drop use of CONFIG_USE_PRIVATE_LIBGCC=y
- Tidy up license headers and remove SPL #ifdefs

Simon Glass (33):
  pinctrl: Add help text to Kconfig
  pinctrl: Add the concept of peripheral IDs
  dm: led: Tidy up SPL options for the led and led-gpio
  mmc: Support bypass mode with the get_mmc_clk() method
  dm: Improve handling of a missing uclass
  dm: Provide better debugging when a device fails to bind
  arm: reset: Avoid a build error when the reset uclass is enabled
  rockchip: Add serial support
  rockchip: Bring in RK3288 device tree file includes and bindings
  rockchip: rk3288: dts: Make core devices available early
  mkimage: Allow padding to any length
  mkimage: Allow the original file size to be recorded
  rockchip: Add the rkimage format to mkimage
  rockchip: Add support for the SD image
  rockchip: Add support for the SPI image
  rockchip: gpio: Add rockchip GPIO driver
  rockchip: Add basic peripheral and clock definitions
  power: Add support for ACT8846 PMIC
  power: regulator: Add a driver for ACT8846 regulators
  rockchip: rk3288: Add clock driver
  rockchip: rk3288: Add header files for PMU and GRF
  rockchip: rk3288: Add SoC reset driver
  rockchip: rk3288: Add a simple syscon driver
  rockchip: rk3288: Add pinctrl driver
  rockchip: rk3288: Add SDRAM init
  rockchip: Add an MMC driver
  rockchip: Add core SoC start-up code
  rockchip: Add I2C driver
  rockchip: Add SPI driver
  rockchip: Add basic support for firefly-rk3288
  rockchip: Add basic support for jerry
  rockchip: Add a simple README
  rockchip: Put README image creation commands on one line

Sjoerd Simons (8):
  doc: Fix reference to Rock pro when Rock 2 is meant
  mmc: Probe DM based mmc devices in u-boot
  rockchip: Disable sdio mmc slot on rk3288-firefly
  rockchip: Turn off CONFIG_SPL_LED for firefly
  rockchip: Add config_distro_bootcmd support
  arm: Turn of d-cache before i-cache
  rockchip: Drop first 32kb of zeros from the rkSD image type
  rockchip: Update todo in README.rockchip

 arch/arm/Kconfig                                   |   10 +
 arch/arm/Makefile                                  |    1 +
 arch/arm/cpu/armv7/cpu.c                           |   15 +-
 arch/arm/dts/Makefile                              |    3 +
 arch/arm/dts/cros-ec-sbs.dtsi                      |   16 +
 arch/arm/dts/rk3288-firefly.dts                    |   75 +
 arch/arm/dts/rk3288-firefly.dtsi                   |  457 ++++++
 arch/arm/dts/rk3288-jerry.dts                      |  203 +++
 arch/arm/dts/rk3288-thermal.dtsi                   |   88 ++
 arch/arm/dts/rk3288-veyron-chromebook.dtsi         |  200 +++
 arch/arm/dts/rk3288-veyron.dtsi                    |  844 +++++++++++
 arch/arm/dts/rk3288.dtsi                           | 1473 ++++++++++++++++++++
 arch/arm/include/asm/arch-rockchip/clock.h         |   45 +
 arch/arm/include/asm/arch-rockchip/cru_rk3288.h    |  185 +++
 arch/arm/include/asm/arch-rockchip/ddr_rk3288.h    |  484 +++++++
 arch/arm/include/asm/arch-rockchip/gpio.h          |   28 +
 arch/arm/include/asm/arch-rockchip/grf_rk3288.h    |  768 ++++++++++
 arch/arm/include/asm/arch-rockchip/hardware.h      |   20 +
 arch/arm/include/asm/arch-rockchip/i2c.h           |   70 +
 arch/arm/include/asm/arch-rockchip/periph.h        |   54 +
 arch/arm/include/asm/arch-rockchip/pmu_rk3288.h    |   89 ++
 arch/arm/include/asm/arch-rockchip/sdram.h         |   92 ++
 arch/arm/lib/Makefile                              |    2 +
 arch/arm/mach-rockchip/Kconfig                     |   41 +
 arch/arm/mach-rockchip/Makefile                    |   13 +
 arch/arm/mach-rockchip/board-spl.c                 |  287 ++++
 arch/arm/mach-rockchip/board.c                     |   46 +
 arch/arm/mach-rockchip/common.c                    |   28 +
 arch/arm/mach-rockchip/rk3288/Kconfig              |   26 +
 arch/arm/mach-rockchip/rk3288/Makefile             |    9 +
 arch/arm/mach-rockchip/rk3288/reset_rk3288.c       |   47 +
 arch/arm/mach-rockchip/rk3288/sdram_rk3288.c       |  878 ++++++++++++
 arch/arm/mach-rockchip/rk3288/syscon_rk3288.c      |   25 +
 board/firefly/firefly-rk3288/Kconfig               |   15 +
 board/firefly/firefly-rk3288/MAINTAINERS           |    6 +
 board/firefly/firefly-rk3288/Makefile              |    7 +
 board/firefly/firefly-rk3288/firefly-rk3288.c      |    7 +
 board/google/chromebook_jerry/Kconfig              |   15 +
 board/google/chromebook_jerry/MAINTAINERS          |    6 +
 board/google/chromebook_jerry/Makefile             |    7 +
 board/google/chromebook_jerry/jerry.c              |    7 +
 board/google/common/Makefile                       |    2 +-
 common/image.c                                     |    3 +
 configs/chromebook_jerry_defconfig                 |   43 +
 configs/firefly-rk3288_defconfig                   |   42 +
 doc/README.rockchip                                |  247 ++++
 .../clock/rockchip,rk3188-cru.txt                  |   61 +
 .../clock/rockchip,rk3288-cru.txt                  |   61 +
 .../clock/rockchip,rk3288-dmc.txt                  |  155 ++
 doc/device-tree-bindings/clock/rockchip.txt        |   77 +
 .../pinctrl/rockchip,pinctrl.txt                   |  157 +++
 .../thermal/rockchip-thermal.txt                   |   68 +
 drivers/clk/Makefile                               |    1 +
 drivers/clk/clk_rk3288.c                           |  618 ++++++++
 drivers/core/device.c                              |    4 +-
 drivers/core/root.c                                |    5 +-
 drivers/core/uclass.c                              |    7 +-
 drivers/gpio/Kconfig                               |    9 +
 drivers/gpio/Makefile                              |    1 +
 drivers/gpio/rk_gpio.c                             |  123 ++
 drivers/i2c/Kconfig                                |    9 +
 drivers/i2c/Makefile                               |    1 +
 drivers/i2c/rk_i2c.c                               |  391 ++++++
 drivers/led/Kconfig                                |    9 +-
 drivers/led/Makefile                               |    4 +-
 drivers/mmc/Kconfig                                |    9 +
 drivers/mmc/Makefile                               |    1 +
 drivers/mmc/dw_mmc.c                               |    2 +-
 drivers/mmc/exynos_dw_mmc.c                        |    2 +-
 drivers/mmc/mmc.c                                  |   43 +-
 drivers/mmc/rockchip_dw_mmc.c                      |   98 ++
 drivers/pinctrl/Kconfig                            |   20 +-
 drivers/pinctrl/Makefile                           |    1 +
 drivers/pinctrl/pinctrl-uclass.c                   |   40 +-
 drivers/pinctrl/rockchip/Makefile                  |    8 +
 drivers/pinctrl/rockchip/pinctrl_rk3288.c          |  441 ++++++
 drivers/power/pmic/Kconfig                         |    9 +
 drivers/power/pmic/Makefile                        |    1 +
 drivers/power/pmic/act8846.c                       |   90 ++
 drivers/power/regulator/Kconfig                    |    9 +
 drivers/power/regulator/Makefile                   |    1 +
 drivers/power/regulator/act8846.c                  |  155 ++
 drivers/serial/Kconfig                             |    9 +
 drivers/serial/Makefile                            |    1 +
 drivers/serial/serial_rockchip.c                   |   43 +
 drivers/spi/Kconfig                                |    8 +
 drivers/spi/Makefile                               |    1 +
 drivers/spi/rk_spi.c                               |  372 +++++
 drivers/spi/rk_spi.h                               |  121 ++
 include/configs/chromebook_jerry.h                 |   16 +
 include/configs/firefly-rk3288.h                   |   14 +
 include/configs/rk3288_common.h                    |  118 ++
 include/dm/pinctrl.h                               |   60 +
 include/dt-bindings/clock/rk3288-cru.h             |  370 +++++
 include/dt-bindings/clock/rockchip,rk808.h         |   11 +
 include/dt-bindings/pinctrl/rockchip.h             |   26 +
 include/dt-bindings/power-domain/rk3288.h          |   11 +
 include/dwmmc.h                                    |   16 +-
 include/image.h                                    |    5 +-
 include/power/act8846_pmic.h                       |   37 +
 tools/Makefile                                     |    3 +
 tools/imagetool.h                                  |    1 +
 tools/mkimage.c                                    |   23 +-
 tools/rkcommon.c                                   |   72 +
 tools/rkcommon.h                                   |   28 +
 tools/rkimage.c                                    |   65 +
 tools/rksd.c                                       |   97 ++
 tools/rkspi.c                                      |  119 ++
 108 files changed, 11325 insertions(+), 42 deletions(-)
 create mode 100644 arch/arm/dts/cros-ec-sbs.dtsi
 create mode 100644 arch/arm/dts/rk3288-firefly.dts
 create mode 100644 arch/arm/dts/rk3288-firefly.dtsi
 create mode 100644 arch/arm/dts/rk3288-jerry.dts
 create mode 100644 arch/arm/dts/rk3288-thermal.dtsi
 create mode 100644 arch/arm/dts/rk3288-veyron-chromebook.dtsi
 create mode 100644 arch/arm/dts/rk3288-veyron.dtsi
 create mode 100644 arch/arm/dts/rk3288.dtsi
 create mode 100644 arch/arm/include/asm/arch-rockchip/clock.h
 create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rk3288.h
 create mode 100644 arch/arm/include/asm/arch-rockchip/ddr_rk3288.h
 create mode 100644 arch/arm/include/asm/arch-rockchip/gpio.h
 create mode 100644 arch/arm/include/asm/arch-rockchip/grf_rk3288.h
 create mode 100644 arch/arm/include/asm/arch-rockchip/hardware.h
 create mode 100644 arch/arm/include/asm/arch-rockchip/i2c.h
 create mode 100644 arch/arm/include/asm/arch-rockchip/periph.h
 create mode 100644 arch/arm/include/asm/arch-rockchip/pmu_rk3288.h
 create mode 100644 arch/arm/include/asm/arch-rockchip/sdram.h
 create mode 100644 arch/arm/mach-rockchip/Kconfig
 create mode 100644 arch/arm/mach-rockchip/Makefile
 create mode 100644 arch/arm/mach-rockchip/board-spl.c
 create mode 100644 arch/arm/mach-rockchip/board.c
 create mode 100644 arch/arm/mach-rockchip/common.c
 create mode 100644 arch/arm/mach-rockchip/rk3288/Kconfig
 create mode 100644 arch/arm/mach-rockchip/rk3288/Makefile
 create mode 100644 arch/arm/mach-rockchip/rk3288/reset_rk3288.c
 create mode 100644 arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
 create mode 100644 arch/arm/mach-rockchip/rk3288/syscon_rk3288.c
 create mode 100644 board/firefly/firefly-rk3288/Kconfig
 create mode 100644 board/firefly/firefly-rk3288/MAINTAINERS
 create mode 100644 board/firefly/firefly-rk3288/Makefile
 create mode 100644 board/firefly/firefly-rk3288/firefly-rk3288.c
 create mode 100644 board/google/chromebook_jerry/Kconfig
 create mode 100644 board/google/chromebook_jerry/MAINTAINERS
 create mode 100644 board/google/chromebook_jerry/Makefile
 create mode 100644 board/google/chromebook_jerry/jerry.c
 create mode 100644 configs/chromebook_jerry_defconfig
 create mode 100644 configs/firefly-rk3288_defconfig
 create mode 100644 doc/README.rockchip
 create mode 100644 doc/device-tree-bindings/clock/rockchip,rk3188-cru.txt
 create mode 100644 doc/device-tree-bindings/clock/rockchip,rk3288-cru.txt
 create mode 100644 doc/device-tree-bindings/clock/rockchip,rk3288-dmc.txt
 create mode 100644 doc/device-tree-bindings/clock/rockchip.txt
 create mode 100644 doc/device-tree-bindings/pinctrl/rockchip,pinctrl.txt
 create mode 100644 doc/device-tree-bindings/thermal/rockchip-thermal.txt
 create mode 100644 drivers/clk/clk_rk3288.c
 create mode 100644 drivers/gpio/rk_gpio.c
 create mode 100644 drivers/i2c/rk_i2c.c
 create mode 100644 drivers/mmc/rockchip_dw_mmc.c
 create mode 100644 drivers/pinctrl/rockchip/Makefile
 create mode 100644 drivers/pinctrl/rockchip/pinctrl_rk3288.c
 create mode 100644 drivers/power/pmic/act8846.c
 create mode 100644 drivers/power/regulator/act8846.c
 create mode 100644 drivers/serial/serial_rockchip.c
 create mode 100644 drivers/spi/rk_spi.c
 create mode 100644 drivers/spi/rk_spi.h
 create mode 100644 include/configs/chromebook_jerry.h
 create mode 100644 include/configs/firefly-rk3288.h
 create mode 100644 include/configs/rk3288_common.h
 create mode 100644 include/dt-bindings/clock/rk3288-cru.h
 create mode 100644 include/dt-bindings/clock/rockchip,rk808.h
 create mode 100644 include/dt-bindings/pinctrl/rockchip.h
 create mode 100644 include/dt-bindings/power-domain/rk3288.h
 create mode 100644 include/power/act8846_pmic.h
 create mode 100644 tools/rkcommon.c
 create mode 100644 tools/rkcommon.h
 create mode 100644 tools/rkimage.c
 create mode 100644 tools/rksd.c
 create mode 100644 tools/rkspi.c

-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 01/41] pinctrl: Add help text to Kconfig
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:57   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 02/41] pinctrl: Add the concept of peripheral IDs Simon Glass
                   ` (39 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

The pinctrl Kconfig options should have help messages. Add this to a few
options.

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

Changes in v5:
- Merge with Masahiro's v5 patch

Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/pinctrl/Kconfig | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 30b8e45..918a859 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -47,7 +47,10 @@ config PINMUX
 	default y
 	help
 	  This option enables pin multiplexing through the generic pinctrl
-	  framework.
+	  framework. Most SoCs have their own own multiplexing arrangement
+	  where a single pin can be used for several functions. An SoC pinctrl
+	  driver allows the required function to be selected for each pin.
+	  The driver is typically controlled by the device tree.
 
 config PINCONF
 	bool "Support pin configuration controllers"
@@ -86,6 +89,12 @@ config SPL_PINMUX
 	help
 	  This option is an SPL-variant of the PINMUX option.
 	  See the help of PINMUX for details.
+	  The pinctrl subsystem can add a substantial overhead to the SPL
+	  image since it typically requires quite a few tables either in the
+	  driver or in the device tree. If this is acceptable and you need
+	  to adjust pin multiplexing in SPL in order to boot into U-Boot,
+	  enable this option. You will need to enable device tree in SPL
+	  for this to work.
 
 config SPL_PINCONF
 	bool "Support pin configuration controllers in SPL"
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 02/41] pinctrl: Add the concept of peripheral IDs
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 01/41] pinctrl: Add help text to Kconfig Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:57   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 03/41] dm: led: Tidy up SPL options for the led and led-gpio Simon Glass
                   ` (38 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

My original pinctrl patch operating using a peripheral ID enum. This was
shared between pinmux and clock and provides an easy way to specify a device
that needs to be controlled, even it is does not (yet) have a driver within
driver model.

Masahiro's new simple pinctrl gets around this by providing a
set_state_simple() pinctrl method. By passing a device to that call the
peripheral ID becomes unnecessary. If the driver needs it, it can calculate
it itself and use it internally.

However this does not solve the problem for peripheral clocks. The 'pure'
solution would be to pass a driver to the clock uclass also. But this
requires that all devices should have a driver, and a struct udevide. Also
a key optimisation of the clock uclass is allowing a peripheral clock to
be set even when there is no device for that clock.

There may be a better way to achive the same goal, but for now it seems
expedient to add in peripheral ID to the pinctrl uclass. Two methods are
added - one to get the peripheral ID and one to select it. The existing
set_state_simple() is effectively the union of these.

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

Changes in v5:
- Rebase on top of Masahiro's v5 series

Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/pinctrl/pinctrl-uclass.c | 40 +++++++++++++++++++++------
 include/dm/pinctrl.h             | 60 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 91 insertions(+), 9 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c
index d96c201..58001ef 100644
--- a/drivers/pinctrl/pinctrl-uclass.c
+++ b/drivers/pinctrl/pinctrl-uclass.c
@@ -11,6 +11,7 @@
 #include <dm/device.h>
 #include <dm/lists.h>
 #include <dm/pinctrl.h>
+#include <dm/root.h>
 #include <dm/uclass.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -159,7 +160,8 @@ static int pinctrl_select_state_full(struct udevice *dev, const char *statename)
 
 static int pinconfig_post_bind(struct udevice *dev)
 {
-	return 0;
+	/* Scan the bus for devices */
+	return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
 }
 #endif
 
@@ -205,6 +207,31 @@ int pinctrl_select_state(struct udevice *dev, const char *statename)
 	return 0;
 }
 
+int pinctrl_request(struct udevice *dev, int func, int flags)
+{
+	struct pinctrl_ops *ops = pinctrl_get_ops(dev);
+
+	if (!ops->request)
+		return -ENOSYS;
+
+	return ops->request(dev, func, flags);
+}
+
+int pinctrl_request_noflags(struct udevice *dev, int func)
+{
+	return pinctrl_request(dev, func, 0);
+}
+
+int pinctrl_get_periph_id(struct udevice *dev, struct udevice *periph)
+{
+	struct pinctrl_ops *ops = pinctrl_get_ops(dev);
+
+	if (!ops->get_periph_id)
+		return -ENOSYS;
+
+	return ops->get_periph_id(dev, periph);
+}
+
 /**
  * pinconfig_post-bind() - post binding for PINCTRL uclass
  * Recursively bind child nodes as pinconfig devices in case of full pinctrl.
@@ -222,15 +249,10 @@ static int pinctrl_post_bind(struct udevice *dev)
 	}
 
 	/*
-	 * If set_state callback is set, we assume this pinctrl driver is the
-	 * full implementation.  In this case, its child nodes should be bound
-	 * so that peripheral devices can easily search in parent devices
-	 * during later DT-parsing.
+	 * The pinctrl driver child nodes should be bound so that peripheral
+	 * devices can easily search in parent devices during later DT-parsing.
 	 */
-	if (ops->set_state)
-		return pinconfig_post_bind(dev);
-
-	return 0;
+	return pinconfig_post_bind(dev);
 }
 
 UCLASS_DRIVER(pinctrl) = {
diff --git a/include/dm/pinctrl.h b/include/dm/pinctrl.h
index bc6fdb4..f6025f6 100644
--- a/include/dm/pinctrl.h
+++ b/include/dm/pinctrl.h
@@ -87,7 +87,33 @@ struct pinctrl_ops {
 	int (*pinconf_group_set)(struct udevice *dev, unsigned group_selector,
 				 unsigned param, unsigned argument);
 	int (*set_state)(struct udevice *dev, struct udevice *config);
+
+	/* for pinctrl-simple */
 	int (*set_state_simple)(struct udevice *dev, struct udevice *periph);
+	/**
+	 * request() - Request a particular pinctrl function
+	 *
+	 * This activates the selected function.
+	 *
+	 * @dev:	Device to adjust (UCLASS_PINCTRL)
+	 * @func:	Function number (driver-specific)
+	 * @return 0 if OK, -ve on error
+	 */
+	int (*request)(struct udevice *dev, int func, int flags);
+
+	/**
+	* get_periph_id() - get the peripheral ID for a device
+	*
+	* This generally looks at the peripheral's device tree node to work
+	* out the peripheral ID. The return value is normally interpreted as
+	* enum periph_id. so long as this is defined by the platform (which it
+	* should be).
+	*
+	* @dev:		Pinctrl device to use for decoding
+	* @periph:	Device to check
+	* @return peripheral ID of @periph, or -ENOENT on error
+	*/
+	int (*get_periph_id)(struct udevice *dev, struct udevice *periph);
 };
 
 #define pinctrl_get_ops(dev)	((struct pinctrl_ops *)(dev)->driver->ops)
@@ -224,4 +250,38 @@ static inline int pinctrl_select_state(struct udevice *dev,
 }
 #endif
 
+/**
+ * pinctrl_request() - Request a particular pinctrl function
+ *
+ * @dev:	Device to check (UCLASS_PINCTRL)
+ * @func:	Function number (driver-specific)
+ * @flags:	Flags (driver-specific)
+ * @return 0 if OK, -ve on error
+ */
+int pinctrl_request(struct udevice *dev, int func, int flags);
+
+/**
+ * pinctrl_request_noflags() - Request a particular pinctrl function
+ *
+ * This is similar to pinctrl_request() but uses 0 for @flags.
+ *
+ * @dev:	Device to check (UCLASS_PINCTRL)
+ * @func:	Function number (driver-specific)
+ * @return 0 if OK, -ve on error
+ */
+int pinctrl_request_noflags(struct udevice *dev, int func);
+
+/**
+ * pinctrl_get_periph_id() - get the peripheral ID for a device
+ *
+ * This generally looks at the peripheral's device tree node to work out the
+ * peripheral ID. The return value is normally interpreted as enum periph_id.
+ * so long as this is defined by the platform (which it should be).
+ *
+ * @dev:	Pinctrl device to use for decoding
+ * @periph:	Device to check
+ * @return peripheral ID of @periph, or -ENOENT on error
+ */
+int pinctrl_get_periph_id(struct udevice *dev, struct udevice *periph);
+
 #endif /* __PINCTRL_H */
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 03/41] dm: led: Tidy up SPL options for the led and led-gpio
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 01/41] pinctrl: Add help text to Kconfig Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 02/41] pinctrl: Add the concept of peripheral IDs Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:57   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 04/41] mmc: Support bypass mode with the get_mmc_clk() method Simon Glass
                   ` (37 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

At present SPL does not have its own option. But these features can
increase SPL code size. Adjust the Kconfig and Makefile so that
separate a SPL option can be selected.

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

Changes in v5:
- Add new patch to tidy up SPL options for the led and led-gpio

Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/led/Kconfig  | 9 ++++++++-
 drivers/led/Makefile | 4 ++--
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
index 2987337..fe74403 100644
--- a/drivers/led/Kconfig
+++ b/drivers/led/Kconfig
@@ -11,7 +11,7 @@ config LED
 
 config SPL_LED
 	bool "Enable LED support in SPL"
-	depends on LED
+	depends on SPL && SPL_DM
 	help
 	  The LED subsystem adds a small amount of overhead to the image.
 	  If this is acceptable and you have a need to use LEDs in SPL,
@@ -27,4 +27,11 @@ config LED_GPIO
 	  The GPIO driver must used driver model. LEDs are configured using
 	  the device tree.
 
+config SPL_LED_GPIO
+	bool "LED support for GPIO-connected LEDs in SPL"
+        depends on SPL_LED && DM_GPIO
+	help
+	  This option is an SPL-variant of the LED_GPIO option.
+	  See the help of LED_GPIO for details.
+
 endmenu
diff --git a/drivers/led/Makefile b/drivers/led/Makefile
index 990129e..02367fd 100644
--- a/drivers/led/Makefile
+++ b/drivers/led/Makefile
@@ -5,5 +5,5 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
-obj-$(CONFIG_LED) += led-uclass.o
-obj-$(CONFIG_LED_GPIO) += led_gpio.o
+obj-y += led-uclass.o
+obj-$(CONFIG_$(SPL_)LED_GPIO) += led_gpio.o
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 04/41] mmc: Support bypass mode with the get_mmc_clk() method
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (2 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 03/41] dm: led: Tidy up SPL options for the led and led-gpio Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:58   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 05/41] dm: Improve handling of a missing uclass Simon Glass
                   ` (36 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

Some SoCs want to adjust the input clock to the DWMMC block as a way of
controlling the MMC bus clock. Update the get_mmc_clk() method to support
this.

Signed-off-by: Simon Glass <sjg@chromium.org>
Acked-by: Jaehoon Chung <jh80.chung@samsung.com>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/mmc/dw_mmc.c        |  2 +-
 drivers/mmc/exynos_dw_mmc.c |  2 +-
 include/dwmmc.h             | 16 +++++++++++++++-
 3 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 77b87e0..1117fed 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -266,7 +266,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
 	 * host->bus_hz should be set by user.
 	 */
 	if (host->get_mmc_clk)
-		sclk = host->get_mmc_clk(host);
+		sclk = host->get_mmc_clk(host, freq);
 	else if (host->bus_hz)
 		sclk = host->bus_hz;
 	else {
diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
index cde2ba7..863bbb3 100644
--- a/drivers/mmc/exynos_dw_mmc.c
+++ b/drivers/mmc/exynos_dw_mmc.c
@@ -39,7 +39,7 @@ static void exynos_dwmci_clksel(struct dwmci_host *host)
 	dwmci_writel(host, DWMCI_CLKSEL, priv->sdr_timing);
 }
 
-unsigned int exynos_dwmci_get_clk(struct dwmci_host *host)
+unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq)
 {
 	unsigned long sclk;
 	int8_t clk_div;
diff --git a/include/dwmmc.h b/include/dwmmc.h
index 7a7555a..25cf42c 100644
--- a/include/dwmmc.h
+++ b/include/dwmmc.h
@@ -163,7 +163,21 @@ struct dwmci_host {
 
 	void (*clksel)(struct dwmci_host *host);
 	void (*board_init)(struct dwmci_host *host);
-	unsigned int (*get_mmc_clk)(struct dwmci_host *host);
+
+	/**
+	 * Get / set a particular MMC clock frequency
+	 *
+	 * This is used to request the current clock frequency of the clock
+	 * that drives the DWMMC peripheral. The caller will then use this
+	 * information to work out the divider it needs to achieve the
+	 * required MMC bus clock frequency. If you want to handle the
+	 * clock external to DWMMC, use @freq to select the frequency and
+	 * return that value too. Then DWMMC will put itself in bypass mode.
+	 *
+	 * @host:	DWMMC host
+	 * @freq:	Frequency the host is trying to achieve
+	 */
+	unsigned int (*get_mmc_clk)(struct dwmci_host *host, uint freq);
 
 	struct mmc_config cfg;
 };
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 05/41] dm: Improve handling of a missing uclass
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (3 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 04/41] mmc: Support bypass mode with the get_mmc_clk() method Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:58   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 06/41] dm: Provide better debugging when a device fails to bind Simon Glass
                   ` (35 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

When a uclass definition is missing, no drivers in that uclass can operate.
This can happen if a board has a strange collection of options (e.g. the
driver is enabled but the uclass is not).

Unfortunately this is very confusing at present. Starting up driver model
results in a -ENOENT error, which is pretty generic. Quite a big of digging
is needed to get to the root cause.

To help with this, change the error to a very strange one with no other
users in U-Boot. Also add a debug message.

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

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/core/device.c | 4 +++-
 drivers/core/uclass.c | 7 ++++++-
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index a6cd936..0ccd443 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -39,8 +39,10 @@ int device_bind(struct udevice *parent, const struct driver *drv,
 		return -EINVAL;
 
 	ret = uclass_get(drv->id, &uc);
-	if (ret)
+	if (ret) {
+		debug("Missing uclass for driver %s\n", drv->name);
 		return ret;
+	}
 
 	dev = calloc(1, sizeof(struct udevice));
 	if (!dev)
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index f63ff59..e800c28 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -58,7 +58,12 @@ static int uclass_add(enum uclass_id id, struct uclass **ucp)
 	if (!uc_drv) {
 		debug("Cannot find uclass for id %d: please add the UCLASS_DRIVER() declaration for this UCLASS_... id\n",
 		      id);
-		return -ENOENT;
+		/*
+		 * Use a strange error to make this case easier to find. When
+		 * a uclass is not available it can prevent driver model from
+		 * starting up and this failure is otherwise hard to debug.
+		 */
+		return -EPFNOSUPPORT;
 	}
 	uc = calloc(1, sizeof(*uc));
 	if (!uc)
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 06/41] dm: Provide better debugging when a device fails to bind
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (4 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 05/41] dm: Improve handling of a missing uclass Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:58   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 07/41] arm: reset: Avoid a build error when the reset uclass is enabled Simon Glass
                   ` (34 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

All devices should bind without error. But when they don't, they can cause
driver model init to fail. A real situation where this can happen is when
there is a missing uclass.

Add a debug() call to dm_scan_fdt_node to make this easier to track.

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

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/core/root.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/core/root.c b/drivers/core/root.c
index 78ab00c..bdb394a 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -162,8 +162,11 @@ int dm_scan_fdt_node(struct udevice *parent, const void *blob, int offset,
 			continue;
 		}
 		err = lists_bind_fdt(parent, blob, offset, NULL);
-		if (err && !ret)
+		if (err && !ret) {
 			ret = err;
+			debug("%s: ret=%d\n", fdt_get_name(blob, offset, NULL),
+			      ret);
+		}
 	}
 
 	if (ret)
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 07/41] arm: reset: Avoid a build error when the reset uclass is enabled
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (5 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 06/41] dm: Provide better debugging when a device fails to bind Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:58   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 08/41] rockchip: Add serial support Simon Glass
                   ` (33 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

There can be only one do_reset(). When CONFIG_RESET is enabled this is
provided by the reset uclass, and ARM's version should be disabled.

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

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arm/lib/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 31a5c8d..15e74bd 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -47,7 +47,9 @@ obj-y	+= interrupts_64.o
 else
 obj-y	+= interrupts.o
 endif
+ifndef CONFIG_RESET
 obj-y	+= reset.o
+endif
 
 obj-y	+= cache.o
 ifndef CONFIG_ARM64
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 08/41] rockchip: Add serial support
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (6 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 07/41] arm: reset: Avoid a build error when the reset uclass is enabled Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:58   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 09/41] rockchip: Bring in RK3288 device tree file includes and bindings Simon Glass
                   ` (32 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

Add support for the Rockchip serial device using the ns16550 driver.
This uses driver model and device tree for both SPL and U-Boot proper.

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

Changes in v5: None
Changes in v4: None
Changes in v3:
- Update clock rate to always be 24MHz

Changes in v2: None

 drivers/serial/Kconfig           |  9 +++++++++
 drivers/serial/Makefile          |  1 +
 drivers/serial/serial_rockchip.c | 43 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 53 insertions(+)
 create mode 100644 drivers/serial/serial_rockchip.c

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 4f6a3b8..7ddda9f 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -109,6 +109,15 @@ config DEBUG_UART_SHIFT
 	  value. Use this value to specify the shift to use, where 0=byte
 	  registers, 2=32-bit word registers, etc.
 
+config ROCKCHIP_SERIAL
+	bool "Rockchip on-chip UART support"
+	depends on ARCH_UNIPHIER && DM_SERIAL
+	help
+	  Select this to enable a debug UART for Rockchip devices. This uses
+	  the ns16550 driver. You will need to #define CONFIG_SYS_NS16550 in
+	  your board config header. The clock input is automatically set to
+	  use the oscillator (24MHz).
+
 config SANDBOX_SERIAL
 	bool "Sandbox UART support"
 	depends on SANDBOX && DM
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 1d1f036..869ea7b 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_ZYNQ_SERIAL) += serial_zynq.o
 obj-$(CONFIG_BFIN_SERIAL) += serial_bfin.o
 obj-$(CONFIG_FSL_LPUART) += serial_lpuart.o
 obj-$(CONFIG_MXS_AUART) += mxs_auart.o
+obj-$(CONFIG_ROCKCHIP_SERIAL) += serial_rockchip.o
 obj-$(CONFIG_ARC_SERIAL) += serial_arc.o
 obj-$(CONFIG_TEGRA_SERIAL) += serial_tegra.o
 obj-$(CONFIG_UNIPHIER_SERIAL) += serial_uniphier.o
diff --git a/drivers/serial/serial_rockchip.c b/drivers/serial/serial_rockchip.c
new file mode 100644
index 0000000..0e7bbfc
--- /dev/null
+++ b/drivers/serial/serial_rockchip.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <ns16550.h>
+#include <serial.h>
+#include <asm/arch/clock.h>
+
+static const struct udevice_id rockchip_serial_ids[] = {
+	{ .compatible = "rockchip,rk3288-uart" },
+	{ }
+};
+
+static int rockchip_serial_ofdata_to_platdata(struct udevice *dev)
+{
+	struct ns16550_platdata *plat = dev_get_platdata(dev);
+	int ret;
+
+	ret = ns16550_serial_ofdata_to_platdata(dev);
+	if (ret)
+		return ret;
+
+	/* Do all Rockchip parts use 24MHz? */
+	plat->clock = 24 * 1000000;
+
+	return 0;
+}
+
+U_BOOT_DRIVER(serial_ns16550) = {
+	.name	= "serial_rockchip",
+	.id	= UCLASS_SERIAL,
+	.of_match = rockchip_serial_ids,
+	.ofdata_to_platdata = rockchip_serial_ofdata_to_platdata,
+	.platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
+	.priv_auto_alloc_size = sizeof(struct NS16550),
+	.probe = ns16550_serial_probe,
+	.ops	= &ns16550_serial_ops,
+	.flags	= DM_FLAG_PRE_RELOC,
+};
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 09/41] rockchip: Bring in RK3288 device tree file includes and bindings
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (7 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 08/41] rockchip: Add serial support Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:58   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 10/41] rockchip: rk3288: dts: Make core devices available early Simon Glass
                   ` (31 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

Bring in required device tree files from Linux. Since mainline Linux is
somewhat behind, use the files from the Chromium tree. We can re-sync once
further code is acccepted upstream.

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

Changes in v5: None
Changes in v4: None
Changes in v3:
- Add device tree bindings for CRU and DMC

Changes in v2:
- Tidy up license headers and remove SPL #ifdefs

 arch/arm/dts/rk3288-thermal.dtsi                   |   88 ++
 arch/arm/dts/rk3288.dtsi                           | 1458 ++++++++++++++++++++
 .../clock/rockchip,rk3188-cru.txt                  |   61 +
 .../clock/rockchip,rk3288-cru.txt                  |   61 +
 .../clock/rockchip,rk3288-dmc.txt                  |  155 +++
 doc/device-tree-bindings/clock/rockchip.txt        |   77 ++
 .../pinctrl/rockchip,pinctrl.txt                   |  157 +++
 .../thermal/rockchip-thermal.txt                   |   68 +
 include/dt-bindings/clock/rk3288-cru.h             |  370 +++++
 include/dt-bindings/clock/rockchip,rk808.h         |   11 +
 include/dt-bindings/pinctrl/rockchip.h             |   26 +
 include/dt-bindings/power-domain/rk3288.h          |   11 +
 12 files changed, 2543 insertions(+)
 create mode 100644 arch/arm/dts/rk3288-thermal.dtsi
 create mode 100644 arch/arm/dts/rk3288.dtsi
 create mode 100644 doc/device-tree-bindings/clock/rockchip,rk3188-cru.txt
 create mode 100644 doc/device-tree-bindings/clock/rockchip,rk3288-cru.txt
 create mode 100644 doc/device-tree-bindings/clock/rockchip,rk3288-dmc.txt
 create mode 100644 doc/device-tree-bindings/clock/rockchip.txt
 create mode 100644 doc/device-tree-bindings/pinctrl/rockchip,pinctrl.txt
 create mode 100644 doc/device-tree-bindings/thermal/rockchip-thermal.txt
 create mode 100644 include/dt-bindings/clock/rk3288-cru.h
 create mode 100644 include/dt-bindings/clock/rockchip,rk808.h
 create mode 100644 include/dt-bindings/pinctrl/rockchip.h
 create mode 100644 include/dt-bindings/power-domain/rk3288.h

diff --git a/arch/arm/dts/rk3288-thermal.dtsi b/arch/arm/dts/rk3288-thermal.dtsi
new file mode 100644
index 0000000..59482c1
--- /dev/null
+++ b/arch/arm/dts/rk3288-thermal.dtsi
@@ -0,0 +1,88 @@
+/*
+ * Device Tree Source for RK3288 SoC thermal
+ *
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <dt-bindings/thermal/thermal.h>
+
+reserve_thermal: reserve_thermal {
+	polling-delay-passive = <1000>; /* milliseconds */
+	polling-delay = <5000>; /* milliseconds */
+
+			/* sensor	ID */
+	thermal-sensors = <&tsadc	0>;
+
+};
+
+cpu_thermal: cpu_thermal {
+	polling-delay-passive = <100>; /* milliseconds */
+	polling-delay = <5000>; /* milliseconds */
+
+			/* sensor	ID */
+	thermal-sensors = <&tsadc	1>;
+	linux,hwmon;
+
+	trips {
+		cpu_alert0: cpu_alert0 {
+			temperature = <70000>; /* millicelsius */
+			hysteresis = <2000>; /* millicelsius */
+			type = "passive";
+		};
+		cpu_alert1: cpu_alert1 {
+			temperature = <75000>; /* millicelsius */
+			hysteresis = <2000>; /* millicelsius */
+			type = "passive";
+		};
+		cpu_crit: cpu_crit {
+			temperature = <100000>; /* millicelsius */
+			hysteresis = <2000>; /* millicelsius */
+			type = "critical";
+		};
+	};
+
+	cooling-maps {
+		map0 {
+			trip = <&cpu_alert0>;
+			cooling-device =
+				<&cpu0 THERMAL_NO_LIMIT 6>;
+		};
+		map1 {
+			trip = <&cpu_alert1>;
+			cooling-device =
+				<&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+		};
+	};
+};
+
+gpu_thermal: gpu_thermal {
+	polling-delay-passive = <100>; /* milliseconds */
+	polling-delay = <5000>; /* milliseconds */
+
+			/* sensor	ID */
+	thermal-sensors = <&tsadc	2>;
+	linux,hwmon;
+
+	trips {
+		gpu_alert0: gpu_alert0 {
+			temperature = <80000>; /* millicelsius */
+			hysteresis = <2000>; /* millicelsius */
+			type = "passive";
+		};
+		gpu_crit: gpu_crit {
+			temperature = <100000>; /* millicelsius */
+			hysteresis = <2000>; /* millicelsius */
+			type = "critical";
+		};
+	};
+
+	cooling-maps {
+		map0 {
+			trip = <&gpu_alert0>;
+			cooling-device =
+				<&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+		};
+	};
+};
diff --git a/arch/arm/dts/rk3288.dtsi b/arch/arm/dts/rk3288.dtsi
new file mode 100644
index 0000000..6b5145c
--- /dev/null
+++ b/arch/arm/dts/rk3288.dtsi
@@ -0,0 +1,1458 @@
+/*
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/clock/rk3288-cru.h>
+#include <dt-bindings/power-domain/rk3288.h>
+#include <dt-bindings/thermal/thermal.h>
+#include "skeleton.dtsi"
+
+/ {
+	compatible = "rockchip,rk3288";
+
+	interrupt-parent = <&gic>;
+	aliases {
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
+		i2c4 = &i2c4;
+		i2c5 = &i2c5;
+		mmc0 = &emmc;
+		mmc1 = &sdmmc;
+		mmc2 = &sdio0;
+		mmc3 = &sdio1;
+		mshc0 = &emmc;
+		mshc1 = &sdmmc;
+		mshc2 = &sdio0;
+		mshc3 = &sdio1;
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+		serial4 = &uart4;
+		spi0 = &spi0;
+		spi1 = &spi1;
+		spi2 = &spi2;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		enable-method = "rockchip,rk3066-smp";
+		rockchip,pmu = <&pmu>;
+
+		cpu0: cpu at 500 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a12";
+			reg = <0x500>;
+			operating-points = <
+				/* KHz    uV */
+				1800000 1400000
+				1704000 1350000
+				1608000 1300000
+				1512000 1250000
+				1416000 1200000
+				1200000 1100000
+				1008000 1050000
+				 816000 1000000
+				 696000  950000
+				 600000  900000
+				 408000  900000
+				 216000  900000
+				 126000  900000
+			>;
+			#cooling-cells = <2>; /* min followed by max */
+			clock-latency = <40000>;
+			clocks = <&cru ARMCLK>;
+			resets = <&cru SRST_CORE0>;
+		};
+		cpu at 501 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a12";
+			reg = <0x501>;
+			resets = <&cru SRST_CORE1>;
+		};
+		cpu at 502 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a12";
+			reg = <0x502>;
+			resets = <&cru SRST_CORE2>;
+		};
+		cpu at 503 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a12";
+			reg = <0x503>;
+			resets = <&cru SRST_CORE3>;
+		};
+	};
+
+	amba {
+		compatible = "arm,amba-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		dmac_peri: dma-controller at ff250000 {
+			compatible = "arm,pl330", "arm,primecell";
+			broken-no-flushp;
+			reg = <0xff250000 0x4000>;
+			interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			clocks = <&cru ACLK_DMAC2>;
+			clock-names = "apb_pclk";
+		};
+
+		dmac_bus_ns: dma-controller at ff600000 {
+			compatible = "arm,pl330", "arm,primecell";
+			broken-no-flushp;
+			reg = <0xff600000 0x4000>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			clocks = <&cru ACLK_DMAC1>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		dmac_bus_s: dma-controller at ffb20000 {
+			compatible = "arm,pl330", "arm,primecell";
+			broken-no-flushp;
+			reg = <0xffb20000 0x4000>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			clocks = <&cru ACLK_DMAC1>;
+			clock-names = "apb_pclk";
+		};
+	};
+
+	xin24m: oscillator {
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		clock-output-names = "xin24m";
+		#clock-cells = <0>;
+	};
+
+	timer {
+	        arm,use-physical-timer;
+		compatible = "arm,armv7-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+		clock-frequency = <24000000>;
+		always-on;
+	};
+
+	display-subsystem {
+		compatible = "rockchip,display-subsystem";
+		ports = <&vopl_out>, <&vopb_out>;
+	};
+
+	sdmmc: dwmmc at ff0c0000 {
+		compatible = "rockchip,rk3288-dw-mshc";
+		clock-freq-min-max = <400000 150000000>;
+		clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
+			 <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+		fifo-depth = <0x100>;
+		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+		reg = <0xff0c0000 0x4000>;
+		status = "disabled";
+	};
+
+	sdio0: dwmmc at ff0d0000 {
+		compatible = "rockchip,rk3288-dw-mshc";
+		clock-freq-min-max = <400000 150000000>;
+		clocks = <&cru HCLK_SDIO0>, <&cru SCLK_SDIO0>,
+			 <&cru SCLK_SDIO0_DRV>, <&cru SCLK_SDIO0_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+		fifo-depth = <0x100>;
+		interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+		reg = <0xff0d0000 0x4000>;
+		status = "disabled";
+	};
+
+	sdio1: dwmmc at ff0e0000 {
+		compatible = "rockchip,rk3288-dw-mshc";
+		clock-freq-min-max = <400000 150000000>;
+		clocks = <&cru HCLK_SDIO1>, <&cru SCLK_SDIO1>,
+			 <&cru SCLK_SDIO1_DRV>, <&cru SCLK_SDIO1_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+		fifo-depth = <0x100>;
+		interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+		reg = <0xff0e0000 0x4000>;
+		status = "disabled";
+	};
+
+	emmc: dwmmc at ff0f0000 {
+		compatible = "rockchip,rk3288-dw-mshc";
+		clock-freq-min-max = <400000 150000000>;
+		clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
+			 <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+		fifo-depth = <0x100>;
+		interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+		reg = <0xff0f0000 0x4000>;
+		status = "disabled";
+	};
+
+	saradc: saradc at ff100000 {
+		compatible = "rockchip,saradc";
+		reg = <0xff100000 0x100>;
+		interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+		#io-channel-cells = <1>;
+		clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
+		clock-names = "saradc", "apb_pclk";
+		status = "disabled";
+	};
+
+	spi0: spi at ff110000 {
+		compatible = "rockchip,rk3288-spi", "rockchip,rk3066-spi";
+		clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>;
+		clock-names = "spiclk", "apb_pclk";
+		dmas = <&dmac_peri 11>, <&dmac_peri 12>;
+		dma-names = "tx", "rx";
+		interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0>;
+		reg = <0xff110000 0x1000>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi1: spi at ff120000 {
+		compatible = "rockchip,rk3288-spi", "rockchip,rk3066-spi";
+		clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>;
+		clock-names = "spiclk", "apb_pclk";
+		dmas = <&dmac_peri 13>, <&dmac_peri 14>;
+		dma-names = "tx", "rx";
+		interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&spi1_clk &spi1_tx &spi1_rx &spi1_cs0>;
+		reg = <0xff120000 0x1000>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi2: spi at ff130000 {
+		compatible = "rockchip,rk3288-spi", "rockchip,rk3066-spi";
+		clocks = <&cru SCLK_SPI2>, <&cru PCLK_SPI2>;
+		clock-names = "spiclk", "apb_pclk";
+		dmas = <&dmac_peri 15>, <&dmac_peri 16>;
+		dma-names = "tx", "rx";
+		interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&spi2_clk &spi2_tx &spi2_rx &spi2_cs0>;
+		reg = <0xff130000 0x1000>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c1: i2c at ff140000 {
+		compatible = "rockchip,rk3288-i2c";
+		reg = <0xff140000 0x1000>;
+		interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clock-names = "i2c";
+		clocks = <&cru PCLK_I2C1>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c1_xfer>;
+		status = "disabled";
+	};
+
+	i2c3: i2c at ff150000 {
+		compatible = "rockchip,rk3288-i2c";
+		reg = <0xff150000 0x1000>;
+		interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clock-names = "i2c";
+		clocks = <&cru PCLK_I2C3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c3_xfer>;
+		status = "disabled";
+	};
+
+	i2c4: i2c at ff160000 {
+		compatible = "rockchip,rk3288-i2c";
+		reg = <0xff160000 0x1000>;
+		interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clock-names = "i2c";
+		clocks = <&cru PCLK_I2C4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c4_xfer>;
+		status = "disabled";
+	};
+
+	i2c5: i2c at ff170000 {
+		compatible = "rockchip,rk3288-i2c";
+		reg = <0xff170000 0x1000>;
+		interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clock-names = "i2c";
+		clocks = <&cru PCLK_I2C5>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c5_xfer>;
+		status = "disabled";
+	};
+	uart0: serial at ff180000 {
+		compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart";
+		reg = <0xff180000 0x100>;
+		interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+		clock-names = "baudclk", "apb_pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart0_xfer>;
+		status = "disabled";
+	};
+
+	uart1: serial at ff190000 {
+		compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart";
+		reg = <0xff190000 0x100>;
+		interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+		clock-names = "baudclk", "apb_pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart1_xfer>;
+		status = "disabled";
+	};
+
+	uart2: serial at ff690000 {
+		compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart";
+		reg = <0xff690000 0x100>;
+		interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+		clock-names = "baudclk", "apb_pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart2_xfer>;
+		status = "disabled";
+	};
+	uart3: serial at ff1b0000 {
+		compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart";
+		reg = <0xff1b0000 0x100>;
+		interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
+		clock-names = "baudclk", "apb_pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart3_xfer>;
+		status = "disabled";
+	};
+
+	uart4: serial at ff1c0000 {
+		compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart";
+		reg = <0xff1c0000 0x100>;
+		interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>;
+		clock-names = "baudclk", "apb_pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart4_xfer>;
+		status = "disabled";
+	};
+	thermal: thermal-zones {
+		#include "rk3288-thermal.dtsi"
+	};
+
+	tsadc: tsadc at ff280000 {
+		compatible = "rockchip,rk3288-tsadc";
+		reg = <0xff280000 0x100>;
+		interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>;
+		clock-names = "tsadc", "apb_pclk";
+		resets = <&cru SRST_TSADC>;
+		reset-names = "tsadc-apb";
+		pinctrl-names = "otp_out";
+		pinctrl-0 = <&otp_out>;
+		#thermal-sensor-cells = <1>;
+		hw-shut-temp = <125000>;
+		status = "disabled";
+	};
+
+	gmac: ethernet at ff290000 {
+		compatible = "rockchip,rk3288-gmac";
+		reg = <0xff290000 0x10000>;
+		interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "macirq";
+		rockchip,grf = <&grf>;
+		clocks = <&cru SCLK_MAC>,
+			<&cru SCLK_MAC_RX>, <&cru SCLK_MAC_TX>,
+			<&cru SCLK_MACREF>, <&cru SCLK_MACREF_OUT>,
+			<&cru ACLK_GMAC>, <&cru PCLK_GMAC>;
+		clock-names = "stmmaceth",
+			"mac_clk_rx", "mac_clk_tx",
+			"clk_mac_ref", "clk_mac_refout",
+			"aclk_mac", "pclk_mac";
+	};
+
+	usb_host0_ehci: usb at ff500000 {
+		compatible = "generic-ehci";
+		reg = <0xff500000 0x100>;
+		interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_USBHOST0>;
+		clock-names = "usbhost";
+		phys = <&usbphy1>;
+		phy-names = "usb";
+		status = "disabled";
+	};
+
+	/* NOTE: ohci at ff520000 doesn't actually work on hardware */
+
+	usb_host1: usb at ff540000 {
+		compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb",
+				"snps,dwc2";
+		reg = <0xff540000 0x40000>;
+		interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_USBHOST1>;
+		clock-names = "otg";
+		phys = <&usbphy2>;
+		phy-names = "usb2-phy";
+		status = "disabled";
+	};
+
+	usb_otg: usb at ff580000 {
+		compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb",
+				"snps,dwc2";
+		reg = <0xff580000 0x40000>;
+		interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_OTG0>;
+		clock-names = "otg";
+		phys = <&usbphy0>;
+		phy-names = "usb2-phy";
+		status = "disabled";
+	};
+
+	usb_hsic: usb at ff5c0000 {
+		compatible = "generic-ehci";
+		reg = <0xff5c0000 0x100>;
+		interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_HSIC>;
+		clock-names = "usbhost";
+		status = "disabled";
+	};
+
+	dmc: dmc at ff610000 {
+		compatible = "rockchip,rk3288-dmc", "syscon";
+		rockchip,cru = <&cru>;
+		rockchip,grf = <&grf>;
+		rockchip,pmu = <&pmu>;
+		rockchip,sgrf = <&sgrf>;
+		rockchip,noc = <&noc>;
+		reg = <0xff610000 0x3fc
+		       0xff620000 0x294
+		       0xff630000 0x3fc
+		       0xff640000 0x294>;
+		rockchip,sram = <&ddr_sram>;
+		clocks = <&cru PCLK_DDRUPCTL0>, <&cru PCLK_PUBL0>,
+			 <&cru PCLK_DDRUPCTL1>, <&cru PCLK_PUBL1>,
+			 <&cru ARMCLK>;
+		clock-names = "pclk_ddrupctl0", "pclk_publ0",
+			      "pclk_ddrupctl1", "pclk_publ1",
+			      "arm_clk";
+	};
+
+	i2c0: i2c at ff650000 {
+		compatible = "rockchip,rk3288-i2c";
+		reg = <0xff650000 0x1000>;
+		interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clock-names = "i2c";
+		clocks = <&cru PCLK_I2C0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c0_xfer>;
+		status = "disabled";
+	};
+
+	i2c2: i2c at ff660000 {
+		compatible = "rockchip,rk3288-i2c";
+		reg = <0xff660000 0x1000>;
+		interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clock-names = "i2c";
+		clocks = <&cru PCLK_I2C2>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c2_xfer>;
+		status = "disabled";
+	};
+
+	pwm0: pwm at ff680000 {
+		compatible = "rockchip,rk3288-pwm";
+		reg = <0xff680000 0x10>;
+		#pwm-cells = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm0_pin>;
+		clocks = <&cru PCLK_PWM>;
+		clock-names = "pwm";
+		rockchip,grf = <&grf>;
+		status = "disabled";
+	};
+
+	pwm1: pwm at ff680010 {
+		compatible = "rockchip,rk3288-pwm";
+		reg = <0xff680010 0x10>;
+		#pwm-cells = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm1_pin>;
+		clocks = <&cru PCLK_PWM>;
+		clock-names = "pwm";
+		rockchip,grf = <&grf>;
+		status = "disabled";
+	};
+
+	pwm2: pwm at ff680020 {
+		compatible = "rockchip,rk3288-pwm";
+		reg = <0xff680020 0x10>;
+		#pwm-cells = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm2_pin>;
+		clocks = <&cru PCLK_PWM>;
+		clock-names = "pwm";
+		rockchip,grf = <&grf>;
+		status = "disabled";
+	};
+
+	pwm3: pwm at ff680030 {
+		compatible = "rockchip,rk3288-pwm";
+		reg = <0xff680030 0x10>;
+		#pwm-cells = <2>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm3_pin>;
+		clocks = <&cru PCLK_PWM>;
+		clock-names = "pwm";
+		rockchip,grf = <&grf>;
+		status = "disabled";
+	};
+
+	bus_intmem at ff700000 {
+		compatible = "mmio-sram";
+		reg = <0xff700000 0x18000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0xff700000 0x18000>;
+		smp-sram at 0 {
+			compatible = "rockchip,rk3066-smp-sram";
+			reg = <0x00 0x10>;
+		};
+		ddr_sram: ddr-sram at 1000 {
+			compatible = "rockchip,rk3288-ddr-sram";
+			reg = <0x1000 0x4000>;
+		};
+	};
+
+	sram at ff720000 {
+		compatible = "rockchip,rk3288-pmu-sram", "mmio-sram";
+		reg = <0xff720000 0x1000>;
+	};
+
+	pmu: power-management at ff730000 {
+		compatible = "rockchip,rk3288-pmu", "syscon";
+		reg = <0xff730000 0x100>;
+	};
+
+	sgrf: syscon at ff740000 {
+		compatible = "rockchip,rk3288-sgrf", "syscon";
+		reg = <0xff740000 0x1000>;
+	};
+
+	cru: clock-controller at ff760000 {
+		compatible = "rockchip,rk3288-cru";
+		reg = <0xff760000 0x1000>;
+		rockchip,grf = <&grf>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+		assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>,
+				  <&cru PLL_GPLL>, <&cru PLL_CPLL>,
+				  <&cru PLL_NPLL>, <&cru ACLK_CPU>,
+				  <&cru HCLK_CPU>, <&cru PCLK_CPU>,
+				  <&cru ACLK_PERI>, <&cru HCLK_PERI>,
+				  <&cru PCLK_PERI>;
+		assigned-clock-rates = <0>, <0>,
+				       <594000000>, <400000000>,
+				       <500000000>, <300000000>,
+				       <150000000>, <75000000>,
+				       <300000000>, <150000000>,
+				       <75000000>;
+		assigned-clock-parents = <&cru PLL_NPLL>, <&cru PLL_GPLL>;
+	};
+
+	grf: syscon at ff770000 {
+		compatible = "rockchip,rk3288-grf", "syscon";
+		reg = <0xff770000 0x1000>;
+	};
+
+	wdt: watchdog at ff800000 {
+		compatible = "rockchip,rk3288-wdt", "snps,dw-wdt";
+		reg = <0xff800000 0x100>;
+		clocks = <&cru PCLK_WDT>;
+		interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+	};
+
+	i2s: i2s at ff890000 {
+		compatible = "rockchip,rk3288-i2s", "rockchip,rk3066-i2s";
+		reg = <0xff890000 0x10000>;
+		interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		dmas = <&dmac_bus_s 0>, <&dmac_bus_s 1>;
+		dma-names = "tx", "rx";
+		clock-names = "i2s_hclk", "i2s_clk";
+		clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2s0_bus>;
+		status = "disabled";
+	};
+
+	vopb: vop at ff930000 {
+		compatible = "rockchip,rk3288-vop";
+		reg = <0xff930000 0x19c>;
+		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_VOP0>, <&cru DCLK_VOP0>, <&cru HCLK_VOP0>;
+		clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+		resets = <&cru SRST_LCDC0_AXI>, <&cru SRST_LCDC0_AHB>, <&cru SRST_LCDC0_DCLK>;
+		reset-names = "axi", "ahb", "dclk";
+		iommus = <&vopb_mmu>;
+		power-domains = <&power RK3288_PD_VIO>;
+		status = "disabled";
+		vopb_out: port {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			vopb_out_edp: endpoint at 0 {
+				reg = <0>;
+				remote-endpoint = <&edp_in_vopb>;
+			};
+			vopb_out_hdmi: endpoint at 1 {
+				reg = <1>;
+				remote-endpoint = <&hdmi_in_vopb>;
+			};
+		};
+	};
+
+	vopb_mmu: iommu at ff930300 {
+		compatible = "rockchip,iommu";
+		reg = <0xff930300 0x100>;
+		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "vopb_mmu";
+		power-domains = <&power RK3288_PD_VIO>;
+		#iommu-cells = <0>;
+		status = "disabled";
+	};
+
+	vopl: vop at ff940000 {
+		compatible = "rockchip,rk3288-vop";
+		reg = <0xff940000 0x19c>;
+		interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_VOP1>, <&cru DCLK_VOP1>, <&cru HCLK_VOP1>;
+		clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+		resets = <&cru SRST_LCDC1_AXI>, <&cru SRST_LCDC1_AHB>, <&cru SRST_LCDC1_DCLK>;
+		reset-names = "axi", "ahb", "dclk";
+		iommus = <&vopl_mmu>;
+		power-domains = <&power RK3288_PD_VIO>;
+		status = "disabled";
+		vopl_out: port {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			vopl_out_edp: endpoint at 0 {
+				reg = <0>;
+				remote-endpoint = <&edp_in_vopl>;
+			};
+			vopl_out_hdmi: endpoint at 1 {
+				reg = <1>;
+				remote-endpoint = <&hdmi_in_vopl>;
+			};
+
+		};
+	};
+
+	vopl_mmu: iommu at ff940300 {
+		compatible = "rockchip,iommu";
+		reg = <0xff940300 0x100>;
+		interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "vopl_mmu";
+		power-domains = <&power RK3288_PD_VIO>;
+		#iommu-cells = <0>;
+		status = "disabled";
+	};
+
+	edp: edp at ff970000 {
+		compatible = "rockchip,rk3288-edp";
+		reg = <0xff970000 0x4000>;
+		interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_EDP>, <&cru SCLK_EDP_24M>, <&cru PCLK_EDP_CTRL>;
+		rockchip,grf = <&grf>;
+		clock-names = "clk_edp", "clk_edp_24m", "pclk_edp";
+		resets = <&cru 111>;
+		reset-names = "edp";
+		power-domains = <&power RK3288_PD_VIO>;
+		status = "disabled";
+		ports {
+			edp_in: port {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				edp_in_vopb: endpoint at 0 {
+					reg = <0>;
+					remote-endpoint = <&vopb_out_edp>;
+				};
+				edp_in_vopl: endpoint at 1 {
+					reg = <1>;
+					remote-endpoint = <&vopl_out_edp>;
+				};
+			};
+		};
+	};
+
+	hdmi: hdmi at ff980000 {
+		compatible = "rockchip,rk3288-dw-hdmi";
+		reg = <0xff980000 0x20000>;
+		reg-io-width = <4>;
+		ddc-i2c-bus = <&i2c5>;
+		rockchip,grf = <&grf>;
+		interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru  PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>;
+		clock-names = "iahb", "isfr";
+		status = "disabled";
+		ports {
+			hdmi_in: port {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				hdmi_in_vopb: endpoint at 0 {
+					reg = <0>;
+					remote-endpoint = <&vopb_out_hdmi>;
+				};
+				hdmi_in_vopl: endpoint at 1 {
+					reg = <1>;
+					remote-endpoint = <&vopl_out_hdmi>;
+				};
+			};
+		};
+	};
+
+	hdmi_audio: hdmi_audio {
+		compatible = "rockchip,rk3288-hdmi-audio";
+		i2s-controller = <&i2s>;
+		status = "disable";
+	};
+
+	vpu: video-codec at ff9a0000 {
+		compatible = "rockchip,rk3288-vpu";
+		reg = <0xff9a0000 0x800>;
+		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "vepu", "vdpu";
+		clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
+		clock-names = "aclk_vcodec", "hclk_vcodec";
+		power-domains = <&power RK3288_PD_VIDEO>;
+		iommus = <&vpu_mmu>;
+	};
+
+	vpu_mmu: iommu at ff9a0800 {
+		compatible = "rockchip,iommu";
+		reg = <0xff9a0800 0x100>;
+		interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "vpu_mmu";
+		power-domains = <&power RK3288_PD_VIDEO>;
+		#iommu-cells = <0>;
+	};
+
+	gpu: gpu at ffa30000 {
+		compatible = "arm,malit764",
+			     "arm,malit76x",
+			     "arm,malit7xx",
+			     "arm,mali-midgard";
+		reg = <0xffa30000 0x10000>;
+		interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "JOB", "MMU", "GPU";
+		clocks = <&cru ACLK_GPU>;
+		clock-names = "aclk_gpu";
+		operating-points = <
+			/* KHz uV */
+			100000 950000
+			200000 950000
+			300000 1000000
+			400000 1100000
+			/* 500000 1200000 - See crosbug.com/p/33857 */
+			600000 1250000
+		>;
+		power-domains = <&power RK3288_PD_GPU>;
+		status = "disabled";
+	};
+
+	noc: syscon at ffac0000 {
+		compatible = "rockchip,rk3288-noc", "syscon";
+		reg = <0xffac0000 0x2000>;
+	};
+
+	efuse: efuse at ffb40000 {
+		compatible = "rockchip,rk3288-efuse";
+		reg = <0xffb40000 0x10000>;
+		status = "disabled";
+	};
+
+	gic: interrupt-controller at ffc01000 {
+		compatible = "arm,gic-400";
+		interrupt-controller;
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+
+		reg = <0xffc01000 0x1000>,
+		      <0xffc02000 0x1000>,
+		      <0xffc04000 0x2000>,
+		      <0xffc06000 0x2000>;
+		interrupts = <GIC_PPI 9 0xf04>;
+	};
+
+	cpuidle: cpuidle {
+		compatible = "rockchip,rk3288-cpuidle";
+	};
+
+	usbphy: phy {
+		compatible = "rockchip,rk3288-usb-phy";
+		rockchip,grf = <&grf>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+
+		usbphy0: usb-phy0 {
+			#phy-cells = <0>;
+			reg = <0x320>;
+			clocks = <&cru SCLK_OTGPHY0>;
+			clock-names = "phyclk";
+		};
+
+		usbphy1: usb-phy1 {
+			#phy-cells = <0>;
+			reg = <0x334>;
+			clocks = <&cru SCLK_OTGPHY1>;
+			clock-names = "phyclk";
+		};
+
+		usbphy2: usb-phy2 {
+			#phy-cells = <0>;
+			reg = <0x348>;
+			clocks = <&cru SCLK_OTGPHY2>;
+			clock-names = "phyclk";
+		};
+	};
+
+	pinctrl: pinctrl {
+		compatible = "rockchip,rk3288-pinctrl";
+		rockchip,grf = <&grf>;
+		rockchip,pmu = <&pmu>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		gpio0: gpio0 at ff750000 {
+			compatible = "rockchip,gpio-bank";
+			reg =	<0xff750000 0x100>;
+			interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO0>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio1: gpio1 at ff780000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0xff780000 0x100>;
+			interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO1>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio2: gpio2 at ff790000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0xff790000 0x100>;
+			interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO2>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio3: gpio3 at ff7a0000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0xff7a0000 0x100>;
+			interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO3>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio4: gpio4 at ff7b0000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0xff7b0000 0x100>;
+			interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO4>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio5: gpio5 at ff7c0000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0xff7c0000 0x100>;
+			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO5>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio6: gpio6 at ff7d0000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0xff7d0000 0x100>;
+			interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO6>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio7: gpio7 at ff7e0000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0xff7e0000 0x100>;
+			interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO7>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio8: gpio8 at ff7f0000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0xff7f0000 0x100>;
+			interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO8>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		pcfg_pull_up: pcfg-pull-up {
+			bias-pull-up;
+		};
+
+		pcfg_pull_down: pcfg-pull-down {
+			bias-pull-down;
+		};
+
+		pcfg_pull_none: pcfg-pull-none {
+			bias-disable;
+		};
+
+		pcfg_pull_none_12ma: pcfg-pull-none-12ma {
+			bias-disable;
+			drive-strength = <12>;
+		};
+
+		sleep {
+			global_pwroff: global-pwroff {
+				rockchip,pins = <0 0 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			ddrio_pwroff: ddrio-pwroff {
+				rockchip,pins = <0 1 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			ddr0_retention: ddr0-retention {
+				rockchip,pins = <0 2 RK_FUNC_1 &pcfg_pull_up>;
+			};
+
+			ddr1_retention: ddr1-retention {
+				rockchip,pins = <0 3 RK_FUNC_1 &pcfg_pull_up>;
+			};
+		};
+
+		i2c0 {
+			i2c0_xfer: i2c0-xfer {
+				rockchip,pins = <0 15 RK_FUNC_1 &pcfg_pull_none>,
+						<0 16 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		i2c1 {
+			i2c1_xfer: i2c1-xfer {
+				rockchip,pins = <8 4 RK_FUNC_1 &pcfg_pull_none>,
+						<8 5 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		i2c2 {
+			i2c2_xfer: i2c2-xfer {
+				rockchip,pins = <6 9 RK_FUNC_1 &pcfg_pull_none>,
+						<6 10 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		i2c3 {
+			i2c3_xfer: i2c3-xfer {
+				rockchip,pins = <2 16 RK_FUNC_1 &pcfg_pull_none>,
+						<2 17 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		i2c4 {
+			i2c4_xfer: i2c4-xfer {
+				rockchip,pins = <7 17 RK_FUNC_1 &pcfg_pull_none>,
+						<7 18 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		i2c5 {
+			i2c5_xfer: i2c5-xfer {
+				rockchip,pins = <7 19 RK_FUNC_1 &pcfg_pull_none>,
+						<7 20 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		i2s0 {
+			i2s0_bus: i2s0-bus {
+				rockchip,pins = <6 0 RK_FUNC_1 &pcfg_pull_none>,
+						<6 1 RK_FUNC_1 &pcfg_pull_none>,
+						<6 2 RK_FUNC_1 &pcfg_pull_none>,
+						<6 3 RK_FUNC_1 &pcfg_pull_none>,
+						<6 4 RK_FUNC_1 &pcfg_pull_none>,
+						<6 8 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		sdmmc {
+			sdmmc_clk: sdmmc-clk {
+				rockchip,pins = <6 20 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			sdmmc_cmd: sdmmc-cmd {
+				rockchip,pins = <6 21 RK_FUNC_1 &pcfg_pull_up>;
+			};
+
+			sdmmc_cd: sdmcc-cd {
+				rockchip,pins = <6 22 RK_FUNC_1 &pcfg_pull_up>;
+			};
+
+			sdmmc_bus1: sdmmc-bus1 {
+				rockchip,pins = <6 16 RK_FUNC_1 &pcfg_pull_up>;
+			};
+
+			sdmmc_bus4: sdmmc-bus4 {
+				rockchip,pins = <6 16 RK_FUNC_1 &pcfg_pull_up>,
+						<6 17 RK_FUNC_1 &pcfg_pull_up>,
+						<6 18 RK_FUNC_1 &pcfg_pull_up>,
+						<6 19 RK_FUNC_1 &pcfg_pull_up>;
+			};
+		};
+
+		sdio0 {
+			sdio0_bus1: sdio0-bus1 {
+				rockchip,pins = <4 20 RK_FUNC_1 &pcfg_pull_up>;
+			};
+
+			sdio0_bus4: sdio0-bus4 {
+				rockchip,pins = <4 20 RK_FUNC_1 &pcfg_pull_up>,
+						<4 21 RK_FUNC_1 &pcfg_pull_up>,
+						<4 22 RK_FUNC_1 &pcfg_pull_up>,
+						<4 23 RK_FUNC_1 &pcfg_pull_up>;
+			};
+
+			sdio0_cmd: sdio0-cmd {
+				rockchip,pins = <4 24 RK_FUNC_1 &pcfg_pull_up>;
+			};
+
+			sdio0_clk: sdio0-clk {
+				rockchip,pins = <4 25 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			sdio0_cd: sdio0-cd {
+				rockchip,pins = <4 26 RK_FUNC_1 &pcfg_pull_up>;
+			};
+
+			sdio0_wp: sdio0-wp {
+				rockchip,pins = <4 27 RK_FUNC_1 &pcfg_pull_up>;
+			};
+
+			sdio0_pwr: sdio0-pwr {
+				rockchip,pins = <4 28 RK_FUNC_1 &pcfg_pull_up>;
+			};
+
+			sdio0_bkpwr: sdio0-bkpwr {
+				rockchip,pins = <4 29 RK_FUNC_1 &pcfg_pull_up>;
+			};
+
+			sdio0_int: sdio0-int {
+				rockchip,pins = <4 30 RK_FUNC_1 &pcfg_pull_up>;
+			};
+		};
+
+		sdio1 {
+			sdio1_bus1: sdio1-bus1 {
+				rockchip,pins = <3 24 RK_FUNC_4 &pcfg_pull_up>;
+			};
+
+			sdio1_bus4: sdio1-bus4 {
+				rockchip,pins = <3 24 RK_FUNC_4 &pcfg_pull_up>,
+						<3 25 RK_FUNC_4 &pcfg_pull_up>,
+						<3 26 RK_FUNC_4 &pcfg_pull_up>,
+						<3 27 RK_FUNC_4 &pcfg_pull_up>;
+			};
+
+			sdio1_cd: sdio1-cd {
+				rockchip,pins = <3 28 RK_FUNC_4 &pcfg_pull_up>;
+			};
+
+			sdio1_wp: sdio1-wp {
+				rockchip,pins = <3 29 RK_FUNC_4 &pcfg_pull_up>;
+			};
+
+			sdio1_bkpwr: sdio1-bkpwr {
+				rockchip,pins = <3 30 RK_FUNC_4 &pcfg_pull_up>;
+			};
+
+			sdio1_int: sdio1-int {
+				rockchip,pins = <3 31 RK_FUNC_4 &pcfg_pull_up>;
+			};
+
+			sdio1_cmd: sdio1-cmd {
+				rockchip,pins = <4 6 RK_FUNC_4 &pcfg_pull_up>;
+			};
+
+			sdio1_clk: sdio1-clk {
+				rockchip,pins = <4 7 RK_FUNC_4 &pcfg_pull_none>;
+			};
+
+			sdio1_pwr: sdio1-pwr {
+				rockchip,pins = <4 9 RK_FUNC_4 &pcfg_pull_up>;
+			};
+		};
+
+		emmc {
+			emmc_clk: emmc-clk {
+				rockchip,pins = <3 18 RK_FUNC_2 &pcfg_pull_none>;
+			};
+
+			emmc_cmd: emmc-cmd {
+				rockchip,pins = <3 16 RK_FUNC_2 &pcfg_pull_up>;
+			};
+
+			emmc_pwr: emmc-pwr {
+				rockchip,pins = <3 9 RK_FUNC_2 &pcfg_pull_up>;
+			};
+
+			emmc_bus1: emmc-bus1 {
+				rockchip,pins = <3 0 RK_FUNC_2 &pcfg_pull_up>;
+			};
+
+			emmc_bus4: emmc-bus4 {
+				rockchip,pins = <3 0 RK_FUNC_2 &pcfg_pull_up>,
+						<3 1 RK_FUNC_2 &pcfg_pull_up>,
+						<3 2 RK_FUNC_2 &pcfg_pull_up>,
+						<3 3 RK_FUNC_2 &pcfg_pull_up>;
+			};
+
+			emmc_bus8: emmc-bus8 {
+				rockchip,pins = <3 0 RK_FUNC_2 &pcfg_pull_up>,
+						<3 1 RK_FUNC_2 &pcfg_pull_up>,
+						<3 2 RK_FUNC_2 &pcfg_pull_up>,
+						<3 3 RK_FUNC_2 &pcfg_pull_up>,
+						<3 4 RK_FUNC_2 &pcfg_pull_up>,
+						<3 5 RK_FUNC_2 &pcfg_pull_up>,
+						<3 6 RK_FUNC_2 &pcfg_pull_up>,
+						<3 7 RK_FUNC_2 &pcfg_pull_up>;
+			};
+		};
+
+		spi0 {
+			spi0_clk: spi0-clk {
+				rockchip,pins = <5 12 RK_FUNC_1 &pcfg_pull_up>;
+			};
+			spi0_cs0: spi0-cs0 {
+				rockchip,pins = <5 13 RK_FUNC_1 &pcfg_pull_up>;
+			};
+			spi0_tx: spi0-tx {
+				rockchip,pins = <5 14 RK_FUNC_1 &pcfg_pull_up>;
+			};
+			spi0_rx: spi0-rx {
+				rockchip,pins = <5 15 RK_FUNC_1 &pcfg_pull_up>;
+			};
+			spi0_cs1: spi0-cs1 {
+				rockchip,pins = <5 16 RK_FUNC_1 &pcfg_pull_up>;
+			};
+		};
+		spi1 {
+			spi1_clk: spi1-clk {
+				rockchip,pins = <7 12 RK_FUNC_2 &pcfg_pull_up>;
+			};
+			spi1_cs0: spi1-cs0 {
+				rockchip,pins = <7 13 RK_FUNC_2 &pcfg_pull_up>;
+			};
+			spi1_rx: spi1-rx {
+				rockchip,pins = <7 14 RK_FUNC_2 &pcfg_pull_up>;
+			};
+			spi1_tx: spi1-tx {
+				rockchip,pins = <7 15 RK_FUNC_2 &pcfg_pull_up>;
+			};
+		};
+
+		spi2 {
+			spi2_cs1: spi2-cs1 {
+				rockchip,pins = <8 3 RK_FUNC_1 &pcfg_pull_up>;
+			};
+			spi2_clk: spi2-clk {
+				rockchip,pins = <8 6 RK_FUNC_1 &pcfg_pull_up>;
+			};
+			spi2_cs0: spi2-cs0 {
+				rockchip,pins = <8 7 RK_FUNC_1 &pcfg_pull_up>;
+			};
+			spi2_rx: spi2-rx {
+				rockchip,pins = <8 8 RK_FUNC_1 &pcfg_pull_up>;
+			};
+			spi2_tx: spi2-tx {
+				rockchip,pins = <8 9 RK_FUNC_1 &pcfg_pull_up>;
+			};
+		};
+
+		uart0 {
+			uart0_xfer: uart0-xfer {
+				rockchip,pins = <4 16 RK_FUNC_1 &pcfg_pull_up>,
+						<4 17 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart0_cts: uart0-cts {
+				rockchip,pins = <4 18 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart0_rts: uart0-rts {
+				rockchip,pins = <4 19 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		uart1 {
+			uart1_xfer: uart1-xfer {
+				rockchip,pins = <5 8 RK_FUNC_1 &pcfg_pull_up>,
+						<5 9 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart1_cts: uart1-cts {
+				rockchip,pins = <5 10 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart1_rts: uart1-rts {
+				rockchip,pins = <5 11 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		uart2 {
+			uart2_xfer: uart2-xfer {
+				rockchip,pins = <7 22 RK_FUNC_1 &pcfg_pull_up>,
+						<7 23 RK_FUNC_1 &pcfg_pull_none>;
+			};
+			/* no rts / cts for uart2 */
+		};
+
+		uart3 {
+			uart3_xfer: uart3-xfer {
+				rockchip,pins = <7 7 RK_FUNC_1 &pcfg_pull_up>,
+						<7 8 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart3_cts: uart3-cts {
+				rockchip,pins = <7 9 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart3_rts: uart3-rts {
+				rockchip,pins = <7 10 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		uart4 {
+			uart4_xfer: uart4-xfer {
+				rockchip,pins = <5 12 3 &pcfg_pull_up>,
+						<5 13 3 &pcfg_pull_none>;
+			};
+
+			uart4_cts: uart4-cts {
+				rockchip,pins = <5 14 3 &pcfg_pull_none>;
+			};
+
+			uart4_rts: uart4-rts {
+				rockchip,pins = <5 15 3 &pcfg_pull_none>;
+			};
+		};
+
+		tsadc {
+			otp_out: otp-out {
+				rockchip,pins = <0 10 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		pwm0 {
+			pwm0_pin: pwm0-pin {
+				rockchip,pins = <7 0 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		pwm1 {
+			pwm1_pin: pwm1-pin {
+				rockchip,pins = <7 1 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		pwm2 {
+			pwm2_pin: pwm2-pin {
+				rockchip,pins = <7 22 RK_FUNC_3 &pcfg_pull_none>;
+			};
+		};
+
+		pwm3 {
+			pwm3_pin: pwm3-pin {
+				rockchip,pins = <7 23 RK_FUNC_3 &pcfg_pull_none>;
+			};
+		};
+
+		gmac {
+			rgmii_pins: rgmii-pins {
+				rockchip,pins = <3 30 3 &pcfg_pull_none>,
+						<3 31 3 &pcfg_pull_none>,
+						<3 26 3 &pcfg_pull_none>,
+						<3 27 3 &pcfg_pull_none>,
+						<3 28 3 &pcfg_pull_none_12ma>,
+						<3 29 3 &pcfg_pull_none_12ma>,
+						<3 24 3 &pcfg_pull_none_12ma>,
+						<3 25 3 &pcfg_pull_none_12ma>,
+						<4 0 3 &pcfg_pull_none>,
+						<4 5 3 &pcfg_pull_none>,
+						<4 6 3 &pcfg_pull_none>,
+						<4 9 3 &pcfg_pull_none_12ma>,
+						<4 4 3 &pcfg_pull_none_12ma>,
+						<4 1 3 &pcfg_pull_none>,
+						<4 3 3 &pcfg_pull_none>;
+			};
+
+			rmii_pins: rmii-pins {
+				rockchip,pins = <3 30 3 &pcfg_pull_none>,
+						<3 31 3 &pcfg_pull_none>,
+						<3 28 3 &pcfg_pull_none>,
+						<3 29 3 &pcfg_pull_none>,
+						<4 0 3 &pcfg_pull_none>,
+						<4 5 3 &pcfg_pull_none>,
+						<4 4 3 &pcfg_pull_none>,
+						<4 1 3 &pcfg_pull_none>,
+						<4 2 3 &pcfg_pull_none>,
+						<4 3 3 &pcfg_pull_none>;
+			};
+		};
+	};
+
+	power: power-controller {
+		compatible = "rockchip,rk3288-power-controller";
+		#power-domain-cells = <1>;
+		rockchip,pmu = <&pmu>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pd_gpu {
+			reg = <RK3288_PD_GPU>;
+			clocks = <&cru ACLK_GPU>;
+		};
+
+		pd_hevc {
+			reg = <RK3288_PD_HEVC>;
+			clocks = <&cru ACLK_HEVC>,
+				 <&cru SCLK_HEVC_CABAC>,
+				 <&cru SCLK_HEVC_CORE>,
+				 <&cru HCLK_HEVC>;
+		};
+
+		pd_vio {
+			reg = <RK3288_PD_VIO>;
+			clocks = <&cru ACLK_IEP>,
+				 <&cru ACLK_ISP>,
+				 <&cru ACLK_RGA>,
+				 <&cru ACLK_VIP>,
+				 <&cru ACLK_VOP0>,
+				 <&cru ACLK_VOP1>,
+				 <&cru DCLK_VOP0>,
+				 <&cru DCLK_VOP1>,
+				 <&cru HCLK_IEP>,
+				 <&cru HCLK_ISP>,
+				 <&cru HCLK_RGA>,
+				 <&cru HCLK_VIP>,
+				 <&cru HCLK_VOP0>,
+				 <&cru HCLK_VOP1>,
+				 <&cru PCLK_EDP_CTRL>,
+				 <&cru PCLK_HDMI_CTRL>,
+				 <&cru PCLK_LVDS_PHY>,
+				 <&cru PCLK_MIPI_CSI>,
+				 <&cru PCLK_MIPI_DSI0>,
+				 <&cru PCLK_MIPI_DSI1>,
+				 <&cru SCLK_EDP_24M>,
+				 <&cru SCLK_EDP>,
+				 <&cru SCLK_HDMI_CEC>,
+				 <&cru SCLK_HDMI_HDCP>,
+				 <&cru SCLK_ISP_JPE>,
+				 <&cru SCLK_ISP>,
+				 <&cru SCLK_RGA>;
+		};
+
+		pd_video {
+			reg = <RK3288_PD_VIDEO>;
+			clocks = <&cru ACLK_VCODEC>,
+				 <&cru HCLK_VCODEC>;
+		};
+	};
+};
diff --git a/doc/device-tree-bindings/clock/rockchip,rk3188-cru.txt b/doc/device-tree-bindings/clock/rockchip,rk3188-cru.txt
new file mode 100644
index 0000000..0c2bf5e
--- /dev/null
+++ b/doc/device-tree-bindings/clock/rockchip,rk3188-cru.txt
@@ -0,0 +1,61 @@
+* Rockchip RK3188/RK3066 Clock and Reset Unit
+
+The RK3188/RK3066 clock controller generates and supplies clock to various
+controllers within the SoC and also implements a reset controller for SoC
+peripherals.
+
+Required Properties:
+
+- compatible: should be "rockchip,rk3188-cru", "rockchip,rk3188a-cru" or
+			"rockchip,rk3066a-cru"
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- #clock-cells: should be 1.
+- #reset-cells: should be 1.
+
+Optional Properties:
+
+- rockchip,grf: phandle to the syscon managing the "general register files"
+  If missing pll rates are not changable, due to the missing pll lock status.
+
+Each clock is assigned an identifier and client nodes can use this identifier
+to specify the clock which they consume. All available clocks are defined as
+preprocessor macros in the dt-bindings/clock/rk3188-cru.h and
+dt-bindings/clock/rk3066-cru.h headers and can be used in device tree sources.
+Similar macros exist for the reset sources in these files.
+
+External clocks:
+
+There are several clocks that are generated outside the SoC. It is expected
+that they are defined using standard clock bindings with following
+clock-output-names:
+ - "xin24m" - crystal input - required,
+ - "xin32k" - rtc clock - optional,
+ - "xin27m" - 27mhz crystal input on rk3066 - optional,
+ - "ext_hsadc" - external HSADC clock - optional,
+ - "ext_cif0" - external camera clock - optional,
+ - "ext_rmii" - external RMII clock - optional,
+ - "ext_jtag" - externalJTAG clock - optional
+
+Example: Clock controller node:
+
+	cru: cru at 20000000 {
+		compatible = "rockchip,rk3188-cru";
+		reg = <0x20000000 0x1000>;
+		rockchip,grf = <&grf>;
+
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+Example: UART controller node that consumes the clock generated by the clock
+  controller:
+
+	uart0: serial at 10124000 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0x10124000 0x400>;
+		interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+		reg-shift = <2>;
+		reg-io-width = <1>;
+		clocks = <&cru SCLK_UART0>;
+	};
diff --git a/doc/device-tree-bindings/clock/rockchip,rk3288-cru.txt b/doc/device-tree-bindings/clock/rockchip,rk3288-cru.txt
new file mode 100644
index 0000000..c9fbb76
--- /dev/null
+++ b/doc/device-tree-bindings/clock/rockchip,rk3288-cru.txt
@@ -0,0 +1,61 @@
+* Rockchip RK3288 Clock and Reset Unit
+
+The RK3288 clock controller generates and supplies clock to various
+controllers within the SoC and also implements a reset controller for SoC
+peripherals.
+
+Required Properties:
+
+- compatible: should be "rockchip,rk3288-cru"
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- #clock-cells: should be 1.
+- #reset-cells: should be 1.
+
+Optional Properties:
+
+- rockchip,grf: phandle to the syscon managing the "general register files"
+  If missing pll rates are not changable, due to the missing pll lock status.
+
+Each clock is assigned an identifier and client nodes can use this identifier
+to specify the clock which they consume. All available clocks are defined as
+preprocessor macros in the dt-bindings/clock/rk3288-cru.h headers and can be
+used in device tree sources. Similar macros exist for the reset sources in
+these files.
+
+External clocks:
+
+There are several clocks that are generated outside the SoC. It is expected
+that they are defined using standard clock bindings with following
+clock-output-names:
+ - "xin24m" - crystal input - required,
+ - "xin32k" - rtc clock - optional,
+ - "ext_i2s" - external I2S clock - optional,
+ - "ext_hsadc" - external HSADC clock - optional,
+ - "ext_edp_24m" - external display port clock - optional,
+ - "ext_vip" - external VIP clock - optional,
+ - "ext_isp" - external ISP clock - optional,
+ - "ext_jtag" - external JTAG clock - optional
+
+Example: Clock controller node:
+
+	cru: cru at 20000000 {
+		compatible = "rockchip,rk3188-cru";
+		reg = <0x20000000 0x1000>;
+		rockchip,grf = <&grf>;
+
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+Example: UART controller node that consumes the clock generated by the clock
+  controller:
+
+	uart0: serial at 10124000 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0x10124000 0x400>;
+		interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+		reg-shift = <2>;
+		reg-io-width = <1>;
+		clocks = <&cru SCLK_UART0>;
+	};
diff --git a/doc/device-tree-bindings/clock/rockchip,rk3288-dmc.txt b/doc/device-tree-bindings/clock/rockchip,rk3288-dmc.txt
new file mode 100644
index 0000000..2ca9db7
--- /dev/null
+++ b/doc/device-tree-bindings/clock/rockchip,rk3288-dmc.txt
@@ -0,0 +1,155 @@
+Rockchip Dynamic Memory Controller Driver
+Required properties:
+- compatible: "rockchip,rk3288-dmc", "syscon"
+- rockchip,cru: this driver should access cru regs, so need get cru here
+- rockchip,grf: this driver should access grf regs, so need get grf here
+- rockchip,pmu: this driver should access pmu regs, so need get pmu here
+- rockchip,sgrf: this driver should access sgrf regs, so need get sgrf here
+- rockchip,noc: this driver should access noc regs, so need get noc here
+- reg: dynamic ram protocol controller(PCTL) address and phy controller(PHYCTL) address
+- clock: must include clock specifiers corresponding to entries in the clock-names property.
+- clock-output-names: from common clock binding to override the default output clock name
+    Must contain
+      pclk_ddrupctl0: support clock for access protocol controller registers of channel 0
+      pclk_publ0: support clock for access phy controller registers of channel 0
+      pclk_ddrupctl1: support clock for access protocol controller registers of channel 1
+      pclk_publ1: support clock for access phy controller registers of channel 1
+      arm_clk: for get arm frequency
+-logic-supply: this driver should adjust VDD_LOGIC according to dmc frequency, so need get logic-supply here
+-timings:
+    Must contain
+      rockchip,odt-disable-freq: if ddr clock frequency low than odt-disable-freq,this driver should disable DDR ODT
+      rockchip,dll-disable-freq: if ddr clock frequency low than dll-disable-freq,this driver should disable DDR DLL
+      rockchip,sr-enable-freq: if ddr clock frequency high than sr-enable-freq,this driver should enable the automatic self refresh function
+      rockchip,pd-enable-freq: if ddr clock frequency high than pd-enable-freq,this driver should enable the automatic power down function
+      rockchip,auto-self-refresh-cnt: Self Refresh idle period. Memories are placed into Self-Refresh mode if the NIF is idle in Access state for auto-self-refresh-cnt * 32 * n_clk cycles.The automatic self refresh function is disabled when auto-self-refresh-cnt=0.
+      rockchip,auto-power-down-cnt: Power-down idle period. Memories are placed into power-down mode if the NIF is idle for auto-power-down-cnt n_clk cycles.The automatic power down function is disabled when auto-power-down-cnt=0.
+      rockchip,ddr-speed-bin: DDR3 type,AC timing parameters from the memory data-sheet
+        0.DDR3_800D (5-5-5)
+        1.DDR3_800E (6-6-6)
+        2.DDR3_1066E (6-6-6)
+        3.DDR3_1066F (7-7-7)
+        4.DDR3_1066G (8-8-8)
+        5.DDR3_1333F (7-7-7)
+        6.DDR3_1333G (8-8-8)
+        7.DDR3_1333H (9-9-9)
+        8.DDR3_1333J (10-10-10)
+        9.DDR3_1600G (8-8-8)
+        10.DDR3_1600H (9-9-9)
+        11.DDR3_1600J (10-10-10)
+        12.DDR3_1600K (11-11-11)
+        13.DDR3_1866J (10-10-10)
+        14.DDR3_1866K (11-11-11)
+        15.DDR3_1866L (12-12-12)
+        16.DDR3_1866M (13-13-13)
+        17.DDR3_2133K (11-11-11)
+        18.DDR3_2133L (12-12-12)
+        19.DDR3_2133M (13-13-13)
+        20.DDR3_2133N (14-14-14)
+        21.DDR3_DEFAULT
+      rockchip,trcd: tRCD,AC timing parameters from the memory data-sheet
+      rockchip,trp: tRP,AC timing parameters from the memory data-sheet
+-rockchip,num-channels: number of SDRAM channels (1 or 2)
+-rockchip,pctl-timing: parameters for the SDRAM setup, in this order:
+	togcnt1u
+	tinit
+	trsth
+	togcnt100n
+	trefi
+	tmrd
+	trfc
+	trp
+	trtw
+	tal
+	tcl
+	tcwl
+	tras
+	trc
+	trcd
+	trrd
+	trtp
+	twr
+	twtr
+	texsr
+	txp
+	txpdll
+	tzqcs
+	tzqcsi
+	tdqs
+	tcksre
+	tcksrx
+	tcke
+	tmod
+	trstl
+	tzqcl
+	tmrr
+	tckesr
+	tdpd
+-rockchip,phy-timing: PHY timing information in this order:
+	dtpr0
+	dtpr1
+	dtpr2
+	mr0..mr3
+-rockchip,sdram-channel: SDRAM channel information, each 8 bits. Both channels
+will be set up the same. The parameters are in this order:
+	rank
+	col
+	bk
+	bw
+	dbw
+	row_3_4
+	cs0_row
+	cs1_row
+- rockchip,sdram-params: SDRAM base parameters, in this order:
+	NOC timing	- value for ddrtiming register
+	NOC activate	- value for activate register
+	ddrconf		- value for ddrconf register
+	DDR frequency in MHz
+	DRAM type (3=DDR3, 6=LPDDR3)
+	stride		- stride value for soc_con2 register
+	odt             - 1 to enable DDR ODT, 0 to disable
+
+Example:
+	dmc: dmc at ff610000 {
+		compatible = "rockchip,rk3288-dmc", "syscon";
+		rockchip,cru = <&cru>;
+		rockchip,grf = <&grf>;
+		rockchip,pmu = <&pmu>;
+		rockchip,sgrf = <&sgrf>;
+		rockchip,noc = <&noc>;
+		reg = <0xff610000 0x3fc
+		       0xff620000 0x294
+		       0xff630000 0x3fc
+		       0xff640000 0x294>;
+		clocks = <&cru PCLK_DDRUPCTL0>, <&cru PCLK_PUBL0>,
+			 <&cru PCLK_DDRUPCTL1>, <&cru PCLK_PUBL1>,
+			 <&cru ARMCLK>;
+		clock-names = "pclk_ddrupctl0", "pclk_publ0",
+			      "pclk_ddrupctl1", "pclk_publ1",
+			      "arm_clk";
+	};
+
+	&dmc {
+		logic-supply = <&vdd_logic>;
+		timings {
+			rockchip,odt-disable-freq = <333000000>;
+			rockchip,dll-disable-freq = <333000000>;
+			rockchip,sr-enable-freq = <333000000>;
+			rockchip,pd-enable-freq = <666000000>;
+			rockchip,auto-self-refresh-cnt = <0>;
+			rockchip,auto-power-down-cnt = <64>;
+			rockchip,ddr-speed-bin = <21>;
+			rockchip,trcd = <10>;
+			rockchip,trp = <10>;
+		};
+		rockchip,num-channels = <2>;
+		rockchip,pctl-timing = <0x29a 0x1f4 0xc8 0x42 0x4e 0x4 0xea 0xa
+			0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7
+			0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0
+			0x1 0x7 0x7 0x4 0xc 0x43 0x100 0x0
+			0x5 0x0>;
+		rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
+			0xa60 0x40 0x10 0x0>;
+		rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf>;
+		rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
+	};
diff --git a/doc/device-tree-bindings/clock/rockchip.txt b/doc/device-tree-bindings/clock/rockchip.txt
new file mode 100644
index 0000000..22f6769
--- /dev/null
+++ b/doc/device-tree-bindings/clock/rockchip.txt
@@ -0,0 +1,77 @@
+Device Tree Clock bindings for arch-rockchip
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+== Gate clocks ==
+
+These bindings are deprecated!
+Please use the soc specific CRU bindings instead.
+
+The gate registers form a continuos block which makes the dt node
+structure a matter of taste, as either all gates can be put into
+one gate clock spanning all registers or they can be divided into
+the 10 individual gates containing 16 clocks each.
+The code supports both approaches.
+
+Required properties:
+- compatible : "rockchip,rk2928-gate-clk"
+- reg : shall be the control register address(es) for the clock.
+- #clock-cells : from common clock binding; shall be set to 1
+- clock-output-names : the corresponding gate names that the clock controls
+- clocks : should contain the parent clock for each individual gate,
+  therefore the number of clocks elements should match the number of
+  clock-output-names
+
+Example using multiple gate clocks:
+
+		clk_gates0: gate-clk at 200000d0 {
+			compatible = "rockchip,rk2928-gate-clk";
+			reg = <0x200000d0 0x4>;
+			clocks = <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>;
+
+			clock-output-names =
+				"gate_core_periph", "gate_cpu_gpll",
+				"gate_ddrphy", "gate_aclk_cpu",
+				"gate_hclk_cpu", "gate_pclk_cpu",
+				"gate_atclk_cpu", "gate_i2s0",
+				"gate_i2s0_frac", "gate_i2s1",
+				"gate_i2s1_frac", "gate_i2s2",
+				"gate_i2s2_frac", "gate_spdif",
+				"gate_spdif_frac", "gate_testclk";
+
+			#clock-cells = <1>;
+		};
+
+		clk_gates1: gate-clk at 200000d4 {
+			compatible = "rockchip,rk2928-gate-clk";
+			reg = <0x200000d4 0x4>;
+			clocks = <&xin24m>, <&xin24m>,
+				 <&xin24m>, <&dummy>,
+				 <&dummy>, <&xin24m>,
+				 <&xin24m>, <&dummy>,
+				 <&xin24m>, <&dummy>,
+				 <&xin24m>, <&dummy>,
+				 <&xin24m>, <&dummy>,
+				 <&xin24m>, <&dummy>;
+
+			clock-output-names =
+				"gate_timer0", "gate_timer1",
+				"gate_timer2", "gate_jtag",
+				"gate_aclk_lcdc1_src", "gate_otgphy0",
+				"gate_otgphy1", "gate_ddr_gpll",
+				"gate_uart0", "gate_frac_uart0",
+				"gate_uart1", "gate_frac_uart1",
+				"gate_uart2", "gate_frac_uart2",
+				"gate_uart3", "gate_frac_uart3";
+
+			#clock-cells = <1>;
+		};
diff --git a/doc/device-tree-bindings/pinctrl/rockchip,pinctrl.txt b/doc/device-tree-bindings/pinctrl/rockchip,pinctrl.txt
new file mode 100644
index 0000000..388b213
--- /dev/null
+++ b/doc/device-tree-bindings/pinctrl/rockchip,pinctrl.txt
@@ -0,0 +1,157 @@
+* Rockchip Pinmux Controller
+
+The Rockchip Pinmux Controller, enables the IC
+to share one PAD to several functional blocks. The sharing is done by
+multiplexing the PAD input/output signals. For each PAD there are several
+muxing options with option 0 being the use as a GPIO.
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+The Rockchip pin configuration node is a node of a group of pins which can be
+used for a specific device or function. This node represents both mux and
+config of the pins in that group. The 'pins' selects the function mode(also
+named pin mode) this pin can work on and the 'config' configures various pad
+settings such as pull-up, etc.
+
+The pins are grouped into up to 5 individual pin banks which need to be
+defined as gpio sub-nodes of the pinmux controller.
+
+Required properties for iomux controller:
+  - compatible: one of "rockchip,rk2928-pinctrl", "rockchip,rk3066a-pinctrl"
+		       "rockchip,rk3066b-pinctrl", "rockchip,rk3188-pinctrl"
+		       "rockchip,rk3288-pinctrl"
+  - rockchip,grf: phandle referencing a syscon providing the
+	 "general register files"
+
+Optional properties for iomux controller:
+  - rockchip,pmu: phandle referencing a syscon providing the pmu registers
+	 as some SoCs carry parts of the iomux controller registers there.
+	 Required for at least rk3188 and rk3288.
+
+Deprecated properties for iomux controller:
+  - reg: first element is the general register space of the iomux controller
+	 It should be large enough to contain also separate pull registers.
+	 second element is the separate pull register space of the rk3188.
+	 Use rockchip,grf and rockchip,pmu described above instead.
+
+Required properties for gpio sub nodes:
+  - compatible: "rockchip,gpio-bank"
+  - reg: register of the gpio bank (different than the iomux registerset)
+  - interrupts: base interrupt of the gpio bank in the interrupt controller
+  - clocks: clock that drives this bank
+  - gpio-controller: identifies the node as a gpio controller and pin bank.
+  - #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
+    binding is used, the amount of cells must be specified as 2. See generic
+    GPIO binding documentation for description of particular cells.
+  - interrupt-controller: identifies the controller node as interrupt-parent.
+  - #interrupt-cells: the value of this property should be 2 and the interrupt
+    cells should use the standard two-cell scheme described in
+    bindings/interrupt-controller/interrupts.txt
+
+Deprecated properties for gpio sub nodes:
+  - compatible: "rockchip,rk3188-gpio-bank0"
+  - reg: second element: separate pull register for rk3188 bank0, use
+	 rockchip,pmu described above instead
+
+Required properties for pin configuration node:
+  - rockchip,pins: 3 integers array, represents a group of pins mux and config
+    setting. The format is rockchip,pins = <PIN_BANK PIN_BANK_IDX MUX &phandle>.
+    The MUX 0 means gpio and MUX 1 to N mean the specific device function.
+    The phandle of a node containing the generic pinconfig options
+    to use, as described in pinctrl-bindings.txt in this directory.
+
+Examples:
+
+#include <dt-bindings/pinctrl/rockchip.h>
+
+...
+
+pinctrl at 20008000 {
+	compatible = "rockchip,rk3066a-pinctrl";
+	rockchip,grf = <&grf>;
+
+	#address-cells = <1>;
+	#size-cells = <1>;
+	ranges;
+
+	gpio0: gpio0 at 20034000 {
+		compatible = "rockchip,gpio-bank";
+		reg = <0x20034000 0x100>;
+		interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clk_gates8 9>;
+
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	...
+
+	pcfg_pull_default: pcfg_pull_default {
+		bias-pull-pin-default
+	};
+
+	uart2 {
+		uart2_xfer: uart2-xfer {
+			rockchip,pins = <RK_GPIO1 8 1 &pcfg_pull_default>,
+					<RK_GPIO1 9 1 &pcfg_pull_default>;
+		};
+	};
+};
+
+uart2: serial at 20064000 {
+	compatible = "snps,dw-apb-uart";
+	reg = <0x20064000 0x400>;
+	interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+	reg-shift = <2>;
+	reg-io-width = <1>;
+	clocks = <&mux_uart2>;
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2_xfer>;
+};
+
+Example for rk3188:
+
+	pinctrl at 20008000 {
+		compatible = "rockchip,rk3188-pinctrl";
+		rockchip,grf = <&grf>;
+		rockchip,pmu = <&pmu>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		gpio0: gpio0 at 0x2000a000 {
+			compatible = "rockchip,rk3188-gpio-bank0";
+			reg = <0x2000a000 0x100>;
+			interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk_gates8 9>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio1: gpio1 at 0x2003c000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x2003c000 0x100>;
+			interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk_gates8 10>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		...
+
+	};
diff --git a/doc/device-tree-bindings/thermal/rockchip-thermal.txt b/doc/device-tree-bindings/thermal/rockchip-thermal.txt
new file mode 100644
index 0000000..ef802de
--- /dev/null
+++ b/doc/device-tree-bindings/thermal/rockchip-thermal.txt
@@ -0,0 +1,68 @@
+* Temperature Sensor ADC (TSADC) on rockchip SoCs
+
+Required properties:
+- compatible : "rockchip,rk3288-tsadc"
+- reg : physical base address of the controller and length of memory mapped
+	region.
+- interrupts : The interrupt number to the cpu. The interrupt specifier format
+	       depends on the interrupt controller.
+- clocks : Must contain an entry for each entry in clock-names.
+- clock-names : Shall be "tsadc" for the converter-clock, and "apb_pclk" for
+		the peripheral clock.
+- resets : Must contain an entry for each entry in reset-names.
+	   See ../reset/reset.txt for details.
+- reset-names : Must include the name "tsadc-apb".
+- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description.
+- rockchip,hw-tshut-temp : The hardware-controlled shutdown temperature value.
+- rockchip,hw-tshut-mode : The hardware-controlled shutdown mode 0:CRU 1:GPIO.
+- rockchip,hw-tshut-polarity : The hardware-controlled active polarity 0:LOW
+			       1:HIGH.
+
+Exiample:
+tsadc: tsadc at ff280000 {
+	compatible = "rockchip,rk3288-tsadc";
+	reg = <0xff280000 0x100>;
+	interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+	clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>;
+	clock-names = "tsadc", "apb_pclk";
+	resets = <&cru SRST_TSADC>;
+	reset-names = "tsadc-apb";
+	pinctrl-names = "default";
+	pinctrl-0 = <&otp_out>;
+	#thermal-sensor-cells = <1>;
+	rockchip,hw-tshut-temp = <95000>;
+	rockchip,hw-tshut-mode = <0>;
+	rockchip,hw-tshut-polarity = <0>;
+};
+
+Example: referring to thermal sensors:
+thermal-zones {
+	cpu_thermal: cpu_thermal {
+		polling-delay-passive = <1000>; /* milliseconds */
+		polling-delay = <5000>; /* milliseconds */
+
+		/* sensor	ID */
+		thermal-sensors = <&tsadc	1>;
+
+		trips {
+			cpu_alert0: cpu_alert {
+				temperature = <70000>; /* millicelsius */
+				hysteresis = <2000>; /* millicelsius */
+				type = "passive";
+			};
+			cpu_crit: cpu_crit {
+				temperature = <90000>; /* millicelsius */
+				hysteresis = <2000>; /* millicelsius */
+				type = "critical";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_alert0>;
+				cooling-device =
+				    <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+};
diff --git a/include/dt-bindings/clock/rk3288-cru.h b/include/dt-bindings/clock/rk3288-cru.h
new file mode 100644
index 0000000..216eee5
--- /dev/null
+++ b/include/dt-bindings/clock/rk3288-cru.h
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 2014 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/* core clocks */
+#define PLL_APLL		1
+#define PLL_DPLL		2
+#define PLL_CPLL		3
+#define PLL_GPLL		4
+#define PLL_NPLL		5
+#define ARMCLK			6
+
+/* sclk gates (special clocks) */
+#define SCLK_GPU		64
+#define SCLK_SPI0		65
+#define SCLK_SPI1		66
+#define SCLK_SPI2		67
+#define SCLK_SDMMC		68
+#define SCLK_SDIO0		69
+#define SCLK_SDIO1		70
+#define SCLK_EMMC		71
+#define SCLK_TSADC		72
+#define SCLK_SARADC		73
+#define SCLK_PS2C		74
+#define SCLK_NANDC0		75
+#define SCLK_NANDC1		76
+#define SCLK_UART0		77
+#define SCLK_UART1		78
+#define SCLK_UART2		79
+#define SCLK_UART3		80
+#define SCLK_UART4		81
+#define SCLK_I2S0		82
+#define SCLK_SPDIF		83
+#define SCLK_SPDIF8CH		84
+#define SCLK_TIMER0		85
+#define SCLK_TIMER1		86
+#define SCLK_TIMER2		87
+#define SCLK_TIMER3		88
+#define SCLK_TIMER4		89
+#define SCLK_TIMER5		90
+#define SCLK_TIMER6		91
+#define SCLK_HSADC		92
+#define SCLK_OTGPHY0		93
+#define SCLK_OTGPHY1		94
+#define SCLK_OTGPHY2		95
+#define SCLK_OTG_ADP		96
+#define SCLK_HSICPHY480M	97
+#define SCLK_HSICPHY12M		98
+#define SCLK_MACREF		99
+#define SCLK_LCDC_PWM0		100
+#define SCLK_LCDC_PWM1		101
+#define SCLK_MAC_RX		102
+#define SCLK_MAC_TX		103
+#define SCLK_EDP_24M		104
+#define SCLK_EDP		105
+#define SCLK_RGA		106
+#define SCLK_ISP		107
+#define SCLK_ISP_JPE		108
+#define SCLK_HDMI_HDCP		109
+#define SCLK_HDMI_CEC		110
+#define SCLK_HEVC_CABAC		111
+#define SCLK_HEVC_CORE		112
+#define SCLK_I2S0_OUT		113
+#define SCLK_SDMMC_DRV		114
+#define SCLK_SDIO0_DRV		115
+#define SCLK_SDIO1_DRV		116
+#define SCLK_EMMC_DRV		117
+#define SCLK_SDMMC_SAMPLE	118
+#define SCLK_SDIO0_SAMPLE	119
+#define SCLK_SDIO1_SAMPLE	120
+#define SCLK_EMMC_SAMPLE	121
+#define SCLK_USBPHY480M_SRC	122
+#define SCLK_PVTM_CORE		123
+#define SCLK_PVTM_GPU		124
+
+#define SCLK_MAC		151
+#define SCLK_MACREF_OUT		152
+
+#define DCLK_VOP0		190
+#define DCLK_VOP1		191
+
+/* aclk gates */
+#define ACLK_GPU		192
+#define ACLK_DMAC1		193
+#define ACLK_DMAC2		194
+#define ACLK_MMU		195
+#define ACLK_GMAC		196
+#define ACLK_VOP0		197
+#define ACLK_VOP1		198
+#define ACLK_CRYPTO		199
+#define ACLK_RGA		200
+#define ACLK_RGA_NIU		201
+#define ACLK_IEP		202
+#define ACLK_VIO0_NIU		203
+#define ACLK_VIP		204
+#define ACLK_ISP		205
+#define ACLK_VIO1_NIU		206
+#define ACLK_HEVC		207
+#define ACLK_VCODEC		208
+#define ACLK_CPU		209
+#define ACLK_PERI		210
+
+/* pclk gates */
+#define PCLK_GPIO0		320
+#define PCLK_GPIO1		321
+#define PCLK_GPIO2		322
+#define PCLK_GPIO3		323
+#define PCLK_GPIO4		324
+#define PCLK_GPIO5		325
+#define PCLK_GPIO6		326
+#define PCLK_GPIO7		327
+#define PCLK_GPIO8		328
+#define PCLK_GRF		329
+#define PCLK_SGRF		330
+#define PCLK_PMU		331
+#define PCLK_I2C0		332
+#define PCLK_I2C1		333
+#define PCLK_I2C2		334
+#define PCLK_I2C3		335
+#define PCLK_I2C4		336
+#define PCLK_I2C5		337
+#define PCLK_SPI0		338
+#define PCLK_SPI1		339
+#define PCLK_SPI2		340
+#define PCLK_UART0		341
+#define PCLK_UART1		342
+#define PCLK_UART2		343
+#define PCLK_UART3		344
+#define PCLK_UART4		345
+#define PCLK_TSADC		346
+#define PCLK_SARADC		347
+#define PCLK_SIM		348
+#define PCLK_GMAC		349
+#define PCLK_PWM		350
+#define PCLK_RKPWM		351
+#define PCLK_PS2C		352
+#define PCLK_TIMER		353
+#define PCLK_TZPC		354
+#define PCLK_EDP_CTRL		355
+#define PCLK_MIPI_DSI0		356
+#define PCLK_MIPI_DSI1		357
+#define PCLK_MIPI_CSI		358
+#define PCLK_LVDS_PHY		359
+#define PCLK_HDMI_CTRL		360
+#define PCLK_VIO2_H2P		361
+#define PCLK_CPU		362
+#define PCLK_PERI		363
+#define PCLK_DDRUPCTL0		364
+#define PCLK_PUBL0		365
+#define PCLK_DDRUPCTL1		366
+#define PCLK_PUBL1		367
+#define PCLK_WDT		368
+
+/* hclk gates */
+#define HCLK_GPS		448
+#define HCLK_OTG0		449
+#define HCLK_USBHOST0		450
+#define HCLK_USBHOST1		451
+#define HCLK_HSIC		452
+#define HCLK_NANDC0		453
+#define HCLK_NANDC1		454
+#define HCLK_TSP		455
+#define HCLK_SDMMC		456
+#define HCLK_SDIO0		457
+#define HCLK_SDIO1		458
+#define HCLK_EMMC		459
+#define HCLK_HSADC		460
+#define HCLK_CRYPTO		461
+#define HCLK_I2S0		462
+#define HCLK_SPDIF		463
+#define HCLK_SPDIF8CH		464
+#define HCLK_VOP0		465
+#define HCLK_VOP1		466
+#define HCLK_ROM		467
+#define HCLK_IEP		468
+#define HCLK_ISP		469
+#define HCLK_RGA		470
+#define HCLK_VIO_AHB_ARBI	471
+#define HCLK_VIO_NIU		472
+#define HCLK_VIP		473
+#define HCLK_VIO2_H2P		474
+#define HCLK_HEVC		475
+#define HCLK_VCODEC		476
+#define HCLK_CPU		477
+#define HCLK_PERI		478
+
+#define CLK_NR_CLKS		(HCLK_PERI + 1)
+
+/* soft-reset indices */
+#define SRST_CORE0		0
+#define SRST_CORE1		1
+#define SRST_CORE2		2
+#define SRST_CORE3		3
+#define SRST_CORE0_PO		4
+#define SRST_CORE1_PO		5
+#define SRST_CORE2_PO		6
+#define SRST_CORE3_PO		7
+#define SRST_PDCORE_STRSYS	8
+#define SRST_PDBUS_STRSYS	9
+#define SRST_L2C		10
+#define SRST_TOPDBG		11
+#define SRST_CORE0_DBG		12
+#define SRST_CORE1_DBG		13
+#define SRST_CORE2_DBG		14
+#define SRST_CORE3_DBG		15
+
+#define SRST_PDBUG_AHB_ARBITOR	16
+#define SRST_EFUSE256		17
+#define SRST_DMAC1		18
+#define SRST_INTMEM		19
+#define SRST_ROM		20
+#define SRST_SPDIF8CH		21
+#define SRST_TIMER		22
+#define SRST_I2S0		23
+#define SRST_SPDIF		24
+#define SRST_TIMER0		25
+#define SRST_TIMER1		26
+#define SRST_TIMER2		27
+#define SRST_TIMER3		28
+#define SRST_TIMER4		29
+#define SRST_TIMER5		30
+#define SRST_EFUSE		31
+
+#define SRST_GPIO0		32
+#define SRST_GPIO1		33
+#define SRST_GPIO2		34
+#define SRST_GPIO3		35
+#define SRST_GPIO4		36
+#define SRST_GPIO5		37
+#define SRST_GPIO6		38
+#define SRST_GPIO7		39
+#define SRST_GPIO8		40
+#define SRST_I2C0		42
+#define SRST_I2C1		43
+#define SRST_I2C2		44
+#define SRST_I2C3		45
+#define SRST_I2C4		46
+#define SRST_I2C5		47
+
+#define SRST_DWPWM		48
+#define SRST_MMC_PERI		49
+#define SRST_PERIPH_MMU		50
+#define SRST_DAP		51
+#define SRST_DAP_SYS		52
+#define SRST_TPIU		53
+#define SRST_PMU_APB		54
+#define SRST_GRF		55
+#define SRST_PMU		56
+#define SRST_PERIPH_AXI		57
+#define SRST_PERIPH_AHB		58
+#define SRST_PERIPH_APB		59
+#define SRST_PERIPH_NIU		60
+#define SRST_PDPERI_AHB_ARBI	61
+#define SRST_EMEM		62
+#define SRST_USB_PERI		63
+
+#define SRST_DMAC2		64
+#define SRST_MAC		66
+#define SRST_GPS		67
+#define SRST_RKPWM		69
+#define SRST_CCP		71
+#define SRST_USBHOST0		72
+#define SRST_HSIC		73
+#define SRST_HSIC_AUX		74
+#define SRST_HSIC_PHY		75
+#define SRST_HSADC		76
+#define SRST_NANDC0		77
+#define SRST_NANDC1		78
+
+#define SRST_TZPC		80
+#define SRST_SPI0		83
+#define SRST_SPI1		84
+#define SRST_SPI2		85
+#define SRST_SARADC		87
+#define SRST_PDALIVE_NIU	88
+#define SRST_PDPMU_INTMEM	89
+#define SRST_PDPMU_NIU		90
+#define SRST_SGRF		91
+
+#define SRST_VIO_ARBI		96
+#define SRST_RGA_NIU		97
+#define SRST_VIO0_NIU_AXI	98
+#define SRST_VIO_NIU_AHB	99
+#define SRST_LCDC0_AXI		100
+#define SRST_LCDC0_AHB		101
+#define SRST_LCDC0_DCLK		102
+#define SRST_VIO1_NIU_AXI	103
+#define SRST_VIP		104
+#define SRST_RGA_CORE		105
+#define SRST_IEP_AXI		106
+#define SRST_IEP_AHB		107
+#define SRST_RGA_AXI		108
+#define SRST_RGA_AHB		109
+#define SRST_ISP		110
+#define SRST_EDP		111
+
+#define SRST_VCODEC_AXI		112
+#define SRST_VCODEC_AHB		113
+#define SRST_VIO_H2P		114
+#define SRST_MIPIDSI0		115
+#define SRST_MIPIDSI1		116
+#define SRST_MIPICSI		117
+#define SRST_LVDS_PHY		118
+#define SRST_LVDS_CON		119
+#define SRST_GPU		120
+#define SRST_HDMI		121
+#define SRST_CORE_PVTM		124
+#define SRST_GPU_PVTM		125
+
+#define SRST_MMC0		128
+#define SRST_SDIO0		129
+#define SRST_SDIO1		130
+#define SRST_EMMC		131
+#define SRST_USBOTG_AHB		132
+#define SRST_USBOTG_PHY		133
+#define SRST_USBOTG_CON		134
+#define SRST_USBHOST0_AHB	135
+#define SRST_USBHOST0_PHY	136
+#define SRST_USBHOST0_CON	137
+#define SRST_USBHOST1_AHB	138
+#define SRST_USBHOST1_PHY	139
+#define SRST_USBHOST1_CON	140
+#define SRST_USB_ADP		141
+#define SRST_ACC_EFUSE		142
+
+#define SRST_CORESIGHT		144
+#define SRST_PD_CORE_AHB_NOC	145
+#define SRST_PD_CORE_APB_NOC	146
+#define SRST_PD_CORE_MP_AXI	147
+#define SRST_GIC		148
+#define SRST_LCDC_PWM0		149
+#define SRST_LCDC_PWM1		150
+#define SRST_VIO0_H2P_BRG	151
+#define SRST_VIO1_H2P_BRG	152
+#define SRST_RGA_H2P_BRG	153
+#define SRST_HEVC		154
+#define SRST_TSADC		159
+
+#define SRST_DDRPHY0		160
+#define SRST_DDRPHY0_APB	161
+#define SRST_DDRCTRL0		162
+#define SRST_DDRCTRL0_APB	163
+#define SRST_DDRPHY0_CTRL	164
+#define SRST_DDRPHY1		165
+#define SRST_DDRPHY1_APB	166
+#define SRST_DDRCTRL1		167
+#define SRST_DDRCTRL1_APB	168
+#define SRST_DDRPHY1_CTRL	169
+#define SRST_DDRMSCH0		170
+#define SRST_DDRMSCH1		171
+#define SRST_CRYPTO		174
+#define SRST_C2C_HOST		175
+
+#define SRST_LCDC1_AXI		176
+#define SRST_LCDC1_AHB		177
+#define SRST_LCDC1_DCLK		178
+#define SRST_UART0		179
+#define SRST_UART1		180
+#define SRST_UART2		181
+#define SRST_UART3		182
+#define SRST_UART4		183
+#define SRST_SIMC		186
+#define SRST_PS2C		187
+#define SRST_TSP		188
+#define SRST_TSP_CLKIN0		189
+#define SRST_TSP_CLKIN1		190
+#define SRST_TSP_27M		191
diff --git a/include/dt-bindings/clock/rockchip,rk808.h b/include/dt-bindings/clock/rockchip,rk808.h
new file mode 100644
index 0000000..1a87343
--- /dev/null
+++ b/include/dt-bindings/clock/rockchip,rk808.h
@@ -0,0 +1,11 @@
+/*
+ * This header provides constants clk index RK808 pmic clkout
+ */
+#ifndef _CLK_ROCKCHIP_RK808
+#define _CLK_ROCKCHIP_RK808
+
+/* CLOCKOUT index */
+#define RK808_CLKOUT0		0
+#define RK808_CLKOUT1		1
+
+#endif
diff --git a/include/dt-bindings/pinctrl/rockchip.h b/include/dt-bindings/pinctrl/rockchip.h
new file mode 100644
index 0000000..56887e1
--- /dev/null
+++ b/include/dt-bindings/pinctrl/rockchip.h
@@ -0,0 +1,26 @@
+/*
+ * Header providing constants for Rockchip pinctrl bindings.
+ *
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_ROCKCHIP_PINCTRL_H__
+#define __DT_BINDINGS_ROCKCHIP_PINCTRL_H__
+
+#define RK_GPIO0	0
+#define RK_GPIO1	1
+#define RK_GPIO2	2
+#define RK_GPIO3	3
+#define RK_GPIO4	4
+#define RK_GPIO6	6
+
+#define RK_FUNC_GPIO	0
+#define RK_FUNC_1	1
+#define RK_FUNC_2	2
+#define RK_FUNC_3	3
+#define RK_FUNC_4	4
+
+#endif
diff --git a/include/dt-bindings/power-domain/rk3288.h b/include/dt-bindings/power-domain/rk3288.h
new file mode 100644
index 0000000..ca68c11
--- /dev/null
+++ b/include/dt-bindings/power-domain/rk3288.h
@@ -0,0 +1,11 @@
+#ifndef __DT_BINDINGS_POWER_DOMAIN_RK3288_H__
+#define __DT_BINDINGS_POWER_DOMAIN_RK3288_H__
+
+/* RK3288 power domain index */
+#define RK3288_PD_GPU          0
+#define RK3288_PD_VIO          1
+#define RK3288_PD_VIDEO        2
+#define RK3288_PD_HEVC         3
+#define RK3288_PD_PERI         4
+
+#endif
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 10/41] rockchip: rk3288: dts: Make core devices available early
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (8 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 09/41] rockchip: Bring in RK3288 device tree file includes and bindings Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:58   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 11/41] mkimage: Allow padding to any length Simon Glass
                   ` (30 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

In SPL we need access to the CRU and other peripherals so we can set up
SDRAM. Mark these so that they will remain in the device tree.

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

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arm/dts/rk3288.dtsi | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm/dts/rk3288.dtsi b/arch/arm/dts/rk3288.dtsi
index 6b5145c..0f49709 100644
--- a/arch/arm/dts/rk3288.dtsi
+++ b/arch/arm/dts/rk3288.dtsi
@@ -16,6 +16,15 @@
 
 	interrupt-parent = <&gic>;
 	aliases {
+		gpio0 = &gpio0;
+		gpio1 = &gpio1;
+		gpio2 = &gpio2;
+		gpio3 = &gpio3;
+		gpio4 = &gpio4;
+		gpio5 = &gpio5;
+		gpio6 = &gpio6;
+		gpio7 = &gpio7;
+		gpio8 = &gpio8;
 		i2c0 = &i2c0;
 		i2c1 = &i2c1;
 		i2c2 = &i2c2;
@@ -454,6 +463,7 @@
 	};
 
 	dmc: dmc at ff610000 {
+		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3288-dmc", "syscon";
 		rockchip,cru = <&cru>;
 		rockchip,grf = <&grf>;
@@ -569,11 +579,13 @@
 	};
 
 	pmu: power-management at ff730000 {
+		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3288-pmu", "syscon";
 		reg = <0xff730000 0x100>;
 	};
 
 	sgrf: syscon at ff740000 {
+		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3288-sgrf", "syscon";
 		reg = <0xff740000 0x1000>;
 	};
@@ -582,6 +594,7 @@
 		compatible = "rockchip,rk3288-cru";
 		reg = <0xff760000 0x1000>;
 		rockchip,grf = <&grf>;
+		u-boot,dm-pre-reloc;
 		#clock-cells = <1>;
 		#reset-cells = <1>;
 		assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>,
@@ -600,6 +613,7 @@
 	};
 
 	grf: syscon at ff770000 {
+		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3288-grf", "syscon";
 		reg = <0xff770000 0x1000>;
 	};
@@ -804,6 +818,7 @@
 	};
 
 	noc: syscon at ffac0000 {
+		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3288-noc", "syscon";
 		reg = <0xffac0000 0x2000>;
 	};
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 11/41] mkimage: Allow padding to any length
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (9 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 10/41] rockchip: rk3288: dts: Make core devices available early Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:58   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 12/41] mkimage: Allow the original file size to be recorded Simon Glass
                   ` (29 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

At present there is an arbitrary limit of 4KB for padding. Rockchip needs
more than that, so remove this restriction.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Joe Hershberger <joe.hershberger@ni.com>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 tools/mkimage.c | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/tools/mkimage.c b/tools/mkimage.c
index e81d455..c50af05 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -488,12 +488,6 @@ copy_file (int ifd, const char *datafile, int pad)
 	int size;
 	struct image_type_params *tparams = imagetool_get_type(params.type);
 
-	if (pad >= sizeof(zeros)) {
-		fprintf(stderr, "%s: Can't pad to %d\n",
-			params.cmdname, pad);
-		exit(EXIT_FAILURE);
-	}
-
 	memset(zeros, 0, sizeof(zeros));
 
 	if (params.vflag) {
@@ -563,11 +557,18 @@ copy_file (int ifd, const char *datafile, int pad)
 			exit (EXIT_FAILURE);
 		}
 	} else if (pad > 1) {
-		if (write(ifd, (char *)&zeros, pad) != pad) {
-			fprintf(stderr, "%s: Write error on %s: %s\n",
-				params.cmdname, params.imagefile,
-				strerror(errno));
-			exit(EXIT_FAILURE);
+		while (pad > 0) {
+			int todo = sizeof(zeros);
+
+			if (todo > pad)
+				todo = pad;
+			if (write(ifd, (char *)&zeros, todo) != todo) {
+				fprintf(stderr, "%s: Write error on %s: %s\n",
+					params.cmdname, params.imagefile,
+					strerror(errno));
+				exit(EXIT_FAILURE);
+			}
+			pad -= todo;
 		}
 	}
 
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 12/41] mkimage: Allow the original file size to be recorded
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (10 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 11/41] mkimage: Allow padding to any length Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:58   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 13/41] rockchip: Add the rkimage format to mkimage Simon Glass
                   ` (28 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

Allow the image handler to store the original input file size so that it
can reference it later.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Joe Hershberger <joe.hershberger@ni.com>
---

Changes in v5:
- Fix comment on orig_file_size

Changes in v4: None
Changes in v3: None
Changes in v2: None

 tools/imagetool.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/imagetool.h b/tools/imagetool.h
index 99bbf2f..ad2deb5 100644
--- a/tools/imagetool.h
+++ b/tools/imagetool.h
@@ -60,6 +60,7 @@ struct image_tool_params {
 	const char *comment;	/* Comment to add to signature node */
 	int require_keys;	/* 1 to mark signing keys as 'required' */
 	int file_size;		/* Total size of output file */
+	int orig_file_size;	/* Original size for file before padding */
 };
 
 /*
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 13/41] rockchip: Add the rkimage format to mkimage
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (11 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 12/41] mkimage: Allow the original file size to be recorded Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:58   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 14/41] rockchip: Add support for the SD image Simon Glass
                   ` (27 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

Rockchip SoCs require certain formats for code that they execute, The
simplest format is a 4-byte header at the start of a binary file. Add
support for this so that we can create images that the boot ROM understands.

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

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 common/image.c   |  1 +
 include/image.h  |  3 ++-
 tools/Makefile   |  3 +++
 tools/rkcommon.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/rkcommon.h | 28 ++++++++++++++++++++++
 tools/rkimage.c  | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 171 insertions(+), 1 deletion(-)
 create mode 100644 tools/rkcommon.c
 create mode 100644 tools/rkcommon.h
 create mode 100644 tools/rkimage.c

diff --git a/common/image.c b/common/image.c
index 678588d..cf2806f 100644
--- a/common/image.c
+++ b/common/image.c
@@ -155,6 +155,7 @@ static const table_entry_t uimage_type[] = {
 	{	IH_TYPE_ATMELIMAGE, "atmelimage", "ATMEL ROM-Boot Image",},
 	{	IH_TYPE_X86_SETUP,  "x86_setup",  "x86 setup.bin",    },
 	{	IH_TYPE_LPC32XXIMAGE, "lpc32xximage",  "LPC32XX Boot Image", },
+	{	IH_TYPE_RKIMAGE,    "rkimage",    "Rockchip Boot Image" },
 	{	-1,		    "",		  "",			},
 };
 
diff --git a/include/image.h b/include/image.h
index 63c3d37..2daa74a 100644
--- a/include/image.h
+++ b/include/image.h
@@ -245,8 +245,9 @@ struct lmb;
 #define IH_TYPE_X86_SETUP	20	/* x86 setup.bin Image		*/
 #define IH_TYPE_LPC32XXIMAGE	21	/* x86 setup.bin Image		*/
 #define IH_TYPE_LOADABLE	22	/* A list of typeless images	*/
+#define IH_TYPE_RKIMAGE		23	/* Rockchip Boot Image		*/
 
-#define IH_TYPE_COUNT		23	/* Number of image types */
+#define IH_TYPE_COUNT		24	/* Number of image types */
 
 /*
  * Compression Types
diff --git a/tools/Makefile b/tools/Makefile
index f673258..267f55c 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -64,6 +64,8 @@ RSA_OBJS-$(CONFIG_FIT_SIGNATURE) := $(addprefix lib/rsa/, \
 					rsa-sign.o rsa-verify.o rsa-checksum.o \
 					rsa-mod-exp.o)
 
+ROCKCHIP_OBS = lib/rc4.o rkcommon.o rkimage.o
+
 # common objs for dumpimage and mkimage
 dumpimage-mkimage-objs := aisimage.o \
 			atmelimage.o \
@@ -90,6 +92,7 @@ dumpimage-mkimage-objs := aisimage.o \
 			os_support.o \
 			pblimage.o \
 			pbl_crc32.o \
+			$(ROCKCHIP_OBS) \
 			socfpgaimage.o \
 			lib/sha1.o \
 			lib/sha256.o \
diff --git a/tools/rkcommon.c b/tools/rkcommon.c
new file mode 100644
index 0000000..4389622
--- /dev/null
+++ b/tools/rkcommon.c
@@ -0,0 +1,72 @@
+/*
+ * (C) Copyright 2015 Google,  Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Helper functions for Rockchip images
+ */
+
+#include "imagetool.h"
+#include <image.h>
+#include <rc4.h>
+#include "mkimage.h"
+#include "rkcommon.h"
+
+enum {
+	RK_SIGNATURE		= 0x0ff0aa55,
+};
+
+/**
+ * struct header0_info - header block for boot ROM
+ *
+ * This is stored at SD card block 64 (where each block is 512 bytes, or at
+ * the start of SPI flash. It is encoded with RC4.
+ *
+ * @signature:		Signature (must be RKSD_SIGNATURE)
+ * @disable_rc4:	0 to use rc4 for boot image,  1 to use plain binary
+ * @code1_offset:	Offset in blocks of the SPL code from this header
+ *			block. E.g. 4 means 2KB after the start of this header.
+ * Other fields are not used by U-Boot
+ */
+struct header0_info {
+	uint32_t signature;
+	uint8_t reserved[4];
+	uint32_t disable_rc4;
+	uint16_t code1_offset;
+	uint16_t code2_offset;
+	uint8_t reserved1[490];
+	uint16_t usflashdatasize;
+	uint16_t ucflashbootsize;
+	uint8_t reserved2[2];
+};
+
+static unsigned char rc4_key[16] = {
+	124, 78, 3, 4, 85, 5, 9, 7,
+	45, 44, 123, 56, 23, 13, 23, 17
+};
+
+int rkcommon_set_header(void *buf, uint file_size)
+{
+	struct header0_info *hdr;
+
+	if (file_size > RK_MAX_CODE1_SIZE)
+		return -ENOSPC;
+
+	memset(buf,  '\0', RK_CODE1_OFFSET * RK_BLK_SIZE);
+	hdr = (struct header0_info *)buf;
+	hdr->signature = RK_SIGNATURE;
+	hdr->disable_rc4 = 1;
+	hdr->code1_offset = RK_CODE1_OFFSET;
+	hdr->code2_offset = 8;
+
+	hdr->usflashdatasize = (file_size + RK_BLK_SIZE - 1) / RK_BLK_SIZE;
+	hdr->usflashdatasize = (hdr->usflashdatasize + 3) & ~3;
+	hdr->ucflashbootsize = hdr->usflashdatasize;
+
+	debug("size=%x, %x\n", params->file_size, hdr->usflashdatasize);
+
+	rc4_encode(buf, RK_BLK_SIZE, rc4_key);
+
+	return 0;
+}
diff --git a/tools/rkcommon.h b/tools/rkcommon.h
new file mode 100644
index 0000000..57fd726
--- /dev/null
+++ b/tools/rkcommon.h
@@ -0,0 +1,28 @@
+/*
+ * (C) Copyright 2015 Google,  Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _RKCOMMON_H
+#define _RKCOMMON_H
+
+enum {
+	RK_BLK_SIZE		= 512,
+	RK_CODE1_OFFSET		= 4,
+	RK_MAX_CODE1_SIZE	= 32 << 10,
+};
+
+/**
+ * rkcommon_set_header() - set up the header for a Rockchip boot image
+ *
+ * This sets up a 2KB header which can be interpreted by the Rockchip boot ROM.
+ *
+ * @buf:	Pointer to header place (must be at least 2KB in size)
+ * @file_size:	Size of the file we want the boot ROM to load, in bytes
+ * @return 0 if OK, -ENOSPC if too large
+ */
+int rkcommon_set_header(void *buf, uint file_size);
+
+#endif
diff --git a/tools/rkimage.c b/tools/rkimage.c
new file mode 100644
index 0000000..7b292f4
--- /dev/null
+++ b/tools/rkimage.c
@@ -0,0 +1,65 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * See README.rockchip for details of the rkimage format
+ */
+
+#include "imagetool.h"
+#include <image.h>
+
+static uint32_t header;
+
+static int rkimage_check_params(struct image_tool_params *params)
+{
+	return 0;
+}
+
+static int rkimage_verify_header(unsigned char *buf, int size,
+				 struct image_tool_params *params)
+{
+	return 0;
+}
+
+static void rkimage_print_header(const void *buf)
+{
+}
+
+static void rkimage_set_header(void *buf, struct stat *sbuf, int ifd,
+			       struct image_tool_params *params)
+{
+	memcpy(buf, "RK32", 4);
+}
+
+static int rkimage_extract_subimage(void *buf, struct image_tool_params *params)
+{
+	return 0;
+}
+
+static int rkimage_check_image_type(uint8_t type)
+{
+	if (type == IH_TYPE_RKIMAGE)
+		return EXIT_SUCCESS;
+	else
+		return EXIT_FAILURE;
+}
+
+/*
+ * rk_image parameters
+ */
+U_BOOT_IMAGE_TYPE(
+	rkimage,
+	"Rockchip Boot Image support",
+	4,
+	&header,
+	rkimage_check_params,
+	rkimage_verify_header,
+	rkimage_print_header,
+	rkimage_set_header,
+	rkimage_extract_subimage,
+	rkimage_check_image_type,
+	NULL,
+	NULL
+);
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 14/41] rockchip: Add support for the SD image
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (12 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 13/41] rockchip: Add the rkimage format to mkimage Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:58   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 15/41] rockchip: Add support for the SPI image Simon Glass
                   ` (26 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

The Rockchip boot ROM requires a particular file format. It consists of
64KB of zeroes, a 512-byte header encoded with RC4, and then some executable
code.

Add support to mkimage so that an SPL image (u-boot-spl-dtb.bin) can be
converted to this format.

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

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 common/image.c  |   1 +
 include/image.h |   3 +-
 tools/Makefile  |   2 +-
 tools/rksd.c    | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 106 insertions(+), 2 deletions(-)
 create mode 100644 tools/rksd.c

diff --git a/common/image.c b/common/image.c
index cf2806f..2cdc728 100644
--- a/common/image.c
+++ b/common/image.c
@@ -156,6 +156,7 @@ static const table_entry_t uimage_type[] = {
 	{	IH_TYPE_X86_SETUP,  "x86_setup",  "x86 setup.bin",    },
 	{	IH_TYPE_LPC32XXIMAGE, "lpc32xximage",  "LPC32XX Boot Image", },
 	{	IH_TYPE_RKIMAGE,    "rkimage",    "Rockchip Boot Image" },
+	{	IH_TYPE_RKSD,       "rksd",       "Rockchip SD Boot Image" },
 	{	-1,		    "",		  "",			},
 };
 
diff --git a/include/image.h b/include/image.h
index 2daa74a..ea16205 100644
--- a/include/image.h
+++ b/include/image.h
@@ -246,8 +246,9 @@ struct lmb;
 #define IH_TYPE_LPC32XXIMAGE	21	/* x86 setup.bin Image		*/
 #define IH_TYPE_LOADABLE	22	/* A list of typeless images	*/
 #define IH_TYPE_RKIMAGE		23	/* Rockchip Boot Image		*/
+#define IH_TYPE_RKSD		24	/* Rockchip SD card		*/
 
-#define IH_TYPE_COUNT		24	/* Number of image types */
+#define IH_TYPE_COUNT		25	/* Number of image types */
 
 /*
  * Compression Types
diff --git a/tools/Makefile b/tools/Makefile
index 267f55c..9082bda 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -64,7 +64,7 @@ RSA_OBJS-$(CONFIG_FIT_SIGNATURE) := $(addprefix lib/rsa/, \
 					rsa-sign.o rsa-verify.o rsa-checksum.o \
 					rsa-mod-exp.o)
 
-ROCKCHIP_OBS = lib/rc4.o rkcommon.o rkimage.o
+ROCKCHIP_OBS = lib/rc4.o rkcommon.o rkimage.o rksd.o
 
 # common objs for dumpimage and mkimage
 dumpimage-mkimage-objs := aisimage.o \
diff --git a/tools/rksd.c b/tools/rksd.c
new file mode 100644
index 0000000..2efcd68
--- /dev/null
+++ b/tools/rksd.c
@@ -0,0 +1,102 @@
+/*
+ * (C) Copyright 2015 Google,  Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * See README.rockchip for details of the rksd format
+ */
+
+#include "imagetool.h"
+#include <image.h>
+#include <rc4.h>
+#include "mkimage.h"
+#include "rkcommon.h"
+
+enum {
+	RKSD_HEADER0_START	= 64 * RK_BLK_SIZE,
+	RKSD_SPL_HDR_START	= RKSD_HEADER0_START +
+					RK_CODE1_OFFSET * RK_BLK_SIZE,
+	RKSD_SPL_START		= RKSD_SPL_HDR_START + 4,
+	RKSD_HEADER_LEN		= RKSD_SPL_START,
+};
+
+static char dummy_hdr[RKSD_HEADER_LEN];
+
+static int rksd_check_params(struct image_tool_params *params)
+{
+	return 0;
+}
+
+static int rksd_verify_header(unsigned char *buf,  int size,
+				 struct image_tool_params *params)
+{
+	return 0;
+}
+
+static void rksd_print_header(const void *buf)
+{
+}
+
+static void rksd_set_header(void *buf,  struct stat *sbuf,  int ifd,
+			       struct image_tool_params *params)
+{
+	unsigned int size;
+	int ret;
+
+	/* Zero the whole header. The first 32KB is empty */
+	memset(buf,  '\0',  RKSD_HEADER0_START);
+
+	size = params->file_size - RKSD_SPL_HDR_START;
+	ret = rkcommon_set_header(buf + RKSD_HEADER0_START, size);
+	if (ret) {
+		/* TODO(sjg at chromium.org): This method should return an error */
+		printf("Warning: SPL image is too large (size %#x) and will not boot\n",
+		       size);
+	}
+
+	memcpy(buf + RKSD_SPL_HDR_START, "RK32", 4);
+}
+
+static int rksd_extract_subimage(void *buf,  struct image_tool_params *params)
+{
+	return 0;
+}
+
+static int rksd_check_image_type(uint8_t type)
+{
+	if (type == IH_TYPE_RKSD)
+		return EXIT_SUCCESS;
+	else
+		return EXIT_FAILURE;
+}
+
+/* We pad the file out to a fixed size - this method returns that size */
+static int rksd_vrec_header(struct image_tool_params *params,
+			    struct image_type_params *tparams)
+{
+	int pad_size;
+
+	pad_size = RKSD_SPL_HDR_START + RK_MAX_CODE1_SIZE;
+	debug("pad_size %x\n", pad_size);
+
+	return pad_size - params->file_size;
+}
+
+/*
+ * rk_sd parameters
+ */
+U_BOOT_IMAGE_TYPE(
+	rksd,
+	"Rockchip SD Boot Image support",
+	RKSD_HEADER_LEN,
+	dummy_hdr,
+	rksd_check_params,
+	rksd_verify_header,
+	rksd_print_header,
+	rksd_set_header,
+	rksd_extract_subimage,
+	rksd_check_image_type,
+	NULL,
+	rksd_vrec_header
+);
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 15/41] rockchip: Add support for the SPI image
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (13 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 14/41] rockchip: Add support for the SD image Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:59   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 16/41] rockchip: gpio: Add rockchip GPIO driver Simon Glass
                   ` (25 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

The Rockchip boot ROM requires a particular file format for booting from SPI.
It consists of a 512-byte header encoded with RC4, some padding and then up
to 32KB of executable code in 2KB blocks, separated by 2KB empty blocks.

Add support to mkimage so that an SPL image (u-boot-spl-dtb.bin) can be
converted to this format. This allows booting from SPI flash on supported
machines.

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

Changes in v5:
- Fix comment in IH_TYPE_RKSPI

Changes in v4: None
Changes in v3: None
Changes in v2: None

 common/image.c  |   1 +
 include/image.h |   3 +-
 tools/rkspi.c   | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 122 insertions(+), 1 deletion(-)
 create mode 100644 tools/rkspi.c

diff --git a/common/image.c b/common/image.c
index 2cdc728..1325e07 100644
--- a/common/image.c
+++ b/common/image.c
@@ -157,6 +157,7 @@ static const table_entry_t uimage_type[] = {
 	{	IH_TYPE_LPC32XXIMAGE, "lpc32xximage",  "LPC32XX Boot Image", },
 	{	IH_TYPE_RKIMAGE,    "rkimage",    "Rockchip Boot Image" },
 	{	IH_TYPE_RKSD,       "rksd",       "Rockchip SD Boot Image" },
+	{	IH_TYPE_RKSPI,      "rkspi",      "Rockchip SPI Boot Image" },
 	{	-1,		    "",		  "",			},
 };
 
diff --git a/include/image.h b/include/image.h
index ea16205..8a864ae 100644
--- a/include/image.h
+++ b/include/image.h
@@ -247,8 +247,9 @@ struct lmb;
 #define IH_TYPE_LOADABLE	22	/* A list of typeless images	*/
 #define IH_TYPE_RKIMAGE		23	/* Rockchip Boot Image		*/
 #define IH_TYPE_RKSD		24	/* Rockchip SD card		*/
+#define IH_TYPE_RKSPI		25	/* Rockchip SPI image		*/
 
-#define IH_TYPE_COUNT		25	/* Number of image types */
+#define IH_TYPE_COUNT		26	/* Number of image types */
 
 /*
  * Compression Types
diff --git a/tools/rkspi.c b/tools/rkspi.c
new file mode 100644
index 0000000..a3c4c73
--- /dev/null
+++ b/tools/rkspi.c
@@ -0,0 +1,119 @@
+/*
+ * (C) Copyright 2015 Google,  Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * See README.rockchip for details of the rkspi format
+ */
+
+#include "imagetool.h"
+#include <image.h>
+#include <rc4.h>
+#include "mkimage.h"
+#include "rkcommon.h"
+
+enum {
+	RKSPI_SPL_HDR_START	= RK_CODE1_OFFSET * RK_BLK_SIZE,
+	RKSPI_SPL_START		= RKSPI_SPL_HDR_START + 4,
+	RKSPI_HEADER_LEN	= RKSPI_SPL_START,
+	RKSPI_SECT_LEN		= RK_BLK_SIZE * 4,
+};
+
+static char dummy_hdr[RKSPI_HEADER_LEN];
+
+static int rkspi_check_params(struct image_tool_params *params)
+{
+	return 0;
+}
+
+static int rkspi_verify_header(unsigned char *buf, int size,
+			       struct image_tool_params *params)
+{
+	return 0;
+}
+
+static void rkspi_print_header(const void *buf)
+{
+}
+
+static void rkspi_set_header(void *buf, struct stat *sbuf, int ifd,
+			     struct image_tool_params *params)
+{
+	int sector;
+	unsigned int size;
+	int ret;
+
+	size = params->orig_file_size;
+	ret = rkcommon_set_header(buf, size);
+	debug("size %x\n", size);
+	if (ret) {
+		/* TODO(sjg at chromium.org): This method should return an error */
+		printf("Warning: SPL image is too large (size %#x) and will not boot\n",
+		       size);
+	}
+
+	memcpy(buf + RKSPI_SPL_HDR_START, "RK32", 4);
+
+	/*
+	 * Spread the image out so we only use the first 2KB of each 4KB
+	 * region. This is a feature of the SPI format required by the Rockchip
+	 * boot ROM. Its rationale is unknown.
+	 */
+	for (sector = size / RKSPI_SECT_LEN - 1; sector >= 0; sector--) {
+		printf("sector %u\n", sector);
+		memmove(buf + sector * RKSPI_SECT_LEN * 2,
+			buf + sector * RKSPI_SECT_LEN,
+			RKSPI_SECT_LEN);
+		memset(buf + sector * RKSPI_SECT_LEN * 2 + RKSPI_SECT_LEN,
+		       '\0', RKSPI_SECT_LEN);
+	}
+}
+
+static int rkspi_extract_subimage(void *buf, struct image_tool_params *params)
+{
+	return 0;
+}
+
+static int rkspi_check_image_type(uint8_t type)
+{
+	if (type == IH_TYPE_RKSPI)
+		return EXIT_SUCCESS;
+	else
+		return EXIT_FAILURE;
+}
+
+/* We pad the file out to a fixed size - this method returns that size */
+static int rkspi_vrec_header(struct image_tool_params *params,
+			     struct image_type_params *tparams)
+{
+	int pad_size;
+
+	pad_size = (RK_MAX_CODE1_SIZE + 0x7ff) / 0x800 * 0x800;
+	params->orig_file_size = pad_size;
+
+	/* We will double the image size due to the SPI format */
+	pad_size *= 2;
+	pad_size += RKSPI_SPL_HDR_START;
+	debug("pad_size %x\n", pad_size);
+
+	return pad_size - params->file_size;
+}
+
+/*
+ * rk_spi parameters
+ */
+U_BOOT_IMAGE_TYPE(
+	rkspi,
+	"Rockchip SPI Boot Image support",
+	RKSPI_HEADER_LEN,
+	dummy_hdr,
+	rkspi_check_params,
+	rkspi_verify_header,
+	rkspi_print_header,
+	rkspi_set_header,
+	rkspi_extract_subimage,
+	rkspi_check_image_type,
+	NULL,
+	rkspi_vrec_header
+);
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 16/41] rockchip: gpio: Add rockchip GPIO driver
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (14 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 15/41] rockchip: Add support for the SPI image Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:59   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 17/41] rockchip: Add basic peripheral and clock definitions Simon Glass
                   ` (24 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

This supports RK3288 at present. It does not implement functions or support
for pull up/down.

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

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arm/include/asm/arch-rockchip/gpio.h |  28 +++++++
 drivers/gpio/Kconfig                      |   9 +++
 drivers/gpio/Makefile                     |   1 +
 drivers/gpio/rk_gpio.c                    | 123 ++++++++++++++++++++++++++++++
 4 files changed, 161 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-rockchip/gpio.h
 create mode 100644 drivers/gpio/rk_gpio.c

diff --git a/arch/arm/include/asm/arch-rockchip/gpio.h b/arch/arm/include/asm/arch-rockchip/gpio.h
new file mode 100644
index 0000000..e39218d
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/gpio.h
@@ -0,0 +1,28 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef _ASM_ARCH_GPIO_H
+#define _ASM_ARCH_GPIO_H
+
+struct rockchip_gpio_regs {
+	u32 swport_dr;
+	u32 swport_ddr;
+	u32 reserved0[(0x30 - 0x08) / 4];
+	u32 inten;
+	u32 intmask;
+	u32 inttype_level;
+	u32 int_polarity;
+	u32 int_status;
+	u32 int_rawstatus;
+	u32 debounce;
+	u32 porta_eoi;
+	u32 ext_port;
+	u32 reserved1[(0x60 - 0x54) / 4];
+	u32 ls_sync;
+};
+check_member(rockchip_gpio_regs, ls_sync, 0x60);
+
+#endif
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 9a5d29d..ef57a89 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -28,6 +28,15 @@ config LPC32XX_GPIO
 	help
 	  Support for the LPC32XX GPIO driver.
 
+config ROCKCHIP_GPIO
+	bool "Rockchip GPIO driver"
+	depends on DM_GPIO
+	help
+	  Support GPIO access on Rockchip SoCs. The GPIOs are arranged into
+	  a number of banks (different for each SoC type) each with 32 GPIOs.
+	  The GPIOs for a device are defined in the device tree with one node
+	  for each bank.
+
 config SANDBOX_GPIO
 	bool "Enable sandbox GPIO driver"
 	depends on SANDBOX && DM && DM_GPIO
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index ba18594..c58aa4d 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_MXC_GPIO)	+= mxc_gpio.o
 obj-$(CONFIG_MXS_GPIO)	+= mxs_gpio.o
 obj-$(CONFIG_PCA953X)		+= pca953x.o
 obj-$(CONFIG_PCA9698)		+= pca9698.o
+obj-$(CONFIG_ROCKCHIP_GPIO)	+= rk_gpio.o
 obj-$(CONFIG_S5P)		+= s5p_gpio.o
 obj-$(CONFIG_SANDBOX_GPIO)	+= sandbox.o
 obj-$(CONFIG_SPEAR_GPIO)	+= spear_gpio.o
diff --git a/drivers/gpio/rk_gpio.c b/drivers/gpio/rk_gpio.c
new file mode 100644
index 0000000..fbdf9f3
--- /dev/null
+++ b/drivers/gpio/rk_gpio.c
@@ -0,0 +1,123 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * (C) Copyright 2008-2014 Rockchip Electronics
+ * Peter, Software Engineering, <superpeter.cai@gmail.com>.
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/errno.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <dt-bindings/gpio/gpio.h>
+
+enum {
+	ROCKCHIP_GPIOS_PER_BANK		= 32,
+};
+
+#define OFFSET_TO_BIT(bit)	(1UL << (bit))
+
+struct rockchip_gpio_priv {
+	struct rockchip_gpio_regs *regs;
+	char name[2];
+};
+
+static int rockchip_gpio_direction_input(struct udevice *dev, unsigned offset)
+{
+	struct rockchip_gpio_priv *priv = dev_get_priv(dev);
+	struct rockchip_gpio_regs *regs = priv->regs;
+
+	clrbits_le32(&regs->swport_ddr, OFFSET_TO_BIT(offset));
+
+	return 0;
+}
+
+static int rockchip_gpio_direction_output(struct udevice *dev, unsigned offset,
+					  int value)
+{
+	struct rockchip_gpio_priv *priv = dev_get_priv(dev);
+	struct rockchip_gpio_regs *regs = priv->regs;
+	int mask = OFFSET_TO_BIT(offset);
+
+	clrsetbits_le32(&regs->swport_dr, mask, value ? mask : 0);
+	setbits_le32(&regs->swport_ddr, mask);
+
+	return 0;
+}
+
+static int rockchip_gpio_get_value(struct udevice *dev, unsigned offset)
+{
+	struct rockchip_gpio_priv *priv = dev_get_priv(dev);
+	struct rockchip_gpio_regs *regs = priv->regs;
+
+	return readl(&regs->ext_port) & OFFSET_TO_BIT(offset);
+}
+
+static int rockchip_gpio_set_value(struct udevice *dev, unsigned offset,
+				   int value)
+{
+	struct rockchip_gpio_priv *priv = dev_get_priv(dev);
+	struct rockchip_gpio_regs *regs = priv->regs;
+	int mask = OFFSET_TO_BIT(offset);
+
+	clrsetbits_le32(&regs->swport_dr, mask, value ? mask : 0);
+
+	return 0;
+}
+
+static int rockchip_gpio_get_function(struct udevice *dev, unsigned offset)
+{
+	return -ENOSYS;
+}
+
+static int rockchip_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
+			    struct fdtdec_phandle_args *args)
+{
+	desc->offset = args->args[0];
+	desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
+
+	return 0;
+}
+
+static int rockchip_gpio_probe(struct udevice *dev)
+{
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct rockchip_gpio_priv *priv = dev_get_priv(dev);
+	char *end;
+	int bank;
+
+	priv->regs = (struct rockchip_gpio_regs *)dev_get_addr(dev);
+	uc_priv->gpio_count = ROCKCHIP_GPIOS_PER_BANK;
+	end = strrchr(dev->name, '@');
+	bank = trailing_strtoln(dev->name, end);
+	priv->name[0] = 'A' + bank;
+	uc_priv->bank_name = priv->name;
+
+	return 0;
+}
+
+static const struct dm_gpio_ops gpio_rockchip_ops = {
+	.direction_input	= rockchip_gpio_direction_input,
+	.direction_output	= rockchip_gpio_direction_output,
+	.get_value		= rockchip_gpio_get_value,
+	.set_value		= rockchip_gpio_set_value,
+	.get_function		= rockchip_gpio_get_function,
+	.xlate			= rockchip_gpio_xlate,
+};
+
+static const struct udevice_id rockchip_gpio_ids[] = {
+	{ .compatible = "rockchip,gpio-bank" },
+	{ }
+};
+
+U_BOOT_DRIVER(gpio_rockchip) = {
+	.name	= "gpio_rockchip",
+	.id	= UCLASS_GPIO,
+	.of_match = rockchip_gpio_ids,
+	.ops	= &gpio_rockchip_ops,
+	.priv_auto_alloc_size = sizeof(struct rockchip_gpio_priv),
+	.probe	= rockchip_gpio_probe,
+};
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 17/41] rockchip: Add basic peripheral and clock definitions
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (15 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 16/41] rockchip: gpio: Add rockchip GPIO driver Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:59   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 18/41] power: Add support for ACT8846 PMIC Simon Glass
                   ` (23 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

Add header files for the peripherals and clocks supported on Rockchip
platforms. The particular implementation (and register set) for each is
SoC-specific, but it seems that the naming can be generic.

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

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arm/include/asm/arch-rockchip/clock.h    | 45 ++++++++++++++++++++++
 arch/arm/include/asm/arch-rockchip/hardware.h | 20 ++++++++++
 arch/arm/include/asm/arch-rockchip/periph.h   | 54 +++++++++++++++++++++++++++
 3 files changed, 119 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-rockchip/clock.h
 create mode 100644 arch/arm/include/asm/arch-rockchip/hardware.h
 create mode 100644 arch/arm/include/asm/arch-rockchip/periph.h

diff --git a/arch/arm/include/asm/arch-rockchip/clock.h b/arch/arm/include/asm/arch-rockchip/clock.h
new file mode 100644
index 0000000..2e5ba86
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/clock.h
@@ -0,0 +1,45 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef _ASM_ARCH_CLOCK_H
+#define _ASM_ARCH_CLOCK_H
+
+/* define pll mode */
+#define RKCLK_PLL_MODE_SLOW		0
+#define RKCLK_PLL_MODE_NORMAL		1
+
+enum {
+	ROCKCHIP_SYSCON_NOC,
+	ROCKCHIP_SYSCON_GRF,
+	ROCKCHIP_SYSCON_SGRF,
+	ROCKCHIP_SYSCON_PMU,
+};
+
+/* Standard Rockchip clock numbers */
+enum rk_clk_id {
+	CLK_OSC,
+	CLK_ARM,
+	CLK_DDR,
+	CLK_CODEC,
+	CLK_GENERAL,
+	CLK_NEW,
+
+	CLK_COUNT,
+};
+
+static inline int rk_pll_id(enum rk_clk_id clk_id)
+{
+	return clk_id - 1;
+}
+
+/**
+ * rockchip_get_cru() - get a pointer to the clock/reset unit registers
+ *
+ * @return pointer to registers, or -ve error on error
+ */
+void *rockchip_get_cru(void);
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/hardware.h b/arch/arm/include/asm/arch-rockchip/hardware.h
new file mode 100644
index 0000000..d5af5b8
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/hardware.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _ASM_ARCH_HARDWARE_H
+#define _ASM_ARCH_HARDWARE_H
+
+#define RK_CLRSETBITS(clr, set)		((((clr) | (set)) << 16) | set)
+#define RK_SETBITS(set)			RK_CLRSETBITS(0, set)
+#define RK_CLRBITS(clr)			RK_CLRSETBITS(clr, 0)
+
+#define TIMER7_BASE		0xff810020
+
+#define rk_clrsetreg(addr, clr, set)	writel((clr) << 16 | (set), addr)
+#define rk_clrreg(addr, clr)		writel((clr) << 16, addr)
+#define rk_setreg(addr, set)		writel(set, addr)
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/periph.h b/arch/arm/include/asm/arch-rockchip/periph.h
new file mode 100644
index 0000000..fa6069b
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/periph.h
@@ -0,0 +1,54 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef _ASM_ARCH_PERIPH_H
+#define _ASM_ARCH_PERIPH_H
+
+/*
+ * The peripherals supported by the hardware. This is used to specify clocks
+ * and pinctrl settings. Some SoCs will not support all of these, but it
+ * provides a common reference for common drivers to use.
+ */
+enum periph_id {
+	PERIPH_ID_PWM0,
+	PERIPH_ID_PWM1,
+	PERIPH_ID_PWM2,
+	PERIPH_ID_PWM3,
+	PERIPH_ID_PWM4,
+	PERIPH_ID_I2C0,
+	PERIPH_ID_I2C1,
+	PERIPH_ID_I2C2,
+	PERIPH_ID_I2C3,
+	PERIPH_ID_I2C4,
+	PERIPH_ID_I2C5,
+	PERIPH_ID_SPI0,
+	PERIPH_ID_SPI1,
+	PERIPH_ID_SPI2,
+	PERIPH_ID_UART0,
+	PERIPH_ID_UART1,
+	PERIPH_ID_UART2,
+	PERIPH_ID_UART3,
+	PERIPH_ID_UART4,
+	PERIPH_ID_LCDC0,
+	PERIPH_ID_LCDC1,
+	PERIPH_ID_SDMMC0,
+	PERIPH_ID_SDMMC1,
+	PERIPH_ID_SDMMC2,
+	PERIPH_ID_HDMI,
+
+	PERIPH_ID_COUNT,
+
+	/* Some aliases */
+	PERIPH_ID_EMMC = PERIPH_ID_SDMMC0,
+	PERIPH_ID_SDCARD = PERIPH_ID_SDMMC1,
+	PERIPH_ID_UART_BT = PERIPH_ID_UART0,
+	PERIPH_ID_UART_BB = PERIPH_ID_UART1,
+	PERIPH_ID_UART_DBG = PERIPH_ID_UART2,
+	PERIPH_ID_UART_GPS = PERIPH_ID_UART3,
+	PERIPH_ID_UART_EXP = PERIPH_ID_UART4,
+};
+
+#endif
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 18/41] power: Add support for ACT8846 PMIC
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (16 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 17/41] rockchip: Add basic peripheral and clock definitions Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:59   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 19/41] power: regulator: Add a driver for ACT8846 regulators Simon Glass
                   ` (22 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

Add a driver for the ACT8846 PMIC. This supports several LDOs and BUCKs and
is connected to the I2C bus. This driver supports using a regulator driver
to access the regulators.

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

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/power/pmic/Kconfig   |  9 +++++
 drivers/power/pmic/Makefile  |  1 +
 drivers/power/pmic/act8846.c | 90 ++++++++++++++++++++++++++++++++++++++++++++
 include/power/act8846_pmic.h | 37 ++++++++++++++++++
 4 files changed, 137 insertions(+)
 create mode 100644 drivers/power/pmic/act8846.c
 create mode 100644 include/power/act8846_pmic.h

diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig
index fc6a374..547fd1a 100644
--- a/drivers/power/pmic/Kconfig
+++ b/drivers/power/pmic/Kconfig
@@ -10,6 +10,15 @@ config DM_PMIC
 	- 'drivers/power/pmic/pmic-uclass.c'
 	- 'include/power/pmic.h'
 
+config PMIC_ACT8846
+	bool "Enable support for the active-semi 8846 PMIC"
+	depends on DM_PMIC && DM_I2C
+	---help---
+	This PMIC includes 4 DC/DC step-down buck regulators and 8 low-dropout
+	regulators (LDOs). It also provides some GPIO, reset and battery
+	functions. It uses an I2C interface and is designed for use with
+	tablets and smartphones.
+
 config DM_PMIC_PFUZE100
 	bool "Enable Driver Model for PMIC PFUZE100"
 	depends on DM_PMIC
diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile
index 99c5778..8f6463e 100644
--- a/drivers/power/pmic/Makefile
+++ b/drivers/power/pmic/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_DM_PMIC) += pmic-uclass.o
 obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o
 obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze100.o
 obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o
+obj-$(CONFIG_PMIC_ACT8846) += act8846.o
 obj-$(CONFIG_PMIC_TPS65090) += tps65090.o
 obj-$(CONFIG_PMIC_S5M8767) += s5m8767.o
 
diff --git a/drivers/power/pmic/act8846.c b/drivers/power/pmic/act8846.c
new file mode 100644
index 0000000..ff096b3
--- /dev/null
+++ b/drivers/power/pmic/act8846.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <libfdt.h>
+#include <power/act8846_pmic.h>
+#include <power/pmic.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const struct pmic_child_info pmic_children_info[] = {
+	{ .prefix = "REG", .driver = "act8846_reg"},
+	{ },
+};
+
+static int act8846_reg_count(struct udevice *dev)
+{
+	return ACT8846_NUM_OF_REGS;
+}
+
+static int act8846_write(struct udevice *dev, uint reg, const uint8_t *buff,
+			  int len)
+{
+	if (dm_i2c_write(dev, reg, buff, len)) {
+		debug("write error to device: %p register: %#x!", dev, reg);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int act8846_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
+{
+	if (dm_i2c_read(dev, reg, buff, len)) {
+		debug("read error from device: %p register: %#x!", dev, reg);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int act8846_bind(struct udevice *dev)
+{
+	const void *blob = gd->fdt_blob;
+	int regulators_node;
+	int children;
+
+	regulators_node = fdt_subnode_offset(blob, dev->of_offset,
+					     "regulators");
+	if (regulators_node <= 0) {
+		debug("%s: %s regulators subnode not found!", __func__,
+		      dev->name);
+		return -ENXIO;
+	}
+
+	debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
+
+	children = pmic_bind_children(dev, regulators_node, pmic_children_info);
+	if (!children)
+		debug("%s: %s - no child found\n", __func__, dev->name);
+
+	/* Always return success for this device */
+	return 0;
+}
+
+static struct dm_pmic_ops act8846_ops = {
+	.reg_count = act8846_reg_count,
+	.read = act8846_read,
+	.write = act8846_write,
+};
+
+static const struct udevice_id act8846_ids[] = {
+	{ .compatible = "active-semi,act8846" },
+	{ }
+};
+
+U_BOOT_DRIVER(pmic_act8846) = {
+	.name = "act8846 pmic",
+	.id = UCLASS_PMIC,
+	.of_match = act8846_ids,
+	.bind = act8846_bind,
+	.ops = &act8846_ops,
+};
diff --git a/include/power/act8846_pmic.h b/include/power/act8846_pmic.h
new file mode 100644
index 0000000..a811f28
--- /dev/null
+++ b/include/power/act8846_pmic.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _PMIC_ACT8846_H_
+#define _PMIC_ACT8846_H_
+
+#include <asm/gpio.h>
+
+#define ACT8846_NUM_OF_REGS	12
+
+#define BUCK_VOL_MASK 0x3f
+#define LDO_VOL_MASK 0x3f
+
+#define BUCK_EN_MASK 0x80
+#define LDO_EN_MASK 0x80
+
+#define VOL_MIN_IDX 0x00
+#define VOL_MAX_IDX 0x3f
+
+struct  act8846_reg_table {
+	char	*name;
+	char	reg_ctl;
+	char	reg_vol;
+};
+
+struct pmic_act8846 {
+	struct pmic *pmic;
+	int node;	/*device tree node*/
+	struct gpio_desc pwr_hold;
+	struct udevice *dev;
+};
+
+#endif
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 19/41] power: regulator: Add a driver for ACT8846 regulators
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (17 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 18/41] power: Add support for ACT8846 PMIC Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:59   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 20/41] rockchip: rk3288: Add clock driver Simon Glass
                   ` (21 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

Add a full regulator driver for the ACT8846. This provides easy access to
voltage and current settings for each regulator.

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

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/power/regulator/Kconfig   |   9 +++
 drivers/power/regulator/Makefile  |   1 +
 drivers/power/regulator/act8846.c | 155 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 165 insertions(+)
 create mode 100644 drivers/power/regulator/act8846.c

diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig
index 77d64e4..434dd02 100644
--- a/drivers/power/regulator/Kconfig
+++ b/drivers/power/regulator/Kconfig
@@ -16,6 +16,15 @@ config DM_REGULATOR
 	for this purpose if PMIC I/O driver is implemented or dm_scan_fdt_node()
 	otherwise. Detailed information can be found in the header file.
 
+config REGULATOR_ACT8846
+	bool "Enable driver for ACT8846 regulator"
+	depends on DM_REGULATOR && PMIC_ACT8846
+	---help---
+	Enable support for the regulator functions of the ACT8846 PMIC. The
+	driver implements get/set api for the various BUCKS and LDOS supported
+	by the PMIC device. This driver is controlled by a device tree node
+	which includes voltage limits.
+
 config DM_REGULATOR_PFUZE100
 	bool "Enable Driver Model for REGULATOR PFUZE100"
 	depends on DM_REGULATOR && DM_PMIC_PFUZE100
diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile
index 7035936..c85978e 100644
--- a/drivers/power/regulator/Makefile
+++ b/drivers/power/regulator/Makefile
@@ -6,6 +6,7 @@
 #
 
 obj-$(CONFIG_DM_REGULATOR) += regulator-uclass.o
+obj-$(CONFIG_REGULATOR_ACT8846) += act8846.o
 obj-$(CONFIG_DM_REGULATOR_MAX77686) += max77686.o
 obj-$(CONFIG_DM_REGULATOR_PFUZE100) += pfuze100.o
 obj-$(CONFIG_DM_REGULATOR_FIXED) += fixed.o
diff --git a/drivers/power/regulator/act8846.c b/drivers/power/regulator/act8846.c
new file mode 100644
index 0000000..255f8b0
--- /dev/null
+++ b/drivers/power/regulator/act8846.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * Based on Rockchip's drivers/power/pmic/pmic_act8846.c:
+ * Copyright (C) 2012 rockchips
+ * zyw <zyw@rock-chips.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <power/act8846_pmic.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+
+static const u16 voltage_map[] = {
+	600, 625, 650, 675, 700, 725, 750, 775,
+	800, 825, 850, 875, 900, 925, 950, 975,
+	1000, 1025, 1050, 1075, 1100, 1125, 1150, 1175,
+	1200, 1250, 1300, 1350, 1400, 1450, 1500, 1550,
+	1600, 1650, 1700, 1750, 1800, 1850, 1900, 1950,
+	2000, 2050, 2100, 2150, 2200, 2250, 2300, 2350,
+	2400, 2500, 2600, 2700, 2800, 2900, 3000, 3100,
+	3200, 3300, 3400, 3500, 3600, 3700, 3800, 3900,
+};
+
+enum {
+	REG_SYS0,
+	REG_SYS1,
+	REG1_VOL	= 0x10,
+	REG1_CTL	= 0X11,
+	REG2_VOL0	= 0x20,
+	REG2_VOL1,
+	REG2_CTL,
+	REG3_VOL0	= 0x30,
+	REG3_VOL1,
+	REG3_CTL,
+	REG4_VOL0	= 0x40,
+	REG4_VOL1,
+	REG4_CTL,
+	REG5_VOL	= 0x50,
+	REG5_CTL,
+	REG6_VOL	= 0X58,
+	REG6_CTL,
+	REG7_VOL	= 0x60,
+	REG7_CTL,
+	REG8_VOL	= 0x68,
+	REG8_CTL,
+	REG9_VOL	= 0x70,
+	REG9_CTL,
+	REG10_VOL	= 0x80,
+	REG10_CTL,
+	REG11_VOL	= 0x90,
+	REG11_CTL,
+	REG12_VOL	= 0xa0,
+	REG12_CTL,
+	REG13		= 0xb1,
+};
+
+static const u8 addr_vol[] = {
+	0, REG1_VOL, REG2_VOL0, REG3_VOL0, REG4_VOL0,
+	REG5_VOL, REG6_VOL, REG7_VOL, REG8_VOL, REG9_VOL,
+	REG10_VOL, REG11_VOL, REG12_VOL,
+};
+
+static const u8 addr_ctl[] = {
+	0, REG1_CTL, REG2_CTL, REG3_CTL, REG4_CTL,
+	REG5_CTL, REG6_CTL, REG7_CTL, REG8_CTL, REG9_CTL,
+	REG10_CTL, REG11_CTL, REG12_CTL,
+};
+
+static int check_volt_table(const u16 *volt_table, int uvolt)
+{
+	int i;
+
+	for (i = VOL_MIN_IDX; i < VOL_MAX_IDX; i++) {
+		if (uvolt <= (volt_table[i] * 1000))
+			return i;
+	}
+	return -EINVAL;
+}
+
+static int reg_get_value(struct udevice *dev)
+{
+	int reg = dev->driver_data;
+	int ret;
+
+	ret = pmic_reg_read(dev->parent, reg);
+	if (ret < 0)
+		return ret;
+
+	return voltage_map[ret & LDO_VOL_MASK] * 1000;
+}
+
+static int reg_set_value(struct udevice *dev, int uvolt)
+{
+	int reg = dev->driver_data;
+	int val;
+
+	val = check_volt_table(voltage_map, uvolt);
+	if (val < 0)
+		return val;
+
+	return pmic_clrsetbits(dev->parent, addr_vol[reg], LDO_VOL_MASK, val);
+}
+
+static int reg_set_enable(struct udevice *dev, bool enable)
+{
+	int reg = dev->driver_data;
+
+	return pmic_clrsetbits(dev->parent, addr_ctl[reg], LDO_EN_MASK,
+			       enable ? LDO_EN_MASK : 0);
+}
+
+static bool reg_get_enable(struct udevice *dev)
+{
+	int reg = dev->driver_data;
+	int ret;
+
+	ret = pmic_reg_read(dev->parent, reg);
+	if (ret < 0)
+		return ret;
+
+	return ret & LDO_EN_MASK ? true : false;
+}
+
+static int act8846_reg_probe(struct udevice *dev)
+{
+	struct dm_regulator_uclass_platdata *uc_pdata;
+	int reg = dev->driver_data;
+
+	uc_pdata = dev_get_uclass_platdata(dev);
+
+	uc_pdata->type = reg <= 4 ? REGULATOR_TYPE_BUCK : REGULATOR_TYPE_LDO;
+	uc_pdata->mode_count = 0;
+
+	return 0;
+}
+
+static const struct dm_regulator_ops act8846_reg_ops = {
+	.get_value  = reg_get_value,
+	.set_value  = reg_set_value,
+	.get_enable = reg_get_enable,
+	.set_enable = reg_set_enable,
+};
+
+U_BOOT_DRIVER(act8846_buck) = {
+	.name = "act8846_reg",
+	.id = UCLASS_REGULATOR,
+	.ops = &act8846_reg_ops,
+	.probe = act8846_reg_probe,
+};
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 20/41] rockchip: rk3288: Add clock driver
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (18 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 19/41] power: regulator: Add a driver for ACT8846 regulators Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:59   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 21/41] rockchip: rk3288: Add header files for PMU and GRF Simon Glass
                   ` (20 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

Add a driver for setting up and modifying the various PLLs and peripheral
clocks on the RK3288.

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

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arm/include/asm/arch-rockchip/cru_rk3288.h | 185 +++++++
 drivers/clk/Makefile                            |   1 +
 drivers/clk/clk_rk3288.c                        | 618 ++++++++++++++++++++++++
 3 files changed, 804 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rk3288.h
 create mode 100644 drivers/clk/clk_rk3288.c

diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3288.h b/arch/arm/include/asm/arch-rockchip/cru_rk3288.h
new file mode 100644
index 0000000..7ebcc40
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3288.h
@@ -0,0 +1,185 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * (C) Copyright 2008-2014 Rockchip Electronics
+ * Peter, Software Engineering, <superpeter.cai@gmail.com>.
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef _ASM_ARCH_CRU_RK3288_H
+#define _ASM_ARCH_CRU_RK3288_H
+
+#define OSC_HZ		(24 * 1000 * 1000)
+
+#define APLL_HZ		(1800 * 1000000)
+#define GPLL_HZ		(594 * 1000000)
+#define CPLL_HZ		(384 * 1000000)
+#define NPLL_HZ		(384 * 1000000)
+
+/* The SRAM is clocked off aclk_bus, so we want to max it out for boot speed */
+#define PD_BUS_ACLK_HZ	297000000
+#define PD_BUS_HCLK_HZ	148500000
+#define PD_BUS_PCLK_HZ	74250000
+
+#define PERI_ACLK_HZ	148500000
+#define PERI_HCLK_HZ	148500000
+#define PERI_PCLK_HZ	74250000
+
+struct rk3288_cru {
+	struct rk3288_pll {
+		u32 con0;
+		u32 con1;
+		u32 con2;
+		u32 con3;
+	} pll[5];
+	u32 cru_mode_con;
+	u32 reserved0[3];
+	u32 cru_clksel_con[43];
+	u32 reserved1[21];
+	u32 cru_clkgate_con[19];
+	u32 reserved2;
+	u32 cru_glb_srst_fst_value;
+	u32 cru_glb_srst_snd_value;
+	u32 cru_softrst_con[12];
+	u32 cru_misc_con;
+	u32 cru_glb_cnt_th;
+	u32 cru_glb_rst_con;
+	u32 reserved3;
+	u32 cru_glb_rst_st;
+	u32 reserved4;
+	u32 cru_sdmmc_con[2];
+	u32 cru_sdio0_con[2];
+	u32 cru_sdio1_con[2];
+	u32 cru_emmc_con[2];
+};
+check_member(rk3288_cru, cru_emmc_con[1], 0x021c);
+
+/* CRU_CLKSEL11_CON */
+enum {
+	HSICPHY_DIV_SHIFT	= 8,
+	HSICPHY_DIV_MASK	= 0x3f,
+
+	MMC0_PLL_SHIFT		= 6,
+	MMC0_PLL_MASK		= 3,
+	MMC0_PLL_SELECT_CODEC	= 0,
+	MMC0_PLL_SELECT_GENERAL,
+	MMC0_PLL_SELECT_24MHZ,
+
+	MMC0_DIV_SHIFT		= 0,
+	MMC0_DIV_MASK		= 0x3f,
+};
+
+/* CRU_CLKSEL12_CON */
+enum {
+	EMMC_PLL_SHIFT		= 0xe,
+	EMMC_PLL_MASK		= 3,
+	EMMC_PLL_SELECT_CODEC	= 0,
+	EMMC_PLL_SELECT_GENERAL,
+	EMMC_PLL_SELECT_24MHZ,
+
+	EMMC_DIV_SHIFT		= 8,
+	EMMC_DIV_MASK		= 0x3f,
+
+	SDIO0_PLL_SHIFT		= 6,
+	SDIO0_PLL_MASK		= 3,
+	SDIO0_PLL_SELECT_CODEC	= 0,
+	SDIO0_PLL_SELECT_GENERAL,
+	SDIO0_PLL_SELECT_24MHZ,
+
+	SDIO0_DIV_SHIFT		= 0,
+	SDIO0_DIV_MASK		= 0x3f,
+};
+
+/* CRU_CLKSEL25_CON */
+enum {
+	SPI1_PLL_SHIFT		= 0xf,
+	SPI1_PLL_MASK		= 1,
+	SPI1_PLL_SELECT_CODEC	= 0,
+	SPI1_PLL_SELECT_GENERAL,
+
+	SPI1_DIV_SHIFT		= 8,
+	SPI1_DIV_MASK		= 0x7f,
+
+	SPI0_PLL_SHIFT		= 7,
+	SPI0_PLL_MASK		= 1,
+	SPI0_PLL_SELECT_CODEC	= 0,
+	SPI0_PLL_SELECT_GENERAL,
+
+	SPI0_DIV_SHIFT		= 0,
+	SPI0_DIV_MASK		= 0x7f,
+};
+
+/* CRU_CLKSEL39_CON */
+enum {
+	ACLK_HEVC_PLL_SHIFT	= 0xe,
+	ACLK_HEVC_PLL_MASK	= 3,
+	ACLK_HEVC_PLL_SELECT_CODEC = 0,
+	ACLK_HEVC_PLL_SELECT_GENERAL,
+	ACLK_HEVC_PLL_SELECT_NEW,
+
+	ACLK_HEVC_DIV_SHIFT	= 8,
+	ACLK_HEVC_DIV_MASK	= 0x1f,
+
+	SPI2_PLL_SHIFT		= 7,
+	SPI2_PLL_MASK		= 1,
+	SPI2_PLL_SELECT_CODEC	= 0,
+	SPI2_PLL_SELECT_GENERAL,
+
+	SPI2_DIV_SHIFT		= 0,
+	SPI2_DIV_MASK		= 0x7f,
+};
+
+/* CRU_MODE_CON */
+enum {
+	NPLL_WORK_SHIFT		= 0xe,
+	NPLL_WORK_MASK		= 3,
+	NPLL_WORK_SLOW		= 0,
+	NPLL_WORK_NORMAL,
+	NPLL_WORK_DEEP,
+
+	GPLL_WORK_SHIFT		= 0xc,
+	GPLL_WORK_MASK		= 3,
+	GPLL_WORK_SLOW		= 0,
+	GPLL_WORK_NORMAL,
+	GPLL_WORK_DEEP,
+
+	CPLL_WORK_SHIFT		= 8,
+	CPLL_WORK_MASK		= 3,
+	CPLL_WORK_SLOW		= 0,
+	CPLL_WORK_NORMAL,
+	CPLL_WORK_DEEP,
+
+	DPLL_WORK_SHIFT		= 4,
+	DPLL_WORK_MASK		= 3,
+	DPLL_WORK_SLOW		= 0,
+	DPLL_WORK_NORMAL,
+	DPLL_WORK_DEEP,
+
+	APLL_WORK_SHIFT		= 0,
+	APLL_WORK_MASK		= 3,
+	APLL_WORK_SLOW		= 0,
+	APLL_WORK_NORMAL,
+	APLL_WORK_DEEP,
+};
+
+/* CRU_APLL_CON0 */
+enum {
+	CLKR_SHIFT		= 8,
+	CLKR_MASK		= 0x3f,
+
+	CLKOD_SHIFT		= 0,
+	CLKOD_MASK		= 0xf,
+};
+
+/* CRU_APLL_CON1 */
+enum {
+	LOCK_SHIFT		= 0x1f,
+	LOCK_MASK		= 1,
+	LOCK_UNLOCK		= 0,
+	LOCK_LOCK,
+
+	CLKF_SHIFT		= 0,
+	CLKF_MASK		= 0x1fff,
+};
+
+#endif
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index bb89fb9..008ec10 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -6,4 +6,5 @@
 #
 
 obj-$(CONFIG_CLK) += clk-uclass.o
+obj-$(CONFIG_ROCKCHIP_RK3288) += clk_rk3288.o
 obj-$(CONFIG_SANDBOX) += clk_sandbox.o
diff --git a/drivers/clk/clk_rk3288.c b/drivers/clk/clk_rk3288.c
new file mode 100644
index 0000000..54d4930
--- /dev/null
+++ b/drivers/clk/clk_rk3288.c
@@ -0,0 +1,618 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3288.h>
+#include <asm/arch/grf_rk3288.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/periph.h>
+#include <dm/lists.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct rk3288_clk_plat {
+	enum rk_clk_id clk_id;
+};
+
+struct rk3288_clk_priv {
+	struct rk3288_grf *grf;
+	struct rk3288_cru *cru;
+	ulong rate;
+};
+
+struct pll_div {
+	u32 nr;
+	u32 nf;
+	u32 no;
+};
+
+enum {
+	VCO_MAX_HZ	= 2200U * 1000000,
+	VCO_MIN_HZ	= 440 * 1000000,
+	OUTPUT_MAX_HZ	= 2200U * 1000000,
+	OUTPUT_MIN_HZ	= 27500000,
+	FREF_MAX_HZ	= 2200U * 1000000,
+	FREF_MIN_HZ	= 269 * 1000000,
+};
+
+enum {
+	/* PLL CON0 */
+	PLL_OD_MASK		= 0x0f,
+
+	/* PLL CON1 */
+	PLL_NF_MASK		= 0x1fff,
+
+	/* PLL CON2 */
+	PLL_BWADJ_MASK		= 0x0fff,
+
+	/* PLL CON3 */
+	PLL_RESET_SHIFT		= 5,
+
+	/* CLKSEL1: pd bus clk pll sel: codec or general */
+	PD_BUS_SEL_PLL_MASK	= 15,
+	PD_BUS_SEL_CPLL		= 0,
+	PD_BUS_SEL_GPLL,
+
+	/* pd bus pclk div: pclk = pd_bus_aclk /(div + 1) */
+	PD_BUS_PCLK_DIV_SHIFT	= 12,
+	PD_BUS_PCLK_DIV_MASK	= 7,
+
+	/* pd bus hclk div: aclk_bus: hclk_bus = 1:1 or 2:1 or 4:1 */
+	PD_BUS_HCLK_DIV_SHIFT	= 8,
+	PD_BUS_HCLK_DIV_MASK	= 3,
+
+	/* pd bus aclk div: pd_bus_aclk = pd_bus_src_clk /(div0 * div1) */
+	PD_BUS_ACLK_DIV0_SHIFT	= 3,
+	PD_BUS_ACLK_DIV0_MASK	= 0x1f,
+	PD_BUS_ACLK_DIV1_SHIFT	= 0,
+	PD_BUS_ACLK_DIV1_MASK	= 0x7,
+
+	/*
+	 * CLKSEL10
+	 * peripheral bus pclk div:
+	 * aclk_bus: pclk_bus = 1:1 or 2:1 or 4:1 or 8:1
+	 */
+	PERI_PCLK_DIV_SHIFT	= 12,
+	PERI_PCLK_DIV_MASK	= 7,
+
+	/* peripheral bus hclk div: aclk_bus: hclk_bus = 1:1 or 2:1 or 4:1 */
+	PERI_HCLK_DIV_SHIFT	= 8,
+	PERI_HCLK_DIV_MASK	= 3,
+
+	/*
+	 * peripheral bus aclk div:
+	 *    aclk_periph = periph_clk_src / (peri_aclk_div_con + 1)
+	 */
+	PERI_ACLK_DIV_SHIFT	= 0,
+	PERI_ACLK_DIV_MASK	= 0x1f,
+
+	/* CLKSEL37 */
+	DPLL_MODE_MASK		= 0x3,
+	DPLL_MODE_SHIFT		= 4,
+	DPLL_MODE_SLOW		= 0,
+	DPLL_MODE_NORM,
+
+	CPLL_MODE_MASK		= 3,
+	CPLL_MODE_SHIFT		= 8,
+	CPLL_MODE_SLOW		= 0,
+	CPLL_MODE_NORM,
+
+	GPLL_MODE_MASK		= 3,
+	GPLL_MODE_SHIFT		= 12,
+	GPLL_MODE_SLOW		= 0,
+	GPLL_MODE_NORM,
+
+	NPLL_MODE_MASK		= 3,
+	NPLL_MODE_SHIFT		= 14,
+	NPLL_MODE_SLOW		= 0,
+	NPLL_MODE_NORM,
+
+	SOCSTS_DPLL_LOCK	= 1 << 5,
+	SOCSTS_APLL_LOCK	= 1 << 6,
+	SOCSTS_CPLL_LOCK	= 1 << 7,
+	SOCSTS_GPLL_LOCK	= 1 << 8,
+	SOCSTS_NPLL_LOCK	= 1 << 9,
+};
+
+#define RATE_TO_DIV(input_rate, output_rate) \
+	((input_rate) / (output_rate) - 1);
+
+#define DIV_TO_RATE(input_rate, div)	((input_rate) / ((div) + 1))
+
+#define PLL_DIVISORS(hz, _nr, _no) {\
+	.nr = _nr, .nf = (u32)((u64)hz * _nr * _no / OSC_HZ), .no = _no};\
+	_Static_assert(((u64)hz * _nr * _no / OSC_HZ) * OSC_HZ /\
+		       (_nr * _no) == hz, #hz "Hz cannot be hit with PLL "\
+		       "divisors on line " __stringify(__LINE__));
+
+/* Keep divisors as low as possible to reduce jitter and power usage */
+static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 1);
+static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2);
+static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2);
+
+static int rkclk_set_pll(struct rk3288_cru *cru, enum rk_clk_id clk_id,
+			 const struct pll_div *div)
+{
+	int pll_id = rk_pll_id(clk_id);
+	struct rk3288_pll *pll = &cru->pll[pll_id];
+	/* All PLLs have same VCO and output frequency range restrictions. */
+	uint vco_hz = OSC_HZ / 1000 * div->nf / div->nr * 1000;
+	uint output_hz = vco_hz / div->no;
+
+	debug("PLL at %p: nf=%d, nr=%d, no=%d, vco=%u Hz, output=%u Hz\n",
+	      pll, div->nf, div->nr, div->no, vco_hz, output_hz);
+	assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
+	       output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ &&
+	       (div->no == 1 || !(div->no % 2)));
+
+	/* enter rest */
+	rk_setreg(&pll->con3, 1 << PLL_RESET_SHIFT);
+
+	rk_clrsetreg(&pll->con0,
+		     CLKR_MASK << CLKR_SHIFT | PLL_OD_MASK,
+		     ((div->nr - 1) << CLKR_SHIFT) | (div->no - 1));
+	rk_clrsetreg(&pll->con1, CLKF_MASK, div->nf - 1);
+	rk_clrsetreg(&pll->con2, PLL_BWADJ_MASK, (div->nf >> 1) - 1);
+
+	udelay(10);
+
+	/* return form rest */
+	rk_clrreg(&pll->con3, 1 << PLL_RESET_SHIFT);
+
+	return 0;
+}
+
+static inline unsigned int log2(unsigned int value)
+{
+	return fls(value) - 1;
+}
+
+static int rkclk_configure_ddr(struct rk3288_cru *cru, struct rk3288_grf *grf,
+			       unsigned int hz)
+{
+	static const struct pll_div dpll_cfg[] = {
+		{.nf = 25, .nr = 2, .no = 1},
+		{.nf = 400, .nr = 9, .no = 2},
+		{.nf = 500, .nr = 9, .no = 2},
+		{.nf = 100, .nr = 3, .no = 1},
+	};
+	int cfg;
+
+	debug("%s: cru=%p, grf=%p, hz=%u\n", __func__, cru, grf, hz);
+	switch (hz) {
+	case 300000000:
+		cfg = 0;
+		break;
+	case 533000000:	/* actually 533.3P MHz */
+		cfg = 1;
+		break;
+	case 666000000:	/* actually 666.6P MHz */
+		cfg = 2;
+		break;
+	case 800000000:
+		cfg = 3;
+		break;
+	default:
+		debug("Unsupported SDRAM frequency, add to clock.c!");
+		return -EINVAL;
+	}
+
+	/* pll enter slow-mode */
+	rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK << DPLL_MODE_SHIFT,
+		     DPLL_MODE_SLOW << DPLL_MODE_SHIFT);
+
+	rkclk_set_pll(cru, CLK_DDR, &dpll_cfg[cfg]);
+
+	/* wait for pll lock */
+	while (!(readl(&grf->soc_status[1]) & SOCSTS_DPLL_LOCK))
+		udelay(1);
+
+	/* PLL enter normal-mode */
+	rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK << DPLL_MODE_SHIFT,
+		     DPLL_MODE_NORM << DPLL_MODE_SHIFT);
+
+	return 0;
+}
+
+#ifdef CONFIG_SPL_BUILD
+static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf)
+{
+	u32 aclk_div;
+	u32 hclk_div;
+	u32 pclk_div;
+
+	/* pll enter slow-mode */
+	rk_clrsetreg(&cru->cru_mode_con,
+		     GPLL_MODE_MASK << GPLL_MODE_SHIFT |
+		     CPLL_MODE_MASK << CPLL_MODE_SHIFT,
+		     GPLL_MODE_SLOW << GPLL_MODE_SHIFT |
+		     CPLL_MODE_SLOW << CPLL_MODE_SHIFT);
+
+	/* init pll */
+	rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
+	rkclk_set_pll(cru, CLK_CODEC, &cpll_init_cfg);
+
+	/* waiting for pll lock */
+	while ((readl(&grf->soc_status[1]) &
+			(SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK)) !=
+			(SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK))
+		udelay(1);
+
+	/*
+	 * pd_bus clock pll source selection and
+	 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+	 */
+	aclk_div = GPLL_HZ / PD_BUS_ACLK_HZ - 1;
+	assert((aclk_div + 1) * PD_BUS_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
+	hclk_div = PD_BUS_ACLK_HZ / PD_BUS_HCLK_HZ - 1;
+	assert((hclk_div + 1) * PD_BUS_HCLK_HZ ==
+		PD_BUS_ACLK_HZ && (hclk_div < 0x4) && (hclk_div != 0x2));
+
+	pclk_div = PD_BUS_ACLK_HZ / PD_BUS_PCLK_HZ - 1;
+	assert((pclk_div + 1) * PD_BUS_PCLK_HZ ==
+		PD_BUS_ACLK_HZ && pclk_div < 0x7);
+
+	rk_clrsetreg(&cru->cru_clksel_con[1],
+		     PD_BUS_PCLK_DIV_MASK << PD_BUS_PCLK_DIV_SHIFT |
+		     PD_BUS_HCLK_DIV_MASK << PD_BUS_HCLK_DIV_SHIFT |
+		     PD_BUS_ACLK_DIV0_MASK << PD_BUS_ACLK_DIV0_SHIFT |
+		     PD_BUS_ACLK_DIV1_MASK << PD_BUS_ACLK_DIV1_SHIFT,
+		     pclk_div << PD_BUS_PCLK_DIV_SHIFT |
+		     hclk_div << PD_BUS_HCLK_DIV_SHIFT |
+		     aclk_div << PD_BUS_ACLK_DIV0_SHIFT |
+		     0 << 0);
+
+	/*
+	 * peri clock pll source selection and
+	 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+	 */
+	aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1;
+	assert((aclk_div + 1) * PERI_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
+
+	hclk_div = log2(PERI_ACLK_HZ / PERI_HCLK_HZ);
+	assert((1 << hclk_div) * PERI_HCLK_HZ ==
+		PERI_ACLK_HZ && (hclk_div < 0x4));
+
+	pclk_div = log2(PERI_ACLK_HZ / PERI_PCLK_HZ);
+	assert((1 << pclk_div) * PERI_PCLK_HZ ==
+		PERI_ACLK_HZ && (pclk_div < 0x4));
+
+	rk_clrsetreg(&cru->cru_clksel_con[10],
+		     PERI_PCLK_DIV_MASK << PERI_PCLK_DIV_SHIFT |
+		     PERI_HCLK_DIV_MASK << PERI_HCLK_DIV_SHIFT |
+		     PERI_ACLK_DIV_MASK << PERI_ACLK_DIV_SHIFT,
+		     pclk_div << PERI_PCLK_DIV_SHIFT |
+		     hclk_div << PERI_HCLK_DIV_SHIFT |
+		     aclk_div << PERI_ACLK_DIV_SHIFT);
+
+	/* PLL enter normal-mode */
+	rk_clrsetreg(&cru->cru_mode_con,
+		     GPLL_MODE_MASK << GPLL_MODE_SHIFT |
+		     CPLL_MODE_MASK << CPLL_MODE_SHIFT,
+		     GPLL_MODE_NORM << GPLL_MODE_SHIFT |
+		     GPLL_MODE_NORM << CPLL_MODE_SHIFT);
+}
+#endif
+
+/* Get pll rate by id */
+static uint32_t rkclk_pll_get_rate(struct rk3288_cru *cru,
+				   enum rk_clk_id clk_id)
+{
+	uint32_t nr, no, nf;
+	uint32_t con;
+	int pll_id = rk_pll_id(clk_id);
+	struct rk3288_pll *pll = &cru->pll[pll_id];
+	static u8 clk_shift[CLK_COUNT] = {
+		0xff, APLL_WORK_SHIFT, DPLL_WORK_SHIFT, CPLL_WORK_SHIFT,
+		GPLL_WORK_SHIFT, NPLL_WORK_SHIFT
+	};
+	uint shift;
+
+	con = readl(&cru->cru_mode_con);
+	shift = clk_shift[clk_id];
+	switch ((con >> shift) & APLL_WORK_MASK) {
+	case APLL_WORK_SLOW:
+		return OSC_HZ;
+	case APLL_WORK_NORMAL:
+		/* normal mode */
+		con = readl(&pll->con0);
+		no = ((con >> CLKOD_SHIFT) & CLKOD_MASK) + 1;
+		nr = ((con >> CLKR_SHIFT) & CLKR_MASK) + 1;
+		con = readl(&pll->con1);
+		nf = ((con >> CLKF_SHIFT) & CLKF_MASK) + 1;
+
+		return (24 * nf / (nr * no)) * 1000000;
+	case APLL_WORK_DEEP:
+	default:
+		return 32768;
+	}
+}
+
+static ulong rk3288_clk_get_rate(struct udevice *dev)
+{
+	struct rk3288_clk_plat *plat = dev_get_platdata(dev);
+	struct rk3288_clk_priv *priv = dev_get_priv(dev);
+
+	debug("%s\n", dev->name);
+	return rkclk_pll_get_rate(priv->cru, plat->clk_id);
+}
+
+static ulong rk3288_clk_set_rate(struct udevice *dev, ulong rate)
+{
+	struct rk3288_clk_plat *plat = dev_get_platdata(dev);
+	struct rk3288_clk_priv *priv = dev_get_priv(dev);
+
+	debug("%s\n", dev->name);
+	switch (plat->clk_id) {
+	case CLK_DDR:
+		rkclk_configure_ddr(priv->cru, priv->grf, rate);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return 0;
+}
+
+static ulong rockchip_mmc_get_clk(struct rk3288_cru *cru, uint clk_general_rate,
+				  enum periph_id periph)
+{
+	uint src_rate;
+	uint div, mux;
+	u32 con;
+
+	switch (periph) {
+	case PERIPH_ID_EMMC:
+		con = readl(&cru->cru_clksel_con[12]);
+		mux = (con >> EMMC_PLL_SHIFT) & EMMC_PLL_MASK;
+		div = (con >> EMMC_DIV_SHIFT) & EMMC_DIV_MASK;
+		break;
+	case PERIPH_ID_SDCARD:
+		con = readl(&cru->cru_clksel_con[12]);
+		mux = (con >> MMC0_PLL_SHIFT) & MMC0_PLL_MASK;
+		div = (con >> MMC0_DIV_SHIFT) & MMC0_DIV_MASK;
+		break;
+	case PERIPH_ID_SDMMC2:
+		con = readl(&cru->cru_clksel_con[12]);
+		mux = (con >> SDIO0_PLL_SHIFT) & SDIO0_PLL_MASK;
+		div = (con >> SDIO0_DIV_SHIFT) & SDIO0_DIV_MASK;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	src_rate = mux == EMMC_PLL_SELECT_24MHZ ? OSC_HZ : clk_general_rate;
+	return DIV_TO_RATE(src_rate, div);
+}
+
+static ulong rockchip_mmc_set_clk(struct rk3288_cru *cru, uint clk_general_rate,
+				  enum periph_id periph, uint freq)
+{
+	int src_clk_div;
+	int mux;
+
+	debug("%s: clk_general_rate=%u\n", __func__, clk_general_rate);
+	src_clk_div = RATE_TO_DIV(clk_general_rate, freq);
+
+	if (src_clk_div > 0x3f) {
+		src_clk_div = RATE_TO_DIV(OSC_HZ, freq);
+		mux = EMMC_PLL_SELECT_24MHZ;
+		assert((int)EMMC_PLL_SELECT_24MHZ ==
+		       (int)MMC0_PLL_SELECT_24MHZ);
+	} else {
+		mux = EMMC_PLL_SELECT_GENERAL;
+		assert((int)EMMC_PLL_SELECT_GENERAL ==
+		       (int)MMC0_PLL_SELECT_GENERAL);
+	}
+	switch (periph) {
+	case PERIPH_ID_EMMC:
+		rk_clrsetreg(&cru->cru_clksel_con[12],
+			     EMMC_PLL_MASK << EMMC_PLL_SHIFT |
+			     EMMC_DIV_MASK << EMMC_DIV_SHIFT,
+			     mux << EMMC_PLL_SHIFT |
+			     (src_clk_div - 1) << EMMC_DIV_SHIFT);
+		break;
+	case PERIPH_ID_SDCARD:
+		rk_clrsetreg(&cru->cru_clksel_con[11],
+			     MMC0_PLL_MASK << MMC0_PLL_SHIFT |
+			     MMC0_DIV_MASK << MMC0_DIV_SHIFT,
+			     mux << MMC0_PLL_SHIFT |
+			     (src_clk_div - 1) << MMC0_DIV_SHIFT);
+		break;
+	case PERIPH_ID_SDMMC2:
+		rk_clrsetreg(&cru->cru_clksel_con[12],
+			     SDIO0_PLL_MASK << SDIO0_PLL_SHIFT |
+			     SDIO0_DIV_MASK << SDIO0_DIV_SHIFT,
+			     mux << SDIO0_PLL_SHIFT |
+			     (src_clk_div - 1) << SDIO0_DIV_SHIFT);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return rockchip_mmc_get_clk(cru, clk_general_rate, periph);
+}
+
+static ulong rockchip_spi_get_clk(struct rk3288_cru *cru, uint clk_general_rate,
+				  enum periph_id periph)
+{
+	uint div, mux;
+	u32 con;
+
+	switch (periph) {
+	case PERIPH_ID_SPI0:
+		con = readl(&cru->cru_clksel_con[25]);
+		mux = (con >> SPI0_PLL_SHIFT) & SPI0_PLL_MASK;
+		div = (con >> SPI0_DIV_SHIFT) & SPI0_DIV_MASK;
+		break;
+	case PERIPH_ID_SPI1:
+		con = readl(&cru->cru_clksel_con[25]);
+		mux = (con >> SPI1_PLL_SHIFT) & SPI1_PLL_MASK;
+		div = (con >> SPI1_DIV_SHIFT) & SPI1_DIV_MASK;
+		break;
+	case PERIPH_ID_SPI2:
+		con = readl(&cru->cru_clksel_con[39]);
+		mux = (con >> SPI2_PLL_SHIFT) & SPI2_PLL_MASK;
+		div = (con >> SPI2_DIV_SHIFT) & SPI2_DIV_MASK;
+		break;
+	default:
+		return -EINVAL;
+	}
+	assert(mux == SPI0_PLL_SELECT_GENERAL);
+
+	return DIV_TO_RATE(clk_general_rate, div);
+}
+
+static ulong rockchip_spi_set_clk(struct rk3288_cru *cru, uint clk_general_rate,
+				  enum periph_id periph, uint freq)
+{
+	int src_clk_div;
+
+	debug("%s: clk_general_rate=%u\n", __func__, clk_general_rate);
+	src_clk_div = RATE_TO_DIV(clk_general_rate, freq);
+	switch (periph) {
+	case PERIPH_ID_SPI0:
+		rk_clrsetreg(&cru->cru_clksel_con[25],
+			     SPI0_PLL_MASK << SPI0_PLL_SHIFT |
+			     SPI0_DIV_MASK << SPI0_DIV_SHIFT,
+			     SPI0_PLL_SELECT_GENERAL << SPI0_PLL_SHIFT |
+			     src_clk_div << SPI0_DIV_SHIFT);
+		break;
+	case PERIPH_ID_SPI1:
+		rk_clrsetreg(&cru->cru_clksel_con[25],
+			     SPI1_PLL_MASK << SPI1_PLL_SHIFT |
+			     SPI1_DIV_MASK << SPI1_DIV_SHIFT,
+			     SPI1_PLL_SELECT_GENERAL << SPI1_PLL_SHIFT |
+			     src_clk_div << SPI1_DIV_SHIFT);
+		break;
+	case PERIPH_ID_SPI2:
+		rk_clrsetreg(&cru->cru_clksel_con[39],
+			     SPI2_PLL_MASK << SPI2_PLL_SHIFT |
+			     SPI2_DIV_MASK << SPI2_DIV_SHIFT,
+			     SPI2_PLL_SELECT_GENERAL << SPI2_PLL_SHIFT |
+			     src_clk_div << SPI2_DIV_SHIFT);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return rockchip_spi_get_clk(cru, clk_general_rate, periph);
+}
+
+ulong rk3288_set_periph_rate(struct udevice *dev, int periph, ulong rate)
+{
+	struct rk3288_clk_priv *priv = dev_get_priv(dev);
+	ulong new_rate;
+
+	switch (periph) {
+	case PERIPH_ID_EMMC:
+	case PERIPH_ID_SDCARD:
+		new_rate = rockchip_mmc_set_clk(priv->cru, clk_get_rate(dev),
+						periph, rate);
+		break;
+	case PERIPH_ID_SPI0:
+	case PERIPH_ID_SPI1:
+	case PERIPH_ID_SPI2:
+		new_rate = rockchip_spi_set_clk(priv->cru, clk_get_rate(dev),
+						periph, rate);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return new_rate;
+}
+
+static struct clk_ops rk3288_clk_ops = {
+	.get_rate	= rk3288_clk_get_rate,
+	.set_rate	= rk3288_clk_set_rate,
+	.set_periph_rate = rk3288_set_periph_rate,
+};
+
+static int rk3288_clk_probe(struct udevice *dev)
+{
+	struct rk3288_clk_plat *plat = dev_get_platdata(dev);
+	struct rk3288_clk_priv *priv = dev_get_priv(dev);
+
+	if (plat->clk_id != CLK_OSC) {
+		struct rk3288_clk_priv *parent_priv = dev_get_priv(dev->parent);
+
+		priv->cru = parent_priv->cru;
+		priv->grf = parent_priv->grf;
+		return 0;
+	}
+	priv->cru = (struct rk3288_cru *)dev_get_addr(dev);
+	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+#ifdef CONFIG_SPL_BUILD
+	rkclk_init(priv->cru, priv->grf);
+#endif
+
+	return 0;
+}
+
+static const char *const clk_name[CLK_COUNT] = {
+	"osc",
+	"apll",
+	"dpll",
+	"cpll",
+	"gpll",
+	"mpll",
+};
+
+static int rk3288_clk_bind(struct udevice *dev)
+{
+	struct rk3288_clk_plat *plat = dev_get_platdata(dev);
+	int pll, ret;
+
+	/* We only need to set up the root clock */
+	if (dev->of_offset == -1) {
+		plat->clk_id = CLK_OSC;
+		return 0;
+	}
+
+	/* Create devices for P main clocks */
+	for (pll = 1; pll < CLK_COUNT; pll++) {
+		struct udevice *child;
+		struct rk3288_clk_plat *cplat;
+
+		debug("%s %s\n", __func__, clk_name[pll]);
+		ret = device_bind_driver(dev, "clk_rk3288", clk_name[pll],
+					 &child);
+		if (ret)
+			return ret;
+		cplat = dev_get_platdata(child);
+		cplat->clk_id = pll;
+	}
+
+	/* The reset driver does not have a device node, so bind it here */
+	ret = device_bind_driver(gd->dm_root, "rk3288_reset", "reset", &dev);
+	if (ret)
+		debug("Warning: No RK3288 reset driver: ret=%d\n", ret);
+
+	return 0;
+}
+
+static const struct udevice_id rk3288_clk_ids[] = {
+	{ .compatible = "rockchip,rk3288-cru" },
+	{ }
+};
+
+U_BOOT_DRIVER(clk_rk3288) = {
+	.name		= "clk_rk3288",
+	.id		= UCLASS_CLK,
+	.of_match	= rk3288_clk_ids,
+	.priv_auto_alloc_size = sizeof(struct rk3288_clk_priv),
+	.platdata_auto_alloc_size = sizeof(struct rk3288_clk_plat),
+	.ops		= &rk3288_clk_ops,
+	.bind		= rk3288_clk_bind,
+	.probe		= rk3288_clk_probe,
+};
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 21/41] rockchip: rk3288: Add header files for PMU and GRF
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (19 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 20/41] rockchip: rk3288: Add clock driver Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:59   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 22/41] rockchip: rk3288: Add SoC reset driver Simon Glass
                   ` (19 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

PMU is the power management unit and GRF is the general register file. Both
are heavily used in U-Boot. Add header files with register definitions.

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

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arm/include/asm/arch-rockchip/grf_rk3288.h | 768 ++++++++++++++++++++++++
 arch/arm/include/asm/arch-rockchip/pmu_rk3288.h |  89 +++
 2 files changed, 857 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-rockchip/grf_rk3288.h
 create mode 100644 arch/arm/include/asm/arch-rockchip/pmu_rk3288.h

diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3288.h b/arch/arm/include/asm/arch-rockchip/grf_rk3288.h
new file mode 100644
index 0000000..0117a17
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3288.h
@@ -0,0 +1,768 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ * Copyright 2014 Rockchip Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef _ASM_ARCH_GRF_RK3288_H
+#define _ASM_ARCH_GRF_RK3288_H
+
+struct rk3288_grf_gpio_lh {
+	u32 l;
+	u32 h;
+};
+
+struct rk3288_grf {
+	u32 reserved[3];
+	u32 gpio1d_iomux;
+	u32 gpio2a_iomux;
+	u32 gpio2b_iomux;
+
+	u32 gpio2c_iomux;
+	u32 reserved2;
+	u32 gpio3a_iomux;
+	u32 gpio3b_iomux;
+
+	u32 gpio3c_iomux;
+	u32 gpio3dl_iomux;
+	u32 gpio3dh_iomux;
+	u32 gpio4al_iomux;
+
+	u32 gpio4ah_iomux;
+	u32 gpio4bl_iomux;
+	u32 reserved3;
+	u32 gpio4c_iomux;
+
+	u32 gpio4d_iomux;
+	u32 reserved4;
+	u32 gpio5b_iomux;
+	u32 gpio5c_iomux;
+
+	u32 reserved5;
+	u32 gpio6a_iomux;
+	u32 gpio6b_iomux;
+	u32 gpio6c_iomux;
+	u32 reserved6;
+	u32 gpio7a_iomux;
+	u32 gpio7b_iomux;
+	u32 gpio7cl_iomux;
+	u32 gpio7ch_iomux;
+	u32 reserved7;
+	u32 gpio8a_iomux;
+	u32 gpio8b_iomux;
+	u32 reserved8[30];
+	struct rk3288_grf_gpio_lh gpio_sr[8];
+	u32 gpio1_p[8][4];
+	u32 gpio1_e[8][4];
+	u32 gpio_smt;
+	u32 soc_con0;
+	u32 soc_con1;
+	u32 soc_con2;
+	u32 soc_con3;
+	u32 soc_con4;
+	u32 soc_con5;
+	u32 soc_con6;
+	u32 soc_con7;
+	u32 soc_con8;
+	u32 soc_con9;
+	u32 soc_con10;
+	u32 soc_con11;
+	u32 soc_con12;
+	u32 soc_con13;
+	u32 soc_con14;
+	u32 soc_status[22];
+	u32 reserved9[2];
+	u32 peridmac_con[4];
+	u32 ddrc0_con0;
+	u32 ddrc1_con0;
+	u32 cpu_con[5];
+	u32 reserved10[3];
+	u32 cpu_status0;
+	u32 reserved11;
+	u32 uoc0_con[5];
+	u32 uoc1_con[5];
+	u32 uoc2_con[4];
+	u32 uoc3_con[2];
+	u32 uoc4_con[2];
+	u32 pvtm_con[3];
+	u32 pvtm_status[3];
+	u32 io_vsel;
+	u32 saradc_testbit;
+	u32 tsadc_testbit_l;
+	u32 tsadc_testbit_h;
+	u32 os_reg[4];
+	u32 reserved12;
+	u32 soc_con15;
+	u32 soc_con16;
+};
+
+struct rk3288_sgrf {
+	u32 soc_con0;
+	u32 soc_con1;
+	u32 soc_con2;
+	u32 soc_con3;
+	u32 soc_con4;
+	u32 soc_con5;
+	u32 reserved1[(0x20-0x18)/4];
+	u32 busdmac_con[2];
+	u32 reserved2[(0x40-0x28)/4];
+	u32 cpu_con[3];
+	u32 reserved3[(0x50-0x4c)/4];
+	u32 soc_con6;
+	u32 soc_con7;
+	u32 soc_con8;
+	u32 soc_con9;
+	u32 soc_con10;
+	u32 soc_con11;
+	u32 soc_con12;
+	u32 soc_con13;
+	u32 soc_con14;
+	u32 soc_con15;
+	u32 soc_con16;
+	u32 soc_con17;
+	u32 soc_con18;
+	u32 soc_con19;
+	u32 soc_con20;
+	u32 soc_con21;
+	u32 reserved4[(0x100-0x90)/4];
+	u32 soc_status[2];
+	u32 reserved5[(0x120-0x108)/4];
+	u32 fast_boot_addr;
+};
+
+/* GRF_GPIO1D_IOMUX */
+enum {
+	GPIO1D3_SHIFT		= 6,
+	GPIO1D3_MASK		= 1,
+	GPIO1D3_GPIO		= 0,
+	GPIO1D3_LCDC0_DCLK,
+
+	GPIO1D2_SHIFT		= 4,
+	GPIO1D2_MASK		= 1,
+	GPIO1D2_GPIO		= 0,
+	GPIO1D2_LCDC0_DEN,
+
+	GPIO1D1_SHIFT		= 2,
+	GPIO1D1_MASK		= 1,
+	GPIO1D1_GPIO		= 0,
+	GPIO1D1_LCDC0_VSYNC,
+
+	GPIO1D0_SHIFT		= 0,
+	GPIO1D0_MASK		= 1,
+	GPIO1D0_GPIO		= 0,
+	GPIO1D0_LCDC0_HSYNC,
+};
+
+/* GRF_GPIO2C_IOMUX */
+enum {
+	GPIO2C1_SHIFT		= 2,
+	GPIO2C1_MASK		= 1,
+	GPIO2C1_GPIO		= 0,
+	GPIO2C1_I2C3CAM_SDA,
+
+	GPIO2C0_SHIFT		= 0,
+	GPIO2C0_MASK		= 1,
+	GPIO2C0_GPIO		= 0,
+	GPIO2C0_I2C3CAM_SCL,
+};
+
+/* GRF_GPIO3A_IOMUX */
+enum {
+	GPIO3A7_SHIFT		= 14,
+	GPIO3A7_MASK		= 3,
+	GPIO3A7_GPIO		= 0,
+	GPIO3A7_FLASH0_DATA7,
+	GPIO3A7_EMMC_DATA7,
+
+	GPIO3A6_SHIFT		= 12,
+	GPIO3A6_MASK		= 3,
+	GPIO3A6_GPIO		= 0,
+	GPIO3A6_FLASH0_DATA6,
+	GPIO3A6_EMMC_DATA6,
+
+	GPIO3A5_SHIFT		= 10,
+	GPIO3A5_MASK		= 3,
+	GPIO3A5_GPIO		= 0,
+	GPIO3A5_FLASH0_DATA5,
+	GPIO3A5_EMMC_DATA5,
+
+	GPIO3A4_SHIFT		= 8,
+	GPIO3A4_MASK		= 3,
+	GPIO3A4_GPIO		= 0,
+	GPIO3A4_FLASH0_DATA4,
+	GPIO3A4_EMMC_DATA4,
+
+	GPIO3A3_SHIFT		= 6,
+	GPIO3A3_MASK		= 3,
+	GPIO3A3_GPIO		= 0,
+	GPIO3A3_FLASH0_DATA3,
+	GPIO3A3_EMMC_DATA3,
+
+	GPIO3A2_SHIFT		= 4,
+	GPIO3A2_MASK		= 3,
+	GPIO3A2_GPIO		= 0,
+	GPIO3A2_FLASH0_DATA2,
+	GPIO3A2_EMMC_DATA2,
+
+	GPIO3A1_SHIFT		= 2,
+	GPIO3A1_MASK		= 3,
+	GPIO3A1_GPIO		= 0,
+	GPIO3A1_FLASH0_DATA1,
+	GPIO3A1_EMMC_DATA1,
+
+	GPIO3A0_SHIFT		= 0,
+	GPIO3A0_MASK		= 3,
+	GPIO3A0_GPIO		= 0,
+	GPIO3A0_FLASH0_DATA0,
+	GPIO3A0_EMMC_DATA0,
+};
+
+/* GRF_GPIO3B_IOMUX */
+enum {
+	GPIO3B7_SHIFT		= 14,
+	GPIO3B7_MASK		= 1,
+	GPIO3B7_GPIO		= 0,
+	GPIO3B7_FLASH0_CSN1,
+
+	GPIO3B6_SHIFT		= 12,
+	GPIO3B6_MASK		= 1,
+	GPIO3B6_GPIO		= 0,
+	GPIO3B6_FLASH0_CSN0,
+
+	GPIO3B5_SHIFT		= 10,
+	GPIO3B5_MASK		= 1,
+	GPIO3B5_GPIO		= 0,
+	GPIO3B5_FLASH0_WRN,
+
+	GPIO3B4_SHIFT		= 8,
+	GPIO3B4_MASK		= 1,
+	GPIO3B4_GPIO		= 0,
+	GPIO3B4_FLASH0_CLE,
+
+	GPIO3B3_SHIFT		= 6,
+	GPIO3B3_MASK		= 1,
+	GPIO3B3_GPIO		= 0,
+	GPIO3B3_FLASH0_ALE,
+
+	GPIO3B2_SHIFT		= 4,
+	GPIO3B2_MASK		= 1,
+	GPIO3B2_GPIO		= 0,
+	GPIO3B2_FLASH0_RDN,
+
+	GPIO3B1_SHIFT		= 2,
+	GPIO3B1_MASK		= 3,
+	GPIO3B1_GPIO		= 0,
+	GPIO3B1_FLASH0_WP,
+	GPIO3B1_EMMC_PWREN,
+
+	GPIO3B0_SHIFT		= 0,
+	GPIO3B0_MASK		= 1,
+	GPIO3B0_GPIO		= 0,
+	GPIO3B0_FLASH0_RDY,
+};
+
+/* GRF_GPIO3C_IOMUX */
+enum {
+	GPIO3C2_SHIFT		= 4,
+	GPIO3C2_MASK		= 3,
+	GPIO3C2_GPIO		= 0,
+	GPIO3C2_FLASH0_DQS,
+	GPIO3C2_EMMC_CLKOUT,
+
+	GPIO3C1_SHIFT		= 2,
+	GPIO3C1_MASK		= 3,
+	GPIO3C1_GPIO		= 0,
+	GPIO3C1_FLASH0_CSN3,
+	GPIO3C1_EMMC_RSTNOUT,
+
+	GPIO3C0_SHIFT		= 0,
+	GPIO3C0_MASK		= 3,
+	GPIO3C0_GPIO		= 0,
+	GPIO3C0_FLASH0_CSN2,
+	GPIO3C0_EMMC_CMD,
+};
+
+/* GRF_GPIO4C_IOMUX */
+enum {
+	GPIO4C7_SHIFT		= 14,
+	GPIO4C7_MASK		= 1,
+	GPIO4C7_GPIO		= 0,
+	GPIO4C7_SDIO0_DATA3,
+
+	GPIO4C6_SHIFT		= 12,
+	GPIO4C6_MASK		= 1,
+	GPIO4C6_GPIO		= 0,
+	GPIO4C6_SDIO0_DATA2,
+
+	GPIO4C5_SHIFT		= 10,
+	GPIO4C5_MASK		= 1,
+	GPIO4C5_GPIO		= 0,
+	GPIO4C5_SDIO0_DATA1,
+
+	GPIO4C4_SHIFT		= 8,
+	GPIO4C4_MASK		= 1,
+	GPIO4C4_GPIO		= 0,
+	GPIO4C4_SDIO0_DATA0,
+
+	GPIO4C3_SHIFT		= 6,
+	GPIO4C3_MASK		= 1,
+	GPIO4C3_GPIO		= 0,
+	GPIO4C3_UART0BT_RTSN,
+
+	GPIO4C2_SHIFT		= 4,
+	GPIO4C2_MASK		= 1,
+	GPIO4C2_GPIO		= 0,
+	GPIO4C2_UART0BT_CTSN,
+
+	GPIO4C1_SHIFT		= 2,
+	GPIO4C1_MASK		= 1,
+	GPIO4C1_GPIO		= 0,
+	GPIO4C1_UART0BT_SOUT,
+
+	GPIO4C0_SHIFT		= 0,
+	GPIO4C0_MASK		= 1,
+	GPIO4C0_GPIO		= 0,
+	GPIO4C0_UART0BT_SIN,
+};
+
+/* GRF_GPIO5B_IOMUX */
+enum {
+	GPIO5B7_SHIFT		= 14,
+	GPIO5B7_MASK		= 3,
+	GPIO5B7_GPIO		= 0,
+	GPIO5B7_SPI0_RXD,
+	GPIO5B7_TS0_DATA7,
+	GPIO5B7_UART4EXP_SIN,
+
+	GPIO5B6_SHIFT		= 12,
+	GPIO5B6_MASK		= 3,
+	GPIO5B6_GPIO		= 0,
+	GPIO5B6_SPI0_TXD,
+	GPIO5B6_TS0_DATA6,
+	GPIO5B6_UART4EXP_SOUT,
+
+	GPIO5B5_SHIFT		= 10,
+	GPIO5B5_MASK		= 3,
+	GPIO5B5_GPIO		= 0,
+	GPIO5B5_SPI0_CSN0,
+	GPIO5B5_TS0_DATA5,
+	GPIO5B5_UART4EXP_RTSN,
+
+	GPIO5B4_SHIFT		= 8,
+	GPIO5B4_MASK		= 3,
+	GPIO5B4_GPIO		= 0,
+	GPIO5B4_SPI0_CLK,
+	GPIO5B4_TS0_DATA4,
+	GPIO5B4_UART4EXP_CTSN,
+
+	GPIO5B3_SHIFT		= 6,
+	GPIO5B3_MASK		= 3,
+	GPIO5B3_GPIO		= 0,
+	GPIO5B3_UART1BB_RTSN,
+	GPIO5B3_TS0_DATA3,
+
+	GPIO5B2_SHIFT		= 4,
+	GPIO5B2_MASK		= 3,
+	GPIO5B2_GPIO		= 0,
+	GPIO5B2_UART1BB_CTSN,
+	GPIO5B2_TS0_DATA2,
+
+	GPIO5B1_SHIFT		= 2,
+	GPIO5B1_MASK		= 3,
+	GPIO5B1_GPIO		= 0,
+	GPIO5B1_UART1BB_SOUT,
+	GPIO5B1_TS0_DATA1,
+
+	GPIO5B0_SHIFT		= 0,
+	GPIO5B0_MASK		= 3,
+	GPIO5B0_GPIO		= 0,
+	GPIO5B0_UART1BB_SIN,
+	GPIO5B0_TS0_DATA0,
+};
+
+/* GRF_GPIO5C_IOMUX */
+enum {
+	GPIO5C3_SHIFT		= 6,
+	GPIO5C3_MASK		= 1,
+	GPIO5C3_GPIO		= 0,
+	GPIO5C3_TS0_ERR,
+
+	GPIO5C2_SHIFT		= 4,
+	GPIO5C2_MASK		= 1,
+	GPIO5C2_GPIO		= 0,
+	GPIO5C2_TS0_CLK,
+
+	GPIO5C1_SHIFT		= 2,
+	GPIO5C1_MASK		= 1,
+	GPIO5C1_GPIO		= 0,
+	GPIO5C1_TS0_VALID,
+
+	GPIO5C0_SHIFT		= 0,
+	GPIO5C0_MASK		= 3,
+	GPIO5C0_GPIO		= 0,
+	GPIO5C0_SPI0_CSN1,
+	GPIO5C0_TS0_SYNC,
+};
+
+/* GRF_GPIO6B_IOMUX */
+enum {
+	GPIO6B3_SHIFT		= 6,
+	GPIO6B3_MASK		= 1,
+	GPIO6B3_GPIO		= 0,
+	GPIO6B3_SPDIF_TX,
+
+	GPIO6B2_SHIFT		= 4,
+	GPIO6B2_MASK		= 1,
+	GPIO6B2_GPIO		= 0,
+	GPIO6B2_I2C1AUDIO_SCL,
+
+	GPIO6B1_SHIFT		= 2,
+	GPIO6B1_MASK		= 1,
+	GPIO6B1_GPIO		= 0,
+	GPIO6B1_I2C1AUDIO_SDA,
+
+	GPIO6B0_SHIFT		= 0,
+	GPIO6B0_MASK		= 1,
+	GPIO6B0_GPIO		= 0,
+	GPIO6B0_I2S_CLK,
+};
+
+/* GRF_GPIO6C_IOMUX */
+enum {
+	GPIO6C6_SHIFT		= 12,
+	GPIO6C6_MASK		= 1,
+	GPIO6C6_GPIO		= 0,
+	GPIO6C6_SDMMC0_DECTN,
+
+	GPIO6C5_SHIFT		= 10,
+	GPIO6C5_MASK		= 1,
+	GPIO6C5_GPIO		= 0,
+	GPIO6C5_SDMMC0_CMD,
+
+	GPIO6C4_SHIFT		= 8,
+	GPIO6C4_MASK		= 3,
+	GPIO6C4_GPIO		= 0,
+	GPIO6C4_SDMMC0_CLKOUT,
+	GPIO6C4_JTAG_TDO,
+
+	GPIO6C3_SHIFT		= 6,
+	GPIO6C3_MASK		= 3,
+	GPIO6C3_GPIO		= 0,
+	GPIO6C3_SDMMC0_DATA3,
+	GPIO6C3_JTAG_TCK,
+
+	GPIO6C2_SHIFT		= 4,
+	GPIO6C2_MASK		= 3,
+	GPIO6C2_GPIO		= 0,
+	GPIO6C2_SDMMC0_DATA2,
+	GPIO6C2_JTAG_TDI,
+
+	GPIO6C1_SHIFT		= 2,
+	GPIO6C1_MASK		= 3,
+	GPIO6C1_GPIO		= 0,
+	GPIO6C1_SDMMC0_DATA1,
+	GPIO6C1_JTAG_TRSTN,
+
+	GPIO6C0_SHIFT		= 0,
+	GPIO6C0_MASK		= 3,
+	GPIO6C0_GPIO		= 0,
+	GPIO6C0_SDMMC0_DATA0,
+	GPIO6C0_JTAG_TMS,
+};
+
+/* GRF_GPIO7A_IOMUX */
+enum {
+	GPIO7A7_SHIFT		= 14,
+	GPIO7A7_MASK		= 3,
+	GPIO7A7_GPIO		= 0,
+	GPIO7A7_UART3GPS_SIN,
+	GPIO7A7_GPS_MAG,
+	GPIO7A7_HSADCT1_DATA0,
+
+	GPIO7A1_SHIFT		= 2,
+	GPIO7A1_MASK		= 1,
+	GPIO7A1_GPIO		= 0,
+	GPIO7A1_PWM_1,
+
+	GPIO7A0_SHIFT		= 0,
+	GPIO7A0_MASK		= 3,
+	GPIO7A0_GPIO		= 0,
+	GPIO7A0_PWM_0,
+	GPIO7A0_VOP0_PWM,
+	GPIO7A0_VOP1_PWM,
+};
+
+/* GRF_GPIO7B_IOMUX */
+enum {
+	GPIO7B7_SHIFT		= 14,
+	GPIO7B7_MASK		= 3,
+	GPIO7B7_GPIO		= 0,
+	GPIO7B7_ISP_SHUTTERTRIG,
+	GPIO7B7_SPI1_TXD,
+
+	GPIO7B6_SHIFT		= 12,
+	GPIO7B6_MASK		= 3,
+	GPIO7B6_GPIO		= 0,
+	GPIO7B6_ISP_PRELIGHTTRIG,
+	GPIO7B6_SPI1_RXD,
+
+	GPIO7B5_SHIFT		= 10,
+	GPIO7B5_MASK		= 3,
+	GPIO7B5_GPIO		= 0,
+	GPIO7B5_ISP_FLASHTRIGOUT,
+	GPIO7B5_SPI1_CSN0,
+
+	GPIO7B4_SHIFT		= 8,
+	GPIO7B4_MASK		= 3,
+	GPIO7B4_GPIO		= 0,
+	GPIO7B4_ISP_SHUTTEREN,
+	GPIO7B4_SPI1_CLK,
+
+	GPIO7B3_SHIFT		= 6,
+	GPIO7B3_MASK		= 3,
+	GPIO7B3_GPIO		= 0,
+	GPIO7B3_USB_DRVVBUS1,
+	GPIO7B3_EDP_HOTPLUG,
+
+	GPIO7B2_SHIFT		= 4,
+	GPIO7B2_MASK		= 3,
+	GPIO7B2_GPIO		= 0,
+	GPIO7B2_UART3GPS_RTSN,
+	GPIO7B2_USB_DRVVBUS0,
+
+	GPIO7B1_SHIFT		= 2,
+	GPIO7B1_MASK		= 3,
+	GPIO7B1_GPIO		= 0,
+	GPIO7B1_UART3GPS_CTSN,
+	GPIO7B1_GPS_RFCLK,
+	GPIO7B1_GPST1_CLK,
+
+	GPIO7B0_SHIFT		= 0,
+	GPIO7B0_MASK		= 3,
+	GPIO7B0_GPIO		= 0,
+	GPIO7B0_UART3GPS_SOUT,
+	GPIO7B0_GPS_SIG,
+	GPIO7B0_HSADCT1_DATA1,
+};
+
+/* GRF_GPIO7CL_IOMUX */
+enum {
+	GPIO7C3_SHIFT		= 12,
+	GPIO7C3_MASK		= 3,
+	GPIO7C3_GPIO		= 0,
+	GPIO7C3_I2C5HDMI_SDA,
+	GPIO7C3_EDPHDMII2C_SDA,
+
+	GPIO7C2_SHIFT		= 8,
+	GPIO7C2_MASK		= 1,
+	GPIO7C2_GPIO		= 0,
+	GPIO7C2_I2C4TP_SCL,
+
+	GPIO7C1_SHIFT		= 4,
+	GPIO7C1_MASK		= 1,
+	GPIO7C1_GPIO		= 0,
+	GPIO7C1_I2C4TP_SDA,
+
+	GPIO7C0_SHIFT		= 0,
+	GPIO7C0_MASK		= 3,
+	GPIO7C0_GPIO		= 0,
+	GPIO7C0_ISP_FLASHTRIGIN,
+	GPIO7C0_EDPHDMI_CECINOUTT1,
+};
+
+/* GRF_GPIO7CH_IOMUX */
+enum {
+	GPIO7C7_SHIFT		= 12,
+	GPIO7C7_MASK		= 7,
+	GPIO7C7_GPIO		= 0,
+	GPIO7C7_UART2DBG_SOUT,
+	GPIO7C7_UART2DBG_SIROUT,
+	GPIO7C7_PWM_3,
+	GPIO7C7_EDPHDMI_CECINOUT,
+
+	GPIO7C6_SHIFT		= 8,
+	GPIO7C6_MASK		= 3,
+	GPIO7C6_GPIO		= 0,
+	GPIO7C6_UART2DBG_SIN,
+	GPIO7C6_UART2DBG_SIRIN,
+	GPIO7C6_PWM_2,
+
+	GPIO7C4_SHIFT		= 0,
+	GPIO7C4_MASK		= 3,
+	GPIO7C4_GPIO		= 0,
+	GPIO7C4_I2C5HDMI_SCL,
+	GPIO7C4_EDPHDMII2C_SCL,
+};
+
+/* GRF_GPIO8A_IOMUX */
+enum {
+	GPIO8A7_SHIFT		= 14,
+	GPIO8A7_MASK		= 3,
+	GPIO8A7_GPIO		= 0,
+	GPIO8A7_SPI2_CSN0,
+	GPIO8A7_SC_DETECT,
+	GPIO8A7_RESERVE,
+
+	GPIO8A6_SHIFT		= 12,
+	GPIO8A6_MASK		= 3,
+	GPIO8A6_GPIO		= 0,
+	GPIO8A6_SPI2_CLK,
+	GPIO8A6_SC_IO,
+	GPIO8A6_RESERVE,
+
+	GPIO8A5_SHIFT		= 10,
+	GPIO8A5_MASK		= 3,
+	GPIO8A5_GPIO		= 0,
+	GPIO8A5_I2C2SENSOR_SCL,
+	GPIO8A5_SC_CLK,
+
+	GPIO8A4_SHIFT		= 8,
+	GPIO8A4_MASK		= 3,
+	GPIO8A4_GPIO		= 0,
+	GPIO8A4_I2C2SENSOR_SDA,
+	GPIO8A4_SC_RST,
+
+	GPIO8A3_SHIFT		= 6,
+	GPIO8A3_MASK		= 3,
+	GPIO8A3_GPIO		= 0,
+	GPIO8A3_SPI2_CSN1,
+	GPIO8A3_SC_IOT1,
+
+	GPIO8A2_SHIFT		= 4,
+	GPIO8A2_MASK		= 1,
+	GPIO8A2_GPIO		= 0,
+	GPIO8A2_SC_DETECTT1,
+
+	GPIO8A1_SHIFT		= 2,
+	GPIO8A1_MASK		= 3,
+	GPIO8A1_GPIO		= 0,
+	GPIO8A1_PS2_DATA,
+	GPIO8A1_SC_VCC33V,
+
+	GPIO8A0_SHIFT		= 0,
+	GPIO8A0_MASK		= 3,
+	GPIO8A0_GPIO		= 0,
+	GPIO8A0_PS2_CLK,
+	GPIO8A0_SC_VCC18V,
+};
+
+/* GRF_GPIO8B_IOMUX */
+enum {
+	GPIO8B1_SHIFT		= 2,
+	GPIO8B1_MASK		= 3,
+	GPIO8B1_GPIO		= 0,
+	GPIO8B1_SPI2_TXD,
+	GPIO8B1_SC_CLK,
+
+	GPIO8B0_SHIFT		= 0,
+	GPIO8B0_MASK		= 3,
+	GPIO8B0_GPIO		= 0,
+	GPIO8B0_SPI2_RXD,
+	GPIO8B0_SC_RST,
+};
+
+/* GRF_SOC_CON0 */
+enum {
+	PAUSE_MMC_PERI_SHIFT	= 0xf,
+	PAUSE_MMC_PERI_MASK	= 1,
+
+	PAUSE_EMEM_PERI_SHIFT	= 0xe,
+	PAUSE_EMEM_PERI_MASK	= 1,
+
+	PAUSE_USB_PERI_SHIFT	= 0xd,
+	PAUSE_USB_PERI_MASK	= 1,
+
+	GRF_FORCE_JTAG_SHIFT	= 0xc,
+	GRF_FORCE_JTAG_MASK	= 1,
+
+	GRF_CORE_IDLE_REQ_MODE_SEL1_SHIFT = 0xb,
+	GRF_CORE_IDLE_REQ_MODE_SEL1_MASK = 1,
+
+	GRF_CORE_IDLE_REQ_MODE_SEL0_SHIFT = 0xa,
+	GRF_CORE_IDLE_REQ_MODE_SEL0_MASK = 1,
+
+	DDR1_16BIT_EN_SHIFT	= 9,
+	DDR1_16BIT_EN_MASK	= 1,
+
+	DDR0_16BIT_EN_SHIFT	= 8,
+	DDR0_16BIT_EN_MASK	= 1,
+
+	VCODEC_SHIFT		= 7,
+	VCODEC_MASK		= 1,
+	VCODEC_SELECT_VEPU_ACLK	= 0,
+	VCODEC_SELECT_VDPU_ACLK,
+
+	UPCTL1_C_ACTIVE_IN_SHIFT = 6,
+	UPCTL1_C_ACTIVE_IN_MASK	= 1,
+	UPCTL1_C_ACTIVE_IN_MAY	= 0,
+	UPCTL1_C_ACTIVE_IN_WILL,
+
+	UPCTL0_C_ACTIVE_IN_SHIFT = 5,
+	UPCTL0_C_ACTIVE_IN_MASK	= 1,
+	UPCTL0_C_ACTIVE_IN_MAY	= 0,
+	UPCTL0_C_ACTIVE_IN_WILL,
+
+	MSCH1_MAINDDR3_SHIFT	= 4,
+	MSCH1_MAINDDR3_MASK	= 1,
+	MSCH1_MAINDDR3_DDR3	= 1,
+
+	MSCH0_MAINDDR3_SHIFT	= 3,
+	MSCH0_MAINDDR3_MASK	= 1,
+	MSCH0_MAINDDR3_DDR3	= 1,
+
+	MSCH1_MAINPARTIALPOP_SHIFT = 2,
+	MSCH1_MAINPARTIALPOP_MASK = 1,
+
+	MSCH0_MAINPARTIALPOP_SHIFT = 1,
+	MSCH0_MAINPARTIALPOP_MASK = 1,
+};
+
+/* GRF_SOC_CON2 */
+enum {
+	UPCTL1_LPDDR3_ODT_EN_SHIFT = 0xd,
+	UPCTL1_LPDDR3_ODT_EN_MASK = 1,
+	UPCTL1_LPDDR3_ODT_EN_ODT = 1,
+
+	UPCTL1_BST_DIABLE_SHIFT	= 0xc,
+	UPCTL1_BST_DIABLE_MASK	= 1,
+	UPCTL1_BST_DIABLE_DISABLE = 1,
+
+	LPDDR3_EN1_SHIFT	= 0xb,
+	LPDDR3_EN1_MASK		= 1,
+	LPDDR3_EN1_LPDDR3	= 1,
+
+	UPCTL0_LPDDR3_ODT_EN_SHIFT = 0xa,
+	UPCTL0_LPDDR3_ODT_EN_MASK = 1,
+	UPCTL0_LPDDR3_ODT_EN_ODT_ENABLE = 1,
+
+	UPCTL0_BST_DIABLE_SHIFT	= 9,
+	UPCTL0_BST_DIABLE_MASK	= 1,
+	UPCTL0_BST_DIABLE_DISABLE = 1,
+
+	LPDDR3_EN0_SHIFT	= 8,
+	LPDDR3_EN0_MASK		= 1,
+	LPDDR3_EN0_LPDDR3	= 1,
+
+	GRF_POC_FLASH0_CTRL_SHIFT = 7,
+	GRF_POC_FLASH0_CTRL_MASK = 1,
+	GRF_POC_FLASH0_CTRL_GPIO3C_3 = 0,
+	GRF_POC_FLASH0_CTRL_GRF_IO_VSEL,
+
+	SIMCARD_MUX_SHIFT	= 6,
+	SIMCARD_MUX_MASK	= 1,
+	SIMCARD_MUX_USE_A	= 1,
+	SIMCARD_MUX_USE_B	= 0,
+
+	GRF_SPDIF_2CH_EN_SHIFT	= 1,
+	GRF_SPDIF_2CH_EN_MASK	= 1,
+	GRF_SPDIF_2CH_EN_8CH	= 0,
+	GRF_SPDIF_2CH_EN_2CH,
+
+	PWM_SHIFT		= 0,
+	PWM_MASK		= 1,
+	PWM_RK			= 1,
+	PWM_PWM			= 0,
+};
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/pmu_rk3288.h b/arch/arm/include/asm/arch-rockchip/pmu_rk3288.h
new file mode 100644
index 0000000..12fa685
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/pmu_rk3288.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ *
+ * Copyright 2014 Rockchip Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _ASM_ARCH_PMU_RK3288_H
+#define _ASM_ARCH_PMU_RK3288_H
+
+struct rk3288_pmu {
+	u32 wakeup_cfg[2];
+	u32 pwrdn_con;
+	u32 pwrdn_st;
+
+	u32 idle_req;
+	u32 idle_st;
+	u32 pwrmode_con;
+	u32 pwr_state;
+
+	u32 osc_cnt;
+	u32 pll_cnt;
+	u32 stabl_cnt;
+	u32 ddr0io_pwron_cnt;
+
+	u32 ddr1io_pwron_cnt;
+	u32 core_pwrdn_cnt;
+	u32 core_pwrup_cnt;
+	u32 gpu_pwrdn_cnt;
+
+	u32 gpu_pwrup_cnt;
+	u32 wakeup_rst_clr_cnt;
+	u32 sft_con;
+	u32 ddr_sref_st;
+
+	u32 int_con;
+	u32 int_st;
+	u32 boot_addr_sel;
+	u32 grf_con;
+
+	u32 gpio_sr;
+	u32 gpio0pull[3];
+
+	u32 gpio0drv[3];
+	u32 gpio_op;
+
+	u32 gpio0_sel18;	/* 0x80 */
+	u32 gpio0a_iomux;
+	u32 gpio0b_iomux;
+	u32 gpio0c_iomux;
+	u32 gpio0d_iomux;
+	u32 sys_reg[4];
+};
+check_member(rk3288_pmu, sys_reg[3], 0x00a0);
+
+/* PMU_GPIO0_B_IOMUX */
+enum {
+	GPIO0_B7_SHIFT		= 14,
+	GPIO0_B7_MASK		= 1,
+	GPIO0_B7_GPIOB7		= 0,
+	GPIO0_B7_I2C0PMU_SDA,
+
+	GPIO0_B5_SHIFT		= 10,
+	GPIO0_B5_MASK		= 1,
+	GPIO0_B5_GPIOB5		= 0,
+	GPIO0_B5_CLK_27M,
+
+	GPIO0_B2_SHIFT		= 4,
+	GPIO0_B2_MASK		= 1,
+	GPIO0_B2_GPIOB2		= 0,
+	GPIO0_B2_TSADC_INT,
+};
+
+/* PMU_GPIO0_C_IOMUX */
+enum {
+	GPIO0_C1_SHIFT		= 2,
+	GPIO0_C1_MASK		= 3,
+	GPIO0_C1_GPIOC1		= 0,
+	GPIO0_C1_TEST_CLKOUT,
+	GPIO0_C1_CLKT1_27M,
+
+	GPIO0_C0_SHIFT		= 0,
+	GPIO0_C0_MASK		= 1,
+	GPIO0_C0_GPIOC0		= 0,
+	GPIO0_C0_I2C0PMU_SCL,
+};
+
+#endif
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 22/41] rockchip: rk3288: Add SoC reset driver
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (20 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 21/41] rockchip: rk3288: Add header files for PMU and GRF Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:59   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 23/41] rockchip: rk3288: Add a simple syscon driver Simon Glass
                   ` (18 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

We can reset the SoC using some CRU (clock/reset unit) registers. Add support
for this.

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

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arm/mach-rockchip/rk3288/Makefile       |  7 +++++
 arch/arm/mach-rockchip/rk3288/reset_rk3288.c | 47 ++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+)
 create mode 100644 arch/arm/mach-rockchip/rk3288/Makefile
 create mode 100644 arch/arm/mach-rockchip/rk3288/reset_rk3288.c

diff --git a/arch/arm/mach-rockchip/rk3288/Makefile b/arch/arm/mach-rockchip/rk3288/Makefile
new file mode 100644
index 0000000..c6663f0
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3288/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2015 Google, Inc
+#
+# SPDX-License-Identifier:      GPL-2.0+
+#
+
+obj-y += reset_rk3288.o
diff --git a/arch/arm/mach-rockchip/rk3288/reset_rk3288.c b/arch/arm/mach-rockchip/rk3288/reset_rk3288.c
new file mode 100644
index 0000000..7affd11
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3288/reset_rk3288.c
@@ -0,0 +1,47 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <reset.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3288.h>
+#include <asm/arch/hardware.h>
+#include <linux/err.h>
+
+int rk3288_reset_request(struct udevice *dev, enum reset_t type)
+{
+	struct rk3288_cru *cru = rockchip_get_cru();
+
+	if (IS_ERR(cru))
+		return PTR_ERR(cru);
+	switch (type) {
+	case RESET_WARM:
+		writel(RK_CLRBITS(0xffff), &cru->cru_mode_con);
+		writel(0xeca8, &cru->cru_glb_srst_snd_value);
+		break;
+	case RESET_COLD:
+		writel(RK_CLRBITS(0xffff), &cru->cru_mode_con);
+		writel(0xfdb9, &cru->cru_glb_srst_fst_value);
+		break;
+	default:
+		return -EPROTONOSUPPORT;
+	}
+
+	return -EINPROGRESS;
+}
+
+static struct reset_ops rk3288_reset = {
+	.request	= rk3288_reset_request,
+};
+
+U_BOOT_DRIVER(reset_rk3288) = {
+	.name	= "rk3288_reset",
+	.id	= UCLASS_RESET,
+	.ops	= &rk3288_reset,
+};
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 23/41] rockchip: rk3288: Add a simple syscon driver
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (21 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 22/41] rockchip: rk3288: Add SoC reset driver Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:59   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 24/41] rockchip: rk3288: Add pinctrl driver Simon Glass
                   ` (17 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

Add a driver that provides access to system controllers.

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

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arm/mach-rockchip/rk3288/Makefile        |  1 +
 arch/arm/mach-rockchip/rk3288/syscon_rk3288.c | 25 +++++++++++++++++++++++++
 2 files changed, 26 insertions(+)
 create mode 100644 arch/arm/mach-rockchip/rk3288/syscon_rk3288.c

diff --git a/arch/arm/mach-rockchip/rk3288/Makefile b/arch/arm/mach-rockchip/rk3288/Makefile
index c6663f0..3f9900d 100644
--- a/arch/arm/mach-rockchip/rk3288/Makefile
+++ b/arch/arm/mach-rockchip/rk3288/Makefile
@@ -5,3 +5,4 @@
 #
 
 obj-y += reset_rk3288.o
+obj-y += syscon_rk3288.o
diff --git a/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c b/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c
new file mode 100644
index 0000000..c9f7c4e
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+
+static const struct udevice_id rk3288_syscon_ids[] = {
+	{ .compatible = "rockchip,rk3288-noc", .data = ROCKCHIP_SYSCON_NOC },
+	{ .compatible = "rockchip,rk3288-grf", .data = ROCKCHIP_SYSCON_GRF },
+	{ .compatible = "rockchip,rk3288-sgrf", .data = ROCKCHIP_SYSCON_SGRF },
+	{ .compatible = "rockchip,rk3288-pmu", .data = ROCKCHIP_SYSCON_PMU },
+	{ }
+};
+
+U_BOOT_DRIVER(syscon_rk3288) = {
+	.name = "rk3288_syscon",
+	.id = UCLASS_SYSCON,
+	.of_match = rk3288_syscon_ids,
+};
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 24/41] rockchip: rk3288: Add pinctrl driver
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (22 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 23/41] rockchip: rk3288: Add a simple syscon driver Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:59   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 25/41] rockchip: rk3288: Add SDRAM init Simon Glass
                   ` (16 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

Add a driver which supports pin multiplexing setup for the most commonly
used peripherals.

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

Changes in v5: None
Changes in v4:
- Add a set_state_simple() method
- Rename pinctrl.h to dm/pinctrl.h

Changes in v3: None
Changes in v2: None

 drivers/pinctrl/Kconfig                   |   9 +
 drivers/pinctrl/Makefile                  |   1 +
 drivers/pinctrl/rockchip/Makefile         |   8 +
 drivers/pinctrl/rockchip/pinctrl_rk3288.c | 441 ++++++++++++++++++++++++++++++
 4 files changed, 459 insertions(+)
 create mode 100644 drivers/pinctrl/rockchip/Makefile
 create mode 100644 drivers/pinctrl/rockchip/pinctrl_rk3288.c

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 918a859..b8146df 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -105,6 +105,15 @@ config SPL_PINCONF
 
 if PINCTRL || SPL_PINCTRL
 
+config ROCKCHIP_PINCTRL
+	bool "Rockchip pin control driver"
+	depends on DM
+	help
+	  Support pin multiplexing control on Rockchip SoCs. The driver is
+	  controlled by a device tree node which contains both the GPIO
+	  definitions and pin control functions for each available multiplex
+	  function.
+
 config PINCTRL_SANDBOX
 	bool "Sandbox pinctrl driver"
 	depends on SANDBOX
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 35decf4..f537df4 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -1,4 +1,5 @@
 obj-y					+= pinctrl-uclass.o
 obj-$(CONFIG_$(SPL_)PINCTRL_GENERIC)	+= pinctrl-generic.o
 
+obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
 obj-$(CONFIG_PINCTRL_SANDBOX)	+= pinctrl-sandbox.o
diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
new file mode 100644
index 0000000..251bace
--- /dev/null
+++ b/drivers/pinctrl/rockchip/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2015 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_ROCKCHIP_PINCTRL) += pinctrl_rk3288.o
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3288.c b/drivers/pinctrl/rockchip/pinctrl_rk3288.c
new file mode 100644
index 0000000..5205498
--- /dev/null
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3288.c
@@ -0,0 +1,441 @@
+/*
+ * Pinctrl driver for Rockchip SoCs
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/grf_rk3288.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/periph.h>
+#include <asm/arch/pmu_rk3288.h>
+#include <dm/pinctrl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct rk3288_pinctrl_priv {
+	struct rk3288_grf *grf;
+	struct rk3288_pmu *pmu;
+};
+
+static void pinctrl_rk3288_pwm_config(struct rk3288_grf *grf, int pwm_id)
+{
+	switch (pwm_id) {
+	case PERIPH_ID_PWM0:
+		rk_clrsetreg(&grf->gpio7a_iomux, GPIO7A0_MASK << GPIO7A0_SHIFT,
+			     GPIO7A0_PWM_0 << GPIO7A0_SHIFT);
+		break;
+	case PERIPH_ID_PWM1:
+		rk_clrsetreg(&grf->gpio7a_iomux, GPIO7A1_MASK << GPIO7A1_SHIFT,
+			     GPIO7A1_PWM_1 << GPIO7A1_SHIFT);
+		break;
+	case PERIPH_ID_PWM2:
+		rk_clrsetreg(&grf->gpio7a_iomux, GPIO7C6_MASK << GPIO7C6_SHIFT,
+			     GPIO7C6_PWM_2 << GPIO7C6_SHIFT);
+		break;
+	case PERIPH_ID_PWM3:
+		rk_clrsetreg(&grf->gpio7a_iomux, GPIO7C7_MASK << GPIO7C6_SHIFT,
+			     GPIO7C7_PWM_3 << GPIO7C7_SHIFT);
+		break;
+	default:
+		debug("pwm id = %d iomux error!\n", pwm_id);
+		break;
+	}
+}
+
+static void pinctrl_rk3288_i2c_config(struct rk3288_grf *grf,
+				      struct rk3288_pmu *pmu, int i2c_id)
+{
+	switch (i2c_id) {
+	case PERIPH_ID_I2C0:
+		clrsetbits_le32(&pmu->gpio0b_iomux,
+				GPIO0_B7_MASK << GPIO0_B7_SHIFT,
+				GPIO0_B7_I2C0PMU_SDA << GPIO0_B7_SHIFT);
+		clrsetbits_le32(&pmu->gpio0b_iomux,
+				GPIO0_C0_MASK << GPIO0_C0_SHIFT,
+				GPIO0_C0_I2C0PMU_SCL << GPIO0_C0_SHIFT);
+		break;
+	case PERIPH_ID_I2C1:
+		rk_clrsetreg(&grf->gpio8a_iomux,
+			     GPIO8A4_MASK << GPIO8A4_SHIFT |
+			     GPIO8A5_MASK << GPIO8A5_SHIFT,
+			     GPIO8A4_I2C2SENSOR_SDA << GPIO8A4_SHIFT |
+			     GPIO8A5_I2C2SENSOR_SCL << GPIO8A5_SHIFT);
+		break;
+	case PERIPH_ID_I2C2:
+		rk_clrsetreg(&grf->gpio6b_iomux,
+			     GPIO6B1_MASK << GPIO6B1_SHIFT |
+			     GPIO6B2_MASK << GPIO6B2_SHIFT,
+			     GPIO6B1_I2C1AUDIO_SDA << GPIO6B1_SHIFT |
+			     GPIO6B2_I2C1AUDIO_SCL << GPIO6B2_SHIFT);
+		break;
+	case PERIPH_ID_I2C3:
+		rk_clrsetreg(&grf->gpio2c_iomux,
+			     GPIO2C1_MASK << GPIO2C1_SHIFT |
+			     GPIO2C0_MASK << GPIO2C0_SHIFT,
+			     GPIO2C1_I2C3CAM_SDA << GPIO2C1_SHIFT |
+			     GPIO2C0_I2C3CAM_SCL << GPIO2C0_SHIFT);
+		break;
+	case PERIPH_ID_I2C4:
+		rk_clrsetreg(&grf->gpio7cl_iomux,
+			     GPIO7C1_MASK << GPIO7C1_SHIFT |
+			     GPIO7C2_MASK << GPIO7C2_SHIFT,
+			     GPIO7C1_I2C4TP_SDA << GPIO7C1_SHIFT |
+			     GPIO7C2_I2C4TP_SCL << GPIO7C2_SHIFT);
+		break;
+	case PERIPH_ID_I2C5:
+		rk_clrsetreg(&grf->gpio7cl_iomux,
+			     GPIO7C3_MASK << GPIO7C3_SHIFT,
+			     GPIO7C3_I2C5HDMI_SDA << GPIO7C3_SHIFT);
+		rk_clrsetreg(&grf->gpio7ch_iomux,
+			     GPIO7C4_MASK << GPIO7C4_SHIFT,
+			     GPIO7C4_I2C5HDMI_SCL << GPIO7C4_SHIFT);
+		break;
+	default:
+		debug("i2c id = %d iomux error!\n", i2c_id);
+		break;
+	}
+}
+
+static void pinctrl_rk3288_lcdc_config(struct rk3288_grf *grf, int lcd_id)
+{
+	switch (lcd_id) {
+	case PERIPH_ID_LCDC0:
+		rk_clrsetreg(&grf->gpio1d_iomux,
+			     GPIO1D3_MASK << GPIO1D0_SHIFT |
+			     GPIO1D2_MASK << GPIO1D2_SHIFT |
+			     GPIO1D1_MASK << GPIO1D1_SHIFT |
+			     GPIO1D0_MASK << GPIO1D0_SHIFT,
+			     GPIO1D3_LCDC0_DCLK << GPIO1D3_SHIFT |
+			     GPIO1D2_LCDC0_DEN << GPIO1D2_SHIFT |
+			     GPIO1D1_LCDC0_VSYNC << GPIO1D1_SHIFT |
+			     GPIO1D0_LCDC0_HSYNC << GPIO1D0_SHIFT);
+		break;
+	default:
+		debug("lcdc id = %d iomux error!\n", lcd_id);
+		break;
+	}
+}
+
+static int pinctrl_rk3288_spi_config(struct rk3288_grf *grf,
+				     enum periph_id spi_id, int cs)
+{
+	switch (spi_id) {
+	case PERIPH_ID_SPI0:
+		switch (cs) {
+		case 0:
+			rk_clrsetreg(&grf->gpio5b_iomux,
+				     GPIO5B5_MASK << GPIO5B5_SHIFT,
+				     GPIO5B5_SPI0_CSN0 << GPIO5B5_SHIFT);
+			break;
+		case 1:
+			rk_clrsetreg(&grf->gpio5c_iomux,
+				     GPIO5C0_MASK << GPIO5C0_SHIFT,
+				     GPIO5C0_SPI0_CSN1 << GPIO5C0_SHIFT);
+			break;
+		default:
+			goto err;
+		}
+		rk_clrsetreg(&grf->gpio5b_iomux,
+			     GPIO5B7_MASK << GPIO5B7_SHIFT |
+			     GPIO5B6_MASK << GPIO5B6_SHIFT |
+			     GPIO5B4_MASK << GPIO5B4_SHIFT,
+			     GPIO5B7_SPI0_RXD << GPIO5B7_SHIFT |
+			     GPIO5B6_SPI0_TXD << GPIO5B6_SHIFT |
+			     GPIO5B4_SPI0_CLK << GPIO5B4_SHIFT);
+		break;
+	case PERIPH_ID_SPI1:
+		if (cs != 0)
+			goto err;
+		rk_clrsetreg(&grf->gpio7b_iomux,
+			     GPIO7B6_MASK << GPIO7B6_SHIFT |
+			     GPIO7B7_MASK << GPIO7B7_SHIFT |
+			     GPIO7B5_MASK << GPIO7B5_SHIFT |
+			     GPIO7B4_MASK << GPIO7B4_SHIFT,
+			     GPIO7B6_SPI1_RXD << GPIO7B6_SHIFT |
+			     GPIO7B7_SPI1_TXD << GPIO7B7_SHIFT |
+			     GPIO7B5_SPI1_CSN0 << GPIO7B5_SHIFT |
+			     GPIO7B4_SPI1_CLK << GPIO7B4_SHIFT);
+		break;
+	case PERIPH_ID_SPI2:
+		switch (cs) {
+		case 0:
+			rk_clrsetreg(&grf->gpio8a_iomux,
+				     GPIO8A7_MASK << GPIO8A7_SHIFT,
+				     GPIO8A7_SPI2_CSN0 << GPIO8A7_SHIFT);
+			break;
+		case 1:
+			rk_clrsetreg(&grf->gpio8a_iomux,
+				     GPIO8A3_MASK << GPIO8A3_SHIFT,
+				     GPIO8A3_SPI2_CSN1 << GPIO8A3_SHIFT);
+			break;
+		default:
+			goto err;
+		}
+		rk_clrsetreg(&grf->gpio8b_iomux,
+			     GPIO8B1_MASK << GPIO8B1_SHIFT |
+			     GPIO8B0_MASK << GPIO8B0_SHIFT,
+			     GPIO8B1_SPI2_TXD << GPIO8B1_SHIFT |
+			     GPIO8B0_SPI2_RXD << GPIO8B0_SHIFT);
+		rk_clrsetreg(&grf->gpio8a_iomux,
+			     GPIO8A6_MASK << GPIO8A6_SHIFT,
+			     GPIO8A6_SPI2_CLK << GPIO8A6_SHIFT);
+		break;
+	default:
+		goto err;
+	}
+
+	return 0;
+err:
+	debug("rkspi: periph%d cs=%d not supported", spi_id, cs);
+	return -ENOENT;
+}
+
+static void pinctrl_rk3288_uart_config(struct rk3288_grf *grf, int uart_id)
+{
+	switch (uart_id) {
+	case PERIPH_ID_UART_BT:
+		rk_clrsetreg(&grf->gpio4c_iomux,
+			     GPIO4C3_MASK << GPIO4C3_SHIFT |
+			     GPIO4C2_MASK << GPIO4C2_SHIFT |
+			     GPIO4C1_MASK << GPIO4C1_SHIFT |
+			     GPIO4C0_MASK << GPIO4C0_SHIFT,
+			     GPIO4C3_UART0BT_RTSN << GPIO4C3_SHIFT |
+			     GPIO4C2_UART0BT_CTSN << GPIO4C2_SHIFT |
+			     GPIO4C1_UART0BT_SOUT << GPIO4C1_SHIFT |
+			     GPIO4C0_UART0BT_SIN << GPIO4C0_SHIFT);
+		break;
+	case PERIPH_ID_UART_BB:
+		rk_clrsetreg(&grf->gpio5b_iomux,
+			     GPIO5B3_MASK << GPIO5B3_SHIFT |
+			     GPIO5B2_MASK << GPIO5B2_SHIFT |
+			     GPIO5B1_MASK << GPIO5B1_SHIFT |
+			     GPIO5B0_MASK << GPIO5B0_SHIFT,
+			     GPIO5B3_UART1BB_RTSN << GPIO5B3_SHIFT |
+			     GPIO5B2_UART1BB_CTSN << GPIO5B2_SHIFT |
+			     GPIO5B1_UART1BB_SOUT << GPIO5B1_SHIFT |
+			     GPIO5B0_UART1BB_SIN << GPIO5B0_SHIFT);
+		break;
+	case PERIPH_ID_UART_DBG:
+		rk_clrsetreg(&grf->gpio7ch_iomux,
+			     GPIO7C7_MASK << GPIO7C7_SHIFT |
+			     GPIO7C6_MASK << GPIO7C6_SHIFT,
+			     GPIO7C7_UART2DBG_SOUT << GPIO7C7_SHIFT |
+			     GPIO7C6_UART2DBG_SIN << GPIO7C6_SHIFT);
+		break;
+	case PERIPH_ID_UART_GPS:
+		rk_clrsetreg(&grf->gpio7b_iomux,
+			     GPIO7B2_MASK << GPIO7B2_SHIFT |
+			     GPIO7B1_MASK << GPIO7B1_SHIFT |
+			     GPIO7B0_MASK << GPIO7B0_SHIFT,
+			     GPIO7B2_UART3GPS_RTSN << GPIO7B2_SHIFT |
+			     GPIO7B1_UART3GPS_CTSN << GPIO7B1_SHIFT |
+			     GPIO7B0_UART3GPS_SOUT << GPIO7B0_SHIFT);
+		rk_clrsetreg(&grf->gpio7a_iomux,
+			     GPIO7A7_MASK << GPIO7A7_SHIFT,
+			     GPIO7A7_UART3GPS_SIN << GPIO7A7_SHIFT);
+		break;
+	case PERIPH_ID_UART_EXP:
+		rk_clrsetreg(&grf->gpio5b_iomux,
+			     GPIO5B5_MASK << GPIO5B5_SHIFT |
+			     GPIO5B4_MASK << GPIO5B4_SHIFT |
+			     GPIO5B6_MASK << GPIO5B6_SHIFT |
+			     GPIO5B7_MASK << GPIO5B7_SHIFT,
+			     GPIO5B5_UART4EXP_RTSN << GPIO5B5_SHIFT |
+			     GPIO5B4_UART4EXP_CTSN << GPIO5B4_SHIFT |
+			     GPIO5B6_UART4EXP_SOUT << GPIO5B6_SHIFT |
+			     GPIO5B7_UART4EXP_SIN << GPIO5B7_SHIFT);
+		break;
+	default:
+		debug("uart id = %d iomux error!\n", uart_id);
+		break;
+	}
+}
+
+static void pinctrl_rk3288_sdmmc_config(struct rk3288_grf *grf, int mmc_id)
+{
+	switch (mmc_id) {
+	case PERIPH_ID_EMMC:
+		rk_clrsetreg(&grf->gpio3a_iomux, 0xffff,
+			     GPIO3A7_EMMC_DATA7 << GPIO3A7_SHIFT |
+			     GPIO3A6_EMMC_DATA6 << GPIO3A6_SHIFT |
+			     GPIO3A5_EMMC_DATA5 << GPIO3A5_SHIFT |
+			     GPIO3A4_EMMC_DATA4 << GPIO3A4_SHIFT |
+			     GPIO3A3_EMMC_DATA3 << GPIO3A3_SHIFT |
+			     GPIO3A2_EMMC_DATA2 << GPIO3A2_SHIFT |
+			     GPIO3A1_EMMC_DATA1 << GPIO3A1_SHIFT |
+			     GPIO3A0_EMMC_DATA0 << GPIO3A0_SHIFT);
+		rk_clrsetreg(&grf->gpio3b_iomux, GPIO3B1_MASK << GPIO3B1_SHIFT,
+			     GPIO3B1_EMMC_PWREN << GPIO3B1_SHIFT);
+		rk_clrsetreg(&grf->gpio3c_iomux,
+			     GPIO3C0_MASK << GPIO3C0_SHIFT,
+			     GPIO3C0_EMMC_CMD << GPIO3C0_SHIFT);
+		break;
+	case PERIPH_ID_SDCARD:
+		rk_clrsetreg(&grf->gpio6c_iomux, 0xffff,
+			     GPIO6C6_SDMMC0_DECTN << GPIO6C6_SHIFT |
+			     GPIO6C5_SDMMC0_CMD << GPIO6C5_SHIFT |
+			     GPIO6C4_SDMMC0_CLKOUT << GPIO6C4_SHIFT |
+			     GPIO6C3_SDMMC0_DATA3 << GPIO6C3_SHIFT |
+			     GPIO6C2_SDMMC0_DATA2 << GPIO6C2_SHIFT |
+			     GPIO6C1_SDMMC0_DATA1 << GPIO6C1_SHIFT |
+			     GPIO6C0_SDMMC0_DATA0 << GPIO6C0_SHIFT);
+
+		/* use sdmmc0 io, disable JTAG function */
+		rk_clrsetreg(&grf->soc_con0, 1 << GRF_FORCE_JTAG_SHIFT, 0);
+		break;
+	default:
+		debug("mmc id = %d iomux error!\n", mmc_id);
+		break;
+	}
+}
+
+static void pinctrl_rk3288_hdmi_config(struct rk3288_grf *grf, int hdmi_id)
+{
+	switch (hdmi_id) {
+	case PERIPH_ID_HDMI:
+		rk_clrsetreg(&grf->gpio7cl_iomux, GPIO7C3_MASK << GPIO7C3_SHIFT,
+			     GPIO7C3_EDPHDMII2C_SDA << GPIO7C3_SHIFT);
+		rk_clrsetreg(&grf->gpio7ch_iomux, GPIO7C4_MASK << GPIO7C4_SHIFT,
+			     GPIO7C4_EDPHDMII2C_SCL << GPIO7C4_SHIFT);
+		break;
+	default:
+		debug("hdmi id = %d iomux error!\n", hdmi_id);
+		break;
+	}
+}
+
+static int rk3288_pinctrl_request(struct udevice *dev, int func, int flags)
+{
+	struct rk3288_pinctrl_priv *priv = dev_get_priv(dev);
+
+	debug("%s: func=%x, flags=%x\n", __func__, func, flags);
+	switch (func) {
+	case PERIPH_ID_PWM0:
+	case PERIPH_ID_PWM1:
+	case PERIPH_ID_PWM2:
+	case PERIPH_ID_PWM3:
+	case PERIPH_ID_PWM4:
+		pinctrl_rk3288_pwm_config(priv->grf, func);
+		break;
+	case PERIPH_ID_I2C0:
+	case PERIPH_ID_I2C1:
+	case PERIPH_ID_I2C2:
+	case PERIPH_ID_I2C3:
+	case PERIPH_ID_I2C4:
+	case PERIPH_ID_I2C5:
+		pinctrl_rk3288_i2c_config(priv->grf, priv->pmu, func);
+		break;
+	case PERIPH_ID_SPI0:
+	case PERIPH_ID_SPI1:
+	case PERIPH_ID_SPI2:
+		pinctrl_rk3288_spi_config(priv->grf, func, flags);
+		break;
+	case PERIPH_ID_UART0:
+	case PERIPH_ID_UART1:
+	case PERIPH_ID_UART2:
+	case PERIPH_ID_UART3:
+	case PERIPH_ID_UART4:
+		pinctrl_rk3288_uart_config(priv->grf, func);
+		break;
+	case PERIPH_ID_LCDC0:
+	case PERIPH_ID_LCDC1:
+		pinctrl_rk3288_lcdc_config(priv->grf, func);
+		break;
+	case PERIPH_ID_SDMMC0:
+	case PERIPH_ID_SDMMC1:
+		pinctrl_rk3288_sdmmc_config(priv->grf, func);
+		break;
+	case PERIPH_ID_HDMI:
+		pinctrl_rk3288_hdmi_config(priv->grf, func);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int rk3288_pinctrl_get_periph_id(struct udevice *dev,
+					struct udevice *periph)
+{
+	u32 cell[3];
+	int ret;
+
+	ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
+				   "interrupts", cell, ARRAY_SIZE(cell));
+	if (ret < 0)
+		return -EINVAL;
+
+	switch (cell[1]) {
+	case 44:
+		return PERIPH_ID_SPI0;
+	case 45:
+		return PERIPH_ID_SPI1;
+	case 46:
+		return PERIPH_ID_SPI2;
+	case 60:
+		return PERIPH_ID_I2C0;
+	case 62: /* Note strange order */
+		return PERIPH_ID_I2C1;
+	case 61:
+		return PERIPH_ID_I2C2;
+	case 63:
+		return PERIPH_ID_I2C3;
+	case 64:
+		return PERIPH_ID_I2C4;
+	case 65:
+		return PERIPH_ID_I2C5;
+	}
+
+	return -ENOENT;
+}
+
+static int rk3288_pinctrl_set_state_simple(struct udevice *dev,
+					   struct udevice *periph)
+{
+	int func;
+
+	func = rk3288_pinctrl_get_periph_id(dev, periph);
+	if (func < 0)
+		return func;
+	return rk3288_pinctrl_request(dev, func, 0);
+}
+
+static struct pinctrl_ops rk3288_pinctrl_ops = {
+	.set_state_simple	= rk3288_pinctrl_set_state_simple,
+	.request	= rk3288_pinctrl_request,
+	.get_periph_id	= rk3288_pinctrl_get_periph_id,
+};
+
+static int rk3288_pinctrl_probe(struct udevice *dev)
+{
+	struct rk3288_pinctrl_priv *priv = dev_get_priv(dev);
+
+	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+	priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
+	debug("%s: grf=%p, pmu=%p\n", __func__, priv->grf, priv->pmu);
+
+	return 0;
+}
+
+static const struct udevice_id rk3288_pinctrl_ids[] = {
+	{ .compatible = "rockchip,rk3288-pinctrl" },
+	{ }
+};
+
+U_BOOT_DRIVER(pinctrl_rk3288) = {
+	.name		= "pinctrl_rk3288",
+	.id		= UCLASS_PINCTRL,
+	.of_match	= rk3288_pinctrl_ids,
+	.priv_auto_alloc_size = sizeof(struct rk3288_pinctrl_priv),
+	.ops		= &rk3288_pinctrl_ops,
+	.probe		= rk3288_pinctrl_probe,
+};
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 25/41] rockchip: rk3288: Add SDRAM init
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (23 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 24/41] rockchip: rk3288: Add pinctrl driver Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:59   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 26/41] rockchip: Add an MMC driver Simon Glass
                   ` (15 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

Add code to set up the SDRAM in SPL, ready for loading U-Boot. This uses
device tree for configuration so should be able to support other RAM
configurations. It may be possible to generalise the code to support other
SoCs at some point.

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

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arm/include/asm/arch-rockchip/ddr_rk3288.h | 484 +++++++++++++
 arch/arm/include/asm/arch-rockchip/sdram.h      |  92 +++
 arch/arm/mach-rockchip/rk3288/Makefile          |   1 +
 arch/arm/mach-rockchip/rk3288/sdram_rk3288.c    | 878 ++++++++++++++++++++++++
 4 files changed, 1455 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-rockchip/ddr_rk3288.h
 create mode 100644 arch/arm/include/asm/arch-rockchip/sdram.h
 create mode 100644 arch/arm/mach-rockchip/rk3288/sdram_rk3288.c

diff --git a/arch/arm/include/asm/arch-rockchip/ddr_rk3288.h b/arch/arm/include/asm/arch-rockchip/ddr_rk3288.h
new file mode 100644
index 0000000..fccabcd
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/ddr_rk3288.h
@@ -0,0 +1,484 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef _ASM_ARCH_DDR_RK3288_H
+#define _ASM_ARCH_DDR_RK3288_H
+
+struct rk3288_ddr_pctl {
+	u32 scfg;
+	u32 sctl;
+	u32 stat;
+	u32 intrstat;
+	u32 reserved0[12];
+	u32 mcmd;
+	u32 powctl;
+	u32 powstat;
+	u32 cmdtstat;
+	u32 tstaten;
+	u32 reserved1[3];
+	u32 mrrcfg0;
+	u32 mrrstat0;
+	u32 mrrstat1;
+	u32 reserved2[4];
+	u32 mcfg1;
+	u32 mcfg;
+	u32 ppcfg;
+	u32 mstat;
+	u32 lpddr2zqcfg;
+	u32 reserved3;
+	u32 dtupdes;
+	u32 dtuna;
+	u32 dtune;
+	u32 dtuprd0;
+	u32 dtuprd1;
+	u32 dtuprd2;
+	u32 dtuprd3;
+	u32 dtuawdt;
+	u32 reserved4[3];
+	u32 togcnt1u;
+	u32 tinit;
+	u32 trsth;
+	u32 togcnt100n;
+	u32 trefi;
+	u32 tmrd;
+	u32 trfc;
+	u32 trp;
+	u32 trtw;
+	u32 tal;
+	u32 tcl;
+	u32 tcwl;
+	u32 tras;
+	u32 trc;
+	u32 trcd;
+	u32 trrd;
+	u32 trtp;
+	u32 twr;
+	u32 twtr;
+	u32 texsr;
+	u32 txp;
+	u32 txpdll;
+	u32 tzqcs;
+	u32 tzqcsi;
+	u32 tdqs;
+	u32 tcksre;
+	u32 tcksrx;
+	u32 tcke;
+	u32 tmod;
+	u32 trstl;
+	u32 tzqcl;
+	u32 tmrr;
+	u32 tckesr;
+	u32 tdpd;
+	u32 reserved5[14];
+	u32 ecccfg;
+	u32 ecctst;
+	u32 eccclr;
+	u32 ecclog;
+	u32 reserved6[28];
+	u32 dtuwactl;
+	u32 dturactl;
+	u32 dtucfg;
+	u32 dtuectl;
+	u32 dtuwd0;
+	u32 dtuwd1;
+	u32 dtuwd2;
+	u32 dtuwd3;
+	u32 dtuwdm;
+	u32 dturd0;
+	u32 dturd1;
+	u32 dturd2;
+	u32 dturd3;
+	u32 dtulfsrwd;
+	u32 dtulfsrrd;
+	u32 dtueaf;
+	u32 dfitctrldelay;
+	u32 dfiodtcfg;
+	u32 dfiodtcfg1;
+	u32 dfiodtrankmap;
+	u32 dfitphywrdata;
+	u32 dfitphywrlat;
+	u32 reserved7[2];
+	u32 dfitrddataen;
+	u32 dfitphyrdlat;
+	u32 reserved8[2];
+	u32 dfitphyupdtype0;
+	u32 dfitphyupdtype1;
+	u32 dfitphyupdtype2;
+	u32 dfitphyupdtype3;
+	u32 dfitctrlupdmin;
+	u32 dfitctrlupdmax;
+	u32 dfitctrlupddly;
+	u32 reserved9;
+	u32 dfiupdcfg;
+	u32 dfitrefmski;
+	u32 dfitctrlupdi;
+	u32 reserved10[4];
+	u32 dfitrcfg0;
+	u32 dfitrstat0;
+	u32 dfitrwrlvlen;
+	u32 dfitrrdlvlen;
+	u32 dfitrrdlvlgateen;
+	u32 dfiststat0;
+	u32 dfistcfg0;
+	u32 dfistcfg1;
+	u32 reserved11;
+	u32 dfitdramclken;
+	u32 dfitdramclkdis;
+	u32 dfistcfg2;
+	u32 dfistparclr;
+	u32 dfistparlog;
+	u32 reserved12[3];
+	u32 dfilpcfg0;
+	u32 reserved13[3];
+	u32 dfitrwrlvlresp0;
+	u32 dfitrwrlvlresp1;
+	u32 dfitrwrlvlresp2;
+	u32 dfitrrdlvlresp0;
+	u32 dfitrrdlvlresp1;
+	u32 dfitrrdlvlresp2;
+	u32 dfitrwrlvldelay0;
+	u32 dfitrwrlvldelay1;
+	u32 dfitrwrlvldelay2;
+	u32 dfitrrdlvldelay0;
+	u32 dfitrrdlvldelay1;
+	u32 dfitrrdlvldelay2;
+	u32 dfitrrdlvlgatedelay0;
+	u32 dfitrrdlvlgatedelay1;
+	u32 dfitrrdlvlgatedelay2;
+	u32 dfitrcmd;
+	u32 reserved14[46];
+	u32 ipvr;
+	u32 iptr;
+};
+check_member(rk3288_ddr_pctl, iptr, 0x03fc);
+
+struct rk3288_ddr_publ_datx {
+	u32 dxgcr;
+	u32 dxgsr[2];
+	u32 dxdllcr;
+	u32 dxdqtr;
+	u32 dxdqstr;
+	u32 reserved[10];
+};
+
+struct rk3288_ddr_publ {
+	u32 ridr;
+	u32 pir;
+	u32 pgcr;
+	u32 pgsr;
+	u32 dllgcr;
+	u32 acdllcr;
+	u32 ptr[3];
+	u32 aciocr;
+	u32 dxccr;
+	u32 dsgcr;
+	u32 dcr;
+	u32 dtpr[3];
+	u32 mr[4];
+	u32 odtcr;
+	u32 dtar;
+	u32 dtdr[2];
+	u32 reserved1[24];
+	u32 dcuar;
+	u32 dcudr;
+	u32 dcurr;
+	u32 dculr;
+	u32 dcugcr;
+	u32 dcutpr;
+	u32 dcusr[2];
+	u32 reserved2[8];
+	u32 bist[17];
+	u32 reserved3[15];
+	u32 zq0cr[2];
+	u32 zq0sr[2];
+	u32 zq1cr[2];
+	u32 zq1sr[2];
+	u32 zq2cr[2];
+	u32 zq2sr[2];
+	u32 zq3cr[2];
+	u32 zq3sr[2];
+	struct rk3288_ddr_publ_datx datx8[4];
+};
+check_member(rk3288_ddr_publ, datx8[3].dxdqstr, 0x0294);
+
+struct rk3288_msch {
+	u32 coreid;
+	u32 revisionid;
+	u32 ddrconf;
+	u32 ddrtiming;
+	u32 ddrmode;
+	u32 readlatency;
+	u32 reserved1[8];
+	u32 activate;
+	u32 devtodev;
+};
+check_member(rk3288_msch, devtodev, 0x003c);
+
+/* PCT_DFISTCFG0 */
+#define DFI_INIT_START			(1 << 0)
+
+/* PCT_DFISTCFG1 */
+#define DFI_DRAM_CLK_SR_EN		(1 << 0)
+#define DFI_DRAM_CLK_DPD_EN		(1 << 1)
+
+/* PCT_DFISTCFG2 */
+#define DFI_PARITY_INTR_EN		(1 << 0)
+#define DFI_PARITY_EN			(1 << 1)
+
+/* PCT_DFILPCFG0 */
+#define TLP_RESP_TIME_SHIFT		16
+#define LP_SR_EN			(1 << 8)
+#define LP_PD_EN			(1 << 0)
+
+/* PCT_DFITCTRLDELAY */
+#define TCTRL_DELAY_TIME_SHIFT		0
+
+/* PCT_DFITPHYWRDATA */
+#define TPHY_WRDATA_TIME_SHIFT		0
+
+/* PCT_DFITPHYRDLAT */
+#define TPHY_RDLAT_TIME_SHIFT		0
+
+/* PCT_DFITDRAMCLKDIS */
+#define TDRAM_CLK_DIS_TIME_SHIFT	0
+
+/* PCT_DFITDRAMCLKEN */
+#define TDRAM_CLK_EN_TIME_SHIFT		0
+
+/* PCTL_DFIODTCFG */
+#define RANK0_ODT_WRITE_SEL		(1 << 3)
+#define RANK1_ODT_WRITE_SEL		(1 << 11)
+
+/* PCTL_DFIODTCFG1 */
+#define ODT_LEN_BL8_W_SHIFT		16
+
+/* PUBL_ACDLLCR */
+#define ACDLLCR_DLLDIS			(1 << 31)
+#define ACDLLCR_DLLSRST			(1 << 30)
+
+/* PUBL_DXDLLCR */
+#define DXDLLCR_DLLDIS			(1 << 31)
+#define DXDLLCR_DLLSRST			(1 << 30)
+
+/* PUBL_DLLGCR */
+#define DLLGCR_SBIAS			(1 << 30)
+
+/* PUBL_DXGCR */
+#define DQSRTT				(1 << 9)
+#define DQRTT				(1 << 10)
+
+/* PIR */
+#define PIR_INIT			(1 << 0)
+#define PIR_DLLSRST			(1 << 1)
+#define PIR_DLLLOCK			(1 << 2)
+#define PIR_ZCAL			(1 << 3)
+#define PIR_ITMSRST			(1 << 4)
+#define PIR_DRAMRST			(1 << 5)
+#define PIR_DRAMINIT			(1 << 6)
+#define PIR_QSTRN			(1 << 7)
+#define PIR_RVTRN			(1 << 8)
+#define PIR_ICPC			(1 << 16)
+#define PIR_DLLBYP			(1 << 17)
+#define PIR_CTLDINIT			(1 << 18)
+#define PIR_CLRSR			(1 << 28)
+#define PIR_LOCKBYP			(1 << 29)
+#define PIR_ZCALBYP			(1 << 30)
+#define PIR_INITBYP			(1u << 31)
+
+/* PGCR */
+#define PGCR_DFTLMT_SHIFT		3
+#define PGCR_DFTCMP_SHIFT		2
+#define PGCR_DQSCFG_SHIFT		1
+#define PGCR_ITMDMD_SHIFT		0
+
+/* PGSR */
+#define PGSR_IDONE			(1 << 0)
+#define PGSR_DLDONE			(1 << 1)
+#define PGSR_ZCDONE			(1 << 2)
+#define PGSR_DIDONE			(1 << 3)
+#define PGSR_DTDONE			(1 << 4)
+#define PGSR_DTERR			(1 << 5)
+#define PGSR_DTIERR			(1 << 6)
+#define PGSR_DFTERR			(1 << 7)
+#define PGSR_RVERR			(1 << 8)
+#define PGSR_RVEIRR			(1 << 9)
+
+/* PTR0 */
+#define PRT_ITMSRST_SHIFT		18
+#define PRT_DLLLOCK_SHIFT		6
+#define PRT_DLLSRST_SHIFT		0
+
+/* PTR1 */
+#define PRT_DINIT0_SHIFT		0
+#define PRT_DINIT1_SHIFT		19
+
+/* PTR2 */
+#define PRT_DINIT2_SHIFT		0
+#define PRT_DINIT3_SHIFT		17
+
+/* DCR */
+#define DDRMD_LPDDR			0
+#define DDRMD_DDR			1
+#define DDRMD_DDR2			2
+#define DDRMD_DDR3			3
+#define DDRMD_LPDDR2_LPDDR3		4
+#define DDRMD_MASK			7
+#define DDRMD_SHIFT			0
+#define PDQ_MASK			7
+#define PDQ_SHIFT			4
+
+/* DXCCR */
+#define DQSNRES_MASK			0xf
+#define DQSNRES_SHIFT			8
+#define DQSRES_MASK			0xf
+#define DQSRES_SHIFT			4
+
+/* DTPR */
+#define TDQSCKMAX_SHIFT			27
+#define TDQSCKMAX_MASK			7
+#define TDQSCK_SHIFT			24
+#define TDQSCK_MASK			7
+
+/* DSGCR */
+#define DQSGX_SHIFT			5
+#define DQSGX_MASK			7
+#define DQSGE_SHIFT			8
+#define DQSGE_MASK			7
+
+/* SCTL */
+#define INIT_STATE			0
+#define CFG_STATE			1
+#define GO_STATE			2
+#define SLEEP_STATE			3
+#define WAKEUP_STATE			4
+
+/* STAT */
+#define LP_TRIG_SHIFT			4
+#define LP_TRIG_MASK			7
+#define PCTL_STAT_MSK			7
+#define INIT_MEM			0
+#define CONFIG				1
+#define CONFIG_REQ			2
+#define ACCESS				3
+#define ACCESS_REQ			4
+#define LOW_POWER			5
+#define LOW_POWER_ENTRY_REQ		6
+#define LOW_POWER_EXIT_REQ		7
+
+/* ZQCR*/
+#define PD_OUTPUT_SHIFT			0
+#define PU_OUTPUT_SHIFT			5
+#define PD_ONDIE_SHIFT			10
+#define PU_ONDIE_SHIFT			15
+#define ZDEN_SHIFT			28
+
+/* DDLGCR */
+#define SBIAS_BYPASS			(1 << 23)
+
+/* MCFG */
+#define MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT	24
+#define PD_IDLE_SHIFT			8
+#define MDDR_EN				(2 << 22)
+#define LPDDR2_EN			(3 << 22)
+#define DDR2_EN				(0 << 5)
+#define DDR3_EN				(1 << 5)
+#define LPDDR2_S2			(0 << 6)
+#define LPDDR2_S4			(1 << 6)
+#define MDDR_LPDDR2_BL_2		(0 << 20)
+#define MDDR_LPDDR2_BL_4		(1 << 20)
+#define MDDR_LPDDR2_BL_8		(2 << 20)
+#define MDDR_LPDDR2_BL_16		(3 << 20)
+#define DDR2_DDR3_BL_4			0
+#define DDR2_DDR3_BL_8			1
+#define TFAW_SHIFT			18
+#define PD_EXIT_SLOW			(0 << 17)
+#define PD_EXIT_FAST			(1 << 17)
+#define PD_TYPE_SHIFT			16
+#define BURSTLENGTH_SHIFT		20
+
+/* POWCTL */
+#define POWER_UP_START			(1 << 0)
+
+/* POWSTAT */
+#define POWER_UP_DONE			(1 << 0)
+
+/* MCMD */
+enum {
+	DESELECT_CMD			= 0,
+	PREA_CMD,
+	REF_CMD,
+	MRS_CMD,
+	ZQCS_CMD,
+	ZQCL_CMD,
+	RSTL_CMD,
+	MRR_CMD				= 8,
+	DPDE_CMD,
+};
+
+#define LPDDR2_MA_SHIFT			4
+#define LPDDR2_MA_MASK			0xff
+#define LPDDR2_OP_SHIFT			12
+#define LPDDR2_OP_MASK			0xff
+
+#define START_CMD			(1u << 31)
+
+/* DEVTODEV */
+#define BUSWRTORD_SHIFT			4
+#define BUSRDTOWR_SHIFT			2
+#define BUSRDTORD_SHIFT			0
+
+/* mr1 for ddr3 */
+#define DDR3_DLL_DISABLE		1
+
+/*
+ *TODO(sjg@chromium.org): We use a PMU register to store SDRAM information for
+ * passing from SPL to U-Boot. It would probably be better to use a normal C
+ * structure in SRAM.
+ *
+ * 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
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram.h b/arch/arm/include/asm/arch-rockchip/sdram.h
new file mode 100644
index 0000000..d3de42d
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/sdram.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ *
+ * Copyright 2014 Rockchip Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef _ASM_ARCH_RK3288_SDRAM_H__
+#define _ASM_ARCH_RK3288_SDRAM_H__
+
+enum {
+	DDR3 = 3,
+	LPDDR3 = 6,
+	UNUSED = 0xFF,
+};
+
+struct rk3288_sdram_channel {
+	u8 rank;
+	u8 col;
+	u8 bk;
+	u8 bw;
+	u8 dbw;
+	u8 row_3_4;
+	u8 cs0_row;
+	u8 cs1_row;
+};
+
+struct rk3288_sdram_pctl_timing {
+	u32 togcnt1u;
+	u32 tinit;
+	u32 trsth;
+	u32 togcnt100n;
+	u32 trefi;
+	u32 tmrd;
+	u32 trfc;
+	u32 trp;
+	u32 trtw;
+	u32 tal;
+	u32 tcl;
+	u32 tcwl;
+	u32 tras;
+	u32 trc;
+	u32 trcd;
+	u32 trrd;
+	u32 trtp;
+	u32 twr;
+	u32 twtr;
+	u32 texsr;
+	u32 txp;
+	u32 txpdll;
+	u32 tzqcs;
+	u32 tzqcsi;
+	u32 tdqs;
+	u32 tcksre;
+	u32 tcksrx;
+	u32 tcke;
+	u32 tmod;
+	u32 trstl;
+	u32 tzqcl;
+	u32 tmrr;
+	u32 tckesr;
+	u32 tdpd;
+};
+check_member(rk3288_sdram_pctl_timing, tdpd, 0x144 - 0xc0);
+
+struct rk3288_sdram_phy_timing {
+	u32 dtpr0;
+	u32 dtpr1;
+	u32 dtpr2;
+	u32 mr[4];
+};
+
+struct rk3288_base_params {
+	u32 noc_timing;
+	u32 noc_activate;
+	u32 ddrconfig;
+	u32 ddr_freq;
+	u32 dramtype;
+	u32 stride;
+	u32 odt;
+};
+
+struct rk3288_sdram_params {
+	struct rk3288_sdram_channel ch[2];
+	struct rk3288_sdram_pctl_timing pctl_timing;
+	struct rk3288_sdram_phy_timing phy_timing;
+	struct rk3288_base_params base;
+	int num_channels;
+};
+
+#endif
diff --git a/arch/arm/mach-rockchip/rk3288/Makefile b/arch/arm/mach-rockchip/rk3288/Makefile
index 3f9900d..6f62375 100644
--- a/arch/arm/mach-rockchip/rk3288/Makefile
+++ b/arch/arm/mach-rockchip/rk3288/Makefile
@@ -5,4 +5,5 @@
 #
 
 obj-y += reset_rk3288.o
+obj-y += sdram_rk3288.o
 obj-y += syscon_rk3288.o
diff --git a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
new file mode 100644
index 0000000..09017cc
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
@@ -0,0 +1,878 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ * Copyright 2014 Rockchip Inc.
+ *
+ * SPDX-License-Identifier:     GPL-2.0
+ *
+ * Adapted from coreboot.
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <errno.h>
+#include <ram.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3288.h>
+#include <asm/arch/ddr_rk3288.h>
+#include <asm/arch/grf_rk3288.h>
+#include <asm/arch/pmu_rk3288.h>
+#include <asm/arch/sdram.h>
+#include <linux/err.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct chan_info {
+	struct rk3288_ddr_pctl *pctl;
+	struct rk3288_ddr_publ *publ;
+	struct rk3288_msch *msch;
+};
+
+struct dram_info {
+	struct chan_info chan[2];
+	struct ram_info info;
+	struct udevice *ddr_clk;
+	struct rk3288_cru *cru;
+	struct rk3288_grf *grf;
+	struct rk3288_sgrf *sgrf;
+	struct rk3288_pmu *pmu;
+};
+
+#ifdef CONFIG_SPL_BUILD
+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 ddr_reset(struct rk3288_cru *cru, u32 ch, u32 ctl, u32 phy)
+{
+	u32 phy_ctl_srstn_shift = 4 + 5 * ch;
+	u32 ctl_psrstn_shift = 3 + 5 * ch;
+	u32 ctl_srstn_shift = 2 + 5 * ch;
+	u32 phy_psrstn_shift = 1 + 5 * ch;
+	u32 phy_srstn_shift = 5 * ch;
+
+	rk_clrsetreg(&cru->cru_softrst_con[10],
+		     1 << phy_ctl_srstn_shift | 1 << ctl_psrstn_shift |
+		     1 << ctl_srstn_shift | 1 << phy_psrstn_shift |
+		     1 << phy_srstn_shift,
+		     phy << phy_ctl_srstn_shift | ctl << ctl_psrstn_shift |
+		     ctl << ctl_srstn_shift | phy << phy_psrstn_shift |
+		     phy << phy_srstn_shift);
+}
+
+static void ddr_phy_ctl_reset(struct rk3288_cru *cru, u32 ch, u32 n)
+{
+	u32 phy_ctl_srstn_shift = 4 + 5 * ch;
+
+	rk_clrsetreg(&cru->cru_softrst_con[10],
+		     1 << phy_ctl_srstn_shift, n << phy_ctl_srstn_shift);
+}
+
+static void phy_pctrl_reset(struct rk3288_cru *cru,
+			    struct rk3288_ddr_publ *publ,
+			    u32 channel)
+{
+	int i;
+
+	ddr_reset(cru, channel, 1, 1);
+	udelay(1);
+	clrbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST);
+	for (i = 0; i < 4; i++)
+		clrbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST);
+
+	udelay(10);
+	setbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST);
+	for (i = 0; i < 4; i++)
+		setbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST);
+
+	udelay(10);
+	ddr_reset(cru, channel, 1, 0);
+	udelay(10);
+	ddr_reset(cru, channel, 0, 0);
+	udelay(10);
+}
+
+static void phy_dll_bypass_set(struct rk3288_ddr_publ *publ,
+	u32 freq)
+{
+	int i;
+	if (freq <= 250000000) {
+		if (freq <= 150000000)
+			clrbits_le32(&publ->dllgcr, SBIAS_BYPASS);
+		else
+			setbits_le32(&publ->dllgcr, SBIAS_BYPASS);
+		setbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS);
+		for (i = 0; i < 4; i++)
+			setbits_le32(&publ->datx8[i].dxdllcr,
+				     DXDLLCR_DLLDIS);
+
+		setbits_le32(&publ->pir, PIR_DLLBYP);
+	} else {
+		clrbits_le32(&publ->dllgcr, SBIAS_BYPASS);
+		clrbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS);
+		for (i = 0; i < 4; i++) {
+			clrbits_le32(&publ->datx8[i].dxdllcr,
+				     DXDLLCR_DLLDIS);
+		}
+
+		clrbits_le32(&publ->pir, PIR_DLLBYP);
+	}
+}
+
+static void dfi_cfg(struct rk3288_ddr_pctl *pctl, u32 dramtype)
+{
+	writel(DFI_INIT_START, &pctl->dfistcfg0);
+	writel(DFI_DRAM_CLK_SR_EN | DFI_DRAM_CLK_DPD_EN,
+	       &pctl->dfistcfg1);
+	writel(DFI_PARITY_INTR_EN | DFI_PARITY_EN, &pctl->dfistcfg2);
+	writel(7 << TLP_RESP_TIME_SHIFT | LP_SR_EN | LP_PD_EN,
+	       &pctl->dfilpcfg0);
+
+	writel(2 << TCTRL_DELAY_TIME_SHIFT, &pctl->dfitctrldelay);
+	writel(1 << TPHY_WRDATA_TIME_SHIFT, &pctl->dfitphywrdata);
+	writel(0xf << TPHY_RDLAT_TIME_SHIFT, &pctl->dfitphyrdlat);
+	writel(2 << TDRAM_CLK_DIS_TIME_SHIFT, &pctl->dfitdramclkdis);
+	writel(2 << TDRAM_CLK_EN_TIME_SHIFT, &pctl->dfitdramclken);
+	writel(1, &pctl->dfitphyupdtype0);
+
+	/* cs0 and cs1 write odt enable */
+	writel((RANK0_ODT_WRITE_SEL | RANK1_ODT_WRITE_SEL),
+	       &pctl->dfiodtcfg);
+	/* odt write length */
+	writel(7 << ODT_LEN_BL8_W_SHIFT, &pctl->dfiodtcfg1);
+	/* phyupd and ctrlupd disabled */
+	writel(0, &pctl->dfiupdcfg);
+}
+
+static void ddr_set_enable(struct rk3288_grf *grf, uint channel, bool enable)
+{
+	uint val = 0;
+
+	if (enable) {
+		val = 1 << (channel ? DDR1_16BIT_EN_SHIFT :
+				DDR0_16BIT_EN_SHIFT);
+	}
+	rk_clrsetreg(&grf->soc_con0,
+		     1 << (channel ? DDR1_16BIT_EN_SHIFT : DDR0_16BIT_EN_SHIFT),
+		     val);
+}
+
+static void ddr_set_ddr3_mode(struct rk3288_grf *grf, uint channel,
+			      bool ddr3_mode)
+{
+	uint mask, val;
+
+	mask = 1 << (channel ? MSCH1_MAINDDR3_SHIFT : MSCH0_MAINDDR3_SHIFT);
+	val = ddr3_mode << (channel ? MSCH1_MAINDDR3_SHIFT :
+					MSCH0_MAINDDR3_SHIFT);
+	rk_clrsetreg(&grf->soc_con0, mask, val);
+}
+
+static void ddr_set_en_bst_odt(struct rk3288_grf *grf, uint channel,
+			       bool enable, bool enable_bst, bool enable_odt)
+{
+	uint mask;
+	bool disable_bst = !enable_bst;
+
+	mask = channel ?
+		(1 << LPDDR3_EN1_SHIFT | 1 << UPCTL1_BST_DIABLE_SHIFT |
+			1 << UPCTL1_LPDDR3_ODT_EN_SHIFT) :
+		(1 << LPDDR3_EN0_SHIFT | 1 << UPCTL0_BST_DIABLE_SHIFT |
+			1 << UPCTL0_LPDDR3_ODT_EN_SHIFT);
+	rk_clrsetreg(&grf->soc_con2, mask,
+		     enable << (channel ? LPDDR3_EN1_SHIFT : LPDDR3_EN0_SHIFT) |
+		     disable_bst << (channel ? UPCTL1_BST_DIABLE_SHIFT :
+				UPCTL0_BST_DIABLE_SHIFT) |
+		     enable_odt << (channel ? UPCTL1_LPDDR3_ODT_EN_SHIFT :
+				UPCTL0_LPDDR3_ODT_EN_SHIFT));
+}
+
+static void pctl_cfg(u32 channel, struct rk3288_ddr_pctl *pctl,
+		     const struct rk3288_sdram_params *sdram_params,
+		     struct rk3288_grf *grf)
+{
+	unsigned int burstlen;
+
+	burstlen = (sdram_params->base.noc_timing >> 18) & 0x7;
+	copy_to_reg(&pctl->togcnt1u, &sdram_params->pctl_timing.togcnt1u,
+		    sizeof(sdram_params->pctl_timing));
+	switch (sdram_params->base.dramtype) {
+	case LPDDR3:
+		writel(sdram_params->pctl_timing.tcl - 1,
+		       &pctl->dfitrddataen);
+		writel(sdram_params->pctl_timing.tcwl,
+		       &pctl->dfitphywrlat);
+		burstlen >>= 1;
+		writel(LPDDR2_S4 | 0 << MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT |
+		       LPDDR2_EN | burstlen << BURSTLENGTH_SHIFT |
+		       (6 - 4) << TFAW_SHIFT | PD_EXIT_FAST |
+		       1 << PD_TYPE_SHIFT | 0 << PD_IDLE_SHIFT,
+		       &pctl->mcfg);
+		ddr_set_ddr3_mode(grf, channel, false);
+		ddr_set_enable(grf, channel, true);
+		ddr_set_en_bst_odt(grf, channel, true, false,
+				   sdram_params->base.odt);
+		break;
+	case DDR3:
+		if (sdram_params->phy_timing.mr[1] & DDR3_DLL_DISABLE) {
+			writel(sdram_params->pctl_timing.tcl - 3,
+			       &pctl->dfitrddataen);
+		} else {
+			writel(sdram_params->pctl_timing.tcl - 2,
+			       &pctl->dfitrddataen);
+		}
+		writel(sdram_params->pctl_timing.tcwl - 1,
+		       &pctl->dfitphywrlat);
+		writel(0 << MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT | DDR3_EN |
+		       DDR2_DDR3_BL_8 | (6 - 4) << TFAW_SHIFT | PD_EXIT_SLOW |
+		       1 << PD_TYPE_SHIFT | 0 << PD_IDLE_SHIFT,
+		       &pctl->mcfg);
+		ddr_set_ddr3_mode(grf, channel, true);
+		ddr_set_enable(grf, channel, true);
+
+		ddr_set_en_bst_odt(grf, channel, false, true, false);
+		break;
+	}
+
+	setbits_le32(&pctl->scfg, 1);
+}
+
+static void phy_cfg(const struct chan_info *chan, u32 channel,
+		    const struct rk3288_sdram_params *sdram_params)
+{
+	struct rk3288_ddr_publ *publ = chan->publ;
+	struct rk3288_msch *msch = chan->msch;
+	uint ddr_freq_mhz = sdram_params->base.ddr_freq / 1000000;
+	u32 dinit2, tmp;
+	int i;
+
+	dinit2 = DIV_ROUND_UP(ddr_freq_mhz * 200000, 1000);
+	/* DDR PHY Timing */
+	copy_to_reg(&publ->dtpr[0], &sdram_params->phy_timing.dtpr0,
+		    sizeof(sdram_params->phy_timing));
+	writel(sdram_params->base.noc_timing, &msch->ddrtiming);
+	writel(0x3f, &msch->readlatency);
+	writel(sdram_params->base.noc_activate, &msch->activate);
+	writel(2 << BUSWRTORD_SHIFT | 2 << BUSRDTOWR_SHIFT |
+	       1 << BUSRDTORD_SHIFT, &msch->devtodev);
+	writel(DIV_ROUND_UP(ddr_freq_mhz * 5120, 1000) << PRT_DLLLOCK_SHIFT |
+	       DIV_ROUND_UP(ddr_freq_mhz * 50, 1000) << PRT_DLLSRST_SHIFT |
+	       8 << PRT_ITMSRST_SHIFT, &publ->ptr[0]);
+	writel(DIV_ROUND_UP(ddr_freq_mhz * 500000, 1000) << PRT_DINIT0_SHIFT |
+	       DIV_ROUND_UP(ddr_freq_mhz * 400, 1000) << PRT_DINIT1_SHIFT,
+	       &publ->ptr[1]);
+	writel(min(dinit2, 0x1ffffU) << PRT_DINIT2_SHIFT |
+	       DIV_ROUND_UP(ddr_freq_mhz * 1000, 1000) << PRT_DINIT3_SHIFT,
+	       &publ->ptr[2]);
+
+	switch (sdram_params->base.dramtype) {
+	case LPDDR3:
+		clrsetbits_le32(&publ->pgcr, 0x1F,
+				0 << PGCR_DFTLMT_SHIFT |
+				0 << PGCR_DFTCMP_SHIFT |
+				1 << PGCR_DQSCFG_SHIFT |
+				0 << PGCR_ITMDMD_SHIFT);
+		/* DDRMODE select LPDDR3 */
+		clrsetbits_le32(&publ->dcr, DDRMD_MASK << DDRMD_SHIFT,
+				DDRMD_LPDDR2_LPDDR3 << DDRMD_SHIFT);
+		clrsetbits_le32(&publ->dxccr,
+				DQSNRES_MASK << DQSNRES_SHIFT |
+				DQSRES_MASK << DQSRES_SHIFT,
+				4 << DQSRES_SHIFT | 0xc << DQSNRES_SHIFT);
+		tmp = readl(&publ->dtpr[1]);
+		tmp = ((tmp >> TDQSCKMAX_SHIFT) & TDQSCKMAX_MASK) -
+			((tmp >> TDQSCK_SHIFT) & TDQSCK_MASK);
+		clrsetbits_le32(&publ->dsgcr,
+				DQSGE_MASK << DQSGE_SHIFT |
+				DQSGX_MASK << DQSGX_SHIFT,
+				tmp << DQSGE_SHIFT | tmp << DQSGX_SHIFT);
+		break;
+	case DDR3:
+		clrbits_le32(&publ->pgcr, 0x1f);
+		clrsetbits_le32(&publ->dcr, DDRMD_MASK << DDRMD_SHIFT,
+				DDRMD_DDR3 << DDRMD_SHIFT);
+		break;
+	}
+	if (sdram_params->base.odt) {
+		/*dynamic RTT enable */
+		for (i = 0; i < 4; i++)
+			setbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT);
+	} else {
+		/*dynamic RTT disable */
+		for (i = 0; i < 4; i++)
+			clrbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT);
+	}
+}
+
+static void phy_init(struct rk3288_ddr_publ *publ)
+{
+	setbits_le32(&publ->pir, PIR_INIT | PIR_DLLSRST
+		| PIR_DLLLOCK | PIR_ZCAL | PIR_ITMSRST | PIR_CLRSR);
+	udelay(1);
+	while ((readl(&publ->pgsr) &
+		(PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE)) !=
+		(PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE))
+		;
+}
+
+static void send_command(struct rk3288_ddr_pctl *pctl, u32 rank,
+			 u32 cmd, u32 arg)
+{
+	writel((START_CMD | (rank << 20) | arg | cmd), &pctl->mcmd);
+	udelay(1);
+	while (readl(&pctl->mcmd) & START_CMD)
+		;
+}
+
+static inline void send_command_op(struct rk3288_ddr_pctl *pctl,
+				   u32 rank, u32 cmd, u32 ma, u32 op)
+{
+	send_command(pctl, rank, cmd, (ma & LPDDR2_MA_MASK) << LPDDR2_MA_SHIFT |
+		     (op & LPDDR2_OP_MASK) << LPDDR2_OP_SHIFT);
+}
+
+static void memory_init(struct rk3288_ddr_publ *publ,
+			u32 dramtype)
+{
+	setbits_le32(&publ->pir,
+		     (PIR_INIT | PIR_DRAMINIT | PIR_LOCKBYP
+		      | PIR_ZCALBYP | PIR_CLRSR | PIR_ICPC
+		      | (dramtype == DDR3 ? PIR_DRAMRST : 0)));
+	udelay(1);
+	while ((readl(&publ->pgsr) & (PGSR_IDONE | PGSR_DLDONE))
+		!= (PGSR_IDONE | PGSR_DLDONE))
+		;
+}
+
+static void move_to_config_state(struct rk3288_ddr_publ *publ,
+				 struct rk3288_ddr_pctl *pctl)
+{
+	unsigned int state;
+
+	while (1) {
+		state = readl(&pctl->stat) & PCTL_STAT_MSK;
+
+		switch (state) {
+		case LOW_POWER:
+			writel(WAKEUP_STATE, &pctl->sctl);
+			while ((readl(&pctl->stat) & PCTL_STAT_MSK)
+				!= ACCESS)
+				;
+			/* wait DLL lock */
+			while ((readl(&publ->pgsr) & PGSR_DLDONE)
+				!= PGSR_DLDONE)
+				;
+			/* if at low power state,need wakeup first,
+			 * and then enter the config
+			 * so here no break.
+			 */
+		case ACCESS:
+			/* no break */
+		case INIT_MEM:
+			writel(CFG_STATE, &pctl->sctl);
+			while ((readl(&pctl->stat) & PCTL_STAT_MSK) != CONFIG)
+				;
+			break;
+		case CONFIG:
+			return;
+		default:
+			break;
+		}
+	}
+}
+
+static void set_bandwidth_ratio(const struct chan_info *chan, u32 channel,
+				u32 n, struct rk3288_grf *grf)
+{
+	struct rk3288_ddr_pctl *pctl = chan->pctl;
+	struct rk3288_ddr_publ *publ = chan->publ;
+	struct rk3288_msch *msch = chan->msch;
+
+	if (n == 1) {
+		setbits_le32(&pctl->ppcfg, 1);
+		writel(RK_SETBITS(1 << (8 + channel)), &grf->soc_con0);
+		setbits_le32(&msch->ddrtiming, 1 << 31);
+		/* Data Byte disable*/
+		clrbits_le32(&publ->datx8[2].dxgcr, 1);
+		clrbits_le32(&publ->datx8[3].dxgcr, 1);
+		/*disable DLL */
+		setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS);
+		setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS);
+	} else {
+		clrbits_le32(&pctl->ppcfg, 1);
+		writel(RK_CLRBITS(1 << (8 + channel)), &grf->soc_con0);
+		clrbits_le32(&msch->ddrtiming, 1 << 31);
+		/* Data Byte enable*/
+		setbits_le32(&publ->datx8[2].dxgcr, 1);
+		setbits_le32(&publ->datx8[3].dxgcr, 1);
+
+		/*enable DLL */
+		clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS);
+		clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS);
+		/* reset DLL */
+		clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST);
+		clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST);
+		udelay(10);
+		setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST);
+		setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST);
+	}
+	setbits_le32(&pctl->dfistcfg0, 1 << 2);
+}
+
+static int data_training(const struct chan_info *chan, u32 channel,
+			 const struct rk3288_sdram_params *sdram_params)
+{
+	unsigned int j;
+	int ret = 0;
+	u32 rank;
+	int i;
+	u32 step[2] = { PIR_QSTRN, PIR_RVTRN };
+	struct rk3288_ddr_publ *publ = chan->publ;
+	struct rk3288_ddr_pctl *pctl = chan->pctl;
+
+	/* disable auto refresh */
+	writel(0, &pctl->trefi);
+
+	if (sdram_params->base.dramtype != LPDDR3)
+		setbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT);
+	rank = sdram_params->ch[channel].rank | 1;
+	for (j = 0; j < ARRAY_SIZE(step); j++) {
+		/*
+		 * trigger QSTRN and RVTRN
+		 * clear DTDONE status
+		 */
+		setbits_le32(&publ->pir, PIR_CLRSR);
+
+		/* trigger DTT */
+		setbits_le32(&publ->pir,
+			     PIR_INIT | step[j] | PIR_LOCKBYP | PIR_ZCALBYP |
+			     PIR_CLRSR);
+		udelay(1);
+		/* wait echo byte DTDONE */
+		while ((readl(&publ->datx8[0].dxgsr[0]) & rank)
+			!= rank)
+			;
+		while ((readl(&publ->datx8[1].dxgsr[0]) & rank)
+			!= rank)
+			;
+		if (!(readl(&pctl->ppcfg) & 1)) {
+			while ((readl(&publ->datx8[2].dxgsr[0])
+				& rank) != rank)
+				;
+			while ((readl(&publ->datx8[3].dxgsr[0])
+				& rank) != rank)
+				;
+		}
+		if (readl(&publ->pgsr) &
+		    (PGSR_DTERR | PGSR_RVERR | PGSR_RVEIRR)) {
+			ret = -1;
+			break;
+		}
+	}
+	/* send some auto refresh to complement the lost while DTT */
+	for (i = 0; i < (rank > 1 ? 8 : 4); i++)
+		send_command(pctl, rank, REF_CMD, 0);
+
+	if (sdram_params->base.dramtype != LPDDR3)
+		clrbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT);
+
+	/* resume auto refresh */
+	writel(sdram_params->pctl_timing.trefi, &pctl->trefi);
+
+	return ret;
+}
+
+static void move_to_access_state(const struct chan_info *chan)
+{
+	struct rk3288_ddr_publ *publ = chan->publ;
+	struct rk3288_ddr_pctl *pctl = chan->pctl;
+	unsigned int state;
+
+	while (1) {
+		state = readl(&pctl->stat) & PCTL_STAT_MSK;
+
+		switch (state) {
+		case LOW_POWER:
+			if (((readl(&pctl->stat) >> LP_TRIG_SHIFT) &
+					LP_TRIG_MASK) == 1)
+				return;
+
+			writel(WAKEUP_STATE, &pctl->sctl);
+			while ((readl(&pctl->stat) & PCTL_STAT_MSK) != ACCESS)
+				;
+			/* wait DLL lock */
+			while ((readl(&publ->pgsr) & PGSR_DLDONE)
+				!= PGSR_DLDONE)
+				;
+			break;
+		case INIT_MEM:
+			writel(CFG_STATE, &pctl->sctl);
+			while ((readl(&pctl->stat) & PCTL_STAT_MSK) != CONFIG)
+				;
+		case CONFIG:
+			writel(GO_STATE, &pctl->sctl);
+			while ((readl(&pctl->stat) & PCTL_STAT_MSK) == CONFIG)
+				;
+			break;
+		case ACCESS:
+			return;
+		default:
+			break;
+		}
+	}
+}
+
+static void dram_cfg_rbc(const struct chan_info *chan, u32 chnum,
+			 const struct rk3288_sdram_params *sdram_params)
+{
+	struct rk3288_ddr_publ *publ = chan->publ;
+
+	if (sdram_params->ch[chnum].bk == 3)
+		clrsetbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT,
+				1 << PDQ_SHIFT);
+	else
+		clrbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT);
+
+	writel(sdram_params->base.ddrconfig, &chan->msch->ddrconf);
+}
+
+static void dram_all_config(const struct dram_info *dram,
+			    const struct rk3288_sdram_params *sdram_params)
+{
+	unsigned int chan;
+	u32 sys_reg = 0;
+
+	sys_reg |= sdram_params->base.dramtype << SYS_REG_DDRTYPE_SHIFT;
+	sys_reg |= (sdram_params->num_channels - 1) << SYS_REG_NUM_CH_SHIFT;
+	for (chan = 0; chan < sdram_params->num_channels; chan++) {
+		const struct rk3288_sdram_channel *info =
+			&sdram_params->ch[chan];
+
+		sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(chan);
+		sys_reg |= chan << SYS_REG_CHINFO_SHIFT(chan);
+		sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(chan);
+		sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(chan);
+		sys_reg |= info->bk == 3 ? 1 << SYS_REG_BK_SHIFT(chan) : 0;
+		sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(chan);
+		sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(chan);
+		sys_reg |= info->bw << SYS_REG_BW_SHIFT(chan);
+		sys_reg |= info->dbw << SYS_REG_DBW_SHIFT(chan);
+
+		dram_cfg_rbc(&dram->chan[chan], chan, sdram_params);
+	}
+	writel(sys_reg, &dram->pmu->sys_reg[2]);
+	writel(RK_CLRSETBITS(0x1F, sdram_params->base.stride),
+	       &dram->sgrf->soc_con2);
+}
+
+static int sdram_init(const struct dram_info *dram,
+		      const struct rk3288_sdram_params *sdram_params)
+{
+	int channel;
+	int zqcr;
+	int ret;
+
+	debug("%s start\n", __func__);
+	if ((sdram_params->base.dramtype == DDR3 &&
+	     sdram_params->base.ddr_freq > 800000000) ||
+	    (sdram_params->base.dramtype == LPDDR3 &&
+	     sdram_params->base.ddr_freq > 533000000)) {
+		debug("SDRAM frequency is too high!");
+		return -E2BIG;
+	}
+
+	debug("ddr clk %s\n", dram->ddr_clk->name);
+	ret = clk_set_rate(dram->ddr_clk, sdram_params->base.ddr_freq);
+	debug("ret=%d\n", ret);
+	if (ret) {
+		debug("Could not set DDR clock\n");
+		return ret;
+	}
+
+	for (channel = 0; channel < 2; channel++) {
+		const struct chan_info *chan = &dram->chan[channel];
+		struct rk3288_ddr_pctl *pctl = chan->pctl;
+		struct rk3288_ddr_publ *publ = chan->publ;
+
+		phy_pctrl_reset(dram->cru, publ, channel);
+		phy_dll_bypass_set(publ, sdram_params->base.ddr_freq);
+
+		if (channel >= sdram_params->num_channels)
+			continue;
+
+		dfi_cfg(pctl, sdram_params->base.dramtype);
+
+		pctl_cfg(channel, pctl, sdram_params, dram->grf);
+
+		phy_cfg(chan, channel, sdram_params);
+
+		phy_init(publ);
+
+		writel(POWER_UP_START, &pctl->powctl);
+		while (!(readl(&pctl->powstat) & POWER_UP_DONE))
+			;
+
+		memory_init(publ, sdram_params->base.dramtype);
+		move_to_config_state(publ, pctl);
+
+		if (sdram_params->base.dramtype == LPDDR3) {
+			send_command(pctl, 3, DESELECT_CMD, 0);
+			udelay(1);
+			send_command(pctl, 3, PREA_CMD, 0);
+			udelay(1);
+			send_command_op(pctl, 3, MRS_CMD, 63, 0xfc);
+			udelay(1);
+			send_command_op(pctl, 3, MRS_CMD, 1,
+					sdram_params->phy_timing.mr[1]);
+			udelay(1);
+			send_command_op(pctl, 3, MRS_CMD, 2,
+					sdram_params->phy_timing.mr[2]);
+			udelay(1);
+			send_command_op(pctl, 3, MRS_CMD, 3,
+					sdram_params->phy_timing.mr[3]);
+			udelay(1);
+		}
+
+		set_bandwidth_ratio(chan, channel,
+				    sdram_params->ch[channel].bw, dram->grf);
+		/*
+		 * set cs
+		 * CS0, n=1
+		 * CS1, n=2
+		 * CS0 & CS1, n = 3
+		 */
+		clrsetbits_le32(&publ->pgcr, 0xF << 18,
+				(sdram_params->ch[channel].rank | 1) << 18);
+		/* DS=40ohm,ODT=155ohm */
+		zqcr = 1 << ZDEN_SHIFT | 2 << PU_ONDIE_SHIFT |
+			2 << PD_ONDIE_SHIFT | 0x19 << PU_OUTPUT_SHIFT |
+			0x19 << PD_OUTPUT_SHIFT;
+		writel(zqcr, &publ->zq1cr[0]);
+		writel(zqcr, &publ->zq0cr[0]);
+
+		if (sdram_params->base.dramtype == LPDDR3) {
+			/* LPDDR2/LPDDR3 need to wait DAI complete, max 10us */
+			udelay(10);
+			send_command_op(pctl,
+					sdram_params->ch[channel].rank | 1,
+					MRS_CMD, 11,
+					sdram_params->base.odt ? 3 : 0);
+			if (channel == 0) {
+				writel(0, &pctl->mrrcfg0);
+				send_command_op(pctl, 1, MRR_CMD, 8, 0);
+				/* S8 */
+				if ((readl(&pctl->mrrstat0) & 0x3) != 3) {
+					debug("failed!");
+					return -EREMOTEIO;
+				}
+			}
+		}
+
+		if (-1 == data_training(chan, channel, sdram_params)) {
+			if (sdram_params->base.dramtype == LPDDR3) {
+				ddr_phy_ctl_reset(dram->cru, channel, 1);
+				udelay(10);
+				ddr_phy_ctl_reset(dram->cru, channel, 0);
+				udelay(10);
+			}
+			debug("failed!");
+			return -EIO;
+		}
+
+		if (sdram_params->base.dramtype == LPDDR3) {
+			u32 i;
+			writel(0, &pctl->mrrcfg0);
+			for (i = 0; i < 17; i++)
+				send_command_op(pctl, 1, MRR_CMD, i, 0);
+		}
+		move_to_access_state(chan);
+	}
+	dram_all_config(dram, sdram_params);
+	debug("%s done\n", __func__);
+
+	return 0;
+}
+#endif
+
+size_t sdram_size_mb(struct rk3288_pmu *pmu)
+{
+	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(&pmu->sys_reg[2]);
+	u32 chans;
+
+	chans = 1 + ((sys_reg >> SYS_REG_NUM_CH_SHIFT) & SYS_REG_NUM_CH_MASK);
+
+	for (ch = 0; ch < chans; 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 = sys_reg & (1 << SYS_REG_BK_SHIFT(ch)) ? 3 : 0;
+		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 = (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~0xfeffffff space since 0xff000000~0xffffffff
+	* is SoC register space (i.e. reserved)
+	*/
+	size_mb = min(size_mb, 0xff000000 >> 20);
+
+	return size_mb;
+}
+
+#ifdef CONFIG_SPL_BUILD
+static int setup_sdram(struct udevice *dev)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+	struct rk3288_sdram_params params;
+	const void *blob = gd->fdt_blob;
+	int node = dev->of_offset;
+	int i, ret;
+
+	params.num_channels = fdtdec_get_int(blob, node,
+					     "rockchip,num-channels", 1);
+	for (i = 0; i < params.num_channels; i++) {
+		ret = fdtdec_get_byte_array(blob, node,
+					    "rockchip,sdram-channel",
+					    (u8 *)&params.ch[i],
+					    sizeof(params.ch[i]));
+		if (ret) {
+			debug("%s: Cannot read rockchip,sdram-channel\n",
+			      __func__);
+			return -EINVAL;
+		}
+	}
+	ret = fdtdec_get_int_array(blob, node, "rockchip,pctl-timing",
+				   (u32 *)&params.pctl_timing,
+				   sizeof(params.pctl_timing) / sizeof(u32));
+	if (ret) {
+		debug("%s: Cannot read rockchip,pctl-timing\n", __func__);
+		return -EINVAL;
+	}
+	ret = fdtdec_get_int_array(blob, node, "rockchip,phy-timing",
+				   (u32 *)&params.phy_timing,
+				   sizeof(params.phy_timing) / sizeof(u32));
+	if (ret) {
+		debug("%s: Cannot read rockchip,phy-timing\n", __func__);
+		return -EINVAL;
+	}
+	ret = fdtdec_get_int_array(blob, node, "rockchip,sdram-params",
+				   (u32 *)&params.base,
+				   sizeof(params.base) / sizeof(u32));
+	if (ret) {
+		debug("%s: Cannot read rockchip,sdram-params\n", __func__);
+		return -EINVAL;
+	}
+
+	return sdram_init(priv, &params);
+}
+#endif
+
+static int rk3288_dmc_probe(struct udevice *dev)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+	struct regmap *map;
+	int ret;
+
+	map = syscon_get_regmap_by_driver_data(ROCKCHIP_SYSCON_NOC);
+	if (IS_ERR(map))
+		return PTR_ERR(map);
+	priv->chan[0].msch = regmap_get_range(map, 0);
+	priv->chan[1].msch = (struct rk3288_msch *)
+			(regmap_get_range(map, 0) + 0x80);
+
+	map = syscon_get_regmap_by_driver_data(ROCKCHIP_SYSCON_GRF);
+	if (IS_ERR(map))
+		return PTR_ERR(map);
+	priv->grf = regmap_get_range(map, 0);
+
+	map = syscon_get_regmap_by_driver_data(ROCKCHIP_SYSCON_SGRF);
+	if (IS_ERR(map))
+		return PTR_ERR(map);
+	priv->sgrf = regmap_get_range(map, 0);
+
+	map = syscon_get_regmap_by_driver_data(ROCKCHIP_SYSCON_PMU);
+	if (IS_ERR(map))
+		return PTR_ERR(map);
+	priv->pmu = regmap_get_range(map, 0);
+
+	ret = regmap_init_mem(dev, &map);
+	if (ret)
+		return ret;
+	priv->chan[0].pctl = regmap_get_range(map, 0);
+	priv->chan[0].publ = regmap_get_range(map, 1);
+	priv->chan[1].pctl = regmap_get_range(map, 2);
+	priv->chan[1].publ = regmap_get_range(map, 3);
+
+	ret = uclass_get_device(UCLASS_CLK, CLK_DDR, &priv->ddr_clk);
+	if (ret)
+		return ret;
+
+	priv->cru = rockchip_get_cru();
+	if (IS_ERR(priv->cru))
+		return PTR_ERR(priv->cru);
+#ifdef CONFIG_SPL_BUILD
+	ret = setup_sdram(dev);
+	if (ret)
+		return ret;
+#endif
+	priv->info.base = 0;
+	priv->info.size = sdram_size_mb(priv->pmu) << 20;
+
+	return 0;
+}
+
+static int rk3288_dmc_get_info(struct udevice *dev, struct ram_info *info)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+
+	*info = priv->info;
+
+	return 0;
+}
+
+static struct ram_ops rk3288_dmc_ops = {
+	.get_info = rk3288_dmc_get_info,
+};
+
+static const struct udevice_id rk3288_dmc_ids[] = {
+	{ .compatible = "rockchip,rk3288-dmc" },
+	{ }
+};
+
+U_BOOT_DRIVER(dmc_rk3288) = {
+	.name = "rk3288_dmc",
+	.id = UCLASS_RAM,
+	.of_match = rk3288_dmc_ids,
+	.ops = &rk3288_dmc_ops,
+	.probe = rk3288_dmc_probe,
+	.priv_auto_alloc_size = sizeof(struct dram_info),
+};
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 26/41] rockchip: Add an MMC driver
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (24 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 25/41] rockchip: rk3288: Add SDRAM init Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 17:59   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 27/41] rockchip: Add core SoC start-up code Simon Glass
                   ` (14 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

Add an MMC driver which supports RK3288, but may also support other SoCs.
It uses the Designware MMC device.

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

Changes in v5:
- Adjust Kconfig help to indicate the MMC device may support newer spec versions
- Fix priv_auto_alloc_size to use correct struct (rockchip_dwmmc_priv)
- Rename driver and Kconfig to indicate it uses designware
- Rename driver functions, etc. from rockchip_mmc to rockchip_dwmmc

Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/mmc/Kconfig           |  9 ++++
 drivers/mmc/Makefile          |  1 +
 drivers/mmc/rockchip_dw_mmc.c | 98 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 108 insertions(+)
 create mode 100644 drivers/mmc/rockchip_dw_mmc.c

diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 3e835f7..6277f92 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -10,6 +10,15 @@ config DM_MMC
 	  appear as block devices in U-Boot and can support filesystems such
 	  as EXT4 and FAT.
 
+config ROCKCHIP_DWMMC
+	bool "Rockchip SD/MMC controller support"
+	depends on DM_MMC && OF_CONTROL
+	help
+	  This enables support for the Rockchip SD/MMM controller, which is
+	  based on Designware IP. The device is compatible with at least
+	  SD 3.0, SDIO 3.0 and MMC 4.5 and supports common eMMC chips as well
+	  as removeable SD and micro-SD cards.
+
 config SH_SDHI
 	bool "SuperH/Renesas ARM SoCs on-chip SDHI host controller support"
 	depends on RMOBILE
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index cae207c..99d0295 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_MXS_MMC) += mxsmmc.o
 obj-$(CONFIG_OMAP_HSMMC) += omap_hsmmc.o
 obj-$(CONFIG_X86) += pci_mmc.o
 obj-$(CONFIG_PXA_MMC_GENERIC) += pxa_mmc_gen.o
+obj-$(CONFIG_ROCKCHIP_DWMMC) += rockchip_dw_mmc.o
 obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o
 obj-$(CONFIG_S3C_SDI) += s3c_sdi.o
 obj-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o
diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c
new file mode 100644
index 0000000..f11c8e0
--- /dev/null
+++ b/drivers/mmc/rockchip_dw_mmc.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2013 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dwmmc.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/periph.h>
+#include <linux/err.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct rockchip_dwmmc_priv {
+	struct udevice *clk;
+	struct rk3288_grf *grf;
+	struct dwmci_host host;
+};
+
+static uint rockchip_dwmmc_get_mmc_clk(struct dwmci_host *host, uint freq)
+{
+	struct udevice *dev = host->priv;
+	struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = clk_set_periph_rate(priv->clk, PERIPH_ID_SDMMC0 + host->dev_index,
+				  freq);
+	if (ret < 0) {
+		debug("%s: err=%d\n", __func__, ret);
+		return ret;
+	}
+
+	return freq;
+}
+
+static int rockchip_dwmmc_ofdata_to_platdata(struct udevice *dev)
+{
+	struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
+	struct dwmci_host *host = &priv->host;
+
+	host->name = dev->name;
+	host->ioaddr = (void *)dev_get_addr(dev);
+	host->buswidth = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+					"bus-width", 4);
+	host->get_mmc_clk = rockchip_dwmmc_get_mmc_clk;
+	host->priv = dev;
+
+	/* TODO(sjg at chromium.org): Remove the need for this hack */
+	host->dev_index = (ulong)host->ioaddr == 0xff0f0000 ? 0 : 1;
+
+	return 0;
+}
+
+static int rockchip_dwmmc_probe(struct udevice *dev)
+{
+	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+	struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
+	struct dwmci_host *host = &priv->host;
+	u32 minmax[2];
+	int ret;
+
+	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+	if (IS_ERR(priv->grf))
+		return PTR_ERR(priv->grf);
+	ret = uclass_get_device(UCLASS_CLK, CLK_GENERAL, &priv->clk);
+	if (ret)
+		return ret;
+
+	ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset,
+				   "clock-freq-min-max", minmax, 2);
+	if (!ret)
+		ret = add_dwmci(host, minmax[1], minmax[0]);
+	if (ret)
+		return ret;
+
+	upriv->mmc = host->mmc;
+
+	return 0;
+}
+
+static const struct udevice_id rockchip_dwmmc_ids[] = {
+	{ .compatible = "rockchip,rk3288-dw-mshc" },
+	{ }
+};
+
+U_BOOT_DRIVER(rockchip_dwmmc_drv) = {
+	.name		= "rockchip_dwmmc",
+	.id		= UCLASS_MMC,
+	.of_match	= rockchip_dwmmc_ids,
+	.ofdata_to_platdata = rockchip_dwmmc_ofdata_to_platdata,
+	.probe		= rockchip_dwmmc_probe,
+	.priv_auto_alloc_size = sizeof(struct rockchip_dwmmc_priv),
+};
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 27/41] rockchip: Add core SoC start-up code
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (25 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 26/41] rockchip: Add an MMC driver Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 18:00   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 28/41] rockchip: Add I2C driver Simon Glass
                   ` (13 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

Add code for starting up U-Boot SPL and U-Boot proper. This is generic and
makes use of devices provided by the board- or SoC-specific code.

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

Changes in v5:
- Drop BSS memset() as it is not needed
- Use CONFIG_SPL_LED instead of CONFIG_SPL_LED_SUPPORT

Changes in v4:
- Rename pinctrl.h to dm/pinctrl.h

Changes in v3: None
Changes in v2: None

 arch/arm/Kconfig                      |  10 ++
 arch/arm/Makefile                     |   1 +
 arch/arm/mach-rockchip/Kconfig        |  41 +++++
 arch/arm/mach-rockchip/Makefile       |  13 ++
 arch/arm/mach-rockchip/board-spl.c    | 287 ++++++++++++++++++++++++++++++++++
 arch/arm/mach-rockchip/board.c        |  46 ++++++
 arch/arm/mach-rockchip/common.c       |  28 ++++
 arch/arm/mach-rockchip/rk3288/Kconfig |   6 +
 8 files changed, 432 insertions(+)
 create mode 100644 arch/arm/mach-rockchip/Kconfig
 create mode 100644 arch/arm/mach-rockchip/Makefile
 create mode 100644 arch/arm/mach-rockchip/board-spl.c
 create mode 100644 arch/arm/mach-rockchip/board.c
 create mode 100644 arch/arm/mach-rockchip/common.c
 create mode 100644 arch/arm/mach-rockchip/rk3288/Kconfig

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a99ae28..1f2eccd 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -827,6 +827,14 @@ config TARGET_STM32F429_DISCOVERY
 	bool "Support STM32F429 Discovery"
 	select CPU_V7M
 
+config ARCH_ROCKCHIP
+	bool "Support Rockchip SoCs"
+	select SUPPORT_SPL
+	select SPL
+	select OF_CONTROL
+	select CPU_V7
+	select DM
+
 endchoice
 
 source "arch/arm/mach-at91/Kconfig"
@@ -861,6 +869,8 @@ source "arch/arm/mach-orion5x/Kconfig"
 
 source "arch/arm/cpu/armv7/rmobile/Kconfig"
 
+source "arch/arm/mach-rockchip/Kconfig"
+
 source "arch/arm/cpu/armv7/s5pc1xx/Kconfig"
 
 source "arch/arm/mach-socfpga/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index e84d6d3..1eca815 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -55,6 +55,7 @@ machine-$(CONFIG_ARCH_NOMADIK)		+= nomadik
 # TODO: rename CONFIG_ORION5X -> CONFIG_ARCH_ORION5X
 machine-$(CONFIG_ORION5X)		+= orion5x
 machine-$(CONFIG_ARCH_SOCFPGA)		+= socfpga
+machine-$(CONFIG_ARCH_ROCKCHIP)		+= rockchip
 machine-$(CONFIG_TEGRA)			+= tegra
 machine-$(CONFIG_ARCH_UNIPHIER)		+= uniphier
 machine-$(CONFIG_ARCH_VERSATILE)	+= versatile
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
new file mode 100644
index 0000000..ab50f4e
--- /dev/null
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -0,0 +1,41 @@
+if ARCH_ROCKCHIP
+
+config ROCKCHIP_RK3288
+	bool "Support Rockchip RK3288"
+	help
+	  The Rockchip RK3288 is a ARM-based SoC with a quad-core Cortex-A17
+	  including NEON and GPU, 1MB L2 cache, Mali-T7 graphics, two
+	  video interfaces supporting HDMI and eDP, several DDR3 options
+	  and video codec support. Peripherals include Gigabit Ethernet,
+	  USB2 host and OTG, SDIO, I2S, UART,s, SPI, I2C and PWMs.
+
+config SYS_MALLOC_F
+	default y
+
+config SYS_MALLOC_F_LEN
+	default 0x800
+
+config SPL_DM
+	default y
+
+config DM_SERIAL
+	default y
+
+config DM_SPI
+	default y
+
+config DM_SPI_FLASH
+	default y
+
+config DM_I2C
+	default y
+
+config DM_GPIO
+	default y
+
+config ROCKCHIP_SERIAL
+	default y
+
+source "arch/arm/mach-rockchip/rk3288/Kconfig"
+
+endif
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
new file mode 100644
index 0000000..5a4e383
--- /dev/null
+++ b/arch/arm/mach-rockchip/Makefile
@@ -0,0 +1,13 @@
+#
+# Copyright (c) 2014 Google, Inc
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+ifdef CONFIG_SPL_BUILD
+obj-y += board-spl.o
+else
+obj-y += board.o
+endif
+obj-y += common.o
+obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288/
diff --git a/arch/arm/mach-rockchip/board-spl.c b/arch/arm/mach-rockchip/board-spl.c
new file mode 100644
index 0000000..a241d96
--- /dev/null
+++ b/arch/arm/mach-rockchip/board-spl.c
@@ -0,0 +1,287 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * 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 <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)
+{
+	const void *blob = gd->fdt_blob;
+	struct udevice *dev;
+	const char *bootdev;
+	int node;
+	int ret;
+
+	bootdev = fdtdec_get_config_string(blob, "u-boot,boot0");
+	debug("Boot device %s\n", bootdev);
+	if (!bootdev)
+		goto fallback;
+
+	node = fdt_path_offset(blob, bootdev);
+	if (node < 0) {
+		debug("node=%d\n", node);
+		goto fallback;
+	}
+	ret = device_get_global_by_of_offset(node, &dev);
+	if (ret) {
+		debug("device@node %s/%d not found: %d\n", bootdev, node,
+		      ret);
+		goto fallback;
+	}
+	debug("Found device %s\n", dev->name);
+	switch (device_get_uclass_id(dev)) {
+	case UCLASS_SPI_FLASH:
+		return BOOT_DEVICE_SPI;
+	case UCLASS_MMC:
+		return BOOT_DEVICE_MMC1;
+	default:
+		debug("Booting from device uclass '%s' not supported\n",
+		      dev_get_uclass_name(dev));
+	}
+
+fallback:
+	return BOOT_DEVICE_MMC1;
+}
+
+u32 spl_boot_mode(void)
+{
+	return MMCSD_MODE_RAW;
+}
+
+/* read L2 control register (L2CTLR) */
+static inline uint32_t read_l2ctlr(void)
+{
+	uint32_t val = 0;
+
+	asm volatile ("mrc p15, 1, %0, c9, c0, 2" : "=r" (val));
+
+	return val;
+}
+
+/* write L2 control register (L2CTLR) */
+static inline void write_l2ctlr(uint32_t val)
+{
+	/*
+	 * Note: L2CTLR can only be written when the L2 memory system
+	 * is idle, ie before the MMU is enabled.
+	 */
+	asm volatile("mcr p15, 1, %0, c9, c0, 2" : : "r" (val) : "memory");
+	isb();
+}
+
+static void configure_l2ctlr(void)
+{
+	uint32_t l2ctlr;
+
+	l2ctlr = read_l2ctlr();
+	l2ctlr &= 0xfffc0000; /* clear bit0~bit17 */
+
+	/*
+	* Data RAM write latency: 2 cycles
+	* Data RAM read latency: 2 cycles
+	* Data RAM setup latency: 1 cycle
+	* Tag RAM write latency: 1 cycle
+	* Tag RAM read latency: 1 cycle
+	* Tag RAM setup latency: 1 cycle
+	*/
+	l2ctlr |= (1 << 3 | 1 << 0);
+	write_l2ctlr(l2ctlr);
+}
+
+struct rk3288_timer {
+	u32 timer_load_count0;
+	u32 timer_load_count1;
+	u32 timer_curr_value0;
+	u32 timer_curr_value1;
+	u32 timer_ctrl_reg;
+	u32 timer_int_status;
+};
+
+void init_timer(void)
+{
+	struct rk3288_timer * const timer7_ptr = (void *)TIMER7_BASE;
+
+	writel(0xffffffff, &timer7_ptr->timer_load_count0);
+	writel(0xffffffff, &timer7_ptr->timer_load_count1);
+	writel(1, &timer7_ptr->timer_ctrl_reg);
+}
+
+static int configure_emmc(struct udevice *pinctrl)
+{
+	struct gpio_desc desc;
+	int ret;
+
+	pinctrl_request_noflags(pinctrl, PERIPH_ID_EMMC);
+
+	/*
+	 * TODO(sjg at chromium.org): Pick this up from device tree or perhaps
+	 * use the EMMC_PWREN setting.
+	 */
+	ret = dm_gpio_lookup_name("D9", &desc);
+	if (ret) {
+		debug("gpio ret=%d\n", ret);
+		return ret;
+	}
+	ret = dm_gpio_request(&desc, "emmc_pwren");
+	if (ret) {
+		debug("gpio_request ret=%d\n", ret);
+		return ret;
+	}
+	ret = dm_gpio_set_dir_flags(&desc, GPIOD_IS_OUT);
+	if (ret) {
+		debug("gpio dir ret=%d\n", ret);
+		return ret;
+	}
+	ret = dm_gpio_set_value(&desc, 1);
+	if (ret) {
+		debug("gpio value ret=%d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+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 */
+#ifdef EARLY_UART
+#include <asm/arch/grf_rk3288.h>
+	/* Enable early UART on the RK3288 */
+#define GRF_BASE	0xff770000
+	struct rk3288_grf * const grf = (void *)GRF_BASE;
+
+	rk_clrsetreg(&grf->gpio7ch_iomux, GPIO7C7_MASK << GPIO7C7_SHIFT |
+		     GPIO7C6_MASK << GPIO7C6_SHIFT,
+		     GPIO7C7_UART2DBG_SOUT << GPIO7C7_SHIFT |
+		     GPIO7C6_UART2DBG_SIN << GPIO7C6_SHIFT);
+	/*
+	 * Debug UART can be used from here if required:
+	 *
+	 * debug_uart_init();
+	 * printch('a');
+	 * printhex8(0x1234);
+	 * printascii("string");
+	 */
+	debug_uart_init();
+#endif
+
+	ret = spl_init();
+	if (ret) {
+		debug("spl_init() failed: %d\n", ret);
+		hang();
+	}
+
+	init_timer();
+	configure_l2ctlr();
+
+	ret = uclass_get_device(UCLASS_CLK, 0, &dev);
+	if (ret) {
+		debug("CLK init failed: %d\n", ret);
+		return;
+	}
+
+	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;
+	}
+}
+
+static int setup_led(void)
+{
+#ifdef CONFIG_SPL_LED
+	struct udevice *dev;
+	char *led_name;
+	int ret;
+
+	led_name = fdtdec_get_config_string(gd->fdt_blob, "u-boot,boot-led");
+	if (!led_name)
+		return 0;
+	ret = led_get_by_label(led_name, &dev);
+	if (ret) {
+		debug("%s: get=%d\n", __func__, ret);
+		return ret;
+	}
+	ret = led_set_on(dev, 1);
+	if (ret)
+		return ret;
+#endif
+
+	return 0;
+}
+
+void spl_board_init(void)
+{
+	struct udevice *pinctrl;
+	int ret;
+
+	ret = setup_led();
+
+	if (ret) {
+		debug("LED ret=%d\n", ret);
+		hang();
+	}
+
+	ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
+	if (ret) {
+		debug("%s: Cannot find pinctrl device\n", __func__);
+		goto err;
+	}
+	ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD);
+	if (ret) {
+		debug("%s: Failed to set up SD card\n", __func__);
+		goto err;
+	}
+	ret = configure_emmc(pinctrl);
+	if (ret) {
+		debug("%s: Failed to set up eMMC\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();
+	return;
+err:
+	printf("spl_board_init: Error %d\n", ret);
+
+	/* No way to report error here */
+	hang();
+}
diff --git a/arch/arm/mach-rockchip/board.c b/arch/arm/mach-rockchip/board.c
new file mode 100644
index 0000000..688bc0f
--- /dev/null
+++ b/arch/arm/mach-rockchip/board.c
@@ -0,0 +1,46 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <ram.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+	return 0;
+}
+
+int dram_init(void)
+{
+	struct ram_info ram;
+	struct udevice *dev;
+	int ret;
+
+	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+	if (ret) {
+		debug("DRAM init failed: %d\n", ret);
+		return ret;
+	}
+	ret = ram_get_info(dev, &ram);
+	if (ret) {
+		debug("Cannot get DRAM size: %d\n", ret);
+		return ret;
+	}
+	debug("SDRAM base=%lx, size=%x\n", ram.base, ram.size);
+	gd->ram_size = ram.size;
+
+	return 0;
+}
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+void enable_caches(void)
+{
+	/* Enable D-cache. I-cache is already enabled in start.S */
+	dcache_enable();
+}
+#endif
diff --git a/arch/arm/mach-rockchip/common.c b/arch/arm/mach-rockchip/common.c
new file mode 100644
index 0000000..fc7ac72
--- /dev/null
+++ b/arch/arm/mach-rockchip/common.c
@@ -0,0 +1,28 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <linux/err.h>
+
+void *rockchip_get_cru(void)
+{
+	struct udevice *dev;
+	fdt_addr_t addr;
+	int ret;
+
+	ret = uclass_get_device(UCLASS_CLK, 0, &dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	addr = dev_get_addr(dev);
+	if (addr == FDT_ADDR_T_NONE)
+		return ERR_PTR(-EINVAL);
+
+	return (void *)addr;
+}
diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig
new file mode 100644
index 0000000..26d5951
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3288/Kconfig
@@ -0,0 +1,6 @@
+if ROCKCHIP_RK3288
+
+config SYS_SOC
+	default "rockchip"
+
+endif
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 28/41] rockchip: Add I2C driver
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (26 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 27/41] rockchip: Add core SoC start-up code Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 18:00   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 29/41] rockchip: Add SPI driver Simon Glass
                   ` (12 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

Add an I2C driver for the Rockchip RK3288, using driver model. It should work
for other Rockchip SoCs also.

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

Changes in v5: None
Changes in v4:
- Rename pinctrl.h to dm/pinctrl.h

Changes in v3: None
Changes in v2: None

 arch/arm/include/asm/arch-rockchip/i2c.h |  70 ++++++
 drivers/i2c/Kconfig                      |   9 +
 drivers/i2c/Makefile                     |   1 +
 drivers/i2c/rk_i2c.c                     | 391 +++++++++++++++++++++++++++++++
 4 files changed, 471 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-rockchip/i2c.h
 create mode 100644 drivers/i2c/rk_i2c.c

diff --git a/arch/arm/include/asm/arch-rockchip/i2c.h b/arch/arm/include/asm/arch-rockchip/i2c.h
new file mode 100644
index 0000000..d81f8ff
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/i2c.h
@@ -0,0 +1,70 @@
+/*
+ * (C) Copyright 2012 SAMSUNG Electronics
+ * Jaehoon Chung <jh80.chung@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __ASM_ARCH_I2C_H
+#define __ASM_ARCH_I2C_H
+
+struct i2c_regs {
+	u32 con;
+	u32 clkdiv;
+	u32 mrxaddr;
+	u32 mrxraddr;
+	u32 mtxcnt;
+	u32 mrxcnt;
+	u32 ien;
+	u32 ipd;
+	u32 fcnt;
+	u32 reserved0[0x37];
+	u32 txdata[8];
+	u32 reserved1[0x38];
+	u32 rxdata[8];
+};
+
+/* Control register */
+#define I2C_CON_EN		(1 << 0)
+#define I2C_CON_MOD(mod)	((mod) << 1)
+#define I2C_MODE_TX		0x00
+#define I2C_MODE_TRX		0x01
+#define I2C_MODE_RX		0x02
+#define I2C_MODE_RRX		0x03
+#define I2C_CON_MASK		(3 << 1)
+
+#define I2C_CON_START		(1 << 3)
+#define I2C_CON_STOP		(1 << 4)
+#define I2C_CON_LASTACK		(1 << 5)
+#define I2C_CON_ACTACK		(1 << 6)
+
+/* Clock dividor register */
+#define I2C_CLKDIV_VAL(divl, divh) \
+	(((divl) & 0xffff) | (((divh) << 16) & 0xffff0000))
+
+/* the slave address accessed  for master rx mode */
+#define I2C_MRXADDR_SET(vld, addr)	(((vld) << 24) | (addr))
+
+/* the slave register address accessed  for master rx mode */
+#define I2C_MRXRADDR_SET(vld, raddr)	(((vld) << 24) | (raddr))
+
+/* interrupt enable register */
+#define I2C_BTFIEN		(1 << 0)
+#define I2C_BRFIEN		(1 << 1)
+#define I2C_MBTFIEN		(1 << 2)
+#define I2C_MBRFIEN		(1 << 3)
+#define I2C_STARTIEN		(1 << 4)
+#define I2C_STOPIEN		(1 << 5)
+#define I2C_NAKRCVIEN		(1 << 6)
+
+/* interrupt pending register */
+#define I2C_BTFIPD              (1 << 0)
+#define I2C_BRFIPD              (1 << 1)
+#define I2C_MBTFIPD             (1 << 2)
+#define I2C_MBRFIPD             (1 << 3)
+#define I2C_STARTIPD            (1 << 4)
+#define I2C_STOPIPD             (1 << 5)
+#define I2C_NAKRCVIPD           (1 << 6)
+#define I2C_IPD_ALL_CLEAN       0x7f
+
+#endif
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index c40bd5c..14adda2 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -58,6 +58,15 @@ config DM_I2C_GPIO
 	  bindings are supported.
 	  Binding info: doc/device-tree-bindings/i2c/i2c-gpio.txt
 
+config SYS_I2C_ROCKCHIP
+	bool "Rockchip I2C driver"
+	depends on DM_I2C
+	help
+	  Add support for the Rockchip I2C driver. This is used with various
+	  Rockchip parts such as RK3126, RK3128, RK3036 and RK3288. All chips
+	  have several I2C ports and all are provided, controled by the
+	  device tree.
+
 config SYS_I2C_SANDBOX
 	bool "Sandbox I2C driver"
 	depends on SANDBOX && DM_I2C
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 9b45248..8ce294b 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_SYS_I2C_OMAP24XX) += omap24xx_i2c.o
 obj-$(CONFIG_SYS_I2C_OMAP34XX) += omap24xx_i2c.o
 obj-$(CONFIG_SYS_I2C_PPC4XX) += ppc4xx_i2c.o
 obj-$(CONFIG_SYS_I2C_RCAR) += rcar_i2c.o
+obj-$(CONFIG_SYS_I2C_ROCKCHIP) += rk_i2c.o
 obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o
 obj-$(CONFIG_SYS_I2C_SANDBOX) += sandbox_i2c.o i2c-emul-uclass.o
 obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o
diff --git a/drivers/i2c/rk_i2c.c b/drivers/i2c/rk_i2c.c
new file mode 100644
index 0000000..ebdba35
--- /dev/null
+++ b/drivers/i2c/rk_i2c.c
@@ -0,0 +1,391 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * (C) Copyright 2008-2014 Rockchip Electronics
+ * Peter, Software Engineering, <superpeter.cai@gmail.com>.
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <errno.h>
+#include <i2c.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/i2c.h>
+#include <asm/arch/periph.h>
+#include <dm/pinctrl.h>
+#include <linux/sizes.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* i2c timerout */
+#define I2C_TIMEOUT_MS		100
+#define I2C_RETRY_COUNT		3
+
+/* rk i2c fifo max transfer bytes */
+#define RK_I2C_FIFO_SIZE	32
+
+struct rk_i2c {
+	struct udevice *clk;
+	struct udevice *pinctrl;
+	struct i2c_regs *regs;
+	unsigned int speed;
+	enum periph_id id;
+};
+
+static inline void rk_i2c_get_div(int div, int *divh, int *divl)
+{
+	*divl = div / 2;
+	if (div % 2 == 0)
+		*divh = div / 2;
+	else
+		*divh = DIV_ROUND_UP(div, 2);
+}
+
+/*
+ * SCL Divisor = 8 * (CLKDIVL+1 + CLKDIVH+1)
+ * SCL = PCLK / SCLK Divisor
+ * i2c_rate = PCLK
+ */
+static void rk_i2c_set_clk(struct rk_i2c *i2c, uint32_t scl_rate)
+{
+	uint32_t i2c_rate;
+	int div, divl, divh;
+
+	/* First get i2c rate from pclk */
+	i2c_rate = clk_get_periph_rate(i2c->clk, i2c->id);
+
+	div = DIV_ROUND_UP(i2c_rate, scl_rate * 8) - 2;
+	divh = 0;
+	divl = 0;
+	if (div >= 0)
+		rk_i2c_get_div(div, &divh, &divl);
+	writel(I2C_CLKDIV_VAL(divl, divh), &i2c->regs->clkdiv);
+
+	debug("rk_i2c_set_clk: i2c rate = %d, scl rate = %d\n", i2c_rate,
+	      scl_rate);
+	debug("set i2c clk div = %d, divh = %d, divl = %d\n", div, divh, divl);
+	debug("set clk(I2C_CLKDIV: 0x%08x)\n", readl(&i2c->regs->clkdiv));
+}
+
+static void rk_i2c_show_regs(struct i2c_regs *regs)
+{
+#ifdef DEBUG
+	uint i;
+
+	debug("i2c_con: 0x%08x\n", readl(&regs->con));
+	debug("i2c_clkdiv: 0x%08x\n", readl(&regs->clkdiv));
+	debug("i2c_mrxaddr: 0x%08x\n", readl(&regs->mrxaddr));
+	debug("i2c_mrxraddR: 0x%08x\n", readl(&regs->mrxraddr));
+	debug("i2c_mtxcnt: 0x%08x\n", readl(&regs->mtxcnt));
+	debug("i2c_mrxcnt: 0x%08x\n", readl(&regs->mrxcnt));
+	debug("i2c_ien: 0x%08x\n", readl(&regs->ien));
+	debug("i2c_ipd: 0x%08x\n", readl(&regs->ipd));
+	debug("i2c_fcnt: 0x%08x\n", readl(&regs->fcnt));
+	for (i = 0; i < 8; i++)
+		debug("i2c_txdata%d: 0x%08x\n", i, readl(&regs->txdata[i]));
+	for (i = 0; i < 8; i++)
+		debug("i2c_rxdata%d: 0x%08x\n", i, readl(&regs->rxdata[i]));
+#endif
+}
+
+static int rk_i2c_send_start_bit(struct rk_i2c *i2c)
+{
+	struct i2c_regs *regs = i2c->regs;
+	ulong start;
+
+	debug("I2c Send Start bit.\n");
+	writel(I2C_IPD_ALL_CLEAN, &regs->ipd);
+
+	writel(I2C_CON_EN | I2C_CON_START, &regs->con);
+	writel(I2C_STARTIEN, &regs->ien);
+
+	start = get_timer(0);
+	while (1) {
+		if (readl(&regs->ipd) & I2C_STARTIPD) {
+			writel(I2C_STARTIPD, &regs->ipd);
+			break;
+		}
+		if (get_timer(start) > I2C_TIMEOUT_MS) {
+			debug("I2C Send Start Bit Timeout\n");
+			rk_i2c_show_regs(regs);
+			return -ETIMEDOUT;
+		}
+		udelay(1);
+	}
+
+	return 0;
+}
+
+static int rk_i2c_send_stop_bit(struct rk_i2c *i2c)
+{
+	struct i2c_regs *regs = i2c->regs;
+	ulong start;
+
+	debug("I2c Send Stop bit.\n");
+	writel(I2C_IPD_ALL_CLEAN, &regs->ipd);
+
+	writel(I2C_CON_EN | I2C_CON_STOP, &regs->con);
+	writel(I2C_CON_STOP, &regs->ien);
+
+	start = get_timer(0);
+	while (1) {
+		if (readl(&regs->ipd) & I2C_STOPIPD) {
+			writel(I2C_STOPIPD, &regs->ipd);
+			break;
+		}
+		if (get_timer(start) > I2C_TIMEOUT_MS) {
+			debug("I2C Send Start Bit Timeout\n");
+			rk_i2c_show_regs(regs);
+			return -ETIMEDOUT;
+		}
+		udelay(1);
+	}
+
+	return 0;
+}
+
+static inline void rk_i2c_disable(struct rk_i2c *i2c)
+{
+	writel(0, &i2c->regs->con);
+}
+
+static int rk_i2c_read(struct rk_i2c *i2c, uchar chip, uint reg, uint r_len,
+		       uchar *buf, uint b_len)
+{
+	struct i2c_regs *regs = i2c->regs;
+	uchar *pbuf = buf;
+	uint bytes_remain_len = b_len;
+	uint bytes_xferred = 0;
+	uint words_xferred = 0;
+	ulong start;
+	uint con = 0;
+	uint rxdata;
+	uint i, j;
+	int err;
+
+	debug("rk_i2c_read: chip = %d, reg = %d, r_len = %d, b_len = %d\n",
+	      chip, reg, r_len, b_len);
+
+	err = rk_i2c_send_start_bit(i2c);
+	if (err)
+		return err;
+
+	writel(I2C_MRXADDR_SET(1, chip << 1 | 1), &regs->mrxaddr);
+	if (r_len == 0) {
+		writel(0, &regs->mrxraddr);
+	} else if (r_len < 4) {
+		writel(I2C_MRXRADDR_SET(r_len, reg), &regs->mrxraddr);
+	} else {
+		debug("I2C Read: addr len %d not supported\n", r_len);
+		return -EIO;
+	}
+
+	while (bytes_remain_len) {
+		if (bytes_remain_len > RK_I2C_FIFO_SIZE) {
+			con = I2C_CON_EN | I2C_CON_MOD(I2C_MODE_TRX);
+			bytes_xferred = 32;
+		} else {
+			con = I2C_CON_EN | I2C_CON_MOD(I2C_MODE_TRX) |
+				I2C_CON_LASTACK;
+			bytes_xferred = bytes_remain_len;
+		}
+		words_xferred = DIV_ROUND_UP(bytes_xferred, 4);
+
+		writel(con, &regs->con);
+		writel(bytes_xferred, &regs->mrxcnt);
+		writel(I2C_MBRFIEN | I2C_NAKRCVIEN, &regs->ien);
+
+		start = get_timer(0);
+		while (1) {
+			if (readl(&regs->ipd) & I2C_NAKRCVIPD) {
+				writel(I2C_NAKRCVIPD, &regs->ipd);
+				err = -EREMOTEIO;
+			}
+			if (readl(&regs->ipd) & I2C_MBRFIPD) {
+				writel(I2C_MBRFIPD, &regs->ipd);
+				break;
+			}
+			if (get_timer(start) > I2C_TIMEOUT_MS) {
+				debug("I2C Read Data Timeout\n");
+				err =  -ETIMEDOUT;
+				rk_i2c_show_regs(regs);
+				goto i2c_exit;
+			}
+			udelay(1);
+		}
+
+		for (i = 0; i < words_xferred; i++) {
+			rxdata = readl(&regs->rxdata[i]);
+			debug("I2c Read RXDATA[%d] = 0x%x\n", i, rxdata);
+			for (j = 0; j < 4; j++) {
+				if ((i * 4 + j) == bytes_xferred)
+					break;
+				*pbuf++ = (rxdata >> (j * 8)) & 0xff;
+			}
+		}
+
+		bytes_remain_len -= bytes_xferred;
+		debug("I2C Read bytes_remain_len %d\n", bytes_remain_len);
+	}
+
+i2c_exit:
+	rk_i2c_send_stop_bit(i2c);
+	rk_i2c_disable(i2c);
+
+	return err;
+}
+
+static int rk_i2c_write(struct rk_i2c *i2c, uchar chip, uint reg, uint r_len,
+			uchar *buf, uint b_len)
+{
+	struct i2c_regs *regs = i2c->regs;
+	int err;
+	uchar *pbuf = buf;
+	uint bytes_remain_len = b_len + r_len + 1;
+	uint bytes_xferred = 0;
+	uint words_xferred = 0;
+	ulong start;
+	uint txdata;
+	uint i, j;
+
+	debug("rk_i2c_write: chip = %d, reg = %d, r_len = %d, b_len = %d\n",
+	      chip, reg, r_len, b_len);
+	err = rk_i2c_send_start_bit(i2c);
+	if (err)
+		return err;
+
+	while (bytes_remain_len) {
+		if (bytes_remain_len > RK_I2C_FIFO_SIZE)
+			bytes_xferred = 32;
+		else
+			bytes_xferred = bytes_remain_len;
+		words_xferred = DIV_ROUND_UP(bytes_xferred, 4);
+
+		for (i = 0; i < words_xferred; i++) {
+			txdata = 0;
+			for (j = 0; j < 4; j++) {
+				if ((i * 4 + j) == bytes_xferred)
+					break;
+
+				if (i == 0 && j == 0) {
+					txdata |= (chip << 1);
+				} else if (i == 0 && j <= r_len) {
+					txdata |= (reg &
+						(0xff << ((j - 1) * 8))) << 8;
+				} else {
+					txdata |= (*pbuf++)<<(j * 8);
+				}
+				writel(txdata, &regs->txdata[i]);
+			}
+			debug("I2c Write TXDATA[%d] = 0x%x\n", i, txdata);
+		}
+
+		writel(I2C_CON_EN | I2C_CON_MOD(I2C_MODE_TX), &regs->con);
+		writel(bytes_xferred, &regs->mtxcnt);
+		writel(I2C_MBTFIEN | I2C_NAKRCVIEN, &regs->ien);
+
+		start = get_timer(0);
+		while (1) {
+			if (readl(&regs->ipd) & I2C_NAKRCVIPD) {
+				writel(I2C_NAKRCVIPD, &regs->ipd);
+				err = -EREMOTEIO;
+			}
+			if (readl(&regs->ipd) & I2C_MBTFIPD) {
+				writel(I2C_MBTFIPD, &regs->ipd);
+				break;
+			}
+			if (get_timer(start) > I2C_TIMEOUT_MS) {
+				debug("I2C Write Data Timeout\n");
+				err =  -ETIMEDOUT;
+				rk_i2c_show_regs(regs);
+				goto i2c_exit;
+			}
+			udelay(1);
+		}
+
+		bytes_remain_len -= bytes_xferred;
+		debug("I2C Write bytes_remain_len %d\n", bytes_remain_len);
+	}
+
+i2c_exit:
+	rk_i2c_send_stop_bit(i2c);
+	rk_i2c_disable(i2c);
+
+	return err;
+}
+
+static int rockchip_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
+			     int nmsgs)
+{
+	struct rk_i2c *i2c = dev_get_priv(bus);
+	int ret;
+
+	debug("i2c_xfer: %d messages\n", nmsgs);
+	for (; nmsgs > 0; nmsgs--, msg++) {
+		debug("i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len);
+		if (msg->flags & I2C_M_RD) {
+			ret = rk_i2c_read(i2c, msg->addr, 0, 0, msg->buf,
+					  msg->len);
+		} else {
+			ret = rk_i2c_write(i2c, msg->addr, 0, 0, msg->buf,
+					   msg->len);
+		}
+		if (ret) {
+			debug("i2c_write: error sending\n");
+			return -EREMOTEIO;
+		}
+	}
+
+	return 0;
+}
+
+int rockchip_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
+{
+	struct rk_i2c *i2c = dev_get_priv(bus);
+
+	rk_i2c_set_clk(i2c, speed);
+
+	return 0;
+}
+
+static int rockchip_i2c_probe(struct udevice *bus)
+{
+	struct rk_i2c *i2c = dev_get_priv(bus);
+	int ret;
+
+	ret = uclass_get_device(UCLASS_PINCTRL, 0, &i2c->pinctrl);
+	if (ret)
+		return ret;
+	ret = uclass_get_device(UCLASS_CLK, 0, &i2c->clk);
+	if (ret)
+		return ret;
+	ret = pinctrl_get_periph_id(i2c->pinctrl, bus);
+	if (ret < 0)
+		return ret;
+	i2c->id = ret;
+	i2c->regs = (void *)dev_get_addr(bus);
+	return pinctrl_request(i2c->pinctrl, i2c->id, 0);
+}
+
+static const struct dm_i2c_ops rockchip_i2c_ops = {
+	.xfer		= rockchip_i2c_xfer,
+	.set_bus_speed	= rockchip_i2c_set_bus_speed,
+};
+
+static const struct udevice_id rockchip_i2c_ids[] = {
+	{ .compatible = "rockchip,rk3288-i2c" },
+	{ }
+};
+
+U_BOOT_DRIVER(i2c_rockchip) = {
+	.name	= "i2c_rockchip",
+	.id	= UCLASS_I2C,
+	.of_match = rockchip_i2c_ids,
+	.probe	= rockchip_i2c_probe,
+	.priv_auto_alloc_size = sizeof(struct rk_i2c),
+	.ops	= &rockchip_i2c_ops,
+};
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 29/41] rockchip: Add SPI driver
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (27 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 28/41] rockchip: Add I2C driver Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-01  5:23   ` Jagan Teki
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 30/41] rockchip: Add basic support for firefly-rk3288 Simon Glass
                   ` (11 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

Add a SPI driver for the Rockchip RK3288, using driver model. It should work
for other Rockchip SoCs also.

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

Changes in v5:
- Drop unnecessary 'depends on DM_SPI' in Kconfig
- Tidy up rkspi_dump_regs() debug output
- Tidy up the delay in rkspi_wait_till_not_busy()

Changes in v4:
- Rename pinctrl.h to dm/pinctrl.h

Changes in v3: None
Changes in v2: None

 drivers/spi/Kconfig  |   8 ++
 drivers/spi/Makefile |   1 +
 drivers/spi/rk_spi.c | 372 +++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/spi/rk_spi.h | 121 +++++++++++++++++
 4 files changed, 502 insertions(+)
 create mode 100644 drivers/spi/rk_spi.c
 create mode 100644 drivers/spi/rk_spi.h

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index c84a7b7..8e04fce 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -58,6 +58,14 @@ config ICH_SPI
 	  access the SPI NOR flash on platforms embedding this Intel
 	  ICH IP core.
 
+config ROCKCHIP_SPI
+	bool "Rockchip SPI driver"
+	help
+	  Enable the Rockchip SPI driver, used to access SPI NOR flash and
+	  other SPI peripherals (such as the Chrome OS EC) on Rockchip SoCs.
+	  This uses driver model and requires a device tree binding to
+	  operate.
+
 config SANDBOX_SPI
 	bool "Sandbox SPI driver"
 	depends on SANDBOX && DM
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index ee88aa1..de241be 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
 obj-$(CONFIG_MXC_SPI) += mxc_spi.o
 obj-$(CONFIG_MXS_SPI) += mxs_spi.o
 obj-$(CONFIG_OMAP3_SPI) += omap3_spi.o
+obj-$(CONFIG_ROCKCHIP_SPI) += rk_spi.o
 obj-$(CONFIG_SANDBOX_SPI) += sandbox_spi.o
 obj-$(CONFIG_SH_SPI) += sh_spi.o
 obj-$(CONFIG_SH_QSPI) += sh_qspi.o
diff --git a/drivers/spi/rk_spi.c b/drivers/spi/rk_spi.c
new file mode 100644
index 0000000..46b1a37
--- /dev/null
+++ b/drivers/spi/rk_spi.c
@@ -0,0 +1,372 @@
+/*
+ * spi driver for rockchip
+ *
+ * (C) Copyright 2015 Google, Inc
+ *
+ * (C) Copyright 2008-2013 Rockchip Electronics
+ * Peter, Software Engineering, <superpeter.cai@gmail.com>.
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <errno.h>
+#include <spi.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/periph.h>
+#include <dm/pinctrl.h>
+#include "rk_spi.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct rockchip_spi_platdata {
+	enum periph_id periph_id;
+	struct udevice *pinctrl;
+	s32 frequency;		/* Default clock frequency, -1 for none */
+	fdt_addr_t base;
+	uint deactivate_delay_us;	/* Delay to wait after deactivate */
+};
+
+struct rockchip_spi_priv {
+	struct rockchip_spi *regs;
+	struct udevice *clk_gpll;
+	unsigned int max_freq;
+	unsigned int mode;
+	enum periph_id periph_id;	/* Peripheral ID for this device */
+	ulong last_transaction_us;	/* Time of last transaction end */
+	u8 bits_per_word;		/* max 16 bits per word */
+	u8 n_bytes;
+	unsigned int speed_hz;
+	unsigned int tmode;
+	uint input_rate;
+};
+
+#define SPI_FIFO_DEPTH		32
+
+static void rkspi_dump_regs(struct rockchip_spi *regs)
+{
+	debug("ctrl0: \t\t0x%08x\n", readl(&regs->ctrlr0));
+	debug("ctrl1: \t\t0x%08x\n", readl(&regs->ctrlr1));
+	debug("ssienr: \t\t0x%08x\n", readl(&regs->enr));
+	debug("ser: \t\t0x%08x\n", readl(&regs->ser));
+	debug("baudr: \t\t0x%08x\n", readl(&regs->baudr));
+	debug("txftlr: \t\t0x%08x\n", readl(&regs->txftlr));
+	debug("rxftlr: \t\t0x%08x\n", readl(&regs->rxftlr));
+	debug("txflr: \t\t0x%08x\n", readl(&regs->txflr));
+	debug("rxflr: \t\t0x%08x\n", readl(&regs->rxflr));
+	debug("sr: \t\t0x%08x\n", readl(&regs->sr));
+	debug("imr: \t\t0x%08x\n", readl(&regs->imr));
+	debug("isr: \t\t0x%08x\n", readl(&regs->isr));
+	debug("dmacr: \t\t0x%08x\n", readl(&regs->dmacr));
+	debug("dmatdlr: \t0x%08x\n", readl(&regs->dmatdlr));
+	debug("dmardlr: \t0x%08x\n", readl(&regs->dmardlr));
+}
+
+static void rkspi_enable_chip(struct rockchip_spi *regs, bool enable)
+{
+	writel(enable ? 1 : 0, &regs->enr);
+}
+
+static void rkspi_set_clk(struct rockchip_spi_priv *priv, uint speed)
+{
+	uint clk_div;
+
+	clk_div = priv->input_rate / speed;
+	clk_div = (clk_div + 1) & 0xfffe;
+	debug("spi speed %u, div %u\n", speed, clk_div);
+
+	writel(clk_div, &priv->regs->baudr);
+}
+
+static int rkspi_wait_till_not_busy(struct rockchip_spi *regs)
+{
+	unsigned long start;
+
+	start = get_timer(0);
+	while (readl(&regs->sr) & SR_BUSY) {
+		if (get_timer(start) > 1000) {
+			debug("RK SPI: Status keeps busy for 1000us after a read/write!\n");
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static void spi_cs_activate(struct rockchip_spi *regs, uint cs)
+{
+	debug("activate cs%u\n", cs);
+	writel(1 << cs, &regs->ser);
+}
+
+static void spi_cs_deactivate(struct rockchip_spi *regs, uint cs)
+{
+	debug("deactivate cs%u\n", cs);
+	writel(0, &regs->ser);
+}
+
+static int rockchip_spi_ofdata_to_platdata(struct udevice *bus)
+{
+	struct rockchip_spi_platdata *plat = bus->platdata;
+	const void *blob = gd->fdt_blob;
+	int node = bus->of_offset;
+	int ret;
+
+	plat->base = dev_get_addr(bus);
+	ret = uclass_get_device(UCLASS_PINCTRL, 0, &plat->pinctrl);
+	if (ret)
+		return ret;
+	ret = pinctrl_get_periph_id(plat->pinctrl, bus);
+
+	if (ret < 0) {
+		debug("%s: Could not get peripheral ID for %s: %d\n", __func__,
+		      bus->name, ret);
+		return -FDT_ERR_NOTFOUND;
+	}
+	plat->periph_id = ret;
+
+	plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
+					50000000);
+	plat->deactivate_delay_us = fdtdec_get_int(blob, node,
+					"spi-deactivate-delay", 0);
+	debug("%s: base=%x, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n",
+	      __func__, plat->base, plat->periph_id, plat->frequency,
+	      plat->deactivate_delay_us);
+
+	return 0;
+}
+
+static int rockchip_spi_probe(struct udevice *bus)
+{
+	struct rockchip_spi_platdata *plat = dev_get_platdata(bus);
+	struct rockchip_spi_priv *priv = dev_get_priv(bus);
+	int ret;
+
+	debug("%s: probe\n", __func__);
+	priv->regs = (struct rockchip_spi *)plat->base;
+
+	priv->last_transaction_us = timer_get_us();
+	priv->max_freq = plat->frequency;
+	priv->periph_id = plat->periph_id;
+	ret = uclass_get_device(UCLASS_CLK, CLK_GENERAL, &priv->clk_gpll);
+	if (ret) {
+		debug("%s: Failed to find CLK_GENERAL: %d\n", __func__, ret);
+		return ret;
+	}
+
+	/*
+	 * Use 99 MHz as our clock since it divides nicely into 594 MHz which
+	 * is the assumed speed for CLK_GENERAL.
+	 */
+	ret = clk_set_periph_rate(priv->clk_gpll, plat->periph_id, 99000000);
+	if (ret < 0) {
+		debug("%s: Failed to set clock: %d\n", __func__, ret);
+		return ret;
+	}
+	priv->input_rate = ret;
+	debug("%s: rate = %u\n", __func__, priv->input_rate);
+	priv->bits_per_word = 8;
+	priv->tmode = TMOD_TR; /* Tx & Rx */
+
+	return 0;
+}
+
+static int rockchip_spi_claim_bus(struct udevice *dev)
+{
+	struct udevice *bus = dev->parent;
+	struct rockchip_spi_platdata *plat = dev_get_platdata(bus);
+	struct rockchip_spi_priv *priv = dev_get_priv(bus);
+	struct rockchip_spi *regs = priv->regs;
+	struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
+	u8 spi_dfs, spi_tf;
+	uint ctrlr0;
+	int ret;
+
+	/* Disable the SPI hardware */
+	rkspi_enable_chip(regs, 0);
+
+	switch (priv->bits_per_word) {
+	case 8:
+		priv->n_bytes = 1;
+		spi_dfs = DFS_8BIT;
+		spi_tf = HALF_WORD_OFF;
+		break;
+	case 16:
+		priv->n_bytes = 2;
+		spi_dfs = DFS_16BIT;
+		spi_tf = HALF_WORD_ON;
+		break;
+	default:
+		debug("%s: unsupported bits: %dbits\n", __func__,
+		      priv->bits_per_word);
+		return -EPROTONOSUPPORT;
+	}
+
+	rkspi_set_clk(priv, priv->speed_hz);
+
+	/* Operation Mode */
+	ctrlr0 = OMOD_MASTER << OMOD_SHIFT;
+
+	/* Data Frame Size */
+	ctrlr0 |= spi_dfs & DFS_MASK << DFS_SHIFT;
+
+	/* set SPI mode 0..3 */
+	if (priv->mode & SPI_CPOL)
+		ctrlr0 |= SCOL_HIGH << SCOL_SHIFT;
+	if (priv->mode & SPI_CPHA)
+		ctrlr0 |= SCPH_TOGSTA << SCPH_SHIFT;
+
+	/* Chip Select Mode */
+	ctrlr0 |= CSM_KEEP << CSM_SHIFT;
+
+	/* SSN to Sclk_out delay */
+	ctrlr0 |= SSN_DELAY_ONE << SSN_DELAY_SHIFT;
+
+	/* Serial Endian Mode */
+	ctrlr0 |= SEM_LITTLE << SEM_SHIFT;
+
+	/* First Bit Mode */
+	ctrlr0 |= FBM_MSB << FBM_SHIFT;
+
+	/* Byte and Halfword Transform */
+	ctrlr0 |= (spi_tf & HALF_WORD_MASK) << HALF_WORD_TX_SHIFT;
+
+	/* Rxd Sample Delay */
+	ctrlr0 |= 0 << RXDSD_SHIFT;
+
+	/* Frame Format */
+	ctrlr0 |= FRF_SPI << FRF_SHIFT;
+
+	/* Tx and Rx mode */
+	ctrlr0 |= (priv->tmode & TMOD_MASK) << TMOD_SHIFT;
+
+	writel(ctrlr0, &regs->ctrlr0);
+
+	ret = pinctrl_request(plat->pinctrl, priv->periph_id, slave_plat->cs);
+	if (ret) {
+		debug("%s: Cannot request pinctrl: %d\n", __func__, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int rockchip_spi_release_bus(struct udevice *dev)
+{
+	return 0;
+}
+
+static int rockchip_spi_xfer(struct udevice *dev, unsigned int bitlen,
+			   const void *dout, void *din, unsigned long flags)
+{
+	struct udevice *bus = dev->parent;
+	struct rockchip_spi_priv *priv = dev_get_priv(bus);
+	struct rockchip_spi *regs = priv->regs;
+	struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
+	int len = bitlen >> 3;
+	const u8 *out = dout;
+	u8 *in = din;
+	int toread, towrite;
+	int ret;
+
+	debug("%s: dout=%p, din=%p, len=%x, flags=%lx\n", __func__, dout, din,
+	      len, flags);
+	if (0)
+		rkspi_dump_regs(regs);
+
+	/* Assert CS before transfer */
+	if (flags & SPI_XFER_BEGIN)
+		spi_cs_activate(regs, slave_plat->cs);
+
+	while (len > 0) {
+		int todo = min(len, 0xffff);
+
+		rkspi_enable_chip(regs, true);
+		writel(todo - 1, &regs->ctrlr1);
+		rkspi_enable_chip(regs, true);
+
+		toread = todo;
+		towrite = todo;
+		while (toread || towrite) {
+			u32 status = readl(&regs->sr);
+
+			if (towrite && !(status & SR_TF_FULL)) {
+				writel(out ? *out++ : 0, regs->txdr);
+				towrite--;
+			}
+			if (toread && !(status & SR_RF_EMPT)) {
+				u32 byte = readl(regs->rxdr);
+
+				if (in)
+					*in++ = byte;
+				toread--;
+			}
+		}
+		ret = rkspi_wait_till_not_busy(regs);
+		if (ret)
+			break;
+		len -= todo;
+	}
+
+	/* Deassert CS after transfer */
+	if (flags & SPI_XFER_END)
+		spi_cs_deactivate(regs, slave_plat->cs);
+
+	rkspi_enable_chip(regs, false);
+
+	return ret;
+}
+
+static int rockchip_spi_set_speed(struct udevice *bus, uint speed)
+{
+	struct rockchip_spi_priv *priv = dev_get_priv(bus);
+
+	if (speed > 48000000)
+		return -EINVAL;
+	if (speed > priv->max_freq)
+		speed = priv->max_freq;
+	priv->speed_hz = speed;
+
+	return 0;
+}
+
+static int rockchip_spi_set_mode(struct udevice *bus, uint mode)
+{
+	struct rockchip_spi_priv *priv = dev_get_priv(bus);
+
+	priv->mode = mode;
+
+	return 0;
+}
+
+static const struct dm_spi_ops rockchip_spi_ops = {
+	.claim_bus	= rockchip_spi_claim_bus,
+	.release_bus	= rockchip_spi_release_bus,
+	.xfer		= rockchip_spi_xfer,
+	.set_speed	= rockchip_spi_set_speed,
+	.set_mode	= rockchip_spi_set_mode,
+	/*
+	 * cs_info is not needed, since we require all chip selects to be
+	 * in the device tree explicitly
+	 */
+};
+
+static const struct udevice_id rockchip_spi_ids[] = {
+	{ .compatible = "rockchip,rk3288-spi" },
+	{ }
+};
+
+U_BOOT_DRIVER(rockchip_spi) = {
+	.name	= "rockchip_spi",
+	.id	= UCLASS_SPI,
+	.of_match = rockchip_spi_ids,
+	.ops	= &rockchip_spi_ops,
+	.ofdata_to_platdata = rockchip_spi_ofdata_to_platdata,
+	.platdata_auto_alloc_size = sizeof(struct rockchip_spi_platdata),
+	.priv_auto_alloc_size = sizeof(struct rockchip_spi_priv),
+	.probe	= rockchip_spi_probe,
+};
diff --git a/drivers/spi/rk_spi.h b/drivers/spi/rk_spi.h
new file mode 100644
index 0000000..bfb1739
--- /dev/null
+++ b/drivers/spi/rk_spi.h
@@ -0,0 +1,121 @@
+/*
+ * SPI driver for rockchip
+ *
+ * (C) Copyright 2015 Google, Inc
+ *
+ * (C) Copyright 2008-2013 Rockchip Electronics
+ * Peter, Software Engineering, <superpeter.cai@gmail.com>.
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __RK_SPI_H
+#define __RK_SPI_H
+
+struct rockchip_spi {
+	u32 ctrlr0;
+	u32 ctrlr1;
+	u32 enr;
+	u32 ser;
+	u32 baudr;
+	u32 txftlr;
+	u32 rxftlr;
+	u32 txflr;
+	u32 rxflr;
+	u32 sr;
+	u32 ipr;
+	u32 imr;
+	u32 isr;
+	u32 risr;
+	u32 icr;
+	u32 dmacr;
+	u32 dmatdlr;
+	u32 dmardlr;		/* 0x44 */
+	u32 reserved[0xef];
+	u32 txdr[0x100];	/* 0x400 */
+	u32 rxdr[0x100];	/* 0x800 */
+};
+
+/* CTRLR0 */
+enum {
+	DFS_SHIFT	= 0,	/* Data Frame Size */
+	DFS_MASK	= 3,
+	DFS_4BIT	= 0,
+	DFS_8BIT,
+	DFS_16BIT,
+	DFS_RESV,
+
+	CFS_SHIFT	= 2,	/* Control Frame Size */
+	CFS_MASK	= 0xf,
+
+	SCPH_SHIFT	= 6,	/* Serial Clock Phase */
+	SCPH_MASK	= 1,
+	SCPH_TOGMID	= 0,	/* SCLK toggles in middle of first data bit */
+	SCPH_TOGSTA,		/* SCLK toggles at start of first data bit */
+
+	SCOL_SHIFT	= 7,	/* Serial Clock Polarity */
+	SCOL_MASK	= 1,
+	SCOL_LOW	= 0,	/* Inactive state of serial clock is low */
+	SCOL_HIGH,		/* Inactive state of serial clock is high */
+
+	CSM_SHIFT	= 8,	/* Chip Select Mode */
+	CSM_MASK	= 0x3,
+	CSM_KEEP	= 0,	/* ss_n stays low after each frame  */
+	CSM_HALF,		/* ss_n high for half sclk_out cycles */
+	CSM_ONE,		/* ss_n high for one sclk_out cycle */
+	CSM_RESV,
+
+	SSN_DELAY_SHIFT	= 10,	/* SSN to Sclk_out delay */
+	SSN_DELAY_MASK	= 1,
+	SSN_DELAY_HALF	= 0,	/* 1/2 sclk_out cycle */
+	SSN_DELAY_ONE	= 1,	/* 1 sclk_out cycle */
+
+	SEM_SHIFT	= 11,	/* Serial Endian Mode */
+	SEM_MASK	= 1,
+	SEM_LITTLE	= 0,	/* little endian */
+	SEM_BIG,		/* big endian */
+
+	FBM_SHIFT	= 12,	/* First Bit Mode */
+	FBM_MASK	= 1,
+	FBM_MSB		= 0,	/* first bit is MSB */
+	FBM_LSB,		/* first bit in LSB */
+
+	HALF_WORD_TX_SHIFT = 13,	/* Byte and Halfword Transform */
+	HALF_WORD_MASK	= 1,
+	HALF_WORD_ON	= 0,	/* apb 16bit write/read, spi 8bit write/read */
+	HALF_WORD_OFF,		/* apb 8bit write/read, spi 8bit write/read */
+
+	RXDSD_SHIFT	= 14,	/* Rxd Sample Delay, in cycles */
+	RXDSD_MASK	= 3,
+
+	FRF_SHIFT	= 16,	/* Frame Format */
+	FRF_MASK	= 3,
+	FRF_SPI		= 0,	/* Motorola SPI */
+	FRF_SSP,			/* Texas Instruments SSP*/
+	FRF_MICROWIRE,		/* National Semiconductors Microwire */
+	FRF_RESV,
+
+	TMOD_SHIFT	= 18,	/* Transfer Mode */
+	TMOD_MASK	= 3,
+	TMOD_TR		= 0,	/* xmit & recv */
+	TMOD_TO,		/* xmit only */
+	TMOD_RO,		/* recv only */
+	TMOD_RESV,
+
+	OMOD_SHIFT	= 20,	/* Operation Mode */
+	OMOD_MASK	= 1,
+	OMOD_MASTER	= 0,	/* Master Mode */
+	OMOD_SLAVE,		/* Slave Mode */
+};
+
+/* SR */
+enum {
+	SR_MASK		= 0x7f,
+	SR_BUSY		= 1 << 0,
+	SR_TF_FULL	= 1 << 1,
+	SR_TF_EMPT	= 1 << 2,
+	SR_RF_EMPT	= 1 << 3,
+	SR_RF_FULL	= 1 << 4,
+};
+
+#endif /* __RK_SPI_H */
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 30/41] rockchip: Add basic support for firefly-rk3288
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (28 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 29/41] rockchip: Add SPI driver Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 18:00   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 31/41] rockchip: Add basic support for jerry Simon Glass
                   ` (10 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

The Firefly RK3288 is a suitable target board for initial mainline Rockchip
support. It includes a good set of peripherals, a recent SoC and it is
readily available.

This adds only some basic files required to allow the baord to display a
serial message in SPL and hang.

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

Changes in v5:
- Drop CONFIG_ROCKCHIP_MMC from rk_common.h
- Drop CONFIG_SPL_LED_SUPPORT from header file and move to Kconfig
- Use CONFIG_ROCKCHIP_DWMMC instead of CONFIG_ROCKCHIP_MMC

Changes in v4:
- Adjust the defconfig file to suit mainline

Changes in v3:
- Make use of additional features since version 2

Changes in v2:
- Drop use of CONFIG_USE_PRIVATE_LIBGCC=y
- Tidy up license headers and remove SPL #ifdefs

 arch/arm/dts/Makefile                         |   2 +
 arch/arm/dts/rk3288-firefly.dts               |  75 +++++
 arch/arm/dts/rk3288-firefly.dtsi              | 457 ++++++++++++++++++++++++++
 arch/arm/mach-rockchip/rk3288/Kconfig         |  10 +
 board/firefly/firefly-rk3288/Kconfig          |  15 +
 board/firefly/firefly-rk3288/MAINTAINERS      |   6 +
 board/firefly/firefly-rk3288/Makefile         |   7 +
 board/firefly/firefly-rk3288/firefly-rk3288.c |   7 +
 configs/firefly-rk3288_defconfig              |  43 +++
 include/configs/firefly-rk3288.h              |  14 +
 include/configs/rk3288_common.h               |  97 ++++++
 11 files changed, 733 insertions(+)
 create mode 100644 arch/arm/dts/rk3288-firefly.dts
 create mode 100644 arch/arm/dts/rk3288-firefly.dtsi
 create mode 100644 board/firefly/firefly-rk3288/Kconfig
 create mode 100644 board/firefly/firefly-rk3288/MAINTAINERS
 create mode 100644 board/firefly/firefly-rk3288/Makefile
 create mode 100644 board/firefly/firefly-rk3288/firefly-rk3288.c
 create mode 100644 configs/firefly-rk3288_defconfig
 create mode 100644 include/configs/firefly-rk3288.h
 create mode 100644 include/configs/rk3288_common.h

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index d9a2f5f..698b195 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -15,6 +15,8 @@ dtb-$(CONFIG_EXYNOS5) += exynos5250-arndale.dtb \
 	exynos5420-peach-pit.dtb \
 	exynos5800-peach-pi.dtb \
 	exynos5422-odroidxu3.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += \
+	rk3288-firefly.dtb
 dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
 	tegra20-medcom-wide.dtb \
 	tegra20-paz00.dtb \
diff --git a/arch/arm/dts/rk3288-firefly.dts b/arch/arm/dts/rk3288-firefly.dts
new file mode 100644
index 0000000..aed8d3a
--- /dev/null
+++ b/arch/arm/dts/rk3288-firefly.dts
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2014, 2015 FUKAUMI Naoki <naobsd@gmail.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+ X11
+ */
+
+/dts-v1/;
+#include "rk3288-firefly.dtsi"
+
+/ {
+	model = "Firefly-RK3288";
+	compatible = "firefly,firefly-rk3288", "rockchip,rk3288";
+
+	chosen {
+		stdout-path = &uart2;
+	};
+
+	config {
+		u-boot,dm-pre-reloc;
+		u-boot,boot-led = "firefly:green:power";
+	};
+};
+
+&dmc {
+	rockchip,num-channels = <2>;
+	rockchip,pctl-timing = <0x29a 0xc8 0x1f8 0x42 0x4e 0x4 0xea 0xa
+		0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7
+		0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0
+		0x1 0x7 0x7 0x4 0xc 0x43 0x100 0x0
+		0x5 0x0>;
+	rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
+		0xa60 0x40 0x10 0x0>;
+	rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf>;
+	rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
+};
+
+&ir {
+	gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
+};
+
+&pinctrl {
+	u-boot,dm-pre-reloc;
+	act8846 {
+		pmic_vsel: pmic-vsel {
+			rockchip,pins = <7 14 RK_FUNC_GPIO &pcfg_output_low>;
+		};
+	};
+
+	ir {
+		ir_int: ir-int {
+			rockchip,pins = <7 0 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
+&pwm1 {
+	status = "okay";
+};
+
+&uart2 {
+	u-boot,dm-pre-reloc;
+	reg-shift = <2>;
+};
+
+&sdmmc {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio3 {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio8 {
+	u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/rk3288-firefly.dtsi b/arch/arm/dts/rk3288-firefly.dtsi
new file mode 100644
index 0000000..8a083f0
--- /dev/null
+++ b/arch/arm/dts/rk3288-firefly.dtsi
@@ -0,0 +1,457 @@
+/*
+ * Copyright (c) 2014, 2015 FUKAUMI Naoki <naobsd@gmail.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+ X11
+ */
+
+#include "rk3288.dtsi"
+
+/ {
+	memory {
+		reg = <0 0x80000000>;
+	};
+
+	ext_gmac: external-gmac-clock {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <125000000>;
+		clock-output-names = "ext_gmac";
+	};
+
+	ir: ir-receiver {
+		compatible = "gpio-ir-receiver";
+		pinctrl-names = "default";
+		pinctrl-0 = <&ir_int>;
+	};
+
+	keys: gpio-keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		button at 0 {
+			gpio-key,wakeup = <1>;
+			gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
+			label = "GPIO Power";
+			linux,code = <116>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pwr_key>;
+		};
+	};
+
+	leds {
+		u-boot,dm-pre-reloc;
+		compatible = "gpio-leds";
+
+		work {
+			u-boot,dm-pre-reloc;
+			gpios = <&gpio8 1 GPIO_ACTIVE_LOW>;
+			label = "firefly:blue:user";
+			linux,default-trigger = "rc-feedback";
+			pinctrl-names = "default";
+			pinctrl-0 = <&work_led>;
+		};
+
+		power {
+			u-boot,dm-pre-reloc;
+			gpios = <&gpio8 2 GPIO_ACTIVE_LOW>;
+			label = "firefly:green:power";
+			linux,default-trigger = "default-on";
+			pinctrl-names = "default";
+			pinctrl-0 = <&power_led>;
+		};
+	};
+
+	vcc_sys: vsys-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_sys";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	vcc_sd: sdmmc-regulator {
+		compatible = "regulator-fixed";
+		gpio = <&gpio7 11 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&sdmmc_pwr>;
+		regulator-name = "vcc_sd";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		startup-delay-us = <100000>;
+		vin-supply = <&vcc_io>;
+	};
+
+	vcc_flash: flash-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_flash";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vcc_io>;
+	};
+
+	vcc_5v: usb-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_5v";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		regulator-boot-on;
+		vin-supply = <&vcc_sys>;
+	};
+
+	vcc_host_5v: usb-host-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&host_vbus_drv>;
+		regulator-name = "vcc_host_5v";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		vin-supply = <&vcc_5v>;
+	};
+
+	vcc_otg_5v: usb-otg-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&otg_vbus_drv>;
+		regulator-name = "vcc_otg_5v";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		vin-supply = <&vcc_5v>;
+	};
+};
+
+&cpu0 {
+	cpu0-supply = <&vdd_cpu>;
+};
+
+&emmc {
+	broken-cd;
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	disable-wp;
+	non-removable;
+	num-slots = <1>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_pwr>, <&emmc_bus8>;
+	vmmc-supply = <&vcc_io>;
+	vqmmc-supply = <&vcc_flash>;
+	status = "okay";
+};
+
+&hdmi {
+	ddc-i2c-bus = <&i2c5>;
+	status = "okay";
+};
+
+&i2c0 {
+	clock-frequency = <400000>;
+	status = "okay";
+
+	vdd_cpu: syr827 at 40 {
+		compatible = "silergy,syr827";
+		fcs,suspend-voltage-selector = <1>;
+		reg = <0x40>;
+		regulator-name = "vdd_cpu";
+		regulator-min-microvolt = <850000>;
+		regulator-max-microvolt = <1350000>;
+		regulator-always-on;
+		regulator-boot-on;
+		vin-supply = <&vcc_sys>;
+	};
+
+	vdd_gpu: syr828 at 41 {
+		compatible = "silergy,syr828";
+		fcs,suspend-voltage-selector = <1>;
+		reg = <0x41>;
+		regulator-name = "vdd_gpu";
+		regulator-min-microvolt = <850000>;
+		regulator-max-microvolt = <1350000>;
+		regulator-always-on;
+		vin-supply = <&vcc_sys>;
+	};
+
+	hym8563: hym8563 at 51 {
+		compatible = "haoyu,hym8563";
+		reg = <0x51>;
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		clock-output-names = "xin32k";
+		interrupt-parent = <&gpio7>;
+		interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&rtc_int>;
+	};
+
+	act8846: act8846 at 5a {
+		compatible = "active-semi,act8846";
+		reg = <0x5a>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_vsel>, <&pwr_hold>;
+		system-power-controller;
+
+		regulators {
+			vcc_ddr: REG1 {
+				regulator-name = "vcc_ddr";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-always-on;
+			};
+
+			vcc_io: REG2 {
+				regulator-name = "vcc_io";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+
+			vdd_log: REG3 {
+				regulator-name = "vdd_log";
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-always-on;
+			};
+
+			vcc_20: REG4 {
+				regulator-name = "vcc_20";
+				regulator-min-microvolt = <2000000>;
+				regulator-max-microvolt = <2000000>;
+				regulator-always-on;
+			};
+
+			vccio_sd: REG5 {
+				regulator-name = "vccio_sd";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+
+			vdd10_lcd: REG6 {
+				regulator-name = "vdd10_lcd";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+			};
+
+			vcca_18: REG7 {
+				regulator-name = "vcca_18";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			vcca_33: REG8 {
+				regulator-name = "vcca_33";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			vcc_lan: REG9 {
+				regulator-name = "vcc_lan";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			vdd_10: REG10 {
+				regulator-name = "vdd_10";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+			};
+
+			vcc_18: REG11 {
+				regulator-name = "vcc_18";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+
+			vcc18_lcd: REG12 {
+				regulator-name = "vcc18_lcd";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+		};
+	};
+};
+
+&i2c1 {
+	status = "okay";
+};
+
+&i2c2 {
+	status = "okay";
+};
+
+&i2c4 {
+	status = "okay";
+};
+
+&i2c5 {
+	status = "okay";
+};
+
+&pinctrl {
+	pcfg_output_high: pcfg-output-high {
+		output-high;
+	};
+
+	pcfg_output_low: pcfg-output-low {
+		output-low;
+	};
+
+	act8846 {
+		pwr_hold: pwr-hold {
+			rockchip,pins = <0 1 RK_FUNC_GPIO &pcfg_output_high>;
+		};
+	};
+
+	gmac {
+		phy_int: phy-int {
+			rockchip,pins = <0 9 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		phy_pmeb: phy-pmeb {
+			rockchip,pins = <0 8 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		phy_rst: phy-rst {
+			rockchip,pins = <4 8 RK_FUNC_GPIO &pcfg_output_high>;
+		};
+	};
+
+	hym8563 {
+		rtc_int: rtc-int {
+			rockchip,pins = <7 4 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	keys {
+		pwr_key: pwr-key {
+			rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	leds {
+		power_led: power-led {
+			rockchip,pins = <8 2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		work_led: work-led {
+			rockchip,pins = <8 1 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	sdmmc {
+		sdmmc_pwr: sdmmc-pwr {
+			rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	usb_host {
+		host_vbus_drv: host-vbus-drv {
+			rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		usbhub_rst: usbhub-rst {
+			rockchip,pins = <8 3 RK_FUNC_GPIO &pcfg_output_high>;
+		};
+	};
+
+	usb_otg {
+		otg_vbus_drv: otg-vbus-drv {
+			rockchip,pins = <0 12 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&saradc {
+	vref-supply = <&vcc_18>;
+	status = "okay";
+};
+
+&sdio0 {
+	broken-cd;
+	bus-width = <4>;
+	disable-wp;
+	non-removable;
+	num-slots = <1>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdio0_bus4>, <&sdio0_cmd>, <&sdio0_clk>;
+	vmmc-supply = <&vcc_18>;
+	status = "okay";
+};
+
+&sdmmc {
+	bus-width = <4>;
+	cap-mmc-highspeed;
+	cap-sd-highspeed;
+	card-detect-delay = <200>;
+	disable-wp;
+	num-slots = <1>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>;
+	vmmc-supply = <&vcc_sd>;
+	status = "okay";
+};
+
+&spi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi0_clk>, <&spi0_cs0>, <&spi0_tx>, <&spi0_rx>, <&spi0_cs1>;
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_xfer>, <&uart0_cts>, <&uart0_rts>;
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&uart3 {
+	status = "okay";
+};
+
+&usb_host1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usbhub_rst>;
+	status = "okay";
+};
+
+&usb_otg {
+	status = "okay";
+};
+
+&vopb {
+	status = "okay";
+};
+
+&vopb_mmu {
+	status = "okay";
+};
+
+&vopl {
+	status = "okay";
+};
+
+&vopl_mmu {
+	status = "okay";
+};
+
+&wdt {
+	status = "okay";
+};
diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig
index 26d5951..7a77615 100644
--- a/arch/arm/mach-rockchip/rk3288/Kconfig
+++ b/arch/arm/mach-rockchip/rk3288/Kconfig
@@ -1,6 +1,16 @@
 if ROCKCHIP_RK3288
 
+config TARGET_FIREFLY_RK3288
+	bool "Firefly-RK3288"
+	help
+	  Firefly is a RK3288-based development board with 2 USB ports,
+	  HDMI, VGA, micro-SD card, audio, WiFi  and Gigabit Ethernet, It
+	  also includes on-board eMMC and 1GB of SDRAM. Expansion connectors
+	  provide access to display pins, I2C, SPI, UART and GPIOs.
+
 config SYS_SOC
 	default "rockchip"
 
+source "board/firefly/firefly-rk3288/Kconfig"
+
 endif
diff --git a/board/firefly/firefly-rk3288/Kconfig b/board/firefly/firefly-rk3288/Kconfig
new file mode 100644
index 0000000..1c2bca8
--- /dev/null
+++ b/board/firefly/firefly-rk3288/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_FIREFLY_RK3288
+
+config SYS_BOARD
+	default "firefly-rk3288"
+
+config SYS_VENDOR
+	default "firefly"
+
+config SYS_CONFIG_NAME
+	default "firefly-rk3288"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+	def_bool y
+
+endif
diff --git a/board/firefly/firefly-rk3288/MAINTAINERS b/board/firefly/firefly-rk3288/MAINTAINERS
new file mode 100644
index 0000000..42db0bd
--- /dev/null
+++ b/board/firefly/firefly-rk3288/MAINTAINERS
@@ -0,0 +1,6 @@
+FIREFLY
+M:	Simon Glass <sjg@chromium.org>
+S:	Maintained
+F:	board/firefly/firefly-rk3288
+F:	include/configs/firefly-rk3288.h
+F:	configs/firefly-rk3288_defconfig
diff --git a/board/firefly/firefly-rk3288/Makefile b/board/firefly/firefly-rk3288/Makefile
new file mode 100644
index 0000000..6716845
--- /dev/null
+++ b/board/firefly/firefly-rk3288/Makefile
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2015 Google, Inc
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y	+= firefly-rk3288.o
diff --git a/board/firefly/firefly-rk3288/firefly-rk3288.c b/board/firefly/firefly-rk3288/firefly-rk3288.c
new file mode 100644
index 0000000..5119e95
--- /dev/null
+++ b/board/firefly/firefly-rk3288/firefly-rk3288.c
@@ -0,0 +1,7 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig
new file mode 100644
index 0000000..2411957
--- /dev/null
+++ b/configs/firefly-rk3288_defconfig
@@ -0,0 +1,43 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_ROCKCHIP_RK3288=y
+CONFIG_TARGET_FIREFLY_RK3288=y
+CONFIG_DEFAULT_DEVICE_TREE="rk3288-firefly"
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_STACK_R_ADDR=0x80000
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_PMIC=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_RESET=y
+CONFIG_LED=y
+CONFIG_SPL_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_BASE=0xff690000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_PINCTRL=y
+CONFIG_SPL_PINCTRL=y
+# CONFIG_PINCTRL_FULL is not set
+# CONFIG_SPL_PINCTRL_FULL is not set
+CONFIG_ROCKCHIP_PINCTRL=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_ACT8846=y
+CONFIG_DM_REGULATOR=y
+CONFIG_REGULATOR_ACT8846=y
+CONFIG_RAM=y
+CONFIG_SPL_RAM=y
+CONFIG_DM_MMC=y
+CONFIG_ROCKCHIP_DWMMC=y
+CONFIG_USE_PRIVATE_LIBGCC=y
+CONFIG_CMD_DHRYSTONE=y
+CONFIG_ERRNO_STR=y
diff --git a/include/configs/firefly-rk3288.h b/include/configs/firefly-rk3288.h
new file mode 100644
index 0000000..a82adc8
--- /dev/null
+++ b/include/configs/firefly-rk3288.h
@@ -0,0 +1,14 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <configs/rk3288_common.h>
+
+#define CONFIG_SPL_MMC_SUPPORT
+
+#endif
diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h
new file mode 100644
index 0000000..ce7fa75
--- /dev/null
+++ b/include/configs/rk3288_common.h
@@ -0,0 +1,97 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __CONFIG_RK3288_COMMON_H
+#define __CONFIG_RK3288_COMMON_H
+
+#include <asm/arch/hardware.h>
+
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_NR_DRAM_BANKS		1
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_SIZE			0x2000
+#define CONFIG_SYS_GENERIC_BOARD
+#define CONFIG_SYS_MAXARGS		16
+#define CONFIG_BAUDRATE			115200
+#define CONFIG_SYS_MALLOC_LEN		(32 << 20)
+#define CONFIG_SYS_CBSIZE		1024
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#define CONFIG_SYS_THUMB_BUILD
+#define CONFIG_OF_LIBFDT
+#define CONFIG_DISPLAY_BOARDINFO
+
+#define CONFIG_SYS_TIMER_RATE		(24 * 1000 * 1000)
+#define CONFIG_SYS_TIMER_COUNTER	(TIMER7_BASE + 8)
+
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_MEM32
+#define CONFIG_SPL_BOARD_INIT
+
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SYS_MALLOC_SIMPLE
+#endif
+
+#define CONFIG_SYS_TEXT_BASE		0x00100000
+#define CONFIG_SYS_INIT_SP_ADDR		0x00100000
+#define CONFIG_SYS_LOAD_ADDR		0x00800800
+#define CONFIG_SPL_STACK		0xff718000
+#define CONFIG_SPL_TEXT_BASE		0xff704004
+
+/* MMC/SD IP block */
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_CMD_MMC
+#define CONFIG_SDHCI
+#define CONFIG_DWMMC
+#define CONFIG_BOUNCE_BUFFER
+
+#define CONFIG_DOS_PARTITION
+#define CONFIG_CMD_FAT
+#define CONFIG_FAT_WRITE
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_EXT4
+#define CONFIG_CMD_FS_GENERIC
+#define CONFIG_PARTITION_UUIDS
+#define CONFIG_CMD_PART
+
+/* RAW SD card / eMMC locations. */
+#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR	256
+#define CONFIG_SYS_SPI_U_BOOT_OFFS	(128 << 10)
+
+/* FAT sd card locations. */
+#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION	1
+#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME		"u-boot.img"
+
+#define CONFIG_SPL_PINCTRL_SUPPORT
+#define CONFIG_SPL_GPIO_SUPPORT
+#define CONFIG_SPL_RAM_SUPPORT
+#define CONFIG_SPL_DRIVERS_MISC_SUPPORT
+
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_TIME
+
+#define CONFIG_SYS_SDRAM_BASE		0
+#define CONFIG_NR_DRAM_BANKS		1
+#define SDRAM_BANK_SIZE			(2UL << 30)
+
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_SPI
+#define CONFIG_SPI_FLASH_GIGADEVICE
+#define CONFIG_SF_DEFAULT_SPEED 20000000
+
+#define CONFIG_CMD_I2C
+
+#ifndef CONFIG_SPL_BUILD
+#include <config_distro_defaults.h>
+#endif
+
+#endif
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 31/41] rockchip: Add basic support for jerry
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (29 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 30/41] rockchip: Add basic support for firefly-rk3288 Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 18:00   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 32/41] rockchip: Add a simple README Simon Glass
                   ` (9 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

This builds and displays an SPL message, but does not function beyond that.

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

Changes in v5:
- Use CONFIG_ROCKCHIP_DWMMC instead of CONFIG_ROCKCHIP_MMC

Changes in v4: None
Changes in v3: None
Changes in v2:
- Tidy up license headers and remove SPL #ifdefs

 arch/arm/dts/Makefile                      |   3 +-
 arch/arm/dts/cros-ec-sbs.dtsi              |  16 +
 arch/arm/dts/rk3288-jerry.dts              | 203 +++++++
 arch/arm/dts/rk3288-veyron-chromebook.dtsi | 200 +++++++
 arch/arm/dts/rk3288-veyron.dtsi            | 844 +++++++++++++++++++++++++++++
 arch/arm/mach-rockchip/rk3288/Kconfig      |  10 +
 board/google/chromebook_jerry/Kconfig      |  15 +
 board/google/chromebook_jerry/MAINTAINERS  |   6 +
 board/google/chromebook_jerry/Makefile     |   7 +
 board/google/chromebook_jerry/jerry.c      |   7 +
 board/google/common/Makefile               |   2 +-
 configs/chromebook_jerry_defconfig         |  43 ++
 include/configs/chromebook_jerry.h         |  16 +
 13 files changed, 1370 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/dts/cros-ec-sbs.dtsi
 create mode 100644 arch/arm/dts/rk3288-jerry.dts
 create mode 100644 arch/arm/dts/rk3288-veyron-chromebook.dtsi
 create mode 100644 arch/arm/dts/rk3288-veyron.dtsi
 create mode 100644 board/google/chromebook_jerry/Kconfig
 create mode 100644 board/google/chromebook_jerry/MAINTAINERS
 create mode 100644 board/google/chromebook_jerry/Makefile
 create mode 100644 board/google/chromebook_jerry/jerry.c
 create mode 100644 configs/chromebook_jerry_defconfig
 create mode 100644 include/configs/chromebook_jerry.h

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 698b195..5ade574 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -16,7 +16,8 @@ dtb-$(CONFIG_EXYNOS5) += exynos5250-arndale.dtb \
 	exynos5800-peach-pi.dtb \
 	exynos5422-odroidxu3.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += \
-	rk3288-firefly.dtb
+	rk3288-firefly.dtb \
+	rk3288-jerry.dtb
 dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
 	tegra20-medcom-wide.dtb \
 	tegra20-paz00.dtb \
diff --git a/arch/arm/dts/cros-ec-sbs.dtsi b/arch/arm/dts/cros-ec-sbs.dtsi
new file mode 100644
index 0000000..3f35d20
--- /dev/null
+++ b/arch/arm/dts/cros-ec-sbs.dtsi
@@ -0,0 +1,16 @@
+/*
+ * Smart battery dts fragment for devices that use cros-ec-sbs
+ *
+ * Copyright (c) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+*/
+
+&i2c_tunnel {
+	battery: sbs-battery at b {
+		compatible = "sbs,sbs-battery";
+		reg = <0xb>;
+		sbs,i2c-retry-count = <2>;
+		sbs,poll-retry-count = <1>;
+	};
+};
diff --git a/arch/arm/dts/rk3288-jerry.dts b/arch/arm/dts/rk3288-jerry.dts
new file mode 100644
index 0000000..da37ea8
--- /dev/null
+++ b/arch/arm/dts/rk3288-jerry.dts
@@ -0,0 +1,203 @@
+/*
+ * Google Veyron Jerry Rev 3+ board device tree source
+ *
+ * Copyright 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+/dts-v1/;
+#include "rk3288-veyron-chromebook.dtsi"
+#include "cros-ec-sbs.dtsi"
+
+/ {
+	model = "Google Jerry";
+	compatible = "google,veyron-jerry-rev7", "google,veyron-jerry-rev6",
+		     "google,veyron-jerry-rev5", "google,veyron-jerry-rev4",
+		     "google,veyron-jerry-rev3", "google,veyron-jerry",
+		     "google,veyron", "rockchip,rk3288";
+
+        chosen {
+                stdout-path = &uart2;
+        };
+
+	panel_regulator: panel-regualtor {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio7 14 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&lcd_enable_h>;
+		regulator-name = "panel_regulator";
+		vin-supply = <&vcc33_sys>;
+	};
+
+	vcc18_lcd: vcc18-lcd {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio2 13 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&avdd_1v8_disp_en>;
+		regulator-name = "vcc18_lcd";
+		regulator-always-on;
+		regulator-boot-on;
+		vin-supply = <&vcc18_wl>;
+	};
+
+	backlight_regulator: backlight-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio2 12 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&bl_pwr_en>;
+		regulator-name = "backlight_regulator";
+		vin-supply = <&vcc33_sys>;
+		startup-delay-us = <15000>;
+	};
+};
+
+&gpio_keys {
+	power {
+		gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&backlight {
+	power-supply = <&backlight_regulator>;
+};
+
+&panel {
+	power-supply= <&panel_regulator>;
+};
+
+&rk808 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pmic_int_l &dvs_1 &dvs_2>;
+	dvs-gpios = <&gpio7 12 GPIO_ACTIVE_HIGH>,
+		    <&gpio7 15 GPIO_ACTIVE_HIGH>;
+
+	regulators {
+		mic_vcc: LDO_REG2 {
+			regulator-always-on;
+			regulator-boot-on;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-name = "mic_vcc";
+			regulator-suspend-mem-disabled;
+		};
+	};
+};
+
+&sdmmc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd_disabled &sdmmc_cd_gpio
+			&sdmmc_bus4>;
+	disable-wp;
+};
+
+&vcc_5v {
+	enable-active-high;
+	gpio = <&gpio7 21 GPIO_ACTIVE_HIGH>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&drv_5v>;
+};
+
+&vcc50_hdmi {
+	enable-active-high;
+	gpio = <&gpio5 19 GPIO_ACTIVE_HIGH>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&vcc50_hdmi_en>;
+};
+
+&edp {
+	pinctrl-names = "default";
+	pinctrl-0 = <&edp_hpd>;
+};
+
+&pinctrl {
+	backlight {
+		bl_pwr_en: bl_pwr_en {
+			rockchip,pins = <2 12 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	buck-5v {
+		drv_5v: drv-5v {
+			rockchip,pins = <7 21 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	edp {
+		edp_hpd: edp_hpd {
+			rockchip,pins = <7 11 RK_FUNC_2 &pcfg_pull_down>;
+		};
+	};
+
+	emmc {
+		/* Make sure eMMC is not in reset */
+		emmc_deassert_reset: emmc-deassert-reset {
+			rockchip,pins = <2 9 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	hdmi {
+		vcc50_hdmi_en: vcc50-hdmi-en {
+			rockchip,pins = <5 19 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	lcd {
+		lcd_enable_h: lcd-en {
+			rockchip,pins = <7 14 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		avdd_1v8_disp_en: avdd-1v8-disp-en {
+			rockchip,pins = <2 13 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pmic {
+		dvs_1: dvs-1 {
+			rockchip,pins = <7 12 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+
+		dvs_2: dvs-2 {
+			rockchip,pins = <7 15 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+	};
+};
+
+&i2c4 {
+	status = "okay";
+
+	/*
+	 * Trackpad pin control is shared between Elan and Synaptics devices
+	 * so we have to pull it up to the bus level.
+	 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c4_xfer &trackpad_int>;
+
+	trackpad at 15 {
+		compatible = "elan,i2c_touchpad";
+		interrupt-parent = <&gpio7>;
+		interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+		/*
+		 * Remove the inherited pinctrl settings to avoid clashing
+		 * with bus-wide ones.
+		 */
+		/delete-property/pinctrl-names;
+		/delete-property/pinctrl-0;
+		reg = <0x15>;
+		vcc-supply = <&vcc33_io>;
+		wakeup-source;
+	};
+
+	trackpad at 2c {
+		compatible = "hid-over-i2c";
+		interrupt-parent = <&gpio7>;
+		interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+		reg = <0x2c>;
+		hid-descr-addr = <0x0020>;
+		vcc-supply = <&vcc33_io>;
+		wakeup-source;
+	};
+};
diff --git a/arch/arm/dts/rk3288-veyron-chromebook.dtsi b/arch/arm/dts/rk3288-veyron-chromebook.dtsi
new file mode 100644
index 0000000..6d619c9
--- /dev/null
+++ b/arch/arm/dts/rk3288-veyron-chromebook.dtsi
@@ -0,0 +1,200 @@
+/*
+ * Google Veyron (and derivatives) board device tree source
+ *
+ * Copyright 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <dt-bindings/clock/rockchip,rk808.h>
+#include <dt-bindings/input/input.h>
+#include "rk3288-veyron.dtsi"
+
+/ {
+	aliases {
+		i2c20 = &i2c_tunnel;
+	};
+
+	gpio_keys: gpio-keys {
+		pinctrl-0 = <&pwr_key_h &ap_lid_int_l>;
+		lid {
+			label = "Lid";
+			gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
+			linux,code = <0>; /* SW_LID */
+			linux,input-type = <5>; /* EV_SW */
+			debounce-interval = <1>;
+			gpio-key,wakeup;
+                };
+	};
+
+	gpio-charger {
+		compatible = "gpio-charger";
+		gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ac_present_ap>;
+		charger-type = "mains";
+	};
+
+	/* A non-regulated voltage from power supply or battery */
+	vccsys: vccsys {
+		compatible = "regulator-fixed";
+		regulator-name = "vccsys";
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	vcc33_sys: vcc33-sys {
+		vin-supply = <&vccsys>;
+	};
+
+	vcc_5v: vcc-5v {
+		vin-supply = <&vccsys>;
+	};
+
+	/* This turns on vbus for host1 (dwc2) */
+	vcc5_host1: vcc5-host1-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 11 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&host1_pwr_en>;
+		regulator-name = "vcc5_host1";
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	/* This turns on vbus for otg for host mode (dwc2) */
+	vcc5v_otg: vcc5v-otg-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usbotg_pwren_h>;
+		regulator-name = "vcc5_host2";
+		regulator-always-on;
+		regulator-boot-on;
+	};
+};
+
+&rk808 {
+	regulators {
+		vcc33_ccd: LDO_REG8 {
+			regulator-always-on;
+			regulator-boot-on;
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-name = "vcc33_ccd";
+			regulator-suspend-mem-disabled;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	cros_ec: ec at 0 {
+		compatible = "google,cros-ec-spi";
+		spi-max-frequency = <3000000>;
+		interrupt-parent = <&gpio7>;
+		interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ec_int>;
+		reg = <0>;
+		google,cros-ec-spi-pre-delay = <30>;
+
+		i2c_tunnel: i2c-tunnel {
+			compatible = "google,cros-ec-i2c-tunnel";
+			google,remote-bus = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+};
+
+&i2c4 {
+	trackpad at 15 {
+		compatible = "elan,i2c_touchpad";
+		interrupt-parent = <&gpio7>;
+		interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&trackpad_int>;
+		reg = <0x15>;
+		vcc-supply = <&vcc33_io>;
+		wakeup-source;
+	};
+};
+
+&pinctrl {
+	pinctrl-0 = <
+		/* Common for sleep and wake, but no owners */
+		&ddr0_retention
+		&ddrio_pwroff
+		&global_pwroff
+
+		/* Wake only */
+		&suspend_l_wake
+		&bt_dev_wake_awake
+	>;
+	pinctrl-1 = <
+		/* Common for sleep and wake, but no owners */
+		&ddr0_retention
+		&ddrio_pwroff
+		&global_pwroff
+
+		/* Sleep only */
+		&suspend_l_sleep
+		&bt_dev_wake_sleep
+	>;
+
+	buttons {
+		ap_lid_int_l: ap-lid-int-l {
+			rockchip,pins = <0 6 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	charger {
+		ac_present_ap: ac-present-ap {
+			rockchip,pins = <0 8 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	cros-ec {
+		ec_int: ec-int {
+			rockchip,pins = <7 7 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	sdmmc {
+		sdmmc_wp_gpio: sdmmc-wp-gpio {
+			rockchip,pins = <7 10 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	suspend {
+		suspend_l_wake: suspend-l-wake {
+			rockchip,pins = <0 17 RK_FUNC_GPIO &pcfg_output_low>;
+		};
+
+		suspend_l_sleep: suspend-l-sleep {
+			rockchip,pins = <0 17 RK_FUNC_GPIO &pcfg_output_high>;
+		};
+	};
+
+	trackpad {
+		trackpad_int: trackpad-int {
+			rockchip,pins = <7 3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	usb-host {
+		host1_pwr_en: host1-pwr-en {
+			rockchip,pins = <0 11 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		usbotg_pwren_h: usbotg-pwren-h {
+			rockchip,pins = <0 12 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+#include "cros-ec-keyboard.dtsi"
diff --git a/arch/arm/dts/rk3288-veyron.dtsi b/arch/arm/dts/rk3288-veyron.dtsi
new file mode 100644
index 0000000..7e37158
--- /dev/null
+++ b/arch/arm/dts/rk3288-veyron.dtsi
@@ -0,0 +1,844 @@
+/*
+ * Google Veyron (and derivatives) board device tree source
+ *
+ * Copyright 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <dt-bindings/clock/rockchip,rk808.h>
+#include <dt-bindings/input/input.h>
+#include "rk3288.dtsi"
+
+/ {
+	memory {
+		reg = <0x0 0x80000000>;
+	};
+
+	chosen {
+		stdout-path = &uart2;
+	};
+
+	config {
+		u-boot,dm-pre-reloc;
+		u-boot,boot0 = &spi_flash;
+	};
+
+	firmware {
+		chromeos {
+			pinctrl-names = "default";
+			pinctrl-0 = <&fw_wp_ap>;
+			write-protect-gpio = <&gpio7 6 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		brightness-levels = <
+			  0   1   2   3   4   5   6   7
+			  8   9  10  11  12  13  14  15
+			 16  17  18  19  20  21  22  23
+			 24  25  26  27  28  29  30  31
+			 32  33  34  35  36  37  38  39
+			 40  41  42  43  44  45  46  47
+			 48  49  50  51  52  53  54  55
+			 56  57  58  59  60  61  62  63
+			 64  65  66  67  68  69  70  71
+			 72  73  74  75  76  77  78  79
+			 80  81  82  83  84  85  86  87
+			 88  89  90  91  92  93  94  95
+			 96  97  98  99 100 101 102 103
+			104 105 106 107 108 109 110 111
+			112 113 114 115 116 117 118 119
+			120 121 122 123 124 125 126 127
+			128 129 130 131 132 133 134 135
+			136 137 138 139 140 141 142 143
+			144 145 146 147 148 149 150 151
+			152 153 154 155 156 157 158 159
+			160 161 162 163 164 165 166 167
+			168 169 170 171 172 173 174 175
+			176 177 178 179 180 181 182 183
+			184 185 186 187 188 189 190 191
+			192 193 194 195 196 197 198 199
+			200 201 202 203 204 205 206 207
+			208 209 210 211 212 213 214 215
+			216 217 218 219 220 221 222 223
+			224 225 226 227 228 229 230 231
+			232 233 234 235 236 237 238 239
+			240 241 242 243 244 245 246 247
+			248 249 250 251 252 253 254 255>;
+		default-brightness-level = <128>;
+		enable-gpios = <&gpio7 2 GPIO_ACTIVE_HIGH>;
+		backlight-boot-off;
+		pinctrl-names = "default";
+		pinctrl-0 = <&bl_en>;
+		pwms = <&pwm0 0 1000000 0>;
+	};
+
+	panel: panel {
+		compatible ="cnm,n116bgeea2","simple-panel";
+		status = "okay";
+		power-supply = <&vcc33_lcd>;
+		backlight = <&backlight>;
+	};
+
+	gpio_keys: gpio-keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwr_key_h>;
+		power {
+			label = "Power";
+			gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_POWER>;
+			debounce-interval = <100>;
+			gpio-key,wakeup;
+		};
+	};
+
+	gpio-restart {
+		compatible = "gpio-restart";
+		gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ap_warm_reset_h>;
+		priority = /bits/ 8 <200>;
+	};
+
+	sound {
+		compatible = "rockchip,rockchip-audio-max98090";
+		rockchip,model = "ROCKCHIP-I2S";
+		rockchip,i2s-controller = <&i2s>;
+		rockchip,audio-codec = <&max98090>;
+		rockchip,hp-det-gpios = <&gpio6 5 GPIO_ACTIVE_HIGH>;
+		rockchip,mic-det-gpios = <&gpio6 11 GPIO_ACTIVE_LOW>;
+		rockchip,headset-codec = <&headsetcodec>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mic_det>, <&hp_det>;
+	};
+
+	vdd_logic: pwm-regulator {
+		compatible = "pwm-regulator";
+		pwms = <&pwm1 0 2000 0>;
+
+		voltage-table = <1350000 0>,
+				<1300000 10>,
+				<1250000 20>,
+				<1200000 31>,
+				<1150000 41>,
+				<1100000 52>,
+				<1050000 62>,
+				<1000000 72>,
+				< 950000 83>;
+
+		regulator-min-microvolt = <950000>;
+		regulator-max-microvolt = <1350000>;
+		regulator-name = "vdd_logic";
+		regulator-ramp-delay = <4000>;
+	};
+
+	vcc33_sys: vcc33-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc33_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vccsys>;
+	};
+
+	vcc_5v: vcc-5v {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_5v";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+
+	vcc50_hdmi: vcc50-hdmi {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc50_hdmi";
+		regulator-always-on;
+		regulator-boot-on;
+		vin-supply = <&vcc_5v>;
+	};
+
+	bt_regulator: bt-regulator {
+		/*
+		 * On the module itself this is one of these (depending
+		 * on the actual card pouplated):
+		 * - BT_I2S_WS_BT_RFDISABLE_L
+		 * - No connect
+		 */
+
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio4 29 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&bt_enable_l>;
+		regulator-name = "bt_regulator";
+	};
+
+	wifi_regulator: wifi-regulator {
+		/*
+		 * On the module itself this is one of these (depending
+		 * on the actual card populated):
+		 * - SDIO_RESET_L_WL_REG_ON
+		 * - PDN (power down when low)
+		 */
+
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio4 28 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&wifi_enable_h>;
+		regulator-name = "wifi_regulator";
+
+		/* Faux input supply.  See bt_regulator description. */
+		vin-supply = <&bt_regulator>;
+	};
+
+	io-domains {
+		compatible = "rockchip,rk3288-io-voltage-domain";
+		rockchip,grf = <&grf>;
+
+		audio-supply = <&vcc18_codec>;
+		bb-supply = <&vcc33_io>;
+		dvp-supply = <&vcc_18>;
+		flash0-supply = <&vcc18_flashio>;
+		gpio1830-supply = <&vcc33_io>;
+		gpio30-supply = <&vcc33_io>;
+		lcdc-supply = <&vcc33_lcd>;
+		sdcard-supply = <&vccio_sd>;
+		wifi-supply = <&vcc18_wl>;
+	};
+};
+
+&cpu0 {
+	cpu0-supply = <&vdd_cpu>;
+};
+
+&dmc {
+	logic-supply = <&vdd_logic>;
+	rockchip,odt-disable-freq = <333000000>;
+	rockchip,dll-disable-freq = <333000000>;
+	rockchip,sr-enable-freq = <333000000>;
+	rockchip,pd-enable-freq = <666000000>;
+	rockchip,auto-self-refresh-cnt = <0>;
+	rockchip,auto-power-down-cnt = <64>;
+	rockchip,ddr-speed-bin = <21>;
+	rockchip,trcd = <10>;
+	rockchip,trp = <10>;
+	operating-points = <
+		/* KHz    uV */
+		200000 1050000
+		333000 1100000
+		533000 1150000
+		666000 1200000
+	>;
+	rockchip,num-channels = <2>;
+	rockchip,pctl-timing = <0x29a 0xc8 0x1f8 0x42 0x4e 0x4 0xea 0xa
+		0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7
+		0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0
+		0x1 0x7 0x7 0x4 0xc 0x43 0x100 0x0
+		0x5 0x0>;
+	rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
+		0xa60 0x40 0x10 0x0>;
+	rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf>;
+	rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
+};
+
+&efuse {
+	status = "okay";
+};
+
+&emmc {
+	broken-cd;
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+	disable-wp;
+	non-removable;
+	num-slots = <1>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8 &emmc_deassert_reset>;
+	status = "okay";
+};
+
+&sdio0 {
+	broken-cd;
+	bus-width = <4>;
+	cap-sd-highspeed;
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
+	cap-sdio-irq;
+	card-external-vcc-supply = <&wifi_regulator>;
+	clocks = <&cru HCLK_SDIO0>, <&cru SCLK_SDIO0>, <&cru SCLK_SDIO0_DRV>,
+		 <&cru SCLK_SDIO0_SAMPLE>, <&rk808 RK808_CLKOUT1>;
+	clock-names = "biu", "ciu", "ciu_drv", "ciu_sample", "card_ext_clock";
+	keep-power-in-suspend;
+	non-removable;
+	num-slots = <1>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdio0_clk &sdio0_cmd &sdio0_bus4>;
+	status = "okay";
+	vmmc-supply = <&vcc33_sys>;
+	vqmmc-supply = <&vcc18_wl>;
+};
+
+&sdmmc {
+	bus-width = <4>;
+	cap-mmc-highspeed;
+	cap-sd-highspeed;
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
+	card-detect-delay = <200>;
+	cd-gpios = <&gpio7 5 GPIO_ACTIVE_LOW>;
+	num-slots = <1>;
+	status = "okay";
+	vmmc-supply = <&vcc33_sd>;
+	vqmmc-supply = <&vccio_sd>;
+};
+
+&spi2 {
+	status = "okay";
+	u-boot,dm-pre-reloc;
+
+	spi_flash: spiflash at 0 {
+		u-boot,dm-pre-reloc;
+		compatible = "spidev", "spi-flash";
+		spi-max-frequency = <20000000>; /* Reduce for Dediprog em100 pro */
+		reg = <0>;
+	};
+};
+
+&i2c0 {
+	status = "okay";
+
+	clock-frequency = <400000>;
+	i2c-scl-falling-time-ns = <50>;		/* 2.5ns measured */
+	i2c-scl-rising-time-ns = <100>;		/* 45ns measured */
+
+	rk808: pmic at 1b {
+		compatible = "rockchip,rk808";
+		clock-output-names = "xin32k", "wifibt_32kin";
+		interrupt-parent = <&gpio0>;
+		interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int_l>;
+		reg = <0x1b>;
+		rockchip,system-power-controller;
+		wakeup-source;
+		#clock-cells = <1>;
+
+		vcc1-supply = <&vcc33_sys>;
+		vcc2-supply = <&vcc33_sys>;
+		vcc3-supply = <&vcc33_sys>;
+		vcc4-supply = <&vcc33_sys>;
+		vcc6-supply = <&vcc_5v>;
+		vcc7-supply = <&vcc33_sys>;
+		vcc8-supply = <&vcc33_sys>;
+		vcc9-supply = <&vcc_5v>;
+		vcc10-supply = <&vcc33_sys>;
+		vcc11-supply = <&vcc_5v>;
+		vcc12-supply = <&vcc_18>;
+
+		vddio-supply = <&vcc33_io>;
+
+		regulators {
+			vdd_cpu: DCDC_REG1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <1450000>;
+				regulator-name = "vdd_arm";
+				regulator-ramp-delay = <6001>;
+				regulator-suspend-mem-disabled;
+			};
+
+			vdd_gpu: DCDC_REG2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1250000>;
+				regulator-name = "vdd_gpu";
+				regulator-ramp-delay = <6001>;
+				regulator-suspend-mem-disabled;
+			};
+
+			vcc135_ddr: DCDC_REG3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vcc135_ddr";
+				regulator-suspend-mem-enabled;
+			};
+
+			/*
+			 * vcc_18 has several aliases.  (vcc18_flashio and
+			 * vcc18_wl).  We'll add those aliases here just to
+			 * make it easier to follow the schematic.  The signals
+			 * are actually hooked together and only separated for
+			 * power measurement purposes).
+			 */
+			vcc18_wl: vcc18_flashio: vcc_18: DCDC_REG4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc_18";
+				regulator-suspend-mem-microvolt = <1800000>;
+			};
+
+			/*
+			 * Note that both vcc33_io and vcc33_pmuio are always
+			 * powered together. To simplify the logic in the dts
+			 * we just refer to vcc33_io every time something is
+			 * powered from vcc33_pmuio. In fact, on later boards
+			 * (such as danger) they're the same net.
+			 */
+			vcc33_io: LDO_REG1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc33_io";
+				regulator-suspend-mem-microvolt = <3300000>;
+			};
+
+			vdd_10: LDO_REG3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-name = "vdd_10";
+				regulator-suspend-mem-microvolt = <1000000>;
+			};
+
+			vccio_sd: LDO_REG4 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vccio_sd";
+				regulator-suspend-mem-disabled;
+			};
+
+			vcc33_sd: LDO_REG5 {
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc33_sd";
+				regulator-suspend-mem-disabled;
+			};
+
+			vcc18_codec: LDO_REG6 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc18_codec";
+				regulator-suspend-mem-disabled;
+			};
+
+			vdd10_lcd_pwren_h: LDO_REG7 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <2500000>;
+				regulator-max-microvolt = <2500000>;
+				regulator-name = "vdd10_lcd_pwren_h";
+				regulator-suspend-mem-disabled;
+			};
+
+			vcc33_lcd: SWITCH_REG1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vcc33_lcd";
+				regulator-suspend-mem-disabled;
+			};
+		};
+	};
+};
+
+&i2c1 {
+	status = "okay";
+
+	clock-frequency = <400000>;
+	i2c-scl-falling-time-ns = <50>;		/* 2.5ns measured */
+	i2c-scl-rising-time-ns = <100>;		/* 40ns measured */
+
+	tpm: tpm at 20 {
+		compatible = "infineon,slb9645tt";
+		reg = <0x20>;
+		powered-while-suspended;
+	};
+};
+
+&i2c2 {
+	status = "okay";
+
+	/* 100kHz since 4.7k resistors don't rise fast enough */
+	clock-frequency = <100000>;
+	i2c-scl-falling-time-ns = <50>;		/* 10ns measured */
+	i2c-scl-rising-time-ns = <800>;		/* 600ns measured */
+
+	max98090: max98090 at 10 {
+		compatible = "maxim,max98090";
+		reg = <0x10>;
+		interrupt-parent = <&gpio6>;
+		interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&int_codec>;
+	};
+};
+
+&i2c3 {
+	status = "okay";
+
+	clock-frequency = <400000>;
+	i2c-scl-falling-time-ns = <50>;
+	i2c-scl-rising-time-ns = <300>;
+};
+
+&i2c4 {
+	status = "okay";
+
+	clock-frequency = <400000>;
+	i2c-scl-falling-time-ns = <50>;		/* 11ns measured */
+	i2c-scl-rising-time-ns = <300>;		/* 225ns measured */
+
+	headsetcodec: ts3a227e at 3b {
+		compatible = "ti,ts3a227e";
+		reg = <0x3b>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ts3a227e_int_l>;
+		ti,micbias = <7>;		/* MICBIAS = 2.8V */
+	};
+};
+
+&i2c5 {
+	status = "okay";
+
+	clock-frequency = <100000>;
+	i2c-scl-falling-time-ns = <300>;
+	i2c-scl-rising-time-ns = <1000>;
+};
+
+&i2s {
+	status = "okay";
+	clock-names = "i2s_hclk", "i2s_clk", "i2s_clk_out";
+	clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>, <&cru SCLK_I2S0_OUT>;
+};
+
+&wdt {
+	status = "okay";
+};
+
+&pwm0 {
+	status = "okay";
+};
+
+&pwm1 {
+	status = "okay";
+};
+
+&uart0 {
+	status = "okay";
+
+	/* Pins don't include flow control by default; add that in */
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+	/* We need to go faster than 24MHz, so adjust clock parents / rates */
+	assigned-clocks = <&cru SCLK_UART0>;
+	assigned-clock-rates = <48000000>;
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+	u-boot,dm-pre-reloc;
+	reg-shift = <2>;
+};
+
+&vopb {
+	status = "okay";
+};
+
+&vopb_mmu {
+	status = "okay";
+};
+
+&vopl {
+	status = "okay";
+};
+
+&vopl_mmu {
+	status = "okay";
+};
+
+&edp {
+	status = "okay";
+	rockchip,panel = <&panel>;
+};
+
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_audio {
+	status = "okay";
+};
+
+&gpu {
+	status = "okay";
+};
+
+&tsadc {
+	tsadc-tshut-mode = <1>; /* tshut mode 0:CRU 1:GPIO */
+	tsadc-tshut-polarity = <1>; /* tshut polarity 0:LOW 1:HIGH */
+	status = "okay";
+};
+
+&pinctrl {
+	u-boot,dm-pre-reloc;
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <
+		/* Common for sleep and wake, but no owners */
+		&ddr0_retention
+		&ddrio_pwroff
+		&global_pwroff
+
+		/* Wake only */
+		&bt_dev_wake_awake
+	>;
+	pinctrl-1 = <
+		/* Common for sleep and wake, but no owners */
+		&ddr0_retention
+		&ddrio_pwroff
+		&global_pwroff
+
+		/* Sleep only */
+		&bt_dev_wake_sleep
+	>;
+
+	/* Add this for sdmmc pins to SD card */
+	pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma {
+		drive-strength = <8>;
+	};
+
+	pcfg_pull_up_drv_8ma: pcfg-pull-up-drv-8ma {
+		bias-pull-up;
+		drive-strength = <8>;
+	};
+
+	pcfg_output_high: pcfg-output-high {
+		output-high;
+	};
+
+	pcfg_output_low: pcfg-output-low {
+		output-low;
+	};
+
+	backlight {
+		bl_en: bl-en {
+			rockchip,pins = <7 2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	buttons {
+		pwr_key_h: pwr-key-h {
+			rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	codec {
+		hp_det: hp-det {
+			rockchip,pins = <6 5 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+		int_codec: int-codec {
+			rockchip,pins = <6 7 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+		mic_det: mic-det {
+			rockchip,pins = <6 11 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	emmc {
+		/* Make sure eMMC is not in reset */
+		emmc_deassert_reset: emmc-deassert-reset {
+			rockchip,pins = <7 12 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		/*
+		 * We run eMMC at max speed; bump up drive strength.
+		 * We also have external pulls, so disable the internal ones.
+		 */
+		emmc_clk: emmc-clk {
+			rockchip,pins = <3 18 RK_FUNC_2 &pcfg_pull_none_drv_8ma>;
+		};
+
+		emmc_cmd: emmc-cmd {
+			rockchip,pins = <3 16 RK_FUNC_2 &pcfg_pull_none_drv_8ma>;
+		};
+
+		emmc_bus8: emmc-bus8 {
+			rockchip,pins = <3 0 RK_FUNC_2 &pcfg_pull_none_drv_8ma>,
+					<3 1 RK_FUNC_2 &pcfg_pull_none_drv_8ma>,
+					<3 2 RK_FUNC_2 &pcfg_pull_none_drv_8ma>,
+					<3 3 RK_FUNC_2 &pcfg_pull_none_drv_8ma>,
+					<3 4 RK_FUNC_2 &pcfg_pull_none_drv_8ma>,
+					<3 5 RK_FUNC_2 &pcfg_pull_none_drv_8ma>,
+					<3 6 RK_FUNC_2 &pcfg_pull_none_drv_8ma>,
+					<3 7 RK_FUNC_2 &pcfg_pull_none_drv_8ma>;
+		};
+	};
+
+	headset {
+		ts3a227e_int_l: ts3a227e-int-l {
+			rockchip,pins = <0 3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	pmic {
+		pmic_int_l: pmic-int-l {
+			rockchip,pins = <RK_GPIO0 4 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	reboot {
+		ap_warm_reset_h: ap-warm-reset-h {
+			rockchip,pins = <RK_GPIO0 13 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	sdio0 {
+		wifi_enable_h: wifienable-h {
+			rockchip,pins = <4 28 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		/* NOTE: mislabelled on schematic; should be bt_enable_h */
+		bt_enable_l: bt-enable-l {
+			rockchip,pins = <4 29 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		/*
+		 * We run sdio0 at max speed; bump up drive strength.
+		 * We also have external pulls, so disable the internal ones.
+		 */
+		sdio0_bus4: sdio0-bus4 {
+			rockchip,pins = <4 20 RK_FUNC_1 &pcfg_pull_none_drv_8ma>,
+					<4 21 RK_FUNC_1 &pcfg_pull_none_drv_8ma>,
+					<4 22 RK_FUNC_1 &pcfg_pull_none_drv_8ma>,
+					<4 23 RK_FUNC_1 &pcfg_pull_none_drv_8ma>;
+		};
+
+		sdio0_cmd: sdio0-cmd {
+			rockchip,pins = <4 24 RK_FUNC_1 &pcfg_pull_none_drv_8ma>;
+		};
+
+		sdio0_clk: sdio0-clk {
+			rockchip,pins = <4 25 RK_FUNC_1 &pcfg_pull_none_drv_8ma>;
+		};
+
+		/*
+		 * These pins are only present on very new veyron boards; on
+		 * older boards bt_dev_wake is simply always high.  Note that
+		 * gpio4_26 is a NC on old veyron boards, so it doesn't hurt
+		 * to map this pin everywhere
+		 */
+		bt_dev_wake_sleep: bt-dev-wake-sleep {
+			rockchip,pins = <4 26 RK_FUNC_GPIO &pcfg_output_low>;
+		};
+
+		bt_dev_wake_awake: bt-dev-wake-awake {
+			rockchip,pins = <4 26 RK_FUNC_GPIO &pcfg_output_high>;
+		};
+	};
+
+	sdmmc {
+		/*
+		 * We run sdmmc at max speed; bump up drive strength.
+		 * We also have external pulls, so disable the internal ones.
+		 */
+		sdmmc_bus4: sdmmc-bus4 {
+			rockchip,pins = <6 16 RK_FUNC_1 &pcfg_pull_none_drv_8ma>,
+					<6 17 RK_FUNC_1 &pcfg_pull_none_drv_8ma>,
+					<6 18 RK_FUNC_1 &pcfg_pull_none_drv_8ma>,
+					<6 19 RK_FUNC_1 &pcfg_pull_none_drv_8ma>;
+		};
+
+		sdmmc_clk: sdmmc-clk {
+			rockchip,pins = <6 20 RK_FUNC_1 &pcfg_pull_none_drv_8ma>;
+		};
+
+		sdmmc_cmd: sdmmc-cmd {
+			rockchip,pins = <6 21 RK_FUNC_1 &pcfg_pull_none_drv_8ma>;
+		};
+
+		/*
+		 * Builtin CD line is hooked to ground to prevent JTAG at boot
+		 * (and also to get the voltage rail correct).  Make we
+		 * configure gpio6_C6 as GPIO so dw_mmc builtin CD doesn't
+		 * think there's a card inserted
+		 */
+		sdmmc_cd_disabled: sdmmc-cd-disabled {
+			rockchip,pins = <6 22 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		/* This is where we actually hook up CD */
+		sdmmc_cd_gpio: sdmmc-cd-gpio {
+			rockchip,pins = <7 5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	tpm {
+		tpm_int_h: tpm-int-h {
+			rockchip,pins = <7 4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	write-protect {
+		fw_wp_ap: fw-wp-ap {
+			rockchip,pins = <7 6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&usbphy {
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+	needs-reset-on-resume;
+};
+
+&usb_host1 {
+	status = "okay";
+};
+
+&usb_otg {
+	dr_mode = "host";
+	status = "okay";
+	assigned-clocks = <&cru SCLK_USBPHY480M_SRC>;
+	assigned-clock-parents = <&cru SCLK_OTGPHY0>;
+};
+
+&sdmmc {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio3 {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio8 {
+	u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig
index 7a77615..4d0f1b5 100644
--- a/arch/arm/mach-rockchip/rk3288/Kconfig
+++ b/arch/arm/mach-rockchip/rk3288/Kconfig
@@ -8,9 +8,19 @@ config TARGET_FIREFLY_RK3288
 	  also includes on-board eMMC and 1GB of SDRAM. Expansion connectors
 	  provide access to display pins, I2C, SPI, UART and GPIOs.
 
+config TARGET_CHROMEBOOK_JERRY
+	bool "Google/Rockchip Veyron-Jerry Chromebook"
+	help
+	  Jerry is a RK3288-based clamshell device with 2 USB 3.0 ports,
+	  HDMI, an 11.9 inch EDP display, micro-SD card, touchpad and
+	  WiFi. It includes a Chrome OS EC (Cortex-M3) to provide access to
+	  the keyboard and battery functions.
+
 config SYS_SOC
 	default "rockchip"
 
+source "board/google/chromebook_jerry/Kconfig"
+
 source "board/firefly/firefly-rk3288/Kconfig"
 
 endif
diff --git a/board/google/chromebook_jerry/Kconfig b/board/google/chromebook_jerry/Kconfig
new file mode 100644
index 0000000..3640513
--- /dev/null
+++ b/board/google/chromebook_jerry/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_CHROMEBOOK_JERRY
+
+config SYS_BOARD
+	default "chromebook_jerry"
+
+config SYS_VENDOR
+	default "google"
+
+config SYS_CONFIG_NAME
+	default "chromebook_jerry"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+	def_bool y
+
+endif
diff --git a/board/google/chromebook_jerry/MAINTAINERS b/board/google/chromebook_jerry/MAINTAINERS
new file mode 100644
index 0000000..b01b6cd
--- /dev/null
+++ b/board/google/chromebook_jerry/MAINTAINERS
@@ -0,0 +1,6 @@
+CHROMEBOOK JERRY BOARD
+M:	Simon Glass <sjg@chromium.org>
+S:	Maintained
+F:	board/google/chromebook_jerry/
+F:	include/configs/chromebook_jerry.h
+F:	configs/chromebook_jerry_defconfig
diff --git a/board/google/chromebook_jerry/Makefile b/board/google/chromebook_jerry/Makefile
new file mode 100644
index 0000000..d29a063
--- /dev/null
+++ b/board/google/chromebook_jerry/Makefile
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2015 Google, Inc
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y	+= jerry.o
diff --git a/board/google/chromebook_jerry/jerry.c b/board/google/chromebook_jerry/jerry.c
new file mode 100644
index 0000000..5119e95
--- /dev/null
+++ b/board/google/chromebook_jerry/jerry.c
@@ -0,0 +1,7 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
diff --git a/board/google/common/Makefile b/board/google/common/Makefile
index b38bc14..2de2799 100644
--- a/board/google/common/Makefile
+++ b/board/google/common/Makefile
@@ -4,4 +4,4 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
-obj-y += early_init.o
+obj-$(CONFIG_X86) += early_init.o
diff --git a/configs/chromebook_jerry_defconfig b/configs/chromebook_jerry_defconfig
new file mode 100644
index 0000000..389dfd2
--- /dev/null
+++ b/configs/chromebook_jerry_defconfig
@@ -0,0 +1,43 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_ROCKCHIP_RK3288=y
+CONFIG_TARGET_CHROMEBOOK_JERRY=y
+CONFIG_DEFAULT_DEVICE_TREE="rk3288-jerry"
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_STACK_R_ADDR=0x80000
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_PMIC=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_RESET=y
+CONFIG_LED=y
+CONFIG_SPL_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_BASE=0xff690000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_SIMPLE=y
+CONFIG_SPL_PINCTRL=y
+CONFIG_SPL_PINCTRL_SIMPLE=y
+CONFIG_ROCKCHIP_PINCTRL=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_ACT8846=y
+CONFIG_DM_REGULATOR=y
+CONFIG_REGULATOR_ACT8846=y
+CONFIG_RAM=y
+CONFIG_SPL_RAM=y
+CONFIG_DM_MMC=y
+CONFIG_ROCKCHIP_DWMMC=y
+CONFIG_USE_PRIVATE_LIBGCC=y
+CONFIG_CMD_DHRYSTONE=y
+CONFIG_ERRNO_STR=y
diff --git a/include/configs/chromebook_jerry.h b/include/configs/chromebook_jerry.h
new file mode 100644
index 0000000..a22b123
--- /dev/null
+++ b/include/configs/chromebook_jerry.h
@@ -0,0 +1,16 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <configs/rk3288_common.h>
+
+#define CONFIG_SPL_SPI_SUPPORT
+#define CONFIG_SPL_SPI_FLASH_SUPPORT
+#define CONFIG_SPL_SPI_LOAD
+
+#endif
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 32/41] rockchip: Add a simple README
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (30 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 31/41] rockchip: Add basic support for jerry Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 18:00   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 33/41] doc: Fix reference to Rock pro when Rock 2 is meant Simon Glass
                   ` (8 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

Add a few notes on how to try out the Rockchip support so far.

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

Changes in v5:
- Bring in Sjoerd's series so that everything is in one place

Changes in v4:
- Tweak the cover letter a little, drop mention of patches already applied

Changes in v3:
- Add various new patches to get RK3288 booting to a prompt
- Update README to mention available drivers

Changes in v2: None

 doc/README.rockchip | 246 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 246 insertions(+)
 create mode 100644 doc/README.rockchip

diff --git a/doc/README.rockchip b/doc/README.rockchip
new file mode 100644
index 0000000..a34e198
--- /dev/null
+++ b/doc/README.rockchip
@@ -0,0 +1,246 @@
+#
+# Copyright (C) 2015 Google. Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+U-Boot on Rockchip
+==================
+
+There are several repositories available with versions of U-Boot that support
+many Rockchip devices [1] [2].
+
+The current mainline support is experimental only and is not useful for
+anything. It should provide a base on which to build.
+
+So far only support for the RK3288 is provided.
+
+
+Prerequisites
+=============
+
+You will need:
+
+   - Firefly RK3288 baord
+   - Power connection to 5V using the supplied micro-USB power cable
+   - Separate USB serial cable attached to your computer and the Firefly
+        (connect to the micro-USB connector below the logo)
+   - rkflashtool [3]
+   - openssl (sudo apt-get install openssl)
+   - Serial UART connection [4]
+   - Suitable ARM cross compiler, e.g.:
+        sudo apt-get install gcc-4.7-arm-linux-gnueabi
+
+
+Building
+========
+
+At present three RK3288 boards are supported:
+
+   - Firefly RK3288 - use firefly-rk3288 configuration
+   - Radxa Rock Pro - also uses firefly-rk3288 configuration
+   - Haier Chromebook - use chromebook_jerry configuration
+
+For example:
+
+   CROSS_COMPILE=arm-linux-gnueabi- make O=firefly firefly-rk3288_defconfig all
+
+(or you can use another cross compiler if you prefer)
+
+Note that the Radxa Rock Pro uses the Firefly configuration for now as
+device tree files are not yet available for the Rock Pro. Clearly the two
+have hardware differences, so this approach will break down as more drivers
+are added.
+
+
+Writing to the board with USB
+=============================
+
+For USB to work you must get your board into ROM boot mode, either by erasing
+your MMC or (perhaps) holding the recovery button when you boot the board.
+To erase your MMC, you can boot into Linux and type (as root)
+
+   dd if=/dev/zero of=/dev/mmcblk0 bs=1M
+
+Connect your board's OTG port to your computer.
+
+To create a suitable image and write it to the board:
+
+   ./firefly-rk3288/tools/mkimage -T rkimage -d ./firefly-rk3288/spl/u-boot-spl-dtb.bin out
+   cat out | openssl rc4 -K 7c4e0304550509072d2c7b38170d1711 | rkflashtool l
+
+If all goes well you should something like:
+
+   U-Boot SPL 2015.07-rc1-00383-ge345740-dirty (Jun 03 2015 - 10:06:49)
+   Card did not respond to voltage select!
+   spl: mmc init failed with error: -17
+   ### ERROR ### Please RESET the board ###
+
+You will need to reset the board before each time you try. Yes, that's all
+it does so far. If support for the Rockchip USB protocol or DFU were added
+in SPL then we could in principle load U-Boot and boot to a prompt from USB
+as several other platforms do. However it does not seem to be possible to
+use the existing boot ROM code from SPL.
+
+
+Booting from an SD card
+=======================
+
+To write an image that boots from an SD card (assumed to be /dev/sdc):
+
+   ./firefly-rk3288/tools/mkimage -T rksd -d firefly-rk3288/spl/u-boot-spl-dtb.bin out
+   sudo dd if=out of=/dev/sdc
+   sudo dd if=firefly-rk3288/u-boot-dtb.img of=/dev/sdc seek=256
+
+This puts the Rockchip header and SPL image first and then places the U-Boot
+image at block 256 (i.e. 128KB from the start of the SD card). This
+corresponds with this setting in U-Boot:
+
+   #define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR	256
+
+Put this SD (or micro-SD) card into your board and reset it. You should see
+something like:
+
+   U-Boot SPL 2015.07-rc1-00383-ge345740-dirty (Jun 03 2015 - 11:04:40)
+
+
+   U-Boot 2015.07-rc1-00383-ge345740-dirty (Jun 03 2015 - 11:04:40)
+
+   DRAM:  2 GiB
+   MMC:
+   Using default environment
+
+   In:    serial at ff690000
+   Out:   serial at ff690000
+   Err:   serial at ff690000
+   =>
+
+
+Booting from SPI
+================
+
+To write an image that boots from SPI flash (e.g. for the Haier Chromebook):
+
+   ./chromebook_jerry/tools/mkimage -T rkspi -d chromebook_jerry/spl/u-boot-spl-dtb.bin out
+   dd if=spl.bin of=out.bin bs=128K conv=sync
+   cat chromebook_jerry/u-boot-dtb.img out.bin
+   dd if=out.bin of=out.bin.pad bs=4M conv=sync
+
+This converts the SPL image to the required SPI format by adding the Rockchip
+header and skipping every 2KB block. Then the U-Boot image is written at
+offset 128KB and the whole image is padded to 4MB which is the SPI flash size.
+The position of U-Boot is controlled with this setting in U-Boot:
+
+   #define CONFIG_SYS_SPI_U_BOOT_OFFS	(128 << 10)
+
+If you have a Dediprog em100pro connected then you can write the image with:
+
+      sudo em100 -s -c GD25LQ32 -d out.bin.pad -r
+
+When booting you should see something like:
+
+   U-Boot SPL 2015.07-rc2-00215-g9a58220-dirty (Jun 23 2015 - 12:11:32)
+
+
+   U-Boot 2015.07-rc2-00215-g9a58220-dirty (Jun 23 2015 - 12:11:32 -0600)
+
+   Model: Google Jerry
+   DRAM:  2 GiB
+   MMC:
+   Using default environment
+
+   In:    serial at ff690000
+   Out:   serial at ff690000
+   Err:   serial@ff690000
+   =>
+
+
+Future work
+===========
+
+Immediate priorities are:
+
+- MMC support (in U-Boot itself)
+- GPIO (driver exists but is lightly tested)
+- I2C (driver exists but is non-functional)
+- USB host
+- USB device
+- PMIC and regulators (only ACT8846 is supported at present)
+- LCD and HDMI
+- Run CPU at full speed
+- Ethernet
+- NAND flash
+- Support for other Rockchip parts
+- Boot U-Boot proper over USB OTG (at present only SPL works)
+
+
+Development Notes
+=================
+
+There are plenty of patches in the links below to help with this work.
+
+[1] https://github.com/rkchrome/uboot.git
+[2] https://github.com/linux-rockchip/u-boot-rockchip.git branch u-boot-rk3288
+[3] https://github.com/linux-rockchip/rkflashtool.git
+[4] http://wiki.t-firefly.com/index.php/Firefly-RK3288/Serial_debug/en
+
+rkimage
+-------
+
+rkimage.c produces an SPL image suitable for sending directly to the boot ROM
+over USB OTG. This is a very simple format - just the string RK32 (as 4 bytes)
+followed by u-boot-spl-dtb.bin.
+
+The boot ROM loads image to 0xff704000 which is in the internal SRAM. The SRAM
+starts at 0xff700000 and extends to 0xff718000 where we put the stack.
+
+rksd
+----
+
+rksd.c produces an image consisting of 32KB of empty space, a header and
+u-boot-spl-dtb.bin. The header is defined by 'struct header0_info' although
+most of the fields are unused by U-Boot. We just need to specify the
+signature, a flag and the block offset and size of the SPL image.
+
+The header occupies a single block but we pad it out to 4 blocks. The header
+is encoding using RC4 with the key 7c4e0304550509072d2c7b38170d1711. The SPL
+image can be encoded too but we don't do that.
+
+The maximum size of u-boot-spl-dtb.bin which the boot ROM will read is 32KB,
+or 0x40 blocks. This is a severe and annoying limitation. There may be a way
+around this limitation, since there is plenty of SRAM, but at present the
+board refuses to boot if this limit is exceeded.
+
+The image produced is padded up to a block boundary (512 bytes). It should be
+written to the start of an SD card using dd.
+
+Since this image is set to load U-Boot from the SD card at block offset,
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, dd should be used to write
+u-boot-dtb.img to the SD card at that offset. See above for instructions.
+
+rkspi
+-----
+
+rkspi.c produces an image consisting of a header and u-boot-spl-dtb.bin. The
+resulting image is then spread out so that only the first 2KB of each 4KB
+sector is used. The header is the same as with rksd and the maximum size is
+also 32KB (before spreading). The image should be written to the start of
+SPI flash.
+
+See above for instructions on how to write a SPI image.
+
+
+Device tree and driver model
+----------------------------
+
+Where possible driver model is used to provide a structure to the
+functionality. Device tree is used for configuration. However these have an
+overhead and in SPL with a 32KB size limit some shortcuts have been taken.
+In general all Rockchip drivers should use these features, with SPL-specific
+modifications where required.
+
+
+--
+Simon Glass <sjg@chromium.org>
+24 June 2015
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 33/41] doc: Fix reference to Rock pro when Rock 2 is meant
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (31 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 32/41] rockchip: Add a simple README Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 18:00   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 34/41] mmc: Probe DM based mmc devices in u-boot Simon Glass
                   ` (7 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

From: Sjoerd Simons <sjoerd.simons@collabora.co.uk>

The Radxa Rock pro board is rk3188 based and thus won't work with U-Boot
built for RK3288. Change the documentation to refer to the intended
board, the Radxa Rock 2, which is an RK3288-based design very similar to
the firefly

Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
Acked-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 doc/README.rockchip | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/doc/README.rockchip b/doc/README.rockchip
index a34e198..ce8ce77 100644
--- a/doc/README.rockchip
+++ b/doc/README.rockchip
@@ -39,7 +39,7 @@ Building
 At present three RK3288 boards are supported:
 
    - Firefly RK3288 - use firefly-rk3288 configuration
-   - Radxa Rock Pro - also uses firefly-rk3288 configuration
+   - Radxa Rock 2 - also uses firefly-rk3288 configuration
    - Haier Chromebook - use chromebook_jerry configuration
 
 For example:
@@ -48,8 +48,8 @@ For example:
 
 (or you can use another cross compiler if you prefer)
 
-Note that the Radxa Rock Pro uses the Firefly configuration for now as
-device tree files are not yet available for the Rock Pro. Clearly the two
+Note that the Radxa Rock 2 uses the Firefly configuration for now as
+device tree files are not yet available for the Rock 2. Clearly the two
 have hardware differences, so this approach will break down as more drivers
 are added.
 
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 34/41] mmc: Probe DM based mmc devices in u-boot
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (32 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 33/41] doc: Fix reference to Rock pro when Rock 2 is meant Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 18:00   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 35/41] rockchip: Disable sdio mmc slot on rk3288-firefly Simon Glass
                   ` (6 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

From: Sjoerd Simons <sjoerd.simons@collabora.co.uk>

During mmc initialize probe all devices with the MMC Uclass if build
with CONFIG_DM_MMC

Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
Acked-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/mmc/mmc.c | 43 +++++++++++++++++++++++++++++++++++++++----
 1 file changed, 39 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index f12546a..371c1ec 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -10,6 +10,8 @@
 #include <config.h>
 #include <common.h>
 #include <command.h>
+#include <dm.h>
+#include <dm/device-internal.h>
 #include <errno.h>
 #include <mmc.h>
 #include <part.h>
@@ -1759,10 +1761,44 @@ static void do_preinit(void)
 	}
 }
 
+#if defined(CONFIG_DM_MMC) && defined(CONFIG_SPL_BUILD)
+static int mmc_probe(bd_t *bis)
+{
+	return 0;
+}
+#elif defined(CONFIG_DM_MMC)
+static int mmc_probe(bd_t *bis)
+{
+	int ret;
+	struct uclass *uc;
+	struct udevice *m;
+
+	ret = uclass_get(UCLASS_MMC, &uc);
+	if (ret)
+		return ret;
+
+	uclass_foreach_dev(m, uc) {
+		ret = device_probe(m);
+		if (ret)
+			printf("%s - probe failed: %d\n", m->name, ret);
+	}
+
+	return 0;
+}
+#else
+static int mmc_probe(bd_t *bis)
+{
+	if (board_mmc_init(bis) < 0)
+		cpu_mmc_init(bis);
+
+	return 0;
+}
+#endif
 
 int mmc_initialize(bd_t *bis)
 {
 	static int initialized = 0;
+	int ret;
 	if (initialized)	/* Avoid initializing mmc multiple times */
 		return 0;
 	initialized = 1;
@@ -1770,10 +1806,9 @@ int mmc_initialize(bd_t *bis)
 	INIT_LIST_HEAD (&mmc_devices);
 	cur_dev_num = 0;
 
-#ifndef CONFIG_DM_MMC
-	if (board_mmc_init(bis) < 0)
-		cpu_mmc_init(bis);
-#endif
+	ret = mmc_probe(bis);
+	if (ret)
+		return ret;
 
 #ifndef CONFIG_SPL_BUILD
 	print_mmc_devices(',');
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 35/41] rockchip: Disable sdio mmc slot on rk3288-firefly
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (33 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 34/41] mmc: Probe DM based mmc devices in u-boot Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 18:00   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 36/41] rockchip: Turn off CONFIG_SPL_LED for firefly Simon Glass
                   ` (5 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

From: Sjoerd Simons <sjoerd.simons@collabora.co.uk>

U-Boot can't use the sdio card so turn it of to prevent things getting
confused/struck when trying to use the card as storage.

Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
Acked-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arm/dts/rk3288-firefly.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/dts/rk3288-firefly.dtsi b/arch/arm/dts/rk3288-firefly.dtsi
index 8a083f0..5aec1b8 100644
--- a/arch/arm/dts/rk3288-firefly.dtsi
+++ b/arch/arm/dts/rk3288-firefly.dtsi
@@ -386,7 +386,7 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&sdio0_bus4>, <&sdio0_cmd>, <&sdio0_clk>;
 	vmmc-supply = <&vcc_18>;
-	status = "okay";
+	status = "disabled";
 };
 
 &sdmmc {
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 36/41] rockchip: Turn off CONFIG_SPL_LED for firefly
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (34 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 35/41] rockchip: Disable sdio mmc slot on rk3288-firefly Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 18:00   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 37/41] rockchip: Add config_distro_bootcmd support Simon Glass
                   ` (4 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

From: Sjoerd Simons <sjoerd.simons@collabora.co.uk>

With LED support enabled the SPL easily goes over the size limit (e.g.
with both Debians gcc 4.9 and 5.2 cross-compilers). Turn off LED support
in the SPL to reduce the size just enough for those compilers.

Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
Tweaked commit subject to remove _SUPPORT
Signed-off-by: Simon Glass <sjg@chromium.org>

---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 configs/firefly-rk3288_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig
index 2411957..5fe90b5 100644
--- a/configs/firefly-rk3288_defconfig
+++ b/configs/firefly-rk3288_defconfig
@@ -17,7 +17,6 @@ CONFIG_REGMAP=y
 CONFIG_SYSCON=y
 CONFIG_RESET=y
 CONFIG_LED=y
-CONFIG_SPL_LED=y
 CONFIG_LED_GPIO=y
 CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART_BASE=0xff690000
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 37/41] rockchip: Add config_distro_bootcmd support
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (35 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 36/41] rockchip: Turn off CONFIG_SPL_LED for firefly Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 18:00   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 38/41] arm: Turn of d-cache before i-cache Simon Glass
                   ` (3 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

From: Sjoerd Simons <sjoerd.simons@collabora.co.uk>

Now that MMC works in U-Boot add config distro command support to start
Linux in a standard fashion. One oddity here is that linux fails to load
when the fdt is relocated to above 512MB, so set fdt_high to make sure it's
loaded below that.

Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
Acked-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 include/configs/rk3288_common.h | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h
index ce7fa75..e8aec28 100644
--- a/include/configs/rk3288_common.h
+++ b/include/configs/rk3288_common.h
@@ -92,6 +92,27 @@
 
 #ifndef CONFIG_SPL_BUILD
 #include <config_distro_defaults.h>
+
+#define ENV_MEM_LAYOUT_SETTINGS \
+	"scriptaddr=0x00000000\0" \
+	"pxefile_addr_r=0x00100000\0" \
+	"fdt_addr_r=0x01f00000\0" \
+	"kernel_addr_r=0x02000000\0" \
+	"ramdisk_addr_r=0x04000000\0"
+
+/* First try to boot from SD (index 0), then eMMC (index 1 */
+#define BOOT_TARGET_DEVICES(func) \
+	func(MMC, mmc, 0) \
+	func(MMC, mmc, 1)
+
+#include <config_distro_bootcmd.h>
+
+/* Linux fails to load the fdt if it's loaded above 512M on a Rock 2 board, so
+ * limit the fdt reallocation to that */
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"fdt_high=0x1fffffff\0" \
+	ENV_MEM_LAYOUT_SETTINGS \
+	BOOTENV
 #endif
 
 #endif
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 38/41] arm: Turn of d-cache before i-cache
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (36 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 37/41] rockchip: Add config_distro_bootcmd support Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 18:00   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 39/41] rockchip: Drop first 32kb of zeros from the rkSD image type Simon Glass
                   ` (2 subsequent siblings)
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

From: Sjoerd Simons <sjoerd.simons@collabora.co.uk>

Booting the kernel fails on RK3288 (and probably other rockchip SoCs)
when the i-cache is disabled/flushed before d-cache.

I have not investigated whether this is due to U-Boot hanging or whether
it's very early in the linux boot, but following the approach of the
various rockchip U-Boot forks (first disable d-cache then i-cache) makes
things work.

Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arm/cpu/armv7/cpu.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/arm/cpu/armv7/cpu.c b/arch/arm/cpu/armv7/cpu.c
index 0b0e500..6eac5ef 100644
--- a/arch/arm/cpu/armv7/cpu.c
+++ b/arch/arm/cpu/armv7/cpu.c
@@ -36,12 +36,6 @@ int cleanup_before_linux_select(int flags)
 	disable_interrupts();
 #endif
 
-	/*
-	 * Turn off I-cache and invalidate it
-	 */
-	icache_disable();
-	invalidate_icache_all();
-
 	if (flags & CBL_DISABLE_CACHES) {
 		/*
 		* turn off D-cache
@@ -61,7 +55,16 @@ int cleanup_before_linux_select(int flags)
 		* to avoid coherency problems for kernel
 		*/
 		invalidate_dcache_all();
+
+		icache_disable();
+		invalidate_icache_all();
 	} else {
+		/*
+		 * Turn off I-cache and invalidate it
+		 */
+		icache_disable();
+		invalidate_icache_all();
+
 		flush_dcache_all();
 		invalidate_icache_all();
 		icache_enable();
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 39/41] rockchip: Drop first 32kb of zeros from the rkSD image type
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (37 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 38/41] arm: Turn of d-cache before i-cache Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 18:00   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 40/41] rockchip: Update todo in README.rockchip Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 41/41] rockchip: Put README image creation commands on one line Simon Glass
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

From: Sjoerd Simons <sjoerd.simons@collabora.co.uk>

Instead of creating a rockchip SPL SD card image with 32KB of zeros
which can be written to the start of an SD card, create the images with
only the useful data that should be written to an offset of 32KB on the
SD card.

The first 32 kilobytes aren't needed for bootup and only serve as
convenient way of accidentally obliterating your partition table.

Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
Acked-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 doc/README.rockchip | 2 +-
 tools/rksd.c        | 9 ++-------
 2 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/doc/README.rockchip b/doc/README.rockchip
index ce8ce77..347fc05 100644
--- a/doc/README.rockchip
+++ b/doc/README.rockchip
@@ -90,7 +90,7 @@ Booting from an SD card
 To write an image that boots from an SD card (assumed to be /dev/sdc):
 
    ./firefly-rk3288/tools/mkimage -T rksd -d firefly-rk3288/spl/u-boot-spl-dtb.bin out
-   sudo dd if=out of=/dev/sdc
+   sudo dd if=out of=/dev/sdc seek=64
    sudo dd if=firefly-rk3288/u-boot-dtb.img of=/dev/sdc seek=256
 
 This puts the Rockchip header and SPL image first and then places the U-Boot
diff --git a/tools/rksd.c b/tools/rksd.c
index 2efcd68..a8dbe98 100644
--- a/tools/rksd.c
+++ b/tools/rksd.c
@@ -14,9 +14,7 @@
 #include "rkcommon.h"
 
 enum {
-	RKSD_HEADER0_START	= 64 * RK_BLK_SIZE,
-	RKSD_SPL_HDR_START	= RKSD_HEADER0_START +
-					RK_CODE1_OFFSET * RK_BLK_SIZE,
+	RKSD_SPL_HDR_START	= RK_CODE1_OFFSET * RK_BLK_SIZE,
 	RKSD_SPL_START		= RKSD_SPL_HDR_START + 4,
 	RKSD_HEADER_LEN		= RKSD_SPL_START,
 };
@@ -44,11 +42,8 @@ static void rksd_set_header(void *buf,  struct stat *sbuf,  int ifd,
 	unsigned int size;
 	int ret;
 
-	/* Zero the whole header. The first 32KB is empty */
-	memset(buf,  '\0',  RKSD_HEADER0_START);
-
 	size = params->file_size - RKSD_SPL_HDR_START;
-	ret = rkcommon_set_header(buf + RKSD_HEADER0_START, size);
+	ret = rkcommon_set_header(buf, size);
 	if (ret) {
 		/* TODO(sjg at chromium.org): This method should return an error */
 		printf("Warning: SPL image is too large (size %#x) and will not boot\n",
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 40/41] rockchip: Update todo in README.rockchip
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (38 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 39/41] rockchip: Drop first 32kb of zeros from the rkSD image type Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 18:00   ` Simon Glass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 41/41] rockchip: Put README image creation commands on one line Simon Glass
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

From: Sjoerd Simons <sjoerd.simons@collabora.co.uk>

MMC support works now, so it can be dropped from the todo

Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
Acked-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 doc/README.rockchip | 1 -
 1 file changed, 1 deletion(-)

diff --git a/doc/README.rockchip b/doc/README.rockchip
index 347fc05..feb11ff 100644
--- a/doc/README.rockchip
+++ b/doc/README.rockchip
@@ -161,7 +161,6 @@ Future work
 
 Immediate priorities are:
 
-- MMC support (in U-Boot itself)
 - GPIO (driver exists but is lightly tested)
 - I2C (driver exists but is non-functional)
 - USB host
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 41/41] rockchip: Put README image creation commands on one line
  2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
                   ` (39 preceding siblings ...)
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 40/41] rockchip: Update todo in README.rockchip Simon Glass
@ 2015-08-30 22:55 ` Simon Glass
  2015-09-03 18:00   ` Simon Glass
  40 siblings, 1 reply; 84+ messages in thread
From: Simon Glass @ 2015-08-30 22:55 UTC (permalink / raw)
  To: u-boot

It is easier to paste these into the command line if they are a single
common. Use line continuation instead of separate lines.

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

Changes in v5:
- Add new patch to put README image creation commands on one line

Changes in v4: None
Changes in v3: None
Changes in v2: None

 doc/README.rockchip | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/doc/README.rockchip b/doc/README.rockchip
index feb11ff..87ce9d2 100644
--- a/doc/README.rockchip
+++ b/doc/README.rockchip
@@ -67,7 +67,8 @@ Connect your board's OTG port to your computer.
 
 To create a suitable image and write it to the board:
 
-   ./firefly-rk3288/tools/mkimage -T rkimage -d ./firefly-rk3288/spl/u-boot-spl-dtb.bin out
+   ./firefly-rk3288/tools/mkimage -T rkimage -d \
+	./firefly-rk3288/spl/u-boot-spl-dtb.bin out && \
    cat out | openssl rc4 -K 7c4e0304550509072d2c7b38170d1711 | rkflashtool l
 
 If all goes well you should something like:
@@ -89,8 +90,9 @@ Booting from an SD card
 
 To write an image that boots from an SD card (assumed to be /dev/sdc):
 
-   ./firefly-rk3288/tools/mkimage -T rksd -d firefly-rk3288/spl/u-boot-spl-dtb.bin out
-   sudo dd if=out of=/dev/sdc seek=64
+   ./firefly-rk3288/tools/mkimage -T rksd -d \
+	firefly-rk3288/spl/u-boot-spl-dtb.bin out && \
+   sudo dd if=out of=/dev/sdc seek=64 && \
    sudo dd if=firefly-rk3288/u-boot-dtb.img of=/dev/sdc seek=256
 
 This puts the Rockchip header and SPL image first and then places the U-Boot
-- 
2.5.0.457.gab17608

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

* [U-Boot] [PATCH v5 29/41] rockchip: Add SPI driver
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 29/41] rockchip: Add SPI driver Simon Glass
@ 2015-09-01  5:23   ` Jagan Teki
  2015-09-02  1:03     ` Simon Glass
  0 siblings, 1 reply; 84+ messages in thread
From: Jagan Teki @ 2015-09-01  5:23 UTC (permalink / raw)
  To: u-boot

On 31 August 2015 at 04:25, Simon Glass <sjg@chromium.org> wrote:
> Add a SPI driver for the Rockchip RK3288, using driver model. It should work
> for other Rockchip SoCs also.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v5:
> - Drop unnecessary 'depends on DM_SPI' in Kconfig
> - Tidy up rkspi_dump_regs() debug output
> - Tidy up the delay in rkspi_wait_till_not_busy()
>
> Changes in v4:
> - Rename pinctrl.h to dm/pinctrl.h
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/spi/Kconfig  |   8 ++
>  drivers/spi/Makefile |   1 +
>  drivers/spi/rk_spi.c | 372 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  drivers/spi/rk_spi.h | 121 +++++++++++++++++
>  4 files changed, 502 insertions(+)
>  create mode 100644 drivers/spi/rk_spi.c
>  create mode 100644 drivers/spi/rk_spi.h
>
> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> index c84a7b7..8e04fce 100644
> --- a/drivers/spi/Kconfig
> +++ b/drivers/spi/Kconfig
> @@ -58,6 +58,14 @@ config ICH_SPI
>           access the SPI NOR flash on platforms embedding this Intel
>           ICH IP core.
>
> +config ROCKCHIP_SPI
> +       bool "Rockchip SPI driver"
> +       help
> +         Enable the Rockchip SPI driver, used to access SPI NOR flash and
> +         other SPI peripherals (such as the Chrome OS EC) on Rockchip SoCs.
> +         This uses driver model and requires a device tree binding to
> +         operate.
> +
>  config SANDBOX_SPI
>         bool "Sandbox SPI driver"
>         depends on SANDBOX && DM
> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
> index ee88aa1..de241be 100644
> --- a/drivers/spi/Makefile
> +++ b/drivers/spi/Makefile
> @@ -39,6 +39,7 @@ obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
>  obj-$(CONFIG_MXC_SPI) += mxc_spi.o
>  obj-$(CONFIG_MXS_SPI) += mxs_spi.o
>  obj-$(CONFIG_OMAP3_SPI) += omap3_spi.o
> +obj-$(CONFIG_ROCKCHIP_SPI) += rk_spi.o
>  obj-$(CONFIG_SANDBOX_SPI) += sandbox_spi.o
>  obj-$(CONFIG_SH_SPI) += sh_spi.o
>  obj-$(CONFIG_SH_QSPI) += sh_qspi.o
> diff --git a/drivers/spi/rk_spi.c b/drivers/spi/rk_spi.c
> new file mode 100644
> index 0000000..46b1a37
> --- /dev/null
> +++ b/drivers/spi/rk_spi.c
> @@ -0,0 +1,372 @@
> +/*
> + * spi driver for rockchip
> + *
> + * (C) Copyright 2015 Google, Inc
> + *
> + * (C) Copyright 2008-2013 Rockchip Electronics
> + * Peter, Software Engineering, <superpeter.cai@gmail.com>.
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <clk.h>
> +#include <dm.h>
> +#include <errno.h>
> +#include <spi.h>
> +#include <asm/errno.h>
> +#include <asm/io.h>
> +#include <asm/arch/clock.h>
> +#include <asm/arch/periph.h>
> +#include <dm/pinctrl.h>
> +#include "rk_spi.h"

Please move the header file data here

> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +struct rockchip_spi_platdata {
> +       enum periph_id periph_id;
> +       struct udevice *pinctrl;
> +       s32 frequency;          /* Default clock frequency, -1 for none */
> +       fdt_addr_t base;
> +       uint deactivate_delay_us;       /* Delay to wait after deactivate */
> +};
> +
> +struct rockchip_spi_priv {
> +       struct rockchip_spi *regs;
> +       struct udevice *clk_gpll;
> +       unsigned int max_freq;
> +       unsigned int mode;
> +       enum periph_id periph_id;       /* Peripheral ID for this device */
> +       ulong last_transaction_us;      /* Time of last transaction end */
> +       u8 bits_per_word;               /* max 16 bits per word */
> +       u8 n_bytes;
> +       unsigned int speed_hz;
> +       unsigned int tmode;
> +       uint input_rate;
> +};
> +
> +#define SPI_FIFO_DEPTH         32
> +
> +static void rkspi_dump_regs(struct rockchip_spi *regs)
> +{
> +       debug("ctrl0: \t\t0x%08x\n", readl(&regs->ctrlr0));
> +       debug("ctrl1: \t\t0x%08x\n", readl(&regs->ctrlr1));
> +       debug("ssienr: \t\t0x%08x\n", readl(&regs->enr));
> +       debug("ser: \t\t0x%08x\n", readl(&regs->ser));
> +       debug("baudr: \t\t0x%08x\n", readl(&regs->baudr));
> +       debug("txftlr: \t\t0x%08x\n", readl(&regs->txftlr));
> +       debug("rxftlr: \t\t0x%08x\n", readl(&regs->rxftlr));
> +       debug("txflr: \t\t0x%08x\n", readl(&regs->txflr));
> +       debug("rxflr: \t\t0x%08x\n", readl(&regs->rxflr));
> +       debug("sr: \t\t0x%08x\n", readl(&regs->sr));
> +       debug("imr: \t\t0x%08x\n", readl(&regs->imr));
> +       debug("isr: \t\t0x%08x\n", readl(&regs->isr));
> +       debug("dmacr: \t\t0x%08x\n", readl(&regs->dmacr));
> +       debug("dmatdlr: \t0x%08x\n", readl(&regs->dmatdlr));
> +       debug("dmardlr: \t0x%08x\n", readl(&regs->dmardlr));
> +}
> +
> +static void rkspi_enable_chip(struct rockchip_spi *regs, bool enable)
> +{
> +       writel(enable ? 1 : 0, &regs->enr);
> +}
> +
> +static void rkspi_set_clk(struct rockchip_spi_priv *priv, uint speed)
> +{
> +       uint clk_div;
> +
> +       clk_div = priv->input_rate / speed;
> +       clk_div = (clk_div + 1) & 0xfffe;

Define a clk divisor macro.

> +       debug("spi speed %u, div %u\n", speed, clk_div);
> +
> +       writel(clk_div, &priv->regs->baudr);
> +}
> +
> +static int rkspi_wait_till_not_busy(struct rockchip_spi *regs)
> +{
> +       unsigned long start;
> +
> +       start = get_timer(0);
> +       while (readl(&regs->sr) & SR_BUSY) {
> +               if (get_timer(start) > 1000) {

Define macro similar to CONFIG_SYS_ROCKCHIP_SPI_WAIT

> +                       debug("RK SPI: Status keeps busy for 1000us after a read/write!\n");
> +                       return -ETIMEDOUT;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +static void spi_cs_activate(struct rockchip_spi *regs, uint cs)
> +{
> +       debug("activate cs%u\n", cs);
> +       writel(1 << cs, &regs->ser);
> +}
> +
> +static void spi_cs_deactivate(struct rockchip_spi *regs, uint cs)
> +{
> +       debug("deactivate cs%u\n", cs);
> +       writel(0, &regs->ser);
> +}
> +
> +static int rockchip_spi_ofdata_to_platdata(struct udevice *bus)
> +{
> +       struct rockchip_spi_platdata *plat = bus->platdata;
> +       const void *blob = gd->fdt_blob;
> +       int node = bus->of_offset;
> +       int ret;
> +
> +       plat->base = dev_get_addr(bus);
> +       ret = uclass_get_device(UCLASS_PINCTRL, 0, &plat->pinctrl);
> +       if (ret)
> +               return ret;
> +       ret = pinctrl_get_periph_id(plat->pinctrl, bus);
> +
> +       if (ret < 0) {
> +               debug("%s: Could not get peripheral ID for %s: %d\n", __func__,
> +                     bus->name, ret);
> +               return -FDT_ERR_NOTFOUND;
> +       }
> +       plat->periph_id = ret;
> +
> +       plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
> +                                       50000000);
> +       plat->deactivate_delay_us = fdtdec_get_int(blob, node,
> +                                       "spi-deactivate-delay", 0);
> +       debug("%s: base=%x, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n",
> +             __func__, plat->base, plat->periph_id, plat->frequency,
> +             plat->deactivate_delay_us);
> +
> +       return 0;
> +}
> +
> +static int rockchip_spi_probe(struct udevice *bus)
> +{
> +       struct rockchip_spi_platdata *plat = dev_get_platdata(bus);
> +       struct rockchip_spi_priv *priv = dev_get_priv(bus);
> +       int ret;
> +
> +       debug("%s: probe\n", __func__);
> +       priv->regs = (struct rockchip_spi *)plat->base;
> +
> +       priv->last_transaction_us = timer_get_us();
> +       priv->max_freq = plat->frequency;
> +       priv->periph_id = plat->periph_id;
> +       ret = uclass_get_device(UCLASS_CLK, CLK_GENERAL, &priv->clk_gpll);
> +       if (ret) {
> +               debug("%s: Failed to find CLK_GENERAL: %d\n", __func__, ret);
> +               return ret;
> +       }
> +
> +       /*
> +        * Use 99 MHz as our clock since it divides nicely into 594 MHz which
> +        * is the assumed speed for CLK_GENERAL.
> +        */
> +       ret = clk_set_periph_rate(priv->clk_gpll, plat->periph_id, 99000000);
> +       if (ret < 0) {
> +               debug("%s: Failed to set clock: %d\n", __func__, ret);
> +               return ret;
> +       }
> +       priv->input_rate = ret;
> +       debug("%s: rate = %u\n", __func__, priv->input_rate);
> +       priv->bits_per_word = 8;
> +       priv->tmode = TMOD_TR; /* Tx & Rx */
> +
> +       return 0;
> +}
> +
> +static int rockchip_spi_claim_bus(struct udevice *dev)
> +{
> +       struct udevice *bus = dev->parent;
> +       struct rockchip_spi_platdata *plat = dev_get_platdata(bus);
> +       struct rockchip_spi_priv *priv = dev_get_priv(bus);
> +       struct rockchip_spi *regs = priv->regs;
> +       struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
> +       u8 spi_dfs, spi_tf;
> +       uint ctrlr0;
> +       int ret;
> +
> +       /* Disable the SPI hardware */
> +       rkspi_enable_chip(regs, 0);
> +
> +       switch (priv->bits_per_word) {
> +       case 8:
> +               priv->n_bytes = 1;
> +               spi_dfs = DFS_8BIT;
> +               spi_tf = HALF_WORD_OFF;
> +               break;
> +       case 16:
> +               priv->n_bytes = 2;
> +               spi_dfs = DFS_16BIT;
> +               spi_tf = HALF_WORD_ON;
> +               break;
> +       default:
> +               debug("%s: unsupported bits: %dbits\n", __func__,
> +                     priv->bits_per_word);
> +               return -EPROTONOSUPPORT;
> +       }
> +
> +       rkspi_set_clk(priv, priv->speed_hz);
> +
> +       /* Operation Mode */
> +       ctrlr0 = OMOD_MASTER << OMOD_SHIFT;
> +
> +       /* Data Frame Size */
> +       ctrlr0 |= spi_dfs & DFS_MASK << DFS_SHIFT;
> +
> +       /* set SPI mode 0..3 */
> +       if (priv->mode & SPI_CPOL)
> +               ctrlr0 |= SCOL_HIGH << SCOL_SHIFT;
> +       if (priv->mode & SPI_CPHA)
> +               ctrlr0 |= SCPH_TOGSTA << SCPH_SHIFT;
> +
> +       /* Chip Select Mode */
> +       ctrlr0 |= CSM_KEEP << CSM_SHIFT;
> +
> +       /* SSN to Sclk_out delay */
> +       ctrlr0 |= SSN_DELAY_ONE << SSN_DELAY_SHIFT;
> +
> +       /* Serial Endian Mode */
> +       ctrlr0 |= SEM_LITTLE << SEM_SHIFT;
> +
> +       /* First Bit Mode */
> +       ctrlr0 |= FBM_MSB << FBM_SHIFT;
> +
> +       /* Byte and Halfword Transform */
> +       ctrlr0 |= (spi_tf & HALF_WORD_MASK) << HALF_WORD_TX_SHIFT;
> +
> +       /* Rxd Sample Delay */
> +       ctrlr0 |= 0 << RXDSD_SHIFT;
> +
> +       /* Frame Format */
> +       ctrlr0 |= FRF_SPI << FRF_SHIFT;
> +
> +       /* Tx and Rx mode */
> +       ctrlr0 |= (priv->tmode & TMOD_MASK) << TMOD_SHIFT;
> +
> +       writel(ctrlr0, &regs->ctrlr0);
> +
> +       ret = pinctrl_request(plat->pinctrl, priv->periph_id, slave_plat->cs);
> +       if (ret) {
> +               debug("%s: Cannot request pinctrl: %d\n", __func__, ret);
> +               return ret;
> +       }
> +
> +       return 0;
> +}
> +
> +static int rockchip_spi_release_bus(struct udevice *dev)
> +{
> +       return 0;
> +}
> +
> +static int rockchip_spi_xfer(struct udevice *dev, unsigned int bitlen,
> +                          const void *dout, void *din, unsigned long flags)
> +{
> +       struct udevice *bus = dev->parent;
> +       struct rockchip_spi_priv *priv = dev_get_priv(bus);
> +       struct rockchip_spi *regs = priv->regs;
> +       struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
> +       int len = bitlen >> 3;
> +       const u8 *out = dout;
> +       u8 *in = din;
> +       int toread, towrite;
> +       int ret;
> +
> +       debug("%s: dout=%p, din=%p, len=%x, flags=%lx\n", __func__, dout, din,
> +             len, flags);
> +       if (0)
> +               rkspi_dump_regs(regs);

if (0) is really needed?

> +
> +       /* Assert CS before transfer */
> +       if (flags & SPI_XFER_BEGIN)
> +               spi_cs_activate(regs, slave_plat->cs);
> +
> +       while (len > 0) {
> +               int todo = min(len, 0xffff);
> +
> +               rkspi_enable_chip(regs, true);
> +               writel(todo - 1, &regs->ctrlr1);
> +               rkspi_enable_chip(regs, true);
> +
> +               toread = todo;
> +               towrite = todo;
> +               while (toread || towrite) {
> +                       u32 status = readl(&regs->sr);
> +
> +                       if (towrite && !(status & SR_TF_FULL)) {
> +                               writel(out ? *out++ : 0, regs->txdr);
> +                               towrite--;
> +                       }
> +                       if (toread && !(status & SR_RF_EMPT)) {
> +                               u32 byte = readl(regs->rxdr);
> +
> +                               if (in)
> +                                       *in++ = byte;
> +                               toread--;
> +                       }
> +               }
> +               ret = rkspi_wait_till_not_busy(regs);
> +               if (ret)
> +                       break;
> +               len -= todo;
> +       }
> +
> +       /* Deassert CS after transfer */
> +       if (flags & SPI_XFER_END)
> +               spi_cs_deactivate(regs, slave_plat->cs);
> +
> +       rkspi_enable_chip(regs, false);
> +
> +       return ret;
> +}
> +
> +static int rockchip_spi_set_speed(struct udevice *bus, uint speed)
> +{
> +       struct rockchip_spi_priv *priv = dev_get_priv(bus);
> +
> +       if (speed > 48000000)

Comment or macro for this numerical.

> +               return -EINVAL;
> +       if (speed > priv->max_freq)
> +               speed = priv->max_freq;
> +       priv->speed_hz = speed;
> +
> +       return 0;
> +}
> +
> +static int rockchip_spi_set_mode(struct udevice *bus, uint mode)
> +{
> +       struct rockchip_spi_priv *priv = dev_get_priv(bus);
> +
> +       priv->mode = mode;
> +
> +       return 0;
> +}
> +
> +static const struct dm_spi_ops rockchip_spi_ops = {
> +       .claim_bus      = rockchip_spi_claim_bus,
> +       .release_bus    = rockchip_spi_release_bus,
> +       .xfer           = rockchip_spi_xfer,
> +       .set_speed      = rockchip_spi_set_speed,
> +       .set_mode       = rockchip_spi_set_mode,
> +       /*
> +        * cs_info is not needed, since we require all chip selects to be
> +        * in the device tree explicitly
> +        */
> +};
> +
> +static const struct udevice_id rockchip_spi_ids[] = {
> +       { .compatible = "rockchip,rk3288-spi" },
> +       { }
> +};
> +
> +U_BOOT_DRIVER(rockchip_spi) = {
> +       .name   = "rockchip_spi",
> +       .id     = UCLASS_SPI,
> +       .of_match = rockchip_spi_ids,
> +       .ops    = &rockchip_spi_ops,
> +       .ofdata_to_platdata = rockchip_spi_ofdata_to_platdata,
> +       .platdata_auto_alloc_size = sizeof(struct rockchip_spi_platdata),
> +       .priv_auto_alloc_size = sizeof(struct rockchip_spi_priv),
> +       .probe  = rockchip_spi_probe,
> +};
> diff --git a/drivers/spi/rk_spi.h b/drivers/spi/rk_spi.h
> new file mode 100644
> index 0000000..bfb1739
> --- /dev/null
> +++ b/drivers/spi/rk_spi.h
> @@ -0,0 +1,121 @@
> +/*
> + * SPI driver for rockchip
> + *
> + * (C) Copyright 2015 Google, Inc
> + *
> + * (C) Copyright 2008-2013 Rockchip Electronics
> + * Peter, Software Engineering, <superpeter.cai@gmail.com>.
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#ifndef __RK_SPI_H
> +#define __RK_SPI_H
> +
> +struct rockchip_spi {
> +       u32 ctrlr0;
> +       u32 ctrlr1;
> +       u32 enr;
> +       u32 ser;
> +       u32 baudr;
> +       u32 txftlr;
> +       u32 rxftlr;
> +       u32 txflr;
> +       u32 rxflr;
> +       u32 sr;
> +       u32 ipr;
> +       u32 imr;
> +       u32 isr;
> +       u32 risr;
> +       u32 icr;
> +       u32 dmacr;
> +       u32 dmatdlr;
> +       u32 dmardlr;            /* 0x44 */
> +       u32 reserved[0xef];
> +       u32 txdr[0x100];        /* 0x400 */
> +       u32 rxdr[0x100];        /* 0x800 */
> +};
> +
> +/* CTRLR0 */
> +enum {
> +       DFS_SHIFT       = 0,    /* Data Frame Size */
> +       DFS_MASK        = 3,
> +       DFS_4BIT        = 0,
> +       DFS_8BIT,
> +       DFS_16BIT,
> +       DFS_RESV,
> +
> +       CFS_SHIFT       = 2,    /* Control Frame Size */
> +       CFS_MASK        = 0xf,
> +
> +       SCPH_SHIFT      = 6,    /* Serial Clock Phase */
> +       SCPH_MASK       = 1,
> +       SCPH_TOGMID     = 0,    /* SCLK toggles in middle of first data bit */
> +       SCPH_TOGSTA,            /* SCLK toggles at start of first data bit */
> +
> +       SCOL_SHIFT      = 7,    /* Serial Clock Polarity */
> +       SCOL_MASK       = 1,
> +       SCOL_LOW        = 0,    /* Inactive state of serial clock is low */
> +       SCOL_HIGH,              /* Inactive state of serial clock is high */
> +
> +       CSM_SHIFT       = 8,    /* Chip Select Mode */
> +       CSM_MASK        = 0x3,
> +       CSM_KEEP        = 0,    /* ss_n stays low after each frame  */
> +       CSM_HALF,               /* ss_n high for half sclk_out cycles */
> +       CSM_ONE,                /* ss_n high for one sclk_out cycle */
> +       CSM_RESV,
> +
> +       SSN_DELAY_SHIFT = 10,   /* SSN to Sclk_out delay */
> +       SSN_DELAY_MASK  = 1,
> +       SSN_DELAY_HALF  = 0,    /* 1/2 sclk_out cycle */
> +       SSN_DELAY_ONE   = 1,    /* 1 sclk_out cycle */
> +
> +       SEM_SHIFT       = 11,   /* Serial Endian Mode */
> +       SEM_MASK        = 1,
> +       SEM_LITTLE      = 0,    /* little endian */
> +       SEM_BIG,                /* big endian */
> +
> +       FBM_SHIFT       = 12,   /* First Bit Mode */
> +       FBM_MASK        = 1,
> +       FBM_MSB         = 0,    /* first bit is MSB */
> +       FBM_LSB,                /* first bit in LSB */
> +
> +       HALF_WORD_TX_SHIFT = 13,        /* Byte and Halfword Transform */
> +       HALF_WORD_MASK  = 1,
> +       HALF_WORD_ON    = 0,    /* apb 16bit write/read, spi 8bit write/read */
> +       HALF_WORD_OFF,          /* apb 8bit write/read, spi 8bit write/read */
> +
> +       RXDSD_SHIFT     = 14,   /* Rxd Sample Delay, in cycles */
> +       RXDSD_MASK      = 3,
> +
> +       FRF_SHIFT       = 16,   /* Frame Format */
> +       FRF_MASK        = 3,
> +       FRF_SPI         = 0,    /* Motorola SPI */
> +       FRF_SSP,                        /* Texas Instruments SSP*/
> +       FRF_MICROWIRE,          /* National Semiconductors Microwire */
> +       FRF_RESV,
> +
> +       TMOD_SHIFT      = 18,   /* Transfer Mode */
> +       TMOD_MASK       = 3,
> +       TMOD_TR         = 0,    /* xmit & recv */
> +       TMOD_TO,                /* xmit only */
> +       TMOD_RO,                /* recv only */
> +       TMOD_RESV,
> +
> +       OMOD_SHIFT      = 20,   /* Operation Mode */
> +       OMOD_MASK       = 1,
> +       OMOD_MASTER     = 0,    /* Master Mode */
> +       OMOD_SLAVE,             /* Slave Mode */
> +};
> +
> +/* SR */
> +enum {
> +       SR_MASK         = 0x7f,
> +       SR_BUSY         = 1 << 0,
> +       SR_TF_FULL      = 1 << 1,
> +       SR_TF_EMPT      = 1 << 2,
> +       SR_RF_EMPT      = 1 << 3,
> +       SR_RF_FULL      = 1 << 4,
> +};
> +
> +#endif /* __RK_SPI_H */
> --
> 2.5.0.457.gab17608
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot



-- 
Jagan | openedev.

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

* [U-Boot] [PATCH v5 29/41] rockchip: Add SPI driver
  2015-09-01  5:23   ` Jagan Teki
@ 2015-09-02  1:03     ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-02  1:03 UTC (permalink / raw)
  To: u-boot

Hi Jagan,

On 31 August 2015 at 23:23, Jagan Teki <jteki@openedev.com> wrote:
> On 31 August 2015 at 04:25, Simon Glass <sjg@chromium.org> wrote:
>> Add a SPI driver for the Rockchip RK3288, using driver model. It should work
>> for other Rockchip SoCs also.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v5:
>> - Drop unnecessary 'depends on DM_SPI' in Kconfig
>> - Tidy up rkspi_dump_regs() debug output
>> - Tidy up the delay in rkspi_wait_till_not_busy()
>>
>> Changes in v4:
>> - Rename pinctrl.h to dm/pinctrl.h
>>
>> Changes in v3: None
>> Changes in v2: None
>>
>>  drivers/spi/Kconfig  |   8 ++
>>  drivers/spi/Makefile |   1 +
>>  drivers/spi/rk_spi.c | 372 +++++++++++++++++++++++++++++++++++++++++++++++++++
>>  drivers/spi/rk_spi.h | 121 +++++++++++++++++
>>  4 files changed, 502 insertions(+)
>>  create mode 100644 drivers/spi/rk_spi.c
>>  create mode 100644 drivers/spi/rk_spi.h
>>
>> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
>> index c84a7b7..8e04fce 100644
>> --- a/drivers/spi/Kconfig
>> +++ b/drivers/spi/Kconfig
>> @@ -58,6 +58,14 @@ config ICH_SPI
>>           access the SPI NOR flash on platforms embedding this Intel
>>           ICH IP core.
>>
>> +config ROCKCHIP_SPI
>> +       bool "Rockchip SPI driver"
>> +       help
>> +         Enable the Rockchip SPI driver, used to access SPI NOR flash and
>> +         other SPI peripherals (such as the Chrome OS EC) on Rockchip SoCs.
>> +         This uses driver model and requires a device tree binding to
>> +         operate.
>> +
>>  config SANDBOX_SPI
>>         bool "Sandbox SPI driver"
>>         depends on SANDBOX && DM
>> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
>> index ee88aa1..de241be 100644
>> --- a/drivers/spi/Makefile
>> +++ b/drivers/spi/Makefile
>> @@ -39,6 +39,7 @@ obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
>>  obj-$(CONFIG_MXC_SPI) += mxc_spi.o
>>  obj-$(CONFIG_MXS_SPI) += mxs_spi.o
>>  obj-$(CONFIG_OMAP3_SPI) += omap3_spi.o
>> +obj-$(CONFIG_ROCKCHIP_SPI) += rk_spi.o
>>  obj-$(CONFIG_SANDBOX_SPI) += sandbox_spi.o
>>  obj-$(CONFIG_SH_SPI) += sh_spi.o
>>  obj-$(CONFIG_SH_QSPI) += sh_qspi.o
>> diff --git a/drivers/spi/rk_spi.c b/drivers/spi/rk_spi.c
>> new file mode 100644
>> index 0000000..46b1a37
>> --- /dev/null
>> +++ b/drivers/spi/rk_spi.c
>> @@ -0,0 +1,372 @@
>> +/*
>> + * spi driver for rockchip
>> + *
>> + * (C) Copyright 2015 Google, Inc
>> + *
>> + * (C) Copyright 2008-2013 Rockchip Electronics
>> + * Peter, Software Engineering, <superpeter.cai@gmail.com>.
>> + *
>> + * SPDX-License-Identifier:     GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <clk.h>
>> +#include <dm.h>
>> +#include <errno.h>
>> +#include <spi.h>
>> +#include <asm/errno.h>
>> +#include <asm/io.h>
>> +#include <asm/arch/clock.h>
>> +#include <asm/arch/periph.h>
>> +#include <dm/pinctrl.h>
>> +#include "rk_spi.h"
>
> Please move the header file data here

I would prefer to keep the declarations separate. They are not needed
in order to understand this code, and in fact just clutter it up. This
pattern is used widely in U-Boot and Linux.

>
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +struct rockchip_spi_platdata {
>> +       enum periph_id periph_id;
>> +       struct udevice *pinctrl;
>> +       s32 frequency;          /* Default clock frequency, -1 for none */
>> +       fdt_addr_t base;
>> +       uint deactivate_delay_us;       /* Delay to wait after deactivate */
>> +};
>> +
>> +struct rockchip_spi_priv {
>> +       struct rockchip_spi *regs;
>> +       struct udevice *clk_gpll;
>> +       unsigned int max_freq;
>> +       unsigned int mode;
>> +       enum periph_id periph_id;       /* Peripheral ID for this device */
>> +       ulong last_transaction_us;      /* Time of last transaction end */
>> +       u8 bits_per_word;               /* max 16 bits per word */
>> +       u8 n_bytes;
>> +       unsigned int speed_hz;
>> +       unsigned int tmode;
>> +       uint input_rate;
>> +};
>> +
>> +#define SPI_FIFO_DEPTH         32
>> +
>> +static void rkspi_dump_regs(struct rockchip_spi *regs)
>> +{
>> +       debug("ctrl0: \t\t0x%08x\n", readl(&regs->ctrlr0));
>> +       debug("ctrl1: \t\t0x%08x\n", readl(&regs->ctrlr1));
>> +       debug("ssienr: \t\t0x%08x\n", readl(&regs->enr));
>> +       debug("ser: \t\t0x%08x\n", readl(&regs->ser));
>> +       debug("baudr: \t\t0x%08x\n", readl(&regs->baudr));
>> +       debug("txftlr: \t\t0x%08x\n", readl(&regs->txftlr));
>> +       debug("rxftlr: \t\t0x%08x\n", readl(&regs->rxftlr));
>> +       debug("txflr: \t\t0x%08x\n", readl(&regs->txflr));
>> +       debug("rxflr: \t\t0x%08x\n", readl(&regs->rxflr));
>> +       debug("sr: \t\t0x%08x\n", readl(&regs->sr));
>> +       debug("imr: \t\t0x%08x\n", readl(&regs->imr));
>> +       debug("isr: \t\t0x%08x\n", readl(&regs->isr));
>> +       debug("dmacr: \t\t0x%08x\n", readl(&regs->dmacr));
>> +       debug("dmatdlr: \t0x%08x\n", readl(&regs->dmatdlr));
>> +       debug("dmardlr: \t0x%08x\n", readl(&regs->dmardlr));
>> +}
>> +
>> +static void rkspi_enable_chip(struct rockchip_spi *regs, bool enable)
>> +{
>> +       writel(enable ? 1 : 0, &regs->enr);
>> +}
>> +
>> +static void rkspi_set_clk(struct rockchip_spi_priv *priv, uint speed)
>> +{
>> +       uint clk_div;
>> +
>> +       clk_div = priv->input_rate / speed;
>> +       clk_div = (clk_div + 1) & 0xfffe;
>
> Define a clk divisor macro.

OK done.

>
>> +       debug("spi speed %u, div %u\n", speed, clk_div);
>> +
>> +       writel(clk_div, &priv->regs->baudr);
>> +}
>> +
>> +static int rkspi_wait_till_not_busy(struct rockchip_spi *regs)
>> +{
>> +       unsigned long start;
>> +
>> +       start = get_timer(0);
>> +       while (readl(&regs->sr) & SR_BUSY) {
>> +               if (get_timer(start) > 1000) {
>
> Define macro similar to CONFIG_SYS_ROCKCHIP_SPI_WAIT

OK done

>
>> +                       debug("RK SPI: Status keeps busy for 1000us after a read/write!\n");
>> +                       return -ETIMEDOUT;
>> +               }
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static void spi_cs_activate(struct rockchip_spi *regs, uint cs)
>> +{
>> +       debug("activate cs%u\n", cs);
>> +       writel(1 << cs, &regs->ser);
>> +}
>> +
>> +static void spi_cs_deactivate(struct rockchip_spi *regs, uint cs)
>> +{
>> +       debug("deactivate cs%u\n", cs);
>> +       writel(0, &regs->ser);
>> +}
>> +
>> +static int rockchip_spi_ofdata_to_platdata(struct udevice *bus)
>> +{
>> +       struct rockchip_spi_platdata *plat = bus->platdata;
>> +       const void *blob = gd->fdt_blob;
>> +       int node = bus->of_offset;
>> +       int ret;
>> +
>> +       plat->base = dev_get_addr(bus);
>> +       ret = uclass_get_device(UCLASS_PINCTRL, 0, &plat->pinctrl);
>> +       if (ret)
>> +               return ret;
>> +       ret = pinctrl_get_periph_id(plat->pinctrl, bus);
>> +
>> +       if (ret < 0) {
>> +               debug("%s: Could not get peripheral ID for %s: %d\n", __func__,
>> +                     bus->name, ret);
>> +               return -FDT_ERR_NOTFOUND;
>> +       }
>> +       plat->periph_id = ret;
>> +
>> +       plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
>> +                                       50000000);
>> +       plat->deactivate_delay_us = fdtdec_get_int(blob, node,
>> +                                       "spi-deactivate-delay", 0);
>> +       debug("%s: base=%x, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n",
>> +             __func__, plat->base, plat->periph_id, plat->frequency,
>> +             plat->deactivate_delay_us);
>> +
>> +       return 0;
>> +}
>> +
>> +static int rockchip_spi_probe(struct udevice *bus)
>> +{
>> +       struct rockchip_spi_platdata *plat = dev_get_platdata(bus);
>> +       struct rockchip_spi_priv *priv = dev_get_priv(bus);
>> +       int ret;
>> +
>> +       debug("%s: probe\n", __func__);
>> +       priv->regs = (struct rockchip_spi *)plat->base;
>> +
>> +       priv->last_transaction_us = timer_get_us();
>> +       priv->max_freq = plat->frequency;
>> +       priv->periph_id = plat->periph_id;
>> +       ret = uclass_get_device(UCLASS_CLK, CLK_GENERAL, &priv->clk_gpll);
>> +       if (ret) {
>> +               debug("%s: Failed to find CLK_GENERAL: %d\n", __func__, ret);
>> +               return ret;
>> +       }
>> +
>> +       /*
>> +        * Use 99 MHz as our clock since it divides nicely into 594 MHz which
>> +        * is the assumed speed for CLK_GENERAL.
>> +        */
>> +       ret = clk_set_periph_rate(priv->clk_gpll, plat->periph_id, 99000000);
>> +       if (ret < 0) {
>> +               debug("%s: Failed to set clock: %d\n", __func__, ret);
>> +               return ret;
>> +       }
>> +       priv->input_rate = ret;
>> +       debug("%s: rate = %u\n", __func__, priv->input_rate);
>> +       priv->bits_per_word = 8;
>> +       priv->tmode = TMOD_TR; /* Tx & Rx */
>> +
>> +       return 0;
>> +}
>> +
>> +static int rockchip_spi_claim_bus(struct udevice *dev)
>> +{
>> +       struct udevice *bus = dev->parent;
>> +       struct rockchip_spi_platdata *plat = dev_get_platdata(bus);
>> +       struct rockchip_spi_priv *priv = dev_get_priv(bus);
>> +       struct rockchip_spi *regs = priv->regs;
>> +       struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
>> +       u8 spi_dfs, spi_tf;
>> +       uint ctrlr0;
>> +       int ret;
>> +
>> +       /* Disable the SPI hardware */
>> +       rkspi_enable_chip(regs, 0);
>> +
>> +       switch (priv->bits_per_word) {
>> +       case 8:
>> +               priv->n_bytes = 1;
>> +               spi_dfs = DFS_8BIT;
>> +               spi_tf = HALF_WORD_OFF;
>> +               break;
>> +       case 16:
>> +               priv->n_bytes = 2;
>> +               spi_dfs = DFS_16BIT;
>> +               spi_tf = HALF_WORD_ON;
>> +               break;
>> +       default:
>> +               debug("%s: unsupported bits: %dbits\n", __func__,
>> +                     priv->bits_per_word);
>> +               return -EPROTONOSUPPORT;
>> +       }
>> +
>> +       rkspi_set_clk(priv, priv->speed_hz);
>> +
>> +       /* Operation Mode */
>> +       ctrlr0 = OMOD_MASTER << OMOD_SHIFT;
>> +
>> +       /* Data Frame Size */
>> +       ctrlr0 |= spi_dfs & DFS_MASK << DFS_SHIFT;
>> +
>> +       /* set SPI mode 0..3 */
>> +       if (priv->mode & SPI_CPOL)
>> +               ctrlr0 |= SCOL_HIGH << SCOL_SHIFT;
>> +       if (priv->mode & SPI_CPHA)
>> +               ctrlr0 |= SCPH_TOGSTA << SCPH_SHIFT;
>> +
>> +       /* Chip Select Mode */
>> +       ctrlr0 |= CSM_KEEP << CSM_SHIFT;
>> +
>> +       /* SSN to Sclk_out delay */
>> +       ctrlr0 |= SSN_DELAY_ONE << SSN_DELAY_SHIFT;
>> +
>> +       /* Serial Endian Mode */
>> +       ctrlr0 |= SEM_LITTLE << SEM_SHIFT;
>> +
>> +       /* First Bit Mode */
>> +       ctrlr0 |= FBM_MSB << FBM_SHIFT;
>> +
>> +       /* Byte and Halfword Transform */
>> +       ctrlr0 |= (spi_tf & HALF_WORD_MASK) << HALF_WORD_TX_SHIFT;
>> +
>> +       /* Rxd Sample Delay */
>> +       ctrlr0 |= 0 << RXDSD_SHIFT;
>> +
>> +       /* Frame Format */
>> +       ctrlr0 |= FRF_SPI << FRF_SHIFT;
>> +
>> +       /* Tx and Rx mode */
>> +       ctrlr0 |= (priv->tmode & TMOD_MASK) << TMOD_SHIFT;
>> +
>> +       writel(ctrlr0, &regs->ctrlr0);
>> +
>> +       ret = pinctrl_request(plat->pinctrl, priv->periph_id, slave_plat->cs);
>> +       if (ret) {
>> +               debug("%s: Cannot request pinctrl: %d\n", __func__, ret);
>> +               return ret;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static int rockchip_spi_release_bus(struct udevice *dev)
>> +{
>> +       return 0;
>> +}
>> +
>> +static int rockchip_spi_xfer(struct udevice *dev, unsigned int bitlen,
>> +                          const void *dout, void *din, unsigned long flags)
>> +{
>> +       struct udevice *bus = dev->parent;
>> +       struct rockchip_spi_priv *priv = dev_get_priv(bus);
>> +       struct rockchip_spi *regs = priv->regs;
>> +       struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
>> +       int len = bitlen >> 3;
>> +       const u8 *out = dout;
>> +       u8 *in = din;
>> +       int toread, towrite;
>> +       int ret;
>> +
>> +       debug("%s: dout=%p, din=%p, len=%x, flags=%lx\n", __func__, dout, din,
>> +             len, flags);
>> +       if (0)
>> +               rkspi_dump_regs(regs);
>
> if (0) is really needed?

I'll change it to use #ifdef above.

>
>> +
>> +       /* Assert CS before transfer */
>> +       if (flags & SPI_XFER_BEGIN)
>> +               spi_cs_activate(regs, slave_plat->cs);
>> +
>> +       while (len > 0) {
>> +               int todo = min(len, 0xffff);
>> +
>> +               rkspi_enable_chip(regs, true);
>> +               writel(todo - 1, &regs->ctrlr1);
>> +               rkspi_enable_chip(regs, true);
>> +
>> +               toread = todo;
>> +               towrite = todo;
>> +               while (toread || towrite) {
>> +                       u32 status = readl(&regs->sr);
>> +
>> +                       if (towrite && !(status & SR_TF_FULL)) {
>> +                               writel(out ? *out++ : 0, regs->txdr);
>> +                               towrite--;
>> +                       }
>> +                       if (toread && !(status & SR_RF_EMPT)) {
>> +                               u32 byte = readl(regs->rxdr);
>> +
>> +                               if (in)
>> +                                       *in++ = byte;
>> +                               toread--;
>> +                       }
>> +               }
>> +               ret = rkspi_wait_till_not_busy(regs);
>> +               if (ret)
>> +                       break;
>> +               len -= todo;
>> +       }
>> +
>> +       /* Deassert CS after transfer */
>> +       if (flags & SPI_XFER_END)
>> +               spi_cs_deactivate(regs, slave_plat->cs);
>> +
>> +       rkspi_enable_chip(regs, false);
>> +
>> +       return ret;
>> +}
>> +
>> +static int rockchip_spi_set_speed(struct udevice *bus, uint speed)
>> +{
>> +       struct rockchip_spi_priv *priv = dev_get_priv(bus);
>> +
>> +       if (speed > 48000000)
>
> Comment or macro for this numerical.

OK done.

>
>> +               return -EINVAL;
>> +       if (speed > priv->max_freq)
>> +               speed = priv->max_freq;
>> +       priv->speed_hz = speed;
>> +
>> +       return 0;
>> +}
>> +
>> +static int rockchip_spi_set_mode(struct udevice *bus, uint mode)
>> +{
>> +       struct rockchip_spi_priv *priv = dev_get_priv(bus);
>> +
>> +       priv->mode = mode;
>> +
>> +       return 0;
>> +}
>> +
>> +static const struct dm_spi_ops rockchip_spi_ops = {
>> +       .claim_bus      = rockchip_spi_claim_bus,
>> +       .release_bus    = rockchip_spi_release_bus,
>> +       .xfer           = rockchip_spi_xfer,
>> +       .set_speed      = rockchip_spi_set_speed,
>> +       .set_mode       = rockchip_spi_set_mode,
>> +       /*
>> +        * cs_info is not needed, since we require all chip selects to be
>> +        * in the device tree explicitly
>> +        */
>> +};
>> +
>> +static const struct udevice_id rockchip_spi_ids[] = {
>> +       { .compatible = "rockchip,rk3288-spi" },
>> +       { }
>> +};
>> +
>> +U_BOOT_DRIVER(rockchip_spi) = {
>> +       .name   = "rockchip_spi",
>> +       .id     = UCLASS_SPI,
>> +       .of_match = rockchip_spi_ids,
>> +       .ops    = &rockchip_spi_ops,
>> +       .ofdata_to_platdata = rockchip_spi_ofdata_to_platdata,
>> +       .platdata_auto_alloc_size = sizeof(struct rockchip_spi_platdata),
>> +       .priv_auto_alloc_size = sizeof(struct rockchip_spi_priv),
>> +       .probe  = rockchip_spi_probe,
>> +};

[snip]

Regards,
Simon

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

* [U-Boot] [PATCH v5 01/41] pinctrl: Add help text to Kconfig
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 01/41] pinctrl: Add help text to Kconfig Simon Glass
@ 2015-09-03 17:57   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:57 UTC (permalink / raw)
  To: u-boot

On 30 August 2015 at 16:55, Simon Glass <sjg@chromium.org> wrote:
> The pinctrl Kconfig options should have help messages. Add this to a few
> options.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v5:
> - Merge with Masahiro's v5 patch
>
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
>
>  drivers/pinctrl/Kconfig | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 02/41] pinctrl: Add the concept of peripheral IDs
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 02/41] pinctrl: Add the concept of peripheral IDs Simon Glass
@ 2015-09-03 17:57   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:57 UTC (permalink / raw)
  To: u-boot

On 30 August 2015 at 16:55, Simon Glass <sjg@chromium.org> wrote:
> My original pinctrl patch operating using a peripheral ID enum. This was
> shared between pinmux and clock and provides an easy way to specify a device
> that needs to be controlled, even it is does not (yet) have a driver within
> driver model.
>
> Masahiro's new simple pinctrl gets around this by providing a
> set_state_simple() pinctrl method. By passing a device to that call the
> peripheral ID becomes unnecessary. If the driver needs it, it can calculate
> it itself and use it internally.
>
> However this does not solve the problem for peripheral clocks. The 'pure'
> solution would be to pass a driver to the clock uclass also. But this
> requires that all devices should have a driver, and a struct udevide. Also
> a key optimisation of the clock uclass is allowing a peripheral clock to
> be set even when there is no device for that clock.
>
> There may be a better way to achive the same goal, but for now it seems
> expedient to add in peripheral ID to the pinctrl uclass. Two methods are
> added - one to get the peripheral ID and one to select it. The existing
> set_state_simple() is effectively the union of these.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v5:
> - Rebase on top of Masahiro's v5 series
>
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
>
>  drivers/pinctrl/pinctrl-uclass.c | 40 +++++++++++++++++++++------
>  include/dm/pinctrl.h             | 60 ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 91 insertions(+), 9 deletions(-)

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 03/41] dm: led: Tidy up SPL options for the led and led-gpio
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 03/41] dm: led: Tidy up SPL options for the led and led-gpio Simon Glass
@ 2015-09-03 17:57   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:57 UTC (permalink / raw)
  To: u-boot

On 30 August 2015 at 16:55, Simon Glass <sjg@chromium.org> wrote:
> At present SPL does not have its own option. But these features can
> increase SPL code size. Adjust the Kconfig and Makefile so that
> separate a SPL option can be selected.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v5:
> - Add new patch to tidy up SPL options for the led and led-gpio
>
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
>
>  drivers/led/Kconfig  | 9 ++++++++-
>  drivers/led/Makefile | 4 ++--
>  2 files changed, 10 insertions(+), 3 deletions(-)

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 04/41] mmc: Support bypass mode with the get_mmc_clk() method
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 04/41] mmc: Support bypass mode with the get_mmc_clk() method Simon Glass
@ 2015-09-03 17:58   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:58 UTC (permalink / raw)
  To: u-boot

On 30 August 2015 at 16:55, Simon Glass <sjg@chromium.org> wrote:
> Some SoCs want to adjust the input clock to the DWMMC block as a way of
> controlling the MMC bus clock. Update the get_mmc_clk() method to support
> this.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Acked-by: Jaehoon Chung <jh80.chung@samsung.com>
> ---
>
> Changes in v5: None
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
>
>  drivers/mmc/dw_mmc.c        |  2 +-
>  drivers/mmc/exynos_dw_mmc.c |  2 +-
>  include/dwmmc.h             | 16 +++++++++++++++-
>  3 files changed, 17 insertions(+), 3 deletions(-)

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 05/41] dm: Improve handling of a missing uclass
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 05/41] dm: Improve handling of a missing uclass Simon Glass
@ 2015-09-03 17:58   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:58 UTC (permalink / raw)
  To: u-boot

On 30 August 2015 at 16:55, Simon Glass <sjg@chromium.org> wrote:
> When a uclass definition is missing, no drivers in that uclass can operate.
> This can happen if a board has a strange collection of options (e.g. the
> driver is enabled but the uclass is not).
>
> Unfortunately this is very confusing at present. Starting up driver model
> results in a -ENOENT error, which is pretty generic. Quite a big of digging
> is needed to get to the root cause.
>
> To help with this, change the error to a very strange one with no other
> users in U-Boot. Also add a debug message.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v5: None
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
>
>  drivers/core/device.c | 4 +++-
>  drivers/core/uclass.c | 7 ++++++-
>  2 files changed, 9 insertions(+), 2 deletions(-)

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 06/41] dm: Provide better debugging when a device fails to bind
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 06/41] dm: Provide better debugging when a device fails to bind Simon Glass
@ 2015-09-03 17:58   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:58 UTC (permalink / raw)
  To: u-boot

On 30 August 2015 at 16:55, Simon Glass <sjg@chromium.org> wrote:
> All devices should bind without error. But when they don't, they can cause
> driver model init to fail. A real situation where this can happen is when
> there is a missing uclass.
>
> Add a debug() call to dm_scan_fdt_node to make this easier to track.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v5: None
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
>
>  drivers/core/root.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 07/41] arm: reset: Avoid a build error when the reset uclass is enabled
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 07/41] arm: reset: Avoid a build error when the reset uclass is enabled Simon Glass
@ 2015-09-03 17:58   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:58 UTC (permalink / raw)
  To: u-boot

On 30 August 2015 at 16:55, Simon Glass <sjg@chromium.org> wrote:
> There can be only one do_reset(). When CONFIG_RESET is enabled this is
> provided by the reset uclass, and ARM's version should be disabled.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v5: None
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
>
>  arch/arm/lib/Makefile | 2 ++
>  1 file changed, 2 insertions(+)

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 08/41] rockchip: Add serial support
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 08/41] rockchip: Add serial support Simon Glass
@ 2015-09-03 17:58   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:58 UTC (permalink / raw)
  To: u-boot

On 30 August 2015 at 16:55, Simon Glass <sjg@chromium.org> wrote:
> Add support for the Rockchip serial device using the ns16550 driver.
> This uses driver model and device tree for both SPL and U-Boot proper.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v5: None
> Changes in v4: None
> Changes in v3:
> - Update clock rate to always be 24MHz
>
> Changes in v2: None
>
>  drivers/serial/Kconfig           |  9 +++++++++
>  drivers/serial/Makefile          |  1 +
>  drivers/serial/serial_rockchip.c | 43 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 53 insertions(+)
>  create mode 100644 drivers/serial/serial_rockchip.c

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 09/41] rockchip: Bring in RK3288 device tree file includes and bindings
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 09/41] rockchip: Bring in RK3288 device tree file includes and bindings Simon Glass
@ 2015-09-03 17:58   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:58 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 10/41] rockchip: rk3288: dts: Make core devices available early
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 10/41] rockchip: rk3288: dts: Make core devices available early Simon Glass
@ 2015-09-03 17:58   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:58 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 11/41] mkimage: Allow padding to any length
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 11/41] mkimage: Allow padding to any length Simon Glass
@ 2015-09-03 17:58   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:58 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 12/41] mkimage: Allow the original file size to be recorded
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 12/41] mkimage: Allow the original file size to be recorded Simon Glass
@ 2015-09-03 17:58   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:58 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 13/41] rockchip: Add the rkimage format to mkimage
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 13/41] rockchip: Add the rkimage format to mkimage Simon Glass
@ 2015-09-03 17:58   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:58 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 14/41] rockchip: Add support for the SD image
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 14/41] rockchip: Add support for the SD image Simon Glass
@ 2015-09-03 17:58   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:58 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 15/41] rockchip: Add support for the SPI image
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 15/41] rockchip: Add support for the SPI image Simon Glass
@ 2015-09-03 17:59   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:59 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 16/41] rockchip: gpio: Add rockchip GPIO driver
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 16/41] rockchip: gpio: Add rockchip GPIO driver Simon Glass
@ 2015-09-03 17:59   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:59 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 17/41] rockchip: Add basic peripheral and clock definitions
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 17/41] rockchip: Add basic peripheral and clock definitions Simon Glass
@ 2015-09-03 17:59   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:59 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 18/41] power: Add support for ACT8846 PMIC
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 18/41] power: Add support for ACT8846 PMIC Simon Glass
@ 2015-09-03 17:59   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:59 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 19/41] power: regulator: Add a driver for ACT8846 regulators
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 19/41] power: regulator: Add a driver for ACT8846 regulators Simon Glass
@ 2015-09-03 17:59   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:59 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 20/41] rockchip: rk3288: Add clock driver
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 20/41] rockchip: rk3288: Add clock driver Simon Glass
@ 2015-09-03 17:59   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:59 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 21/41] rockchip: rk3288: Add header files for PMU and GRF
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 21/41] rockchip: rk3288: Add header files for PMU and GRF Simon Glass
@ 2015-09-03 17:59   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:59 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 22/41] rockchip: rk3288: Add SoC reset driver
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 22/41] rockchip: rk3288: Add SoC reset driver Simon Glass
@ 2015-09-03 17:59   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:59 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 23/41] rockchip: rk3288: Add a simple syscon driver
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 23/41] rockchip: rk3288: Add a simple syscon driver Simon Glass
@ 2015-09-03 17:59   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:59 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 24/41] rockchip: rk3288: Add pinctrl driver
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 24/41] rockchip: rk3288: Add pinctrl driver Simon Glass
@ 2015-09-03 17:59   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:59 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 25/41] rockchip: rk3288: Add SDRAM init
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 25/41] rockchip: rk3288: Add SDRAM init Simon Glass
@ 2015-09-03 17:59   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:59 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 26/41] rockchip: Add an MMC driver
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 26/41] rockchip: Add an MMC driver Simon Glass
@ 2015-09-03 17:59   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 17:59 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 27/41] rockchip: Add core SoC start-up code
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 27/41] rockchip: Add core SoC start-up code Simon Glass
@ 2015-09-03 18:00   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 18:00 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 28/41] rockchip: Add I2C driver
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 28/41] rockchip: Add I2C driver Simon Glass
@ 2015-09-03 18:00   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 18:00 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 30/41] rockchip: Add basic support for firefly-rk3288
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 30/41] rockchip: Add basic support for firefly-rk3288 Simon Glass
@ 2015-09-03 18:00   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 18:00 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 31/41] rockchip: Add basic support for jerry
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 31/41] rockchip: Add basic support for jerry Simon Glass
@ 2015-09-03 18:00   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 18:00 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 32/41] rockchip: Add a simple README
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 32/41] rockchip: Add a simple README Simon Glass
@ 2015-09-03 18:00   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 18:00 UTC (permalink / raw)
  To: u-boot

Applied to u-boot-rockchip.

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

* [U-Boot] [PATCH v5 34/41] mmc: Probe DM based mmc devices in u-boot
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 34/41] mmc: Probe DM based mmc devices in u-boot Simon Glass
@ 2015-09-03 18:00   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 18:00 UTC (permalink / raw)
  To: u-boot

On 30 August 2015 at 16:55, Simon Glass <sjg@chromium.org> wrote:
> From: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
>
> During mmc initialize probe all devices with the MMC Uclass if build
> with CONFIG_DM_MMC
>
> Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
> Acked-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v5: None
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
>
>  drivers/mmc/mmc.c | 43 +++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 39 insertions(+), 4 deletions(-)

Applied to u-boot-rockchip, thanks!

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

* [U-Boot] [PATCH v5 33/41] doc: Fix reference to Rock pro when Rock 2 is meant
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 33/41] doc: Fix reference to Rock pro when Rock 2 is meant Simon Glass
@ 2015-09-03 18:00   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 18:00 UTC (permalink / raw)
  To: u-boot

On 30 August 2015 at 16:55, Simon Glass <sjg@chromium.org> wrote:
> From: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
>
> The Radxa Rock pro board is rk3188 based and thus won't work with U-Boot
> built for RK3288. Change the documentation to refer to the intended
> board, the Radxa Rock 2, which is an RK3288-based design very similar to
> the firefly
>
> Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
> Acked-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v5: None
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
>
>  doc/README.rockchip | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)

Applied to u-boot-rockchip, thanks!

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

* [U-Boot] [PATCH v5 35/41] rockchip: Disable sdio mmc slot on rk3288-firefly
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 35/41] rockchip: Disable sdio mmc slot on rk3288-firefly Simon Glass
@ 2015-09-03 18:00   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 18:00 UTC (permalink / raw)
  To: u-boot

On 30 August 2015 at 16:55, Simon Glass <sjg@chromium.org> wrote:
> From: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
>
> U-Boot can't use the sdio card so turn it of to prevent things getting
> confused/struck when trying to use the card as storage.
>
> Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
> Acked-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v5: None
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
>
>  arch/arm/dts/rk3288-firefly.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Applied to u-boot-rockchip, thanks!

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

* [U-Boot] [PATCH v5 36/41] rockchip: Turn off CONFIG_SPL_LED for firefly
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 36/41] rockchip: Turn off CONFIG_SPL_LED for firefly Simon Glass
@ 2015-09-03 18:00   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 18:00 UTC (permalink / raw)
  To: u-boot

On 30 August 2015 at 16:55, Simon Glass <sjg@chromium.org> wrote:
> From: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
>
> With LED support enabled the SPL easily goes over the size limit (e.g.
> with both Debians gcc 4.9 and 5.2 cross-compilers). Turn off LED support
> in the SPL to reduce the size just enough for those compilers.
>
> Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
> Tweaked commit subject to remove _SUPPORT
> Signed-off-by: Simon Glass <sjg@chromium.org>
>
> ---
>
> Changes in v5: None
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
>
>  configs/firefly-rk3288_defconfig | 1 -
>  1 file changed, 1 deletion(-)

Applied to u-boot-rockchip, thanks!

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

* [U-Boot] [PATCH v5 37/41] rockchip: Add config_distro_bootcmd support
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 37/41] rockchip: Add config_distro_bootcmd support Simon Glass
@ 2015-09-03 18:00   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 18:00 UTC (permalink / raw)
  To: u-boot

On 30 August 2015 at 16:55, Simon Glass <sjg@chromium.org> wrote:
> From: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
>
> Now that MMC works in U-Boot add config distro command support to start
> Linux in a standard fashion. One oddity here is that linux fails to load
> when the fdt is relocated to above 512MB, so set fdt_high to make sure it's
> loaded below that.
>
> Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
> Acked-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v5: None
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
>
>  include/configs/rk3288_common.h | 21 +++++++++++++++++++++
>  1 file changed, 21 insertions(+)

Applied to u-boot-rockchip, thanks!

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

* [U-Boot] [PATCH v5 38/41] arm: Turn of d-cache before i-cache
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 38/41] arm: Turn of d-cache before i-cache Simon Glass
@ 2015-09-03 18:00   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 18:00 UTC (permalink / raw)
  To: u-boot

On 30 August 2015 at 16:55, Simon Glass <sjg@chromium.org> wrote:
> From: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
>
> Booting the kernel fails on RK3288 (and probably other rockchip SoCs)
> when the i-cache is disabled/flushed before d-cache.
>
> I have not investigated whether this is due to U-Boot hanging or whether
> it's very early in the linux boot, but following the approach of the
> various rockchip U-Boot forks (first disable d-cache then i-cache) makes
> things work.
>
> Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v5: None
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
>
>  arch/arm/cpu/armv7/cpu.c | 15 +++++++++------
>  1 file changed, 9 insertions(+), 6 deletions(-)

I have not seen any comments on this patch. It looks safe and more
correct to me. Please chime in if you see problem.

Applied to u-boot-rockchip, thanks!

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

* [U-Boot] [PATCH v5 39/41] rockchip: Drop first 32kb of zeros from the rkSD image type
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 39/41] rockchip: Drop first 32kb of zeros from the rkSD image type Simon Glass
@ 2015-09-03 18:00   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 18:00 UTC (permalink / raw)
  To: u-boot

On 30 August 2015 at 16:55, Simon Glass <sjg@chromium.org> wrote:
> From: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
>
> Instead of creating a rockchip SPL SD card image with 32KB of zeros
> which can be written to the start of an SD card, create the images with
> only the useful data that should be written to an offset of 32KB on the
> SD card.
>
> The first 32 kilobytes aren't needed for bootup and only serve as
> convenient way of accidentally obliterating your partition table.
>
> Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
> Acked-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v5: None
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
>
>  doc/README.rockchip | 2 +-
>  tools/rksd.c        | 9 ++-------
>  2 files changed, 3 insertions(+), 8 deletions(-)

Applied to u-boot-rockchip, thanks!

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

* [U-Boot] [PATCH v5 40/41] rockchip: Update todo in README.rockchip
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 40/41] rockchip: Update todo in README.rockchip Simon Glass
@ 2015-09-03 18:00   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 18:00 UTC (permalink / raw)
  To: u-boot

On 30 August 2015 at 16:55, Simon Glass <sjg@chromium.org> wrote:
> From: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
>
> MMC support works now, so it can be dropped from the todo
>
> Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
> Acked-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v5: None
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
>
>  doc/README.rockchip | 1 -
>  1 file changed, 1 deletion(-)

Applied to u-boot-rockchip, thanks!

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

* [U-Boot] [PATCH v5 41/41] rockchip: Put README image creation commands on one line
  2015-08-30 22:55 ` [U-Boot] [PATCH v5 41/41] rockchip: Put README image creation commands on one line Simon Glass
@ 2015-09-03 18:00   ` Simon Glass
  0 siblings, 0 replies; 84+ messages in thread
From: Simon Glass @ 2015-09-03 18:00 UTC (permalink / raw)
  To: u-boot

On 30 August 2015 at 16:55, Simon Glass <sjg@chromium.org> wrote:
> It is easier to paste these into the command line if they are a single
> common. Use line continuation instead of separate lines.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v5:
> - Add new patch to put README image creation commands on one line
>
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
>
>  doc/README.rockchip | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)

Applied to u-boot-rockchip, thanks!

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

end of thread, other threads:[~2015-09-03 18:00 UTC | newest]

Thread overview: 84+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-30 22:55 [U-Boot] [PATCH v5 00/41] dm: Introduce Rockchip RK3288 support Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 01/41] pinctrl: Add help text to Kconfig Simon Glass
2015-09-03 17:57   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 02/41] pinctrl: Add the concept of peripheral IDs Simon Glass
2015-09-03 17:57   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 03/41] dm: led: Tidy up SPL options for the led and led-gpio Simon Glass
2015-09-03 17:57   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 04/41] mmc: Support bypass mode with the get_mmc_clk() method Simon Glass
2015-09-03 17:58   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 05/41] dm: Improve handling of a missing uclass Simon Glass
2015-09-03 17:58   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 06/41] dm: Provide better debugging when a device fails to bind Simon Glass
2015-09-03 17:58   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 07/41] arm: reset: Avoid a build error when the reset uclass is enabled Simon Glass
2015-09-03 17:58   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 08/41] rockchip: Add serial support Simon Glass
2015-09-03 17:58   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 09/41] rockchip: Bring in RK3288 device tree file includes and bindings Simon Glass
2015-09-03 17:58   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 10/41] rockchip: rk3288: dts: Make core devices available early Simon Glass
2015-09-03 17:58   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 11/41] mkimage: Allow padding to any length Simon Glass
2015-09-03 17:58   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 12/41] mkimage: Allow the original file size to be recorded Simon Glass
2015-09-03 17:58   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 13/41] rockchip: Add the rkimage format to mkimage Simon Glass
2015-09-03 17:58   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 14/41] rockchip: Add support for the SD image Simon Glass
2015-09-03 17:58   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 15/41] rockchip: Add support for the SPI image Simon Glass
2015-09-03 17:59   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 16/41] rockchip: gpio: Add rockchip GPIO driver Simon Glass
2015-09-03 17:59   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 17/41] rockchip: Add basic peripheral and clock definitions Simon Glass
2015-09-03 17:59   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 18/41] power: Add support for ACT8846 PMIC Simon Glass
2015-09-03 17:59   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 19/41] power: regulator: Add a driver for ACT8846 regulators Simon Glass
2015-09-03 17:59   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 20/41] rockchip: rk3288: Add clock driver Simon Glass
2015-09-03 17:59   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 21/41] rockchip: rk3288: Add header files for PMU and GRF Simon Glass
2015-09-03 17:59   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 22/41] rockchip: rk3288: Add SoC reset driver Simon Glass
2015-09-03 17:59   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 23/41] rockchip: rk3288: Add a simple syscon driver Simon Glass
2015-09-03 17:59   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 24/41] rockchip: rk3288: Add pinctrl driver Simon Glass
2015-09-03 17:59   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 25/41] rockchip: rk3288: Add SDRAM init Simon Glass
2015-09-03 17:59   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 26/41] rockchip: Add an MMC driver Simon Glass
2015-09-03 17:59   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 27/41] rockchip: Add core SoC start-up code Simon Glass
2015-09-03 18:00   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 28/41] rockchip: Add I2C driver Simon Glass
2015-09-03 18:00   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 29/41] rockchip: Add SPI driver Simon Glass
2015-09-01  5:23   ` Jagan Teki
2015-09-02  1:03     ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 30/41] rockchip: Add basic support for firefly-rk3288 Simon Glass
2015-09-03 18:00   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 31/41] rockchip: Add basic support for jerry Simon Glass
2015-09-03 18:00   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 32/41] rockchip: Add a simple README Simon Glass
2015-09-03 18:00   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 33/41] doc: Fix reference to Rock pro when Rock 2 is meant Simon Glass
2015-09-03 18:00   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 34/41] mmc: Probe DM based mmc devices in u-boot Simon Glass
2015-09-03 18:00   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 35/41] rockchip: Disable sdio mmc slot on rk3288-firefly Simon Glass
2015-09-03 18:00   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 36/41] rockchip: Turn off CONFIG_SPL_LED for firefly Simon Glass
2015-09-03 18:00   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 37/41] rockchip: Add config_distro_bootcmd support Simon Glass
2015-09-03 18:00   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 38/41] arm: Turn of d-cache before i-cache Simon Glass
2015-09-03 18:00   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 39/41] rockchip: Drop first 32kb of zeros from the rkSD image type Simon Glass
2015-09-03 18:00   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 40/41] rockchip: Update todo in README.rockchip Simon Glass
2015-09-03 18:00   ` Simon Glass
2015-08-30 22:55 ` [U-Boot] [PATCH v5 41/41] rockchip: Put README image creation commands on one line Simon Glass
2015-09-03 18:00   ` Simon Glass

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