From d2d763fa837e7f1d769fd00bb730c3abc6650667 Mon Sep 17 00:00:00 2001 From: Xu Ziyuan Date: Thu, 28 Jul 2016 11:42:34 +0800 Subject: [PATCH 01/12] rockchip: add fastboot support for rk3036 board Enable fastboot feature on rk3036, please refer to doc/README.rockchip for more detailed usage. Signed-off-by: Ziyuan Xu Reviewed-by: Simon Glass --- arch/arm/dts/rk3036-sdk.dts | 2 - board/rockchip/evb_rk3036/evb_rk3036.c | 46 ++++++++++++++++++++++ board/rockchip/kylin_rk3036/kylin_rk3036.c | 46 ++++++++++++++++++++++ include/configs/rk3036_common.h | 21 +++++++++- 4 files changed, 112 insertions(+), 3 deletions(-) diff --git a/arch/arm/dts/rk3036-sdk.dts b/arch/arm/dts/rk3036-sdk.dts index a83badb59c..1c9ddf9856 100644 --- a/arch/arm/dts/rk3036-sdk.dts +++ b/arch/arm/dts/rk3036-sdk.dts @@ -41,6 +41,4 @@ &usb_otg { status = "okay"; - - dr_mode = "host"; }; diff --git a/board/rockchip/evb_rk3036/evb_rk3036.c b/board/rockchip/evb_rk3036/evb_rk3036.c index f5758b1e9a..e5582b47d9 100644 --- a/board/rockchip/evb_rk3036/evb_rk3036.c +++ b/board/rockchip/evb_rk3036/evb_rk3036.c @@ -47,3 +47,49 @@ void enable_caches(void) dcache_enable(); } #endif + +#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG) +#include +#include + +static struct dwc2_plat_otg_data rk3036_otg_data = { + .rx_fifo_sz = 512, + .np_tx_fifo_sz = 16, + .tx_fifo_sz = 128, +}; + +int board_usb_init(int index, enum usb_init_type init) +{ + int node; + const char *mode; + bool matched = false; + const void *blob = gd->fdt_blob; + + /* find the usb_otg node */ + node = fdt_node_offset_by_compatible(blob, -1, + "rockchip,rk3288-usb"); + + while (node > 0) { + mode = fdt_getprop(blob, node, "dr_mode", NULL); + if (mode && strcmp(mode, "otg") == 0) { + matched = true; + break; + } + + node = fdt_node_offset_by_compatible(blob, node, + "rockchip,rk3288-usb"); + } + if (!matched) { + debug("Not found usb_otg device\n"); + return -ENODEV; + } + rk3036_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg"); + + return dwc2_udc_probe(&rk3036_otg_data); +} + +int board_usb_cleanup(int index, enum usb_init_type init) +{ + return 0; +} +#endif diff --git a/board/rockchip/kylin_rk3036/kylin_rk3036.c b/board/rockchip/kylin_rk3036/kylin_rk3036.c index 2a258710ac..5ade695616 100644 --- a/board/rockchip/kylin_rk3036/kylin_rk3036.c +++ b/board/rockchip/kylin_rk3036/kylin_rk3036.c @@ -79,3 +79,49 @@ void enable_caches(void) dcache_enable(); } #endif + +#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG) +#include +#include + +static struct dwc2_plat_otg_data rk3036_otg_data = { + .rx_fifo_sz = 512, + .np_tx_fifo_sz = 16, + .tx_fifo_sz = 128, +}; + +int board_usb_init(int index, enum usb_init_type init) +{ + int node; + const char *mode; + bool matched = false; + const void *blob = gd->fdt_blob; + + /* find the usb_otg node */ + node = fdt_node_offset_by_compatible(blob, -1, + "rockchip,rk3288-usb"); + + while (node > 0) { + mode = fdt_getprop(blob, node, "dr_mode", NULL); + if (mode && strcmp(mode, "otg") == 0) { + matched = true; + break; + } + + node = fdt_node_offset_by_compatible(blob, node, + "rockchip,rk3288-usb"); + } + if (!matched) { + debug("Not found usb_otg device\n"); + return -ENODEV; + } + rk3036_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg"); + + return dwc2_udc_probe(&rk3036_otg_data); +} + +int board_usb_cleanup(int index, enum usb_init_type init) +{ + return 0; +} +#endif diff --git a/include/configs/rk3036_common.h b/include/configs/rk3036_common.h index ffcaa6f0e5..21d468354b 100644 --- a/include/configs/rk3036_common.h +++ b/include/configs/rk3036_common.h @@ -6,7 +6,7 @@ #ifndef __CONFIG_RK3036_COMMON_H #define __CONFIG_RK3036_COMMON_H -#define CONFIG_SYS_CACHELINE_SIZE 32 +#define CONFIG_SYS_CACHELINE_SIZE 64 #include @@ -60,6 +60,25 @@ #define CONFIG_SF_DEFAULT_SPEED 20000000 #ifndef CONFIG_SPL_BUILD +/* usb otg */ +#define CONFIG_USB_GADGET +#define CONFIG_USB_GADGET_DUALSPEED +#define CONFIG_USB_GADGET_DWC2_OTG +#define CONFIG_USB_GADGET_VBUS_DRAW 0 + +/* fastboot */ +#define CONFIG_CMD_FASTBOOT +#define CONFIG_USB_FUNCTION_FASTBOOT +#define CONFIG_FASTBOOT_FLASH +#define CONFIG_FASTBOOT_FLASH_MMC_DEV 0 +#define CONFIG_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR +#define CONFIG_FASTBOOT_BUF_SIZE 0x08000000 + +#define CONFIG_USB_GADGET_DOWNLOAD +#define CONFIG_G_DNL_MANUFACTURER "Rockchip" +#define CONFIG_G_DNL_VENDOR_NUM 0x2207 +#define CONFIG_G_DNL_PRODUCT_NUM 0x310a + #include #define ENV_MEM_LAYOUT_SETTINGS \ From 2918d96728379b544fd8ba397cdeb47170dc38f8 Mon Sep 17 00:00:00 2001 From: Sandy Patterson Date: Thu, 28 Jul 2016 09:49:01 -0400 Subject: [PATCH 02/12] rockchip: rockchip, sdram-channel 0xff fix remaining dts Add an extra byte so that this data is not byteswapped. Signed-off-by: Sandy Patterson Acked-by: Simon Glass --- arch/arm/dts/rk3288-rock2-square.dts | 2 +- arch/arm/dts/rk3288-veyron.dtsi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/dts/rk3288-rock2-square.dts b/arch/arm/dts/rk3288-rock2-square.dts index 34073c9405..2c30355f06 100644 --- a/arch/arm/dts/rk3288-rock2-square.dts +++ b/arch/arm/dts/rk3288-rock2-square.dts @@ -192,7 +192,7 @@ 0x5 0x0>; rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200 0xa60 0x40 0x10 0x0>; - rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf>; + rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>; rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>; }; diff --git a/arch/arm/dts/rk3288-veyron.dtsi b/arch/arm/dts/rk3288-veyron.dtsi index 421d21290c..d9d51879f0 100644 --- a/arch/arm/dts/rk3288-veyron.dtsi +++ b/arch/arm/dts/rk3288-veyron.dtsi @@ -253,7 +253,7 @@ 0x5 0x0>; rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200 0xa60 0x40 0x10 0x0>; - rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf>; + rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>; rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>; }; From b0b3c86521e0fe4cca3676adfc0b937d77456f9e Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Fri, 29 Jul 2016 10:35:25 +0800 Subject: [PATCH 03/12] rk3399: add basic soc driver This patch add driver for: - clock driver including set_rate for cpu, mmc, vop, I2C. - sysreset driver - grf syscon driver Signed-off-by: Kever Yang Acked-by: Simon Glass --- .../include/asm/arch-rockchip/cru_rk3399.h | 93 ++ arch/arm/mach-rockchip/rk3399/Makefile | 2 + arch/arm/mach-rockchip/rk3399/reset_rk3399.c | 45 + arch/arm/mach-rockchip/rk3399/syscon_rk3399.c | 20 + drivers/clk/Makefile | 1 + drivers/clk/clk_rk3399.c | 819 ++++++++++++++++++ 6 files changed, 980 insertions(+) create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rk3399.h create mode 100644 arch/arm/mach-rockchip/rk3399/reset_rk3399.c create mode 100644 arch/arm/mach-rockchip/rk3399/syscon_rk3399.c create mode 100644 drivers/clk/clk_rk3399.c diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3399.h b/arch/arm/include/asm/arch-rockchip/cru_rk3399.h new file mode 100644 index 0000000000..c919f47745 --- /dev/null +++ b/arch/arm/include/asm/arch-rockchip/cru_rk3399.h @@ -0,0 +1,93 @@ +/* + * (C) Copyright 2016 Rockchip Electronics Co., Ltd + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARCH_CRU_RK3399_H_ +#define __ASM_ARCH_CRU_RK3399_H_ + +#include + +struct rk3399_pmucru { + u32 ppll_con[6]; + u32 reserved[0x1a]; + u32 pmucru_clksel[6]; + u32 pmucru_clkfrac_con[2]; + u32 reserved2[0x18]; + u32 pmucru_clkgate_con[3]; + u32 reserved3; + u32 pmucru_softrst_con[2]; + u32 reserved4[2]; + u32 pmucru_rstnhold_con[2]; + u32 reserved5[2]; + u32 pmucru_gatedis_con[2]; +}; +check_member(rk3399_pmucru, pmucru_gatedis_con[1], 0x134); + +struct rk3399_cru { + u32 apll_l_con[6]; + u32 reserved[2]; + u32 apll_b_con[6]; + u32 reserved1[2]; + u32 dpll_con[6]; + u32 reserved2[2]; + u32 cpll_con[6]; + u32 reserved3[2]; + u32 gpll_con[6]; + u32 reserved4[2]; + u32 npll_con[6]; + u32 reserved5[2]; + u32 vpll_con[6]; + u32 reserved6[0x0a]; + u32 clksel_con[108]; + u32 reserved7[0x14]; + u32 clkgate_con[35]; + u32 reserved8[0x1d]; + u32 softrst_con[21]; + u32 reserved9[0x2b]; + u32 glb_srst_fst_value; + u32 glb_srst_snd_value; + u32 glb_cnt_th; + u32 misc_con; + u32 glb_rst_con; + u32 glb_rst_st; + u32 reserved10[0x1a]; + u32 sdmmc_con[2]; + u32 sdio0_con[2]; + u32 sdio1_con[2]; +}; +check_member(rk3399_cru, sdio1_con[1], 0x594); +#define MHz 1000000 +#define KHz 1000 +#define OSC_HZ (24*MHz) +#define APLL_HZ (600*MHz) +#define GPLL_HZ (594*MHz) +#define CPLL_HZ (384*MHz) +#define PPLL_HZ (594*MHz) + +#define PMU_PCLK_HZ (99*MHz) + +#define ACLKM_CORE_HZ (300*MHz) +#define ATCLK_CORE_HZ (300*MHz) +#define PCLK_DBG_HZ (100*MHz) + +#define PERIHP_ACLK_HZ (148500*KHz) +#define PERIHP_HCLK_HZ (148500*KHz) +#define PERIHP_PCLK_HZ (37125*KHz) + +#define PERILP0_ACLK_HZ (99000*KHz) +#define PERILP0_HCLK_HZ (99000*KHz) +#define PERILP0_PCLK_HZ (49500*KHz) + +#define PERILP1_HCLK_HZ (99000*KHz) +#define PERILP1_PCLK_HZ (49500*KHz) + +#define PWM_CLOCK_HZ PMU_PCLK_HZ + +enum apll_l_frequencies { + APLL_L_1600_MHZ, + APLL_L_600_MHZ, +}; + +#endif /* __ASM_ARCH_CRU_RK3399_H_ */ diff --git a/arch/arm/mach-rockchip/rk3399/Makefile b/arch/arm/mach-rockchip/rk3399/Makefile index 3f219ac6f8..3ca20284ef 100644 --- a/arch/arm/mach-rockchip/rk3399/Makefile +++ b/arch/arm/mach-rockchip/rk3399/Makefile @@ -5,3 +5,5 @@ # obj-y += rk3399.o +obj-y += reset_rk3399.o +obj-y += syscon_rk3399.o diff --git a/arch/arm/mach-rockchip/rk3399/reset_rk3399.c b/arch/arm/mach-rockchip/rk3399/reset_rk3399.c new file mode 100644 index 0000000000..9a555464c6 --- /dev/null +++ b/arch/arm/mach-rockchip/rk3399/reset_rk3399.c @@ -0,0 +1,45 @@ +/* + * (C) Copyright 2016 Rockchip Electronics Co., Ltd + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int rk3399_sysreset_request(struct udevice *dev, enum sysreset_t type) +{ + struct rk3399_cru *cru = rockchip_get_cru(); + + if (IS_ERR(cru)) + return PTR_ERR(cru); + switch (type) { + case SYSRESET_WARM: + writel(0xeca8, &cru->glb_srst_snd_value); + break; + case SYSRESET_COLD: + writel(0xfdb9, &cru->glb_srst_fst_value); + break; + default: + return -EPROTONOSUPPORT; + } + + return -EINPROGRESS; +} + +static struct sysreset_ops rk3399_sysreset = { + .request = rk3399_sysreset_request, +}; + +U_BOOT_DRIVER(sysreset_rk3399) = { + .name = "rk3399_sysreset", + .id = UCLASS_SYSRESET, + .ops = &rk3399_sysreset, +}; diff --git a/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c b/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c new file mode 100644 index 0000000000..2d81c55cd2 --- /dev/null +++ b/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c @@ -0,0 +1,20 @@ +/* + * (C) Copyright 2016 Rockchip Electronics Co., Ltd + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +static const struct udevice_id rk3399_syscon_ids[] = { + { .compatible = "rockchip,rk3399-grf", .data = ROCKCHIP_SYSCON_GRF }, +}; + +U_BOOT_DRIVER(syscon_rk3399) = { + .name = "rk3399_syscon", + .id = UCLASS_SYSCON, + .of_match = rk3399_syscon_ids, +}; diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index f7a88912e0..e20e932337 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_CLK) += clk-uclass.o clk_fixed_rate.o obj-$(CONFIG_ROCKCHIP_RK3036) += clk_rk3036.o obj-$(CONFIG_ROCKCHIP_RK3288) += clk_rk3288.o +obj-$(CONFIG_ROCKCHIP_RK3399) += clk_rk3399.o obj-$(CONFIG_SANDBOX) += clk_sandbox.o obj-$(CONFIG_SANDBOX) += clk_sandbox_test.o obj-$(CONFIG_MACH_PIC32) += clk_pic32.o diff --git a/drivers/clk/clk_rk3399.c b/drivers/clk/clk_rk3399.c new file mode 100644 index 0000000000..c0bb80c462 --- /dev/null +++ b/drivers/clk/clk_rk3399.c @@ -0,0 +1,819 @@ +/* + * (C) Copyright 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +struct rk3399_clk_priv { + struct rk3399_cru *cru; + ulong rate; +}; + +struct pll_div { + u32 refdiv; + u32 fbdiv; + u32 postdiv1; + u32 postdiv2; + u32 frac; +}; + +#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 const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1); +static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2, 2); +static const struct pll_div ppll_init_cfg = PLL_DIVISORS(PPLL_HZ, 2, 2, 1); + +static const struct pll_div apll_l_1600_cfg = PLL_DIVISORS(1600*MHz, 3, 1, 1); +static const struct pll_div apll_l_600_cfg = PLL_DIVISORS(600*MHz, 1, 2, 1); + +static const struct pll_div *apll_l_cfgs[] = { + [APLL_L_1600_MHZ] = &apll_l_1600_cfg, + [APLL_L_600_MHZ] = &apll_l_600_cfg, +}; + +enum { + /* PLL_CON0 */ + PLL_FBDIV_MASK = 0xfff, + PLL_FBDIV_SHIFT = 0, + + /* PLL_CON1 */ + PLL_POSTDIV2_SHIFT = 12, + PLL_POSTDIV2_MASK = 0x7 << PLL_POSTDIV2_SHIFT, + PLL_POSTDIV1_SHIFT = 8, + PLL_POSTDIV1_MASK = 0x7 << PLL_POSTDIV1_SHIFT, + PLL_REFDIV_MASK = 0x3f, + PLL_REFDIV_SHIFT = 0, + + /* PLL_CON2 */ + PLL_LOCK_STATUS_SHIFT = 31, + PLL_LOCK_STATUS_MASK = 1 << PLL_LOCK_STATUS_SHIFT, + PLL_FRACDIV_MASK = 0xffffff, + PLL_FRACDIV_SHIFT = 0, + + /* PLL_CON3 */ + PLL_MODE_SHIFT = 8, + PLL_MODE_MASK = 3 << PLL_MODE_SHIFT, + PLL_MODE_SLOW = 0, + PLL_MODE_NORM, + PLL_MODE_DEEP, + PLL_DSMPD_SHIFT = 3, + PLL_DSMPD_MASK = 1 << PLL_DSMPD_SHIFT, + PLL_INTEGER_MODE = 1, + + /* PMUCRU_CLKSEL_CON0 */ + PMU_PCLK_DIV_CON_MASK = 0x1f, + PMU_PCLK_DIV_CON_SHIFT = 0, + + /* PMUCRU_CLKSEL_CON1 */ + SPI3_PLL_SEL_SHIFT = 7, + SPI3_PLL_SEL_MASK = 1 << SPI3_PLL_SEL_SHIFT, + SPI3_PLL_SEL_24M = 0, + SPI3_PLL_SEL_PPLL = 1, + SPI3_DIV_CON_SHIFT = 0x0, + SPI3_DIV_CON_MASK = 0x7f, + + /* PMUCRU_CLKSEL_CON2 */ + I2C_DIV_CON_MASK = 0x7f, + I2C8_DIV_CON_SHIFT = 8, + I2C0_DIV_CON_SHIFT = 0, + + /* PMUCRU_CLKSEL_CON3 */ + I2C4_DIV_CON_SHIFT = 0, + + /* CLKSEL_CON0 */ + ACLKM_CORE_L_DIV_CON_SHIFT = 8, + ACLKM_CORE_L_DIV_CON_MASK = 0x1f << ACLKM_CORE_L_DIV_CON_SHIFT, + CLK_CORE_L_PLL_SEL_SHIFT = 6, + CLK_CORE_L_PLL_SEL_MASK = 3 << CLK_CORE_L_PLL_SEL_SHIFT, + CLK_CORE_L_PLL_SEL_ALPLL = 0x0, + CLK_CORE_L_PLL_SEL_ABPLL = 0x1, + CLK_CORE_L_PLL_SEL_DPLL = 0x10, + CLK_CORE_L_PLL_SEL_GPLL = 0x11, + CLK_CORE_L_DIV_MASK = 0x1f, + CLK_CORE_L_DIV_SHIFT = 0, + + /* CLKSEL_CON1 */ + PCLK_DBG_L_DIV_SHIFT = 0x8, + PCLK_DBG_L_DIV_MASK = 0x1f << PCLK_DBG_L_DIV_SHIFT, + ATCLK_CORE_L_DIV_SHIFT = 0, + ATCLK_CORE_L_DIV_MASK = 0x1f << ATCLK_CORE_L_DIV_SHIFT, + + /* CLKSEL_CON14 */ + PCLK_PERIHP_DIV_CON_SHIFT = 12, + PCLK_PERIHP_DIV_CON_MASK = 0x7 << PCLK_PERIHP_DIV_CON_SHIFT, + HCLK_PERIHP_DIV_CON_SHIFT = 8, + HCLK_PERIHP_DIV_CON_MASK = 3 << HCLK_PERIHP_DIV_CON_SHIFT, + ACLK_PERIHP_PLL_SEL_SHIFT = 7, + ACLK_PERIHP_PLL_SEL_MASK = 1 << ACLK_PERIHP_PLL_SEL_SHIFT, + ACLK_PERIHP_PLL_SEL_CPLL = 0, + ACLK_PERIHP_PLL_SEL_GPLL = 1, + ACLK_PERIHP_DIV_CON_SHIFT = 0, + ACLK_PERIHP_DIV_CON_MASK = 0x1f, + + /* CLKSEL_CON21 */ + ACLK_EMMC_PLL_SEL_SHIFT = 7, + ACLK_EMMC_PLL_SEL_MASK = 0x1 << ACLK_EMMC_PLL_SEL_SHIFT, + ACLK_EMMC_PLL_SEL_GPLL = 0x1, + ACLK_EMMC_DIV_CON_SHIFT = 0, + ACLK_EMMC_DIV_CON_MASK = 0x1f, + + /* CLKSEL_CON22 */ + CLK_EMMC_PLL_SHIFT = 8, + CLK_EMMC_PLL_MASK = 0x7 << CLK_EMMC_PLL_SHIFT, + CLK_EMMC_PLL_SEL_GPLL = 0x1, + CLK_EMMC_DIV_CON_SHIFT = 0, + CLK_EMMC_DIV_CON_MASK = 0x7f << CLK_EMMC_DIV_CON_SHIFT, + + /* CLKSEL_CON23 */ + PCLK_PERILP0_DIV_CON_SHIFT = 12, + PCLK_PERILP0_DIV_CON_MASK = 0x7 << PCLK_PERILP0_DIV_CON_SHIFT, + HCLK_PERILP0_DIV_CON_SHIFT = 8, + HCLK_PERILP0_DIV_CON_MASK = 3 << HCLK_PERILP0_DIV_CON_SHIFT, + ACLK_PERILP0_PLL_SEL_SHIFT = 7, + ACLK_PERILP0_PLL_SEL_MASK = 1 << ACLK_PERILP0_PLL_SEL_SHIFT, + ACLK_PERILP0_PLL_SEL_CPLL = 0, + ACLK_PERILP0_PLL_SEL_GPLL = 1, + ACLK_PERILP0_DIV_CON_SHIFT = 0, + ACLK_PERILP0_DIV_CON_MASK = 0x1f, + + /* CLKSEL_CON25 */ + PCLK_PERILP1_DIV_CON_SHIFT = 8, + PCLK_PERILP1_DIV_CON_MASK = 0x7 << PCLK_PERILP1_DIV_CON_SHIFT, + HCLK_PERILP1_PLL_SEL_SHIFT = 7, + HCLK_PERILP1_PLL_SEL_MASK = 1 << HCLK_PERILP1_PLL_SEL_SHIFT, + HCLK_PERILP1_PLL_SEL_CPLL = 0, + HCLK_PERILP1_PLL_SEL_GPLL = 1, + HCLK_PERILP1_DIV_CON_SHIFT = 0, + HCLK_PERILP1_DIV_CON_MASK = 0x1f, + + /* CLKSEL_CON26 */ + CLK_SARADC_DIV_CON_SHIFT = 8, + CLK_SARADC_DIV_CON_MASK = 0xff << CLK_SARADC_DIV_CON_SHIFT, + + /* CLKSEL_CON27 */ + CLK_TSADC_SEL_X24M = 0x0, + CLK_TSADC_SEL_SHIFT = 15, + CLK_TSADC_SEL_MASK = 1 << CLK_TSADC_SEL_SHIFT, + CLK_TSADC_DIV_CON_SHIFT = 0, + CLK_TSADC_DIV_CON_MASK = 0x3ff, + + /* CLKSEL_CON47 & CLKSEL_CON48 */ + ACLK_VOP_PLL_SEL_SHIFT = 6, + ACLK_VOP_PLL_SEL_MASK = 0x3 << ACLK_VOP_PLL_SEL_SHIFT, + ACLK_VOP_PLL_SEL_CPLL = 0x1, + ACLK_VOP_DIV_CON_SHIFT = 0, + ACLK_VOP_DIV_CON_MASK = 0x1f << ACLK_VOP_DIV_CON_SHIFT, + + /* CLKSEL_CON49 & CLKSEL_CON50 */ + DCLK_VOP_DCLK_SEL_SHIFT = 11, + DCLK_VOP_DCLK_SEL_MASK = 1 << DCLK_VOP_DCLK_SEL_SHIFT, + DCLK_VOP_DCLK_SEL_DIVOUT = 0, + DCLK_VOP_PLL_SEL_SHIFT = 8, + DCLK_VOP_PLL_SEL_MASK = 3 << DCLK_VOP_PLL_SEL_SHIFT, + DCLK_VOP_PLL_SEL_VPLL = 0, + DCLK_VOP_DIV_CON_MASK = 0xff, + DCLK_VOP_DIV_CON_SHIFT = 0, + + /* CLKSEL_CON58 */ + CLK_SPI_PLL_SEL_MASK = 1, + CLK_SPI_PLL_SEL_CPLL = 0, + CLK_SPI_PLL_SEL_GPLL = 1, + CLK_SPI_PLL_DIV_CON_MASK = 0x7f, + CLK_SPI5_PLL_DIV_CON_SHIFT = 8, + CLK_SPI5_PLL_SEL_SHIFT = 15, + + /* CLKSEL_CON59 */ + CLK_SPI1_PLL_SEL_SHIFT = 15, + CLK_SPI1_PLL_DIV_CON_SHIFT = 8, + CLK_SPI0_PLL_SEL_SHIFT = 7, + CLK_SPI0_PLL_DIV_CON_SHIFT = 0, + + /* CLKSEL_CON60 */ + CLK_SPI4_PLL_SEL_SHIFT = 15, + CLK_SPI4_PLL_DIV_CON_SHIFT = 8, + CLK_SPI2_PLL_SEL_SHIFT = 7, + CLK_SPI2_PLL_DIV_CON_SHIFT = 0, + + /* CLKSEL_CON61 */ + CLK_I2C_PLL_SEL_MASK = 1, + CLK_I2C_PLL_SEL_CPLL = 0, + CLK_I2C_PLL_SEL_GPLL = 1, + CLK_I2C5_PLL_SEL_SHIFT = 15, + CLK_I2C5_DIV_CON_SHIFT = 8, + CLK_I2C1_PLL_SEL_SHIFT = 7, + CLK_I2C1_DIV_CON_SHIFT = 0, + + /* CLKSEL_CON62 */ + CLK_I2C6_PLL_SEL_SHIFT = 15, + CLK_I2C6_DIV_CON_SHIFT = 8, + CLK_I2C2_PLL_SEL_SHIFT = 7, + CLK_I2C2_DIV_CON_SHIFT = 0, + + /* CLKSEL_CON63 */ + CLK_I2C7_PLL_SEL_SHIFT = 15, + CLK_I2C7_DIV_CON_SHIFT = 8, + CLK_I2C3_PLL_SEL_SHIFT = 7, + CLK_I2C3_DIV_CON_SHIFT = 0, + + /* CRU_SOFTRST_CON4 */ + RESETN_DDR0_REQ_SHIFT = 8, + RESETN_DDR0_REQ_MASK = 1 << RESETN_DDR0_REQ_SHIFT, + RESETN_DDRPHY0_REQ_SHIFT = 9, + RESETN_DDRPHY0_REQ_MASK = 1 << RESETN_DDRPHY0_REQ_SHIFT, + RESETN_DDR1_REQ_SHIFT = 12, + RESETN_DDR1_REQ_MASK = 1 << RESETN_DDR1_REQ_SHIFT, + RESETN_DDRPHY1_REQ_SHIFT = 13, + RESETN_DDRPHY1_REQ_MASK = 1 << RESETN_DDRPHY1_REQ_SHIFT, +}; + +#define VCO_MAX_KHZ (3200 * (MHz / KHz)) +#define VCO_MIN_KHZ (800 * (MHz / KHz)) +#define OUTPUT_MAX_KHZ (3200 * (MHz / KHz)) +#define OUTPUT_MIN_KHZ (16 * (MHz / KHz)) + +/* + * the div restructions of pll in integer mode, these are defined in + * * CRU_*PLL_CON0 or PMUCRU_*PLL_CON0 + */ +#define PLL_DIV_MIN 16 +#define PLL_DIV_MAX 3200 + +/* + * How to calculate the PLL(from TRM V0.3 Part 1 Page 63): + * Formulas also embedded within the Fractional PLL Verilog model: + * If DSMPD = 1 (DSM is disabled, "integer mode") + * FOUTVCO = FREF / REFDIV * FBDIV + * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2 + * Where: + * FOUTVCO = Fractional PLL non-divided output frequency + * FOUTPOSTDIV = Fractional PLL divided output frequency + * (output of second post divider) + * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input) + * REFDIV = Fractional PLL input reference clock divider + * FBDIV = Integer value programmed into feedback divide + * + */ +static void rkclk_set_pll(u32 *pll_con, const struct pll_div *div) +{ + /* All 8 PLLs have same VCO and output frequency range restrictions. */ + u32 vco_khz = OSC_HZ / 1000 * div->fbdiv / div->refdiv; + u32 output_khz = vco_khz / div->postdiv1 / div->postdiv2; + + debug("PLL at %p: fbdiv=%d, refdiv=%d, postdiv1=%d, " + "postdiv2=%d, vco=%u khz, output=%u khz\n", + pll_con, div->fbdiv, div->refdiv, div->postdiv1, + div->postdiv2, vco_khz, output_khz); + assert(vco_khz >= VCO_MIN_KHZ && vco_khz <= VCO_MAX_KHZ && + output_khz >= OUTPUT_MIN_KHZ && output_khz <= OUTPUT_MAX_KHZ && + div->fbdiv >= PLL_DIV_MIN && div->fbdiv <= PLL_DIV_MAX); + + /* + * When power on or changing PLL setting, + * we must force PLL into slow mode to ensure output stable clock. + */ + rk_clrsetreg(&pll_con[3], PLL_MODE_MASK, + PLL_MODE_SLOW << PLL_MODE_SHIFT); + + /* use integer mode */ + rk_clrsetreg(&pll_con[3], PLL_DSMPD_MASK, + PLL_INTEGER_MODE << PLL_DSMPD_SHIFT); + + rk_clrsetreg(&pll_con[0], PLL_FBDIV_MASK, + div->fbdiv << PLL_FBDIV_SHIFT); + rk_clrsetreg(&pll_con[1], + PLL_POSTDIV2_MASK | PLL_POSTDIV1_MASK | + PLL_REFDIV_MASK | PLL_REFDIV_SHIFT, + (div->postdiv2 << PLL_POSTDIV2_SHIFT) | + (div->postdiv1 << PLL_POSTDIV1_SHIFT) | + (div->refdiv << PLL_REFDIV_SHIFT)); + + /* waiting for pll lock */ + while (!(readl(&pll_con[2]) & (1 << PLL_LOCK_STATUS_SHIFT))) + udelay(1); + + /* pll enter normal mode */ + rk_clrsetreg(&pll_con[3], PLL_MODE_MASK, + PLL_MODE_NORM << PLL_MODE_SHIFT); +} + +static int pll_para_config(u32 freq_hz, struct pll_div *div) +{ + u32 ref_khz = OSC_HZ / KHz, refdiv, fbdiv = 0; + u32 postdiv1, postdiv2 = 1; + u32 fref_khz; + u32 diff_khz, best_diff_khz; + const u32 max_refdiv = 63, max_fbdiv = 3200, min_fbdiv = 16; + const u32 max_postdiv1 = 7, max_postdiv2 = 7; + u32 vco_khz; + u32 freq_khz = freq_hz / KHz; + + if (!freq_hz) { + printf("%s: the frequency can't be 0 Hz\n", __func__); + return -1; + } + + postdiv1 = DIV_ROUND_UP(VCO_MIN_KHZ, freq_khz); + if (postdiv1 > max_postdiv1) { + postdiv2 = DIV_ROUND_UP(postdiv1, max_postdiv1); + postdiv1 = DIV_ROUND_UP(postdiv1, postdiv2); + } + + vco_khz = freq_khz * postdiv1 * postdiv2; + + if (vco_khz < VCO_MIN_KHZ || vco_khz > VCO_MAX_KHZ || + postdiv2 > max_postdiv2) { + printf("%s: Cannot find out a supported VCO" + " for Frequency (%uHz).\n", __func__, freq_hz); + return -1; + } + + div->postdiv1 = postdiv1; + div->postdiv2 = postdiv2; + + best_diff_khz = vco_khz; + for (refdiv = 1; refdiv < max_refdiv && best_diff_khz; refdiv++) { + fref_khz = ref_khz / refdiv; + + fbdiv = vco_khz / fref_khz; + if ((fbdiv >= max_fbdiv) || (fbdiv <= min_fbdiv)) + continue; + diff_khz = vco_khz - fbdiv * fref_khz; + if (fbdiv + 1 < max_fbdiv && diff_khz > fref_khz / 2) { + fbdiv++; + diff_khz = fref_khz - diff_khz; + } + + if (diff_khz >= best_diff_khz) + continue; + + best_diff_khz = diff_khz; + div->refdiv = refdiv; + div->fbdiv = fbdiv; + } + + if (best_diff_khz > 4 * (MHz/KHz)) { + printf("%s: Failed to match output frequency %u, " + "difference is %u Hz,exceed 4MHZ\n", __func__, freq_hz, + best_diff_khz * KHz); + return -1; + } + return 0; +} + +static void rkclk_init(struct rk3399_cru *cru) +{ + u32 aclk_div; + u32 hclk_div; + u32 pclk_div; + + /* + * some cru registers changed by bootrom, we'd better reset them to + * reset/default values described in TRM to avoid confusion in kernel. + * Please consider these three lines as a fix of bootrom bug. + */ + rk_clrsetreg(&cru->clksel_con[12], 0xffff, 0x4101); + rk_clrsetreg(&cru->clksel_con[19], 0xffff, 0x033f); + rk_clrsetreg(&cru->clksel_con[56], 0x0003, 0x0003); + + /* configure gpll cpll */ + rkclk_set_pll(&cru->gpll_con[0], &gpll_init_cfg); + rkclk_set_pll(&cru->cpll_con[0], &cpll_init_cfg); + + /* configure perihp aclk, hclk, pclk */ + aclk_div = GPLL_HZ / PERIHP_ACLK_HZ - 1; + assert((aclk_div + 1) * PERIHP_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f); + + hclk_div = PERIHP_ACLK_HZ / PERIHP_HCLK_HZ - 1; + assert((hclk_div + 1) * PERIHP_HCLK_HZ == + PERIHP_ACLK_HZ && (hclk_div < 0x4)); + + pclk_div = PERIHP_ACLK_HZ / PERIHP_PCLK_HZ - 1; + assert((pclk_div + 1) * PERIHP_PCLK_HZ == + PERIHP_ACLK_HZ && (pclk_div < 0x7)); + + rk_clrsetreg(&cru->clksel_con[14], + PCLK_PERIHP_DIV_CON_MASK | HCLK_PERIHP_DIV_CON_MASK | + ACLK_PERIHP_PLL_SEL_MASK | ACLK_PERIHP_DIV_CON_MASK, + pclk_div << PCLK_PERIHP_DIV_CON_SHIFT | + hclk_div << HCLK_PERIHP_DIV_CON_SHIFT | + ACLK_PERIHP_PLL_SEL_GPLL << ACLK_PERIHP_PLL_SEL_SHIFT | + aclk_div << ACLK_PERIHP_DIV_CON_SHIFT); + + /* configure perilp0 aclk, hclk, pclk */ + aclk_div = GPLL_HZ / PERILP0_ACLK_HZ - 1; + assert((aclk_div + 1) * PERILP0_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f); + + hclk_div = PERILP0_ACLK_HZ / PERILP0_HCLK_HZ - 1; + assert((hclk_div + 1) * PERILP0_HCLK_HZ == + PERILP0_ACLK_HZ && (hclk_div < 0x4)); + + pclk_div = PERILP0_ACLK_HZ / PERILP0_PCLK_HZ - 1; + assert((pclk_div + 1) * PERILP0_PCLK_HZ == + PERILP0_ACLK_HZ && (pclk_div < 0x7)); + + rk_clrsetreg(&cru->clksel_con[23], + PCLK_PERILP0_DIV_CON_MASK | HCLK_PERILP0_DIV_CON_MASK | + ACLK_PERILP0_PLL_SEL_MASK | ACLK_PERILP0_DIV_CON_MASK, + pclk_div << PCLK_PERILP0_DIV_CON_SHIFT | + hclk_div << HCLK_PERILP0_DIV_CON_SHIFT | + ACLK_PERILP0_PLL_SEL_GPLL << ACLK_PERILP0_PLL_SEL_SHIFT | + aclk_div << ACLK_PERILP0_DIV_CON_SHIFT); + + /* perilp1 hclk select gpll as source */ + hclk_div = GPLL_HZ / PERILP1_HCLK_HZ - 1; + assert((hclk_div + 1) * PERILP1_HCLK_HZ == + GPLL_HZ && (hclk_div < 0x1f)); + + pclk_div = PERILP1_HCLK_HZ / PERILP1_HCLK_HZ - 1; + assert((pclk_div + 1) * PERILP1_HCLK_HZ == + PERILP1_HCLK_HZ && (hclk_div < 0x7)); + + rk_clrsetreg(&cru->clksel_con[25], + PCLK_PERILP1_DIV_CON_MASK | HCLK_PERILP1_DIV_CON_MASK | + HCLK_PERILP1_PLL_SEL_MASK, + pclk_div << PCLK_PERILP1_DIV_CON_SHIFT | + hclk_div << HCLK_PERILP1_DIV_CON_SHIFT | + HCLK_PERILP1_PLL_SEL_GPLL << HCLK_PERILP1_PLL_SEL_SHIFT); +} + +void rk3399_configure_cpu(struct rk3399_cru *cru, + enum apll_l_frequencies apll_l_freq) +{ + u32 aclkm_div; + u32 pclk_dbg_div; + u32 atclk_div; + + rkclk_set_pll(&cru->apll_l_con[0], apll_l_cfgs[apll_l_freq]); + + aclkm_div = APLL_HZ / ACLKM_CORE_HZ - 1; + assert((aclkm_div + 1) * ACLKM_CORE_HZ == APLL_HZ && + aclkm_div < 0x1f); + + pclk_dbg_div = APLL_HZ / PCLK_DBG_HZ - 1; + assert((pclk_dbg_div + 1) * PCLK_DBG_HZ == APLL_HZ && + pclk_dbg_div < 0x1f); + + atclk_div = APLL_HZ / ATCLK_CORE_HZ - 1; + assert((atclk_div + 1) * ATCLK_CORE_HZ == APLL_HZ && + atclk_div < 0x1f); + + rk_clrsetreg(&cru->clksel_con[0], + ACLKM_CORE_L_DIV_CON_MASK | CLK_CORE_L_PLL_SEL_MASK | + CLK_CORE_L_DIV_MASK, + aclkm_div << ACLKM_CORE_L_DIV_CON_SHIFT | + CLK_CORE_L_PLL_SEL_ALPLL << CLK_CORE_L_PLL_SEL_SHIFT | + 0 << CLK_CORE_L_DIV_SHIFT); + + rk_clrsetreg(&cru->clksel_con[1], + PCLK_DBG_L_DIV_MASK | ATCLK_CORE_L_DIV_MASK, + pclk_dbg_div << PCLK_DBG_L_DIV_SHIFT | + atclk_div << ATCLK_CORE_L_DIV_SHIFT); +} +#define I2C_CLK_REG_MASK(bus) \ + (I2C_DIV_CON_MASK << \ + CLK_I2C ##bus## _DIV_CON_SHIFT | \ + CLK_I2C_PLL_SEL_MASK << \ + CLK_I2C ##bus## _PLL_SEL_SHIFT) + +#define I2C_CLK_REG_VALUE(bus, clk_div) \ + ((clk_div - 1) << \ + CLK_I2C ##bus## _DIV_CON_SHIFT | \ + CLK_I2C_PLL_SEL_GPLL << \ + CLK_I2C ##bus## _PLL_SEL_SHIFT) + +#define I2C_CLK_DIV_VALUE(con, bus) \ + (con >> CLK_I2C ##bus## _DIV_CON_SHIFT) & \ + I2C_DIV_CON_MASK; + +static ulong rk3399_i2c_get_clk(struct rk3399_cru *cru, ulong clk_id) +{ + u32 div, con; + + switch (clk_id) { + case SCLK_I2C1: + con = readl(&cru->clksel_con[61]); + div = I2C_CLK_DIV_VALUE(con, 1); + break; + case SCLK_I2C2: + con = readl(&cru->clksel_con[62]); + div = I2C_CLK_DIV_VALUE(con, 2); + break; + case SCLK_I2C3: + con = readl(&cru->clksel_con[63]); + div = I2C_CLK_DIV_VALUE(con, 3); + break; + case SCLK_I2C5: + con = readl(&cru->clksel_con[61]); + div = I2C_CLK_DIV_VALUE(con, 5); + break; + case SCLK_I2C6: + con = readl(&cru->clksel_con[62]); + div = I2C_CLK_DIV_VALUE(con, 6); + break; + case SCLK_I2C7: + con = readl(&cru->clksel_con[63]); + div = I2C_CLK_DIV_VALUE(con, 7); + break; + default: + printf("do not support this i2c bus\n"); + return -EINVAL; + } + + return DIV_TO_RATE(GPLL_HZ, div); +} + +static ulong rk3399_i2c_set_clk(struct rk3399_cru *cru, ulong clk_id, uint hz) +{ + int src_clk_div; + + /* i2c0,4,8 src clock from ppll, i2c1,2,3,5,6,7 src clock from gpll*/ + src_clk_div = GPLL_HZ / hz; + assert(src_clk_div - 1 < 127); + + switch (clk_id) { + case SCLK_I2C1: + rk_clrsetreg(&cru->clksel_con[61], I2C_CLK_REG_MASK(1), + I2C_CLK_REG_VALUE(1, src_clk_div)); + break; + case SCLK_I2C2: + rk_clrsetreg(&cru->clksel_con[62], I2C_CLK_REG_MASK(2), + I2C_CLK_REG_VALUE(2, src_clk_div)); + break; + case SCLK_I2C3: + rk_clrsetreg(&cru->clksel_con[63], I2C_CLK_REG_MASK(3), + I2C_CLK_REG_VALUE(3, src_clk_div)); + break; + case SCLK_I2C5: + rk_clrsetreg(&cru->clksel_con[61], I2C_CLK_REG_MASK(5), + I2C_CLK_REG_VALUE(5, src_clk_div)); + break; + case SCLK_I2C6: + rk_clrsetreg(&cru->clksel_con[62], I2C_CLK_REG_MASK(6), + I2C_CLK_REG_VALUE(6, src_clk_div)); + break; + case SCLK_I2C7: + rk_clrsetreg(&cru->clksel_con[63], I2C_CLK_REG_MASK(7), + I2C_CLK_REG_VALUE(7, src_clk_div)); + break; + default: + printf("do not support this i2c bus\n"); + return -EINVAL; + } + + return DIV_TO_RATE(GPLL_HZ, src_clk_div); +} + +static ulong rk3399_vop_set_clk(struct rk3399_cru *cru, ulong clk_id, u32 hz) +{ + struct pll_div vpll_config = {0}; + int aclk_vop = 198*MHz; + void *aclkreg_addr, *dclkreg_addr; + u32 div; + + switch (clk_id) { + case DCLK_VOP0: + aclkreg_addr = &cru->clksel_con[47]; + dclkreg_addr = &cru->clksel_con[49]; + break; + case DCLK_VOP1: + aclkreg_addr = &cru->clksel_con[48]; + dclkreg_addr = &cru->clksel_con[50]; + break; + default: + return -EINVAL; + } + /* vop aclk source clk: cpll */ + div = CPLL_HZ / aclk_vop; + assert(div - 1 < 32); + + rk_clrsetreg(aclkreg_addr, + ACLK_VOP_PLL_SEL_MASK | ACLK_VOP_DIV_CON_MASK, + ACLK_VOP_PLL_SEL_CPLL << ACLK_VOP_PLL_SEL_SHIFT | + (div - 1) << ACLK_VOP_DIV_CON_SHIFT); + + /* vop dclk source from vpll, and equals to vpll(means div == 1) */ + if (pll_para_config(hz, &vpll_config)) + return -1; + + rkclk_set_pll(&cru->vpll_con[0], &vpll_config); + + rk_clrsetreg(dclkreg_addr, + DCLK_VOP_DCLK_SEL_MASK | DCLK_VOP_PLL_SEL_MASK| + DCLK_VOP_DIV_CON_MASK, + DCLK_VOP_DCLK_SEL_DIVOUT << DCLK_VOP_DCLK_SEL_SHIFT | + DCLK_VOP_PLL_SEL_VPLL << DCLK_VOP_PLL_SEL_SHIFT | + (1 - 1) << DCLK_VOP_DIV_CON_SHIFT); + + return hz; +} + +static ulong rk3399_mmc_get_clk(struct rk3399_cru *cru, uint clk_id) +{ + u32 div, con; + + switch (clk_id) { + case SCLK_SDMMC: + con = readl(&cru->clksel_con[16]); + break; + case SCLK_EMMC: + con = readl(&cru->clksel_con[21]); + break; + default: + return -EINVAL; + } + div = (con>>CLK_EMMC_DIV_CON_SHIFT) & CLK_EMMC_DIV_CON_MASK; + + return DIV_TO_RATE(GPLL_HZ, div); +} + +static ulong rk3399_mmc_set_clk(struct rk3399_cru *cru, + ulong clk_id, ulong set_rate) +{ + int src_clk_div; + int aclk_emmc = 198*MHz; + + switch (clk_id) { + case SCLK_SDMMC: + /* Select clk_sdmmc source from GPLL too */ + src_clk_div = GPLL_HZ / set_rate; + assert(src_clk_div - 1 < 127); + + rk_clrsetreg(&cru->clksel_con[16], + CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, + CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT | + (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); + break; + case SCLK_EMMC: + /* Select aclk_emmc source from GPLL */ + src_clk_div = GPLL_HZ / aclk_emmc; + assert(src_clk_div - 1 < 31); + + rk_clrsetreg(&cru->clksel_con[21], + ACLK_EMMC_PLL_SEL_MASK | ACLK_EMMC_DIV_CON_MASK, + ACLK_EMMC_PLL_SEL_GPLL << ACLK_EMMC_PLL_SEL_SHIFT | + (src_clk_div - 1) << ACLK_EMMC_DIV_CON_SHIFT); + + /* Select clk_emmc source from GPLL too */ + src_clk_div = GPLL_HZ / set_rate; + assert(src_clk_div - 1 < 127); + + rk_clrsetreg(&cru->clksel_con[22], + CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, + CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT | + (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); + break; + default: + return -EINVAL; + } + return rk3399_mmc_get_clk(cru, clk_id); +} + +static ulong rk3399_clk_get_rate(struct clk *clk) +{ + struct rk3399_clk_priv *priv = dev_get_priv(clk->dev); + ulong rate = 0; + + switch (clk->id) { + case 0 ... 63: + return 0; + case SCLK_SDMMC: + case SCLK_EMMC: + rate = rk3399_mmc_get_clk(priv->cru, clk->id); + break; + case SCLK_I2C1: + case SCLK_I2C2: + case SCLK_I2C3: + case SCLK_I2C5: + case SCLK_I2C6: + case SCLK_I2C7: + rate = rk3399_i2c_get_clk(priv->cru, clk->id); + break; + case DCLK_VOP0: + case DCLK_VOP1: + break; + default: + return -ENOENT; + } + + return rate; +} + +static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate) +{ + struct rk3399_clk_priv *priv = dev_get_priv(clk->dev); + ulong ret = 0; + + switch (clk->id) { + case 0 ... 63: + return 0; + case SCLK_SDMMC: + case SCLK_EMMC: + ret = rk3399_mmc_set_clk(priv->cru, clk->id, rate); + break; + case SCLK_I2C1: + case SCLK_I2C2: + case SCLK_I2C3: + case SCLK_I2C5: + case SCLK_I2C6: + case SCLK_I2C7: + ret = rk3399_i2c_set_clk(priv->cru, clk->id, rate); + break; + case DCLK_VOP0: + case DCLK_VOP1: + rate = rk3399_vop_set_clk(priv->cru, clk->id, rate); + break; + default: + return -ENOENT; + } + + return ret; +} + +static struct clk_ops rk3399_clk_ops = { + .get_rate = rk3399_clk_get_rate, + .set_rate = rk3399_clk_set_rate, +}; + +void *rockchip_get_cru(void) +{ + struct udevice *dev; + fdt_addr_t *addr; + int ret; + + ret = uclass_get_device_by_name(UCLASS_CLK, "clk_rk3399", &dev); + if (ret) + return ERR_PTR(ret); + + addr = dev_get_addr_ptr(dev); + if ((fdt_addr_t)addr == FDT_ADDR_T_NONE) + return ERR_PTR(-EINVAL); + + return addr; +} + +static int rk3399_clk_probe(struct udevice *dev) +{ + struct rk3399_clk_priv *priv = dev_get_priv(dev); + + rkclk_init(priv->cru); + + return 0; +} + +static int rk3399_clk_ofdata_to_platdata(struct udevice *dev) +{ + struct rk3399_clk_priv *priv = dev_get_priv(dev); + + priv->cru = (struct rk3399_cru *)dev_get_addr(dev); + + return 0; +} + +static int rk3399_clk_bind(struct udevice *dev) +{ + int ret; + + /* The reset driver does not have a device node, so bind it here */ + ret = device_bind_driver(gd->dm_root, "rk3399_sysreset", "reset", &dev); + if (ret) + printf("Warning: No RK3399 reset driver: ret=%d\n", ret); + + return 0; +} + +static const struct udevice_id rk3399_clk_ids[] = { + { .compatible = "rockchip,rk3399-cru" }, + { } +}; + +U_BOOT_DRIVER(clk_rk3399) = { + .name = "clk_rk3399", + .id = UCLASS_CLK, + .of_match = rk3399_clk_ids, + .priv_auto_alloc_size = sizeof(struct rk3399_clk_priv), + .ofdata_to_platdata = rk3399_clk_ofdata_to_platdata, + .ops = &rk3399_clk_ops, + .bind = rk3399_clk_bind, + .probe = rk3399_clk_probe, +}; From aff8795c01c39318eb07b4bf0cd7f170ff67d591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Fri, 29 Jul 2016 14:47:21 +0200 Subject: [PATCH 04/12] move: rockchip: move clock drivers into a subdirectory With the number of Rockchip clock drivers increasing, don't clutter up the core drivers/clk directory with them and instead move them out of the way into a separate subdirectory. Suggested-by: Simon Glass Signed-off-by: Heiko Stuebner Acked-by: Simon Glass Updated for rk3399: Signed-off-by: Simon Glass --- drivers/clk/Makefile | 4 +--- drivers/clk/rockchip/Makefile | 9 +++++++++ drivers/clk/{ => rockchip}/clk_rk3036.c | 0 drivers/clk/{ => rockchip}/clk_rk3288.c | 0 drivers/clk/{ => rockchip}/clk_rk3399.c | 0 5 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 drivers/clk/rockchip/Makefile rename drivers/clk/{ => rockchip}/clk_rk3036.c (100%) rename drivers/clk/{ => rockchip}/clk_rk3288.c (100%) rename drivers/clk/{ => rockchip}/clk_rk3399.c (100%) diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index e20e932337..3cbdd54f4f 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -6,9 +6,7 @@ # obj-$(CONFIG_CLK) += clk-uclass.o clk_fixed_rate.o -obj-$(CONFIG_ROCKCHIP_RK3036) += clk_rk3036.o -obj-$(CONFIG_ROCKCHIP_RK3288) += clk_rk3288.o -obj-$(CONFIG_ROCKCHIP_RK3399) += clk_rk3399.o +obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ obj-$(CONFIG_SANDBOX) += clk_sandbox.o obj-$(CONFIG_SANDBOX) += clk_sandbox_test.o obj-$(CONFIG_MACH_PIC32) += clk_pic32.o diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile new file mode 100644 index 0000000000..1f8e41739d --- /dev/null +++ b/drivers/clk/rockchip/Makefile @@ -0,0 +1,9 @@ +# +# Copyright (c) 2016 Google, Inc +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_ROCKCHIP_RK3036) += clk_rk3036.o +obj-$(CONFIG_ROCKCHIP_RK3288) += clk_rk3288.o +obj-$(CONFIG_ROCKCHIP_RK3399) += clk_rk3399.o diff --git a/drivers/clk/clk_rk3036.c b/drivers/clk/rockchip/clk_rk3036.c similarity index 100% rename from drivers/clk/clk_rk3036.c rename to drivers/clk/rockchip/clk_rk3036.c diff --git a/drivers/clk/clk_rk3288.c b/drivers/clk/rockchip/clk_rk3288.c similarity index 100% rename from drivers/clk/clk_rk3288.c rename to drivers/clk/rockchip/clk_rk3288.c diff --git a/drivers/clk/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c similarity index 100% rename from drivers/clk/clk_rk3399.c rename to drivers/clk/rockchip/clk_rk3399.c From 1c62d999528da1f052cb4b07cbb540b148c52537 Mon Sep 17 00:00:00 2001 From: Xu Ziyuan Date: Mon, 1 Aug 2016 08:46:19 +0800 Subject: [PATCH 05/12] rockchip: add support for rk3288 miniarm board Miniarm is a rockchip rk3288 based development board, which has lots of interface such as HDMI, USB, micro-SD card, Audio etc. Signed-off-by: Ziyuan Xu Acked-by: Simon Glass --- arch/arm/dts/Makefile | 1 + arch/arm/dts/rk3288-miniarm.dts | 61 ++ arch/arm/dts/rk3288-miniarm.dtsi | 533 ++++++++++++++++++ arch/arm/mach-rockchip/rk3288/Kconfig | 14 +- board/rockchip/miniarm_rk3288/Kconfig | 15 + board/rockchip/miniarm_rk3288/MAINTAINERS | 6 + board/rockchip/miniarm_rk3288/Makefile | 7 + .../rockchip/miniarm_rk3288/miniarm-rk3288.c | 15 + configs/miniarm-rk3288_defconfig | 65 +++ doc/README.rockchip | 9 +- include/configs/miniarm_rk3288.h | 26 + 11 files changed, 746 insertions(+), 6 deletions(-) create mode 100644 arch/arm/dts/rk3288-miniarm.dts create mode 100644 arch/arm/dts/rk3288-miniarm.dtsi create mode 100644 board/rockchip/miniarm_rk3288/Kconfig create mode 100644 board/rockchip/miniarm_rk3288/MAINTAINERS create mode 100644 board/rockchip/miniarm_rk3288/Makefile create mode 100644 board/rockchip/miniarm_rk3288/miniarm-rk3288.c create mode 100644 configs/miniarm-rk3288_defconfig create mode 100644 include/configs/miniarm_rk3288.h diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 639c06db0a..d93fabc76d 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -33,6 +33,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ rk3288-rock2-square.dtb \ rk3288-evb.dtb \ rk3288-fennec.dtb \ + rk3288-miniarm.dtb \ rk3288-popmetal.dtb \ rk3036-sdk.dtb \ rk3399-evb.dtb diff --git a/arch/arm/dts/rk3288-miniarm.dts b/arch/arm/dts/rk3288-miniarm.dts new file mode 100644 index 0000000000..c7410821d3 --- /dev/null +++ b/arch/arm/dts/rk3288-miniarm.dts @@ -0,0 +1,61 @@ +/* + * (C) Copyright 2016 Rockchip Electronics Co., Ltd + * + * SPDX-License-Identifier: GPL-2.0+ X11 + */ + +/dts-v1/; +#include "rk3288-miniarm.dtsi" + +/ { + model = "Miniarm-RK3288"; + compatible = "rockchip,rk3288-miniarm", "rockchip,rk3288"; + + chosen { + stdout-path = &uart2; + }; +}; + +&dmc { + rockchip,num-channels = <2>; + rockchip,pctl-timing = <0x29a 0xc8 0x1f8 0x42 0x4e 0x4 0xea 0xa + 0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7 + 0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0 + 0x1 0x7 0x7 0x4 0xc 0x43 0x100 0x0 + 0x5 0x0>; + rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200 + 0xa60 0x40 0x10 0x0>; + /* Add a dummy value to cause of-platdata think this is bytes */ + rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>; + rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>; +}; + + +&pinctrl { + u-boot,dm-pre-reloc; +}; + +&pwm1 { + status = "okay"; +}; + +&uart2 { + u-boot,dm-pre-reloc; + reg-shift = <2>; +}; + +&sdmmc { + u-boot,dm-pre-reloc; +}; + +&emmc { + u-boot,dm-pre-reloc; +}; + +&gpio3 { + u-boot,dm-pre-reloc; +}; + +&gpio8 { + u-boot,dm-pre-reloc; +}; diff --git a/arch/arm/dts/rk3288-miniarm.dtsi b/arch/arm/dts/rk3288-miniarm.dtsi new file mode 100644 index 0000000000..b88987557a --- /dev/null +++ b/arch/arm/dts/rk3288-miniarm.dtsi @@ -0,0 +1,533 @@ +/* + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "rk3288.dtsi" + +/ { + memory { + device_type = "memory"; + reg = <0x0 0x80000000>; + }; + + ext_gmac: external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "ext_gmac"; + #clock-cells = <0>; + }; + + gpio-keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + autorepeat; + + pinctrl-names = "default"; + pinctrl-0 = <&pwrbtn>; + + button@0 { + gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; + label = "GPIO Key Power"; + linux,input-type = <1>; + gpio-key,wakeup = <1>; + debounce-interval = <100>; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + pwr-led { + gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "default-on"; + }; + + act-led { + gpios=<&gpio2 3 GPIO_ACTIVE_LOW>; + linux,default-trigger="mmc0"; + }; + }; + + vcc_sys: vsys-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + regulator-boot-on; + }; + + /* + * NOTE: vcc_sd isn't hooked up on v1.0 boards where power comes from + * vcc_io directly. Those boards won't be able to power cycle SD cards + * but it shouldn't hurt to toggle this pin there anyway. + */ + vcc_sd: sdmmc-regulator { + compatible = "regulator-fixed"; + gpio = <&gpio7 11 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_pwr>; + regulator-name = "vcc_sd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + startup-delay-us = <100000>; + vin-supply = <&vcc_io>; + }; +}; + +&cpu0 { + cpu0-supply = <&vdd_cpu>; +}; + +&emmc { + broken-cd; + bus-width = <8>; + cap-mmc-highspeed; + disable-wp; + non-removable; + num-slots = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_pwr &emmc_bus8>; + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + card-detect-delay = <200>; + disable-wp; /* wp not hooked up */ + num-slots = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; + status = "okay"; + supports-sd; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; +}; + +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + +&gmac { + phy-supply = <&vcc33_lan>; + phy-mode = "rgmii"; + clock_in_out = "input"; + snps,reset-gpio = <&gpio4 7 0>; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 1000000>; + assigned-clocks = <&cru SCLK_MAC>; + assigned-clock-parents = <&ext_gmac>; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; + tx_delay = <0x30>; + rx_delay = <0x10>; + status = "ok"; +}; + +&hdmi { + ddc-i2c-bus = <&i2c5>; + status = "okay"; +}; + +&i2c0 { + status = "okay"; + clock-frequency = <400000>; + + rk808: pmic@1b { + compatible = "rockchip,rk808"; + reg = <0x1b>; + interrupt-parent = <&gpio0>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int &global_pwroff>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk808-clkout2"; + + vcc1-supply = <&vcc_sys>; + vcc2-supply = <&vcc_sys>; + vcc3-supply = <&vcc_sys>; + vcc4-supply = <&vcc_sys>; + vcc6-supply = <&vcc_sys>; + vcc7-supply = <&vcc_sys>; + vcc8-supply = <&vcc_18>; + vcc9-supply = <&vcc_io>; + vcc10-supply = <&vcc_io>; + vcc11-supply = <&vcc_sys>; + vcc12-supply = <&vcc_io>; + vddio-supply = <&vcc18_ldo1>; + + regulators { + vdd_cpu: DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-name = "vdd_arm"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1250000>; + regulator-name = "vdd_gpu"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vcc_ddr"; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_io: DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc_io"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc18_ldo1: LDO_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc18_ldo1"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc33_mipi: LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc33_mipi"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_10: LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-name = "vdd_10"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc18_codec: LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc18_codec"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vccio_sd: LDO_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vccio_sd"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vdd10_lcd: LDO_REG6 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-name = "vdd10_lcd"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc_18: LDO_REG7 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc_18"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc18_lcd: LDO_REG8 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc18_lcd"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc33_sd: SWITCH_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vcc33_sd"; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc33_lan: SWITCH_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vcc33_lan"; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + }; + }; +}; + +&i2c2 { + status = "okay"; + headset: nau8825@1a { + compatible = "nuvoton,nau8825"; + #sound-dai-cells = <0>; + reg = <0x1a>; + interrupt-parent = <&gpio6>; + interrupts = <5 IRQ_TYPE_LEVEL_LOW>; + nuvoton,jkdet-enable = <1>; + nuvoton,jkdet-pull-enable = <1>; + nuvoton,jkdet-pull-up = <0>; + nuvoton,jkdet-polarity = <1>; + nuvoton,vref-impedance = <2>; + nuvoton,micbias-voltage = <6>; + nuvoton,sar-threshold-num = <4>; + nuvoton,sar-threshold = <0xa 0x14 0x26 0x73>; + nuvoton,sar-hysteresis = <0>; + nuvoton,sar-voltage = <6>; + nuvoton,sar-compare-time = <0>; + nuvoton,sar-sampling-time = <0>; + nuvoton,short-key-debounce = <3>; + nuvoton,jack-insert-debounce = <7>; + nuvoton,jack-eject-debounce = <7>; + clock-names = "mclk"; + clocks = <&cru SCLK_I2S0_OUT>; + }; +}; + +&i2c5 { + status = "okay"; +}; + +&wdt { + status = "okay"; +}; + +&pwm0 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcc18_ldo1>; + status ="okay"; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&uart3 { + status = "okay"; +}; + +&uart4 { + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <1>; /* tshut mode 0:CRU 1:GPIO */ + rockchip,hw-tshut-polarity = <1>; /* tshut polarity 0:LOW 1:HIGH */ + status = "okay"; +}; + +&usbphy { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host1 { + status = "okay"; +}; + +&usb_otg { + status= "okay"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&vopl { + status = "okay"; +}; + +&vopl_mmu { + status = "okay"; +}; + +&pinctrl { + pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma { + drive-strength = <8>; + }; + + pcfg_pull_up_drv_8ma: pcfg-pull-up-drv-8ma { + bias-pull-up; + drive-strength = <8>; + }; + + backlight { + bl_en: bl-en { + rockchip,pins = <7 2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + buttons { + pwrbtn: pwrbtn { + rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + eth_phy { + eth_phy_pwr: eth-phy-pwr { + rockchip,pins = <0 6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int: pmic-int { + rockchip,pins = ; + }; + }; + + sdmmc { + /* + * Default drive strength isn't enough to achieve even + * high-speed mode on EVB board so bump up to 8ma. + */ + sdmmc_bus4: sdmmc-bus4 { + rockchip,pins = <6 16 RK_FUNC_1 &pcfg_pull_up_drv_8ma>, + <6 17 RK_FUNC_1 &pcfg_pull_up_drv_8ma>, + <6 18 RK_FUNC_1 &pcfg_pull_up_drv_8ma>, + <6 19 RK_FUNC_1 &pcfg_pull_up_drv_8ma>; + }; + + sdmmc_clk: sdmmc-clk { + rockchip,pins = <6 20 RK_FUNC_1 &pcfg_pull_none_drv_8ma>; + }; + + sdmmc_cmd: sdmmc-cmd { + rockchip,pins = <6 21 RK_FUNC_1 &pcfg_pull_up_drv_8ma>; + }; + + sdmmc_pwr: sdmmc-pwr { + rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb { + host_vbus_drv: host-vbus-drv { + rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pwr_3g: pwr-3g { + rockchip,pins = <7 8 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig index 8ec1920d19..b4113e085b 100644 --- a/arch/arm/mach-rockchip/rk3288/Kconfig +++ b/arch/arm/mach-rockchip/rk3288/Kconfig @@ -33,6 +33,14 @@ config TARGET_POPMETAL_RK3288 2GB DDR3. Expansion connectors provide access to I2C, SPI, UART, GPIOs and display interface. +config TARGET_MINIARM_RK3288 + bool "miniarm-RK3288" + help + Miniarm is a RK3288-based development board with 2 USB ports, HDMI, + micro-SD card, audio, Gigabit Ethernet. It also includes on-board + 8GB eMMC and 2GB of SDRAM. Expansion connectors provide access to + I2C, SPI, UART, GPIOs. + config TARGET_CHROMEBOOK_JERRY bool "Google/Rockchip Veyron-Jerry Chromebook" help @@ -64,16 +72,18 @@ config SYS_SOC config SYS_MALLOC_F_LEN default 0x0800 -source "board/google/chromebook_jerry/Kconfig" +source "board/chipspark/popmetal_rk3288/Kconfig" source "board/firefly/firefly-rk3288/Kconfig" +source "board/google/chromebook_jerry/Kconfig" + source "board/radxa/rock2/Kconfig" source "board/rockchip/evb_rk3288/Kconfig" source "board/rockchip/fennec_rk3288/Kconfig" -source "board/chipspark/popmetal_rk3288/Kconfig" +source "board/rockchip/miniarm_rk3288/Kconfig" endif diff --git a/board/rockchip/miniarm_rk3288/Kconfig b/board/rockchip/miniarm_rk3288/Kconfig new file mode 100644 index 0000000000..529c09f2c8 --- /dev/null +++ b/board/rockchip/miniarm_rk3288/Kconfig @@ -0,0 +1,15 @@ +if TARGET_MINIARM_RK3288 + +config SYS_BOARD + default "miniarm_rk3288" + +config SYS_VENDOR + default "rockchip" + +config SYS_CONFIG_NAME + default "miniarm_rk3288" + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + +endif diff --git a/board/rockchip/miniarm_rk3288/MAINTAINERS b/board/rockchip/miniarm_rk3288/MAINTAINERS new file mode 100644 index 0000000000..7537b8fbf9 --- /dev/null +++ b/board/rockchip/miniarm_rk3288/MAINTAINERS @@ -0,0 +1,6 @@ +MINIARM-RK3288 +M: Lin Huang +S: Maintained +F: board/rockchip/miniarm_rk3288 +F: include/configs/miniarm_rk3288.h +F: configs/miniarm-rk3288_defconfig diff --git a/board/rockchip/miniarm_rk3288/Makefile b/board/rockchip/miniarm_rk3288/Makefile new file mode 100644 index 0000000000..9419b91ea0 --- /dev/null +++ b/board/rockchip/miniarm_rk3288/Makefile @@ -0,0 +1,7 @@ +# +# (C) Copyright 2016 Rockchip Electronics Co., Ltd +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += miniarm-rk3288.o diff --git a/board/rockchip/miniarm_rk3288/miniarm-rk3288.c b/board/rockchip/miniarm_rk3288/miniarm-rk3288.c new file mode 100644 index 0000000000..aad74ef109 --- /dev/null +++ b/board/rockchip/miniarm_rk3288/miniarm-rk3288.c @@ -0,0 +1,15 @@ +/* + * (C) Copyright 2016 Rockchip Electronics Co., Ltd + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +void board_boot_order(u32 *spl_boot_list) +{ + /* eMMC prior to sdcard */ + spl_boot_list[0] = BOOT_DEVICE_MMC2; + spl_boot_list[1] = BOOT_DEVICE_MMC1; +} diff --git a/configs/miniarm-rk3288_defconfig b/configs/miniarm-rk3288_defconfig new file mode 100644 index 0000000000..33a4a56a6f --- /dev/null +++ b/configs/miniarm-rk3288_defconfig @@ -0,0 +1,65 @@ +CONFIG_ARM=y +CONFIG_ARCH_ROCKCHIP=y +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_ROCKCHIP_RK3288=y +CONFIG_TARGET_MINIARM_RK3288=y +CONFIG_SPL_STACK_R_ADDR=0x80000 +CONFIG_DEFAULT_DEVICE_TREE="rk3288-miniarm" +CONFIG_SPL_STACK_R=y +CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000 +CONFIG_HUSH_PARSER=y +CONFIG_CMD_BOOTZ=y +# CONFIG_CMD_IMLS is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_SF=y +CONFIG_CMD_SPI=y +CONFIG_CMD_I2C=y +CONFIG_CMD_GPIO=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_TIME=y +CONFIG_CMD_PMIC=y +CONFIG_CMD_REGULATOR=y +CONFIG_CMD_EXT2=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" +CONFIG_REGMAP=y +CONFIG_SPL_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_SYSCON=y +# CONFIG_SPL_SIMPLE_BUS is not set +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_ROCKCHIP_GPIO=y +CONFIG_SYS_I2C_ROCKCHIP=y +CONFIG_SYSRESET=y +CONFIG_DM_MMC=y +CONFIG_ROCKCHIP_DWMMC=y +CONFIG_PINCTRL=y +CONFIG_SPL_PINCTRL=y +# CONFIG_SPL_PINCTRL_FULL is not set +CONFIG_ROCKCHIP_RK3288_PINCTRL=y +CONFIG_DM_PMIC=y +CONFIG_PMIC_RK808=y +CONFIG_DM_REGULATOR=y +CONFIG_REGULATOR_RK808=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_PWM=y +CONFIG_PWM_ROCKCHIP=y +CONFIG_RAM=y +CONFIG_SPL_RAM=y +CONFIG_DEBUG_UART=y +CONFIG_DEBUG_UART_BASE=0xff690000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYS_NS16550=y +CONFIG_USE_PRIVATE_LIBGCC=y +CONFIG_USE_TINY_PRINTF=y +CONFIG_CMD_DHRYSTONE=y +CONFIG_ERRNO_STR=y diff --git a/doc/README.rockchip b/doc/README.rockchip index 1b3a602234..69b926c52d 100644 --- a/doc/README.rockchip +++ b/doc/README.rockchip @@ -36,14 +36,15 @@ You will need: Building ======== -At present six RK3288 boards are supported: +At present seven RK3288 boards are supported: - - Firefly RK3288 - use firefly-rk3288 configuration - - Radxa Rock 2 - use rock2 configuration - - Hisense Chromebook - use chromebook_jerry configuration - EVB RK3288 - use evb-rk3288 configuration - Fennec RK3288 - use fennec-rk3288 configuration + - Firefly RK3288 - use firefly-rk3288 configuration + - Hisense Chromebook - use chromebook_jerry configuration + - Miniarm RK3288 - use miniarm-rk3288 configuration - PopMetal RK3288 - use popmetal-rk3288 configuration + - Radxa Rock 2 - use rock2 configuration Two RK3036 board are supported: diff --git a/include/configs/miniarm_rk3288.h b/include/configs/miniarm_rk3288.h new file mode 100644 index 0000000000..342557fff3 --- /dev/null +++ b/include/configs/miniarm_rk3288.h @@ -0,0 +1,26 @@ +/* + * (C) Copyright 2016 Rockchip Electronics Co., Ltd + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#define ROCKCHIP_DEVICE_SETTINGS +#include + +#define CONFIG_SPL_MMC_SUPPORT + +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 1 +/* SPL @ 32k for ~36k + * ENV @ 96k + * u-boot @ 128K + */ +#define CONFIG_ENV_OFFSET (96 * 1024) + +#define CONFIG_SYS_WHITE_ON_BLACK +#define CONFIG_CONSOLE_SCROLL_LINES 10 + +#endif From 6ead8bd7c338f31788402f2dd82bc68c38cd8b42 Mon Sep 17 00:00:00 2001 From: Xu Ziyuan Date: Wed, 3 Aug 2016 11:55:05 +0800 Subject: [PATCH 06/12] rockchip: add basic partitions support for rk3288 For compatibility with distro boot, fastboot, and mount the mmc deivce to PC via usb mass storage feature, GPT partitions are essential. You should write the partitions to mmc device prior to use above feature. => gpt write mmc 1 $partitions GPT successfully written to block device! success! Signed-off-by: Ziyuan Xu Acked-by: Simon Glass --- include/configs/rk3288_common.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h index 814116c93e..fa37335b8b 100644 --- a/include/configs/rk3288_common.h +++ b/include/configs/rk3288_common.h @@ -113,6 +113,12 @@ "kernel_addr_r=0x02000000\0" \ "ramdisk_addr_r=0x04000000\0" +#define CONFIG_RANDOM_UUID +#define PARTS_DEFAULT \ + "uuid_disk=${uuid_gpt_disk};" \ + "name=boot,start=8M,size=64M,bootable,uuid=${uuid_gpt_boot};" \ + "name=rootfs,size=-,uuid=${uuid_gpt_rootfs};\0" \ + /* First try to boot from SD (index 0), then eMMC (index 1 */ #define BOOT_TARGET_DEVICES(func) \ func(MMC, mmc, 0) \ @@ -125,6 +131,7 @@ #define CONFIG_EXTRA_ENV_SETTINGS \ "fdt_high=0x1fffffff\0" \ "initrd_high=0x1fffffff\0" \ + "partitions=" PARTS_DEFAULT \ ENV_MEM_LAYOUT_SETTINGS \ ROCKCHIP_DEVICE_SETTINGS \ BOOTENV From b9f9339b7e69b7f81b3b57dcf7f1b51a0bf4a7e2 Mon Sep 17 00:00:00 2001 From: Xu Ziyuan Date: Wed, 3 Aug 2016 11:55:06 +0800 Subject: [PATCH 07/12] rockchip: add usb mass storage feature support for rk3288 Enable ums feature for rk3288 boards, so that we can mount the mmc device to PC. Signed-off-by: Ziyuan Xu Acked-by: Simon Glass --- include/configs/rk3288_common.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h index fa37335b8b..d3d4c680e9 100644 --- a/include/configs/rk3288_common.h +++ b/include/configs/rk3288_common.h @@ -96,6 +96,10 @@ #define CONFIG_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR #define CONFIG_FASTBOOT_BUF_SIZE 0x08000000 +/* usb mass storage */ +#define CONFIG_USB_FUNCTION_MASS_STORAGE +#define CONFIG_CMD_USB_MASS_STORAGE + #define CONFIG_USB_GADGET_DOWNLOAD #define CONFIG_G_DNL_MANUFACTURER "Rockchip" #define CONFIG_G_DNL_VENDOR_NUM 0x2207 From 583b1bc029d86d87152d7819cd06cc557de6ddf9 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Thu, 4 Aug 2016 11:40:29 +0800 Subject: [PATCH 08/12] configs: rk3399: add gpt and fs support To compatible with distro boot, we need to add gpt and fs support, including gpt table and vfat, ext2, ext4 support. Signed-off-by: Kever Yang Reviewed-by: Simon Glass Acked-by: Simon Glass --- include/configs/rk3399_common.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h index 6ce1aa76a6..1ed46416a1 100644 --- a/include/configs/rk3399_common.h +++ b/include/configs/rk3399_common.h @@ -34,7 +34,11 @@ #define CONFIG_BOUNCE_BUFFER #define CONFIG_ROCKCHIP_SDHCI_MAX_FREQ 200000000 +#define CONFIG_SUPPORT_VFAT +#define CONFIG_FS_FAT #define CONFIG_FAT_WRITE +#define CONFIG_FS_EXT4 +#define CONFIG_CMD_PART /* RAW SD card / eMMC locations. */ #define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 256 @@ -59,6 +63,14 @@ "kernel_addr_r=0x02000000\0" \ "ramdisk_addr_r=0x04000000\0" +#define CONFIG_CMD_GPT +#define CONFIG_RANDOM_UUID +#define CONFIG_PARTITION_UUIDS +#define PARTS_DEFAULT \ + "uuid_disk=${uuid_gpt_disk};" \ + "name=boot,start=16M,size=32M,bootable;" \ + "name=rootfs,size=-,uuid=${uuid_gpt_rootfs};\0" \ + /* First try to boot from SD (index 0), then eMMC (index 1) */ #define BOOT_TARGET_DEVICES(func) \ func(MMC, mmc, 0) \ @@ -66,6 +78,8 @@ #include #define CONFIG_EXTRA_ENV_SETTINGS \ + ENV_MEM_LAYOUT_SETTINGS \ + "partitions=" PARTS_DEFAULT \ BOOTENV #endif From fd4b2dc05996dad7680442ed574614d3db048f86 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Thu, 4 Aug 2016 11:44:58 +0800 Subject: [PATCH 09/12] clock: rk3399: add support for dwmmc 400K MMC core will use 400KHz for card initialize first and then switch to higher frequency like 50MHz, we need to support both 400KHz and about 50MHz for dwmmc controller. Signed-off-by: Kever Yang Acked-by: Simon Glass --- drivers/clk/rockchip/clk_rk3399.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c index c0bb80c462..0b4ea828f6 100644 --- a/drivers/clk/rockchip/clk_rk3399.c +++ b/drivers/clk/rockchip/clk_rk3399.c @@ -142,6 +142,7 @@ enum { CLK_EMMC_PLL_SHIFT = 8, CLK_EMMC_PLL_MASK = 0x7 << CLK_EMMC_PLL_SHIFT, CLK_EMMC_PLL_SEL_GPLL = 0x1, + CLK_EMMC_PLL_SEL_24M = 0x5, CLK_EMMC_DIV_CON_SHIFT = 0, CLK_EMMC_DIV_CON_MASK = 0x7f << CLK_EMMC_DIV_CON_SHIFT, @@ -642,9 +643,13 @@ static ulong rk3399_mmc_get_clk(struct rk3399_cru *cru, uint clk_id) default: return -EINVAL; } - div = (con>>CLK_EMMC_DIV_CON_SHIFT) & CLK_EMMC_DIV_CON_MASK; + div = (con & CLK_EMMC_DIV_CON_MASK) >> CLK_EMMC_DIV_CON_SHIFT; - return DIV_TO_RATE(GPLL_HZ, div); + if ((con & CLK_EMMC_PLL_MASK) >> CLK_EMMC_PLL_SHIFT + == CLK_EMMC_PLL_SEL_24M) + return DIV_TO_RATE(24*1024*1024, div); + else + return DIV_TO_RATE(GPLL_HZ, div); } static ulong rk3399_mmc_set_clk(struct rk3399_cru *cru, @@ -655,14 +660,22 @@ static ulong rk3399_mmc_set_clk(struct rk3399_cru *cru, switch (clk_id) { case SCLK_SDMMC: - /* Select clk_sdmmc source from GPLL too */ + /* Select clk_sdmmc source from GPLL by default */ src_clk_div = GPLL_HZ / set_rate; - assert(src_clk_div - 1 < 127); - rk_clrsetreg(&cru->clksel_con[16], - CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, - CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT | - (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); + if (src_clk_div > 127) { + /* use 24MHz source for 400KHz clock */ + src_clk_div = 24*1024*1024 / set_rate; + rk_clrsetreg(&cru->clksel_con[16], + CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, + CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT | + (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); + } else { + rk_clrsetreg(&cru->clksel_con[16], + CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, + CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT | + (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); + } break; case SCLK_EMMC: /* Select aclk_emmc source from GPLL */ From da8ff82e73f559ed22a7a0da44f670088f4154f8 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Thu, 4 Aug 2016 11:44:59 +0800 Subject: [PATCH 10/12] dts: rk3399: enable dwmmc for sdcard rk3399 sdcard is using dwmmc controller, enable it for sdcard. SCLK_SDMMC is the clock for controller operation clock, move it to the first place. Signed-off-by: Kever Yang Acked-by: Simon Glass --- arch/arm/dts/rk3399-evb.dts | 4 ++++ arch/arm/dts/rk3399.dtsi | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/dts/rk3399-evb.dts b/arch/arm/dts/rk3399-evb.dts index bbcfcd0da9..e92a492545 100644 --- a/arch/arm/dts/rk3399-evb.dts +++ b/arch/arm/dts/rk3399-evb.dts @@ -61,6 +61,10 @@ status = "okay"; }; +&sdmmc { + status = "okay"; +}; + &sdhci { bus-width = <8>; mmc-hs400-1_8v; diff --git a/arch/arm/dts/rk3399.dtsi b/arch/arm/dts/rk3399.dtsi index fb5af54799..a4c6e27b39 100644 --- a/arch/arm/dts/rk3399.dtsi +++ b/arch/arm/dts/rk3399.dtsi @@ -172,9 +172,9 @@ reg = <0x0 0xfe320000 0x0 0x4000>; interrupts = ; clock-freq-min-max = <400000 150000000>; - clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, + clocks = <&cru SCLK_SDMMC>, <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; - clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + clock-names = "ciu", "biu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; status = "disabled"; }; From 75a52bd770bcaa3fd065237538263f8e11240fe0 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Thu, 4 Aug 2016 11:45:00 +0800 Subject: [PATCH 11/12] config: rk3399: enable dwmmc controller Enable the rockchip dwmmc driver for rk3399 and its evb. Signed-off-by: Kever Yang Acked-by: Simon Glass --- configs/evb-rk3399_defconfig | 1 + include/configs/rk3399_common.h | 1 + 2 files changed, 2 insertions(+) diff --git a/configs/evb-rk3399_defconfig b/configs/evb-rk3399_defconfig index 3f9b47e679..cd06cae595 100644 --- a/configs/evb-rk3399_defconfig +++ b/configs/evb-rk3399_defconfig @@ -21,6 +21,7 @@ CONFIG_CLK=y CONFIG_FIT=y CONFIG_SYSRESET=y CONFIG_DM_MMC=y +CONFIG_ROCKCHIP_DWMMC=y CONFIG_ROCKCHIP_SDHCI=y CONFIG_PINCTRL=y CONFIG_RAM=y diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h index 1ed46416a1..6875308e11 100644 --- a/include/configs/rk3399_common.h +++ b/include/configs/rk3399_common.h @@ -30,6 +30,7 @@ /* MMC/SD IP block */ #define CONFIG_MMC #define CONFIG_GENERIC_MMC +#define CONFIG_DWMMC #define CONFIG_SDHCI #define CONFIG_BOUNCE_BUFFER #define CONFIG_ROCKCHIP_SDHCI_MAX_FREQ 200000000 From abd0128eb12232948c6b7d3ad88132bb2d4897f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Fri, 22 Jul 2016 23:51:06 +0200 Subject: [PATCH 12/12] rockchip: remove log2 reimplementation from clock drivers The already available ilog2 function does exactly the same in the common case than the log2 function the current clock-driver reimplement. So, simply move to that one. Signed-off-by: Heiko Stuebner Acked-by: Simon Glass --- drivers/clk/rockchip/clk_rk3036.c | 10 +++------- drivers/clk/rockchip/clk_rk3288.c | 10 +++------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/drivers/clk/rockchip/clk_rk3036.c b/drivers/clk/rockchip/clk_rk3036.c index 6202c9da5d..8899b0c62d 100644 --- a/drivers/clk/rockchip/clk_rk3036.c +++ b/drivers/clk/rockchip/clk_rk3036.c @@ -15,6 +15,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -48,11 +49,6 @@ enum { 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; -} - void *rockchip_get_cru(void) { struct udevice *dev; @@ -177,11 +173,11 @@ static void rkclk_init(struct rk3036_cru *cru) 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); + hclk_div = ilog2(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); + pclk_div = ilog2(PERI_ACLK_HZ / PERI_PCLK_HZ); assert((1 << pclk_div) * PERI_PCLK_HZ == PERI_ACLK_HZ && pclk_div < 0x8); diff --git a/drivers/clk/rockchip/clk_rk3288.c b/drivers/clk/rockchip/clk_rk3288.c index e00feb0809..c07203d84b 100644 --- a/drivers/clk/rockchip/clk_rk3288.c +++ b/drivers/clk/rockchip/clk_rk3288.c @@ -20,6 +20,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -186,11 +187,6 @@ static int rkclk_set_pll(struct rk3288_cru *cru, enum rk_clk_id clk_id, return 0; } -static inline unsigned int log2(unsigned int value) -{ - return fls(value) - 1; -} - static int rkclk_configure_ddr(struct rk3288_cru *cru, struct rk3288_grf *grf, unsigned int hz) { @@ -421,11 +417,11 @@ static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf) 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); + hclk_div = ilog2(PERI_ACLK_HZ / PERI_HCLK_HZ); assert((1 << hclk_div) * PERI_HCLK_HZ == PERI_ACLK_HZ && (hclk_div < 0x4)); - pclk_div = log2(PERI_ACLK_HZ / PERI_PCLK_HZ); + pclk_div = ilog2(PERI_ACLK_HZ / PERI_PCLK_HZ); assert((1 << pclk_div) * PERI_PCLK_HZ == PERI_ACLK_HZ && (pclk_div < 0x4));