* [U-Boot] [PATCH v2 01/17] rockchip: add timer driver
2015-11-04 12:53 [U-Boot] [PATCH v2 00/17] Lin Huang
@ 2015-11-04 12:53 ` Lin Huang
2015-11-04 12:53 ` [U-Boot] [PATCH v2 02/17] rockchip: move SYS_MALLOC_F_LEN to rk3288 own Kconfig Lin Huang
` (15 subsequent siblings)
16 siblings, 0 replies; 21+ messages in thread
From: Lin Huang @ 2015-11-04 12:53 UTC (permalink / raw)
To: u-boot
some rockchip soc will not include lib/timer.c in SPL stage,
so implement timer driver for some soc can use us delay function in SPL.
Signed-off-by: Lin Huang <hl@rock-chips.com>
---
Changes in v1: None
Changes in v2: add udelay function
arch/arm/include/asm/arch-rockchip/timer.h | 16 ++++++++++
arch/arm/mach-rockchip/Makefile | 1 +
arch/arm/mach-rockchip/board-spl.c | 21 ++-----------
arch/arm/mach-rockchip/rk_timer.c | 48 ++++++++++++++++++++++++++++++
include/configs/rk3288_common.h | 3 +-
5 files changed, 69 insertions(+), 20 deletions(-)
create mode 100644 arch/arm/include/asm/arch-rockchip/timer.h
create mode 100644 arch/arm/mach-rockchip/rk_timer.c
diff --git a/arch/arm/include/asm/arch-rockchip/timer.h b/arch/arm/include/asm/arch-rockchip/timer.h
new file mode 100644
index 0000000..db9e927
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/timer.h
@@ -0,0 +1,16 @@
+#ifndef __ASM_ARCH_TIMER_H
+#define __ASM_ARCH_TIMER_H
+
+struct rk_timer {
+ unsigned int timer_load_count0;
+ unsigned int timer_load_count1;
+ unsigned int timer_curr_value0;
+ unsigned int timer_curr_value1;
+ unsigned int timer_ctrl_reg;
+ unsigned int timer_int_status;
+};
+
+void rockchip_timer_init(void);
+void rockchip_udelay(unsigned int us);
+
+#endif
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 5a4e383..abe03a8 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -10,4 +10,5 @@ else
obj-y += board.o
endif
obj-y += common.o
+obj-y += rk_timer.o
obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288/
diff --git a/arch/arm/mach-rockchip/board-spl.c b/arch/arm/mach-rockchip/board-spl.c
index a241d96..8199cad 100644
--- a/arch/arm/mach-rockchip/board-spl.c
+++ b/arch/arm/mach-rockchip/board-spl.c
@@ -18,6 +18,7 @@
#include <asm/arch/hardware.h>
#include <asm/arch/periph.h>
#include <asm/arch/sdram.h>
+#include <asm/arch/timer.h>
#include <dm/pinctrl.h>
#include <dm/root.h>
#include <dm/test.h>
@@ -110,24 +111,6 @@ static void configure_l2ctlr(void)
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;
@@ -197,7 +180,7 @@ void board_init_f(ulong dummy)
hang();
}
- init_timer();
+ rockchip_timer_init();
configure_l2ctlr();
ret = uclass_get_device(UCLASS_CLK, 0, &dev);
diff --git a/arch/arm/mach-rockchip/rk_timer.c b/arch/arm/mach-rockchip/rk_timer.c
new file mode 100644
index 0000000..9afae41
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk_timer.c
@@ -0,0 +1,48 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm/arch/timer.h>
+#include <asm/io.h>
+#include <common.h>
+#include <linux/types.h>
+
+struct rk_timer * const timer_ptr = (void *)CONFIG_SYS_TIMER_BASE;
+
+static uint64_t rockchip_get_ticks(void)
+{
+ uint64_t timebase_h, timebase_l;
+
+ timebase_l = readl(&timer_ptr->timer_curr_value0);
+ timebase_h = readl(&timer_ptr->timer_curr_value1);
+
+ return (timebase_h << 32 | timebase_l);
+}
+
+static unsigned int usec_to_tick(unsigned long usec)
+{
+ unsigned int tick = usec;
+ tick *= CONFIG_SYS_TIMER_RATE / (1000 * 1000);
+ return tick;
+}
+
+void rockchip_udelay(unsigned int us)
+{
+ uint64_t tmp;
+
+ /* get current timestamp */
+ tmp = rockchip_get_ticks() + usec_to_tick(us);
+
+ /* loop till event */
+ while (rockchip_get_ticks() < tmp+1)
+ ;
+}
+
+void rockchip_timer_init(void)
+{
+ writel(0xffffffff, &timer_ptr->timer_load_count0);
+ writel(0xffffffff, &timer_ptr->timer_load_count1);
+ writel(1, &timer_ptr->timer_ctrl_reg);
+}
diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h
index e8aec28..2a7d7ac 100644
--- a/include/configs/rk3288_common.h
+++ b/include/configs/rk3288_common.h
@@ -24,7 +24,8 @@
#define CONFIG_DISPLAY_BOARDINFO
#define CONFIG_SYS_TIMER_RATE (24 * 1000 * 1000)
-#define CONFIG_SYS_TIMER_COUNTER (TIMER7_BASE + 8)
+#define CONFIG_SYS_TIMER_BASE 0xff810020 /* TIMER7 */
+#define CONFIG_SYS_TIMER_COUNTER (CONFIG_SYS_TIMER_BASE + 8)
#define CONFIG_SPL_FRAMEWORK
#define CONFIG_SPL_LIBCOMMON_SUPPORT
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [U-Boot] [PATCH v2 02/17] rockchip: move SYS_MALLOC_F_LEN to rk3288 own Kconfig
2015-11-04 12:53 [U-Boot] [PATCH v2 00/17] Lin Huang
2015-11-04 12:53 ` [U-Boot] [PATCH v2 01/17] rockchip: add timer driver Lin Huang
@ 2015-11-04 12:53 ` Lin Huang
2015-11-04 12:53 ` [U-Boot] [PATCH v2 03/17] rockchip: rename board-spl.c to rk3288-board-spl.c Lin Huang
` (14 subsequent siblings)
16 siblings, 0 replies; 21+ messages in thread
From: Lin Huang @ 2015-11-04 12:53 UTC (permalink / raw)
To: u-boot
since different rockchip SOC have different size of SRAM,
So the size SYS_MALLOC_F_LEN may different, so move this
config to rk3288 own Kconfig
Signed-off-by: Lin Huang <hl@rock-chips.com>
---
Changes in v1: None
Changes in v2: None
arch/arm/mach-rockchip/Kconfig | 3 ---
arch/arm/mach-rockchip/rk3288/Kconfig | 3 +++
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index ab50f4e..da665ef 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -12,9 +12,6 @@ config ROCKCHIP_RK3288
config SYS_MALLOC_F
default y
-config SYS_MALLOC_F_LEN
- default 0x800
-
config SPL_DM
default y
diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig
index 4d0f1b5..d0a7276 100644
--- a/arch/arm/mach-rockchip/rk3288/Kconfig
+++ b/arch/arm/mach-rockchip/rk3288/Kconfig
@@ -19,6 +19,9 @@ config TARGET_CHROMEBOOK_JERRY
config SYS_SOC
default "rockchip"
+config SYS_MALLOC_F_LEN
+ default 0x0800
+
source "board/google/chromebook_jerry/Kconfig"
source "board/firefly/firefly-rk3288/Kconfig"
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [U-Boot] [PATCH v2 03/17] rockchip: rename board-spl.c to rk3288-board-spl.c
2015-11-04 12:53 [U-Boot] [PATCH v2 00/17] Lin Huang
2015-11-04 12:53 ` [U-Boot] [PATCH v2 01/17] rockchip: add timer driver Lin Huang
2015-11-04 12:53 ` [U-Boot] [PATCH v2 02/17] rockchip: move SYS_MALLOC_F_LEN to rk3288 own Kconfig Lin Huang
@ 2015-11-04 12:53 ` Lin Huang
2015-11-04 12:53 ` [U-Boot] [PATCH v2 04/17] rockchip: add config decide whether to build common.c Lin Huang
` (13 subsequent siblings)
16 siblings, 0 replies; 21+ messages in thread
From: Lin Huang @ 2015-11-04 12:53 UTC (permalink / raw)
To: u-boot
since different rockchip soc need different spl file,
so rename board-spl.c.
Signed-off-by: Lin Huang <hl@rock-chips.com>
---
arch/arm/mach-rockchip/Makefile | 2 +-
arch/arm/mach-rockchip/board-spl.c | 270 ------------------------------
arch/arm/mach-rockchip/rk3288-board-spl.c | 270 ++++++++++++++++++++++++++++++
3 files changed, 271 insertions(+), 271 deletions(-)
delete mode 100644 arch/arm/mach-rockchip/board-spl.c
create mode 100644 arch/arm/mach-rockchip/rk3288-board-spl.c
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index abe03a8..7088711 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -5,7 +5,7 @@
#
ifdef CONFIG_SPL_BUILD
-obj-y += board-spl.o
+obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-spl.o
else
obj-y += board.o
endif
diff --git a/arch/arm/mach-rockchip/board-spl.c b/arch/arm/mach-rockchip/board-spl.c
deleted file mode 100644
index 8199cad..0000000
--- a/arch/arm/mach-rockchip/board-spl.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * (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 <asm/arch/timer.h>
-#include <dm/pinctrl.h>
-#include <dm/root.h>
-#include <dm/test.h>
-#include <dm/util.h>
-#include <power/regulator.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-u32 spl_boot_device(void)
-{
- 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);
-}
-
-static int configure_emmc(struct udevice *pinctrl)
-{
- struct gpio_desc desc;
- int ret;
-
- pinctrl_request_noflags(pinctrl, PERIPH_ID_EMMC);
-
- /*
- * TODO(sjg@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();
- }
-
- rockchip_timer_init();
- 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/rk3288-board-spl.c b/arch/arm/mach-rockchip/rk3288-board-spl.c
new file mode 100644
index 0000000..8199cad
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3288-board-spl.c
@@ -0,0 +1,270 @@
+/*
+ * (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 <asm/arch/timer.h>
+#include <dm/pinctrl.h>
+#include <dm/root.h>
+#include <dm/test.h>
+#include <dm/util.h>
+#include <power/regulator.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+u32 spl_boot_device(void)
+{
+ 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);
+}
+
+static int configure_emmc(struct udevice *pinctrl)
+{
+ struct gpio_desc desc;
+ int ret;
+
+ pinctrl_request_noflags(pinctrl, PERIPH_ID_EMMC);
+
+ /*
+ * TODO(sjg@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();
+ }
+
+ rockchip_timer_init();
+ 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();
+}
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [U-Boot] [PATCH v2 04/17] rockchip: add config decide whether to build common.c
2015-11-04 12:53 [U-Boot] [PATCH v2 00/17] Lin Huang
` (2 preceding siblings ...)
2015-11-04 12:53 ` [U-Boot] [PATCH v2 03/17] rockchip: rename board-spl.c to rk3288-board-spl.c Lin Huang
@ 2015-11-04 12:53 ` Lin Huang
2015-11-04 12:53 ` [U-Boot] [PATCH v2 05/17] dm: core: Add SPL Kconfig for REGMAP and SYSCON Lin Huang
` (12 subsequent siblings)
16 siblings, 0 replies; 21+ messages in thread
From: Lin Huang @ 2015-11-04 12:53 UTC (permalink / raw)
To: u-boot
some rockchips soc will not use uclass in SPL stage,
so define config to decide whether to build common.c
Signed-off-by: Lin Huang <hl@rock-chips.com>
---
arch/arm/mach-rockchip/Makefile | 2 +-
include/configs/rk3288_common.h | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 7088711..902235b 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -9,6 +9,6 @@ obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-spl.o
else
obj-y += board.o
endif
-obj-y += common.o
obj-y += rk_timer.o
+obj-$(CONFIG_$(SPL_)ROCKCHIP_COMMON) += common.o
obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288/
diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h
index 2a7d7ac..3823fbb 100644
--- a/include/configs/rk3288_common.h
+++ b/include/configs/rk3288_common.h
@@ -45,6 +45,9 @@
#define CONFIG_SPL_STACK 0xff718000
#define CONFIG_SPL_TEXT_BASE 0xff704004
+#define CONFIG_ROCKCHIP_COMMON
+#define CONFIG_SPL_ROCKCHIP_COMMON
+
/* MMC/SD IP block */
#define CONFIG_MMC
#define CONFIG_GENERIC_MMC
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [U-Boot] [PATCH v2 05/17] dm: core: Add SPL Kconfig for REGMAP and SYSCON
2015-11-04 12:53 [U-Boot] [PATCH v2 00/17] Lin Huang
` (3 preceding siblings ...)
2015-11-04 12:53 ` [U-Boot] [PATCH v2 04/17] rockchip: add config decide whether to build common.c Lin Huang
@ 2015-11-04 12:53 ` Lin Huang
2015-11-04 12:53 ` [U-Boot] [PATCH v2 06/17] rockchip: serial driver support rk3036 Lin Huang
` (11 subsequent siblings)
16 siblings, 0 replies; 21+ messages in thread
From: Lin Huang @ 2015-11-04 12:53 UTC (permalink / raw)
To: u-boot
Add SPL Kconfig for REGMAP and SYSCON, so REGMAP and SYSCON can
remove from SPL stage.
---
configs/chromebook_jerry_defconfig | 2 ++
configs/firefly-rk3288_defconfig | 2 ++
configs/sandbox_defconfig | 2 ++
drivers/core/Kconfig | 19 +++++++++++++++++++
drivers/core/Makefile | 4 ++--
5 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/configs/chromebook_jerry_defconfig b/configs/chromebook_jerry_defconfig
index 389dfd2..05ab984 100644
--- a/configs/chromebook_jerry_defconfig
+++ b/configs/chromebook_jerry_defconfig
@@ -14,7 +14,9 @@ CONFIG_SPL_OF_CONTROL=y
CONFIG_CLK=y
CONFIG_SPL_CLK=y
CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
CONFIG_RESET=y
CONFIG_LED=y
CONFIG_SPL_LED=y
diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig
index 5fe90b5..b202d6e 100644
--- a/configs/firefly-rk3288_defconfig
+++ b/configs/firefly-rk3288_defconfig
@@ -14,7 +14,9 @@ CONFIG_SPL_OF_CONTROL=y
CONFIG_CLK=y
CONFIG_SPL_CLK=y
CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
CONFIG_RESET=y
CONFIG_LED=y
CONFIG_LED_GPIO=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index e9e1597..008ec90 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -17,7 +17,9 @@ CONFIG_OF_CONTROL=y
CONFIG_OF_HOSTFILE=y
CONFIG_CLK=y
CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
CONFIG_DEVRES=y
CONFIG_DM_PCI=y
CONFIG_PCI_SANDBOX=y
diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
index 41f4e69..ee65884 100644
--- a/drivers/core/Kconfig
+++ b/drivers/core/Kconfig
@@ -72,6 +72,16 @@ config REGMAP
support any bus type (I2C, SPI) but so far this only supports
direct memory access.
+config SPL_REGMAP
+ bool "Support register maps in SPL"
+ depends on DM
+ help
+ Hardware peripherals tend to have one or more sets of registers
+ which can be accessed to control the hardware. A register map
+ models this with a simple read/write interface. It can in principle
+ support any bus type (I2C, SPI) but so far this only supports
+ direct memory access.
+
config SYSCON
bool "Support system controllers"
depends on REGMAP
@@ -81,6 +91,15 @@ config SYSCON
by this uclass, including accessing registers via regmap and
assigning a unique number to each.
+config SPL_SYSCON
+ bool "Support system controllers in SPL"
+ depends on REGMAP
+ help
+ Many SoCs have a number of system controllers which are dealt with
+ as a group by a single driver. Some common functionality is provided
+ by this uclass, including accessing registers via regmap and
+ assigning a unique number to each.
+
config DEVRES
bool "Managed device resources"
depends on DM
diff --git a/drivers/core/Makefile b/drivers/core/Makefile
index f19f67d..07adb61 100644
--- a/drivers/core/Makefile
+++ b/drivers/core/Makefile
@@ -9,5 +9,5 @@ obj-$(CONFIG_DEVRES) += devres.o
obj-$(CONFIG_$(SPL_)DM_DEVICE_REMOVE) += device-remove.o
obj-$(CONFIG_$(SPL_)SIMPLE_BUS) += simple-bus.o
obj-$(CONFIG_DM) += dump.o
-obj-$(CONFIG_REGMAP) += regmap.o
-obj-$(CONFIG_SYSCON) += syscon-uclass.o
+obj-$(CONFIG_$(SPL_)REGMAP) += regmap.o
+obj-$(CONFIG_$(SPL_)SYSCON) += syscon-uclass.o
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [U-Boot] [PATCH v2 06/17] rockchip: serial driver support rk3036
2015-11-04 12:53 [U-Boot] [PATCH v2 00/17] Lin Huang
` (4 preceding siblings ...)
2015-11-04 12:53 ` [U-Boot] [PATCH v2 05/17] dm: core: Add SPL Kconfig for REGMAP and SYSCON Lin Huang
@ 2015-11-04 12:53 ` Lin Huang
2015-11-04 12:53 ` [U-Boot] [PATCH v2 07/17] rockchip: Bring in RK3036 device tree file includes and bindings Lin Huang
` (10 subsequent siblings)
16 siblings, 0 replies; 21+ messages in thread
From: Lin Huang @ 2015-11-04 12:53 UTC (permalink / raw)
To: u-boot
Signed-off-by: Lin Huang <hl@rock-chips.com>
---
Changes in v1: None
Changes in v2:
- modify code suggest by Simon
drivers/serial/serial_rockchip.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/serial/serial_rockchip.c b/drivers/serial/serial_rockchip.c
index 0e7bbfc..21836bb 100644
--- a/drivers/serial/serial_rockchip.c
+++ b/drivers/serial/serial_rockchip.c
@@ -12,6 +12,7 @@
static const struct udevice_id rockchip_serial_ids[] = {
{ .compatible = "rockchip,rk3288-uart" },
+ { .compatible = "rockchip,rk3036-uart" },
{ }
};
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [U-Boot] [PATCH v2 07/17] rockchip: Bring in RK3036 device tree file includes and bindings
2015-11-04 12:53 [U-Boot] [PATCH v2 00/17] Lin Huang
` (5 preceding siblings ...)
2015-11-04 12:53 ` [U-Boot] [PATCH v2 06/17] rockchip: serial driver support rk3036 Lin Huang
@ 2015-11-04 12:53 ` Lin Huang
2015-11-04 12:53 ` [U-Boot] [PATCH v2 08/17] rockchip: rk3036: Add clock driver Lin Huang
` (9 subsequent siblings)
16 siblings, 0 replies; 21+ messages in thread
From: Lin Huang @ 2015-11-04 12:53 UTC (permalink / raw)
To: u-boot
Since rk3036 device tree file still in reviewing, bring it from
https://patchwork.kernel.org/patch/7203371/ and add some aliases
we need in uboot
Signed-off-by: Lin Huang <hl@rock-chips.com>
---
Changes in v1:
- clean copyright announcement
Changes in v2: None
arch/arm/dts/rk3036.dtsi | 427 +++++++++++++++++++++++++++++++++
include/dt-bindings/clock/rk3036-cru.h | 186 ++++++++++++++
2 files changed, 613 insertions(+)
create mode 100644 arch/arm/dts/rk3036.dtsi
create mode 100644 include/dt-bindings/clock/rk3036-cru.h
diff --git a/arch/arm/dts/rk3036.dtsi b/arch/arm/dts/rk3036.dtsi
new file mode 100644
index 0000000..e2f3ba9
--- /dev/null
+++ b/arch/arm/dts/rk3036.dtsi
@@ -0,0 +1,427 @@
+/*
+ * 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/rk3036-cru.h>
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "rockchip,rk3036";
+
+ interrupt-parent = <&gic>;
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ i2c1 = &i2c1;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ mmc0 = &emmc;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x60000000 0x40000000>;
+ };
+
+ arm-pmu {
+ compatible = "arm,cortex-a7-pmu";
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&cpu0>, <&cpu1>;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "rockchip,rk3036-smp";
+
+ cpu0: cpu at f00 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0xf00>;
+ operating-points = <
+ /* KHz uV */
+ 816000 1000000
+ >;
+ #cooling-cells = <2>; /* min followed by max */
+ clock-latency = <40000>;
+ clocks = <&cru ARMCLK>;
+ resets = <&cru SRST_CORE0>;
+ };
+ cpu1: cpu at f01 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0xf01>;
+ resets = <&cru SRST_CORE1>;
+ };
+ };
+
+ amba {
+ compatible = "arm,amba-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ pdma: pdma at 20078000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x20078000 0x4000>;
+ arm,pl330-broken-no-flushp;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ clocks = <&cru ACLK_DMAC2>;
+ clock-names = "apb_pclk";
+ };
+ };
+
+ xin24m: oscillator {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "xin24m";
+ #clock-cells = <0>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ arm,cpu-registers-not-fw-configured;
+ 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>;
+ };
+
+ cru: clock-controller at 20000000 {
+ compatible = "rockchip,rk3036-cru";
+ reg = <0x20000000 0x1000>;
+ rockchip,grf = <&grf>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ assigned-clocks = <&cru PLL_GPLL>;
+ assigned-clock-rates = <594000000>;
+ };
+
+ uart0: serial at 20060000 {
+ compatible = "rockchip,rk3036-uart", "snps,dw-apb-uart";
+ reg = <0x20060000 0x100>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+ clock-names = "baudclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+ };
+
+ uart1: serial at 20064000 {
+ compatible = "rockchip,rk3036-uart", "snps,dw-apb-uart";
+ reg = <0x20064000 0x100>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+ clock-names = "baudclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_xfer>;
+ };
+
+ uart2: serial at 20068000 {
+ compatible = "rockchip,rk3036-uart", "snps,dw-apb-uart";
+ reg = <0x20068000 0x100>;
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+ clock-names = "baudclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_xfer>;
+ };
+
+ pwm0: pwm at 20050000 {
+ compatible = "rockchip,rk2928-pwm";
+ reg = <0x20050000 0x10>;
+ #pwm-cells = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_pin>;
+ clocks = <&cru PCLK_PWM>;
+ clock-names = "pwm";
+ status = "disabled";
+ };
+
+ pwm1: pwm at 20050010 {
+ compatible = "rockchip,rk2928-pwm";
+ reg = <0x20050010 0x10>;
+ #pwm-cells = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm1_pin>;
+ clocks = <&cru PCLK_PWM>;
+ clock-names = "pwm";
+ status = "disabled";
+ };
+
+ pwm2: pwm at 20050020 {
+ compatible = "rockchip,rk2928-pwm";
+ reg = <0x20050020 0x10>;
+ #pwm-cells = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm2_pin>;
+ clocks = <&cru PCLK_PWM>;
+ clock-names = "pwm";
+ status = "disabled";
+ };
+
+ pwm3: pwm at 20050030 {
+ compatible = "rockchip,rk2928-pwm";
+ reg = <0x20050030 0x10>;
+ #pwm-cells = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3_pin>;
+ clocks = <&cru PCLK_PWM>;
+ clock-names = "pwm";
+ status = "disabled";
+ };
+
+ sram: sram at 10080000 {
+ compatible = "rockchip,rk3036-smp-sram", "mmio-sram";
+ reg = <0x10080000 0x2000>;
+ };
+
+ gic: interrupt-controller at 10139000 {
+ compatible = "arm,gic-400";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+
+ reg = <0x10139000 0x1000>,
+ <0x1013a000 0x1000>,
+ <0x1013c000 0x2000>,
+ <0x1013e000 0x2000>;
+ interrupts = <GIC_PPI 9 0xf04>;
+ };
+
+ grf: syscon at 20008000 {
+ compatible = "rockchip,rk3036-grf", "syscon";
+ reg = <0x20008000 0x1000>;
+ };
+
+ usb_otg: usb at 10180000 {
+ compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb",
+ "snps,dwc2";
+ reg = <0x10180000 0x40000>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_OTG0>;
+ clock-names = "otg";
+ dr_mode = "otg";
+ g-np-tx-fifo-size = <16>;
+ g-rx-fifo-size = <275>;
+ g-tx-fifo-size = <256 128 128 64 64 32>;
+ g-use-dma;
+ status = "disabled";
+ };
+
+ usb_host: usb at 101c0000 {
+ compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb",
+ "snps,dwc2";
+ reg = <0x101c0000 0x40000>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_OTG1>;
+ clock-names = "otg";
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ emmc: dwmmc at 1021c000 {
+ compatible = "rockchip,rk3288-dw-mshc";
+ clock-frequency = <37500000>;
+ clock-freq-min-max = <400000 37500000>;
+ clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
+ <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+ dmas = <&pdma 12>;
+ dma-names = "rx-tx";
+ fifo-depth = <0x100>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x1021c000 0x4000>;
+ broken-cd;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ mmc-ddr-1_8v;
+ disable-wp;
+ non-removable;
+ num-slots = <1>;
+ default-sample-phase = <158>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
+ };
+
+ pinctrl: pinctrl {
+ compatible = "rockchip,rk3036-pinctrl";
+ rockchip,grf = <&grf>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gpio0: gpio0 at 2007c000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x2007c000 0x100>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO0>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio1 at 20080000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20080000 0x100>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO1>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio2 at 20084000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20084000 0x100>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO2>;
+
+ 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;
+ };
+
+ emmc {
+ /*
+ * 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 = <2 4 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ emmc_cmd: emmc-cmd {
+ rockchip,pins = <2 1 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ emmc_bus8: emmc-bus8 {
+ rockchip,pins = <1 24 RK_FUNC_2 &pcfg_pull_none>,
+ <1 25 RK_FUNC_2 &pcfg_pull_none>,
+ <1 26 RK_FUNC_2 &pcfg_pull_none>,
+ <1 27 RK_FUNC_2 &pcfg_pull_none>;
+ /*
+ <1 28 RK_FUNC_2 &pcfg_pull_up>,
+ <1 29 RK_FUNC_2 &pcfg_pull_up>,
+ <1 30 RK_FUNC_2 &pcfg_pull_up>,
+ <1 31 RK_FUNC_2 &pcfg_pull_up>;
+ */
+ };
+ };
+
+ uart0 {
+ uart0_xfer: uart0-xfer {
+ rockchip,pins = <0 16 RK_FUNC_1 &pcfg_pull_none>,
+ <0 17 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_cts: uart0-cts {
+ rockchip,pins = <0 18 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_rts: uart0-rts {
+ rockchip,pins = <0 19 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart1 {
+ uart1_xfer: uart1-xfer {
+ rockchip,pins = <2 22 RK_FUNC_1 &pcfg_pull_none>,
+ <2 23 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ /* no rts / cts for uart1 */
+ };
+
+ uart2 {
+ uart2_xfer: uart2-xfer {
+ rockchip,pins = <1 18 RK_FUNC_2 &pcfg_pull_none>,
+ <1 19 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ /* no rts / cts for uart2 */
+ };
+
+ pwm0 {
+ pwm0_pin: pwm0-pin {
+ rockchip,pins = <0 0 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ pwm1 {
+ pwm1_pin: pwm1-pin {
+ rockchip,pins = <0 1 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ pwm2 {
+ pwm2_pin: pwm2-pin {
+ rockchip,pins = <0 1 2 &pcfg_pull_none>;
+ };
+ };
+
+ pwm3 {
+ pwm3_pin: pwm3-pin {
+ rockchip,pins = <0 27 1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c1 {
+ i2c1_xfer: i2c1-xfer {
+ rockchip,pins = <0 2 RK_FUNC_1 &pcfg_pull_none>,
+ <0 3 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+ };
+
+ i2c1: i2c at 20056000 {
+ compatible = "rockchip,rk3288-i2c";
+ reg = <0x20056000 0x1000>;
+ interrupts = <GIC_SPI 25 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";
+ };
+};
diff --git a/include/dt-bindings/clock/rk3036-cru.h b/include/dt-bindings/clock/rk3036-cru.h
new file mode 100644
index 0000000..87acf4a
--- /dev/null
+++ b/include/dt-bindings/clock/rk3036-cru.h
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2014 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3036_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3036_H
+
+/* core clocks */
+#define PLL_APLL 1
+#define PLL_DPLL 2
+#define PLL_GPLL 3
+#define ARMCLK 4
+
+/* sclk gates (special clocks) */
+#define SCLK_GPU 64
+#define SCLK_SPI 65
+#define SCLK_SDMMC 68
+#define SCLK_SDIO 69
+#define SCLK_EMMC 71
+#define SCLK_NANDC 76
+#define SCLK_UART0 77
+#define SCLK_UART1 78
+#define SCLK_UART2 79
+#define SCLK_I2S 82
+#define SCLK_SPDIF 83
+#define SCLK_TIMER0 85
+#define SCLK_TIMER1 86
+#define SCLK_TIMER2 87
+#define SCLK_TIMER3 88
+#define SCLK_OTGPHY0 93
+#define SCLK_LCDC 100
+#define SCLK_HDMI 109
+#define SCLK_HEVC 111
+#define SCLK_I2S_OUT 113
+#define SCLK_SDMMC_DRV 114
+#define SCLK_SDIO_DRV 115
+#define SCLK_EMMC_DRV 117
+#define SCLK_SDMMC_SAMPLE 118
+#define SCLK_SDIO_SAMPLE 119
+#define SCLK_EMMC_SAMPLE 121
+#define SCLK_PVTM_CORE 123
+#define SCLK_PVTM_GPU 124
+#define SCLK_PVTM_VIDEO 125
+#define SCLK_MAC 151
+#define SCLK_MACREF 152
+#define SCLK_SFC 160
+
+#define DCLK_LCDC 190
+
+/* aclk gates */
+#define ACLK_DMAC2 194
+#define ACLK_LCDC 197
+#define ACLK_VIO 203
+#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_GRF 329
+#define PCLK_I2C0 332
+#define PCLK_I2C1 333
+#define PCLK_I2C2 334
+#define PCLK_SPI 338
+#define PCLK_UART0 341
+#define PCLK_UART1 342
+#define PCLK_UART2 343
+#define PCLK_PWM 350
+#define PCLK_TIMER 353
+#define PCLK_HDMI 360
+#define PCLK_CPU 362
+#define PCLK_PERI 363
+#define PCLK_DDRUPCTL 364
+#define PCLK_WDT 368
+
+/* hclk gates */
+#define HCLK_OTG0 449
+#define HCLK_OTG1 450
+#define HCLK_NANDC 453
+#define HCLK_SDMMC 456
+#define HCLK_SDIO 457
+#define HCLK_EMMC 459
+#define HCLK_I2S 462
+#define HCLK_LCDC 465
+#define HCLK_ROM 467
+#define HCLK_VIO_BUS 472
+#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_CORE0_DBG 4
+#define SRST_CORE1_DBG 5
+#define SRST_CORE0_POR 8
+#define SRST_CORE1_POR 9
+#define SRST_L2C 12
+#define SRST_TOPDBG 13
+#define SRST_STRC_SYS_A 14
+#define SRST_PD_CORE_NIU 15
+
+#define SRST_TIMER2 16
+#define SRST_CPUSYS_H 17
+#define SRST_AHB2APB_H 19
+#define SRST_TIMER3 20
+#define SRST_INTMEM 21
+#define SRST_ROM 22
+#define SRST_PERI_NIU 23
+#define SRST_I2S 24
+#define SRST_DDR_PLL 25
+#define SRST_GPU_DLL 26
+#define SRST_TIMER0 27
+#define SRST_TIMER1 28
+#define SRST_CORE_DLL 29
+#define SRST_EFUSE_P 30
+#define SRST_ACODEC_P 31
+
+#define SRST_GPIO0 32
+#define SRST_GPIO1 33
+#define SRST_GPIO2 34
+#define SRST_UART0 39
+#define SRST_UART1 40
+#define SRST_UART2 41
+#define SRST_I2C0 43
+#define SRST_I2C1 44
+#define SRST_I2C2 45
+#define SRST_SFC 47
+
+#define SRST_PWM0 48
+#define SRST_DAP 51
+#define SRST_DAP_SYS 52
+#define SRST_GRF 55
+#define SRST_PERIPHSYS_A 57
+#define SRST_PERIPHSYS_H 58
+#define SRST_PERIPHSYS_P 59
+#define SRST_CPU_PERI 61
+#define SRST_EMEM_PERI 62
+#define SRST_USB_PERI 63
+
+#define SRST_DMA2 64
+#define SRST_MAC 66
+#define SRST_NANDC 68
+#define SRST_USBOTG0 69
+#define SRST_OTGC0 71
+#define SRST_USBOTG1 72
+#define SRST_OTGC1 74
+#define SRST_DDRMSCH 79
+
+#define SRST_MMC0 81
+#define SRST_SDIO 82
+#define SRST_EMMC 83
+#define SRST_SPI0 84
+#define SRST_WDT 86
+#define SRST_DDRPHY 88
+#define SRST_DDRPHY_P 89
+#define SRST_DDRCTRL 90
+#define SRST_DDRCTRL_P 91
+
+#define SRST_HDMI_P 96
+#define SRST_VIO_BUS_H 99
+#define SRST_UTMI0 103
+#define SRST_UTMI1 104
+#define SRST_USBPOR 105
+
+#define SRST_VCODEC_A 112
+#define SRST_VCODEC_H 113
+#define SRST_VIO1_A 114
+#define SRST_HEVC 115
+#define SRST_VCODEC_NIU_A 116
+#define SRST_LCDC1_A 117
+#define SRST_LCDC1_H 118
+#define SRST_LCDC1_D 119
+#define SRST_GPU 120
+#define SRST_GPU_NIU_A 122
+
+#define SRST_DBG_P 131
+
+#endif
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [U-Boot] [PATCH v2 08/17] rockchip: rk3036: Add clock driver
2015-11-04 12:53 [U-Boot] [PATCH v2 00/17] Lin Huang
` (6 preceding siblings ...)
2015-11-04 12:53 ` [U-Boot] [PATCH v2 07/17] rockchip: Bring in RK3036 device tree file includes and bindings Lin Huang
@ 2015-11-04 12:53 ` Lin Huang
2015-11-04 12:53 ` [U-Boot] [PATCH v2 09/17] rockchip: rk3036: Add header files for GRF Lin Huang
` (8 subsequent siblings)
16 siblings, 0 replies; 21+ messages in thread
From: Lin Huang @ 2015-11-04 12:53 UTC (permalink / raw)
To: u-boot
Add a driver for setting up and modifying the various PLLs, peripheral
clocks and mmc clocks on RK3036
Signed-off-by: Lin Huang <hl@rock-chips.com>
---
Changes in v1:
- clean copyright announcement
Changes in v2:
- move some macro to cru_rk3036.h
arch/arm/include/asm/arch-rockchip/cru_rk3036.h | 168 ++++++++++
drivers/clk/Makefile | 1 +
drivers/clk/clk_rk3036.c | 414 ++++++++++++++++++++++++
3 files changed, 583 insertions(+)
create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rk3036.h
create mode 100644 drivers/clk/clk_rk3036.c
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3036.h b/arch/arm/include/asm/arch-rockchip/cru_rk3036.h
new file mode 100644
index 0000000..7ecc8ee
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3036.h
@@ -0,0 +1,168 @@
+/*
+ * (C) Copyright 2015 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef _ASM_ARCH_CRU_RK3036_H
+#define _ASM_ARCH_CRU_RK3036_H
+
+#include <common.h>
+
+#define OSC_HZ (24 * 1000 * 1000)
+
+#define APLL_HZ (600 * 1000000)
+#define GPLL_HZ (594 * 1000000)
+
+#define CORE_PERI_HZ 150000000
+#define CORE_ACLK_HZ 300000000
+
+#define CPU_ACLK_HZ 150000000
+#define CPU_HCLK_HZ 300000000
+#define CPU_PCLK_HZ 300000000
+
+#define PERI_ACLK_HZ 148500000
+#define PERI_HCLK_HZ 148500000
+#define PERI_PCLK_HZ 74250000
+
+struct rk3036_cru {
+ struct rk3036_pll {
+ unsigned int con0;
+ unsigned int con1;
+ unsigned int con2;
+ unsigned int con3;
+ } pll[4];
+ unsigned int cru_mode_con;
+ unsigned int cru_clksel_con[35];
+ unsigned int cru_clkgate_con[11];
+ unsigned int reserved;
+ unsigned int cru_glb_srst_fst_value;
+ unsigned int cru_glb_srst_snd_value;
+ unsigned int reserved1[2];
+ unsigned int cru_softrst_con[9];
+ unsigned int cru_misc_con;
+ unsigned int reserved2[2];
+ unsigned int cru_glb_cnt_th;
+ unsigned int cru_sdmmc_con[2];
+ unsigned int cru_sdio_con[2];
+ unsigned int cru_emmc_con[2];
+ unsigned int reserved3;
+ unsigned int cru_rst_st;
+ unsigned int reserved4[0x23];
+ unsigned int cru_pll_mask_con;
+};
+check_member(rk3036_cru, cru_pll_mask_con, 0x01f0);
+
+struct pll_div {
+ u32 refdiv;
+ u32 fbdiv;
+ u32 postdiv1;
+ u32 postdiv2;
+ u32 frac;
+};
+
+enum {
+ /* PLLCON0*/
+ PLL_POSTDIV1_MASK = 7,
+ PLL_POSTDIV1_SHIFT = 12,
+ PLL_FBDIV_MASK = 0xfff,
+ PLL_FBDIV_SHIFT = 0,
+
+ /* PLLCON1 */
+ PLL_DSMPD_MASK = 1,
+ PLL_DSMPD_SHIFT = 12,
+ PLL_LOCK_STATUS_MASK = 1,
+ PLL_LOCK_STATUS_SHIFT = 10,
+ PLL_POSTDIV2_MASK = 7,
+ PLL_POSTDIV2_SHIFT = 6,
+ PLL_REFDIV_MASK = 0x3f,
+ PLL_REFDIV_SHIFT = 0,
+ PLL_RST_SHIFT = 14,
+
+ /* CRU_MODE */
+ GPLL_MODE_MASK = 3,
+ GPLL_MODE_SHIFT = 12,
+ GPLL_MODE_SLOW = 0,
+ GPLL_MODE_NORM,
+ GPLL_MODE_DEEP,
+ DPLL_MODE_MASK = 1,
+ DPLL_MODE_SHIFT = 4,
+ DPLL_MODE_SLOW = 0,
+ DPLL_MODE_NORM,
+ APLL_MODE_MASK = 1,
+ APLL_MODE_SHIFT = 0,
+ APLL_MODE_SLOW = 0,
+ APLL_MODE_NORM,
+
+ /* CRU_CLK_SEL0_CON */
+ CPU_CLK_PLL_SEL_MASK = 3,
+ CPU_CLK_PLL_SEL_SHIFT = 14,
+ CPU_CLK_PLL_SEL_APLL = 0,
+ CPU_CLK_PLL_SEL_DPLL,
+ CPU_CLK_PLL_SEL_GPLL,
+ ACLK_CPU_DIV_MASK = 0x1f,
+ ACLK_CPU_DIV_SHIFT = 8,
+ CORE_CLK_PLL_SEL_MASK = 1,
+ CORE_CLK_PLL_SEL_SHIFT = 7,
+ CORE_CLK_PLL_SEL_APLL = 0,
+ CORE_CLK_PLL_SEL_GPLL,
+ CORE_DIV_CON_MASK = 0x1f,
+ CORE_DIV_CON_SHIFT = 0,
+
+ /* CRU_CLK_SEL1_CON */
+ CPU_PCLK_DIV_MASK = 7,
+ CPU_PCLK_DIV_SHIFT = 12,
+ CPU_HCLK_DIV_MASK = 3,
+ CPU_HCLK_DIV_SHIFT = 8,
+ CORE_ACLK_DIV_MASK = 7,
+ CORE_ACLK_DIV_SHIFT = 4,
+ CORE_PERI_DIV_MASK = 0xf,
+ CORE_PERI_DIV_SHIFT = 0,
+
+ /* CRU_CLKSEL10_CON */
+ PERI_PLL_SEL_MASK = 3,
+ PERI_PLL_SEL_SHIFT = 14,
+ PERI_PLL_APLL = 0,
+ PERI_PLL_DPLL,
+ PERI_PLL_GPLL,
+ PERI_PCLK_DIV_MASK = 3,
+ PERI_PCLK_DIV_SHIFT = 12,
+ PERI_HCLK_DIV_MASK = 3,
+ PERI_HCLK_DIV_SHIFT = 8,
+ PERI_ACLK_DIV_MASK = 0x1f,
+ PERI_ACLK_DIV_SHIFT = 0,
+
+ /* CRU_CLKSEL11_CON */
+ SDIO_DIV_MASK = 0x7f,
+ SDIO_DIV_SHIFT = 8,
+ MMC0_DIV_MASK = 0x7f,
+ MMC0_DIV_SHIFT = 0,
+
+ /* CRU_CLKSEL12_CON */
+ EMMC_PLL_MASK = 3,
+ EMMC_PLL_SHIFT = 12,
+ EMMC_SEL_APLL = 0,
+ EMMC_SEL_DPLL,
+ EMMC_SEL_GPLL,
+ EMMC_SEL_24M,
+ SDIO_PLL_MASK = 3,
+ SDIO_PLL_SHIFT = 10,
+ SDIO_SEL_APLL = 0,
+ SDIO_SEL_DPLL,
+ SDIO_SEL_GPLL,
+ SDIO_SEL_24M,
+ MMC0_PLL_MASK = 3,
+ MMC0_PLL_SHIFT = 8,
+ MMC0_SEL_APLL = 0,
+ MMC0_SEL_DPLL,
+ MMC0_SEL_GPLL,
+ MMC0_SEL_24M,
+ EMMC_DIV_MASK = 0x7f,
+ EMMC_DIV_SHIFT = 0,
+
+ /* CRU_SOFTRST5_CON */
+ DDRCTRL_PSRST_SHIFT = 11,
+ DDRCTRL_SRST_SHIFT = 10,
+ DDRPHY_PSRST_SHIFT = 9,
+ DDRPHY_SRST_SHIFT = 8,
+};
+#endif
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 008ec10..4a6a4a8 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -6,5 +6,6 @@
#
obj-$(CONFIG_CLK) += clk-uclass.o
+obj-$(CONFIG_ROCKCHIP_RK3036) += clk_rk3036.o
obj-$(CONFIG_ROCKCHIP_RK3288) += clk_rk3288.o
obj-$(CONFIG_SANDBOX) += clk_sandbox.o
diff --git a/drivers/clk/clk_rk3036.c b/drivers/clk/clk_rk3036.c
new file mode 100644
index 0000000..6c802b6
--- /dev/null
+++ b/drivers/clk/clk_rk3036.c
@@ -0,0 +1,414 @@
+/*
+ * (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_rk3036.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/periph.h>
+#include <dm/lists.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct rk3036_clk_plat {
+ enum rk_clk_id clk_id;
+};
+
+struct rk3036_clk_priv {
+ struct rk3036_cru *cru;
+ ulong rate;
+};
+
+enum {
+ VCO_MAX_HZ = 2400U * 1000000,
+ VCO_MIN_HZ = 600 * 1000000,
+ OUTPUT_MAX_HZ = 2400U * 1000000,
+ OUTPUT_MIN_HZ = 24 * 1000000,
+};
+
+#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, _refdiv, _postdiv1, _postdiv2) {\
+ .refdiv = _refdiv,\
+ .fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\
+ .postdiv1 = _postdiv1, .postdiv2 = _postdiv2};\
+ _Static_assert(((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ) *\
+ OSC_HZ / (_refdiv * _postdiv1 * _postdiv2) == hz,\
+ #hz "Hz cannot be hit with PLL "\
+ "divisors on line " __stringify(__LINE__));
+
+/* use interge mode*/
+static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 3, 1);
+static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1);
+
+static inline unsigned int log2(unsigned int value)
+{
+ return fls(value) - 1;
+}
+
+static int rkclk_set_pll(struct rk3036_cru *cru, enum rk_clk_id clk_id,
+ const struct pll_div *div)
+{
+ int pll_id = rk_pll_id(clk_id);
+ struct rk3036_pll *pll = &cru->pll[pll_id];
+
+ /* All PLLs have same VCO and output frequency range restrictions. */
+ uint vco_hz = OSC_HZ / 1000 * div->fbdiv / div->refdiv * 1000;
+ uint output_hz = vco_hz / div->postdiv1 / div->postdiv2;
+
+ debug("PLL at %p: fbdiv=%d, refdiv=%d, postdiv1=%d, postdiv2=%d,\
+ vco=%u Hz, output=%u Hz\n",
+ pll, div->fbdiv, div->refdiv, div->postdiv1,
+ div->postdiv2, 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);
+
+ /* use interger mode */
+ rk_clrreg(&pll->con1, 1 << PLL_DSMPD_SHIFT);
+
+ rk_clrsetreg(&pll->con0,
+ PLL_POSTDIV1_MASK << PLL_POSTDIV1_SHIFT | PLL_FBDIV_MASK,
+ (div->postdiv1 << PLL_POSTDIV1_SHIFT) | div->fbdiv);
+ rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK << PLL_POSTDIV2_SHIFT |
+ PLL_REFDIV_MASK << PLL_REFDIV_SHIFT,
+ (div->postdiv2 << PLL_POSTDIV2_SHIFT |
+ div->refdiv << PLL_REFDIV_SHIFT));
+
+ /* waiting for pll lock */
+ while (readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT))
+ udelay(1);
+
+ return 0;
+}
+
+static void rkclk_init(struct rk3036_cru *cru)
+{
+ 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 |
+ APLL_MODE_MASK << APLL_MODE_SHIFT,
+ GPLL_MODE_SLOW << GPLL_MODE_SHIFT |
+ APLL_MODE_SLOW << APLL_MODE_SHIFT);
+
+ /* init pll */
+ rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg);
+ rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
+
+ /*
+ * select apll as core clock pll source and
+ * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+ * core hz : apll = 1:1
+ */
+ aclk_div = APLL_HZ / CORE_ACLK_HZ - 1;
+ assert((aclk_div + 1) * CORE_ACLK_HZ == APLL_HZ && aclk_div < 0x7);
+
+ pclk_div = APLL_HZ / CORE_PERI_HZ - 1;
+ assert((pclk_div + 1) * CORE_PERI_HZ == APLL_HZ && pclk_div < 0xf);
+
+ rk_clrsetreg(&cru->cru_clksel_con[0],
+ CORE_CLK_PLL_SEL_MASK << CORE_CLK_PLL_SEL_SHIFT |
+ CORE_DIV_CON_MASK << CORE_DIV_CON_SHIFT,
+ CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
+ 0 << CORE_DIV_CON_SHIFT);
+
+ rk_clrsetreg(&cru->cru_clksel_con[1],
+ CORE_ACLK_DIV_MASK << CORE_ACLK_DIV_SHIFT |
+ CORE_PERI_DIV_MASK << CORE_PERI_DIV_SHIFT,
+ aclk_div << CORE_ACLK_DIV_SHIFT |
+ pclk_div << CORE_PERI_DIV_SHIFT);
+
+ /*
+ * select apll as cpu clock pll source and
+ * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+ */
+ aclk_div = APLL_HZ / CPU_ACLK_HZ - 1;
+ assert((aclk_div + 1) * CPU_ACLK_HZ == APLL_HZ && aclk_div < 0x1f);
+
+ pclk_div = APLL_HZ / CPU_PCLK_HZ - 1;
+ assert((pclk_div + 1) * CPU_PCLK_HZ == APLL_HZ && pclk_div < 0x7);
+
+ hclk_div = APLL_HZ / CPU_HCLK_HZ - 1;
+ assert((hclk_div + 1) * CPU_HCLK_HZ == APLL_HZ && hclk_div < 0x3);
+
+ rk_clrsetreg(&cru->cru_clksel_con[0],
+ CPU_CLK_PLL_SEL_MASK << CPU_CLK_PLL_SEL_SHIFT |
+ ACLK_CPU_DIV_MASK << ACLK_CPU_DIV_SHIFT,
+ CPU_CLK_PLL_SEL_APLL << CPU_CLK_PLL_SEL_SHIFT |
+ aclk_div << ACLK_CPU_DIV_SHIFT);
+
+ rk_clrsetreg(&cru->cru_clksel_con[1],
+ CPU_PCLK_DIV_MASK << CPU_PCLK_DIV_SHIFT |
+ CPU_HCLK_DIV_MASK << CPU_HCLK_DIV_SHIFT,
+ pclk_div << CPU_PCLK_DIV_SHIFT |
+ hclk_div << CPU_HCLK_DIV_SHIFT);
+
+ /*
+ * select gpll as peri clock pll source and
+ * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+ */
+ aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1;
+ assert((aclk_div + 1) * PERI_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
+
+ hclk_div = log2(PERI_ACLK_HZ / PERI_HCLK_HZ);
+ assert((1 << hclk_div) * PERI_HCLK_HZ ==
+ PERI_ACLK_HZ && (pclk_div < 0x4));
+
+ pclk_div = log2(PERI_ACLK_HZ / PERI_PCLK_HZ);
+ assert((1 << pclk_div) * PERI_PCLK_HZ ==
+ PERI_ACLK_HZ && pclk_div < 0x8);
+
+ rk_clrsetreg(&cru->cru_clksel_con[10],
+ PERI_PLL_SEL_MASK << PERI_PLL_SEL_SHIFT |
+ PERI_PCLK_DIV_MASK << PERI_PCLK_DIV_SHIFT |
+ PERI_HCLK_DIV_MASK << PERI_HCLK_DIV_SHIFT |
+ PERI_ACLK_DIV_MASK << PERI_ACLK_DIV_SHIFT,
+ PERI_PLL_GPLL << PERI_PLL_SEL_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 |
+ APLL_MODE_MASK << APLL_MODE_SHIFT,
+ GPLL_MODE_NORM << GPLL_MODE_SHIFT |
+ APLL_MODE_NORM << APLL_MODE_SHIFT);
+}
+
+/* Get pll rate by id */
+static uint32_t rkclk_pll_get_rate(struct rk3036_cru *cru,
+ enum rk_clk_id clk_id)
+{
+ uint32_t refdiv, fbdiv, postdiv1, postdiv2;
+ uint32_t con;
+ int pll_id = rk_pll_id(clk_id);
+ struct rk3036_pll *pll = &cru->pll[pll_id];
+ static u8 clk_shift[CLK_COUNT] = {
+ 0xff, APLL_MODE_SHIFT, DPLL_MODE_SHIFT, 0xff,
+ GPLL_MODE_SHIFT, 0xff
+ };
+ static u8 clk_mask[CLK_COUNT] = {
+ 0xff, APLL_MODE_MASK, DPLL_MODE_MASK, 0xff,
+ GPLL_MODE_MASK, 0xff
+ };
+ uint shift;
+ uint mask;
+
+ con = readl(&cru->cru_mode_con);
+ shift = clk_shift[clk_id];
+ mask = clk_mask[clk_id];
+
+ switch ((con >> shift) & mask) {
+ case GPLL_MODE_SLOW:
+ return OSC_HZ;
+ case GPLL_MODE_NORM:
+
+ /* normal mode */
+ con = readl(&pll->con0);
+ postdiv1 = (con >> PLL_POSTDIV1_SHIFT) & PLL_POSTDIV1_MASK;
+ fbdiv = (con >> PLL_FBDIV_SHIFT) & PLL_FBDIV_MASK;
+ con = readl(&pll->con1);
+ postdiv2 = (con >> PLL_POSTDIV2_SHIFT) & PLL_POSTDIV2_MASK;
+ refdiv = (con >> PLL_REFDIV_SHIFT) & PLL_REFDIV_MASK;
+ return (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
+ case GPLL_MODE_DEEP:
+ default:
+ return 32768;
+ }
+}
+
+static ulong rockchip_mmc_get_clk(struct rk3036_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;
+ default:
+ return -EINVAL;
+ }
+
+ src_rate = mux == EMMC_SEL_24M ? OSC_HZ : clk_general_rate;
+ return DIV_TO_RATE(src_rate, div);
+}
+
+static ulong rockchip_mmc_set_clk(struct rk3036_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);
+
+ /* mmc clock auto divide 2 in internal */
+ src_clk_div = (clk_general_rate / 2 + freq - 1) / freq;
+
+ if (src_clk_div > 0x7f) {
+ src_clk_div = (OSC_HZ / 2 + freq - 1) / freq;
+ mux = EMMC_SEL_24M;
+ } else {
+ mux = EMMC_SEL_GPLL;
+ }
+
+ 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;
+ default:
+ return -EINVAL;
+ }
+
+ return rockchip_mmc_get_clk(cru, clk_general_rate, periph);
+}
+
+static ulong rk3036_clk_get_rate(struct udevice *dev)
+{
+ struct rk3036_clk_plat *plat = dev_get_platdata(dev);
+ struct rk3036_clk_priv *priv = dev_get_priv(dev);
+
+ debug("%s\n", dev->name);
+ return rkclk_pll_get_rate(priv->cru, plat->clk_id);
+}
+
+static ulong rk3036_clk_set_rate(struct udevice *dev, ulong rate)
+{
+ debug("%s\n", dev->name);
+
+ return 0;
+}
+
+ulong rk3036_set_periph_rate(struct udevice *dev, int periph, ulong rate)
+{
+ struct rk3036_clk_priv *priv = dev_get_priv(dev);
+ ulong new_rate;
+
+ switch (periph) {
+ case PERIPH_ID_EMMC:
+ new_rate = rockchip_mmc_set_clk(priv->cru, clk_get_rate(dev),
+ periph, rate);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return new_rate;
+}
+
+static struct clk_ops rk3036_clk_ops = {
+ .get_rate = rk3036_clk_get_rate,
+ .set_rate = rk3036_clk_set_rate,
+ .set_periph_rate = rk3036_set_periph_rate,
+};
+
+static int rk3036_clk_probe(struct udevice *dev)
+{
+ struct rk3036_clk_plat *plat = dev_get_platdata(dev);
+ struct rk3036_clk_priv *priv = dev_get_priv(dev);
+
+ if (plat->clk_id != CLK_OSC) {
+ struct rk3036_clk_priv *parent_priv = dev_get_priv(dev->parent);
+
+ priv->cru = parent_priv->cru;
+ return 0;
+ }
+ priv->cru = (struct rk3036_cru *)dev_get_addr(dev);
+ rkclk_init(priv->cru);
+
+ return 0;
+}
+
+static const char *const clk_name[] = {
+ "osc",
+ "apll",
+ "dpll",
+ "cpll",
+ "gpll",
+ "mpll",
+};
+
+static int rk3036_clk_bind(struct udevice *dev)
+{
+ struct rk3036_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 rk3036_clk_plat *cplat;
+
+ debug("%s %s\n", __func__, clk_name[pll]);
+ ret = device_bind_driver(dev, "clk_rk3036", 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, "rk3036_reset", "reset", &dev);
+ if (ret)
+ debug("Warning: No RK3036 reset driver: ret=%d\n", ret);
+
+ return 0;
+}
+
+static const struct udevice_id rk3036_clk_ids[] = {
+ { .compatible = "rockchip,rk3036-cru" },
+ { }
+};
+
+U_BOOT_DRIVER(clk_rk3036) = {
+ .name = "clk_rk3036",
+ .id = UCLASS_CLK,
+ .of_match = rk3036_clk_ids,
+ .priv_auto_alloc_size = sizeof(struct rk3036_clk_priv),
+ .platdata_auto_alloc_size = sizeof(struct rk3036_clk_plat),
+ .ops = &rk3036_clk_ops,
+ .bind = rk3036_clk_bind,
+ .probe = rk3036_clk_probe,
+};
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [U-Boot] [PATCH v2 09/17] rockchip: rk3036: Add header files for GRF
2015-11-04 12:53 [U-Boot] [PATCH v2 00/17] Lin Huang
` (7 preceding siblings ...)
2015-11-04 12:53 ` [U-Boot] [PATCH v2 08/17] rockchip: rk3036: Add clock driver Lin Huang
@ 2015-11-04 12:53 ` Lin Huang
2015-11-04 12:53 ` [U-Boot] [PATCH v2 10/17] rockchip: rk3036: Add Soc reset driver Lin Huang
` (7 subsequent siblings)
16 siblings, 0 replies; 21+ messages in thread
From: Lin Huang @ 2015-11-04 12:53 UTC (permalink / raw)
To: u-boot
GRF is the gereral register file. Add header files with register definitions.
Signed-off-by: Lin Huang <hl@rock-chips.com>
---
Changes in v1:
- clean copyright announcement
Changes in v2:
- move some macro to grf_rk3036.h
arch/arm/include/asm/arch-rockchip/grf_rk3036.h | 493 ++++++++++++++++++++++++
1 file changed, 493 insertions(+)
create mode 100644 arch/arm/include/asm/arch-rockchip/grf_rk3036.h
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3036.h b/arch/arm/include/asm/arch-rockchip/grf_rk3036.h
new file mode 100644
index 0000000..72d133c
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3036.h
@@ -0,0 +1,493 @@
+/*
+ * (C) Copyright 2015 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef _ASM_ARCH_GRF_RK3036_H
+#define _ASM_ARCH_GRF_RK3036_H
+
+#include <common.h>
+
+struct rk3036_grf {
+ unsigned int reserved[0x2a];
+ unsigned int gpio0a_iomux;
+ unsigned int gpio0b_iomux;
+ unsigned int gpio0c_iomux;
+ unsigned int gpio0d_iomux;
+
+ unsigned int gpio1a_iomux;
+ unsigned int gpio1b_iomux;
+ unsigned int gpio1c_iomux;
+ unsigned int gpio1d_iomux;
+
+ unsigned int gpio2a_iomux;
+ unsigned int gpio2b_iomux;
+ unsigned int gpio2c_iomux;
+ unsigned int gpio2d_iomux;
+
+ unsigned int reserved2[0x0a];
+ unsigned int gpiods;
+ unsigned int reserved3[0x05];
+ unsigned int gpio0l_pull;
+ unsigned int gpio0h_pull;
+ unsigned int gpio1l_pull;
+ unsigned int gpio1h_pull;
+ unsigned int gpio2l_pull;
+ unsigned int gpio2h_pull;
+ unsigned int reserved4[4];
+ unsigned int soc_con0;
+ unsigned int soc_con1;
+ unsigned int soc_con2;
+ unsigned int soc_status0;
+ unsigned int reserved5;
+ unsigned int soc_con3;
+ unsigned int reserved6;
+ unsigned int dmac_con0;
+ unsigned int dmac_con1;
+ unsigned int dmac_con2;
+ unsigned int reserved7[5];
+ unsigned int uoc0_con5;
+ unsigned int reserved8[4];
+ unsigned int uoc1_con4;
+ unsigned int uoc1_con5;
+ unsigned int reserved9;
+ unsigned int ddrc_stat;
+ unsigned int uoc_con6;
+ unsigned int soc_status1;
+ unsigned int cpu_con0;
+ unsigned int cpu_con1;
+ unsigned int cpu_con2;
+ unsigned int cpu_con3;
+ unsigned int reserved10;
+ unsigned int reserved11;
+ unsigned int cpu_status0;
+ unsigned int cpu_status1;
+ unsigned int os_reg[8];
+ unsigned int reserved12[6];
+ unsigned int dll_con[4];
+ unsigned int dll_status[4];
+ unsigned int dfi_wrnum;
+ unsigned int dfi_rdnum;
+ unsigned int dfi_actnum;
+ unsigned int dfi_timerval;
+ unsigned int nfi_fifo[4];
+ unsigned int reserved13[0x10];
+ unsigned int usbphy0_con[8];
+ unsigned int usbphy1_con[8];
+ unsigned int reserved14[0x10];
+ unsigned int chip_tag;
+ unsigned int sdmmc_det_cnt;
+};
+check_member(rk3036_grf, sdmmc_det_cnt, 0x304);
+
+/* GRF_GPIO0A_IOMUX */
+enum {
+ GPIO0A3_SHIFT = 6,
+ GPIO0A3_MASK = 1,
+ GPIO0A3_GPIO = 0,
+ GPIO0A3_I2C1_SDA,
+
+ GPIO0A2_SHIFT = 4,
+ GPIO0A2_MASK = 1,
+ GPIO0A2_GPIO = 0,
+ GPIO0A2_I2C1_SCL,
+
+ GPIO0A1_SHIFT = 2,
+ GPIO0A1_MASK = 3,
+ GPIO0A1_GPIO = 0,
+ GPIO0A1_I2C0_SDA,
+ GPIO0A1_PWM2,
+
+ GPIO0A0_SHIFT = 0,
+ GPIO0A0_MASK = 3,
+ GPIO0A0_GPIO = 0,
+ GPIO0A0_I2C0_SCL,
+ GPIO0A0_PWM1,
+
+};
+
+/* GRF_GPIO0B_IOMUX */
+enum {
+ GPIO0B6_SHIFT = 12,
+ GPIO0B6_MASK = 3,
+ GPIO0B6_GPIO = 0,
+ GPIO0B6_MMC1_D3,
+ GPIO0B6_I2S1_SCLK,
+
+ GPIO0B5_SHIFT = 10,
+ GPIO0B5_MASK = 3,
+ GPIO0B5_GPIO = 0,
+ GPIO0B5_MMC1_D2,
+ GPIO0B5_I2S1_SDI,
+
+ GPIO0B4_SHIFT = 8,
+ GPIO0B4_MASK = 3,
+ GPIO0B4_GPIO = 0,
+ GPIO0B4_MMC1_D1,
+ GPIO0B4_I2S1_LRCKTX,
+
+ GPIO0B3_SHIFT = 6,
+ GPIO0B3_MASK = 3,
+ GPIO0B3_GPIO = 0,
+ GPIO0B3_MMC1_D0,
+ GPIO0B3_I2S1_LRCKRX,
+
+ GPIO0B1_SHIFT = 2,
+ GPIO0B1_MASK = 3,
+ GPIO0B1_GPIO = 0,
+ GPIO0B1_MMC1_CLKOUT,
+ GPIO0B1_I2S1_MCLK,
+
+ GPIO0B0_SHIFT = 0,
+ GPIO0B0_MASK = 3,
+ GPIO0B0_GPIO = 0,
+ GPIO0B0_MMC1_CMD,
+ GPIO0B0_I2S1_SDO,
+};
+
+/* GRF_GPIO0C_IOMUX */
+enum {
+ GPIO0C4_SHIFT = 8,
+ GPIO0C4_MASK = 1,
+ GPIO0C4_GPIO = 0,
+ GPIO0C4_DRIVE_VBUS,
+
+ GPIO0C3_SHIFT = 6,
+ GPIO0C3_MASK = 1,
+ GPIO0C3_GPIO = 0,
+ GPIO0C3_UART0_CTSN,
+
+ GPIO0C2_SHIFT = 4,
+ GPIO0C2_MASK = 1,
+ GPIO0C2_GPIO = 0,
+ GPIO0C2_UART0_RTSN,
+
+ GPIO0C1_SHIFT = 2,
+ GPIO0C1_MASK = 1,
+ GPIO0C1_GPIO = 0,
+ GPIO0C1_UART0_SIN,
+
+
+ GPIO0C0_SHIFT = 0,
+ GPIO0C0_MASK = 1,
+ GPIO0C0_GPIO = 0,
+ GPIO0C0_UART0_SOUT,
+};
+
+/* GRF_GPIO0D_IOMUX */
+enum {
+ GPIO0D4_SHIFT = 8,
+ GPIO0D4_MASK = 1,
+ GPIO0D4_GPIO = 0,
+ GPIO0D4_SPDIF,
+
+ GPIO0D3_SHIFT = 6,
+ GPIO0D3_MASK = 1,
+ GPIO0D3_GPIO = 0,
+ GPIO0D3_PWM3,
+
+ GPIO0D2_SHIFT = 4,
+ GPIO0D2_MASK = 1,
+ GPIO0D2_GPIO = 0,
+ GPIO0D2_PWM0,
+};
+
+/* GRF_GPIO1A_IOMUX */
+enum {
+ GPIO1A5_SHIFT = 10,
+ GPIO1A5_MASK = 1,
+ GPIO1A5_GPIO = 0,
+ GPIO1A5_I2S_SDI,
+
+ GPIO1A4_SHIFT = 8,
+ GPIO1A4_MASK = 1,
+ GPIO1A4_GPIO = 0,
+ GPIO1A4_I2S_SD0,
+
+ GPIO1A3_SHIFT = 6,
+ GPIO1A3_MASK = 1,
+ GPIO1A3_GPIO = 0,
+ GPIO1A3_I2S_LRCKTX,
+
+ GPIO1A2_SHIFT = 4,
+ GPIO1A2_MASK = 6,
+ GPIO1A2_GPIO = 0,
+ GPIO1A2_I2S_LRCKRX,
+ GPIO1A2_I2S_PWM1_0,
+
+ GPIO1A1_SHIFT = 2,
+ GPIO1A1_MASK = 1,
+ GPIO1A1_GPIO = 0,
+ GPIO1A1_I2S_SCLK,
+
+ GPIO1A0_SHIFT = 0,
+ GPIO1A0_MASK = 1,
+ GPIO1A0_GPIO = 0,
+ GPIO1A0_I2S_MCLK,
+
+};
+
+/* GRF_GPIO1B_IOMUX */
+enum {
+ GPIO1B7_SHIFT = 14,
+ GPIO1B7_MASK = 1,
+ GPIO1B7_GPIO = 0,
+ GPIO1B7_MMC0_CMD,
+
+ GPIO1B3_SHIFT = 6,
+ GPIO1B3_MASK = 1,
+ GPIO1B3_GPIO = 0,
+ GPIO1B3_HDMI_HPD,
+
+ GPIO1B2_SHIFT = 4,
+ GPIO1B2_MASK = 1,
+ GPIO1B2_GPIO = 0,
+ GPIO1B2_HDMI_SCL,
+
+ GPIO1B1_SHIFT = 2,
+ GPIO1B1_MASK = 1,
+ GPIO1B1_GPIO = 0,
+ GPIO1B1_HDMI_SDA,
+
+ GPIO1B0_SHIFT = 0,
+ GPIO1B0_MASK = 1,
+ GPIO1B0_GPIO = 0,
+ GPIO1B0_HDMI_CEC,
+};
+
+/* GRF_GPIO1C_IOMUX */
+enum {
+ GPIO1C5_SHIFT = 10,
+ GPIO1C5_MASK = 3,
+ GPIO1C5_GPIO = 0,
+ GPIO1C5_MMC0_D3,
+ GPIO1C5_JTAG_TMS,
+
+ GPIO1C4_SHIFT = 8,
+ GPIO1C4_MASK = 3,
+ GPIO1C4_GPIO = 0,
+ GPIO1C4_MMC0_D2,
+ GPIO1C4_JTAG_TCK,
+
+ GPIO1C3_SHIFT = 6,
+ GPIO1C3_MASK = 3,
+ GPIO1C3_GPIO = 0,
+ GPIO1C3_MMC0_D1,
+ GPIO1C3_UART2_SOUT,
+
+ GPIO1C2_SHIFT = 4,
+ GPIO1C2_MASK = 3,
+ GPIO1C2_GPIO = 0,
+ GPIO1C2_MMC0_D0,
+ GPIO1C2_UART2_SIN,
+
+ GPIO1C1_SHIFT = 2,
+ GPIO1C1_MASK = 1,
+ GPIO1C1_GPIO = 0,
+ GPIO1C1_MMC0_DETN,
+
+ GPIO1C0_SHIFT = 0,
+ GPIO1C0_MASK = 1,
+ GPIO1C0_GPIO = 0,
+ GPIO1C0_MMC0_CLKOUT,
+};
+
+/* GRF_GPIO1D_IOMUX */
+enum {
+ GPIO1D7_SHIFT = 14,
+ GPIO1D7_MASK = 3,
+ GPIO1D7_GPIO = 0,
+ GPIO1D7_NAND_D7,
+ GPIO1D7_EMMC_D7,
+ GPIO1D7_SPI_CSN1,
+
+ GPIO1D6_SHIFT = 12,
+ GPIO1D6_MASK = 3,
+ GPIO1D6_GPIO = 0,
+ GPIO1D6_NAND_D6,
+ GPIO1D6_EMMC_D6,
+ GPIO1D6_SPI_CSN0,
+
+ GPIO1D5_SHIFT = 10,
+ GPIO1D5_MASK = 3,
+ GPIO1D5_GPIO = 0,
+ GPIO1D5_NAND_D5,
+ GPIO1D5_EMMC_D5,
+ GPIO1D5_SPI_TXD,
+
+ GPIO1D4_SHIFT = 8,
+ GPIO1D4_MASK = 3,
+ GPIO1D4_GPIO = 0,
+ GPIO1D4_NAND_D4,
+ GPIO1D4_EMMC_D4,
+ GPIO1D4_SPI_RXD,
+
+ GPIO1D3_SHIFT = 6,
+ GPIO1D3_MASK = 3,
+ GPIO1D3_GPIO = 0,
+ GPIO1D3_NAND_D3,
+ GPIO1D3_EMMC_D3,
+ GPIO1D3_SFC_SIO3,
+
+ GPIO1D2_SHIFT = 4,
+ GPIO1D2_MASK = 3,
+ GPIO1D2_GPIO = 0,
+ GPIO1D2_NAND_D2,
+ GPIO1D2_EMMC_D2,
+ GPIO1D2_SFC_SIO2,
+
+ GPIO1D1_SHIFT = 2,
+ GPIO1D1_MASK = 3,
+ GPIO1D1_GPIO = 0,
+ GPIO1D1_NAND_D1,
+ GPIO1D1_EMMC_D1,
+ GPIO1D1_SFC_SIO1,
+
+ GPIO1D0_SHIFT = 0,
+ GPIO1D0_MASK = 3,
+ GPIO1D0_GPIO = 0,
+ GPIO1D0_NAND_D0,
+ GPIO1D0_EMMC_D0,
+ GPIO1D0_SFC_SIO0,
+};
+
+/* GRF_GPIO2A_IOMUX */
+enum {
+ GPIO2A7_SHIFT = 14,
+ GPIO2A7_MASK = 1,
+ GPIO2A7_GPIO = 0,
+ GPIO2A7_TESTCLK_OUT,
+
+ GPIO2A6_SHIFT = 12,
+ GPIO2A6_MASK = 1,
+ GPIO2A6_GPIO = 0,
+ GPIO2A6_NAND_CS0,
+
+ GPIO2A4_SHIFT = 8,
+ GPIO2A4_MASK = 3,
+ GPIO2A4_GPIO = 0,
+ GPIO2A4_NAND_RDY,
+ GPIO2A4_EMMC_CMD,
+ GPIO2A3_SFC_CLK,
+
+ GPIO2A3_SHIFT = 6,
+ GPIO2A3_MASK = 3,
+ GPIO2A3_GPIO = 0,
+ GPIO2A3_NAND_RDN,
+ GPIO2A4_SFC_CSN1,
+
+ GPIO2A2_SHIFT = 4,
+ GPIO2A2_MASK = 3,
+ GPIO2A2_GPIO = 0,
+ GPIO2A2_NAND_WRN,
+ GPIO2A4_SFC_CSN0,
+
+ GPIO2A1_SHIFT = 2,
+ GPIO2A1_MASK = 3,
+ GPIO2A1_GPIO = 0,
+ GPIO2A1_NAND_CLE,
+ GPIO2A1_EMMC_CLKOUT,
+
+ GPIO2A0_SHIFT = 0,
+ GPIO2A0_MASK = 3,
+ GPIO2A0_GPIO = 0,
+ GPIO2A0_NAND_ALE,
+ GPIO2A0_SPI_CLK,
+};
+
+/* GRF_GPIO2B_IOMUX */
+enum {
+ GPIO2B7_SHIFT = 14,
+ GPIO2B7_MASK = 1,
+ GPIO2B7_GPIO = 0,
+ GPIO2B7_MAC_RXER,
+
+ GPIO2B6_SHIFT = 12,
+ GPIO2B6_MASK = 3,
+ GPIO2B6_GPIO = 0,
+ GPIO2B6_MAC_CLKOUT,
+ GPIO2B6_MAC_CLKIN,
+
+ GPIO2B5_SHIFT = 10,
+ GPIO2B5_MASK = 1,
+ GPIO2B5_GPIO = 0,
+ GPIO2B5_MAC_TXEN,
+
+ GPIO2B4_SHIFT = 8,
+ GPIO2B4_MASK = 1,
+ GPIO2B4_GPIO = 0,
+ GPIO2B4_MAC_MDIO,
+
+ GPIO2B2_SHIFT = 4,
+ GPIO2B2_MASK = 1,
+ GPIO2B2_GPIO = 0,
+ GPIO2B2_MAC_CRS,
+};
+
+/* GRF_GPIO2C_IOMUX */
+enum {
+ GPIO2C7_SHIFT = 14,
+ GPIO2C7_MASK = 3,
+ GPIO2C7_GPIO = 0,
+ GPIO2C7_UART1_SOUT,
+ GPIO2C7_TESTCLK_OUT1,
+
+ GPIO2C6_SHIFT = 12,
+ GPIO2C6_MASK = 1,
+ GPIO2C6_GPIO = 0,
+ GPIO2C6_UART1_SIN,
+
+ GPIO2C5_SHIFT = 10,
+ GPIO2C5_MASK = 1,
+ GPIO2C5_GPIO = 0,
+ GPIO2C5_I2C2_SCL,
+
+ GPIO2C4_SHIFT = 8,
+ GPIO2C4_MASK = 1,
+ GPIO2C4_GPIO = 0,
+ GPIO2C4_I2C2_SDA,
+
+ GPIO2C3_SHIFT = 6,
+ GPIO2C3_MASK = 1,
+ GPIO2C3_GPIO = 0,
+ GPIO2C3_MAC_TXD0,
+
+ GPIO2C2_SHIFT = 4,
+ GPIO2C2_MASK = 1,
+ GPIO2C2_GPIO = 0,
+ GPIO2C2_MAC_TXD1,
+
+ GPIO2C1_SHIFT = 2,
+ GPIO2C1_MASK = 1,
+ GPIO2C1_GPIO = 0,
+ GPIO2C1_MAC_RXD0,
+
+ GPIO2C0_SHIFT = 0,
+ GPIO2C0_MASK = 1,
+ GPIO2C0_GPIO = 0,
+ GPIO2C0_MAC_RXD1,
+};
+
+/* GRF_GPIO2D_IOMUX */
+enum {
+ GPIO2D6_SHIFT = 12,
+ GPIO2D6_MASK = 1,
+ GPIO2D6_GPIO = 0,
+ GPIO2D6_I2S_SDO1,
+
+ GPIO2D5_SHIFT = 10,
+ GPIO2D5_MASK = 1,
+ GPIO2D5_GPIO = 0,
+ GPIO2D5_I2S_SDO2,
+
+ GPIO2D4_SHIFT = 8,
+ GPIO2D4_MASK = 1,
+ GPIO2D4_GPIO = 0,
+ GPIO2D4_I2S_SDO3,
+
+ GPIO2D1_SHIFT = 2,
+ GPIO2D1_MASK = 1,
+ GPIO2D1_GPIO = 0,
+ GPIO2D1_MAC_MDC,
+};
+#endif
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [U-Boot] [PATCH v2 10/17] rockchip: rk3036: Add Soc reset driver
2015-11-04 12:53 [U-Boot] [PATCH v2 00/17] Lin Huang
` (8 preceding siblings ...)
2015-11-04 12:53 ` [U-Boot] [PATCH v2 09/17] rockchip: rk3036: Add header files for GRF Lin Huang
@ 2015-11-04 12:53 ` Lin Huang
2015-11-04 12:53 ` [U-Boot] [PATCH v2 11/17] rockchip: rk3036: Add a simple syscon driver Lin Huang
` (6 subsequent siblings)
16 siblings, 0 replies; 21+ messages in thread
From: Lin Huang @ 2015-11-04 12:53 UTC (permalink / raw)
To: u-boot
We can reset the Soc using some CRU (clock/reset unit) register.
Add support for this.
Signed-off-by: Lin Huang <hl@rock-chips.com>
---
Changes in v1:
- clean copyright announcement
Changes in v2:
- only build reset_rk3036.c in NON-SPL stage
arch/arm/mach-rockchip/rk3036/Makefile | 10 +++++++
arch/arm/mach-rockchip/rk3036/reset_rk3036.c | 45 ++++++++++++++++++++++++++++
2 files changed, 55 insertions(+)
create mode 100644 arch/arm/mach-rockchip/rk3036/Makefile
create mode 100644 arch/arm/mach-rockchip/rk3036/reset_rk3036.c
diff --git a/arch/arm/mach-rockchip/rk3036/Makefile b/arch/arm/mach-rockchip/rk3036/Makefile
new file mode 100644
index 0000000..a483347
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3036/Makefile
@@ -0,0 +1,10 @@
+#
+# (C) Copyright 2015 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+ifndef CONFIG_SPL_BUILD
+obj-y += reset_rk3036.o
+endif
+
diff --git a/arch/arm/mach-rockchip/rk3036/reset_rk3036.c b/arch/arm/mach-rockchip/rk3036/reset_rk3036.c
new file mode 100644
index 0000000..fefb568
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3036/reset_rk3036.c
@@ -0,0 +1,45 @@
+/*
+ * (C) Copyright 2015 Rockchip Electronics Co., Ltd
+ *
+ * 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_rk3036.h>
+#include <asm/arch/hardware.h>
+#include <linux/err.h>
+
+int rk3036_reset_request(struct udevice *dev, enum reset_t type)
+{
+ struct rk3036_cru *cru = rockchip_get_cru();
+
+ if (IS_ERR(cru))
+ return PTR_ERR(cru);
+ switch (type) {
+ case RESET_WARM:
+ writel(0xeca8, &cru->cru_glb_srst_snd_value);
+ break;
+ case RESET_COLD:
+ writel(0xfdb9, &cru->cru_glb_srst_fst_value);
+ break;
+ default:
+ return -EPROTONOSUPPORT;
+ }
+
+ return -EINPROGRESS;
+}
+
+static struct reset_ops rk3036_reset = {
+ .request = rk3036_reset_request,
+};
+
+U_BOOT_DRIVER(reset_rk3036) = {
+ .name = "rk3036_reset",
+ .id = UCLASS_RESET,
+ .ops = &rk3036_reset,
+};
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [U-Boot] [PATCH v2 11/17] rockchip: rk3036: Add a simple syscon driver
2015-11-04 12:53 [U-Boot] [PATCH v2 00/17] Lin Huang
` (9 preceding siblings ...)
2015-11-04 12:53 ` [U-Boot] [PATCH v2 10/17] rockchip: rk3036: Add Soc reset driver Lin Huang
@ 2015-11-04 12:53 ` Lin Huang
2015-11-04 12:53 ` [U-Boot] [PATCH v2 12/17] rockchip: rk3036: Add pinctrl driver Lin Huang
` (5 subsequent siblings)
16 siblings, 0 replies; 21+ messages in thread
From: Lin Huang @ 2015-11-04 12:53 UTC (permalink / raw)
To: u-boot
Add a driver that provides access to system controllers
Signed-off-by: Lin Huang <hl@rock-chips.com>
---
Changes in v1:
- clean copyright announcement
Changes in v2:
- only build syscon_rk3036.c on NON-SPL stage
arch/arm/mach-rockchip/rk3036/Makefile | 2 +-
arch/arm/mach-rockchip/rk3036/syscon_rk3036.c | 21 +++++++++++++++++++++
2 files changed, 22 insertions(+), 1 deletion(-)
create mode 100644 arch/arm/mach-rockchip/rk3036/syscon_rk3036.c
diff --git a/arch/arm/mach-rockchip/rk3036/Makefile b/arch/arm/mach-rockchip/rk3036/Makefile
index a483347..5d14b95 100644
--- a/arch/arm/mach-rockchip/rk3036/Makefile
+++ b/arch/arm/mach-rockchip/rk3036/Makefile
@@ -6,5 +6,5 @@
ifndef CONFIG_SPL_BUILD
obj-y += reset_rk3036.o
+obj-y += syscon_rk3036.o
endif
-
diff --git a/arch/arm/mach-rockchip/rk3036/syscon_rk3036.c b/arch/arm/mach-rockchip/rk3036/syscon_rk3036.c
new file mode 100644
index 0000000..965afde
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3036/syscon_rk3036.c
@@ -0,0 +1,21 @@
+/*
+ * (C) Copyright 2015 Rockchip Electronics Co., Ltd
+ *
+ * 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 rk3036_syscon_ids[] = {
+ { .compatible = "rockchip,rk3036-grf", .data = ROCKCHIP_SYSCON_GRF },
+ { }
+};
+
+U_BOOT_DRIVER(syscon_rk3036) = {
+ .name = "rk3036_syscon",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3036_syscon_ids,
+};
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [U-Boot] [PATCH v2 12/17] rockchip: rk3036: Add pinctrl driver
2015-11-04 12:53 [U-Boot] [PATCH v2 00/17] Lin Huang
` (10 preceding siblings ...)
2015-11-04 12:53 ` [U-Boot] [PATCH v2 11/17] rockchip: rk3036: Add a simple syscon driver Lin Huang
@ 2015-11-04 12:53 ` Lin Huang
2015-11-04 12:53 ` [U-Boot] [PATCH v2 13/17] rockchip: Add an rk3036 MMC driver Lin Huang
` (4 subsequent siblings)
16 siblings, 0 replies; 21+ messages in thread
From: Lin Huang @ 2015-11-04 12:53 UTC (permalink / raw)
To: u-boot
Add a driver which support pin multiplexing setup for rk3036
Signed-off-by: Lin Huang <hl@rock-chips.com>
---
Changes in v1:
- clean copyright announcement
Changes in v2: None
drivers/pinctrl/Kconfig | 18 ++
drivers/pinctrl/rockchip/Makefile | 1 +
drivers/pinctrl/rockchip/pinctrl_rk3036.c | 276 ++++++++++++++++++++++++++++++
3 files changed, 295 insertions(+)
create mode 100644 drivers/pinctrl/rockchip/pinctrl_rk3036.c
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index b8146df..8e414cd 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -114,6 +114,24 @@ config ROCKCHIP_PINCTRL
definitions and pin control functions for each available multiplex
function.
+config ROCKCHIP_3036_PINCTRL
+ bool "Rockchip rk3036 pin control driver"
+ depends on DM
+ help
+ Support pin multiplexing control on Rockchip rk3036 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 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/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
index 251bace..6fa7d00 100644
--- a/drivers/pinctrl/rockchip/Makefile
+++ b/drivers/pinctrl/rockchip/Makefile
@@ -6,3 +6,4 @@
#
obj-$(CONFIG_ROCKCHIP_PINCTRL) += pinctrl_rk3288.o
+obj-$(CONFIG_ROCKCHIP_3036_PINCTRL) += pinctrl_rk3036.o
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3036.c b/drivers/pinctrl/rockchip/pinctrl_rk3036.c
new file mode 100644
index 0000000..25aba1f
--- /dev/null
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3036.c
@@ -0,0 +1,276 @@
+/*
+ * Pinctrl driver for Rockchip 3036 SoCs
+ * (C) Copyright 2015 Rockchip Electronics Co., Ltd
+ *
+ * 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_rk3036.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/periph.h>
+#include <dm/pinctrl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct rk3036_pinctrl_priv {
+ struct rk3036_grf *grf;
+};
+
+static void pinctrl_rk3036_pwm_config(struct rk3036_grf *grf, int pwm_id)
+{
+ switch (pwm_id) {
+ case PERIPH_ID_PWM0:
+ rk_clrsetreg(&grf->gpio0d_iomux, GPIO0D2_MASK << GPIO0D2_SHIFT,
+ GPIO0D2_PWM0 << GPIO0D2_SHIFT);
+ break;
+ case PERIPH_ID_PWM1:
+ rk_clrsetreg(&grf->gpio0a_iomux, GPIO0A0_MASK << GPIO0A0_SHIFT,
+ GPIO0A0_PWM1 << GPIO0A0_SHIFT);
+ break;
+ case PERIPH_ID_PWM2:
+ rk_clrsetreg(&grf->gpio0a_iomux, GPIO0A1_MASK << GPIO0A1_SHIFT,
+ GPIO0A1_PWM2 << GPIO0A1_SHIFT);
+ break;
+ case PERIPH_ID_PWM3:
+ rk_clrsetreg(&grf->gpio0a_iomux, GPIO0D3_MASK << GPIO0D3_SHIFT,
+ GPIO0D3_PWM3 << GPIO0D3_SHIFT);
+ break;
+ default:
+ debug("pwm id = %d iomux error!\n", pwm_id);
+ break;
+ }
+}
+
+static void pinctrl_rk3036_i2c_config(struct rk3036_grf *grf, int i2c_id)
+{
+ switch (i2c_id) {
+ case PERIPH_ID_I2C0:
+ rk_clrsetreg(&grf->gpio0a_iomux,
+ GPIO0A1_MASK << GPIO0A1_SHIFT |
+ GPIO0A0_MASK << GPIO0A0_SHIFT,
+ GPIO0A1_I2C0_SDA << GPIO0A1_SHIFT |
+ GPIO0A0_I2C0_SCL << GPIO0A0_SHIFT);
+
+ break;
+ case PERIPH_ID_I2C1:
+ rk_clrsetreg(&grf->gpio0a_iomux,
+ GPIO0A3_MASK << GPIO0A3_SHIFT |
+ GPIO0A2_MASK << GPIO0A2_SHIFT,
+ GPIO0A3_I2C1_SDA << GPIO0A3_SHIFT |
+ GPIO0A2_I2C1_SCL << GPIO0A2_SHIFT);
+ break;
+ case PERIPH_ID_I2C2:
+ rk_clrsetreg(&grf->gpio2c_iomux,
+ GPIO2C5_MASK << GPIO2C5_SHIFT |
+ GPIO2C4_MASK << GPIO2C4_SHIFT,
+ GPIO2C5_I2C2_SCL << GPIO2C5_SHIFT |
+ GPIO2C4_I2C2_SDA << GPIO2C4_SHIFT);
+
+ break;
+ }
+}
+
+static void pinctrl_rk3036_spi_config(struct rk3036_grf *grf, int cs)
+{
+ switch (cs) {
+ case 0:
+ rk_clrsetreg(&grf->gpio1d_iomux,
+ GPIO1D6_MASK << GPIO1D6_SHIFT,
+ GPIO1D6_SPI_CSN0 << GPIO1D6_SHIFT);
+ break;
+ case 1:
+ rk_clrsetreg(&grf->gpio1d_iomux,
+ GPIO1D7_MASK << GPIO1D7_SHIFT,
+ GPIO1D7_SPI_CSN1 << GPIO1D7_SHIFT);
+ break;
+ }
+ rk_clrsetreg(&grf->gpio1d_iomux,
+ GPIO1D5_MASK << GPIO1D5_SHIFT |
+ GPIO1D4_MASK << GPIO1D4_SHIFT,
+ GPIO1D5_SPI_TXD << GPIO1D5_SHIFT |
+ GPIO1D4_SPI_RXD << GPIO1D4_SHIFT);
+
+ rk_clrsetreg(&grf->gpio2a_iomux,
+ GPIO2A0_MASK << GPIO2A0_SHIFT,
+ GPIO2A0_SPI_CLK << GPIO2A0_SHIFT);
+}
+
+static void pinctrl_rk3036_uart_config(struct rk3036_grf *grf, int uart_id)
+{
+ switch (uart_id) {
+ case PERIPH_ID_UART0:
+ rk_clrsetreg(&grf->gpio0c_iomux,
+ GPIO0C3_MASK << GPIO0C3_SHIFT |
+ GPIO0C2_MASK << GPIO0C2_SHIFT |
+ GPIO0C1_MASK << GPIO0C1_SHIFT |
+ GPIO0C0_MASK << GPIO0C0_SHIFT,
+ GPIO0C3_UART0_CTSN << GPIO0C3_SHIFT |
+ GPIO0C2_UART0_RTSN << GPIO0C2_SHIFT |
+ GPIO0C1_UART0_SIN << GPIO0C1_SHIFT |
+ GPIO0C0_UART0_SOUT << GPIO0C0_SHIFT);
+ break;
+ case PERIPH_ID_UART1:
+ rk_clrsetreg(&grf->gpio2c_iomux,
+ GPIO2C7_MASK << GPIO2C7_SHIFT |
+ GPIO2C6_MASK << GPIO2C6_SHIFT,
+ GPIO2C7_UART1_SOUT << GPIO2C7_SHIFT |
+ GPIO2C6_UART1_SIN << GPIO2C6_SHIFT);
+ break;
+ case PERIPH_ID_UART2:
+ rk_clrsetreg(&grf->gpio1c_iomux,
+ GPIO1C3_MASK << GPIO1C3_SHIFT |
+ GPIO1C2_MASK << GPIO1C2_SHIFT,
+ GPIO1C3_UART2_SOUT << GPIO1C3_SHIFT |
+ GPIO1C2_UART2_SIN << GPIO1C2_SHIFT);
+ break;
+ }
+}
+
+static void pinctrl_rk3036_sdmmc_config(struct rk3036_grf *grf, int mmc_id)
+{
+ switch (mmc_id) {
+ case PERIPH_ID_EMMC:
+ rk_clrsetreg(&grf->gpio1d_iomux, 0xffff,
+ GPIO1D7_EMMC_D7 << GPIO1D7_SHIFT |
+ GPIO1D6_EMMC_D6 << GPIO1D6_SHIFT |
+ GPIO1D5_EMMC_D5 << GPIO1D5_SHIFT |
+ GPIO1D4_EMMC_D4 << GPIO1D4_SHIFT |
+ GPIO1D3_EMMC_D3 << GPIO1D3_SHIFT |
+ GPIO1D2_EMMC_D2 << GPIO1D2_SHIFT |
+ GPIO1D1_EMMC_D1 << GPIO1D1_SHIFT |
+ GPIO1D0_EMMC_D0 << GPIO1D0_SHIFT);
+ rk_clrsetreg(&grf->gpio2a_iomux,
+ GPIO2A4_MASK << GPIO2A4_SHIFT |
+ GPIO2A1_MASK << GPIO2A1_SHIFT,
+ GPIO2A4_EMMC_CMD << GPIO2A4_SHIFT |
+ GPIO2A1_EMMC_CLKOUT << GPIO2A1_SHIFT);
+ break;
+ case PERIPH_ID_SDCARD:
+ rk_clrsetreg(&grf->gpio1c_iomux, 0xffff,
+ GPIO1C5_MMC0_D3 << GPIO1C5_SHIFT |
+ GPIO1C4_MMC0_D2 << GPIO1C4_SHIFT |
+ GPIO1C3_MMC0_D1 << GPIO1C3_SHIFT |
+ GPIO1C2_MMC0_D0 << GPIO1C2_SHIFT |
+ GPIO1C1_MMC0_DETN << GPIO1C1_SHIFT |
+ GPIO1C0_MMC0_CLKOUT << GPIO1C0_SHIFT);
+ break;
+ }
+}
+
+static int rk3036_pinctrl_request(struct udevice *dev, int func, int flags)
+{
+ struct rk3036_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:
+ pinctrl_rk3036_pwm_config(priv->grf, func);
+ break;
+ case PERIPH_ID_I2C0:
+ case PERIPH_ID_I2C1:
+ case PERIPH_ID_I2C2:
+ pinctrl_rk3036_i2c_config(priv->grf, func);
+ break;
+ case PERIPH_ID_SPI0:
+ pinctrl_rk3036_spi_config(priv->grf, flags);
+ break;
+ case PERIPH_ID_UART0:
+ case PERIPH_ID_UART1:
+ case PERIPH_ID_UART2:
+ pinctrl_rk3036_uart_config(priv->grf, func);
+ break;
+ case PERIPH_ID_SDMMC0:
+ case PERIPH_ID_SDMMC1:
+ pinctrl_rk3036_sdmmc_config(priv->grf, func);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rk3036_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 14:
+ return PERIPH_ID_SDCARD;
+ case 16:
+ return PERIPH_ID_EMMC;
+ case 20:
+ return PERIPH_ID_UART0;
+ case 21:
+ return PERIPH_ID_UART1;
+ case 22:
+ return PERIPH_ID_UART2;
+ case 23:
+ return PERIPH_ID_SPI0;
+ case 24:
+ return PERIPH_ID_I2C0;
+ case 25:
+ return PERIPH_ID_I2C1;
+ case 26:
+ return PERIPH_ID_I2C2;
+ case 30:
+ return PERIPH_ID_PWM0;
+ }
+ return -ENOENT;
+}
+
+static int rk3036_pinctrl_set_state_simple(struct udevice *dev,
+ struct udevice *periph)
+{
+ int func;
+
+ func = rk3036_pinctrl_get_periph_id(dev, periph);
+ if (func < 0)
+ return func;
+ return rk3036_pinctrl_request(dev, func, 0);
+}
+
+static struct pinctrl_ops rk3036_pinctrl_ops = {
+ .set_state_simple = rk3036_pinctrl_set_state_simple,
+ .request = rk3036_pinctrl_request,
+ .get_periph_id = rk3036_pinctrl_get_periph_id,
+};
+
+static int rk3036_pinctrl_probe(struct udevice *dev)
+{
+ struct rk3036_pinctrl_priv *priv = dev_get_priv(dev);
+
+ priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ debug("%s: grf=%p\n", __func__, priv->grf);
+ return 0;
+}
+
+static const struct udevice_id rk3036_pinctrl_ids[] = {
+ { .compatible = "rockchip,rk3036-pinctrl" },
+ { }
+};
+
+U_BOOT_DRIVER(pinctrl_rk3036) = {
+ .name = "pinctrl_rk3036",
+ .id = UCLASS_PINCTRL,
+ .of_match = rk3036_pinctrl_ids,
+ .priv_auto_alloc_size = sizeof(struct rk3036_pinctrl_priv),
+ .ops = &rk3036_pinctrl_ops,
+ .probe = rk3036_pinctrl_probe,
+};
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [U-Boot] [PATCH v2 13/17] rockchip: Add an rk3036 MMC driver
2015-11-04 12:53 [U-Boot] [PATCH v2 00/17] Lin Huang
` (11 preceding siblings ...)
2015-11-04 12:53 ` [U-Boot] [PATCH v2 12/17] rockchip: rk3036: Add pinctrl driver Lin Huang
@ 2015-11-04 12:53 ` Lin Huang
2015-11-04 12:53 ` [U-Boot] [PATCH v2 14/17] rockchip: add early uart driver Lin Huang
` (3 subsequent siblings)
16 siblings, 0 replies; 21+ messages in thread
From: Lin Huang @ 2015-11-04 12:53 UTC (permalink / raw)
To: u-boot
rk3036 mmc driver is similar to dw_mmc, but use external dma,
this patch implment fifo mode, need to do dma mode in future.
Signed-off-by: Lin Huang <hl@rock-chips.com>
---
Changes in v1:
- clean copyright announcement
Changes in v2:
- modify code suggest by Simon:
- use get_time() to do timeout
drivers/mmc/Kconfig | 9 +
drivers/mmc/Makefile | 1 +
drivers/mmc/rockchip_3036_dw_mmc.c | 487 +++++++++++++++++++++++++++++++++++++
3 files changed, 497 insertions(+)
create mode 100644 drivers/mmc/rockchip_3036_dw_mmc.c
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 6277f92..38bfb9c 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -19,6 +19,15 @@ config ROCKCHIP_DWMMC
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 ROCKCHIP_3036_DWMMC
+ bool "Rockchip 3036 SD/MMC controller support"
+ depends on DM_MMC && OF_CONTROL
+ help
+ This enables support for the Rockchip 3036 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 99d0295..ff3920a 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -30,6 +30,7 @@ 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_ROCKCHIP_3036_DWMMC) += rockchip_3036_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_3036_dw_mmc.c b/drivers/mmc/rockchip_3036_dw_mmc.c
new file mode 100644
index 0000000..c18112c
--- /dev/null
+++ b/drivers/mmc/rockchip_3036_dw_mmc.c
@@ -0,0 +1,487 @@
+/*
+ * (C) Copyright 2015 Rockchip Electronics Co., Ltd
+ *
+ * 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>
+#include <bouncebuf.h>
+#include <common.h>
+#include <errno.h>
+#include <malloc.h>
+#include <mmc.h>
+#include <dwmmc.h>
+#include <asm-generic/errno.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define PAGE_SIZE 4096
+
+/* SDMMC_STATUS */
+#define MMC_FIFO_MASK 0x1ff
+#define MMC_FIFO_SHIFT 0x17
+
+struct rockchip_dwmmc_priv {
+ struct udevice *clk;
+ struct dwmci_host host;
+};
+
+static int dwmci_wait_reset(struct dwmci_host *host, u32 value)
+{
+ unsigned long timeout = 1000;
+ unsigned long start = get_timer(0);
+ u32 ctrl;
+
+ dwmci_writel(host, DWMCI_CTRL, value);
+
+ do {
+ ctrl = dwmci_readl(host, DWMCI_CTRL);
+ if (!(ctrl & DWMCI_RESET_ALL))
+ return 1;
+ } while (get_timer(start) < timeout);
+
+ return 0;
+}
+
+static int dwmci_set_transfer_mode(struct dwmci_host *host,
+ struct mmc_data *data)
+{
+ unsigned long mode;
+
+ mode = DWMCI_CMD_DATA_EXP;
+ if (data->flags & MMC_DATA_WRITE)
+ mode |= DWMCI_CMD_RW;
+
+ return mode;
+}
+
+static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ struct dwmci_host *host = mmc->priv;
+ int ret = 0, flags = 0, i;
+ unsigned int timeout = 100000;
+ u32 retry = 10000;
+ u32 mask;
+ ulong start = get_timer(0);
+ int size;
+ unsigned int fifo_len;
+ unsigned int *buf = 0;
+
+ while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) {
+ if (get_timer(start) > timeout) {
+ debug("%s: Timeout on data busy\n", __func__);
+ return TIMEOUT;
+ }
+ }
+
+ dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL);
+
+ if (data) {
+ /*
+ * TODO: rk3036 use external DMA,
+ * need to support DMA mode in future
+ */
+ if (data->flags == MMC_DATA_READ)
+ buf = (unsigned int *)data->dest;
+ else
+ buf = (unsigned int *)data->src;
+ dwmci_writel(host, DWMCI_BLKSIZ, data->blocksize);
+ dwmci_writel(host, DWMCI_BYTCNT,
+ data->blocksize * data->blocks);
+ dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET);
+ }
+
+ dwmci_writel(host, DWMCI_CMDARG, cmd->cmdarg);
+
+ if (data)
+ flags = dwmci_set_transfer_mode(host, data);
+
+ if ((cmd->resp_type & MMC_RSP_136) && (cmd->resp_type & MMC_RSP_BUSY))
+ return -1;
+
+ if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
+ flags |= DWMCI_CMD_ABORT_STOP;
+ else
+ flags |= DWMCI_CMD_PRV_DAT_WAIT;
+
+ if (cmd->resp_type & MMC_RSP_PRESENT) {
+ flags |= DWMCI_CMD_RESP_EXP;
+ if (cmd->resp_type & MMC_RSP_136)
+ flags |= DWMCI_CMD_RESP_LENGTH;
+ }
+
+ if (cmd->resp_type & MMC_RSP_CRC)
+ flags |= DWMCI_CMD_CHECK_CRC;
+
+ flags |= (cmd->cmdidx | DWMCI_CMD_START | DWMCI_CMD_USE_HOLD_REG);
+
+ debug("Sending CMD%d\n", cmd->cmdidx);
+
+ dwmci_writel(host, DWMCI_CMD, flags);
+
+ for (i = 0; i < retry; i++) {
+ mask = dwmci_readl(host, DWMCI_RINTSTS);
+ if (mask & DWMCI_INTMSK_CDONE) {
+ if (!data)
+ dwmci_writel(host, DWMCI_RINTSTS, mask);
+ break;
+ }
+ }
+
+ if (i == retry) {
+ debug("%s: Timeout.\n", __func__);
+ return TIMEOUT;
+ }
+
+ if (mask & DWMCI_INTMSK_RTO) {
+ /*
+ * Timeout here is not necessarily fatal. (e)MMC cards
+ * will splat here when they receive CMD55 as they do
+ * not support this command and that is exactly the way
+ * to tell them apart from SD cards. Thus, this output
+ * below shall be debug(). eMMC cards also do not favor
+ * CMD8, please keep that in mind.
+ */
+ debug("%s: Response Timeout.\n", __func__);
+ return TIMEOUT;
+ } else if (mask & DWMCI_INTMSK_RE) {
+ debug("%s: Response Error.\n", __func__);
+ return -EIO;
+ }
+
+ if (cmd->resp_type & MMC_RSP_PRESENT) {
+ if (cmd->resp_type & MMC_RSP_136) {
+ cmd->response[0] = dwmci_readl(host, DWMCI_RESP3);
+ cmd->response[1] = dwmci_readl(host, DWMCI_RESP2);
+ cmd->response[2] = dwmci_readl(host, DWMCI_RESP1);
+ cmd->response[3] = dwmci_readl(host, DWMCI_RESP0);
+ } else {
+ cmd->response[0] = dwmci_readl(host, DWMCI_RESP0);
+ }
+ }
+
+ if (data) {
+ size = data->blocksize * data->blocks / 4;
+ start = get_timer(0);
+ timeout = 1000;
+ for (;;) {
+ mask = dwmci_readl(host, DWMCI_RINTSTS);
+ /* Error during data transfer. */
+ if (mask & (DWMCI_DATA_ERR | DWMCI_DATA_TOUT)) {
+ debug("%s: DATA ERROR!\n", __func__);
+ ret = -EINVAL;
+ break;
+ }
+
+ /*
+ * TODO: rk3036 use external DMA,
+ * need to support DMA mode in future
+ */
+ if (data->flags == MMC_DATA_READ) {
+ if ((dwmci_readl(host, DWMCI_RINTSTS) &&
+ DWMCI_INTMSK_RXDR) && size) {
+ fifo_len = dwmci_readl(host,
+ DWMCI_STATUS);
+ fifo_len = (fifo_len >> MMC_FIFO_SHIFT)
+ & MMC_FIFO_MASK;
+ for (i = 0; i < fifo_len; i++)
+ *buf++ = dwmci_readl(host,
+ DWMCI_DATA);
+ dwmci_writel(host, DWMCI_RINTSTS,
+ DWMCI_INTMSK_RXDR);
+ size = size > fifo_len ?
+ (size - fifo_len) : 0;
+ }
+ } else {
+ if ((dwmci_readl(host, DWMCI_RINTSTS) &&
+ DWMCI_INTMSK_TXDR) && size) {
+ fifo_len = dwmci_readl(host,
+ DWMCI_STATUS);
+ fifo_len = (fifo_len >> MMC_FIFO_SHIFT)
+ & MMC_FIFO_MASK;
+ for (i = 0; i < fifo_len; i++)
+ dwmci_writel(host, DWMCI_DATA,
+ *buf++);
+ dwmci_writel(host, DWMCI_RINTSTS,
+ DWMCI_INTMSK_TXDR);
+ size = size > fifo_len ?
+ (size - fifo_len) : 0;
+ }
+ }
+
+ /* Data arrived correctly. */
+ if (mask & DWMCI_INTMSK_DTO) {
+ ret = 0;
+ break;
+ }
+
+ /* Check for timeout. */
+ if (get_timer(start) > timeout) {
+ debug("%s: Timeout waiting for data!\n",
+ __func__);
+ ret = TIMEOUT;
+ break;
+ }
+ }
+ dwmci_writel(host, DWMCI_RINTSTS, mask);
+ }
+
+ udelay(100);
+
+ return ret;
+}
+
+static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
+{
+ u32 div, status;
+ int timeout = 10000;
+ unsigned long sclk;
+ unsigned long start = get_timer(0);
+
+ if ((freq == host->clock) || (freq == 0))
+ return 0;
+ /*
+ * If host->get_mmc_clk isn't defined,
+ * then assume that host->bus_hz is source clock value.
+ * host->bus_hz should be set by user.
+ */
+ if (host->get_mmc_clk) {
+ sclk = host->get_mmc_clk(host, freq);
+ } else if (host->bus_hz) {
+ sclk = host->bus_hz;
+ } else {
+ debug("%s: Didn't get source clock value.\n", __func__);
+ return -EINVAL;
+ }
+
+ if (sclk == freq)
+ div = 0; /* bypass mode */
+ else
+ div = DIV_ROUND_UP(sclk, 2 * freq);
+
+ dwmci_writel(host, DWMCI_CLKENA, 0);
+ dwmci_writel(host, DWMCI_CLKSRC, 0);
+
+ dwmci_writel(host, DWMCI_CLKDIV, div);
+ dwmci_writel(host, DWMCI_CMD, DWMCI_CMD_PRV_DAT_WAIT |
+ DWMCI_CMD_UPD_CLK | DWMCI_CMD_START);
+
+ do {
+ status = dwmci_readl(host, DWMCI_CMD);
+ if (get_timer(start) > timeout) {
+ debug("%s: Timeout!\n", __func__);
+ return -ETIMEDOUT;
+ }
+ } while (status & DWMCI_CMD_START);
+
+ dwmci_writel(host, DWMCI_CLKENA, DWMCI_CLKEN_ENABLE |
+ DWMCI_CLKEN_LOW_PWR);
+
+ dwmci_writel(host, DWMCI_CMD, DWMCI_CMD_PRV_DAT_WAIT |
+ DWMCI_CMD_UPD_CLK | DWMCI_CMD_START);
+
+ start = get_timer(0);
+ do {
+ status = dwmci_readl(host, DWMCI_CMD);
+ if (get_timer(start) > timeout) {
+ debug("%s: Timeout!\n", __func__);
+ return -ETIMEDOUT;
+ }
+ } while (status & DWMCI_CMD_START);
+
+ host->clock = freq;
+
+ return 0;
+}
+
+static void dwmci_set_ios(struct mmc *mmc)
+{
+ struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
+ u32 ctype, regs;
+
+ debug("Buswidth = %d, clock: %d\n", mmc->bus_width, mmc->clock);
+
+ dwmci_setup_bus(host, mmc->clock);
+ switch (mmc->bus_width) {
+ case 8:
+ ctype = DWMCI_CTYPE_8BIT;
+ break;
+ case 4:
+ ctype = DWMCI_CTYPE_4BIT;
+ break;
+ default:
+ ctype = DWMCI_CTYPE_1BIT;
+ break;
+ }
+
+ dwmci_writel(host, DWMCI_CTYPE, ctype);
+
+ regs = dwmci_readl(host, DWMCI_UHS_REG);
+ if (mmc->ddr_mode)
+ regs |= DWMCI_DDR_MODE;
+ else
+ regs &= ~DWMCI_DDR_MODE;
+
+ dwmci_writel(host, DWMCI_UHS_REG, regs);
+
+ if (host->clksel)
+ host->clksel(host);
+}
+
+static int dwmci_init(struct mmc *mmc)
+{
+ struct dwmci_host *host = mmc->priv;
+
+ if (host->board_init)
+ host->board_init(host);
+
+ dwmci_writel(host, DWMCI_PWREN, 1);
+
+ if (!dwmci_wait_reset(host, DWMCI_RESET_ALL)) {
+ debug("%s[%d] Fail-reset!!\n", __func__, __LINE__);
+ return -EIO;
+ }
+
+ /* Enumerate at 400KHz */
+ dwmci_setup_bus(host, mmc->cfg->f_min);
+
+ dwmci_writel(host, DWMCI_RINTSTS, 0xFFFFFFFF);
+ dwmci_writel(host, DWMCI_INTMASK, 0);
+
+ dwmci_writel(host, DWMCI_TMOUT, 0xFFFFFFFF);
+
+ dwmci_writel(host, DWMCI_IDINTEN, 0);
+ dwmci_writel(host, DWMCI_BMOD, 1);
+
+ if (!host->fifoth_val) {
+ uint32_t fifo_size;
+ fifo_size = dwmci_readl(host, DWMCI_FIFOTH);
+ fifo_size = ((fifo_size & RX_WMARK_MASK) >> RX_WMARK_SHIFT) + 1;
+ host->fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size / 2 - 1) |
+ TX_WMARK(fifo_size / 2);
+ }
+ dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val);
+
+ dwmci_writel(host, DWMCI_CLKENA, 0);
+ dwmci_writel(host, DWMCI_CLKSRC, 0);
+
+ return 0;
+}
+
+static const struct mmc_ops dwmci_ops = {
+ .send_cmd = dwmci_send_cmd,
+ .set_ios = dwmci_set_ios,
+ .init = dwmci_init,
+};
+
+int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk)
+{
+ host->cfg.name = host->name;
+ host->cfg.ops = &dwmci_ops;
+ host->cfg.f_min = min_clk;
+ host->cfg.f_max = max_clk;
+
+ host->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
+
+ host->cfg.host_caps = host->caps;
+
+ if (host->buswidth == 8) {
+ host->cfg.host_caps |= MMC_MODE_8BIT;
+ host->cfg.host_caps &= ~MMC_MODE_4BIT;
+ } else {
+ host->cfg.host_caps |= MMC_MODE_4BIT;
+ host->cfg.host_caps &= ~MMC_MODE_8BIT;
+ }
+ host->cfg.host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
+
+ host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+
+ host->mmc = mmc_create(&host->cfg, host);
+ if (host->mmc == NULL)
+ return -1;
+
+ return 0;
+}
+
+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;
+
+ /* use non-removeable as sdcard and emmc as judgement */
+ if (fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset, "non-removable")
+ == -FDT_ERR_NOTFOUND)
+ host->dev_index = (ulong)host->ioaddr == 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;
+
+ 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_3036_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),
+};
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [U-Boot] [PATCH v2 14/17] rockchip: add early uart driver
2015-11-04 12:53 [U-Boot] [PATCH v2 00/17] Lin Huang
` (12 preceding siblings ...)
2015-11-04 12:53 ` [U-Boot] [PATCH v2 13/17] rockchip: Add an rk3036 MMC driver Lin Huang
@ 2015-11-04 12:53 ` Lin Huang
2015-11-04 12:53 ` [U-Boot] [PATCH v2 15/17] rockchip: add rk3036 sdram driver Lin Huang
` (2 subsequent siblings)
16 siblings, 0 replies; 21+ messages in thread
From: Lin Huang @ 2015-11-04 12:53 UTC (permalink / raw)
To: u-boot
add early uart driver so we can print debug message in
SPL stage
Signed-off-by: Lin Huang <hl@rock-chips.com>
---
arch/arm/include/asm/arch-rockchip/uart.h | 39 ++++++++++++++++++++++
arch/arm/mach-rockchip/Makefile | 1 +
arch/arm/mach-rockchip/rk_early_print.c | 55 +++++++++++++++++++++++++++++++
3 files changed, 95 insertions(+)
create mode 100644 arch/arm/include/asm/arch-rockchip/uart.h
create mode 100644 arch/arm/mach-rockchip/rk_early_print.c
diff --git a/arch/arm/include/asm/arch-rockchip/uart.h b/arch/arm/include/asm/arch-rockchip/uart.h
new file mode 100644
index 0000000..db45f9a
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/uart.h
@@ -0,0 +1,39 @@
+#ifndef __ASM_ARCH_UART_H
+#define __ASM_ARCH_UART_H
+struct rk_uart {
+ unsigned int rbr; /* Receive buffer register. */
+ unsigned int ier; /* Interrupt enable register. */
+ unsigned int fcr; /* FIFO control register. */
+ unsigned int lcr; /* Line control register. */
+ unsigned int mcr; /* Modem control register. */
+ unsigned int lsr; /* Line status register. */
+ unsigned int msr; /* Modem status register. */
+ unsigned int scr;
+ unsigned int reserved1[(0x30 - 0x20) / 4];
+ unsigned int srbr[(0x70 - 0x30) / 4];
+ unsigned int far;
+ unsigned int tfr;
+ unsigned int rfw;
+ unsigned int usr;
+ unsigned int tfl;
+ unsigned int rfl;
+ unsigned int srr;
+ unsigned int srts;
+ unsigned int sbcr;
+ unsigned int sdmam;
+ unsigned int sfe;
+ unsigned int srt;
+ unsigned int stet;
+ unsigned int htx;
+ unsigned int dmasa;
+ unsigned int reserver2[(0xf4 - 0xac) / 4];
+ unsigned int cpr;
+ unsigned int ucv;
+ unsigned int ctr;
+};
+
+void rk_uart_init(void);
+void print_hex(unsigned int n);
+void print(char *s);
+#endif
+
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 902235b..a29675d 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -10,5 +10,6 @@ else
obj-y += board.o
endif
obj-y += rk_timer.o
+obj-y += rk_early_print.o
obj-$(CONFIG_$(SPL_)ROCKCHIP_COMMON) += common.o
obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288/
diff --git a/arch/arm/mach-rockchip/rk_early_print.c b/arch/arm/mach-rockchip/rk_early_print.c
new file mode 100644
index 0000000..e712016
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk_early_print.c
@@ -0,0 +1,55 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm/io.h>
+#include <asm/arch/uart.h>
+#include <common.h>
+
+static struct rk_uart * const uart_ptr = (void *)CONFIG_DEBUG_UART_BASE;
+
+static void uart_wrtie_byte(char byte)
+{
+ writel(byte, &uart_ptr->rbr);
+ while (!(readl(&uart_ptr->lsr) & 0x40))
+ ;
+}
+
+void print(char *s)
+{
+ while (*s) {
+ if (*s == '\n')
+ uart_wrtie_byte('\r');
+ uart_wrtie_byte(*s);
+ s++;
+ }
+}
+
+void print_hex(unsigned int n)
+{
+ int i;
+ int temp;
+
+ uart_wrtie_byte('0');
+ uart_wrtie_byte('x');
+
+ for (i = 8; i > 0; i--) {
+ temp = (n >> (i - 1) * 4) & 0x0f;
+ if (temp < 10)
+ uart_wrtie_byte((char)(temp + '0'));
+ else
+ uart_wrtie_byte((char)(temp - 10 + 'a'));
+ }
+ uart_wrtie_byte('\n');
+ uart_wrtie_byte('\r');
+}
+
+void rk_uart_init(void)
+{
+ writel(0x83, &uart_ptr->lcr);
+ writel(0x0d, &uart_ptr->rbr);
+ writel(0x03, &uart_ptr->lcr);
+ writel(0x01, &uart_ptr->sfe);
+}
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [U-Boot] [PATCH v2 15/17] rockchip: add rk3036 sdram driver
2015-11-04 12:53 [U-Boot] [PATCH v2 00/17] Lin Huang
` (13 preceding siblings ...)
2015-11-04 12:53 ` [U-Boot] [PATCH v2 14/17] rockchip: add early uart driver Lin Huang
@ 2015-11-04 12:53 ` Lin Huang
2015-11-04 12:53 ` [U-Boot] [PATCH v2 16/17] rockchip: rk3036: Add core Soc start-up code Lin Huang
2015-11-04 12:53 ` [U-Boot] [PATCH v2 17/17] rockchip: Add basic support for evb-rk3036 board Lin Huang
16 siblings, 0 replies; 21+ messages in thread
From: Lin Huang @ 2015-11-04 12:53 UTC (permalink / raw)
To: u-boot
add rk3036 sdram driver so we can set up sdram in SPL
Signed-off-by: Lin Huang <hl@rock-chips.com>
---
arch/arm/include/asm/arch-rockchip/sdram_rk3036.h | 337 ++++++++++
arch/arm/mach-rockchip/rk3036/Makefile | 2 +
arch/arm/mach-rockchip/rk3036/sdram_rk3036.c | 732 ++++++++++++++++++++++
3 files changed, 1071 insertions(+)
create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_rk3036.h
create mode 100644 arch/arm/mach-rockchip/rk3036/sdram_rk3036.c
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rk3036.h b/arch/arm/include/asm/arch-rockchip/sdram_rk3036.h
new file mode 100644
index 0000000..ac9c8cd
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/sdram_rk3036.h
@@ -0,0 +1,337 @@
+/*
+ * (C) Copyright 2015 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef _ASM_ARCH_SDRAM_RK3036_H
+#define _ASM_ARCH_SDRAM_RK3036_H
+
+#include <common.h>
+
+struct rk3036_ddr_pctl {
+ u32 scfg;
+ u32 sctl;
+ u32 stat;
+ u32 intrstat;
+ u32 reserved0[12];
+ u32 mcmd;
+ u32 powctl;
+ u32 powstat;
+ u32 cmdtstat;
+ u32 cmdtstaten;
+ 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 reserved5[47];
+ 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(rk3036_ddr_pctl, iptr, 0x03fc);
+
+struct rk3036_ddr_phy {
+ u32 ddrphy_reg1;
+ u32 ddrphy_reg3;
+ u32 ddrphy_reg2;
+ u32 reserve[11];
+ u32 ddrphy_reg4a;
+ u32 ddrphy_reg4b;
+ u32 reserve1[5];
+ u32 ddrphy_reg16;
+ u32 reserve2;
+ u32 ddrphy_reg18;
+ u32 ddrphy_reg19;
+ u32 reserve3;
+ u32 ddrphy_reg21;
+ u32 reserve4;
+ u32 ddrphy_reg22;
+ u32 reserve5[3];
+ u32 ddrphy_reg25;
+ u32 ddrphy_reg26;
+ u32 ddrphy_reg27;
+ u32 ddrphy_reg28;
+ u32 reserve6[17];
+ u32 ddrphy_reg6;
+ u32 ddrphy_reg7;
+ u32 reserve7;
+ u32 ddrphy_reg8;
+ u32 ddrphy_reg0e4;
+ u32 reserve8[11];
+ u32 ddrphy_reg9;
+ u32 ddrphy_reg10;
+ u32 reserve9;
+ u32 ddrphy_reg11;
+ u32 ddrphy_reg124;
+ u32 reserve10[38];
+ u32 ddrphy_reg29;
+ u32 reserve11[40];
+ u32 ddrphy_reg264;
+ u32 reserve12[18];
+ u32 ddrphy_reg2a;
+ u32 reserve13[4];
+ u32 ddrphy_reg30;
+ u32 ddrphy_reg31;
+ u32 ddrphy_reg32;
+ u32 ddrphy_reg33;
+ u32 ddrphy_reg34;
+ u32 ddrphy_reg35;
+ u32 ddrphy_reg36;
+ u32 ddrphy_reg37;
+ u32 ddrphy_reg38;
+ u32 ddrphy_reg39;
+ u32 ddrphy_reg40;
+ u32 ddrphy_reg41;
+ u32 ddrphy_reg42;
+ u32 ddrphy_reg43;
+ u32 ddrphy_reg44;
+ u32 ddrphy_reg45;
+ u32 ddrphy_reg46;
+ u32 ddrphy_reg47;
+ u32 ddrphy_reg48;
+ u32 ddrphy_reg49;
+ u32 ddrphy_reg50;
+ u32 ddrphy_reg51;
+ u32 ddrphy_reg52;
+ u32 ddrphy_reg53;
+ u32 reserve14;
+ u32 ddrphy_reg54;
+ u32 ddrphy_reg55;
+ u32 ddrphy_reg56;
+ u32 ddrphy_reg57;
+ u32 ddrphy_reg58;
+ u32 ddrphy_reg59;
+ u32 ddrphy_reg5a;
+ u32 ddrphy_reg5b;
+ u32 ddrphy_reg5c;
+ u32 ddrphy_reg5d;
+ u32 ddrphy_reg5e;
+ u32 reserve15[28];
+ u32 ddrphy_reg5f;
+ u32 reserve16[6];
+ u32 ddrphy_reg60;
+ u32 ddrphy_reg61;
+ u32 ddrphy_reg62;
+};
+check_member(rk3036_ddr_phy, ddrphy_reg62, 0x03e8);
+
+struct rk3036_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;
+};
+
+struct rk3036_phy_timing {
+ u32 mr[4];
+ u32 bl;
+ u32 cl_al;
+};
+
+typedef union {
+ u32 noc_timing;
+ struct {
+ u32 acttoact:6;
+ u32 rdtomiss:6;
+ u32 wrtomiss:6;
+ u32 burstlen:3;
+ u32 rdtowr:5;
+ u32 wrtord:5;
+ u32 bwratio:1;
+ };
+} rk3036_noc_timing;
+
+struct rk3036_ddr_timing {
+ u32 freq;
+ struct rk3036_pctl_timing pctl_timing;
+ struct rk3036_phy_timing phy_timing;
+ rk3036_noc_timing noc_timing;
+};
+
+struct rk3036_service_sys {
+ u32 id_coreid;
+ u32 id_revisionid;
+ u32 ddrconf;
+ u32 ddrtiming;
+ u32 ddrmode;
+ u32 readlatency;
+};
+
+struct rk3036_ddr_config {
+
+ /*
+ * 000: lpddr
+ * 001: ddr
+ * 010: ddr2
+ * 011: ddr3
+ * 100: lpddr2-s2
+ * 101: lpddr2-s4
+ * 110: lpddr3
+ */
+ u32 ddr_type;
+ u32 rank;
+ u32 cs0_row;
+ u32 cs1_row;
+
+ /* 2: 4bank, 3: 8bank */
+ u32 bank;
+ u32 col;
+
+ /* bw(0: 8bit, 1: 16bit, 2: 32bit) */
+ u32 bw;
+};
+
+void sdram_init(void);
+void get_ddr_config(struct rk3036_ddr_config *config);
+size_t sdram_size(void);
+#endif
diff --git a/arch/arm/mach-rockchip/rk3036/Makefile b/arch/arm/mach-rockchip/rk3036/Makefile
index 5d14b95..6095777 100644
--- a/arch/arm/mach-rockchip/rk3036/Makefile
+++ b/arch/arm/mach-rockchip/rk3036/Makefile
@@ -8,3 +8,5 @@ ifndef CONFIG_SPL_BUILD
obj-y += reset_rk3036.o
obj-y += syscon_rk3036.o
endif
+
+obj-y += sdram_rk3036.o
diff --git a/arch/arm/mach-rockchip/rk3036/sdram_rk3036.c b/arch/arm/mach-rockchip/rk3036/sdram_rk3036.c
new file mode 100644
index 0000000..665e8eb
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3036/sdram_rk3036.c
@@ -0,0 +1,732 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <asm/arch/cru_rk3036.h>
+#include <asm/arch/grf_rk3036.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sdram_rk3036.h>
+#include <asm/arch/timer.h>
+#include <asm/arch/uart.h>
+#include <asm/io.h>
+#include <asm/types.h>
+#include <common.h>
+
+#define CRU_BASE 0x20000000
+static struct rk3036_cru * const cru = (void *)CRU_BASE;
+
+#define GRF_BASE 0x20008000
+static struct rk3036_grf * const grf = (void *)GRF_BASE;
+
+#define DDR_PHY_BASE 0x2000a000
+static struct rk3036_ddr_phy * const ddr_phy = (void *)DDR_PHY_BASE;
+
+#define DDR_PCTL_BASE 0x20004000
+static struct rk3036_ddr_pctl * const pctl = (void *)DDR_PCTL_BASE;
+
+#define CPU_AXI_BUS_BASE 0x10128000
+static struct rk3036_service_sys * const axi_bus = (void *)CPU_AXI_BUS_BASE;
+
+/* use interge mode, 396M dpll setting
+ * refdiv, fbdiv, postdiv1, postdiv2
+ */
+static const struct pll_div dpll_init_cfg = {1, 66, 4, 1};
+
+/* 396Mhz ddr timing */
+struct rk3036_ddr_timing ddr_timing = {0x18c,
+ 0x18c, 0xc8, 0x1f4, 0x27, 0x4e,
+ 0x4, 0x8b, 0x06, 0x03, 0x0, 0x06, 0x05, 0x0f, 0x15, 0x06, 0x04, 0x04,
+ 0x06, 0x04, 0x200, 0x03, 0x0a, 0x40, 0x2710, 0x01, 0x05, 0x05, 0x03,
+ 0x0c, 0x28, 0x100, 0x0, 0x04, 0x0,
+ 0x420, 0x42, 0x0, 0x0, 0x01, 0x60,
+ 0x24717315};
+
+/* ddr die config */
+static struct rk3036_ddr_config ddr_config;
+
+/*
+ * [7:6] bank(n:n bit bank)
+ * [5:4] row(13+n)
+ * [3] cs(0:1 cs, 1:2 cs)
+ * [2:1] bank(n:n bit bank)
+ * [0] col(10+n)
+ */
+char ddr_cfg_2_rbc[] = {
+ ((3 << 6) | (3 << 4) | (0 << 3) | (0 << 1) | 1),
+ ((0 << 6) | (1 << 4) | (0 << 3) | (3 << 1) | 0),
+ ((0 << 6) | (2 << 4) | (0 << 3) | (3 << 1) | 0),
+ ((0 << 6) | (3 << 4) | (0 << 3) | (3 << 1) | 0),
+ ((0 << 6) | (1 << 4) | (0 << 3) | (3 << 1) | 1),
+ ((0 << 6) | (2 << 4) | (0 << 3) | (3 << 1) | 1),
+ ((0 << 6) | (3 << 4) | (0 << 3) | (3 << 1) | 1),
+ ((0 << 6) | (0 << 4) | (0 << 3) | (3 << 1) | 0),
+ ((0 << 6) | (0 << 4) | (0 << 3) | (3 << 1) | 1),
+ ((0 << 6) | (3 << 4) | (1 << 3) | (3 << 1) | 0),
+ ((0 << 6) | (3 << 4) | (1 << 3) | (3 << 1) | 1),
+ ((1 << 6) | (2 << 4) | (0 << 3) | (2 << 1) | 0),
+ ((3 << 6) | (2 << 4) | (0 << 3) | (0 << 1) | 1),
+ ((3 << 6) | (3 << 4) | (0 << 3) | (0 << 1) | 0),
+};
+
+/* DDRPHY REG */
+enum {
+ /* DDRPHY_REG1 */
+ SOFT_RESET_MASK = 3,
+ SOFT_RESET_SHIFT = 2,
+
+ /* DDRPHY_REG2 */
+ MEMORY_SELECT_DDR3 = 0 << 6,
+ DQS_SQU_CAL_NORMAL_MODE = 0 << 1,
+ DQS_SQU_CAL_START = 1 << 0,
+ DQS_SQU_NO_CAL = 0 << 0,
+
+ /* DDRPHY_REG2A */
+ CMD_DLL_BYPASS = 1 << 4,
+ CMD_DLL_BYPASS_DISABLE = 0 << 4,
+ HIGH_8BIT_DLL_BYPASS = 1 << 3,
+ HIGH_8BIT_DLL_BYPASS_DISABLE = 0 << 3,
+ LOW_8BIT_DLL_BYPASS = 1 << 2,
+ LOW_8BIT_DLL_BYPASS_DISABLE = 0 << 2,
+
+ /* DDRPHY_REG19 */
+ CMD_FEEDBACK_ENABLE = 1 << 5,
+ CMD_SLAVE_DLL_INVERSE_MODE = 1 << 4,
+ CMD_SLAVE_DLL_NO_INVERSE_MODE = 0 << 4,
+ CMD_SLAVE_DLL_ENALBE = 1 << 3,
+ CMD_TX_SLAVE_DLL_DELAY_MASK = 7,
+ CMD_TX_SLAVE_DLL_DELAY_SHIFT = 0,
+
+ /* DDRPHY_REG6 */
+ LEFT_CHN_TX_DQ_PHASE_BYPASS_90 = 1 << 4,
+ LEFT_CHN_TX_DQ_PHASE_BYPASS_0 = 0 << 4,
+ LEFT_CHN_TX_DQ_DLL_ENABLE = 1 << 3,
+ LEFT_CHN_TX_DQ_DLL_DELAY_MASK = 7,
+ LEFT_CHN_TX_DQ_DLL_DELAY_SHIFT = 0,
+
+ /* DDRPHY_REG8 */
+ LEFT_CHN_RX_DQS_DELAY_TAP_MASK = 3,
+ LEFT_CHN_RX_DQS_DELAY_TAP_SHIFT = 0,
+
+ /* DDRPHY_REG9 */
+ RIGHT_CHN_TX_DQ_PHASE_BYPASS_90 = 1 << 4,
+ RIGHT_CHN_TX_DQ_PHASE_BYPASS_0 = 0 << 4,
+ RIGHT_CHN_TX_DQ_DLL_ENABLE = 1 << 3,
+ RIGHT_CHN_TX_DQ_DLL_DELAY_MASK = 7,
+ RIGHT_CHN_TX_DQ_DLL_DELAY_SHIFT = 0,
+
+ /* DDRPHY_REG11 */
+ RIGHT_CHN_RX_DQS_DELAY_TAP_MASK = 3,
+ RIGHT_CHN_RX_DQS_DELAY_TAP_SHIFT = 0,
+
+ /* DDRPHY_REG62 */
+ CAL_DONE_MASK = 3,
+ HIGH_8BIT_CAL_DONE = 1 << 1,
+ LOW_8BIT_CAL_DONE = 1 << 0,
+};
+
+/* PTCL */
+enum {
+ /* PCTL_DFISTCFG0 */
+ DFI_INIT_START = 1 << 0,
+ DFI_DATA_BYTE_DISABLE_EN = 1 << 2,
+
+ /* PCTL_DFISTCFG1 */
+ DFI_DRAM_CLK_SR_EN = 1 << 0,
+ DFI_DRAM_CLK_DPD_EN = 1 << 1,
+
+ /* PCTL_DFISTCFG2 */
+ DFI_PARITY_INTR_EN = 1 << 0,
+ DFI_PARITY_EN = 1 << 1,
+
+ /* PCTL_DFILPCFG0 */
+ TLP_RESP_TIME_SHIFT = 16,
+ LP_SR_EN = 1 << 8,
+ LP_PD_EN = 1 << 0,
+
+ /* PCTL_DFIODTCFG */
+ RANK0_ODT_WRITE_SEL = 1 << 3,
+ RANK1_ODT_WRITE_SEL = 1 << 11,
+
+ /* PCTL_DFIODTCFG1 */
+ ODT_LEN_BL8_W_SHIFT = 16,
+
+ /* PCTL_MCFG */
+ TFAW_CFG_MASK = 3,
+ TFAW_CFG_SHIFT = 18,
+ PD_EXIT_SLOW_MODE = 0 << 17,
+ PD_ACTIVE_POWER_DOWN = 1 << 16,
+ PD_IDLE_MASK = 0xff,
+ PD_IDLE_SHIFT = 8,
+ MEM_BL4 = 0 << 0,
+ MEM_BL8 = 1 << 0,
+
+ /* PCTL_MCFG1 */
+ HW_EXIT_IDLE_EN_MASK = 1,
+ HW_EXIT_IDLE_EN_SHIFT = 31,
+ SR_IDLE_MASK = 0x1ff,
+ SR_IDLE_SHIFT = 0,
+
+ /* PCTL_SCFG */
+ HW_LOW_POWER_EN = 1 << 0,
+
+ /* PCTL_POWCTL */
+ POWER_UP_START = 1 << 0,
+
+ /* PCTL_POWSTAT */
+ POWER_UP_DONE = 1 << 0,
+
+ /* PCTL_MCMD */
+ START_CMD = 1 << 31,
+ BANK_ADDR_MASK = 7,
+ BANK_ADDR_SHIFT = 17,
+ CMD_ADDR_MASK = 0x1fff,
+ CMD_ADDR_SHIFT = 4,
+ DESELECT_CMD = 0,
+ PREA_CMD,
+ REF_CMD,
+ MRS_CMD,
+ ZQCS_CMD,
+ ZQCL_CMD,
+ RSTL_CMD,
+ MRR_CMD = 8,
+
+ /* PCTL_STAT */
+ INIT_MEM = 0,
+ CONFIG,
+ CONFIG_REQ,
+ ACCESS,
+ ACCESS_REQ,
+ LOW_POWER,
+ LOW_POWER_ENTRY_REQ,
+ LOW_POWER_EXIT_REQ,
+ PCTL_STAT_MASK = 7,
+
+ /* PCTL_SCTL */
+ INIT_STATE = 0,
+ CFG_STATE = 1,
+ GO_STATE = 2,
+ SLEEP_STATE = 3,
+ WAKEUP_STATE = 4,
+};
+
+/* GRF_SOC_CON2 */
+#define MSCH4_MAINDDR3 1 << 7
+
+#define PHY_RON_DISABLE 0
+#define PHY_RON_309OHM 1
+#define PHY_RON_155OHM 2
+#define PHY_RON_103OHM 3
+#define PHY_RON_63OHM 5
+#define PHY_RON_45OHM 7
+#define PHY_RON_77OHM 8
+#define PHY_RON_62OHM 9
+#define PHY_RON_52OHM 0xa
+#define PHY_RON_44OHM 0xb
+#define PHY_RON_39OHM 0xc
+#define PHY_RON_34OHM 0xd
+#define PHY_RON_31OHM 0xe
+#define PHY_RON_28OHM 0xf
+
+
+#define PHY_RTT_DISABLE 0
+#define PHY_RTT_861OHM 1
+#define PHY_RTT_431OHM 2
+#define PHY_RTT_287OHM 3
+#define PHY_RTT_216OHM 4
+#define PHY_RTT_172OHM 5
+#define PHY_RTT_145OHM 6
+#define PHY_RTT_124OHM 7
+#define PHY_RTT_215OHM 8
+#define PHY_RTT_144OHM 0xa
+#define PHY_RTT_123OHM 0xb
+#define PHY_RTT_108OHM 0xc
+#define PHY_RTT_96OHM 0xd
+#define PHY_RTT_86OHM 0xe
+#define PHY_RTT_78OHM 0xf
+
+#define PHY_DRV_ODT_SET(n) ((n << 4) | n)
+
+#define DDR3_DLL_RESET (1 << 8)
+
+/* GRF_OS_REG1 */
+enum {
+
+ /*
+ * 000: lpddr
+ * 001: ddr
+ * 010: ddr2
+ * 011: ddr3
+ * 100: lpddr2-s2
+ * 101: lpddr2-s4
+ * 110: lpddr3
+ */
+ DDR_TYPE_MASK = 7,
+ DDR_TYPE_SHIFT = 13,
+
+ /* 0: 1 chn, 1: 2 chn */
+ DDR_CHN_CNT_SHIFT = 12,
+
+ /* 0: 1 rank, 1: 2 rank */
+ DDR_RANK_CNT_MASK = 1,
+ DDR_RANK_CNT_SHIFT = 11,
+
+ /*
+ * 00: 9col
+ * 01: 10col
+ * 10: 11col
+ * 11: 12col
+ */
+ DDR_COL_MASK = 3,
+ DDR_COL_SHIFT = 9,
+
+ /* 0: 8 bank, 1: 4 bank*/
+ DDR_BANK_MASK = 1,
+ DDR_BANK_SHIFT = 8,
+
+ /*
+ * 00: 13 row
+ * 01: 14 row
+ * 10: 15 row
+ * 11: 16 row
+ */
+ DDR_CS0_ROW_MASK = 3,
+ DDR_CS0_ROW_SHIFT = 6,
+ DDR_CS1_ROW_MASK = 3,
+ DDR_CS1_ROW_SHIFT = 4,
+
+ /*
+ * 00: 32 bit
+ * 01: 16 bit
+ * 10: 8 bit
+ * rk3036 only support 16bit
+ */
+ DDR_BW_MASK = 3,
+ DDR_BW_SHIFT = 2,
+ DDR_DIE_BW_MASK = 3,
+ DDR_DIE_BW_SHIFT = 0,
+};
+
+static void rkdclk_init(void)
+{
+ struct rk3036_pll *pll = &cru->pll[1];
+
+ /* pll enter slow-mode */
+ rk_clrsetreg(&cru->cru_mode_con,
+ DPLL_MODE_MASK << DPLL_MODE_SHIFT,
+ DPLL_MODE_SLOW << DPLL_MODE_SHIFT);
+
+ /* use interger mode */
+ rk_clrreg(&pll->con1, 1 << PLL_DSMPD_SHIFT);
+
+ rk_clrsetreg(&pll->con0,
+ PLL_POSTDIV1_MASK << PLL_POSTDIV1_SHIFT | PLL_FBDIV_MASK,
+ (dpll_init_cfg.postdiv1 << PLL_POSTDIV1_SHIFT) |
+ dpll_init_cfg.fbdiv);
+ rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK << PLL_POSTDIV2_SHIFT |
+ PLL_REFDIV_MASK << PLL_REFDIV_SHIFT,
+ (dpll_init_cfg.postdiv2 << PLL_POSTDIV2_SHIFT |
+ dpll_init_cfg.refdiv << PLL_REFDIV_SHIFT));
+
+ /* waiting for pll lock */
+ while (readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT))
+ rockchip_udelay(1);
+
+ /* PLL enter normal-mode */
+ rk_clrsetreg(&cru->cru_mode_con,
+ DPLL_MODE_MASK << DPLL_MODE_SHIFT,
+ DPLL_MODE_NORM << DPLL_MODE_SHIFT);
+}
+
+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++;
+ }
+}
+
+void phy_pctrl_reset(void)
+{
+ rk_clrsetreg(&cru->cru_softrst_con[5], 1 << DDRCTRL_PSRST_SHIFT |
+ 1 << DDRCTRL_SRST_SHIFT | 1 << DDRPHY_PSRST_SHIFT |
+ 1 << DDRPHY_SRST_SHIFT,
+ 1 << DDRCTRL_PSRST_SHIFT | 1 << DDRCTRL_SRST_SHIFT |
+ 1 << DDRPHY_PSRST_SHIFT | 1 << DDRPHY_SRST_SHIFT);
+ rockchip_udelay(10);
+
+ rk_clrsetreg(&cru->cru_softrst_con[5], 1 << DDRCTRL_PSRST_SHIFT |
+ 1 << DDRCTRL_SRST_SHIFT | 1 << DDRPHY_PSRST_SHIFT |
+ 1 << DDRPHY_SRST_SHIFT,
+ 1 << DDRCTRL_PSRST_SHIFT | 1 << DDRCTRL_SRST_SHIFT |
+ 0 << DDRPHY_PSRST_SHIFT | 0 << DDRPHY_SRST_SHIFT);
+ rockchip_udelay(10);
+
+ rk_clrsetreg(&cru->cru_softrst_con[5], 1 << DDRCTRL_PSRST_SHIFT |
+ 1 << DDRCTRL_SRST_SHIFT | 1 << DDRPHY_PSRST_SHIFT |
+ 1 << DDRPHY_SRST_SHIFT,
+ 0 << DDRCTRL_PSRST_SHIFT | 0 << DDRCTRL_SRST_SHIFT |
+ 0 << DDRPHY_PSRST_SHIFT | 0 << DDRPHY_SRST_SHIFT);
+ rockchip_udelay(10);
+
+ clrsetbits_le32(&ddr_phy->ddrphy_reg1,
+ SOFT_RESET_MASK << SOFT_RESET_SHIFT,
+ 0 << SOFT_RESET_SHIFT);
+ rockchip_udelay(10);
+ clrsetbits_le32(&ddr_phy->ddrphy_reg1,
+ SOFT_RESET_MASK << SOFT_RESET_SHIFT,
+ 3 << SOFT_RESET_SHIFT);
+
+ rockchip_udelay(1);
+}
+
+void phy_dll_bypass_set(unsigned int freq)
+{
+ if (freq < ddr_timing.freq) {
+ writel(CMD_DLL_BYPASS | HIGH_8BIT_DLL_BYPASS |
+ LOW_8BIT_DLL_BYPASS, &ddr_phy->ddrphy_reg2a);
+
+ writel(CMD_SLAVE_DLL_NO_INVERSE_MODE | CMD_SLAVE_DLL_ENALBE |
+ (0 & CMD_TX_SLAVE_DLL_DELAY_MASK) <<
+ CMD_TX_SLAVE_DLL_DELAY_SHIFT, &ddr_phy->ddrphy_reg19);
+
+ writel(LEFT_CHN_TX_DQ_PHASE_BYPASS_90 |
+ LEFT_CHN_TX_DQ_DLL_ENABLE |
+ (0 & LEFT_CHN_TX_DQ_DLL_DELAY_MASK) <<
+ LEFT_CHN_TX_DQ_DLL_DELAY_SHIFT, &ddr_phy->ddrphy_reg6);
+
+ writel(RIGHT_CHN_TX_DQ_PHASE_BYPASS_90 |
+ RIGHT_CHN_TX_DQ_DLL_ENABLE |
+ (0 & RIGHT_CHN_TX_DQ_DLL_DELAY_MASK) <<
+ RIGHT_CHN_TX_DQ_DLL_DELAY_SHIFT,
+ &ddr_phy->ddrphy_reg9);
+ } else {
+ writel(CMD_DLL_BYPASS_DISABLE | HIGH_8BIT_DLL_BYPASS_DISABLE |
+ LOW_8BIT_DLL_BYPASS_DISABLE, &ddr_phy->ddrphy_reg2a);
+
+ writel(CMD_SLAVE_DLL_NO_INVERSE_MODE | CMD_SLAVE_DLL_ENALBE |
+ (0 & CMD_TX_SLAVE_DLL_DELAY_MASK) <<
+ CMD_TX_SLAVE_DLL_DELAY_SHIFT, &ddr_phy->ddrphy_reg19);
+
+ writel(LEFT_CHN_TX_DQ_PHASE_BYPASS_0 |
+ LEFT_CHN_TX_DQ_DLL_ENABLE |
+ (4 & LEFT_CHN_TX_DQ_DLL_DELAY_MASK) <<
+ LEFT_CHN_TX_DQ_DLL_DELAY_SHIFT,
+ &ddr_phy->ddrphy_reg6);
+
+ writel(RIGHT_CHN_TX_DQ_PHASE_BYPASS_0 |
+ RIGHT_CHN_TX_DQ_DLL_ENABLE |
+ (4 & RIGHT_CHN_TX_DQ_DLL_DELAY_MASK) <<
+ RIGHT_CHN_TX_DQ_DLL_DELAY_SHIFT,
+ &ddr_phy->ddrphy_reg9);
+ }
+
+ /* 45 degree delay */
+ writel((2 & LEFT_CHN_RX_DQS_DELAY_TAP_MASK) <<
+ LEFT_CHN_RX_DQS_DELAY_TAP_SHIFT, &ddr_phy->ddrphy_reg8);
+ writel((2 & RIGHT_CHN_RX_DQS_DELAY_TAP_MASK) <<
+ RIGHT_CHN_RX_DQS_DELAY_TAP_SHIFT, &ddr_phy->ddrphy_reg11);
+}
+
+static void send_command(u32 rank, u32 cmd, u32 arg)
+{
+ writel((START_CMD | (rank << 20) | arg | cmd), &pctl->mcmd);
+ rockchip_udelay(1);
+ while (readl(&pctl->mcmd) & START_CMD)
+ ;
+}
+
+static void memory_init(void)
+{
+ send_command(3, DESELECT_CMD, 0);
+ rockchip_udelay(1);
+ send_command(3, PREA_CMD, 0);
+ send_command(3, MRS_CMD, (0x02 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
+ (ddr_timing.phy_timing.mr[2] & CMD_ADDR_MASK) <<
+ CMD_ADDR_SHIFT);
+
+ send_command(3, MRS_CMD, (0x03 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
+ (ddr_timing.phy_timing.mr[3] & CMD_ADDR_MASK) <<
+ CMD_ADDR_SHIFT);
+
+ send_command(3, MRS_CMD, (0x01 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
+ (ddr_timing.phy_timing.mr[1] & CMD_ADDR_MASK) <<
+ CMD_ADDR_SHIFT);
+
+ send_command(3, MRS_CMD, (0x00 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
+ (ddr_timing.phy_timing.mr[0] & CMD_ADDR_MASK) <<
+ CMD_ADDR_SHIFT | DDR3_DLL_RESET);
+
+ send_command(3, ZQCL_CMD, 0);
+}
+
+static void data_training(void)
+{
+ u32 value;
+
+ /* disable auto refresh */
+ value = readl(&pctl->trefi),
+ writel(0, &pctl->trefi);
+
+ clrsetbits_le32(&ddr_phy->ddrphy_reg2, 0x03,
+ DQS_SQU_CAL_NORMAL_MODE | DQS_SQU_CAL_START);
+
+ rockchip_udelay(10);
+ while ((readl(&ddr_phy->ddrphy_reg62) & CAL_DONE_MASK) !=
+ (HIGH_8BIT_CAL_DONE | LOW_8BIT_CAL_DONE)) {
+ ;
+ }
+
+ clrsetbits_le32(&ddr_phy->ddrphy_reg2, 0x03,
+ DQS_SQU_CAL_NORMAL_MODE | DQS_SQU_NO_CAL);
+ send_command(3, REF_CMD, 0);
+ send_command(3, REF_CMD, 0);
+ send_command(3, REF_CMD, 0);
+
+ writel(value, &pctl->trefi);
+}
+
+static void move_to_config_state(void)
+{
+ unsigned int state;
+
+ while (1) {
+ state = readl(&pctl->stat) & PCTL_STAT_MASK;
+ switch (state) {
+ case LOW_POWER:
+ writel(WAKEUP_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MASK)
+ != ACCESS)
+ ;
+ /* if at low power state,need wakeup first,
+ * and then enter the config
+ * so fallthrough.
+ */
+ case ACCESS:
+ /* fallthrough */
+ case INIT_MEM:
+ writel(CFG_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MASK) != CONFIG)
+ ;
+ break;
+
+ case CONFIG:
+ return;
+ default:
+ break;
+ }
+ }
+}
+
+static void move_to_access_state(void)
+{
+ unsigned int state;
+
+ while (1) {
+ state = readl(&pctl->stat) & PCTL_STAT_MASK;
+ switch (state) {
+ case LOW_POWER:
+ writel(WAKEUP_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MASK) != ACCESS)
+ ;
+ break;
+ case INIT_MEM:
+ writel(CFG_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MASK) != CONFIG)
+ ;
+ /* fallthrough */
+ case CONFIG:
+ writel(GO_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MASK) != ACCESS)
+ ;
+ break;
+ case ACCESS:
+ return;
+ default:
+ break;
+ }
+ }
+}
+
+static void pctl_cfg(void)
+{
+ u32 burst_len;
+ u32 reg;
+
+ writel(DFI_INIT_START | DFI_DATA_BYTE_DISABLE_EN, &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(1, &pctl->dfitphyupdtype0);
+ writel(0x0d, &pctl->dfitphyrdlat);
+
+ /* 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);
+
+ if ((ddr_timing.noc_timing.burstlen << 1) == 4)
+ burst_len = MEM_BL4;
+ else
+ burst_len = MEM_BL8;
+
+ copy_to_reg(&pctl->togcnt1u, &ddr_timing.pctl_timing.togcnt1u,
+ sizeof(struct rk3036_pctl_timing));
+
+ reg = readl(&pctl->tcl);
+ writel(reg - 3, &pctl->dfitrddataen);
+ reg = readl(&pctl->tcwl);
+ writel(reg - 1, &pctl->dfitphywrlat);
+
+ writel(burst_len | (1 & TFAW_CFG_MASK) << TFAW_CFG_SHIFT |
+ PD_EXIT_SLOW_MODE | PD_ACTIVE_POWER_DOWN |
+ (0 & PD_IDLE_MASK) << PD_IDLE_SHIFT,
+ &pctl->mcfg);
+
+ writel(RK_SETBITS(MSCH4_MAINDDR3), &grf->soc_con2);
+ setbits_le32(&pctl->scfg, HW_LOW_POWER_EN);
+}
+
+static void phy_cfg(void)
+{
+ writel(ddr_timing.noc_timing.noc_timing, &axi_bus->ddrtiming);
+ writel(0x3f, &axi_bus->readlatency);
+
+ writel(MEMORY_SELECT_DDR3 | DQS_SQU_CAL_NORMAL_MODE,
+ &ddr_phy->ddrphy_reg2);
+
+ clrsetbits_le32(&ddr_phy->ddrphy_reg3, 1, ddr_timing.phy_timing.bl);
+ writel(ddr_timing.phy_timing.cl_al, &ddr_phy->ddrphy_reg4a);
+ writel(PHY_DRV_ODT_SET(PHY_RON_44OHM), &ddr_phy->ddrphy_reg16);
+ writel(PHY_DRV_ODT_SET(PHY_RON_44OHM), &ddr_phy->ddrphy_reg22);
+ writel(PHY_DRV_ODT_SET(PHY_RON_44OHM), &ddr_phy->ddrphy_reg25);
+ writel(PHY_DRV_ODT_SET(PHY_RON_44OHM), &ddr_phy->ddrphy_reg26);
+ writel(PHY_DRV_ODT_SET(PHY_RTT_216OHM), &ddr_phy->ddrphy_reg27);
+ writel(PHY_DRV_ODT_SET(PHY_RTT_216OHM), &ddr_phy->ddrphy_reg28);
+}
+
+void dram_cfg_rbc(void)
+{
+ char noc_config;
+ int i = 0;
+
+ move_to_config_state();
+
+ /* 2bit in BIT1, 2 */
+ if (ddr_config.rank == 2) {
+ noc_config = (ddr_config.cs0_row - 13) << 4 | ddr_config.bank << 1 |
+ 1 << 3 | (ddr_config.col - 10);
+ if (noc_config == ddr_cfg_2_rbc[9]) {
+ i = 9;
+ goto finish;
+ } else if (noc_config == ddr_cfg_2_rbc[10]) {
+ i = 10;
+ goto finish;
+ }
+ }
+
+ noc_config = (ddr_config.cs0_row - 13) << 4 | ddr_config.bank << 1 |
+ (ddr_config.col - 10);
+
+ for (i = 0; i < sizeof(ddr_cfg_2_rbc); i++) {
+ if (noc_config == ddr_cfg_2_rbc[i])
+ goto finish;
+ }
+
+ /* bank: 1 bit in BIT6,7, 1bit in BIT1, 2 */
+ noc_config = 1 << 6 | (ddr_config.cs0_row - 13) << 4 |
+ 2 << 1 | (ddr_config.col - 10);
+ if (noc_config == ddr_cfg_2_rbc[11]) {
+ i = 11;
+ goto finish;
+ }
+
+ /* bank: 2bit in BIT6,7 */
+ noc_config = (ddr_config.bank << 6) | (ddr_config.cs0_row - 13) << 4 |
+ (ddr_config.col - 10);
+
+ if (noc_config == ddr_cfg_2_rbc[0])
+ i = 0;
+ else if (noc_config == ddr_cfg_2_rbc[12])
+ i = 12;
+ else if (noc_config == ddr_cfg_2_rbc[13])
+ i = 13;
+finish:
+ writel(i, &axi_bus->ddrconf);
+ move_to_access_state();
+
+ return;
+}
+
+static void sdram_all_config(void)
+{
+ u32 os_reg = 0;
+
+ os_reg = ddr_config.ddr_type << DDR_TYPE_SHIFT |
+ 0 << DDR_CHN_CNT_SHIFT |
+ (ddr_config.rank - 1) << DDR_RANK_CNT_SHIFT |
+ (ddr_config.col - 1) << DDR_COL_SHIFT |
+ (ddr_config.bank == 3 ? 0 : 1) << DDR_BANK_SHIFT |
+ (ddr_config.cs0_row - 13) << DDR_CS0_ROW_SHIFT |
+ (ddr_config.cs1_row - 13) << DDR_CS1_ROW_SHIFT |
+ 1 << DDR_BW_SHIFT | ddr_config.bw << DDR_DIE_BW_SHIFT;
+ writel(os_reg, &grf->os_reg[1]);
+}
+
+size_t sdram_size(void)
+{
+ u32 size, os_reg, cs0_row, cs1_row, col, bank, rank;
+
+ os_reg = readl(&grf->os_reg[1]);
+ print_hex(os_reg);
+
+ cs0_row = 13 + ((os_reg >> DDR_CS0_ROW_SHIFT) & DDR_CS0_ROW_MASK);
+ cs1_row = 13 + ((os_reg >> DDR_CS1_ROW_SHIFT) & DDR_CS1_ROW_MASK);
+ col = 9 + ((os_reg >> DDR_COL_SHIFT) & DDR_COL_MASK);
+ bank = 3 - ((os_reg >> DDR_BANK_SHIFT) & DDR_BANK_MASK);
+ rank = 1 + ((os_reg >> DDR_RANK_CNT_SHIFT) & DDR_RANK_CNT_MASK);
+
+ /* row + col + bank + bw(rk3036 only support 16bit, so fix in 1) */
+ size = 1 << (cs0_row + col + bank + 1);
+
+ if (rank > 1)
+ size += size >> (cs0_row - cs1_row);
+
+ return size;
+}
+
+__weak void get_ddr_config(struct rk3036_ddr_config *config)
+{
+
+}
+
+void sdram_init(void)
+{
+ get_ddr_config(&ddr_config);
+ sdram_all_config();
+ rkdclk_init();
+ phy_pctrl_reset();
+ phy_dll_bypass_set(ddr_timing.freq);
+ pctl_cfg();
+ phy_cfg();
+ writel(POWER_UP_START, &pctl->powctl);
+ while (!(readl(&pctl->powstat) & POWER_UP_DONE))
+ ;
+ memory_init();
+ move_to_config_state();
+ data_training();
+ move_to_access_state();
+ dram_cfg_rbc();
+ print("ddr init sucess\n");
+}
+
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [U-Boot] [PATCH v2 16/17] rockchip: rk3036: Add core Soc start-up code
2015-11-04 12:53 [U-Boot] [PATCH v2 00/17] Lin Huang
` (14 preceding siblings ...)
2015-11-04 12:53 ` [U-Boot] [PATCH v2 15/17] rockchip: add rk3036 sdram driver Lin Huang
@ 2015-11-04 12:53 ` Lin Huang
2015-11-06 9:11 ` Sjoerd Simons
2015-11-04 12:53 ` [U-Boot] [PATCH v2 17/17] rockchip: Add basic support for evb-rk3036 board Lin Huang
16 siblings, 1 reply; 21+ messages in thread
From: Lin Huang @ 2015-11-04 12:53 UTC (permalink / raw)
To: u-boot
rk3036 only 4K size SRAM for SPL, so only support
timer, uart, sdram driver in SPL stage, when finish
initial sdram, back to bootrom.
Signed-off-by: Lin Huang <hl@rock-chips.com>
---
Changes in v1:
- clean copyright announcement
Changes in v2:
- support SPL
arch/arm/mach-rockchip/Kconfig | 10 +-
arch/arm/mach-rockchip/Makefile | 4 +-
arch/arm/mach-rockchip/board.c | 1 +
arch/arm/mach-rockchip/rk3036-board-spl.c | 44 +++++++++
arch/arm/mach-rockchip/rk3036/Kconfig | 17 ++++
arch/arm/mach-rockchip/rk3036/Makefile | 1 +
arch/arm/mach-rockchip/rk3036/save_boot_param.S | 34 +++++++
include/configs/rk3036_common.h | 120 ++++++++++++++++++++++++
8 files changed, 229 insertions(+), 2 deletions(-)
create mode 100644 arch/arm/mach-rockchip/rk3036-board-spl.c
create mode 100644 arch/arm/mach-rockchip/rk3036/Kconfig
create mode 100644 arch/arm/mach-rockchip/rk3036/save_boot_param.S
create mode 100644 include/configs/rk3036_common.h
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index da665ef..6b608db 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -9,6 +9,14 @@ config ROCKCHIP_RK3288
and video codec support. Peripherals include Gigabit Ethernet,
USB2 host and OTG, SDIO, I2S, UART,s, SPI, I2C and PWMs.
+config ROCKCHIP_RK3036
+ bool "Support Rockchip RK3036"
+ help
+ The Rockchip RK3036 is a ARM-based SoC with a dual-core Cortex-A7
+ including NEON and GPU, Mali-400 graphics, several DDR3 options
+ and video codec support. Peripherals include Gigabit Ethernet,
+ USB2 host and OTG, SDIO, I2S, UART, SPI, I2C and PWMs.
+
config SYS_MALLOC_F
default y
@@ -34,5 +42,5 @@ config ROCKCHIP_SERIAL
default y
source "arch/arm/mach-rockchip/rk3288/Kconfig"
-
+source "arch/arm/mach-rockchip/rk3036/Kconfig"
endif
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index a29675d..b703c3c 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -6,10 +6,12 @@
ifdef CONFIG_SPL_BUILD
obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-spl.o
+obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board-spl.o
else
-obj-y += board.o
+obj-$(CONFIG_ROCKCHIP_RK3288) += board.o
endif
obj-y += rk_timer.o
obj-y += rk_early_print.o
obj-$(CONFIG_$(SPL_)ROCKCHIP_COMMON) += common.o
obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288/
+obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/
diff --git a/arch/arm/mach-rockchip/board.c b/arch/arm/mach-rockchip/board.c
index 688bc0f..d7a8312 100644
--- a/arch/arm/mach-rockchip/board.c
+++ b/arch/arm/mach-rockchip/board.c
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: GPL-2.0+
*/
+#include <asm/io.h>
#include <common.h>
#include <dm.h>
#include <ram.h>
diff --git a/arch/arm/mach-rockchip/rk3036-board-spl.c b/arch/arm/mach-rockchip/rk3036-board-spl.c
new file mode 100644
index 0000000..734dfe5
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3036-board-spl.c
@@ -0,0 +1,44 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <asm/arch/grf_rk3036.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sdram_rk3036.h>
+#include <asm/arch/timer.h>
+#include <asm/arch/uart.h>
+#include <asm/io.h>
+#include <common.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define GRF_BASE 0x20008000
+static struct rk3036_grf * const grf = (void *)GRF_BASE;
+
+extern void back_to_bootrom(void);
+
+void board_init_f(ulong dummy)
+{
+ //Debug UART can be used from here if required:
+ rk_clrsetreg(&grf->gpio1c_iomux,
+ GPIO1C3_MASK << GPIO1C3_SHIFT |
+ GPIO1C2_MASK << GPIO1C2_SHIFT,
+ GPIO1C3_UART2_SOUT << GPIO1C3_SHIFT |
+ GPIO1C2_UART2_SIN << GPIO1C2_SHIFT);
+ rk_uart_init();
+ rockchip_timer_init();
+ sdram_init();
+
+ /* return to maskrom */
+ back_to_bootrom();
+}
+
+/* Place Holders */
+void board_init_r(gd_t *id, ulong dest_addr)
+{
+ /* Function attribute is no-return */
+ /* This Function never executes */
+ while (1)
+ ;
+}
diff --git a/arch/arm/mach-rockchip/rk3036/Kconfig b/arch/arm/mach-rockchip/rk3036/Kconfig
new file mode 100644
index 0000000..0fbc58e
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3036/Kconfig
@@ -0,0 +1,17 @@
+if ROCKCHIP_RK3036
+
+config TARGET_EVB_RK3036
+ bool "EVB_RK3036"
+
+config SYS_SOC
+ default "rockchip"
+
+config SYS_MALLOC_F_LEN
+ default 0x400
+
+config ROCKCHIP_COMMON
+ bool "Support rk common fuction"
+
+source "board/evb_rk3036/evb_rk3036/Kconfig"
+
+endif
diff --git a/arch/arm/mach-rockchip/rk3036/Makefile b/arch/arm/mach-rockchip/rk3036/Makefile
index 6095777..97d299d 100644
--- a/arch/arm/mach-rockchip/rk3036/Makefile
+++ b/arch/arm/mach-rockchip/rk3036/Makefile
@@ -10,3 +10,4 @@ obj-y += syscon_rk3036.o
endif
obj-y += sdram_rk3036.o
+obj-y += save_boot_param.o
diff --git a/arch/arm/mach-rockchip/rk3036/save_boot_param.S b/arch/arm/mach-rockchip/rk3036/save_boot_param.S
new file mode 100644
index 0000000..3d3883d
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3036/save_boot_param.S
@@ -0,0 +1,34 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <linux/linkage.h>
+
+.globl SAVE_SP_ADDR
+SAVE_SP_ADDR:
+ .word 0
+
+/*************************************************************************
+ *
+ * void save_boot_params
+ *
+ * Save sp, lr, r1~r12
+ *
+ *************************************************************************/
+ENTRY(save_boot_params)
+ push {r1-r12, lr}
+ ldr r0, =SAVE_SP_ADDR
+ str sp, [r0]
+ b save_boot_params_ret @ back to my caller
+ENDPROC(save_boot_params)
+
+
+.globl back_to_bootrom
+ENTRY(back_to_bootrom)
+ ldr r0, =SAVE_SP_ADDR
+ ldr sp, [r0]
+ mov r0, #0
+ pop {r1-r12, pc}
+ENDPROC(back_to_bootrom)
diff --git a/include/configs/rk3036_common.h b/include/configs/rk3036_common.h
new file mode 100644
index 0000000..f7bd852
--- /dev/null
+++ b/include/configs/rk3036_common.h
@@ -0,0 +1,120 @@
+/*
+ * (C) Copyright 2015 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef __CONFIG_RK3036_COMMON_H
+#define __CONFIG_RK3036_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_BASE 0x200440a0 /* TIMER5 */
+#define CONFIG_SYS_TIMER_COUNTER (CONFIG_SYS_TIMER_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 0x60000000
+#define CONFIG_SYS_INIT_SP_ADDR 0x60100000
+#define CONFIG_SYS_LOAD_ADDR 0x60800800
+#define CONFIG_SPL_STACK 0x10081fff
+#define CONFIG_SPL_TEXT_BASE 0x10081004
+
+#define CONFIG_ROCKCHIP_COMMON
+
+/* MMC/SD IP block */
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_CMD_MMC
+#define CONFIG_SDHCI
+#define CONFIG_ROCKCHIP_3036_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 0x60000000
+#define CONFIG_NR_DRAM_BANKS 1
+#define SDRAM_BANK_SIZE (512UL << 20UL)
+
+#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>
+
+#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
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [U-Boot] [PATCH v2 16/17] rockchip: rk3036: Add core Soc start-up code
2015-11-04 12:53 ` [U-Boot] [PATCH v2 16/17] rockchip: rk3036: Add core Soc start-up code Lin Huang
@ 2015-11-06 9:11 ` Sjoerd Simons
2015-11-06 9:47 ` Eddie Cai
2015-11-06 9:59 ` hl
0 siblings, 2 replies; 21+ messages in thread
From: Sjoerd Simons @ 2015-11-06 9:11 UTC (permalink / raw)
To: u-boot
On Wed, 2015-11-04 at 20:53 +0800, Lin Huang wrote:
> rk3036 only 4K size SRAM for SPL, so only support
> timer, uart, sdram driver in SPL stage, when finish
> initial sdram, back to bootrom.
>
> Signed-off-by: Lin Huang <hl@rock-chips.com>
>?
>?
> diff --git a/arch/arm/mach-rockchip/rk3036/save_boot_param.S
> b/arch/arm/mach-rockchip/rk3036/save_boot_param.S
> new file mode 100644
> index 0000000..3d3883d
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/rk3036/save_boot_param.S
> @@ -0,0 +1,34 @@
> +/*
> + * (C) Copyright 2015 Google, Inc
> + *
> + * SPDX-License-Identifier:?????GPL-2.0+
> + */
> +
> +#include <linux/linkage.h>
> +
> +.globl SAVE_SP_ADDR
> +SAVE_SP_ADDR:
> + .word 0
> +
> +/*******************************************************************
> ******
> + *
> + * void save_boot_params
> + *
> + * Save sp, lr, r1~r12
> + *
> +
> *********************************************************************
> ****/
> +ENTRY(save_boot_params)
> + push {r1-r12, lr}
> + ldr r0, =SAVE_SP_ADDR
> + str sp, [r0]
> + b save_boot_params_ret @ back to my
> caller
> +ENDPROC(save_boot_params)
> +
> +
> +.globl back_to_bootrom
> +ENTRY(back_to_bootrom)
> + ldr r0, =SAVE_SP_ADDR
> + ldr sp, [r0]
> + mov r0, #0
> + pop {r1-r12, pc}
> +ENDPROC(back_to_bootrom)
Is this way of going back to be bootrom generic for other Rockchip SOCs
as well??
Specifically for RK3288 in maskrom mode we can currently load the?
u-boot SPL, but not the main loader. If we could use this method of
going to the bootrom on that board that should be a nice way forward.
> diff --git a/include/configs/rk3036_common.h
> b/include/configs/rk3036_common.h
> new file mode 100644
> index 0000000..f7bd852
> --- /dev/null
> +++ b/include/configs/rk3036_common.h
> @@ -0,0 +1,120 @@
> +/*
> + * (C) Copyright 2015 Rockchip Electronics Co., Ltd
> + *
> + * SPDX-License-Identifier:?????GPL-2.0+
> + */
>?
> +/* RAW SD card / eMMC locations. */
> +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 256
> +#define CONFIG_SYS_SPI_U_BOOT_OFFS (128 << 10)
I don't think you need to define these if you're having the main u-boot
image loaded by your bootrom rather then SPL directly.
> +/* FAT sd card locations. */
> +#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1
> +#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img"
ditto
> +/* #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 0x60000000
> +#define CONFIG_NR_DRAM_BANKS 1
> +#define SDRAM_BANK_SIZE (512UL << 20UL)
> +
> +#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>
> +
> +#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"
I suspect these offset don't make sense for this board given your
SYS_SDRAM_BASE is?0x60000000
> +/* 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 */
You probably want to change the comment here :)
> +#define CONFIG_EXTRA_ENV_SETTINGS \
> + "fdt_high=0x1fffffff\0" \
Hopefully the fdt_high isn't needed on 3036? (It's hopefully temporary
as well on 3288 until someone figures out what's wrong.
> + ENV_MEM_LAYOUT_SETTINGS \
> + BOOTENV
> +#endif
> +
> +#endif
--
Sjoerd Simons
Collabora Ltd.
^ permalink raw reply [flat|nested] 21+ messages in thread* [U-Boot] [PATCH v2 16/17] rockchip: rk3036: Add core Soc start-up code
2015-11-06 9:11 ` Sjoerd Simons
@ 2015-11-06 9:47 ` Eddie Cai
2015-11-06 9:59 ` hl
1 sibling, 0 replies; 21+ messages in thread
From: Eddie Cai @ 2015-11-06 9:47 UTC (permalink / raw)
To: u-boot
Hi Sjoerd
2015-11-06 17:11 GMT+08:00 Sjoerd Simons <sjoerd.simons@collabora.co.uk>:
> On Wed, 2015-11-04 at 20:53 +0800, Lin Huang wrote:
> > rk3036 only 4K size SRAM for SPL, so only support
> > timer, uart, sdram driver in SPL stage, when finish
> > initial sdram, back to bootrom.
> >
> > Signed-off-by: Lin Huang <hl@rock-chips.com>
> >
> >
> > diff --git a/arch/arm/mach-rockchip/rk3036/save_boot_param.S
> > b/arch/arm/mach-rockchip/rk3036/save_boot_param.S
> > new file mode 100644
> > index 0000000..3d3883d
> > --- /dev/null
> > +++ b/arch/arm/mach-rockchip/rk3036/save_boot_param.S
> > @@ -0,0 +1,34 @@
> > +/*
> > + * (C) Copyright 2015 Google, Inc
> > + *
> > + * SPDX-License-Identifier: GPL-2.0+
> > + */
> > +
> > +#include <linux/linkage.h>
> > +
> > +.globl SAVE_SP_ADDR
> > +SAVE_SP_ADDR:
> > + .word 0
> > +
> > +/*******************************************************************
> > ******
> > + *
> > + * void save_boot_params
> > + *
> > + * Save sp, lr, r1~r12
> > + *
> > +
> > *********************************************************************
> > ****/
> > +ENTRY(save_boot_params)
> > + push {r1-r12, lr}
> > + ldr r0, =SAVE_SP_ADDR
> > + str sp, [r0]
> > + b save_boot_params_ret @ back to my
> > caller
> > +ENDPROC(save_boot_params)
> > +
> > +
> > +.globl back_to_bootrom
> > +ENTRY(back_to_bootrom)
> > + ldr r0, =SAVE_SP_ADDR
> > + ldr sp, [r0]
> > + mov r0, #0
> > + pop {r1-r12, pc}
> > +ENDPROC(back_to_bootrom)
>
> Is this way of going back to be bootrom generic for other Rockchip SOCs
> as well?
>
Yes
>
> Specifically for RK3288 in maskrom mode we can currently load the
> u-boot SPL, but not the main loader. If we could use this method of
> going to the bootrom on that board that should be a nice way forward.
>
Agree.
Simon.What do you think?
>
>
> > diff --git a/include/configs/rk3036_common.h
> > b/include/configs/rk3036_common.h
> > new file mode 100644
> > index 0000000..f7bd852
> > --- /dev/null
> > +++ b/include/configs/rk3036_common.h
> > @@ -0,0 +1,120 @@
> > +/*
> > + * (C) Copyright 2015 Rockchip Electronics Co., Ltd
> > + *
> > + * SPDX-License-Identifier: GPL-2.0+
> > + */
> >
> > +/* RAW SD card / eMMC locations. */
> > +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 256
> > +#define CONFIG_SYS_SPI_U_BOOT_OFFS (128 << 10)
>
> I don't think you need to define these if you're having the main u-boot
> image loaded by your bootrom rather then SPL directly.
>
> > +/* FAT sd card locations. */
> > +#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1
> > +#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img"
>
> ditto
>
> > +/* #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 0x60000000
> > +#define CONFIG_NR_DRAM_BANKS 1
> > +#define SDRAM_BANK_SIZE (512UL << 20UL)
> > +
> > +#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>
> > +
> > +#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"
>
> I suspect these offset don't make sense for this board given your
> SYS_SDRAM_BASE is 0x60000000
>
> > +/* 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 */
>
> You probably want to change the comment here :)
>
> > +#define CONFIG_EXTRA_ENV_SETTINGS \
> > + "fdt_high=0x1fffffff\0" \
>
> Hopefully the fdt_high isn't needed on 3036? (It's hopefully temporary
> as well on 3288 until someone figures out what's wrong.
>
> > + ENV_MEM_LAYOUT_SETTINGS \
> > + BOOTENV
> > +#endif
> > +
> > +#endif
>
> --
> Sjoerd Simons
> Collabora Ltd.
>
>
>
--
Eddie
^ permalink raw reply [flat|nested] 21+ messages in thread* [U-Boot] [PATCH v2 16/17] rockchip: rk3036: Add core Soc start-up code
2015-11-06 9:11 ` Sjoerd Simons
2015-11-06 9:47 ` Eddie Cai
@ 2015-11-06 9:59 ` hl
1 sibling, 0 replies; 21+ messages in thread
From: hl @ 2015-11-06 9:59 UTC (permalink / raw)
To: u-boot
Hi
On 06/11/15 17:11, Sjoerd Simons wrote:
> On Wed, 2015-11-04 at 20:53 +0800, Lin Huang wrote:
>> rk3036 only 4K size SRAM for SPL, so only support
>> timer, uart, sdram driver in SPL stage, when finish
>> initial sdram, back to bootrom.
>>
>> Signed-off-by: Lin Huang <hl@rock-chips.com>
>>
>>
>> diff --git a/arch/arm/mach-rockchip/rk3036/save_boot_param.S
>> b/arch/arm/mach-rockchip/rk3036/save_boot_param.S
>> new file mode 100644
>> index 0000000..3d3883d
>> --- /dev/null
>> +++ b/arch/arm/mach-rockchip/rk3036/save_boot_param.S
>> @@ -0,0 +1,34 @@
>> +/*
>> + * (C) Copyright 2015 Google, Inc
>> + *
>> + * SPDX-License-Identifier: GPL-2.0+
>> + */
>> +
>> +#include <linux/linkage.h>
>> +
>> +.globl SAVE_SP_ADDR
>> +SAVE_SP_ADDR:
>> + .word 0
>> +
>> +/*******************************************************************
>> ******
>> + *
>> + * void save_boot_params
>> + *
>> + * Save sp, lr, r1~r12
>> + *
>> +
>> *********************************************************************
>> ****/
>> +ENTRY(save_boot_params)
>> + push {r1-r12, lr}
>> + ldr r0, =SAVE_SP_ADDR
>> + str sp, [r0]
>> + b save_boot_params_ret @ back to my
>> caller
>> +ENDPROC(save_boot_params)
>> +
>> +
>> +.globl back_to_bootrom
>> +ENTRY(back_to_bootrom)
>> + ldr r0, =SAVE_SP_ADDR
>> + ldr sp, [r0]
>> + mov r0, #0
>> + pop {r1-r12, pc}
>> +ENDPROC(back_to_bootrom)
> Is this way of going back to be bootrom generic for other Rockchip SOCs
> as well?
>
> Specifically for RK3288 in maskrom mode we can currently load the
> u-boot SPL, but not the main loader. If we could use this method of
> going to the bootrom on that board that should be a nice way forward.
>
>
>> diff --git a/include/configs/rk3036_common.h
>> b/include/configs/rk3036_common.h
>> new file mode 100644
>> index 0000000..f7bd852
>> --- /dev/null
>> +++ b/include/configs/rk3036_common.h
>> @@ -0,0 +1,120 @@
>> +/*
>> + * (C) Copyright 2015 Rockchip Electronics Co., Ltd
>> + *
>> + * SPDX-License-Identifier: GPL-2.0+
>> + */
>>
>> +/* RAW SD card / eMMC locations. */
>> +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 256
>> +#define CONFIG_SYS_SPI_U_BOOT_OFFS (128 << 10)
> I don't think you need to define these if you're having the main u-boot
> image loaded by your bootrom rather then SPL directly.
yes, you are right, i just sended v3, will correct it in v4, thank you.
>> +/* FAT sd card locations. */
>> +#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1
>> +#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img"
> ditto
>
>> +/* #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 0x60000000
>> +#define CONFIG_NR_DRAM_BANKS 1
>> +#define SDRAM_BANK_SIZE (512UL << 20UL)
>> +
>> +#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>
>> +
>> +#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"
> I suspect these offset don't make sense for this board given your
> SYS_SDRAM_BASE is 0x60000000
Have been correct in v3 patch.
>> +/* 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 */
> You probably want to change the comment here :)
>
yes, will modify it in v4
>> +#define CONFIG_EXTRA_ENV_SETTINGS \
>> + "fdt_high=0x1fffffff\0" \
> Hopefully the fdt_high isn't needed on 3036? (It's hopefully temporary
> as well on 3288 until someone figures out what's wrong.
sorry, i am not very clear why 3288 need it.
>> + ENV_MEM_LAYOUT_SETTINGS \
>> + BOOTENV
>> +#endif
>> +
>> +#endif
--
Lin Huang
^ permalink raw reply [flat|nested] 21+ messages in thread
* [U-Boot] [PATCH v2 17/17] rockchip: Add basic support for evb-rk3036 board
2015-11-04 12:53 [U-Boot] [PATCH v2 00/17] Lin Huang
` (15 preceding siblings ...)
2015-11-04 12:53 ` [U-Boot] [PATCH v2 16/17] rockchip: rk3036: Add core Soc start-up code Lin Huang
@ 2015-11-04 12:53 ` Lin Huang
16 siblings, 0 replies; 21+ messages in thread
From: Lin Huang @ 2015-11-04 12:53 UTC (permalink / raw)
To: u-boot
This add some basic files required to allow the board to dispaly
serial message and can run command(mmc info etc)
Signed-off-by: Lin Huang <hl@rock-chips.com>
---
Changes in v1:
- clean copyright announcement
Changes in v2:
- get sdram info from evb_rk3036.c
arch/arm/dts/Makefile | 3 +-
arch/arm/dts/rk3036-sdk.dts | 46 ++++++++++++++++++++++++++++++
board/evb_rk3036/evb_rk3036/Kconfig | 15 ++++++++++
board/evb_rk3036/evb_rk3036/MAINTAINERS | 0
board/evb_rk3036/evb_rk3036/Makefile | 7 +++++
board/evb_rk3036/evb_rk3036/evb_rk3036.c | 48 ++++++++++++++++++++++++++++++++
configs/evb-rk3036_defconfig | 29 +++++++++++++++++++
include/configs/evb_rk3036.h | 12 ++++++++
8 files changed, 159 insertions(+), 1 deletion(-)
create mode 100644 arch/arm/dts/rk3036-sdk.dts
create mode 100644 board/evb_rk3036/evb_rk3036/Kconfig
create mode 100644 board/evb_rk3036/evb_rk3036/MAINTAINERS
create mode 100644 board/evb_rk3036/evb_rk3036/Makefile
create mode 100644 board/evb_rk3036/evb_rk3036/evb_rk3036.c
create mode 100644 configs/evb-rk3036_defconfig
create mode 100644 include/configs/evb_rk3036.h
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 3babe65..d007199 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -17,7 +17,8 @@ dtb-$(CONFIG_EXYNOS5) += exynos5250-arndale.dtb \
exynos5422-odroidxu3.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += \
rk3288-firefly.dtb \
- rk3288-jerry.dtb
+ rk3288-jerry.dtb \
+ rk3036-sdk.dtb
dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
tegra20-medcom-wide.dtb \
tegra20-paz00.dtb \
diff --git a/arch/arm/dts/rk3036-sdk.dts b/arch/arm/dts/rk3036-sdk.dts
new file mode 100644
index 0000000..a83badb
--- /dev/null
+++ b/arch/arm/dts/rk3036-sdk.dts
@@ -0,0 +1,46 @@
+/*
+ * (C) Copyright 2015 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/dts-v1/;
+
+#include "rk3036.dtsi"
+
+/ {
+ model = "SDK-RK3036";
+ compatible = "sdk,sdk-rk3036", "rockchip,rk3036";
+
+ chosen {
+ stdout-path = &uart2;
+ };
+
+ usb_control {
+ compatible = "rockchip,rk3036-usb-control";
+ host_drv_gpio = <&gpio2 23 GPIO_ACTIVE_LOW>;
+ otg_drv_gpio = <&gpio0 26 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&i2c1 {
+ status = "okay";
+
+ hym8563: hym8563 at 51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "xin32k";
+ };
+};
+
+&usb_host {
+ status = "okay";
+};
+
+&usb_otg {
+ status = "okay";
+
+ dr_mode = "host";
+};
diff --git a/board/evb_rk3036/evb_rk3036/Kconfig b/board/evb_rk3036/evb_rk3036/Kconfig
new file mode 100644
index 0000000..ae2a9eb
--- /dev/null
+++ b/board/evb_rk3036/evb_rk3036/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_EVB_RK3036
+
+config SYS_BOARD
+ default "evb_rk3036"
+
+config SYS_VENDOR
+ default "evb_rk3036"
+
+config SYS_CONFIG_NAME
+ default "evb_rk3036"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+ def_bool y
+
+endif
diff --git a/board/evb_rk3036/evb_rk3036/MAINTAINERS b/board/evb_rk3036/evb_rk3036/MAINTAINERS
new file mode 100644
index 0000000..e69de29
diff --git a/board/evb_rk3036/evb_rk3036/Makefile b/board/evb_rk3036/evb_rk3036/Makefile
new file mode 100644
index 0000000..0403836
--- /dev/null
+++ b/board/evb_rk3036/evb_rk3036/Makefile
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2015 Google, Inc
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += evb_rk3036.o
diff --git a/board/evb_rk3036/evb_rk3036/evb_rk3036.c b/board/evb_rk3036/evb_rk3036/evb_rk3036.c
new file mode 100644
index 0000000..52d45e5
--- /dev/null
+++ b/board/evb_rk3036/evb_rk3036/evb_rk3036.c
@@ -0,0 +1,48 @@
+/*
+ * (C) Copyright 2015 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <asm/arch/sdram_rk3036.h>
+#include <asm/arch/uart.h>
+#include <asm/io.h>
+#include <common.h>
+#include <dm.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void get_ddr_config(struct rk3036_ddr_config *config)
+{
+ /* K4B4G1646Q config */
+ config->ddr_type = 3;
+ config->rank = 2;
+ config->cs0_row = 15;
+ config->cs1_row = 15;
+
+ /* 8bank */
+ config->bank = 3;
+ config->col = 10;
+
+ /* 16bit bw */
+ config->bw = 1;
+}
+
+int board_init(void)
+{
+ return 0;
+}
+
+int dram_init(void)
+{
+ gd->ram_size = sdram_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/configs/evb-rk3036_defconfig b/configs/evb-rk3036_defconfig
new file mode 100644
index 0000000..6585a34
--- /dev/null
+++ b/configs/evb-rk3036_defconfig
@@ -0,0 +1,29 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_ROCKCHIP_RK3036=y
+CONFIG_TARGET_EVB_RK3036=y
+CONFIG_DEFAULT_DEVICE_TREE="rk3036-sdk"
+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_CLK=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_RESET=y
+CONFIG_LED=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_BASE=0x20068000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_PINCTRL=y
+CONFIG_ROCKCHIP_3036_PINCTRL=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_RAM=y
+CONFIG_DM_MMC=y
+CONFIG_USE_PRIVATE_LIBGCC=y
+CONFIG_CMD_DHRYSTONE=y
+CONFIG_ERRNO_STR=y
diff --git a/include/configs/evb_rk3036.h b/include/configs/evb_rk3036.h
new file mode 100644
index 0000000..aa07889
--- /dev/null
+++ b/include/configs/evb_rk3036.h
@@ -0,0 +1,12 @@
+/*
+ * (C) Copyright 2015 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <configs/rk3036_common.h>
+
+#endif
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread