From 2e4ce50d1aca35d13944f48a7e15d0b63e86eb38 Mon Sep 17 00:00:00 2001 From: David Wu Date: Wed, 20 Sep 2017 14:28:18 +0800 Subject: rockchip: clk: Add rv1108 SARADC clock support The clk_saradc is dividing from the 24M, clk_saradc=24MHz/(saradc_div_con+1). SARADC integer divider control register is 10-bits width. Signed-off-by: David Wu Acked-by: Philipp Tomsich Reviewed-by: Philipp Tomsich --- arch/arm/include/asm/arch-rockchip/cru_rv1108.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-rockchip/cru_rv1108.h b/arch/arm/include/asm/arch-rockchip/cru_rv1108.h index 2a1ae692bef..ad2dc964675 100644 --- a/arch/arm/include/asm/arch-rockchip/cru_rv1108.h +++ b/arch/arm/include/asm/arch-rockchip/cru_rv1108.h @@ -90,6 +90,11 @@ enum { CORE_CLK_DIV_SHIFT = 0, CORE_CLK_DIV_MASK = 0x1f << CORE_CLK_DIV_SHIFT, + /* CLKSEL_CON22 */ + CLK_SARADC_DIV_CON_SHIFT= 0, + CLK_SARADC_DIV_CON_MASK = GENMASK(9, 0), + CLK_SARADC_DIV_CON_WIDTH= 10, + /* CLKSEL24_CON */ MAC_PLL_SEL_SHIFT = 12, MAC_PLL_SEL_MASK = 1 << MAC_PLL_SEL_SHIFT, -- cgit v1.2.3 From 615514c16dee4d43bd584ea326a5a56ebcb89c85 Mon Sep 17 00:00:00 2001 From: David Wu Date: Wed, 20 Sep 2017 14:37:50 +0800 Subject: rockchip: clk: Add rk3368 SARADC clock support The clk_saradc is dividing from the 24M, clk_saradc=24MHz/(saradc_div_con+1). SARADC integer divider control register is 8-bits width. Signed-off-by: David Wu Acked-by: Philipp Tomsich Reviewed-by: Philipp Tomsich --- arch/arm/include/asm/arch-rockchip/cru_rk3368.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3368.h b/arch/arm/include/asm/arch-rockchip/cru_rk3368.h index 2b1197fd466..5f6a5fbe4cb 100644 --- a/arch/arm/include/asm/arch-rockchip/cru_rk3368.h +++ b/arch/arm/include/asm/arch-rockchip/cru_rk3368.h @@ -89,6 +89,11 @@ enum { MCU_CLK_DIV_SHIFT = 0, MCU_CLK_DIV_MASK = GENMASK(4, 0), + /* CLKSEL_CON25 */ + CLK_SARADC_DIV_CON_SHIFT = 8, + CLK_SARADC_DIV_CON_MASK = GENMASK(15, 8), + CLK_SARADC_DIV_CON_WIDTH = 8, + /* CLKSEL43_CON */ GMAC_MUX_SEL_EXTCLK = BIT(8), -- cgit v1.2.3 From fdc1eccbd19e8ea45e527d2b199917c075b6a4cd Mon Sep 17 00:00:00 2001 From: David Wu Date: Wed, 20 Sep 2017 14:40:11 +0800 Subject: rockchip: dts: rv1108: Add SARADC node at dtsi level Signed-off-by: David Wu Acked-by: Philipp Tomsich Reviewed-by: Philipp Tomsich --- arch/arm/dts/rv1108.dtsi | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch') diff --git a/arch/arm/dts/rv1108.dtsi b/arch/arm/dts/rv1108.dtsi index 3153dfe6584..31b4d93b076 100644 --- a/arch/arm/dts/rv1108.dtsi +++ b/arch/arm/dts/rv1108.dtsi @@ -126,6 +126,17 @@ reg = <0x10300000 0x1000>; }; + saradc: saradc@1038c000 { + compatible = "rockchip,rv1108-saradc", "rockchip,rk3399-saradc"; + reg = <0x1038c000 0x100>; + interrupts = ; + #io-channel-cells = <1>; + clock-frequency = <1000000>; + clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>; + clock-names = "saradc", "apb_pclk"; + status = "disabled"; + }; + pmugrf: syscon@20060000 { compatible = "rockchip,rv1108-pmugrf", "syscon"; reg = <0x20060000 0x1000>; -- cgit v1.2.3 From 679276bde6f0aebb207053b5f11012f20577ce37 Mon Sep 17 00:00:00 2001 From: David Wu Date: Wed, 20 Sep 2017 14:41:38 +0800 Subject: rockchip: dts: Enable SARADC for rv1108-evb Enable the SARADC for download key pressed detect. Signed-off-by: David Wu Acked-by: Philipp Tomsich Reviewed-by: Philipp Tomsich --- arch/arm/dts/rv1108-evb.dts | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/arm/dts/rv1108-evb.dts b/arch/arm/dts/rv1108-evb.dts index 2b221b6d61e..8e857b2c891 100644 --- a/arch/arm/dts/rv1108-evb.dts +++ b/arch/arm/dts/rv1108-evb.dts @@ -39,6 +39,10 @@ snps,reset-gpio = <&gpio1 RK_PC1 GPIO_ACTIVE_LOW>; }; +&saradc { + status = "okay"; +}; + &sfc { status = "okay"; flash@0 { -- cgit v1.2.3 From 0eaf58bfaa0cffe822e216e260c1d36284d8bf10 Mon Sep 17 00:00:00 2001 From: David Wu Date: Wed, 20 Sep 2017 14:43:08 +0800 Subject: rockchip: dts: Enable SARADC for rk3288-popmetal Enable the SARADC for download key pressed detect. Signed-off-by: David Wu Acked-by: Philipp Tomsich Reviewed-by: Philipp Tomsich --- arch/arm/dts/rk3288-popmetal.dtsi | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/arm/dts/rk3288-popmetal.dtsi b/arch/arm/dts/rk3288-popmetal.dtsi index dd6ce8b69e6..63785eb55ef 100644 --- a/arch/arm/dts/rk3288-popmetal.dtsi +++ b/arch/arm/dts/rk3288-popmetal.dtsi @@ -491,6 +491,10 @@ }; }; +&saradc { + status = "okay"; +}; + &tsadc { rockchip,hw-tshut-mode = <0>; rockchip,hw-tshut-polarity = <0>; -- cgit v1.2.3 From f957dec682dc2fa0363e09bfb5f41f008569245b Mon Sep 17 00:00:00 2001 From: David Wu Date: Wed, 20 Sep 2017 14:44:23 +0800 Subject: rockchip: dts: Enable SARADC for rk3328-evb Enable the SARADC for download key pressed detect. Signed-off-by: David Wu Acked-by: Philipp Tomsich Reviewed-by: Philipp Tomsich --- arch/arm/dts/rk3328-evb.dts | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/arm/dts/rk3328-evb.dts b/arch/arm/dts/rk3328-evb.dts index 8a14c653e46..df44ccbdb02 100644 --- a/arch/arm/dts/rk3328-evb.dts +++ b/arch/arm/dts/rk3328-evb.dts @@ -42,6 +42,10 @@ }; }; +&saradc { + status = "okay"; +}; + &uart2 { status = "okay"; }; -- cgit v1.2.3 From 0ac1ae65eae072b56928f17b4a2abf79d2d1c477 Mon Sep 17 00:00:00 2001 From: David Wu Date: Wed, 20 Sep 2017 14:45:21 +0800 Subject: rockchip: dts: Enable SARADC for rk3368-px5-evb Enable the SARADC for download key pressed detect. Signed-off-by: David Wu Acked-by: Philipp Tomsich Reviewed-by: Philipp Tomsich --- arch/arm/dts/rk3368-px5-evb.dts | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/arm/dts/rk3368-px5-evb.dts b/arch/arm/dts/rk3368-px5-evb.dts index c7478f7ddb7..e9c5ebad478 100644 --- a/arch/arm/dts/rk3368-px5-evb.dts +++ b/arch/arm/dts/rk3368-px5-evb.dts @@ -296,6 +296,10 @@ }; }; +&saradc { + status = "okay"; +}; + &tsadc { status = "okay"; rockchip,hw-tshut-mode = <0>; /* CRU */ -- cgit v1.2.3 From 6333a3bad91153c9183060624de190709076eb48 Mon Sep 17 00:00:00 2001 From: David Wu Date: Wed, 20 Sep 2017 14:46:19 +0800 Subject: rockchip: dts: Enable SARADC for rk3368-sheep Enable the SARADC for download key pressed detect. Signed-off-by: David Wu Acked-by: Philipp Tomsich Reviewed-by: Philipp Tomsich --- arch/arm/dts/rk3368-sheep.dts | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/arm/dts/rk3368-sheep.dts b/arch/arm/dts/rk3368-sheep.dts index 7c190f74566..27befadd67c 100644 --- a/arch/arm/dts/rk3368-sheep.dts +++ b/arch/arm/dts/rk3368-sheep.dts @@ -260,6 +260,10 @@ }; }; +&saradc { + status = "okay"; +}; + &tsadc { status = "okay"; rockchip,hw-tshut-mode = <0>; /* CRU */ -- cgit v1.2.3 From 3b4cab15acd83aa468e809a300797253d8f66818 Mon Sep 17 00:00:00 2001 From: David Wu Date: Wed, 20 Sep 2017 14:47:19 +0800 Subject: rockchip: dts: Enable SARADC for rk3399-evb Enable the SARADC for download key pressed detect. Signed-off-by: David Wu Acked-by: Philipp Tomsich Reviewed-by: Philipp Tomsich --- arch/arm/dts/rk3399-evb.dts | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/arm/dts/rk3399-evb.dts b/arch/arm/dts/rk3399-evb.dts index be0c6d98bd3..0e5d8d79a19 100644 --- a/arch/arm/dts/rk3399-evb.dts +++ b/arch/arm/dts/rk3399-evb.dts @@ -149,6 +149,10 @@ status = "okay"; }; +&saradc { + status = "okay"; +}; + &sdmmc { bus-width = <4>; status = "okay"; -- cgit v1.2.3 From 8e8bcccc1830723ead3eaa9fdbf9579f09973f39 Mon Sep 17 00:00:00 2001 From: Philipp Tomsich Date: Wed, 20 Sep 2017 13:50:13 +0200 Subject: rockchip: imply ADC and SARADC_ROCKCHIP for Rockchip SOCs Enable the Rockchip SARADC driver for all Rockchip SoCs. Note that the SARADC peripheral is available on all SoCs except the RK3036 and RK3228. However, as this is a DM-driver, enabling by default will not cause any function problems (and can always be changed from defconfig, if size is a concern). Signed-off-by: Philipp Tomsich Reviewed-by: David Wu --- arch/arm/Kconfig | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index fca23b4e64e..f0135307df7 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1115,6 +1115,8 @@ config ARCH_ROCKCHIP imply FAT_WRITE imply USB_FUNCTION_FASTBOOT imply SPL_SYSRESET + imply ADC + imply SARADC_ROCKCHIP config TARGET_THUNDERX_88XX bool "Support ThunderX 88xx" -- cgit v1.2.3 From b5934cf67cc3072f87b6c8a220b686b7d452b0b3 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Wed, 27 Sep 2017 16:11:30 +0800 Subject: rockchip: rk3399: move sdram driver to driver/ram Since we have CONFIG_RAM framwork and its driver folder, move the driver into it. Signed-off-by: Kever Yang Acked-by: Philipp Tomsich Reviewed-by: Philipp Tomsich --- arch/arm/mach-rockchip/rk3399/Makefile | 1 - arch/arm/mach-rockchip/rk3399/sdram_rk3399.c | 1238 -------------------------- 2 files changed, 1239 deletions(-) delete mode 100644 arch/arm/mach-rockchip/rk3399/sdram_rk3399.c (limited to 'arch') diff --git a/arch/arm/mach-rockchip/rk3399/Makefile b/arch/arm/mach-rockchip/rk3399/Makefile index 793ce31c12c..98ebeac340d 100644 --- a/arch/arm/mach-rockchip/rk3399/Makefile +++ b/arch/arm/mach-rockchip/rk3399/Makefile @@ -6,5 +6,4 @@ obj-y += clk_rk3399.o obj-y += rk3399.o -obj-y += sdram_rk3399.o obj-y += syscon_rk3399.o diff --git a/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c b/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c deleted file mode 100644 index 5ed4b03837d..00000000000 --- a/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c +++ /dev/null @@ -1,1238 +0,0 @@ -/* - * (C) Copyright 2016-2017 Rockchip Inc. - * - * SPDX-License-Identifier: GPL-2.0 - * - * Adapted from coreboot. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; -struct chan_info { - struct rk3399_ddr_pctl_regs *pctl; - struct rk3399_ddr_pi_regs *pi; - struct rk3399_ddr_publ_regs *publ; - struct rk3399_msch_regs *msch; -}; - -struct dram_info { -#ifdef CONFIG_SPL_BUILD - struct chan_info chan[2]; - struct clk ddr_clk; - struct rk3399_cru *cru; - struct rk3399_pmucru *pmucru; - struct rk3399_pmusgrf_regs *pmusgrf; - struct rk3399_ddr_cic_regs *cic; -#endif - struct ram_info info; - struct rk3399_pmugrf_regs *pmugrf; -}; - -#define PRESET_SGRF_HOLD(n) ((0x1 << (6 + 16)) | ((n) << 6)) -#define PRESET_GPIO0_HOLD(n) ((0x1 << (7 + 16)) | ((n) << 7)) -#define PRESET_GPIO1_HOLD(n) ((0x1 << (8 + 16)) | ((n) << 8)) - -#define PHY_DRV_ODT_Hi_Z 0x0 -#define PHY_DRV_ODT_240 0x1 -#define PHY_DRV_ODT_120 0x8 -#define PHY_DRV_ODT_80 0x9 -#define PHY_DRV_ODT_60 0xc -#define PHY_DRV_ODT_48 0xd -#define PHY_DRV_ODT_40 0xe -#define PHY_DRV_ODT_34_3 0xf - -#ifdef CONFIG_SPL_BUILD - -struct rockchip_dmc_plat { -#if CONFIG_IS_ENABLED(OF_PLATDATA) - struct dtd_rockchip_rk3399_dmc dtplat; -#else - struct rk3399_sdram_params sdram_params; -#endif - struct regmap *map; -}; - -static void copy_to_reg(u32 *dest, const u32 *src, u32 n) -{ - int i; - - for (i = 0; i < n / sizeof(u32); i++) { - writel(*src, dest); - src++; - dest++; - } -} - -static void phy_dll_bypass_set(struct rk3399_ddr_publ_regs *ddr_publ_regs, - u32 freq) -{ - u32 *denali_phy = ddr_publ_regs->denali_phy; - - /* From IP spec, only freq small than 125 can enter dll bypass mode */ - if (freq <= 125) { - /* phy_sw_master_mode_X PHY_86/214/342/470 4bits offset_8 */ - setbits_le32(&denali_phy[86], (0x3 << 2) << 8); - setbits_le32(&denali_phy[214], (0x3 << 2) << 8); - setbits_le32(&denali_phy[342], (0x3 << 2) << 8); - setbits_le32(&denali_phy[470], (0x3 << 2) << 8); - - /* phy_adrctl_sw_master_mode PHY_547/675/803 4bits offset_16 */ - setbits_le32(&denali_phy[547], (0x3 << 2) << 16); - setbits_le32(&denali_phy[675], (0x3 << 2) << 16); - setbits_le32(&denali_phy[803], (0x3 << 2) << 16); - } else { - /* phy_sw_master_mode_X PHY_86/214/342/470 4bits offset_8 */ - clrbits_le32(&denali_phy[86], (0x3 << 2) << 8); - clrbits_le32(&denali_phy[214], (0x3 << 2) << 8); - clrbits_le32(&denali_phy[342], (0x3 << 2) << 8); - clrbits_le32(&denali_phy[470], (0x3 << 2) << 8); - - /* phy_adrctl_sw_master_mode PHY_547/675/803 4bits offset_16 */ - clrbits_le32(&denali_phy[547], (0x3 << 2) << 16); - clrbits_le32(&denali_phy[675], (0x3 << 2) << 16); - clrbits_le32(&denali_phy[803], (0x3 << 2) << 16); - } -} - -static void set_memory_map(const struct chan_info *chan, u32 channel, - const struct rk3399_sdram_params *sdram_params) -{ - const struct rk3399_sdram_channel *sdram_ch = - &sdram_params->ch[channel]; - u32 *denali_ctl = chan->pctl->denali_ctl; - u32 *denali_pi = chan->pi->denali_pi; - u32 cs_map; - u32 reduc; - u32 row; - - /* Get row number from ddrconfig setting */ - if (sdram_ch->ddrconfig < 2 || sdram_ch->ddrconfig == 4) - row = 16; - else if (sdram_ch->ddrconfig == 3) - row = 14; - else - row = 15; - - cs_map = (sdram_ch->rank > 1) ? 3 : 1; - reduc = (sdram_ch->bw == 2) ? 0 : 1; - - /* Set the dram configuration to ctrl */ - clrsetbits_le32(&denali_ctl[191], 0xF, (12 - sdram_ch->col)); - clrsetbits_le32(&denali_ctl[190], (0x3 << 16) | (0x7 << 24), - ((3 - sdram_ch->bk) << 16) | - ((16 - row) << 24)); - - clrsetbits_le32(&denali_ctl[196], 0x3 | (1 << 16), - cs_map | (reduc << 16)); - - /* PI_199 PI_COL_DIFF:RW:0:4 */ - clrsetbits_le32(&denali_pi[199], 0xF, (12 - sdram_ch->col)); - - /* PI_155 PI_ROW_DIFF:RW:24:3 PI_BANK_DIFF:RW:16:2 */ - clrsetbits_le32(&denali_pi[155], (0x3 << 16) | (0x7 << 24), - ((3 - sdram_ch->bk) << 16) | - ((16 - row) << 24)); - /* PI_41 PI_CS_MAP:RW:24:4 */ - clrsetbits_le32(&denali_pi[41], 0xf << 24, cs_map << 24); - if ((sdram_ch->rank == 1) && (sdram_params->base.dramtype == DDR3)) - writel(0x2EC7FFFF, &denali_pi[34]); -} - -static void set_ds_odt(const struct chan_info *chan, - const struct rk3399_sdram_params *sdram_params) -{ - u32 *denali_phy = chan->publ->denali_phy; - - u32 tsel_idle_en, tsel_wr_en, tsel_rd_en; - u32 tsel_idle_select_p, tsel_wr_select_p, tsel_rd_select_p; - u32 ca_tsel_wr_select_p, ca_tsel_wr_select_n; - u32 tsel_idle_select_n, tsel_wr_select_n, tsel_rd_select_n; - u32 reg_value; - - if (sdram_params->base.dramtype == LPDDR4) { - tsel_rd_select_p = PHY_DRV_ODT_Hi_Z; - tsel_wr_select_p = PHY_DRV_ODT_40; - ca_tsel_wr_select_p = PHY_DRV_ODT_40; - tsel_idle_select_p = PHY_DRV_ODT_Hi_Z; - - tsel_rd_select_n = PHY_DRV_ODT_240; - tsel_wr_select_n = PHY_DRV_ODT_40; - ca_tsel_wr_select_n = PHY_DRV_ODT_40; - tsel_idle_select_n = PHY_DRV_ODT_240; - } else if (sdram_params->base.dramtype == LPDDR3) { - tsel_rd_select_p = PHY_DRV_ODT_240; - tsel_wr_select_p = PHY_DRV_ODT_34_3; - ca_tsel_wr_select_p = PHY_DRV_ODT_48; - tsel_idle_select_p = PHY_DRV_ODT_240; - - tsel_rd_select_n = PHY_DRV_ODT_Hi_Z; - tsel_wr_select_n = PHY_DRV_ODT_34_3; - ca_tsel_wr_select_n = PHY_DRV_ODT_48; - tsel_idle_select_n = PHY_DRV_ODT_Hi_Z; - } else { - tsel_rd_select_p = PHY_DRV_ODT_240; - tsel_wr_select_p = PHY_DRV_ODT_34_3; - ca_tsel_wr_select_p = PHY_DRV_ODT_34_3; - tsel_idle_select_p = PHY_DRV_ODT_240; - - tsel_rd_select_n = PHY_DRV_ODT_240; - tsel_wr_select_n = PHY_DRV_ODT_34_3; - ca_tsel_wr_select_n = PHY_DRV_ODT_34_3; - tsel_idle_select_n = PHY_DRV_ODT_240; - } - - if (sdram_params->base.odt == 1) - tsel_rd_en = 1; - else - tsel_rd_en = 0; - - tsel_wr_en = 0; - tsel_idle_en = 0; - - /* - * phy_dq_tsel_select_X 24bits DENALI_PHY_6/134/262/390 offset_0 - * sets termination values for read/idle cycles and drive strength - * for write cycles for DQ/DM - */ - reg_value = tsel_rd_select_n | (tsel_rd_select_p << 0x4) | - (tsel_wr_select_n << 8) | (tsel_wr_select_p << 12) | - (tsel_idle_select_n << 16) | (tsel_idle_select_p << 20); - clrsetbits_le32(&denali_phy[6], 0xffffff, reg_value); - clrsetbits_le32(&denali_phy[134], 0xffffff, reg_value); - clrsetbits_le32(&denali_phy[262], 0xffffff, reg_value); - clrsetbits_le32(&denali_phy[390], 0xffffff, reg_value); - - /* - * phy_dqs_tsel_select_X 24bits DENALI_PHY_7/135/263/391 offset_0 - * sets termination values for read/idle cycles and drive strength - * for write cycles for DQS - */ - clrsetbits_le32(&denali_phy[7], 0xffffff, reg_value); - clrsetbits_le32(&denali_phy[135], 0xffffff, reg_value); - clrsetbits_le32(&denali_phy[263], 0xffffff, reg_value); - clrsetbits_le32(&denali_phy[391], 0xffffff, reg_value); - - /* phy_adr_tsel_select_ 8bits DENALI_PHY_544/672/800 offset_0 */ - reg_value = ca_tsel_wr_select_n | (ca_tsel_wr_select_p << 0x4); - clrsetbits_le32(&denali_phy[544], 0xff, reg_value); - clrsetbits_le32(&denali_phy[672], 0xff, reg_value); - clrsetbits_le32(&denali_phy[800], 0xff, reg_value); - - /* phy_pad_addr_drive 8bits DENALI_PHY_928 offset_0 */ - clrsetbits_le32(&denali_phy[928], 0xff, reg_value); - - /* phy_pad_rst_drive 8bits DENALI_PHY_937 offset_0 */ - clrsetbits_le32(&denali_phy[937], 0xff, reg_value); - - /* phy_pad_cke_drive 8bits DENALI_PHY_935 offset_0 */ - clrsetbits_le32(&denali_phy[935], 0xff, reg_value); - - /* phy_pad_cs_drive 8bits DENALI_PHY_939 offset_0 */ - clrsetbits_le32(&denali_phy[939], 0xff, reg_value); - - /* phy_pad_clk_drive 8bits DENALI_PHY_929 offset_0 */ - clrsetbits_le32(&denali_phy[929], 0xff, reg_value); - - /* phy_pad_fdbk_drive 23bit DENALI_PHY_924/925 */ - clrsetbits_le32(&denali_phy[924], 0xff, - tsel_wr_select_n | (tsel_wr_select_p << 4)); - clrsetbits_le32(&denali_phy[925], 0xff, - tsel_rd_select_n | (tsel_rd_select_p << 4)); - - /* phy_dq_tsel_enable_X 3bits DENALI_PHY_5/133/261/389 offset_16 */ - reg_value = (tsel_rd_en | (tsel_wr_en << 1) | (tsel_idle_en << 2)) - << 16; - clrsetbits_le32(&denali_phy[5], 0x7 << 16, reg_value); - clrsetbits_le32(&denali_phy[133], 0x7 << 16, reg_value); - clrsetbits_le32(&denali_phy[261], 0x7 << 16, reg_value); - clrsetbits_le32(&denali_phy[389], 0x7 << 16, reg_value); - - /* phy_dqs_tsel_enable_X 3bits DENALI_PHY_6/134/262/390 offset_24 */ - reg_value = (tsel_rd_en | (tsel_wr_en << 1) | (tsel_idle_en << 2)) - << 24; - clrsetbits_le32(&denali_phy[6], 0x7 << 24, reg_value); - clrsetbits_le32(&denali_phy[134], 0x7 << 24, reg_value); - clrsetbits_le32(&denali_phy[262], 0x7 << 24, reg_value); - clrsetbits_le32(&denali_phy[390], 0x7 << 24, reg_value); - - /* phy_adr_tsel_enable_ 1bit DENALI_PHY_518/646/774 offset_8 */ - reg_value = tsel_wr_en << 8; - clrsetbits_le32(&denali_phy[518], 0x1 << 8, reg_value); - clrsetbits_le32(&denali_phy[646], 0x1 << 8, reg_value); - clrsetbits_le32(&denali_phy[774], 0x1 << 8, reg_value); - - /* phy_pad_addr_term tsel 1bit DENALI_PHY_933 offset_17 */ - reg_value = tsel_wr_en << 17; - clrsetbits_le32(&denali_phy[933], 0x1 << 17, reg_value); - /* - * pad_rst/cke/cs/clk_term tsel 1bits - * DENALI_PHY_938/936/940/934 offset_17 - */ - clrsetbits_le32(&denali_phy[938], 0x1 << 17, reg_value); - clrsetbits_le32(&denali_phy[936], 0x1 << 17, reg_value); - clrsetbits_le32(&denali_phy[940], 0x1 << 17, reg_value); - clrsetbits_le32(&denali_phy[934], 0x1 << 17, reg_value); - - /* phy_pad_fdbk_term 1bit DENALI_PHY_930 offset_17 */ - clrsetbits_le32(&denali_phy[930], 0x1 << 17, reg_value); -} - -static int phy_io_config(const struct chan_info *chan, - const struct rk3399_sdram_params *sdram_params) -{ - u32 *denali_phy = chan->publ->denali_phy; - u32 vref_mode_dq, vref_value_dq, vref_mode_ac, vref_value_ac; - u32 mode_sel; - u32 reg_value; - u32 drv_value, odt_value; - u32 speed; - - /* vref setting */ - if (sdram_params->base.dramtype == LPDDR4) { - /* LPDDR4 */ - vref_mode_dq = 0x6; - vref_value_dq = 0x1f; - vref_mode_ac = 0x6; - vref_value_ac = 0x1f; - } else if (sdram_params->base.dramtype == LPDDR3) { - if (sdram_params->base.odt == 1) { - vref_mode_dq = 0x5; /* LPDDR3 ODT */ - drv_value = (readl(&denali_phy[6]) >> 12) & 0xf; - odt_value = (readl(&denali_phy[6]) >> 4) & 0xf; - if (drv_value == PHY_DRV_ODT_48) { - switch (odt_value) { - case PHY_DRV_ODT_240: - vref_value_dq = 0x16; - break; - case PHY_DRV_ODT_120: - vref_value_dq = 0x26; - break; - case PHY_DRV_ODT_60: - vref_value_dq = 0x36; - break; - default: - debug("Invalid ODT value.\n"); - return -EINVAL; - } - } else if (drv_value == PHY_DRV_ODT_40) { - switch (odt_value) { - case PHY_DRV_ODT_240: - vref_value_dq = 0x19; - break; - case PHY_DRV_ODT_120: - vref_value_dq = 0x23; - break; - case PHY_DRV_ODT_60: - vref_value_dq = 0x31; - break; - default: - debug("Invalid ODT value.\n"); - return -EINVAL; - } - } else if (drv_value == PHY_DRV_ODT_34_3) { - switch (odt_value) { - case PHY_DRV_ODT_240: - vref_value_dq = 0x17; - break; - case PHY_DRV_ODT_120: - vref_value_dq = 0x20; - break; - case PHY_DRV_ODT_60: - vref_value_dq = 0x2e; - break; - default: - debug("Invalid ODT value.\n"); - return -EINVAL; - } - } else { - debug("Invalid DRV value.\n"); - return -EINVAL; - } - } else { - vref_mode_dq = 0x2; /* LPDDR3 */ - vref_value_dq = 0x1f; - } - vref_mode_ac = 0x2; - vref_value_ac = 0x1f; - } else if (sdram_params->base.dramtype == DDR3) { - /* DDR3L */ - vref_mode_dq = 0x1; - vref_value_dq = 0x1f; - vref_mode_ac = 0x1; - vref_value_ac = 0x1f; - } else { - debug("Unknown DRAM type.\n"); - return -EINVAL; - } - - reg_value = (vref_mode_dq << 9) | (0x1 << 8) | vref_value_dq; - - /* PHY_913 PHY_PAD_VREF_CTRL_DQ_0 12bits offset_8 */ - clrsetbits_le32(&denali_phy[913], 0xfff << 8, reg_value << 8); - /* PHY_914 PHY_PAD_VREF_CTRL_DQ_1 12bits offset_0 */ - clrsetbits_le32(&denali_phy[914], 0xfff, reg_value); - /* PHY_914 PHY_PAD_VREF_CTRL_DQ_2 12bits offset_16 */ - clrsetbits_le32(&denali_phy[914], 0xfff << 16, reg_value << 16); - /* PHY_915 PHY_PAD_VREF_CTRL_DQ_3 12bits offset_0 */ - clrsetbits_le32(&denali_phy[915], 0xfff, reg_value); - - reg_value = (vref_mode_ac << 9) | (0x1 << 8) | vref_value_ac; - - /* PHY_915 PHY_PAD_VREF_CTRL_AC 12bits offset_16 */ - clrsetbits_le32(&denali_phy[915], 0xfff << 16, reg_value << 16); - - if (sdram_params->base.dramtype == LPDDR4) - mode_sel = 0x6; - else if (sdram_params->base.dramtype == LPDDR3) - mode_sel = 0x0; - else if (sdram_params->base.dramtype == DDR3) - mode_sel = 0x1; - else - return -EINVAL; - - /* PHY_924 PHY_PAD_FDBK_DRIVE */ - clrsetbits_le32(&denali_phy[924], 0x7 << 15, mode_sel << 15); - /* PHY_926 PHY_PAD_DATA_DRIVE */ - clrsetbits_le32(&denali_phy[926], 0x7 << 6, mode_sel << 6); - /* PHY_927 PHY_PAD_DQS_DRIVE */ - clrsetbits_le32(&denali_phy[927], 0x7 << 6, mode_sel << 6); - /* PHY_928 PHY_PAD_ADDR_DRIVE */ - clrsetbits_le32(&denali_phy[928], 0x7 << 14, mode_sel << 14); - /* PHY_929 PHY_PAD_CLK_DRIVE */ - clrsetbits_le32(&denali_phy[929], 0x7 << 14, mode_sel << 14); - /* PHY_935 PHY_PAD_CKE_DRIVE */ - clrsetbits_le32(&denali_phy[935], 0x7 << 14, mode_sel << 14); - /* PHY_937 PHY_PAD_RST_DRIVE */ - clrsetbits_le32(&denali_phy[937], 0x7 << 14, mode_sel << 14); - /* PHY_939 PHY_PAD_CS_DRIVE */ - clrsetbits_le32(&denali_phy[939], 0x7 << 14, mode_sel << 14); - - - /* speed setting */ - if (sdram_params->base.ddr_freq < 400) - speed = 0x0; - else if (sdram_params->base.ddr_freq < 800) - speed = 0x1; - else if (sdram_params->base.ddr_freq < 1200) - speed = 0x2; - else - speed = 0x3; - - /* PHY_924 PHY_PAD_FDBK_DRIVE */ - clrsetbits_le32(&denali_phy[924], 0x3 << 21, speed << 21); - /* PHY_926 PHY_PAD_DATA_DRIVE */ - clrsetbits_le32(&denali_phy[926], 0x3 << 9, speed << 9); - /* PHY_927 PHY_PAD_DQS_DRIVE */ - clrsetbits_le32(&denali_phy[927], 0x3 << 9, speed << 9); - /* PHY_928 PHY_PAD_ADDR_DRIVE */ - clrsetbits_le32(&denali_phy[928], 0x3 << 17, speed << 17); - /* PHY_929 PHY_PAD_CLK_DRIVE */ - clrsetbits_le32(&denali_phy[929], 0x3 << 17, speed << 17); - /* PHY_935 PHY_PAD_CKE_DRIVE */ - clrsetbits_le32(&denali_phy[935], 0x3 << 17, speed << 17); - /* PHY_937 PHY_PAD_RST_DRIVE */ - clrsetbits_le32(&denali_phy[937], 0x3 << 17, speed << 17); - /* PHY_939 PHY_PAD_CS_DRIVE */ - clrsetbits_le32(&denali_phy[939], 0x3 << 17, speed << 17); - - return 0; -} - -static int pctl_cfg(const struct chan_info *chan, u32 channel, - const struct rk3399_sdram_params *sdram_params) -{ - u32 *denali_ctl = chan->pctl->denali_ctl; - u32 *denali_pi = chan->pi->denali_pi; - u32 *denali_phy = chan->publ->denali_phy; - const u32 *params_ctl = sdram_params->pctl_regs.denali_ctl; - const u32 *params_phy = sdram_params->phy_regs.denali_phy; - u32 tmp, tmp1, tmp2; - u32 pwrup_srefresh_exit; - int ret; - const ulong timeout_ms = 200; - - /* - * work around controller bug: - * Do not program DRAM_CLASS until NO_PHY_IND_TRAIN_INT is programmed - */ - copy_to_reg(&denali_ctl[1], ¶ms_ctl[1], - sizeof(struct rk3399_ddr_pctl_regs) - 4); - writel(params_ctl[0], &denali_ctl[0]); - copy_to_reg(denali_pi, &sdram_params->pi_regs.denali_pi[0], - sizeof(struct rk3399_ddr_pi_regs)); - /* rank count need to set for init */ - set_memory_map(chan, channel, sdram_params); - - writel(sdram_params->phy_regs.denali_phy[910], &denali_phy[910]); - writel(sdram_params->phy_regs.denali_phy[911], &denali_phy[911]); - writel(sdram_params->phy_regs.denali_phy[912], &denali_phy[912]); - - pwrup_srefresh_exit = readl(&denali_ctl[68]) & PWRUP_SREFRESH_EXIT; - clrbits_le32(&denali_ctl[68], PWRUP_SREFRESH_EXIT); - - /* PHY_DLL_RST_EN */ - clrsetbits_le32(&denali_phy[957], 0x3 << 24, 1 << 24); - - setbits_le32(&denali_pi[0], START); - setbits_le32(&denali_ctl[0], START); - - /* Wating for phy DLL lock */ - while (1) { - tmp = readl(&denali_phy[920]); - tmp1 = readl(&denali_phy[921]); - tmp2 = readl(&denali_phy[922]); - if ((((tmp >> 16) & 0x1) == 0x1) && - (((tmp1 >> 16) & 0x1) == 0x1) && - (((tmp1 >> 0) & 0x1) == 0x1) && - (((tmp2 >> 0) & 0x1) == 0x1)) - break; - } - - copy_to_reg(&denali_phy[896], ¶ms_phy[896], (958 - 895) * 4); - copy_to_reg(&denali_phy[0], ¶ms_phy[0], (90 - 0 + 1) * 4); - copy_to_reg(&denali_phy[128], ¶ms_phy[128], (218 - 128 + 1) * 4); - copy_to_reg(&denali_phy[256], ¶ms_phy[256], (346 - 256 + 1) * 4); - copy_to_reg(&denali_phy[384], ¶ms_phy[384], (474 - 384 + 1) * 4); - copy_to_reg(&denali_phy[512], ¶ms_phy[512], (549 - 512 + 1) * 4); - copy_to_reg(&denali_phy[640], ¶ms_phy[640], (677 - 640 + 1) * 4); - copy_to_reg(&denali_phy[768], ¶ms_phy[768], (805 - 768 + 1) * 4); - set_ds_odt(chan, sdram_params); - - /* - * phy_dqs_tsel_wr_timing_X 8bits DENALI_PHY_84/212/340/468 offset_8 - * dqs_tsel_wr_end[7:4] add Half cycle - */ - tmp = (readl(&denali_phy[84]) >> 8) & 0xff; - clrsetbits_le32(&denali_phy[84], 0xff << 8, (tmp + 0x10) << 8); - tmp = (readl(&denali_phy[212]) >> 8) & 0xff; - clrsetbits_le32(&denali_phy[212], 0xff << 8, (tmp + 0x10) << 8); - tmp = (readl(&denali_phy[340]) >> 8) & 0xff; - clrsetbits_le32(&denali_phy[340], 0xff << 8, (tmp + 0x10) << 8); - tmp = (readl(&denali_phy[468]) >> 8) & 0xff; - clrsetbits_le32(&denali_phy[468], 0xff << 8, (tmp + 0x10) << 8); - - /* - * phy_dqs_tsel_wr_timing_X 8bits DENALI_PHY_83/211/339/467 offset_8 - * dq_tsel_wr_end[7:4] add Half cycle - */ - tmp = (readl(&denali_phy[83]) >> 16) & 0xff; - clrsetbits_le32(&denali_phy[83], 0xff << 16, (tmp + 0x10) << 16); - tmp = (readl(&denali_phy[211]) >> 16) & 0xff; - clrsetbits_le32(&denali_phy[211], 0xff << 16, (tmp + 0x10) << 16); - tmp = (readl(&denali_phy[339]) >> 16) & 0xff; - clrsetbits_le32(&denali_phy[339], 0xff << 16, (tmp + 0x10) << 16); - tmp = (readl(&denali_phy[467]) >> 16) & 0xff; - clrsetbits_le32(&denali_phy[467], 0xff << 16, (tmp + 0x10) << 16); - - ret = phy_io_config(chan, sdram_params); - if (ret) - return ret; - - /* PHY_DLL_RST_EN */ - clrsetbits_le32(&denali_phy[957], 0x3 << 24, 0x2 << 24); - - /* Wating for PHY and DRAM init complete */ - tmp = get_timer(0); - do { - if (get_timer(tmp) > timeout_ms) { - error("DRAM (%s): phy failed to lock within %ld ms\n", - __func__, timeout_ms); - return -ETIME; - } - } while (!(readl(&denali_ctl[203]) & (1 << 3))); - debug("DRAM (%s): phy locked after %ld ms\n", __func__, get_timer(tmp)); - - clrsetbits_le32(&denali_ctl[68], PWRUP_SREFRESH_EXIT, - pwrup_srefresh_exit); - return 0; -} - -static void select_per_cs_training_index(const struct chan_info *chan, - u32 rank) -{ - u32 *denali_phy = chan->publ->denali_phy; - - /* PHY_84 PHY_PER_CS_TRAINING_EN_0 1bit offset_16 */ - if ((readl(&denali_phy[84])>>16) & 1) { - /* - * PHY_8/136/264/392 - * phy_per_cs_training_index_X 1bit offset_24 - */ - clrsetbits_le32(&denali_phy[8], 0x1 << 24, rank << 24); - clrsetbits_le32(&denali_phy[136], 0x1 << 24, rank << 24); - clrsetbits_le32(&denali_phy[264], 0x1 << 24, rank << 24); - clrsetbits_le32(&denali_phy[392], 0x1 << 24, rank << 24); - } -} - -static void override_write_leveling_value(const struct chan_info *chan) -{ - u32 *denali_ctl = chan->pctl->denali_ctl; - u32 *denali_phy = chan->publ->denali_phy; - u32 byte; - - /* PHY_896 PHY_FREQ_SEL_MULTICAST_EN 1bit offset_0 */ - setbits_le32(&denali_phy[896], 1); - - /* - * PHY_8/136/264/392 - * phy_per_cs_training_multicast_en_X 1bit offset_16 - */ - clrsetbits_le32(&denali_phy[8], 0x1 << 16, 1 << 16); - clrsetbits_le32(&denali_phy[136], 0x1 << 16, 1 << 16); - clrsetbits_le32(&denali_phy[264], 0x1 << 16, 1 << 16); - clrsetbits_le32(&denali_phy[392], 0x1 << 16, 1 << 16); - - for (byte = 0; byte < 4; byte++) - clrsetbits_le32(&denali_phy[63 + (128 * byte)], 0xffff << 16, - 0x200 << 16); - - /* PHY_896 PHY_FREQ_SEL_MULTICAST_EN 1bit offset_0 */ - clrbits_le32(&denali_phy[896], 1); - - /* CTL_200 ctrlupd_req 1bit offset_8 */ - clrsetbits_le32(&denali_ctl[200], 0x1 << 8, 0x1 << 8); -} - -static int data_training_ca(const struct chan_info *chan, u32 channel, - const struct rk3399_sdram_params *sdram_params) -{ - u32 *denali_pi = chan->pi->denali_pi; - u32 *denali_phy = chan->publ->denali_phy; - u32 i, tmp; - u32 obs_0, obs_1, obs_2, obs_err = 0; - u32 rank = sdram_params->ch[channel].rank; - - for (i = 0; i < rank; i++) { - select_per_cs_training_index(chan, i); - /* PI_100 PI_CALVL_EN:RW:8:2 */ - clrsetbits_le32(&denali_pi[100], 0x3 << 8, 0x2 << 8); - /* PI_92 PI_CALVL_REQ:WR:16:1,PI_CALVL_CS:RW:24:2 */ - clrsetbits_le32(&denali_pi[92], - (0x1 << 16) | (0x3 << 24), - (0x1 << 16) | (i << 24)); - - /* Waiting for training complete */ - while (1) { - /* PI_174 PI_INT_STATUS:RD:8:18 */ - tmp = readl(&denali_pi[174]) >> 8; - /* - * check status obs - * PHY_532/660/789 phy_adr_calvl_obs1_:0:32 - */ - obs_0 = readl(&denali_phy[532]); - obs_1 = readl(&denali_phy[660]); - obs_2 = readl(&denali_phy[788]); - if (((obs_0 >> 30) & 0x3) || - ((obs_1 >> 30) & 0x3) || - ((obs_2 >> 30) & 0x3)) - obs_err = 1; - if ((((tmp >> 11) & 0x1) == 0x1) && - (((tmp >> 13) & 0x1) == 0x1) && - (((tmp >> 5) & 0x1) == 0x0) && - (obs_err == 0)) - break; - else if ((((tmp >> 5) & 0x1) == 0x1) || - (obs_err == 1)) - return -EIO; - } - /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */ - writel(0x00003f7c, (&denali_pi[175])); - } - clrbits_le32(&denali_pi[100], 0x3 << 8); - - return 0; -} - -static int data_training_wl(const struct chan_info *chan, u32 channel, - const struct rk3399_sdram_params *sdram_params) -{ - u32 *denali_pi = chan->pi->denali_pi; - u32 *denali_phy = chan->publ->denali_phy; - u32 i, tmp; - u32 obs_0, obs_1, obs_2, obs_3, obs_err = 0; - u32 rank = sdram_params->ch[channel].rank; - - for (i = 0; i < rank; i++) { - select_per_cs_training_index(chan, i); - /* PI_60 PI_WRLVL_EN:RW:8:2 */ - clrsetbits_le32(&denali_pi[60], 0x3 << 8, 0x2 << 8); - /* PI_59 PI_WRLVL_REQ:WR:8:1,PI_WRLVL_CS:RW:16:2 */ - clrsetbits_le32(&denali_pi[59], - (0x1 << 8) | (0x3 << 16), - (0x1 << 8) | (i << 16)); - - /* Waiting for training complete */ - while (1) { - /* PI_174 PI_INT_STATUS:RD:8:18 */ - tmp = readl(&denali_pi[174]) >> 8; - - /* - * check status obs, if error maybe can not - * get leveling done PHY_40/168/296/424 - * phy_wrlvl_status_obs_X:0:13 - */ - obs_0 = readl(&denali_phy[40]); - obs_1 = readl(&denali_phy[168]); - obs_2 = readl(&denali_phy[296]); - obs_3 = readl(&denali_phy[424]); - if (((obs_0 >> 12) & 0x1) || - ((obs_1 >> 12) & 0x1) || - ((obs_2 >> 12) & 0x1) || - ((obs_3 >> 12) & 0x1)) - obs_err = 1; - if ((((tmp >> 10) & 0x1) == 0x1) && - (((tmp >> 13) & 0x1) == 0x1) && - (((tmp >> 4) & 0x1) == 0x0) && - (obs_err == 0)) - break; - else if ((((tmp >> 4) & 0x1) == 0x1) || - (obs_err == 1)) - return -EIO; - } - /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */ - writel(0x00003f7c, (&denali_pi[175])); - } - - override_write_leveling_value(chan); - clrbits_le32(&denali_pi[60], 0x3 << 8); - - return 0; -} - -static int data_training_rg(const struct chan_info *chan, u32 channel, - const struct rk3399_sdram_params *sdram_params) -{ - u32 *denali_pi = chan->pi->denali_pi; - u32 *denali_phy = chan->publ->denali_phy; - u32 i, tmp; - u32 obs_0, obs_1, obs_2, obs_3, obs_err = 0; - u32 rank = sdram_params->ch[channel].rank; - - for (i = 0; i < rank; i++) { - select_per_cs_training_index(chan, i); - /* PI_80 PI_RDLVL_GATE_EN:RW:24:2 */ - clrsetbits_le32(&denali_pi[80], 0x3 << 24, 0x2 << 24); - /* - * PI_74 PI_RDLVL_GATE_REQ:WR:16:1 - * PI_RDLVL_CS:RW:24:2 - */ - clrsetbits_le32(&denali_pi[74], - (0x1 << 16) | (0x3 << 24), - (0x1 << 16) | (i << 24)); - - /* Waiting for training complete */ - while (1) { - /* PI_174 PI_INT_STATUS:RD:8:18 */ - tmp = readl(&denali_pi[174]) >> 8; - - /* - * check status obs - * PHY_43/171/299/427 - * PHY_GTLVL_STATUS_OBS_x:16:8 - */ - obs_0 = readl(&denali_phy[43]); - obs_1 = readl(&denali_phy[171]); - obs_2 = readl(&denali_phy[299]); - obs_3 = readl(&denali_phy[427]); - if (((obs_0 >> (16 + 6)) & 0x3) || - ((obs_1 >> (16 + 6)) & 0x3) || - ((obs_2 >> (16 + 6)) & 0x3) || - ((obs_3 >> (16 + 6)) & 0x3)) - obs_err = 1; - if ((((tmp >> 9) & 0x1) == 0x1) && - (((tmp >> 13) & 0x1) == 0x1) && - (((tmp >> 3) & 0x1) == 0x0) && - (obs_err == 0)) - break; - else if ((((tmp >> 3) & 0x1) == 0x1) || - (obs_err == 1)) - return -EIO; - } - /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */ - writel(0x00003f7c, (&denali_pi[175])); - } - clrbits_le32(&denali_pi[80], 0x3 << 24); - - return 0; -} - -static int data_training_rl(const struct chan_info *chan, u32 channel, - const struct rk3399_sdram_params *sdram_params) -{ - u32 *denali_pi = chan->pi->denali_pi; - u32 i, tmp; - u32 rank = sdram_params->ch[channel].rank; - - for (i = 0; i < rank; i++) { - select_per_cs_training_index(chan, i); - /* PI_80 PI_RDLVL_EN:RW:16:2 */ - clrsetbits_le32(&denali_pi[80], 0x3 << 16, 0x2 << 16); - /* PI_74 PI_RDLVL_REQ:WR:8:1,PI_RDLVL_CS:RW:24:2 */ - clrsetbits_le32(&denali_pi[74], - (0x1 << 8) | (0x3 << 24), - (0x1 << 8) | (i << 24)); - - /* Waiting for training complete */ - while (1) { - /* PI_174 PI_INT_STATUS:RD:8:18 */ - tmp = readl(&denali_pi[174]) >> 8; - - /* - * make sure status obs not report error bit - * PHY_46/174/302/430 - * phy_rdlvl_status_obs_X:16:8 - */ - if ((((tmp >> 8) & 0x1) == 0x1) && - (((tmp >> 13) & 0x1) == 0x1) && - (((tmp >> 2) & 0x1) == 0x0)) - break; - else if (((tmp >> 2) & 0x1) == 0x1) - return -EIO; - } - /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */ - writel(0x00003f7c, (&denali_pi[175])); - } - clrbits_le32(&denali_pi[80], 0x3 << 16); - - return 0; -} - -static int data_training_wdql(const struct chan_info *chan, u32 channel, - const struct rk3399_sdram_params *sdram_params) -{ - u32 *denali_pi = chan->pi->denali_pi; - u32 i, tmp; - u32 rank = sdram_params->ch[channel].rank; - - for (i = 0; i < rank; i++) { - select_per_cs_training_index(chan, i); - /* - * disable PI_WDQLVL_VREF_EN before wdq leveling? - * PI_181 PI_WDQLVL_VREF_EN:RW:8:1 - */ - clrbits_le32(&denali_pi[181], 0x1 << 8); - /* PI_124 PI_WDQLVL_EN:RW:16:2 */ - clrsetbits_le32(&denali_pi[124], 0x3 << 16, 0x2 << 16); - /* PI_121 PI_WDQLVL_REQ:WR:8:1,PI_WDQLVL_CS:RW:16:2 */ - clrsetbits_le32(&denali_pi[121], - (0x1 << 8) | (0x3 << 16), - (0x1 << 8) | (i << 16)); - - /* Waiting for training complete */ - while (1) { - /* PI_174 PI_INT_STATUS:RD:8:18 */ - tmp = readl(&denali_pi[174]) >> 8; - if ((((tmp >> 12) & 0x1) == 0x1) && - (((tmp >> 13) & 0x1) == 0x1) && - (((tmp >> 6) & 0x1) == 0x0)) - break; - else if (((tmp >> 6) & 0x1) == 0x1) - return -EIO; - } - /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */ - writel(0x00003f7c, (&denali_pi[175])); - } - clrbits_le32(&denali_pi[124], 0x3 << 16); - - return 0; -} - -static int data_training(const struct chan_info *chan, u32 channel, - const struct rk3399_sdram_params *sdram_params, - u32 training_flag) -{ - u32 *denali_phy = chan->publ->denali_phy; - - /* PHY_927 PHY_PAD_DQS_DRIVE RPULL offset_22 */ - setbits_le32(&denali_phy[927], (1 << 22)); - - if (training_flag == PI_FULL_TRAINING) { - if (sdram_params->base.dramtype == LPDDR4) { - training_flag = PI_CA_TRAINING | PI_WRITE_LEVELING | - PI_READ_GATE_TRAINING | - PI_READ_LEVELING | PI_WDQ_LEVELING; - } else if (sdram_params->base.dramtype == LPDDR3) { - training_flag = PI_CA_TRAINING | PI_WRITE_LEVELING | - PI_READ_GATE_TRAINING; - } else if (sdram_params->base.dramtype == DDR3) { - training_flag = PI_WRITE_LEVELING | - PI_READ_GATE_TRAINING | - PI_READ_LEVELING; - } - } - - /* ca training(LPDDR4,LPDDR3 support) */ - if ((training_flag & PI_CA_TRAINING) == PI_CA_TRAINING) - data_training_ca(chan, channel, sdram_params); - - /* write leveling(LPDDR4,LPDDR3,DDR3 support) */ - if ((training_flag & PI_WRITE_LEVELING) == PI_WRITE_LEVELING) - data_training_wl(chan, channel, sdram_params); - - /* read gate training(LPDDR4,LPDDR3,DDR3 support) */ - if ((training_flag & PI_READ_GATE_TRAINING) == PI_READ_GATE_TRAINING) - data_training_rg(chan, channel, sdram_params); - - /* read leveling(LPDDR4,LPDDR3,DDR3 support) */ - if ((training_flag & PI_READ_LEVELING) == PI_READ_LEVELING) - data_training_rl(chan, channel, sdram_params); - - /* wdq leveling(LPDDR4 support) */ - if ((training_flag & PI_WDQ_LEVELING) == PI_WDQ_LEVELING) - data_training_wdql(chan, channel, sdram_params); - - /* PHY_927 PHY_PAD_DQS_DRIVE RPULL offset_22 */ - clrbits_le32(&denali_phy[927], (1 << 22)); - - return 0; -} - -static void set_ddrconfig(const struct chan_info *chan, - const struct rk3399_sdram_params *sdram_params, - unsigned char channel, u32 ddrconfig) -{ - /* only need to set ddrconfig */ - struct rk3399_msch_regs *ddr_msch_regs = chan->msch; - unsigned int cs0_cap = 0; - unsigned int cs1_cap = 0; - - cs0_cap = (1 << (sdram_params->ch[channel].cs0_row - + sdram_params->ch[channel].col - + sdram_params->ch[channel].bk - + sdram_params->ch[channel].bw - 20)); - if (sdram_params->ch[channel].rank > 1) - cs1_cap = cs0_cap >> (sdram_params->ch[channel].cs0_row - - sdram_params->ch[channel].cs1_row); - if (sdram_params->ch[channel].row_3_4) { - cs0_cap = cs0_cap * 3 / 4; - cs1_cap = cs1_cap * 3 / 4; - } - - writel(ddrconfig | (ddrconfig << 8), &ddr_msch_regs->ddrconf); - writel(((cs0_cap / 32) & 0xff) | (((cs1_cap / 32) & 0xff) << 8), - &ddr_msch_regs->ddrsize); -} - -static void dram_all_config(struct dram_info *dram, - const struct rk3399_sdram_params *sdram_params) -{ - u32 sys_reg = 0; - unsigned int channel, idx; - - sys_reg |= sdram_params->base.dramtype << SYS_REG_DDRTYPE_SHIFT; - sys_reg |= (sdram_params->base.num_channels - 1) - << SYS_REG_NUM_CH_SHIFT; - for (channel = 0, idx = 0; - (idx < sdram_params->base.num_channels) && (channel < 2); - channel++) { - const struct rk3399_sdram_channel *info = - &sdram_params->ch[channel]; - struct rk3399_msch_regs *ddr_msch_regs; - const struct rk3399_msch_timings *noc_timing; - - if (sdram_params->ch[channel].col == 0) - continue; - idx++; - sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(channel); - sys_reg |= 1 << SYS_REG_CHINFO_SHIFT(channel); - sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(channel); - sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(channel); - sys_reg |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(channel); - sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(channel); - sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(channel); - sys_reg |= (2 >> info->bw) << SYS_REG_BW_SHIFT(channel); - sys_reg |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(channel); - - ddr_msch_regs = dram->chan[channel].msch; - noc_timing = &sdram_params->ch[channel].noc_timings; - writel(noc_timing->ddrtiminga0, - &ddr_msch_regs->ddrtiminga0); - writel(noc_timing->ddrtimingb0, - &ddr_msch_regs->ddrtimingb0); - writel(noc_timing->ddrtimingc0, - &ddr_msch_regs->ddrtimingc0); - writel(noc_timing->devtodev0, - &ddr_msch_regs->devtodev0); - writel(noc_timing->ddrmode, - &ddr_msch_regs->ddrmode); - - /* rank 1 memory clock disable (dfi_dram_clk_disable = 1) */ - if (sdram_params->ch[channel].rank == 1) - setbits_le32(&dram->chan[channel].pctl->denali_ctl[276], - 1 << 17); - } - - writel(sys_reg, &dram->pmugrf->os_reg2); - rk_clrsetreg(&dram->pmusgrf->soc_con4, 0x1f << 10, - sdram_params->base.stride << 10); - - /* reboot hold register set */ - writel(PRESET_SGRF_HOLD(0) | PRESET_GPIO0_HOLD(1) | - PRESET_GPIO1_HOLD(1), - &dram->pmucru->pmucru_rstnhold_con[1]); - clrsetbits_le32(&dram->cru->glb_rst_con, 0x3, 0x3); -} - -static int switch_to_phy_index1(struct dram_info *dram, - const struct rk3399_sdram_params *sdram_params) -{ - u32 channel; - u32 *denali_phy; - u32 ch_count = sdram_params->base.num_channels; - int ret; - int i = 0; - - writel(RK_CLRSETBITS(0x03 << 4 | 1 << 2 | 1, - 1 << 4 | 1 << 2 | 1), - &dram->cic->cic_ctrl0); - while (!(readl(&dram->cic->cic_status0) & (1 << 2))) { - mdelay(10); - i++; - if (i > 10) { - debug("index1 frequency change overtime\n"); - return -ETIME; - } - } - - i = 0; - writel(RK_CLRSETBITS(1 << 1, 1 << 1), &dram->cic->cic_ctrl0); - while (!(readl(&dram->cic->cic_status0) & (1 << 0))) { - mdelay(10); - if (i > 10) { - debug("index1 frequency done overtime\n"); - return -ETIME; - } - } - - for (channel = 0; channel < ch_count; channel++) { - denali_phy = dram->chan[channel].publ->denali_phy; - clrsetbits_le32(&denali_phy[896], (0x3 << 8) | 1, 1 << 8); - ret = data_training(&dram->chan[channel], channel, - sdram_params, PI_FULL_TRAINING); - if (ret) { - debug("index1 training failed\n"); - return ret; - } - } - - return 0; -} - -static int sdram_init(struct dram_info *dram, - const struct rk3399_sdram_params *sdram_params) -{ - unsigned char dramtype = sdram_params->base.dramtype; - unsigned int ddr_freq = sdram_params->base.ddr_freq; - int channel; - - debug("Starting SDRAM initialization...\n"); - - if ((dramtype == DDR3 && ddr_freq > 933) || - (dramtype == LPDDR3 && ddr_freq > 933) || - (dramtype == LPDDR4 && ddr_freq > 800)) { - debug("SDRAM frequency is to high!"); - return -E2BIG; - } - - for (channel = 0; channel < 2; channel++) { - const struct chan_info *chan = &dram->chan[channel]; - struct rk3399_ddr_publ_regs *publ = chan->publ; - - phy_dll_bypass_set(publ, ddr_freq); - - if (channel >= sdram_params->base.num_channels) - continue; - - if (pctl_cfg(chan, channel, sdram_params) != 0) { - printf("pctl_cfg fail, reset\n"); - return -EIO; - } - - /* LPDDR2/LPDDR3 need to wait DAI complete, max 10us */ - if (dramtype == LPDDR3) - udelay(10); - - if (data_training(chan, channel, - sdram_params, PI_FULL_TRAINING)) { - printf("SDRAM initialization failed, reset\n"); - return -EIO; - } - - set_ddrconfig(chan, sdram_params, channel, - sdram_params->ch[channel].ddrconfig); - } - dram_all_config(dram, sdram_params); - switch_to_phy_index1(dram, sdram_params); - - debug("Finish SDRAM initialization...\n"); - return 0; -} - -static int rk3399_dmc_ofdata_to_platdata(struct udevice *dev) -{ -#if !CONFIG_IS_ENABLED(OF_PLATDATA) - struct rockchip_dmc_plat *plat = dev_get_platdata(dev); - int ret; - - ret = dev_read_u32_array(dev, "rockchip,sdram-params", - (u32 *)&plat->sdram_params, - sizeof(plat->sdram_params) / sizeof(u32)); - if (ret) { - printf("%s: Cannot read rockchip,sdram-params %d\n", - __func__, ret); - return ret; - } - ret = regmap_init_mem(dev, &plat->map); - if (ret) - printf("%s: regmap failed %d\n", __func__, ret); - -#endif - return 0; -} - -#if CONFIG_IS_ENABLED(OF_PLATDATA) -static int conv_of_platdata(struct udevice *dev) -{ - struct rockchip_dmc_plat *plat = dev_get_platdata(dev); - struct dtd_rockchip_rk3399_dmc *dtplat = &plat->dtplat; - int ret; - - ret = regmap_init_mem_platdata(dev, dtplat->reg, - ARRAY_SIZE(dtplat->reg) / 2, - &plat->map); - if (ret) - return ret; - - return 0; -} -#endif - -static int rk3399_dmc_init(struct udevice *dev) -{ - struct dram_info *priv = dev_get_priv(dev); - struct rockchip_dmc_plat *plat = dev_get_platdata(dev); - int ret; -#if !CONFIG_IS_ENABLED(OF_PLATDATA) - struct rk3399_sdram_params *params = &plat->sdram_params; -#else - struct dtd_rockchip_rk3399_dmc *dtplat = &plat->dtplat; - struct rk3399_sdram_params *params = - (void *)dtplat->rockchip_sdram_params; - - ret = conv_of_platdata(dev); - if (ret) - return ret; -#endif - - priv->cic = syscon_get_first_range(ROCKCHIP_SYSCON_CIC); - priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF); - priv->pmusgrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUSGRF); - priv->pmucru = rockchip_get_pmucru(); - priv->cru = rockchip_get_cru(); - priv->chan[0].pctl = regmap_get_range(plat->map, 0); - priv->chan[0].pi = regmap_get_range(plat->map, 1); - priv->chan[0].publ = regmap_get_range(plat->map, 2); - priv->chan[0].msch = regmap_get_range(plat->map, 3); - priv->chan[1].pctl = regmap_get_range(plat->map, 4); - priv->chan[1].pi = regmap_get_range(plat->map, 5); - priv->chan[1].publ = regmap_get_range(plat->map, 6); - priv->chan[1].msch = regmap_get_range(plat->map, 7); - - debug("con reg %p %p %p %p %p %p %p %p\n", - priv->chan[0].pctl, priv->chan[0].pi, - priv->chan[0].publ, priv->chan[0].msch, - priv->chan[1].pctl, priv->chan[1].pi, - priv->chan[1].publ, priv->chan[1].msch); - debug("cru %p, cic %p, grf %p, sgrf %p, pmucru %p\n", priv->cru, - priv->cic, priv->pmugrf, priv->pmusgrf, priv->pmucru); -#if CONFIG_IS_ENABLED(OF_PLATDATA) - ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->ddr_clk); -#else - ret = clk_get_by_index(dev, 0, &priv->ddr_clk); -#endif - if (ret) { - printf("%s clk get failed %d\n", __func__, ret); - return ret; - } - ret = clk_set_rate(&priv->ddr_clk, params->base.ddr_freq * MHz); - if (ret < 0) { - printf("%s clk set failed %d\n", __func__, ret); - return ret; - } - ret = sdram_init(priv, params); - if (ret < 0) { - printf("%s DRAM init failed%d\n", __func__, ret); - return ret; - } - - return 0; -} -#endif - -static int rk3399_dmc_probe(struct udevice *dev) -{ -#ifdef CONFIG_SPL_BUILD - if (rk3399_dmc_init(dev)) - return 0; -#else - struct dram_info *priv = dev_get_priv(dev); - - priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF); - debug("%s: pmugrf=%p\n", __func__, priv->pmugrf); - priv->info.base = CONFIG_SYS_SDRAM_BASE; - priv->info.size = rockchip_sdram_size( - (phys_addr_t)&priv->pmugrf->os_reg2); -#endif - return 0; -} - -static int rk3399_dmc_get_info(struct udevice *dev, struct ram_info *info) -{ - struct dram_info *priv = dev_get_priv(dev); - - *info = priv->info; - - return 0; -} - -static struct ram_ops rk3399_dmc_ops = { - .get_info = rk3399_dmc_get_info, -}; - - -static const struct udevice_id rk3399_dmc_ids[] = { - { .compatible = "rockchip,rk3399-dmc" }, - { } -}; - -U_BOOT_DRIVER(dmc_rk3399) = { - .name = "rockchip_rk3399_dmc", - .id = UCLASS_RAM, - .of_match = rk3399_dmc_ids, - .ops = &rk3399_dmc_ops, -#ifdef CONFIG_SPL_BUILD - .ofdata_to_platdata = rk3399_dmc_ofdata_to_platdata, -#endif - .probe = rk3399_dmc_probe, - .priv_auto_alloc_size = sizeof(struct dram_info), -#ifdef CONFIG_SPL_BUILD - .platdata_auto_alloc_size = sizeof(struct rockchip_dmc_plat), -#endif -}; -- cgit v1.2.3 From 5b67d7010b73a6e17b593f1f3af25dd06996830a Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Wed, 27 Sep 2017 16:11:31 +0800 Subject: rockchip: rk3188: move sdram driver to driver/ram Since we have CONFIG_RAM framwork and its driver folder, move the driver into it. Signed-off-by: Kever Yang Acked-by: Philipp Tomsich Reviewed-by: Philipp Tomsich --- arch/arm/mach-rockchip/rk3188/Makefile | 1 - arch/arm/mach-rockchip/rk3188/sdram_rk3188.c | 953 --------------------------- 2 files changed, 954 deletions(-) delete mode 100644 arch/arm/mach-rockchip/rk3188/sdram_rk3188.c (limited to 'arch') diff --git a/arch/arm/mach-rockchip/rk3188/Makefile b/arch/arm/mach-rockchip/rk3188/Makefile index 2dc9511de7f..7fa010405b1 100644 --- a/arch/arm/mach-rockchip/rk3188/Makefile +++ b/arch/arm/mach-rockchip/rk3188/Makefile @@ -6,6 +6,5 @@ ifndef CONFIG_TPL_BUILD obj-y += clk_rk3188.o -obj-y += sdram_rk3188.o obj-y += syscon_rk3188.o endif diff --git a/arch/arm/mach-rockchip/rk3188/sdram_rk3188.c b/arch/arm/mach-rockchip/rk3188/sdram_rk3188.c deleted file mode 100644 index 9d8b225dfac..00000000000 --- a/arch/arm/mach-rockchip/rk3188/sdram_rk3188.c +++ /dev/null @@ -1,953 +0,0 @@ -/* - * (C) Copyright 2015 Google, Inc - * Copyright 2014 Rockchip Inc. - * - * SPDX-License-Identifier: GPL-2.0 - * - * Adapted from the very similar rk3288 ddr init. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -struct chan_info { - struct rk3288_ddr_pctl *pctl; - struct rk3288_ddr_publ *publ; - struct rk3188_msch *msch; -}; - -struct dram_info { - struct chan_info chan[1]; - struct ram_info info; - struct clk ddr_clk; - struct rk3188_cru *cru; - struct rk3188_grf *grf; - struct rk3188_sgrf *sgrf; - struct rk3188_pmu *pmu; -}; - -struct rk3188_sdram_params { -#if CONFIG_IS_ENABLED(OF_PLATDATA) - struct dtd_rockchip_rk3188_dmc of_plat; -#endif - struct rk3288_sdram_channel ch[2]; - struct rk3288_sdram_pctl_timing pctl_timing; - struct rk3288_sdram_phy_timing phy_timing; - struct rk3288_base_params base; - int num_channels; - struct regmap *map; -}; - -const int ddrconf_table[] = { - /* - * [5:4] row(13+n) - * [1:0] col(9+n), assume bw=2 - * row col,bw - */ - 0, - ((2 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT), - ((1 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT), - ((0 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT), - ((2 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT), - ((1 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT), - ((0 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT), - ((1 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT), - ((0 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT), - 0, - 0, - 0, - 0, - 0, - 0, - 0, -}; - -#define TEST_PATTEN 0x5aa5f00f -#define DQS_GATE_TRAINING_ERROR_RANK0 (1 << 4) -#define DQS_GATE_TRAINING_ERROR_RANK1 (2 << 4) - -#ifdef CONFIG_SPL_BUILD -static void copy_to_reg(u32 *dest, const u32 *src, u32 n) -{ - int i; - - for (i = 0; i < n / sizeof(u32); i++) { - writel(*src, dest); - src++; - dest++; - } -} - -static void ddr_reset(struct rk3188_cru *cru, u32 ch, u32 ctl, u32 phy) -{ - u32 phy_ctl_srstn_shift = 13; - u32 ctl_psrstn_shift = 11; - u32 ctl_srstn_shift = 10; - u32 phy_psrstn_shift = 9; - u32 phy_srstn_shift = 8; - - rk_clrsetreg(&cru->cru_softrst_con[5], - 1 << phy_ctl_srstn_shift | 1 << ctl_psrstn_shift | - 1 << ctl_srstn_shift | 1 << phy_psrstn_shift | - 1 << phy_srstn_shift, - phy << phy_ctl_srstn_shift | ctl << ctl_psrstn_shift | - ctl << ctl_srstn_shift | phy << phy_psrstn_shift | - phy << phy_srstn_shift); -} - -static void ddr_phy_ctl_reset(struct rk3188_cru *cru, u32 ch, u32 n) -{ - u32 phy_ctl_srstn_shift = 13; - - rk_clrsetreg(&cru->cru_softrst_con[5], - 1 << phy_ctl_srstn_shift, n << phy_ctl_srstn_shift); -} - -static void phy_pctrl_reset(struct rk3188_cru *cru, - struct rk3288_ddr_publ *publ, - int channel) -{ - int i; - - ddr_reset(cru, channel, 1, 1); - udelay(1); - clrbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST); - for (i = 0; i < 4; i++) - clrbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST); - - udelay(10); - setbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST); - for (i = 0; i < 4; i++) - setbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST); - - udelay(10); - ddr_reset(cru, channel, 1, 0); - udelay(10); - ddr_reset(cru, channel, 0, 0); - udelay(10); -} - -static void phy_dll_bypass_set(struct rk3288_ddr_publ *publ, - u32 freq) -{ - int i; - - if (freq <= 250000000) { - if (freq <= 150000000) - clrbits_le32(&publ->dllgcr, SBIAS_BYPASS); - else - setbits_le32(&publ->dllgcr, SBIAS_BYPASS); - setbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS); - for (i = 0; i < 4; i++) - setbits_le32(&publ->datx8[i].dxdllcr, - DXDLLCR_DLLDIS); - - setbits_le32(&publ->pir, PIR_DLLBYP); - } else { - clrbits_le32(&publ->dllgcr, SBIAS_BYPASS); - clrbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS); - for (i = 0; i < 4; i++) { - clrbits_le32(&publ->datx8[i].dxdllcr, - DXDLLCR_DLLDIS); - } - - clrbits_le32(&publ->pir, PIR_DLLBYP); - } -} - -static void dfi_cfg(struct rk3288_ddr_pctl *pctl, u32 dramtype) -{ - writel(DFI_INIT_START, &pctl->dfistcfg0); - writel(DFI_DRAM_CLK_SR_EN | DFI_DRAM_CLK_DPD_EN, - &pctl->dfistcfg1); - writel(DFI_PARITY_INTR_EN | DFI_PARITY_EN, &pctl->dfistcfg2); - writel(7 << TLP_RESP_TIME_SHIFT | LP_SR_EN | LP_PD_EN, - &pctl->dfilpcfg0); - - writel(2 << TCTRL_DELAY_TIME_SHIFT, &pctl->dfitctrldelay); - writel(1 << TPHY_WRDATA_TIME_SHIFT, &pctl->dfitphywrdata); - writel(0xf << TPHY_RDLAT_TIME_SHIFT, &pctl->dfitphyrdlat); - writel(2 << TDRAM_CLK_DIS_TIME_SHIFT, &pctl->dfitdramclkdis); - writel(2 << TDRAM_CLK_EN_TIME_SHIFT, &pctl->dfitdramclken); - writel(1, &pctl->dfitphyupdtype0); - - /* cs0 and cs1 write odt enable */ - writel((RANK0_ODT_WRITE_SEL | RANK1_ODT_WRITE_SEL), - &pctl->dfiodtcfg); - /* odt write length */ - writel(7 << ODT_LEN_BL8_W_SHIFT, &pctl->dfiodtcfg1); - /* phyupd and ctrlupd disabled */ - writel(0, &pctl->dfiupdcfg); -} - -static void ddr_set_enable(struct rk3188_grf *grf, uint channel, bool enable) -{ - uint val = 0; - - if (enable) - val = 1 << DDR_16BIT_EN_SHIFT; - - rk_clrsetreg(&grf->ddrc_con0, 1 << DDR_16BIT_EN_SHIFT, val); -} - -static void ddr_set_ddr3_mode(struct rk3188_grf *grf, uint channel, - bool ddr3_mode) -{ - uint mask, val; - - mask = MSCH4_MAINDDR3_MASK << MSCH4_MAINDDR3_SHIFT; - val = ddr3_mode << MSCH4_MAINDDR3_SHIFT; - rk_clrsetreg(&grf->soc_con2, mask, val); -} - -static void ddr_rank_2_row15en(struct rk3188_grf *grf, bool enable) -{ - uint mask, val; - - mask = RANK_TO_ROW15_EN_MASK << RANK_TO_ROW15_EN_SHIFT; - val = enable << RANK_TO_ROW15_EN_SHIFT; - rk_clrsetreg(&grf->soc_con2, mask, val); -} - -static void pctl_cfg(int channel, struct rk3288_ddr_pctl *pctl, - struct rk3188_sdram_params *sdram_params, - struct rk3188_grf *grf) -{ - copy_to_reg(&pctl->togcnt1u, &sdram_params->pctl_timing.togcnt1u, - sizeof(sdram_params->pctl_timing)); - switch (sdram_params->base.dramtype) { - case DDR3: - if (sdram_params->phy_timing.mr[1] & DDR3_DLL_DISABLE) { - writel(sdram_params->pctl_timing.tcl - 3, - &pctl->dfitrddataen); - } else { - writel(sdram_params->pctl_timing.tcl - 2, - &pctl->dfitrddataen); - } - writel(sdram_params->pctl_timing.tcwl - 1, - &pctl->dfitphywrlat); - writel(0 << MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT | DDR3_EN | - DDR2_DDR3_BL_8 | (6 - 4) << TFAW_SHIFT | PD_EXIT_SLOW | - 1 << PD_TYPE_SHIFT | 0 << PD_IDLE_SHIFT, - &pctl->mcfg); - ddr_set_ddr3_mode(grf, channel, true); - ddr_set_enable(grf, channel, true); - break; - } - - setbits_le32(&pctl->scfg, 1); -} - -static void phy_cfg(const struct chan_info *chan, int channel, - struct rk3188_sdram_params *sdram_params) -{ - struct rk3288_ddr_publ *publ = chan->publ; - struct rk3188_msch *msch = chan->msch; - uint ddr_freq_mhz = sdram_params->base.ddr_freq / 1000000; - u32 dinit2; - int i; - - dinit2 = DIV_ROUND_UP(ddr_freq_mhz * 200000, 1000); - /* DDR PHY Timing */ - copy_to_reg(&publ->dtpr[0], &sdram_params->phy_timing.dtpr0, - sizeof(sdram_params->phy_timing)); - writel(sdram_params->base.noc_timing, &msch->ddrtiming); - writel(0x3f, &msch->readlatency); - writel(DIV_ROUND_UP(ddr_freq_mhz * 5120, 1000) << PRT_DLLLOCK_SHIFT | - DIV_ROUND_UP(ddr_freq_mhz * 50, 1000) << PRT_DLLSRST_SHIFT | - 8 << PRT_ITMSRST_SHIFT, &publ->ptr[0]); - writel(DIV_ROUND_UP(ddr_freq_mhz * 500000, 1000) << PRT_DINIT0_SHIFT | - DIV_ROUND_UP(ddr_freq_mhz * 400, 1000) << PRT_DINIT1_SHIFT, - &publ->ptr[1]); - writel(min(dinit2, 0x1ffffU) << PRT_DINIT2_SHIFT | - DIV_ROUND_UP(ddr_freq_mhz * 1000, 1000) << PRT_DINIT3_SHIFT, - &publ->ptr[2]); - - switch (sdram_params->base.dramtype) { - case DDR3: - clrbits_le32(&publ->pgcr, 0x1f); - clrsetbits_le32(&publ->dcr, DDRMD_MASK << DDRMD_SHIFT, - DDRMD_DDR3 << DDRMD_SHIFT); - break; - } - if (sdram_params->base.odt) { - /*dynamic RTT enable */ - for (i = 0; i < 4; i++) - setbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT); - } else { - /*dynamic RTT disable */ - for (i = 0; i < 4; i++) - clrbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT); - } -} - -static void phy_init(struct rk3288_ddr_publ *publ) -{ - setbits_le32(&publ->pir, PIR_INIT | PIR_DLLSRST - | PIR_DLLLOCK | PIR_ZCAL | PIR_ITMSRST | PIR_CLRSR); - udelay(1); - while ((readl(&publ->pgsr) & - (PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE)) != - (PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE)) - ; -} - -static void send_command(struct rk3288_ddr_pctl *pctl, u32 rank, - u32 cmd, u32 arg) -{ - writel((START_CMD | (rank << 20) | arg | cmd), &pctl->mcmd); - udelay(1); - while (readl(&pctl->mcmd) & START_CMD) - ; -} - -static inline void send_command_op(struct rk3288_ddr_pctl *pctl, - u32 rank, u32 cmd, u32 ma, u32 op) -{ - send_command(pctl, rank, cmd, (ma & LPDDR2_MA_MASK) << LPDDR2_MA_SHIFT | - (op & LPDDR2_OP_MASK) << LPDDR2_OP_SHIFT); -} - -static void memory_init(struct rk3288_ddr_publ *publ, - u32 dramtype) -{ - setbits_le32(&publ->pir, - (PIR_INIT | PIR_DRAMINIT | PIR_LOCKBYP - | PIR_ZCALBYP | PIR_CLRSR | PIR_ICPC - | (dramtype == DDR3 ? PIR_DRAMRST : 0))); - udelay(1); - while ((readl(&publ->pgsr) & (PGSR_IDONE | PGSR_DLDONE)) - != (PGSR_IDONE | PGSR_DLDONE)) - ; -} - -static void move_to_config_state(struct rk3288_ddr_publ *publ, - struct rk3288_ddr_pctl *pctl) -{ - unsigned int state; - - while (1) { - state = readl(&pctl->stat) & PCTL_STAT_MSK; - - switch (state) { - case LOW_POWER: - writel(WAKEUP_STATE, &pctl->sctl); - while ((readl(&pctl->stat) & PCTL_STAT_MSK) - != ACCESS) - ; - /* wait DLL lock */ - while ((readl(&publ->pgsr) & PGSR_DLDONE) - != PGSR_DLDONE) - ; - /* - * if at low power state,need wakeup first, - * and then enter the config, so - * fallthrough - */ - case ACCESS: - /* fallthrough */ - case INIT_MEM: - writel(CFG_STATE, &pctl->sctl); - while ((readl(&pctl->stat) & PCTL_STAT_MSK) != CONFIG) - ; - break; - case CONFIG: - return; - default: - break; - } - } -} - -static void set_bandwidth_ratio(const struct chan_info *chan, int channel, - u32 n, struct rk3188_grf *grf) -{ - struct rk3288_ddr_pctl *pctl = chan->pctl; - struct rk3288_ddr_publ *publ = chan->publ; - struct rk3188_msch *msch = chan->msch; - - if (n == 1) { - setbits_le32(&pctl->ppcfg, 1); - ddr_set_enable(grf, channel, 1); - setbits_le32(&msch->ddrtiming, 1 << 31); - /* Data Byte disable*/ - clrbits_le32(&publ->datx8[2].dxgcr, 1); - clrbits_le32(&publ->datx8[3].dxgcr, 1); - /* disable DLL */ - setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS); - setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS); - } else { - clrbits_le32(&pctl->ppcfg, 1); - ddr_set_enable(grf, channel, 0); - clrbits_le32(&msch->ddrtiming, 1 << 31); - /* Data Byte enable*/ - setbits_le32(&publ->datx8[2].dxgcr, 1); - setbits_le32(&publ->datx8[3].dxgcr, 1); - - /* enable DLL */ - clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS); - clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS); - /* reset DLL */ - clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST); - clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST); - udelay(10); - setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST); - setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST); - } - setbits_le32(&pctl->dfistcfg0, 1 << 2); -} - -static int data_training(const struct chan_info *chan, int channel, - struct rk3188_sdram_params *sdram_params) -{ - unsigned int j; - int ret = 0; - u32 rank; - int i; - u32 step[2] = { PIR_QSTRN, PIR_RVTRN }; - struct rk3288_ddr_publ *publ = chan->publ; - struct rk3288_ddr_pctl *pctl = chan->pctl; - - /* disable auto refresh */ - writel(0, &pctl->trefi); - - if (sdram_params->base.dramtype != LPDDR3) - setbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT); - rank = sdram_params->ch[channel].rank | 1; - for (j = 0; j < ARRAY_SIZE(step); j++) { - /* - * trigger QSTRN and RVTRN - * clear DTDONE status - */ - setbits_le32(&publ->pir, PIR_CLRSR); - - /* trigger DTT */ - setbits_le32(&publ->pir, - PIR_INIT | step[j] | PIR_LOCKBYP | PIR_ZCALBYP | - PIR_CLRSR); - udelay(1); - /* wait echo byte DTDONE */ - while ((readl(&publ->datx8[0].dxgsr[0]) & rank) - != rank) - ; - while ((readl(&publ->datx8[1].dxgsr[0]) & rank) - != rank) - ; - if (!(readl(&pctl->ppcfg) & 1)) { - while ((readl(&publ->datx8[2].dxgsr[0]) - & rank) != rank) - ; - while ((readl(&publ->datx8[3].dxgsr[0]) - & rank) != rank) - ; - } - if (readl(&publ->pgsr) & - (PGSR_DTERR | PGSR_RVERR | PGSR_RVEIRR)) { - ret = -1; - break; - } - } - /* send some auto refresh to complement the lost while DTT */ - for (i = 0; i < (rank > 1 ? 8 : 4); i++) - send_command(pctl, rank, REF_CMD, 0); - - if (sdram_params->base.dramtype != LPDDR3) - clrbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT); - - /* resume auto refresh */ - writel(sdram_params->pctl_timing.trefi, &pctl->trefi); - - return ret; -} - -static void move_to_access_state(const struct chan_info *chan) -{ - struct rk3288_ddr_publ *publ = chan->publ; - struct rk3288_ddr_pctl *pctl = chan->pctl; - unsigned int state; - - while (1) { - state = readl(&pctl->stat) & PCTL_STAT_MSK; - - switch (state) { - case LOW_POWER: - if (((readl(&pctl->stat) >> LP_TRIG_SHIFT) & - LP_TRIG_MASK) == 1) - return; - - writel(WAKEUP_STATE, &pctl->sctl); - while ((readl(&pctl->stat) & PCTL_STAT_MSK) != ACCESS) - ; - /* wait DLL lock */ - while ((readl(&publ->pgsr) & PGSR_DLDONE) - != PGSR_DLDONE) - ; - break; - case INIT_MEM: - writel(CFG_STATE, &pctl->sctl); - while ((readl(&pctl->stat) & PCTL_STAT_MSK) != CONFIG) - ; - /* fallthrough */ - case CONFIG: - writel(GO_STATE, &pctl->sctl); - while ((readl(&pctl->stat) & PCTL_STAT_MSK) == CONFIG) - ; - break; - case ACCESS: - return; - default: - break; - } - } -} - -static void dram_cfg_rbc(const struct chan_info *chan, u32 chnum, - struct rk3188_sdram_params *sdram_params) -{ - struct rk3288_ddr_publ *publ = chan->publ; - - if (sdram_params->ch[chnum].bk == 3) - clrsetbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT, - 1 << PDQ_SHIFT); - else - clrbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT); - - writel(sdram_params->base.ddrconfig, &chan->msch->ddrconf); -} - -static void dram_all_config(const struct dram_info *dram, - struct rk3188_sdram_params *sdram_params) -{ - unsigned int chan; - u32 sys_reg = 0; - - sys_reg |= sdram_params->base.dramtype << SYS_REG_DDRTYPE_SHIFT; - sys_reg |= (sdram_params->num_channels - 1) << SYS_REG_NUM_CH_SHIFT; - for (chan = 0; chan < sdram_params->num_channels; chan++) { - const struct rk3288_sdram_channel *info = - &sdram_params->ch[chan]; - - sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(chan); - sys_reg |= 1 << SYS_REG_CHINFO_SHIFT(chan); - sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(chan); - sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(chan); - sys_reg |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(chan); - sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(chan); - sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(chan); - sys_reg |= (2 >> info->bw) << SYS_REG_BW_SHIFT(chan); - sys_reg |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(chan); - - dram_cfg_rbc(&dram->chan[chan], chan, sdram_params); - } - if (sdram_params->ch[0].rank == 2) - ddr_rank_2_row15en(dram->grf, 0); - else - ddr_rank_2_row15en(dram->grf, 1); - - writel(sys_reg, &dram->pmu->sys_reg[2]); -} - -static int sdram_rank_bw_detect(struct dram_info *dram, int channel, - struct rk3188_sdram_params *sdram_params) -{ - int reg; - int need_trainig = 0; - const struct chan_info *chan = &dram->chan[channel]; - struct rk3288_ddr_publ *publ = chan->publ; - - ddr_rank_2_row15en(dram->grf, 0); - - if (data_training(chan, channel, sdram_params) < 0) { - printf("first data training fail!\n"); - reg = readl(&publ->datx8[0].dxgsr[0]); - /* Check the result for rank 0 */ - if ((channel == 0) && (reg & DQS_GATE_TRAINING_ERROR_RANK0)) { - printf("data training fail!\n"); - return -EIO; - } - - /* Check the result for rank 1 */ - if (reg & DQS_GATE_TRAINING_ERROR_RANK1) { - sdram_params->ch[channel].rank = 1; - clrsetbits_le32(&publ->pgcr, 0xF << 18, - sdram_params->ch[channel].rank << 18); - need_trainig = 1; - } - reg = readl(&publ->datx8[2].dxgsr[0]); - if (reg & (1 << 4)) { - sdram_params->ch[channel].bw = 1; - set_bandwidth_ratio(chan, channel, - sdram_params->ch[channel].bw, - dram->grf); - need_trainig = 1; - } - } - /* Assume the Die bit width are the same with the chip bit width */ - sdram_params->ch[channel].dbw = sdram_params->ch[channel].bw; - - if (need_trainig && - (data_training(chan, channel, sdram_params) < 0)) { - if (sdram_params->base.dramtype == LPDDR3) { - ddr_phy_ctl_reset(dram->cru, channel, 1); - udelay(10); - ddr_phy_ctl_reset(dram->cru, channel, 0); - udelay(10); - } - printf("2nd data training failed!"); - return -EIO; - } - - return 0; -} - -/* - * Detect ram columns and rows. - * @dram: dram info struct - * @channel: channel number to handle - * @sdram_params: sdram parameters, function will fill in col and row values - * - * Returns 0 or negative on error. - */ -static int sdram_col_row_detect(struct dram_info *dram, int channel, - struct rk3188_sdram_params *sdram_params) -{ - int row, col; - unsigned int addr; - const struct chan_info *chan = &dram->chan[channel]; - struct rk3288_ddr_pctl *pctl = chan->pctl; - struct rk3288_ddr_publ *publ = chan->publ; - int ret = 0; - - /* Detect col */ - for (col = 11; col >= 9; col--) { - writel(0, CONFIG_SYS_SDRAM_BASE); - addr = CONFIG_SYS_SDRAM_BASE + - (1 << (col + sdram_params->ch[channel].bw - 1)); - writel(TEST_PATTEN, addr); - if ((readl(addr) == TEST_PATTEN) && - (readl(CONFIG_SYS_SDRAM_BASE) == 0)) - break; - } - if (col == 8) { - printf("Col detect error\n"); - ret = -EINVAL; - goto out; - } else { - sdram_params->ch[channel].col = col; - } - - ddr_rank_2_row15en(dram->grf, 1); - move_to_config_state(publ, pctl); - writel(1, &chan->msch->ddrconf); - move_to_access_state(chan); - /* Detect row, max 15,min13 in rk3188*/ - for (row = 16; row >= 13; row--) { - writel(0, CONFIG_SYS_SDRAM_BASE); - addr = CONFIG_SYS_SDRAM_BASE + (1 << (row + 15 - 1)); - writel(TEST_PATTEN, addr); - if ((readl(addr) == TEST_PATTEN) && - (readl(CONFIG_SYS_SDRAM_BASE) == 0)) - break; - } - if (row == 12) { - printf("Row detect error\n"); - ret = -EINVAL; - } else { - sdram_params->ch[channel].cs1_row = row; - sdram_params->ch[channel].row_3_4 = 0; - debug("chn %d col %d, row %d\n", channel, col, row); - sdram_params->ch[channel].cs0_row = row; - } - -out: - return ret; -} - -static int sdram_get_niu_config(struct rk3188_sdram_params *sdram_params) -{ - int i, tmp, size, ret = 0; - - tmp = sdram_params->ch[0].col - 9; - tmp -= (sdram_params->ch[0].bw == 2) ? 0 : 1; - tmp |= ((sdram_params->ch[0].cs0_row - 13) << 4); - size = sizeof(ddrconf_table)/sizeof(ddrconf_table[0]); - for (i = 0; i < size; i++) - if (tmp == ddrconf_table[i]) - break; - if (i >= size) { - printf("niu config not found\n"); - ret = -EINVAL; - } else { - debug("niu config %d\n", i); - sdram_params->base.ddrconfig = i; - } - - return ret; -} - -static int sdram_init(struct dram_info *dram, - struct rk3188_sdram_params *sdram_params) -{ - int channel; - int zqcr; - int ret; - - if ((sdram_params->base.dramtype == DDR3 && - sdram_params->base.ddr_freq > 800000000)) { - printf("SDRAM frequency is too high!"); - return -E2BIG; - } - - ret = clk_set_rate(&dram->ddr_clk, sdram_params->base.ddr_freq); - if (ret) { - printf("Could not set DDR clock\n"); - return ret; - } - - for (channel = 0; channel < 1; channel++) { - const struct chan_info *chan = &dram->chan[channel]; - struct rk3288_ddr_pctl *pctl = chan->pctl; - struct rk3288_ddr_publ *publ = chan->publ; - - phy_pctrl_reset(dram->cru, publ, channel); - phy_dll_bypass_set(publ, sdram_params->base.ddr_freq); - - dfi_cfg(pctl, sdram_params->base.dramtype); - - pctl_cfg(channel, pctl, sdram_params, dram->grf); - - phy_cfg(chan, channel, sdram_params); - - phy_init(publ); - - writel(POWER_UP_START, &pctl->powctl); - while (!(readl(&pctl->powstat) & POWER_UP_DONE)) - ; - - memory_init(publ, sdram_params->base.dramtype); - move_to_config_state(publ, pctl); - - /* Using 32bit bus width for detect */ - sdram_params->ch[channel].bw = 2; - set_bandwidth_ratio(chan, channel, - sdram_params->ch[channel].bw, dram->grf); - /* - * set cs, using n=3 for detect - * CS0, n=1 - * CS1, n=2 - * CS0 & CS1, n = 3 - */ - sdram_params->ch[channel].rank = 2, - clrsetbits_le32(&publ->pgcr, 0xF << 18, - (sdram_params->ch[channel].rank | 1) << 18); - - /* DS=40ohm,ODT=155ohm */ - zqcr = 1 << ZDEN_SHIFT | 2 << PU_ONDIE_SHIFT | - 2 << PD_ONDIE_SHIFT | 0x19 << PU_OUTPUT_SHIFT | - 0x19 << PD_OUTPUT_SHIFT; - writel(zqcr, &publ->zq1cr[0]); - writel(zqcr, &publ->zq0cr[0]); - - /* Detect the rank and bit-width with data-training */ - writel(1, &chan->msch->ddrconf); - sdram_rank_bw_detect(dram, channel, sdram_params); - - if (sdram_params->base.dramtype == LPDDR3) { - u32 i; - writel(0, &pctl->mrrcfg0); - for (i = 0; i < 17; i++) - send_command_op(pctl, 1, MRR_CMD, i, 0); - } - writel(4, &chan->msch->ddrconf); - move_to_access_state(chan); - /* DDR3 and LPDDR3 are always 8 bank, no need detect */ - sdram_params->ch[channel].bk = 3; - /* Detect Col and Row number*/ - ret = sdram_col_row_detect(dram, channel, sdram_params); - if (ret) - goto error; - } - /* Find NIU DDR configuration */ - ret = sdram_get_niu_config(sdram_params); - if (ret) - goto error; - - dram_all_config(dram, sdram_params); - debug("%s done\n", __func__); - - return 0; -error: - printf("DRAM init failed!\n"); - hang(); -} - -static int setup_sdram(struct udevice *dev) -{ - struct dram_info *priv = dev_get_priv(dev); - struct rk3188_sdram_params *params = dev_get_platdata(dev); - - return sdram_init(priv, params); -} - -static int rk3188_dmc_ofdata_to_platdata(struct udevice *dev) -{ -#if !CONFIG_IS_ENABLED(OF_PLATDATA) - struct rk3188_sdram_params *params = dev_get_platdata(dev); - int ret; - - /* rk3188 supports only one-channel */ - params->num_channels = 1; - ret = dev_read_u32_array(dev, "rockchip,pctl-timing", - (u32 *)¶ms->pctl_timing, - sizeof(params->pctl_timing) / sizeof(u32)); - if (ret) { - printf("%s: Cannot read rockchip,pctl-timing\n", __func__); - return -EINVAL; - } - ret = dev_read_u32_array(dev, "rockchip,phy-timing", - (u32 *)¶ms->phy_timing, - sizeof(params->phy_timing) / sizeof(u32)); - if (ret) { - printf("%s: Cannot read rockchip,phy-timing\n", __func__); - return -EINVAL; - } - ret = dev_read_u32_array(dev, "rockchip,sdram-params", - (u32 *)¶ms->base, - sizeof(params->base) / sizeof(u32)); - if (ret) { - printf("%s: Cannot read rockchip,sdram-params\n", __func__); - return -EINVAL; - } - ret = regmap_init_mem(dev, ¶ms->map); - if (ret) - return ret; -#endif - - return 0; -} -#endif /* CONFIG_SPL_BUILD */ - -#if CONFIG_IS_ENABLED(OF_PLATDATA) -static int conv_of_platdata(struct udevice *dev) -{ - struct rk3188_sdram_params *plat = dev_get_platdata(dev); - struct dtd_rockchip_rk3188_dmc *of_plat = &plat->of_plat; - int ret; - - memcpy(&plat->pctl_timing, of_plat->rockchip_pctl_timing, - sizeof(plat->pctl_timing)); - memcpy(&plat->phy_timing, of_plat->rockchip_phy_timing, - sizeof(plat->phy_timing)); - memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base)); - /* rk3188 supports dual-channel, set default channel num to 2 */ - plat->num_channels = 1; - ret = regmap_init_mem_platdata(dev, of_plat->reg, - ARRAY_SIZE(of_plat->reg) / 2, - &plat->map); - if (ret) - return ret; - - return 0; -} -#endif - -static int rk3188_dmc_probe(struct udevice *dev) -{ -#ifdef CONFIG_SPL_BUILD - struct rk3188_sdram_params *plat = dev_get_platdata(dev); - struct regmap *map; - struct udevice *dev_clk; - int ret; -#endif - struct dram_info *priv = dev_get_priv(dev); - - priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU); - -#ifdef CONFIG_SPL_BUILD -#if CONFIG_IS_ENABLED(OF_PLATDATA) - ret = conv_of_platdata(dev); - if (ret) - return ret; -#endif - map = syscon_get_regmap_by_driver_data(ROCKCHIP_SYSCON_NOC); - if (IS_ERR(map)) - return PTR_ERR(map); - priv->chan[0].msch = regmap_get_range(map, 0); - - priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); - - priv->chan[0].pctl = regmap_get_range(plat->map, 0); - priv->chan[0].publ = regmap_get_range(plat->map, 1); - - ret = rockchip_get_clk(&dev_clk); - if (ret) - return ret; - priv->ddr_clk.id = CLK_DDR; - ret = clk_request(dev_clk, &priv->ddr_clk); - if (ret) - return ret; - - priv->cru = rockchip_get_cru(); - if (IS_ERR(priv->cru)) - return PTR_ERR(priv->cru); - ret = setup_sdram(dev); - if (ret) - return ret; -#else - priv->info.base = CONFIG_SYS_SDRAM_BASE; - priv->info.size = rockchip_sdram_size( - (phys_addr_t)&priv->pmu->sys_reg[2]); -#endif - - return 0; -} - -static int rk3188_dmc_get_info(struct udevice *dev, struct ram_info *info) -{ - struct dram_info *priv = dev_get_priv(dev); - - *info = priv->info; - - return 0; -} - -static struct ram_ops rk3188_dmc_ops = { - .get_info = rk3188_dmc_get_info, -}; - -static const struct udevice_id rk3188_dmc_ids[] = { - { .compatible = "rockchip,rk3188-dmc" }, - { } -}; - -U_BOOT_DRIVER(dmc_rk3188) = { - .name = "rockchip_rk3188_dmc", - .id = UCLASS_RAM, - .of_match = rk3188_dmc_ids, - .ops = &rk3188_dmc_ops, -#ifdef CONFIG_SPL_BUILD - .ofdata_to_platdata = rk3188_dmc_ofdata_to_platdata, -#endif - .probe = rk3188_dmc_probe, - .priv_auto_alloc_size = sizeof(struct dram_info), -#ifdef CONFIG_SPL_BUILD - .platdata_auto_alloc_size = sizeof(struct rk3188_sdram_params), -#endif -}; -- cgit v1.2.3 From c9eb7bca4b77523fb4a870208351af81a7f0ee67 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Wed, 27 Sep 2017 16:11:32 +0800 Subject: rockchip: rk3288: move sdram driver to driver/ram Since we have CONFIG_RAM framwork and its driver folder, move the driver into it. Signed-off-by: Kever Yang Acked-by: Philipp Tomsich Reviewed-by: Philipp Tomsich --- arch/arm/mach-rockchip/rk3288/Makefile | 1 - arch/arm/mach-rockchip/rk3288/sdram_rk3288.c | 1125 -------------------------- 2 files changed, 1126 deletions(-) delete mode 100644 arch/arm/mach-rockchip/rk3288/sdram_rk3288.c (limited to 'arch') diff --git a/arch/arm/mach-rockchip/rk3288/Makefile b/arch/arm/mach-rockchip/rk3288/Makefile index b5b28efbe81..a0033a0d845 100644 --- a/arch/arm/mach-rockchip/rk3288/Makefile +++ b/arch/arm/mach-rockchip/rk3288/Makefile @@ -6,5 +6,4 @@ obj-y += clk_rk3288.o obj-y += rk3288.o -obj-y += sdram_rk3288.o obj-y += syscon_rk3288.o diff --git a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c deleted file mode 100644 index 95efb117fc1..00000000000 --- a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +++ /dev/null @@ -1,1125 +0,0 @@ -/* - * (C) Copyright 2015 Google, Inc - * Copyright 2014 Rockchip Inc. - * - * SPDX-License-Identifier: GPL-2.0 - * - * Adapted from coreboot. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -struct chan_info { - struct rk3288_ddr_pctl *pctl; - struct rk3288_ddr_publ *publ; - struct rk3288_msch *msch; -}; - -struct dram_info { - struct chan_info chan[2]; - struct ram_info info; - struct clk ddr_clk; - struct rk3288_cru *cru; - struct rk3288_grf *grf; - struct rk3288_sgrf *sgrf; - struct rk3288_pmu *pmu; - bool is_veyron; -}; - -struct rk3288_sdram_params { -#if CONFIG_IS_ENABLED(OF_PLATDATA) - struct dtd_rockchip_rk3288_dmc of_plat; -#endif - struct rk3288_sdram_channel ch[2]; - struct rk3288_sdram_pctl_timing pctl_timing; - struct rk3288_sdram_phy_timing phy_timing; - struct rk3288_base_params base; - int num_channels; - struct regmap *map; -}; - -const int ddrconf_table[] = { - /* row col,bw */ - 0, - ((1 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT), - ((2 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT), - ((3 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT), - ((4 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT), - ((1 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT), - ((2 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT), - ((3 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT), - ((1 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT), - ((2 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT), - ((3 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT), - 0, - 0, - 0, - 0, - ((4 << 4) | 2), -}; - -#define TEST_PATTEN 0x5aa5f00f -#define DQS_GATE_TRAINING_ERROR_RANK0 (1 << 4) -#define DQS_GATE_TRAINING_ERROR_RANK1 (2 << 4) - -#ifdef CONFIG_SPL_BUILD -static void copy_to_reg(u32 *dest, const u32 *src, u32 n) -{ - int i; - - for (i = 0; i < n / sizeof(u32); i++) { - writel(*src, dest); - src++; - dest++; - } -} - -static void ddr_reset(struct rk3288_cru *cru, u32 ch, u32 ctl, u32 phy) -{ - u32 phy_ctl_srstn_shift = 4 + 5 * ch; - u32 ctl_psrstn_shift = 3 + 5 * ch; - u32 ctl_srstn_shift = 2 + 5 * ch; - u32 phy_psrstn_shift = 1 + 5 * ch; - u32 phy_srstn_shift = 5 * ch; - - rk_clrsetreg(&cru->cru_softrst_con[10], - 1 << phy_ctl_srstn_shift | 1 << ctl_psrstn_shift | - 1 << ctl_srstn_shift | 1 << phy_psrstn_shift | - 1 << phy_srstn_shift, - phy << phy_ctl_srstn_shift | ctl << ctl_psrstn_shift | - ctl << ctl_srstn_shift | phy << phy_psrstn_shift | - phy << phy_srstn_shift); -} - -static void ddr_phy_ctl_reset(struct rk3288_cru *cru, u32 ch, u32 n) -{ - u32 phy_ctl_srstn_shift = 4 + 5 * ch; - - rk_clrsetreg(&cru->cru_softrst_con[10], - 1 << phy_ctl_srstn_shift, n << phy_ctl_srstn_shift); -} - -static void phy_pctrl_reset(struct rk3288_cru *cru, - struct rk3288_ddr_publ *publ, - int channel) -{ - int i; - - ddr_reset(cru, channel, 1, 1); - udelay(1); - clrbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST); - for (i = 0; i < 4; i++) - clrbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST); - - udelay(10); - setbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST); - for (i = 0; i < 4; i++) - setbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST); - - udelay(10); - ddr_reset(cru, channel, 1, 0); - udelay(10); - ddr_reset(cru, channel, 0, 0); - udelay(10); -} - -static void phy_dll_bypass_set(struct rk3288_ddr_publ *publ, - u32 freq) -{ - int i; - - if (freq <= 250000000) { - if (freq <= 150000000) - clrbits_le32(&publ->dllgcr, SBIAS_BYPASS); - else - setbits_le32(&publ->dllgcr, SBIAS_BYPASS); - setbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS); - for (i = 0; i < 4; i++) - setbits_le32(&publ->datx8[i].dxdllcr, - DXDLLCR_DLLDIS); - - setbits_le32(&publ->pir, PIR_DLLBYP); - } else { - clrbits_le32(&publ->dllgcr, SBIAS_BYPASS); - clrbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS); - for (i = 0; i < 4; i++) { - clrbits_le32(&publ->datx8[i].dxdllcr, - DXDLLCR_DLLDIS); - } - - clrbits_le32(&publ->pir, PIR_DLLBYP); - } -} - -static void dfi_cfg(struct rk3288_ddr_pctl *pctl, u32 dramtype) -{ - writel(DFI_INIT_START, &pctl->dfistcfg0); - writel(DFI_DRAM_CLK_SR_EN | DFI_DRAM_CLK_DPD_EN, - &pctl->dfistcfg1); - writel(DFI_PARITY_INTR_EN | DFI_PARITY_EN, &pctl->dfistcfg2); - writel(7 << TLP_RESP_TIME_SHIFT | LP_SR_EN | LP_PD_EN, - &pctl->dfilpcfg0); - - writel(2 << TCTRL_DELAY_TIME_SHIFT, &pctl->dfitctrldelay); - writel(1 << TPHY_WRDATA_TIME_SHIFT, &pctl->dfitphywrdata); - writel(0xf << TPHY_RDLAT_TIME_SHIFT, &pctl->dfitphyrdlat); - writel(2 << TDRAM_CLK_DIS_TIME_SHIFT, &pctl->dfitdramclkdis); - writel(2 << TDRAM_CLK_EN_TIME_SHIFT, &pctl->dfitdramclken); - writel(1, &pctl->dfitphyupdtype0); - - /* cs0 and cs1 write odt enable */ - writel((RANK0_ODT_WRITE_SEL | RANK1_ODT_WRITE_SEL), - &pctl->dfiodtcfg); - /* odt write length */ - writel(7 << ODT_LEN_BL8_W_SHIFT, &pctl->dfiodtcfg1); - /* phyupd and ctrlupd disabled */ - writel(0, &pctl->dfiupdcfg); -} - -static void ddr_set_enable(struct rk3288_grf *grf, uint channel, bool enable) -{ - uint val = 0; - - if (enable) { - val = 1 << (channel ? DDR1_16BIT_EN_SHIFT : - DDR0_16BIT_EN_SHIFT); - } - rk_clrsetreg(&grf->soc_con0, - 1 << (channel ? DDR1_16BIT_EN_SHIFT : DDR0_16BIT_EN_SHIFT), - val); -} - -static void ddr_set_ddr3_mode(struct rk3288_grf *grf, uint channel, - bool ddr3_mode) -{ - uint mask, val; - - mask = 1 << (channel ? MSCH1_MAINDDR3_SHIFT : MSCH0_MAINDDR3_SHIFT); - val = ddr3_mode << (channel ? MSCH1_MAINDDR3_SHIFT : - MSCH0_MAINDDR3_SHIFT); - rk_clrsetreg(&grf->soc_con0, mask, val); -} - -static void ddr_set_en_bst_odt(struct rk3288_grf *grf, uint channel, - bool enable, bool enable_bst, bool enable_odt) -{ - uint mask; - bool disable_bst = !enable_bst; - - mask = channel ? - (1 << LPDDR3_EN1_SHIFT | 1 << UPCTL1_BST_DIABLE_SHIFT | - 1 << UPCTL1_LPDDR3_ODT_EN_SHIFT) : - (1 << LPDDR3_EN0_SHIFT | 1 << UPCTL0_BST_DIABLE_SHIFT | - 1 << UPCTL0_LPDDR3_ODT_EN_SHIFT); - rk_clrsetreg(&grf->soc_con2, mask, - enable << (channel ? LPDDR3_EN1_SHIFT : LPDDR3_EN0_SHIFT) | - disable_bst << (channel ? UPCTL1_BST_DIABLE_SHIFT : - UPCTL0_BST_DIABLE_SHIFT) | - enable_odt << (channel ? UPCTL1_LPDDR3_ODT_EN_SHIFT : - UPCTL0_LPDDR3_ODT_EN_SHIFT)); -} - -static void pctl_cfg(int channel, struct rk3288_ddr_pctl *pctl, - struct rk3288_sdram_params *sdram_params, - struct rk3288_grf *grf) -{ - unsigned int burstlen; - - burstlen = (sdram_params->base.noc_timing >> 18) & 0x7; - copy_to_reg(&pctl->togcnt1u, &sdram_params->pctl_timing.togcnt1u, - sizeof(sdram_params->pctl_timing)); - switch (sdram_params->base.dramtype) { - case LPDDR3: - writel(sdram_params->pctl_timing.tcl - 1, - &pctl->dfitrddataen); - writel(sdram_params->pctl_timing.tcwl, - &pctl->dfitphywrlat); - burstlen >>= 1; - writel(LPDDR2_S4 | 0 << MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT | - LPDDR2_EN | burstlen << BURSTLENGTH_SHIFT | - (6 - 4) << TFAW_SHIFT | PD_EXIT_FAST | - 1 << PD_TYPE_SHIFT | 0 << PD_IDLE_SHIFT, - &pctl->mcfg); - ddr_set_ddr3_mode(grf, channel, false); - ddr_set_enable(grf, channel, true); - ddr_set_en_bst_odt(grf, channel, true, false, - sdram_params->base.odt); - break; - case DDR3: - if (sdram_params->phy_timing.mr[1] & DDR3_DLL_DISABLE) { - writel(sdram_params->pctl_timing.tcl - 3, - &pctl->dfitrddataen); - } else { - writel(sdram_params->pctl_timing.tcl - 2, - &pctl->dfitrddataen); - } - writel(sdram_params->pctl_timing.tcwl - 1, - &pctl->dfitphywrlat); - writel(0 << MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT | DDR3_EN | - DDR2_DDR3_BL_8 | (6 - 4) << TFAW_SHIFT | PD_EXIT_SLOW | - 1 << PD_TYPE_SHIFT | 0 << PD_IDLE_SHIFT, - &pctl->mcfg); - ddr_set_ddr3_mode(grf, channel, true); - ddr_set_enable(grf, channel, true); - - ddr_set_en_bst_odt(grf, channel, false, true, false); - break; - } - - setbits_le32(&pctl->scfg, 1); -} - -static void phy_cfg(const struct chan_info *chan, int channel, - struct rk3288_sdram_params *sdram_params) -{ - struct rk3288_ddr_publ *publ = chan->publ; - struct rk3288_msch *msch = chan->msch; - uint ddr_freq_mhz = sdram_params->base.ddr_freq / 1000000; - u32 dinit2, tmp; - int i; - - dinit2 = DIV_ROUND_UP(ddr_freq_mhz * 200000, 1000); - /* DDR PHY Timing */ - copy_to_reg(&publ->dtpr[0], &sdram_params->phy_timing.dtpr0, - sizeof(sdram_params->phy_timing)); - writel(sdram_params->base.noc_timing, &msch->ddrtiming); - writel(0x3f, &msch->readlatency); - writel(sdram_params->base.noc_activate, &msch->activate); - writel(2 << BUSWRTORD_SHIFT | 2 << BUSRDTOWR_SHIFT | - 1 << BUSRDTORD_SHIFT, &msch->devtodev); - writel(DIV_ROUND_UP(ddr_freq_mhz * 5120, 1000) << PRT_DLLLOCK_SHIFT | - DIV_ROUND_UP(ddr_freq_mhz * 50, 1000) << PRT_DLLSRST_SHIFT | - 8 << PRT_ITMSRST_SHIFT, &publ->ptr[0]); - writel(DIV_ROUND_UP(ddr_freq_mhz * 500000, 1000) << PRT_DINIT0_SHIFT | - DIV_ROUND_UP(ddr_freq_mhz * 400, 1000) << PRT_DINIT1_SHIFT, - &publ->ptr[1]); - writel(min(dinit2, 0x1ffffU) << PRT_DINIT2_SHIFT | - DIV_ROUND_UP(ddr_freq_mhz * 1000, 1000) << PRT_DINIT3_SHIFT, - &publ->ptr[2]); - - switch (sdram_params->base.dramtype) { - case LPDDR3: - clrsetbits_le32(&publ->pgcr, 0x1F, - 0 << PGCR_DFTLMT_SHIFT | - 0 << PGCR_DFTCMP_SHIFT | - 1 << PGCR_DQSCFG_SHIFT | - 0 << PGCR_ITMDMD_SHIFT); - /* DDRMODE select LPDDR3 */ - clrsetbits_le32(&publ->dcr, DDRMD_MASK << DDRMD_SHIFT, - DDRMD_LPDDR2_LPDDR3 << DDRMD_SHIFT); - clrsetbits_le32(&publ->dxccr, - DQSNRES_MASK << DQSNRES_SHIFT | - DQSRES_MASK << DQSRES_SHIFT, - 4 << DQSRES_SHIFT | 0xc << DQSNRES_SHIFT); - tmp = readl(&publ->dtpr[1]); - tmp = ((tmp >> TDQSCKMAX_SHIFT) & TDQSCKMAX_MASK) - - ((tmp >> TDQSCK_SHIFT) & TDQSCK_MASK); - clrsetbits_le32(&publ->dsgcr, - DQSGE_MASK << DQSGE_SHIFT | - DQSGX_MASK << DQSGX_SHIFT, - tmp << DQSGE_SHIFT | tmp << DQSGX_SHIFT); - break; - case DDR3: - clrbits_le32(&publ->pgcr, 0x1f); - clrsetbits_le32(&publ->dcr, DDRMD_MASK << DDRMD_SHIFT, - DDRMD_DDR3 << DDRMD_SHIFT); - break; - } - if (sdram_params->base.odt) { - /*dynamic RTT enable */ - for (i = 0; i < 4; i++) - setbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT); - } else { - /*dynamic RTT disable */ - for (i = 0; i < 4; i++) - clrbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT); - } -} - -static void phy_init(struct rk3288_ddr_publ *publ) -{ - setbits_le32(&publ->pir, PIR_INIT | PIR_DLLSRST - | PIR_DLLLOCK | PIR_ZCAL | PIR_ITMSRST | PIR_CLRSR); - udelay(1); - while ((readl(&publ->pgsr) & - (PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE)) != - (PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE)) - ; -} - -static void send_command(struct rk3288_ddr_pctl *pctl, u32 rank, - u32 cmd, u32 arg) -{ - writel((START_CMD | (rank << 20) | arg | cmd), &pctl->mcmd); - udelay(1); - while (readl(&pctl->mcmd) & START_CMD) - ; -} - -static inline void send_command_op(struct rk3288_ddr_pctl *pctl, - u32 rank, u32 cmd, u32 ma, u32 op) -{ - send_command(pctl, rank, cmd, (ma & LPDDR2_MA_MASK) << LPDDR2_MA_SHIFT | - (op & LPDDR2_OP_MASK) << LPDDR2_OP_SHIFT); -} - -static void memory_init(struct rk3288_ddr_publ *publ, - u32 dramtype) -{ - setbits_le32(&publ->pir, - (PIR_INIT | PIR_DRAMINIT | PIR_LOCKBYP - | PIR_ZCALBYP | PIR_CLRSR | PIR_ICPC - | (dramtype == DDR3 ? PIR_DRAMRST : 0))); - udelay(1); - while ((readl(&publ->pgsr) & (PGSR_IDONE | PGSR_DLDONE)) - != (PGSR_IDONE | PGSR_DLDONE)) - ; -} - -static void move_to_config_state(struct rk3288_ddr_publ *publ, - struct rk3288_ddr_pctl *pctl) -{ - unsigned int state; - - while (1) { - state = readl(&pctl->stat) & PCTL_STAT_MSK; - - switch (state) { - case LOW_POWER: - writel(WAKEUP_STATE, &pctl->sctl); - while ((readl(&pctl->stat) & PCTL_STAT_MSK) - != ACCESS) - ; - /* wait DLL lock */ - while ((readl(&publ->pgsr) & PGSR_DLDONE) - != PGSR_DLDONE) - ; - /* - * if at low power state,need wakeup first, - * and then enter the config - * so here no break. - */ - case ACCESS: - /* no break */ - case INIT_MEM: - writel(CFG_STATE, &pctl->sctl); - while ((readl(&pctl->stat) & PCTL_STAT_MSK) != CONFIG) - ; - break; - case CONFIG: - return; - default: - break; - } - } -} - -static void set_bandwidth_ratio(const struct chan_info *chan, int channel, - u32 n, struct rk3288_grf *grf) -{ - struct rk3288_ddr_pctl *pctl = chan->pctl; - struct rk3288_ddr_publ *publ = chan->publ; - struct rk3288_msch *msch = chan->msch; - - if (n == 1) { - setbits_le32(&pctl->ppcfg, 1); - rk_setreg(&grf->soc_con0, 1 << (8 + channel)); - setbits_le32(&msch->ddrtiming, 1 << 31); - /* Data Byte disable*/ - clrbits_le32(&publ->datx8[2].dxgcr, 1); - clrbits_le32(&publ->datx8[3].dxgcr, 1); - /* disable DLL */ - setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS); - setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS); - } else { - clrbits_le32(&pctl->ppcfg, 1); - rk_clrreg(&grf->soc_con0, 1 << (8 + channel)); - clrbits_le32(&msch->ddrtiming, 1 << 31); - /* Data Byte enable*/ - setbits_le32(&publ->datx8[2].dxgcr, 1); - setbits_le32(&publ->datx8[3].dxgcr, 1); - - /* enable DLL */ - clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS); - clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS); - /* reset DLL */ - clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST); - clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST); - udelay(10); - setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST); - setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST); - } - setbits_le32(&pctl->dfistcfg0, 1 << 2); -} - -static int data_training(const struct chan_info *chan, int channel, - struct rk3288_sdram_params *sdram_params) -{ - unsigned int j; - int ret = 0; - u32 rank; - int i; - u32 step[2] = { PIR_QSTRN, PIR_RVTRN }; - struct rk3288_ddr_publ *publ = chan->publ; - struct rk3288_ddr_pctl *pctl = chan->pctl; - - /* disable auto refresh */ - writel(0, &pctl->trefi); - - if (sdram_params->base.dramtype != LPDDR3) - setbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT); - rank = sdram_params->ch[channel].rank | 1; - for (j = 0; j < ARRAY_SIZE(step); j++) { - /* - * trigger QSTRN and RVTRN - * clear DTDONE status - */ - setbits_le32(&publ->pir, PIR_CLRSR); - - /* trigger DTT */ - setbits_le32(&publ->pir, - PIR_INIT | step[j] | PIR_LOCKBYP | PIR_ZCALBYP | - PIR_CLRSR); - udelay(1); - /* wait echo byte DTDONE */ - while ((readl(&publ->datx8[0].dxgsr[0]) & rank) - != rank) - ; - while ((readl(&publ->datx8[1].dxgsr[0]) & rank) - != rank) - ; - if (!(readl(&pctl->ppcfg) & 1)) { - while ((readl(&publ->datx8[2].dxgsr[0]) - & rank) != rank) - ; - while ((readl(&publ->datx8[3].dxgsr[0]) - & rank) != rank) - ; - } - if (readl(&publ->pgsr) & - (PGSR_DTERR | PGSR_RVERR | PGSR_RVEIRR)) { - ret = -1; - break; - } - } - /* send some auto refresh to complement the lost while DTT */ - for (i = 0; i < (rank > 1 ? 8 : 4); i++) - send_command(pctl, rank, REF_CMD, 0); - - if (sdram_params->base.dramtype != LPDDR3) - clrbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT); - - /* resume auto refresh */ - writel(sdram_params->pctl_timing.trefi, &pctl->trefi); - - return ret; -} - -static void move_to_access_state(const struct chan_info *chan) -{ - struct rk3288_ddr_publ *publ = chan->publ; - struct rk3288_ddr_pctl *pctl = chan->pctl; - unsigned int state; - - while (1) { - state = readl(&pctl->stat) & PCTL_STAT_MSK; - - switch (state) { - case LOW_POWER: - if (((readl(&pctl->stat) >> LP_TRIG_SHIFT) & - LP_TRIG_MASK) == 1) - return; - - writel(WAKEUP_STATE, &pctl->sctl); - while ((readl(&pctl->stat) & PCTL_STAT_MSK) != ACCESS) - ; - /* wait DLL lock */ - while ((readl(&publ->pgsr) & PGSR_DLDONE) - != PGSR_DLDONE) - ; - break; - case INIT_MEM: - writel(CFG_STATE, &pctl->sctl); - while ((readl(&pctl->stat) & PCTL_STAT_MSK) != CONFIG) - ; - case CONFIG: - writel(GO_STATE, &pctl->sctl); - while ((readl(&pctl->stat) & PCTL_STAT_MSK) == CONFIG) - ; - break; - case ACCESS: - return; - default: - break; - } - } -} - -static void dram_cfg_rbc(const struct chan_info *chan, u32 chnum, - struct rk3288_sdram_params *sdram_params) -{ - struct rk3288_ddr_publ *publ = chan->publ; - - if (sdram_params->ch[chnum].bk == 3) - clrsetbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT, - 1 << PDQ_SHIFT); - else - clrbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT); - - writel(sdram_params->base.ddrconfig, &chan->msch->ddrconf); -} - -static void dram_all_config(const struct dram_info *dram, - struct rk3288_sdram_params *sdram_params) -{ - unsigned int chan; - u32 sys_reg = 0; - - sys_reg |= sdram_params->base.dramtype << SYS_REG_DDRTYPE_SHIFT; - sys_reg |= (sdram_params->num_channels - 1) << SYS_REG_NUM_CH_SHIFT; - for (chan = 0; chan < sdram_params->num_channels; chan++) { - const struct rk3288_sdram_channel *info = - &sdram_params->ch[chan]; - - sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(chan); - sys_reg |= 1 << SYS_REG_CHINFO_SHIFT(chan); - sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(chan); - sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(chan); - sys_reg |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(chan); - sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(chan); - sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(chan); - sys_reg |= (2 >> info->bw) << SYS_REG_BW_SHIFT(chan); - sys_reg |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(chan); - - dram_cfg_rbc(&dram->chan[chan], chan, sdram_params); - } - writel(sys_reg, &dram->pmu->sys_reg[2]); - rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, sdram_params->base.stride); -} - -static int sdram_rank_bw_detect(struct dram_info *dram, int channel, - struct rk3288_sdram_params *sdram_params) -{ - int reg; - int need_trainig = 0; - const struct chan_info *chan = &dram->chan[channel]; - struct rk3288_ddr_publ *publ = chan->publ; - - if (data_training(chan, channel, sdram_params) < 0) { - reg = readl(&publ->datx8[0].dxgsr[0]); - /* Check the result for rank 0 */ - if ((channel == 0) && (reg & DQS_GATE_TRAINING_ERROR_RANK0)) { - debug("data training fail!\n"); - return -EIO; - } else if ((channel == 1) && - (reg & DQS_GATE_TRAINING_ERROR_RANK0)) { - sdram_params->num_channels = 1; - } - - /* Check the result for rank 1 */ - if (reg & DQS_GATE_TRAINING_ERROR_RANK1) { - sdram_params->ch[channel].rank = 1; - clrsetbits_le32(&publ->pgcr, 0xF << 18, - sdram_params->ch[channel].rank << 18); - need_trainig = 1; - } - reg = readl(&publ->datx8[2].dxgsr[0]); - if (reg & (1 << 4)) { - sdram_params->ch[channel].bw = 1; - set_bandwidth_ratio(chan, channel, - sdram_params->ch[channel].bw, - dram->grf); - need_trainig = 1; - } - } - /* Assume the Die bit width are the same with the chip bit width */ - sdram_params->ch[channel].dbw = sdram_params->ch[channel].bw; - - if (need_trainig && - (data_training(chan, channel, sdram_params) < 0)) { - if (sdram_params->base.dramtype == LPDDR3) { - ddr_phy_ctl_reset(dram->cru, channel, 1); - udelay(10); - ddr_phy_ctl_reset(dram->cru, channel, 0); - udelay(10); - } - debug("2nd data training failed!"); - return -EIO; - } - - return 0; -} - -static int sdram_col_row_detect(struct dram_info *dram, int channel, - struct rk3288_sdram_params *sdram_params) -{ - int row, col; - unsigned int addr; - const struct chan_info *chan = &dram->chan[channel]; - struct rk3288_ddr_pctl *pctl = chan->pctl; - struct rk3288_ddr_publ *publ = chan->publ; - int ret = 0; - - /* Detect col */ - for (col = 11; col >= 9; col--) { - writel(0, CONFIG_SYS_SDRAM_BASE); - addr = CONFIG_SYS_SDRAM_BASE + - (1 << (col + sdram_params->ch[channel].bw - 1)); - writel(TEST_PATTEN, addr); - if ((readl(addr) == TEST_PATTEN) && - (readl(CONFIG_SYS_SDRAM_BASE) == 0)) - break; - } - if (col == 8) { - printf("Col detect error\n"); - ret = -EINVAL; - goto out; - } else { - sdram_params->ch[channel].col = col; - } - - move_to_config_state(publ, pctl); - writel(4, &chan->msch->ddrconf); - move_to_access_state(chan); - /* Detect row*/ - for (row = 16; row >= 12; row--) { - writel(0, CONFIG_SYS_SDRAM_BASE); - addr = CONFIG_SYS_SDRAM_BASE + (1 << (row + 15 - 1)); - writel(TEST_PATTEN, addr); - if ((readl(addr) == TEST_PATTEN) && - (readl(CONFIG_SYS_SDRAM_BASE) == 0)) - break; - } - if (row == 11) { - printf("Row detect error\n"); - ret = -EINVAL; - } else { - sdram_params->ch[channel].cs1_row = row; - sdram_params->ch[channel].row_3_4 = 0; - debug("chn %d col %d, row %d\n", channel, col, row); - sdram_params->ch[channel].cs0_row = row; - } - -out: - return ret; -} - -static int sdram_get_niu_config(struct rk3288_sdram_params *sdram_params) -{ - int i, tmp, size, ret = 0; - - tmp = sdram_params->ch[0].col - 9; - tmp -= (sdram_params->ch[0].bw == 2) ? 0 : 1; - tmp |= ((sdram_params->ch[0].cs0_row - 12) << 4); - size = sizeof(ddrconf_table)/sizeof(ddrconf_table[0]); - for (i = 0; i < size; i++) - if (tmp == ddrconf_table[i]) - break; - if (i >= size) { - printf("niu config not found\n"); - ret = -EINVAL; - } else { - sdram_params->base.ddrconfig = i; - } - - return ret; -} - -static int sdram_get_stride(struct rk3288_sdram_params *sdram_params) -{ - int stride = -1; - int ret = 0; - long cap = sdram_params->num_channels * (1u << - (sdram_params->ch[0].cs0_row + - sdram_params->ch[0].col + - (sdram_params->ch[0].rank - 1) + - sdram_params->ch[0].bw + - 3 - 20)); - - switch (cap) { - case 512: - stride = 0; - break; - case 1024: - stride = 5; - break; - case 2048: - stride = 9; - break; - case 4096: - stride = 0xd; - break; - default: - stride = -1; - printf("could not find correct stride, cap error!\n"); - ret = -EINVAL; - break; - } - sdram_params->base.stride = stride; - - return ret; -} - -static int sdram_init(struct dram_info *dram, - struct rk3288_sdram_params *sdram_params) -{ - int channel; - int zqcr; - int ret; - - debug("%s start\n", __func__); - if ((sdram_params->base.dramtype == DDR3 && - sdram_params->base.ddr_freq > 800000000) || - (sdram_params->base.dramtype == LPDDR3 && - sdram_params->base.ddr_freq > 533000000)) { - debug("SDRAM frequency is too high!"); - return -E2BIG; - } - - debug("ddr clk dpll\n"); - ret = clk_set_rate(&dram->ddr_clk, sdram_params->base.ddr_freq); - debug("ret=%d\n", ret); - if (ret) { - debug("Could not set DDR clock\n"); - return ret; - } - - for (channel = 0; channel < 2; channel++) { - const struct chan_info *chan = &dram->chan[channel]; - struct rk3288_ddr_pctl *pctl = chan->pctl; - struct rk3288_ddr_publ *publ = chan->publ; - - /* map all the 4GB space to the current channel */ - if (channel) - rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, 0x17); - else - rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, 0x1a); - phy_pctrl_reset(dram->cru, publ, channel); - phy_dll_bypass_set(publ, sdram_params->base.ddr_freq); - - dfi_cfg(pctl, sdram_params->base.dramtype); - - pctl_cfg(channel, pctl, sdram_params, dram->grf); - - phy_cfg(chan, channel, sdram_params); - - phy_init(publ); - - writel(POWER_UP_START, &pctl->powctl); - while (!(readl(&pctl->powstat) & POWER_UP_DONE)) - ; - - memory_init(publ, sdram_params->base.dramtype); - move_to_config_state(publ, pctl); - - if (sdram_params->base.dramtype == LPDDR3) { - send_command(pctl, 3, DESELECT_CMD, 0); - udelay(1); - send_command(pctl, 3, PREA_CMD, 0); - udelay(1); - send_command_op(pctl, 3, MRS_CMD, 63, 0xfc); - udelay(1); - send_command_op(pctl, 3, MRS_CMD, 1, - sdram_params->phy_timing.mr[1]); - udelay(1); - send_command_op(pctl, 3, MRS_CMD, 2, - sdram_params->phy_timing.mr[2]); - udelay(1); - send_command_op(pctl, 3, MRS_CMD, 3, - sdram_params->phy_timing.mr[3]); - udelay(1); - } - - /* Using 32bit bus width for detect */ - sdram_params->ch[channel].bw = 2; - set_bandwidth_ratio(chan, channel, - sdram_params->ch[channel].bw, dram->grf); - /* - * set cs, using n=3 for detect - * CS0, n=1 - * CS1, n=2 - * CS0 & CS1, n = 3 - */ - sdram_params->ch[channel].rank = 2, - clrsetbits_le32(&publ->pgcr, 0xF << 18, - (sdram_params->ch[channel].rank | 1) << 18); - - /* DS=40ohm,ODT=155ohm */ - zqcr = 1 << ZDEN_SHIFT | 2 << PU_ONDIE_SHIFT | - 2 << PD_ONDIE_SHIFT | 0x19 << PU_OUTPUT_SHIFT | - 0x19 << PD_OUTPUT_SHIFT; - writel(zqcr, &publ->zq1cr[0]); - writel(zqcr, &publ->zq0cr[0]); - - if (sdram_params->base.dramtype == LPDDR3) { - /* LPDDR2/LPDDR3 need to wait DAI complete, max 10us */ - udelay(10); - send_command_op(pctl, - sdram_params->ch[channel].rank | 1, - MRS_CMD, 11, - sdram_params->base.odt ? 3 : 0); - if (channel == 0) { - writel(0, &pctl->mrrcfg0); - send_command_op(pctl, 1, MRR_CMD, 8, 0); - /* S8 */ - if ((readl(&pctl->mrrstat0) & 0x3) != 3) { - debug("failed!"); - return -EREMOTEIO; - } - } - } - - /* Detect the rank and bit-width with data-training */ - sdram_rank_bw_detect(dram, channel, sdram_params); - - if (sdram_params->base.dramtype == LPDDR3) { - u32 i; - writel(0, &pctl->mrrcfg0); - for (i = 0; i < 17; i++) - send_command_op(pctl, 1, MRR_CMD, i, 0); - } - writel(15, &chan->msch->ddrconf); - move_to_access_state(chan); - /* DDR3 and LPDDR3 are always 8 bank, no need detect */ - sdram_params->ch[channel].bk = 3; - /* Detect Col and Row number*/ - ret = sdram_col_row_detect(dram, channel, sdram_params); - if (ret) - goto error; - } - /* Find NIU DDR configuration */ - ret = sdram_get_niu_config(sdram_params); - if (ret) - goto error; - /* Find stride setting */ - ret = sdram_get_stride(sdram_params); - if (ret) - goto error; - - dram_all_config(dram, sdram_params); - debug("%s done\n", __func__); - - return 0; -error: - printf("DRAM init failed!\n"); - hang(); -} - -# ifdef CONFIG_ROCKCHIP_FAST_SPL -static int veyron_init(struct dram_info *priv) -{ - struct udevice *pmic; - int ret; - - ret = uclass_first_device_err(UCLASS_PMIC, &pmic); - if (ret) - return ret; - - /* Slowly raise to max CPU voltage to prevent overshoot */ - ret = rk8xx_spl_configure_buck(pmic, 1, 1200000); - if (ret) - return ret; - udelay(175);/* Must wait for voltage to stabilize, 2mV/us */ - ret = rk8xx_spl_configure_buck(pmic, 1, 1400000); - if (ret) - return ret; - udelay(100);/* Must wait for voltage to stabilize, 2mV/us */ - - rk3288_clk_configure_cpu(priv->cru, priv->grf); - - return 0; -} -# endif - -static int setup_sdram(struct udevice *dev) -{ - struct dram_info *priv = dev_get_priv(dev); - struct rk3288_sdram_params *params = dev_get_platdata(dev); - -# ifdef CONFIG_ROCKCHIP_FAST_SPL - if (priv->is_veyron) { - int ret; - - ret = veyron_init(priv); - if (ret) - return ret; - } -# endif - - return sdram_init(priv, params); -} - -static int rk3288_dmc_ofdata_to_platdata(struct udevice *dev) -{ -#if !CONFIG_IS_ENABLED(OF_PLATDATA) - struct rk3288_sdram_params *params = dev_get_platdata(dev); - int ret; - - /* Rk3288 supports dual-channel, set default channel num to 2 */ - params->num_channels = 2; - ret = dev_read_u32_array(dev, "rockchip,pctl-timing", - (u32 *)¶ms->pctl_timing, - sizeof(params->pctl_timing) / sizeof(u32)); - if (ret) { - debug("%s: Cannot read rockchip,pctl-timing\n", __func__); - return -EINVAL; - } - ret = dev_read_u32_array(dev, "rockchip,phy-timing", - (u32 *)¶ms->phy_timing, - sizeof(params->phy_timing) / sizeof(u32)); - if (ret) { - debug("%s: Cannot read rockchip,phy-timing\n", __func__); - return -EINVAL; - } - ret = dev_read_u32_array(dev, "rockchip,sdram-params", - (u32 *)¶ms->base, - sizeof(params->base) / sizeof(u32)); - if (ret) { - debug("%s: Cannot read rockchip,sdram-params\n", __func__); - return -EINVAL; - } -#ifdef CONFIG_ROCKCHIP_FAST_SPL - struct dram_info *priv = dev_get_priv(dev); - - priv->is_veyron = !fdt_node_check_compatible(blob, 0, "google,veyron"); -#endif - ret = regmap_init_mem(dev, ¶ms->map); - if (ret) - return ret; -#endif - - return 0; -} -#endif /* CONFIG_SPL_BUILD */ - -#if CONFIG_IS_ENABLED(OF_PLATDATA) -static int conv_of_platdata(struct udevice *dev) -{ - struct rk3288_sdram_params *plat = dev_get_platdata(dev); - struct dtd_rockchip_rk3288_dmc *of_plat = &plat->of_plat; - int ret; - - memcpy(&plat->pctl_timing, of_plat->rockchip_pctl_timing, - sizeof(plat->pctl_timing)); - memcpy(&plat->phy_timing, of_plat->rockchip_phy_timing, - sizeof(plat->phy_timing)); - memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base)); - /* Rk3288 supports dual-channel, set default channel num to 2 */ - plat->num_channels = 2; - ret = regmap_init_mem_platdata(dev, of_plat->reg, - ARRAY_SIZE(of_plat->reg) / 2, - &plat->map); - if (ret) - return ret; - - return 0; -} -#endif - -static int rk3288_dmc_probe(struct udevice *dev) -{ -#ifdef CONFIG_SPL_BUILD - struct rk3288_sdram_params *plat = dev_get_platdata(dev); - struct udevice *dev_clk; - struct regmap *map; - int ret; -#endif - struct dram_info *priv = dev_get_priv(dev); - - priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU); -#ifdef CONFIG_SPL_BUILD -#if CONFIG_IS_ENABLED(OF_PLATDATA) - ret = conv_of_platdata(dev); - if (ret) - return ret; -#endif - map = syscon_get_regmap_by_driver_data(ROCKCHIP_SYSCON_NOC); - if (IS_ERR(map)) - return PTR_ERR(map); - priv->chan[0].msch = regmap_get_range(map, 0); - priv->chan[1].msch = (struct rk3288_msch *) - (regmap_get_range(map, 0) + 0x80); - - priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); - priv->sgrf = syscon_get_first_range(ROCKCHIP_SYSCON_SGRF); - - priv->chan[0].pctl = regmap_get_range(plat->map, 0); - priv->chan[0].publ = regmap_get_range(plat->map, 1); - priv->chan[1].pctl = regmap_get_range(plat->map, 2); - priv->chan[1].publ = regmap_get_range(plat->map, 3); - - ret = rockchip_get_clk(&dev_clk); - if (ret) - return ret; - priv->ddr_clk.id = CLK_DDR; - ret = clk_request(dev_clk, &priv->ddr_clk); - if (ret) - return ret; - - priv->cru = rockchip_get_cru(); - if (IS_ERR(priv->cru)) - return PTR_ERR(priv->cru); - ret = setup_sdram(dev); - if (ret) - return ret; -#else - priv->info.base = CONFIG_SYS_SDRAM_BASE; - priv->info.size = rockchip_sdram_size( - (phys_addr_t)&priv->pmu->sys_reg[2]); -#endif - - return 0; -} - -static int rk3288_dmc_get_info(struct udevice *dev, struct ram_info *info) -{ - struct dram_info *priv = dev_get_priv(dev); - - *info = priv->info; - - return 0; -} - -static struct ram_ops rk3288_dmc_ops = { - .get_info = rk3288_dmc_get_info, -}; - -static const struct udevice_id rk3288_dmc_ids[] = { - { .compatible = "rockchip,rk3288-dmc" }, - { } -}; - -U_BOOT_DRIVER(dmc_rk3288) = { - .name = "rockchip_rk3288_dmc", - .id = UCLASS_RAM, - .of_match = rk3288_dmc_ids, - .ops = &rk3288_dmc_ops, -#ifdef CONFIG_SPL_BUILD - .ofdata_to_platdata = rk3288_dmc_ofdata_to_platdata, -#endif - .probe = rk3288_dmc_probe, - .priv_auto_alloc_size = sizeof(struct dram_info), -#ifdef CONFIG_SPL_BUILD - .platdata_auto_alloc_size = sizeof(struct rk3288_sdram_params), -#endif -}; -- cgit v1.2.3 From f0768491db98249b3f54f16dd99a1d8dcdea9f2a Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Wed, 27 Sep 2017 16:11:33 +0800 Subject: rockchip: rk3328: move sdram driver to driver/ram Since we have CONFIG_RAM framwork and its driver folder, move the driver into it. Signed-off-by: Kever Yang Acked-by: Philipp Tomsich Reviewed-by: Philipp Tomsich --- arch/arm/mach-rockchip/rk3328/Makefile | 1 - arch/arm/mach-rockchip/rk3328/sdram_rk3328.c | 60 ---------------------------- 2 files changed, 61 deletions(-) delete mode 100644 arch/arm/mach-rockchip/rk3328/sdram_rk3328.c (limited to 'arch') diff --git a/arch/arm/mach-rockchip/rk3328/Makefile b/arch/arm/mach-rockchip/rk3328/Makefile index 72873e29e6a..bbab036a12a 100644 --- a/arch/arm/mach-rockchip/rk3328/Makefile +++ b/arch/arm/mach-rockchip/rk3328/Makefile @@ -6,5 +6,4 @@ obj-y += clk_rk3328.o obj-y += rk3328.o -obj-y += sdram_rk3328.o obj-y += syscon_rk3328.o diff --git a/arch/arm/mach-rockchip/rk3328/sdram_rk3328.c b/arch/arm/mach-rockchip/rk3328/sdram_rk3328.c deleted file mode 100644 index 9637a35e231..00000000000 --- a/arch/arm/mach-rockchip/rk3328/sdram_rk3328.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * (C) Copyright 2017 Rockchip Electronics Co., Ltd. - * - * SPDX-License-Identifier: GPL-2.0 - */ - -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; -struct dram_info { - struct ram_info info; - struct rk3328_grf_regs *grf; -}; - -static int rk3328_dmc_probe(struct udevice *dev) -{ - struct dram_info *priv = dev_get_priv(dev); - - priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); - debug("%s: grf=%p\n", __func__, priv->grf); - priv->info.base = CONFIG_SYS_SDRAM_BASE; - priv->info.size = rockchip_sdram_size( - (phys_addr_t)&priv->grf->os_reg[2]); - - return 0; -} - -static int rk3328_dmc_get_info(struct udevice *dev, struct ram_info *info) -{ - struct dram_info *priv = dev_get_priv(dev); - - *info = priv->info; - - return 0; -} - -static struct ram_ops rk3328_dmc_ops = { - .get_info = rk3328_dmc_get_info, -}; - - -static const struct udevice_id rk3328_dmc_ids[] = { - { .compatible = "rockchip,rk3328-dmc" }, - { } -}; - -U_BOOT_DRIVER(dmc_rk3328) = { - .name = "rockchip_rk3328_dmc", - .id = UCLASS_RAM, - .of_match = rk3328_dmc_ids, - .ops = &rk3328_dmc_ops, - .probe = rk3328_dmc_probe, - .priv_auto_alloc_size = sizeof(struct dram_info), -}; -- cgit v1.2.3 From 0176399b79330ffecb9a18fa392ec7e48a7b6a58 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Wed, 27 Sep 2017 16:38:22 +0800 Subject: rockchip: rk322x: add sdram driver Add driver for rk322x to support sdram initialize in SPL. Signed-off-by: Kever Yang Acked-by: Philipp Tomsich Reviewed-by: Philipp Tomsich --- arch/arm/include/asm/arch-rockchip/sdram_rk322x.h | 581 ++++++++++++++++++++++ 1 file changed, 581 insertions(+) create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_rk322x.h (limited to 'arch') diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rk322x.h b/arch/arm/include/asm/arch-rockchip/sdram_rk322x.h new file mode 100644 index 00000000000..b40da409d4f --- /dev/null +++ b/arch/arm/include/asm/arch-rockchip/sdram_rk322x.h @@ -0,0 +1,581 @@ +/* + * (C) Copyright 2017 Rockchip Electronics Co., Ltd + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _ASM_ARCH_SDRAM_RK322X_H +#define _ASM_ARCH_SDRAM_RK322X_H + +#include + +enum { + DDR3 = 3, + LPDDR2 = 5, + LPDDR3 = 6, + UNUSED = 0xFF, +}; + +struct rk322x_sdram_channel { + /* + * bit width in address, eg: + * 8 banks using 3 bit to address, + * 2 cs using 1 bit to address. + */ + u8 rank; + u8 col; + u8 bk; + u8 bw; + u8 dbw; + u8 row_3_4; + u8 cs0_row; + u8 cs1_row; +#if CONFIG_IS_ENABLED(OF_PLATDATA) + /* + * For of-platdata, which would otherwise convert this into two + * byte-swapped integers. With a size of 9 bytes, this struct will + * appear in of-platdata as a byte array. + * + * If OF_PLATDATA enabled, need to add a dummy byte in dts.(i.e 0xff) + */ + u8 dummy; +#endif +}; + +struct rk322x_ddr_pctl { + u32 scfg; + u32 sctl; + u32 stat; + u32 intrstat; + u32 reserved0[(0x40 - 0x10) / 4]; + u32 mcmd; + u32 powctl; + u32 powstat; + u32 cmdtstat; + u32 cmdtstaten; + u32 reserved1[(0x60 - 0x54) / 4]; + u32 mrrcfg0; + u32 mrrstat0; + u32 mrrstat1; + u32 reserved2[(0x7c - 0x6c) / 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[(0xc0 - 0xb4) / 4]; + + u32 togcnt1u; + u32 tinit; + u32 trsth; + u32 togcnt100n; + u32 trefi; + u32 tmrd; + u32 trfc; + u32 trp; + u32 trtw; + u32 tal; + u32 tcl; + u32 tcwl; + u32 tras; + u32 trc; + u32 trcd; + u32 trrd; + u32 trtp; + u32 twr; + u32 twtr; + u32 texsr; + u32 txp; + u32 txpdll; + u32 tzqcs; + u32 tzqcsi; + u32 tdqs; + u32 tcksre; + u32 tcksrx; + u32 tcke; + u32 tmod; + u32 trstl; + u32 tzqcl; + u32 tmrr; + u32 tckesr; + u32 tdpd; + u32 tref_mem_ddr3; + u32 reserved5[(0x180 - 0x14c) / 4]; + u32 ecccfg; + u32 ecctst; + u32 eccclr; + u32 ecclog; + u32 reserved6[(0x200 - 0x190) / 4]; + 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; + /* dfi control registers */ + u32 dfitctrldelay; + u32 dfiodtcfg; + u32 dfiodtcfg1; + u32 dfiodtrankmap; + /* dfi write data registers */ + u32 dfitphywrdata; + u32 dfitphywrlat; + u32 reserved7[(0x260 - 0x258) / 4]; + u32 dfitrddataen; + u32 dfitphyrdlat; + u32 reserved8[(0x270 - 0x268) / 4]; + u32 dfitphyupdtype0; + u32 dfitphyupdtype1; + u32 dfitphyupdtype2; + u32 dfitphyupdtype3; + u32 dfitctrlupdmin; + u32 dfitctrlupdmax; + u32 dfitctrlupddly; + u32 reserved9; + u32 dfiupdcfg; + u32 dfitrefmski; + u32 dfitctrlupdi; + u32 reserved10[(0x2ac - 0x29c) / 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[(0x2f0 - 0x2e4) / 4]; + + u32 dfilpcfg0; + u32 reserved13[(0x300 - 0x2f4) / 4]; + 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[(0x3f8 - 0x340) / 4]; + u32 ipvr; + u32 iptr; +}; +check_member(rk322x_ddr_pctl, iptr, 0x03fc); + +struct rk322x_ddr_phy { + u32 ddrphy_reg[0x100]; +}; + +struct rk322x_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; + u32 trefi_mem_ddr3; +}; + +struct rk322x_phy_timing { + u32 mr[4]; + u32 mr11; + u32 bl; + u32 cl_al; +}; + +struct rk322x_msch_timings { + u32 ddrtiming; + u32 ddrmode; + u32 readlatency; + u32 activate; + u32 devtodev; +}; + +struct rk322x_service_sys { + u32 id_coreid; + u32 id_revisionid; + u32 ddrconf; + u32 ddrtiming; + u32 ddrmode; + u32 readlatency; + u32 activate; + u32 devtodev; +}; + +struct rk322x_base_params { + struct rk322x_msch_timings noc_timing; + u32 ddrconfig; + u32 ddr_freq; + u32 dramtype; + /* + * unused for rk322x + */ + u32 stride; + u32 odt; +}; + +/* PCT_DFISTCFG0 */ +#define DFI_INIT_START BIT(0) +#define DFI_DATA_BYTE_DISABLE_EN BIT(2) + +/* PCT_DFISTCFG1 */ +#define DFI_DRAM_CLK_SR_EN BIT(0) +#define DFI_DRAM_CLK_DPD_EN BIT(1) + +/* PCT_DFISTCFG2 */ +#define DFI_PARITY_INTR_EN BIT(0) +#define DFI_PARITY_EN BIT(1) + +/* PCT_DFILPCFG0 */ +#define TLP_RESP_TIME_SHIFT 16 +#define LP_SR_EN BIT(8) +#define LP_PD_EN BIT(0) + +/* PCT_DFITCTRLDELAY */ +#define TCTRL_DELAY_TIME_SHIFT 0 + +/* PCT_DFITPHYWRDATA */ +#define TPHY_WRDATA_TIME_SHIFT 0 + +/* PCT_DFITPHYRDLAT */ +#define TPHY_RDLAT_TIME_SHIFT 0 + +/* PCT_DFITDRAMCLKDIS */ +#define TDRAM_CLK_DIS_TIME_SHIFT 0 + +/* PCT_DFITDRAMCLKEN */ +#define TDRAM_CLK_EN_TIME_SHIFT 0 + +/* PCTL_DFIODTCFG */ +#define RANK0_ODT_WRITE_SEL BIT(3) +#define RANK1_ODT_WRITE_SEL BIT(11) + +/* PCTL_DFIODTCFG1 */ +#define ODT_LEN_BL8_W_SHIFT 16 + +/* PUBL_ACDLLCR */ +#define ACDLLCR_DLLDIS BIT(31) +#define ACDLLCR_DLLSRST BIT(30) + +/* PUBL_DXDLLCR */ +#define DXDLLCR_DLLDIS BIT(31) +#define DXDLLCR_DLLSRST BIT(30) + +/* PUBL_DLLGCR */ +#define DLLGCR_SBIAS BIT(30) + +/* PUBL_DXGCR */ +#define DQSRTT BIT(9) +#define DQRTT BIT(10) + +/* PIR */ +#define PIR_INIT BIT(0) +#define PIR_DLLSRST BIT(1) +#define PIR_DLLLOCK BIT(2) +#define PIR_ZCAL BIT(3) +#define PIR_ITMSRST BIT(4) +#define PIR_DRAMRST BIT(5) +#define PIR_DRAMINIT BIT(6) +#define PIR_QSTRN BIT(7) +#define PIR_RVTRN BIT(8) +#define PIR_ICPC BIT(16) +#define PIR_DLLBYP BIT(17) +#define PIR_CTLDINIT BIT(18) +#define PIR_CLRSR BIT(28) +#define PIR_LOCKBYP BIT(29) +#define PIR_ZCALBYP BIT(30) +#define PIR_INITBYP BIT(31) + +/* PGCR */ +#define PGCR_DFTLMT_SHIFT 3 +#define PGCR_DFTCMP_SHIFT 2 +#define PGCR_DQSCFG_SHIFT 1 +#define PGCR_ITMDMD_SHIFT 0 + +/* PGSR */ +#define PGSR_IDONE BIT(0) +#define PGSR_DLDONE BIT(1) +#define PGSR_ZCDONE BIT(2) +#define PGSR_DIDONE BIT(3) +#define PGSR_DTDONE BIT(4) +#define PGSR_DTERR BIT(5) +#define PGSR_DTIERR BIT(6) +#define PGSR_DFTERR BIT(7) +#define PGSR_RVERR BIT(8) +#define PGSR_RVEIRR BIT(9) + +/* PTR0 */ +#define PRT_ITMSRST_SHIFT 18 +#define PRT_DLLLOCK_SHIFT 6 +#define PRT_DLLSRST_SHIFT 0 + +/* PTR1 */ +#define PRT_DINIT0_SHIFT 0 +#define PRT_DINIT1_SHIFT 19 + +/* PTR2 */ +#define PRT_DINIT2_SHIFT 0 +#define PRT_DINIT3_SHIFT 17 + +/* DCR */ +#define DDRMD_LPDDR 0 +#define DDRMD_DDR 1 +#define DDRMD_DDR2 2 +#define DDRMD_DDR3 3 +#define DDRMD_LPDDR2_LPDDR3 4 +#define DDRMD_MASK 7 +#define DDRMD_SHIFT 0 +#define PDQ_MASK 7 +#define PDQ_SHIFT 4 + +/* DXCCR */ +#define DQSNRES_MASK 0xf +#define DQSNRES_SHIFT 8 +#define DQSRES_MASK 0xf +#define DQSRES_SHIFT 4 + +/* DTPR */ +#define TDQSCKMAX_SHIFT 27 +#define TDQSCKMAX_MASK 7 +#define TDQSCK_SHIFT 24 +#define TDQSCK_MASK 7 + +/* DSGCR */ +#define DQSGX_SHIFT 5 +#define DQSGX_MASK 7 +#define DQSGE_SHIFT 8 +#define DQSGE_MASK 7 + +/* SCTL */ +#define INIT_STATE 0 +#define CFG_STATE 1 +#define GO_STATE 2 +#define SLEEP_STATE 3 +#define WAKEUP_STATE 4 + +/* STAT */ +#define LP_TRIG_SHIFT 4 +#define LP_TRIG_MASK 7 +#define PCTL_STAT_MASK 7 +#define INIT_MEM 0 +#define CONFIG 1 +#define CONFIG_REQ 2 +#define ACCESS 3 +#define ACCESS_REQ 4 +#define LOW_POWER 5 +#define LOW_POWER_ENTRY_REQ 6 +#define LOW_POWER_EXIT_REQ 7 + +/* ZQCR*/ +#define PD_OUTPUT_SHIFT 0 +#define PU_OUTPUT_SHIFT 5 +#define PD_ONDIE_SHIFT 10 +#define PU_ONDIE_SHIFT 15 +#define ZDEN_SHIFT 28 + +/* DDLGCR */ +#define SBIAS_BYPASS BIT(23) + +/* MCFG */ +#define MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT 24 +#define PD_IDLE_SHIFT 8 +#define MDDR_EN (2 << 22) +#define LPDDR2_EN (3 << 22) +#define LPDDR3_EN (1 << 22) +#define DDR2_EN (0 << 5) +#define DDR3_EN (1 << 5) +#define LPDDR2_S2 (0 << 6) +#define LPDDR2_S4 (1 << 6) +#define MDDR_LPDDR2_BL_2 (0 << 20) +#define MDDR_LPDDR2_BL_4 (1 << 20) +#define MDDR_LPDDR2_BL_8 (2 << 20) +#define MDDR_LPDDR2_BL_16 (3 << 20) +#define DDR2_DDR3_BL_4 0 +#define DDR2_DDR3_BL_8 1 +#define TFAW_SHIFT 18 +#define PD_EXIT_SLOW (0 << 17) +#define PD_EXIT_FAST (1 << 17) +#define PD_TYPE_SHIFT 16 +#define BURSTLENGTH_SHIFT 20 + +/* POWCTL */ +#define POWER_UP_START BIT(0) + +/* POWSTAT */ +#define POWER_UP_DONE BIT(0) + +/* MCMD */ +enum { + DESELECT_CMD = 0, + PREA_CMD, + REF_CMD, + MRS_CMD, + ZQCS_CMD, + ZQCL_CMD, + RSTL_CMD, + MRR_CMD = 8, + DPDE_CMD, +}; + +#define BANK_ADDR_MASK 7 +#define BANK_ADDR_SHIFT 17 +#define CMD_ADDR_MASK 0x1fff +#define CMD_ADDR_SHIFT 4 + +#define LPDDR23_MA_SHIFT 4 +#define LPDDR23_MA_MASK 0xff +#define LPDDR23_OP_SHIFT 12 +#define LPDDR23_OP_MASK 0xff + +#define START_CMD (1u << 31) + +/* DDRPHY REG */ +enum { + /* DDRPHY_REG0 */ + SOFT_RESET_MASK = 3, + SOFT_DERESET_ANALOG = 1 << 2, + SOFT_DERESET_DIGITAL = 1 << 3, + SOFT_RESET_SHIFT = 2, + + /* DDRPHY REG1 */ + PHY_DDR3 = 0, + PHY_DDR2 = 1, + PHY_LPDDR3 = 2, + PHY_LPDDR2 = 3, + + PHT_BL_8 = 1 << 2, + PHY_BL_4 = 0 << 2, + + /* DDRPHY_REG2 */ + MEMORY_SELECT_DDR3 = 0 << 0, + MEMORY_SELECT_LPDDR3 = 2 << 0, + MEMORY_SELECT_LPDDR2 = 3 << 0, + DQS_SQU_CAL_SEL_CS0_CS1 = 0 << 4, + DQS_SQU_CAL_SEL_CS1 = 1 << 4, + DQS_SQU_CAL_SEL_CS0 = 2 << 4, + DQS_SQU_CAL_NORMAL_MODE = 0 << 1, + DQS_SQU_CAL_BYPASS_MODE = 1 << 1, + DQS_SQU_CAL_START = 1 << 0, + DQS_SQU_NO_CAL = 0 << 0, +}; + +/* CK pull up/down driver strength control */ +enum { + PHY_RON_RTT_DISABLE = 0, + PHY_RON_RTT_451OHM = 1, + PHY_RON_RTT_225OHM, + PHY_RON_RTT_150OHM, + PHY_RON_RTT_112OHM, + PHY_RON_RTT_90OHM, + PHY_RON_RTT_75OHM, + PHY_RON_RTT_64OHM = 7, + + PHY_RON_RTT_56OHM = 16, + PHY_RON_RTT_50OHM, + PHY_RON_RTT_45OHM, + PHY_RON_RTT_41OHM, + PHY_RON_RTT_37OHM, + PHY_RON_RTT_34OHM, + PHY_RON_RTT_33OHM, + PHY_RON_RTT_30OHM = 23, + + PHY_RON_RTT_28OHM = 24, + PHY_RON_RTT_26OHM, + PHY_RON_RTT_25OHM, + PHY_RON_RTT_23OHM, + PHY_RON_RTT_22OHM, + PHY_RON_RTT_21OHM, + PHY_RON_RTT_20OHM, + PHY_RON_RTT_19OHM = 31, +}; + +/* DQS squelch DLL delay */ +enum { + DQS_DLL_NO_DELAY = 0, + DQS_DLL_22P5_DELAY, + DQS_DLL_45_DELAY, + DQS_DLL_67P5_DELAY, + DQS_DLL_90_DELAY, + DQS_DLL_112P5_DELAY, + DQS_DLL_135_DELAY, + DQS_DLL_157P5_DELAY, +}; + +/* GRF_SOC_CON0 */ +#define GRF_DDR_16BIT_EN (((0x1 << 0) << 16) | (0x1 << 0)) +#define GRF_DDR_32BIT_EN (((0x1 << 0) << 16) | (0x0 << 0)) +#define GRF_MSCH_NOC_16BIT_EN (((0x1 << 7) << 16) | (0x1 << 7)) +#define GRF_MSCH_NOC_32BIT_EN (((0x1 << 7) << 16) | (0x0 << 7)) + +#define GRF_DDRPHY_BUFFEREN_CORE_EN (((0x1 << 8) << 16) | (0x0 << 8)) +#define GRF_DDRPHY_BUFFEREN_CORE_DIS (((0x1 << 8) << 16) | (0x1 << 8)) + +#define GRF_DDR3_EN (((0x1 << 6) << 16) | (0x1 << 6)) +#define GRF_LPDDR2_3_EN (((0x1 << 6) << 16) | (0x0 << 6)) + +#define PHY_DRV_ODT_SET(n) (((n) << 4) | (n)) +#define DDR3_DLL_RESET (1 << 8) + +#endif /* _ASM_ARCH_SDRAM_RK322X_H */ -- cgit v1.2.3 From ffd1cd67daf322a9c450c6b2d7e2c3413aaa830a Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Wed, 27 Sep 2017 16:38:23 +0800 Subject: rockchip: dts: rk3229: remove dram channel info The dram channel info will be auto detect by the driver, we do not need it. Signed-off-by: Kever Yang --- arch/arm/dts/rk3229-evb.dts | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/dts/rk3229-evb.dts b/arch/arm/dts/rk3229-evb.dts index 64f1c2d7dac..ae0b0a4b8e3 100644 --- a/arch/arm/dts/rk3229-evb.dts +++ b/arch/arm/dts/rk3229-evb.dts @@ -40,7 +40,6 @@ }; &dmc { - rockchip,sdram-channel = /bits/ 8 <1 10 3 2 1 0 15 15>; rockchip,pctl-timing = <0x96 0xC8 0x1F3 0xF 0x8000004D 0x4 0x4E 0x6 0x3 0x0 0x6 0x5 0xC 0x10 0x6 0x4 0x4 0x5 0x4 0x200 0x3 0xA 0x40 0x0 0x1 -- cgit v1.2.3 From cbe18f10e6943db628e779da03dad97a93c627f3 Mon Sep 17 00:00:00 2001 From: Philipp Tomsich Date: Mon, 11 Sep 2017 12:48:12 +0200 Subject: rockchip: rk3399: spl: convert to using BOOT_DEVICE_BOOTROM Instead of directly calling into the back-to-bootrom code, the RK3399 common SPL implementation now uses BOOT_DEVICE_BOOTROM to trigger a transfer back into the bootrom. With this factored out, the spl_board_init function can not be customised for each RK3399 board. Signed-off-by: Philipp Tomsich Reviewed-by: Simon Glass --- arch/arm/mach-rockchip/rk3399-board-spl.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-rockchip/rk3399-board-spl.c b/arch/arm/mach-rockchip/rk3399-board-spl.c index 34061564478..1c39d9b04b5 100644 --- a/arch/arm/mach-rockchip/rk3399-board-spl.c +++ b/arch/arm/mach-rockchip/rk3399-board-spl.c @@ -1,10 +1,12 @@ /* * (C) Copyright 2016 Rockchip Electronics Co., Ltd + * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH * * SPDX-License-Identifier: GPL-2.0+ */ #include +#include #include #include #include @@ -19,9 +21,19 @@ DECLARE_GLOBAL_DATA_PTR; +void board_return_to_bootrom(void) +{ + back_to_bootrom(); +} + u32 spl_boot_device(void) { - return BOOT_DEVICE_MMC1; + u32 boot_device = BOOT_DEVICE_MMC1; + + if (CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)) + return BOOT_DEVICE_BOOTROM; + + return boot_device; } u32 spl_boot_mode(const u32 boot_device) @@ -156,10 +168,6 @@ void spl_board_init(void) } preloader_console_init(); -#if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) - back_to_bootrom(); -#endif - return; err: printf("spl_board_init: Error %d\n", ret); -- cgit v1.2.3 From 04e97e48d049118218f48043802c9b05ff3efe62 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Wed, 27 Sep 2017 17:02:58 +0800 Subject: rockchip: rk3036: fix grf macro define Some of macros definition are not correct, fix them according to TRM. Signed-off-by: Kever Yang Reviewed-by: Philipp Tomsich --- arch/arm/include/asm/arch-rockchip/grf_rk3036.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3036.h b/arch/arm/include/asm/arch-rockchip/grf_rk3036.h index 7625f249bd9..d995b7db14c 100644 --- a/arch/arm/include/asm/arch-rockchip/grf_rk3036.h +++ b/arch/arm/include/asm/arch-rockchip/grf_rk3036.h @@ -209,10 +209,10 @@ enum { GPIO1A3_I2S_LRCKTX, GPIO1A2_SHIFT = 4, - GPIO1A2_MASK = 6 << GPIO1A2_SHIFT, + GPIO1A2_MASK = 3 << GPIO1A2_SHIFT, GPIO1A2_GPIO = 0, GPIO1A2_I2S_LRCKRX, - GPIO1A2_I2S_PWM1_0, + GPIO1A2_PWM1_0, GPIO1A1_SHIFT = 2, GPIO1A1_MASK = 1 << GPIO1A1_SHIFT, -- cgit v1.2.3 From d9a7dcf5b8da5460a08305cdc9452f4e62dd34e5 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Wed, 27 Sep 2017 23:03:10 +0530 Subject: armv7: Move L2CTLR read/write to common L2CTLR read/write functions are common to armv7 so, move them in to include/asm/armv7.h and use them where ever it need. Cc: Tom Warren Signed-off-by: Jagan Teki Acked-by: Philipp Tomsich Reviewed-by: Philipp Tomsich [Backed out the change to arch/arm/mach-tegra/cache.c:] Signed-off-by: Philipp Tomsich --- arch/arm/include/asm/armv7.h | 21 +++++++++++++++++++++ arch/arm/mach-rockchip/rk3288-board-spl.c | 22 +--------------------- 2 files changed, 22 insertions(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/armv7.h b/arch/arm/include/asm/armv7.h index a20702e612b..efc515eb334 100644 --- a/arch/arm/include/asm/armv7.h +++ b/arch/arm/include/asm/armv7.h @@ -61,6 +61,27 @@ #include #include +/* 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(); +} + /* * Workaround for ARM errata # 798870 * Set L2ACTLR[7] to reissue any memory transaction in the L2 that has been diff --git a/arch/arm/mach-rockchip/rk3288-board-spl.c b/arch/arm/mach-rockchip/rk3288-board-spl.c index 6b7bf85d8d3..8a1066ccf88 100644 --- a/arch/arm/mach-rockchip/rk3288-board-spl.c +++ b/arch/arm/mach-rockchip/rk3288-board-spl.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -80,27 +81,6 @@ u32 spl_boot_mode(const u32 boot_device) 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; -- cgit v1.2.3 From a982d5156db0587f5118a118c7e9f18d4c70891d Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Wed, 27 Sep 2017 23:03:11 +0530 Subject: armv7: rk3288: Move configure_l2ctlr to common configure_l2ctlr will be shared between SPL and TPL so move them into asm/arch/sys_proto.h Signed-off-by: Jagan Teki Acked-by: Philipp Tomsich Reviewed-by: Philipp Tomsich --- arch/arm/include/asm/arch-rockchip/sys_proto.h | 23 +++++++++++++++++++++++ arch/arm/mach-rockchip/rk3288-board-spl.c | 21 +-------------------- 2 files changed, 24 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-rockchip/sys_proto.h b/arch/arm/include/asm/arch-rockchip/sys_proto.h index 35423e1ba07..e428d59336a 100644 --- a/arch/arm/include/asm/arch-rockchip/sys_proto.h +++ b/arch/arm/include/asm/arch-rockchip/sys_proto.h @@ -7,4 +7,27 @@ #ifndef _ASM_ARCH_SYS_PROTO_H #define _ASM_ARCH_SYS_PROTO_H +#ifdef CONFIG_ROCKCHIP_RK3288 +#include + +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); +} +#endif /* CONFIG_ROCKCHIP_RK3288 */ + #endif /* _ASM_ARCH_SYS_PROTO_H */ diff --git a/arch/arm/mach-rockchip/rk3288-board-spl.c b/arch/arm/mach-rockchip/rk3288-board-spl.c index 8a1066ccf88..23af653454e 100644 --- a/arch/arm/mach-rockchip/rk3288-board-spl.c +++ b/arch/arm/mach-rockchip/rk3288-board-spl.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -21,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -81,25 +81,6 @@ u32 spl_boot_mode(const u32 boot_device) return MMCSD_MODE_RAW; } -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); -} - #ifdef CONFIG_SPL_MMC_SUPPORT static int configure_emmc(struct udevice *pinctrl) { -- cgit v1.2.3 From 532cb7f5ada0cc3779c33606d760ec99f6aa847a Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Wed, 27 Sep 2017 23:03:12 +0530 Subject: rk3288: vyasa: Add TPL support Since the size of SPL can't be exceeded 0x8000 bytes in RK3288, it is not possible add new SPL features like Falcon mode or etc. So add TPL stage so-that adding new features to SPL is possible. - TPL: DRAM init, clocks - SPL: MMC, falcon, etc Signed-off-by: Jagan Teki Reviewed-by: Philipp Tomsich Acked-by: Philipp Tomsich --- arch/arm/mach-rockchip/Makefile | 1 + arch/arm/mach-rockchip/rk3288-board-spl.c | 3 ++ arch/arm/mach-rockchip/rk3288-board-tpl.c | 84 +++++++++++++++++++++++++++++++ arch/arm/mach-rockchip/rk3288/Kconfig | 16 ++++++ 4 files changed, 104 insertions(+) create mode 100644 arch/arm/mach-rockchip/rk3288-board-tpl.c (limited to 'arch') diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile index 79e9704a2c5..daafc8de6a8 100644 --- a/arch/arm/mach-rockchip/Makefile +++ b/arch/arm/mach-rockchip/Makefile @@ -12,6 +12,7 @@ obj-spl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o save_boot_param.o obj-tpl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o save_boot_param.o obj-tpl-$(CONFIG_ROCKCHIP_RK3188) += rk3188-board-tpl.o +obj-tpl-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-tpl.o obj-tpl-$(CONFIG_ROCKCHIP_RK3368) += rk3368-board-tpl.o obj-spl-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board-spl.o diff --git a/arch/arm/mach-rockchip/rk3288-board-spl.c b/arch/arm/mach-rockchip/rk3288-board-spl.c index 23af653454e..5239cbc37c4 100644 --- a/arch/arm/mach-rockchip/rk3288-board-spl.c +++ b/arch/arm/mach-rockchip/rk3288-board-spl.c @@ -204,12 +204,15 @@ void board_init_f(ulong dummy) } #endif +#if !defined(CONFIG_SUPPORT_TPL) debug("\nspl:init dram\n"); ret = uclass_get_device(UCLASS_RAM, 0, &dev); if (ret) { debug("DRAM init failed: %d\n", ret); return; } +#endif + #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT) back_to_bootrom(); #endif diff --git a/arch/arm/mach-rockchip/rk3288-board-tpl.c b/arch/arm/mach-rockchip/rk3288-board-tpl.c new file mode 100644 index 00000000000..3d08b5b6d8d --- /dev/null +++ b/arch/arm/mach-rockchip/rk3288-board-tpl.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2017 Amarula Solutions + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define GRF_BASE 0xff770000 +void board_init_f(ulong dummy) +{ + struct udevice *dev; + int ret; + + /* Example code showing how to enable the debug UART on RK3288 */ + /* Enable early UART on the RK3288 */ + 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(); + + ret = spl_early_init(); + if (ret) { + debug("spl_early_init() failed: %d\n", ret); + hang(); + } + + rockchip_timer_init(); + configure_l2ctlr(); + + ret = rockchip_get_clk(&dev); + if (ret) { + debug("CLK init failed: %d\n", ret); + return; + } + + ret = uclass_get_device(UCLASS_RAM, 0, &dev); + if (ret) { + debug("DRAM init failed: %d\n", ret); + return; + } +} + +void board_return_to_bootrom(void) +{ + back_to_bootrom(); +} + +u32 spl_boot_device(void) +{ + return BOOT_DEVICE_BOOTROM; +} + +void spl_board_init(void) +{ + puts("\nU-Boot TPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \ + U_BOOT_TIME ")\n"); +} diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig index 4ad29400694..6beb26fd7a6 100644 --- a/arch/arm/mach-rockchip/rk3288/Kconfig +++ b/arch/arm/mach-rockchip/rk3288/Kconfig @@ -87,6 +87,22 @@ config TARGET_POPMETAL_RK3288 config TARGET_VYASA_RK3288 bool "Vyasa-RK3288" select BOARD_LATE_INIT + select TPL + select SUPPORT_TPL + select TPL_DM + select TPL_REGMAP + select TPL_SYSCON + select TPL_CLK + select TPL_RAM + select TPL_OF_PLATDATA + select TPL_OF_CONTROL + select TPL_BOOTROM_SUPPORT + select TPL_NEEDS_SEPARATE_TEXT_BASE if SPL + select ROCKCHIP_BROM_HELPER + select TPL_DRIVERS_MISC_SUPPORT + select TPL_LIBCOMMON_SUPPORT + select TPL_LIBGENERIC_SUPPORT + select TPL_SERIAL_SUPPORT help Vyasa is a RK3288-based development board with 2 USB ports, HDMI, VGA, micro-SD card, audio, WiFi and Gigabit Ethernet, It -- cgit v1.2.3 From f9674f5eec984e3ae8442c7b2b7bde667e108e55 Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Wed, 27 Sep 2017 15:23:38 +0800 Subject: rockchip: dts: rk3328-evb: add i2c1 and rk805 nodes add i2c1 and rk805 nodes to support rk805 init setting. Signed-off-by: Elaine Zhang Signed-off-by: Kever Yang Acked-by: Philipp Tomsich Reviewed-by: Philipp Tomsich --- arch/arm/dts/rk3328-evb.dts | 118 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) (limited to 'arch') diff --git a/arch/arm/dts/rk3328-evb.dts b/arch/arm/dts/rk3328-evb.dts index df44ccbdb02..3dd9d819614 100644 --- a/arch/arm/dts/rk3328-evb.dts +++ b/arch/arm/dts/rk3328-evb.dts @@ -91,3 +91,121 @@ vbus-supply = <&vcc5v0_host_xhci>; status = "okay"; }; + +&i2c1 { + clock-frequency = <400000>; + i2c-scl-rising-time-ns = <168>; + i2c-scl-falling-time-ns = <4>; + status = "okay"; + + rk805: pmic@18 { + compatible = "rockchip,rk805"; + status = "okay"; + reg = <0x18>; + interrupt-parent = <&gpio2>; + interrupts = <6 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>; + rockchip,system-power-controller; + wakeup-source; + gpio-controller; + #gpio-cells = <2>; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk805-clkout2"; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1450000>; + regulator-ramp-delay = <6001>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1450000>; + regulator-ramp-delay = <6001>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_io: DCDC_REG4 { + regulator-name = "vcc_io"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vdd_18: LDO_REG1 { + regulator-name = "vdd_18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_18emmc: LDO_REG2 { + regulator-name = "vcc_18emmc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_10: LDO_REG3 { + regulator-name = "vdd_10"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + }; + }; +}; + +&pinctrl { + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; /* gpio2_a6 */ + }; + }; +}; + -- cgit v1.2.3 From 4a18729726144678c090ad0e3c26f4829b1c4aeb Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Tue, 22 Aug 2017 15:34:58 +0800 Subject: rockchip: rk322x: update the sysreg number for boot mode The boot mode for rk322x is stored in sysreg 0, update it. Signed-off-by: Kever Yang Acked-by: Philipp Tomsich Reviewed-by: Philipp Tomsich --- arch/arm/mach-rockchip/rk322x-board.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-rockchip/rk322x-board.c b/arch/arm/mach-rockchip/rk322x-board.c index dcd8cf805fe..d44311457a4 100644 --- a/arch/arm/mach-rockchip/rk322x-board.c +++ b/arch/arm/mach-rockchip/rk322x-board.c @@ -21,12 +21,12 @@ DECLARE_GLOBAL_DATA_PTR; static void setup_boot_mode(void) { struct rk322x_grf *const grf = (void *)GRF_BASE; - int boot_mode = readl(&grf->os_reg[4]); + int boot_mode = readl(&grf->os_reg[0]); debug("boot mode %x.\n", boot_mode); /* Clear boot mode */ - writel(BOOT_NORMAL, &grf->os_reg[4]); + writel(BOOT_NORMAL, &grf->os_reg[0]); switch (boot_mode) { case BOOT_FASTBOOT: -- cgit v1.2.3 From fb7406469c012092d652741f103b0993103cf8e3 Mon Sep 17 00:00:00 2001 From: Philipp Tomsich Date: Fri, 29 Sep 2017 19:27:54 +0200 Subject: rockchip: rk3399: make spl_board_init board-specific The later-stage spl_board_init (as opposed to board_init_f) should set up board-specific details: these differ between the EVB-RK3399 and the RK3399-Q7 (Puma). This moves spl_board_init back into the individual boards and removes the unneeded functionality from Puma. Signed-off-by: Philipp Tomsich --- arch/arm/mach-rockchip/rk3399-board-spl.c | 27 --------------------------- 1 file changed, 27 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-rockchip/rk3399-board-spl.c b/arch/arm/mach-rockchip/rk3399-board-spl.c index 1c39d9b04b5..8e38ef19a3d 100644 --- a/arch/arm/mach-rockchip/rk3399-board-spl.c +++ b/arch/arm/mach-rockchip/rk3399-board-spl.c @@ -149,33 +149,6 @@ void board_init_f(ulong dummy) } } -void spl_board_init(void) -{ - struct udevice *pinctrl; - int ret; - - ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl); - if (ret) { - debug("%s: Cannot find pinctrl device\n", __func__); - goto err; - } - - /* Enable debug UART */ - ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_UART_DBG); - if (ret) { - debug("%s: Failed to set up console UART\n", __func__); - goto err; - } - - preloader_console_init(); - return; -err: - printf("spl_board_init: Error %d\n", ret); - - /* No way to report error here */ - hang(); -} - #ifdef CONFIG_SPL_LOAD_FIT int board_fit_config_name_match(const char *name) { -- cgit v1.2.3 From 3b4f87735d093463e3b227a07a62996fc0b47b53 Mon Sep 17 00:00:00 2001 From: Philipp Tomsich Date: Fri, 29 Sep 2017 19:27:55 +0200 Subject: rockchip: bootrom: add definitions to retrieve BROM boot-source The Rockchip BROM allows reading where it booted from from SRAM. This adds the necessary definitions (as received from Kever) for the location of this information in the RK3399's SRAM and naming for the constants used. Signed-off-by: Philipp Tomsich Reviewed-by: Simon Glass --- arch/arm/include/asm/arch-rockchip/bootrom.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-rockchip/bootrom.h b/arch/arm/include/asm/arch-rockchip/bootrom.h index 92eb8783a3a..169cc5e50b0 100644 --- a/arch/arm/include/asm/arch-rockchip/bootrom.h +++ b/arch/arm/include/asm/arch-rockchip/bootrom.h @@ -24,4 +24,22 @@ void back_to_bootrom(void); */ void _back_to_bootrom_s(void); +/** + * Boot-device identifiers as used by the BROM + */ +enum { + BROM_BOOTSOURCE_NAND = 1, + BROM_BOOTSOURCE_EMMC = 2, + BROM_BOOTSOURCE_SPINOR = 3, + BROM_BOOTSOURCE_SPINAND = 4, + BROM_BOOTSOURCE_SD = 5, + BROM_BOOTSOURCE_USB = 10, + BROM_LAST_BOOTSOURCE = BROM_BOOTSOURCE_USB +}; + +/** + * Locations of the boot-device identifier in SRAM + */ +#define RK3399_BROM_BOOTSOURCE_ID_ADDR 0xff8c0010 + #endif -- cgit v1.2.3 From dbad01cab576c12852931c6bf22361b5234c506a Mon Sep 17 00:00:00 2001 From: Philipp Tomsich Date: Fri, 29 Sep 2017 19:27:56 +0200 Subject: rockchip: spl: add documentation for spl_node_to_boot_device() In the expectation that the spl-boot-order code will eventually gain use outside of mach-rockchip: let's add documentation on the spl_node_to_boot_device() function, which is likely to become a publicly exported function. Signed-off-by: Philipp Tomsich Reviewed-by: Simon Glass --- arch/arm/mach-rockchip/spl-boot-order.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-rockchip/spl-boot-order.c b/arch/arm/mach-rockchip/spl-boot-order.c index 4f78c727209..0bb9a73a8ab 100644 --- a/arch/arm/mach-rockchip/spl-boot-order.c +++ b/arch/arm/mach-rockchip/spl-boot-order.c @@ -10,6 +10,25 @@ #include #if CONFIG_IS_ENABLED(OF_CONTROL) +/** + * spl_node_to_boot_device() - maps from a DT-node to a SPL boot device + * @node: of_offset of the node + * + * The SPL framework uses BOOT_DEVICE_... constants to identify its boot + * sources. These may take on a device-specific meaning, depending on + * what nodes are enabled in a DTS (e.g. BOOT_DEVICE_MMC1 may refer to + * different controllers/block-devices, depending on which SD/MMC controllers + * are enabled in any given DTS). This function maps from a DT-node back + * onto a BOOT_DEVICE_... constant, considering the currently active devices. + * + * Returns + * -ENOENT, if no device matching the node could be found + * -ENOSYS, if the device matching the node can not be mapped onto a + * SPL boot device (e.g. the third MMC device) + * -1, for unspecified failures + * a positive integer (from the BOOT_DEVICE_... family) on succes. + */ + static int spl_node_to_boot_device(int node) { struct udevice *parent; -- cgit v1.2.3 From 80e9f88e67398ae65c89af3bace59e7e14debd33 Mon Sep 17 00:00:00 2001 From: Philipp Tomsich Date: Fri, 29 Sep 2017 19:27:57 +0200 Subject: rockchip: spl: support a 'same-as-spl'-specifier in the spl-boot-order It is often desirable to configure the spl-boot-order (i.e. the order that SPL probes devices to find the FIT image containing a full U-Boot) such that it contains 'the same device the SPL stage was booted from' early on. To support this, we introduce the 'same-as-spl' specifier for the spl-boot-order property. This commit adds: - documentation for the new board_spl_was_booted_from() function that individual SoCs/boards should provide, if they can determine where the SPL was booted from - implements the new board_spl_was_booted_from() stub function - adds support for handling the 'same-as-spl' specifier and calling into the per-SoC/per-board support code. This also updates the documentation for the 'u-boot,spl-boot-order' property. Signed-off-by: Philipp Tomsich Reviewed-by: Simon Glass --- arch/arm/mach-rockchip/spl-boot-order.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-rockchip/spl-boot-order.c b/arch/arm/mach-rockchip/spl-boot-order.c index 0bb9a73a8ab..843998dfdcb 100644 --- a/arch/arm/mach-rockchip/spl-boot-order.c +++ b/arch/arm/mach-rockchip/spl-boot-order.c @@ -76,6 +76,24 @@ static int spl_node_to_boot_device(int node) return -1; } +/** + * board_spl_was_booted_from() - retrieves the of-path the SPL was loaded from + * + * To support a 'same-as-spl' specification in the search-order for the next + * stage, we need a SoC- or board-specific way to handshake with what 'came + * before us' (either a BROM or TPL stage) and map the info retrieved onto + * a OF path. + * + * Returns + * NULL, on failure or if the device could not be identified + * a of_path (a string), on success + */ +__weak const char *board_spl_was_booted_from(void) +{ + debug("%s: no support for 'same-as-spl' for this board\n", __func__); + return NULL; +} + void board_boot_order(u32 *spl_boot_list) { const void *blob = gd->fdt_blob; @@ -97,8 +115,17 @@ void board_boot_order(u32 *spl_boot_list) (conf = fdt_stringlist_get(blob, chosen_node, "u-boot,spl-boot-order", elem, NULL)); elem++) { + const char *alias; + + /* Handle the case of 'same device the SPL was loaded from' */ + if (strncmp(conf, "same-as-spl", 11) == 0) { + conf = board_spl_was_booted_from(); + if (!conf) + continue; + } + /* First check if the list element is an alias */ - const char *alias = fdt_get_alias(blob, conf); + alias = fdt_get_alias(blob, conf); if (alias) conf = alias; -- cgit v1.2.3 From c55addd36008e82cd0081c591a68a1f1667346e7 Mon Sep 17 00:00:00 2001 From: Philipp Tomsich Date: Fri, 29 Sep 2017 19:27:58 +0200 Subject: rockchip: spl: rk3399: implement chip-specific board_spl_was_booted_from() To support the new "same-as-spl" specifier in the boot-order on the RK3399, this implements the chip-specific mapping from the information obtainable from the BROM to a OF path name. Signed-off-by: Philipp Tomsich Reviewed-by: Simon Glass --- arch/arm/mach-rockchip/rk3399-board-spl.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-rockchip/rk3399-board-spl.c b/arch/arm/mach-rockchip/rk3399-board-spl.c index 8e38ef19a3d..9c20f56dc94 100644 --- a/arch/arm/mach-rockchip/rk3399-board-spl.c +++ b/arch/arm/mach-rockchip/rk3399-board-spl.c @@ -26,6 +26,30 @@ void board_return_to_bootrom(void) back_to_bootrom(); } +static const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = { + [BROM_BOOTSOURCE_EMMC] = "/sdhci@fe330000", + [BROM_BOOTSOURCE_SPINOR] = "/spi@ff1d0000", + [BROM_BOOTSOURCE_SD] = "/dwmmc@fe320000", +}; + +const char *board_spl_was_booted_from(void) +{ + u32 bootdevice_brom_id = readl(RK3399_BROM_BOOTSOURCE_ID_ADDR); + const char *bootdevice_ofpath = NULL; + + if (bootdevice_brom_id < ARRAY_SIZE(boot_devices)) + bootdevice_ofpath = boot_devices[bootdevice_brom_id]; + + if (bootdevice_ofpath) + debug("%s: brom_bootdevice_id %x maps to '%s'\n", + __func__, bootdevice_brom_id, bootdevice_ofpath); + else + debug("%s: failed to resolve brom_bootdevice_id %x\n", + __func__, bootdevice_brom_id); + + return bootdevice_ofpath; +} + u32 spl_boot_device(void) { u32 boot_device = BOOT_DEVICE_MMC1; -- cgit v1.2.3 From 775bd78a1126497f57bdab8be2419a063cf12111 Mon Sep 17 00:00:00 2001 From: Philipp Tomsich Date: Fri, 29 Sep 2017 19:27:59 +0200 Subject: rockchip: dts: rk3399-puma: add 'same-as-spl' to the front of the boot-order In the general case, we want to continue booting the full U-Boot (contained in a discoverable FIT image) from the same device the SPL stage was loaded from. This prepends the 'same-as-spl' specifier to our configurable boot-order to make this the default behaviour. Signed-off-by: Philipp Tomsich Reviewed-by: Simon Glass --- arch/arm/dts/rk3399-puma.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/dts/rk3399-puma.dtsi b/arch/arm/dts/rk3399-puma.dtsi index a04878e223c..f95c68e9f6e 100644 --- a/arch/arm/dts/rk3399-puma.dtsi +++ b/arch/arm/dts/rk3399-puma.dtsi @@ -20,7 +20,8 @@ chosen { stdout-path = "serial0:115200n8"; - u-boot,spl-boot-order = &spiflash, &sdhci, &sdmmc; + u-boot,spl-boot-order = \ + "same-as-spl", &spiflash, &sdhci, &sdmmc; }; aliases { -- cgit v1.2.3 From 482cf22333dbfb7c706d6a7ec1ffbfa5409cc6a3 Mon Sep 17 00:00:00 2001 From: Philipp Tomsich Date: Fri, 29 Sep 2017 19:28:01 +0200 Subject: rockchip: rk3399-puma: add boot-on regulator to override BIOS_DISABLE The (Qseven) BIOS_DISABLE signal on the RK3399-Q7 (Puma) keeps the eMMC and SPI in reset initially and we need to write a GPIO to turn them on before continuing the boot-up. This adds the DTS entries for the additional regulator and makes pinctrl and gpio3 available during SPL. It also adds a hook to the spl_board_init() to ensure that the regulator gets probed and enabled. Signed-off-by: Philipp Tomsich Reviewed-by: Simon Glass --- arch/arm/dts/rk3399-puma.dtsi | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/dts/rk3399-puma.dtsi b/arch/arm/dts/rk3399-puma.dtsi index f95c68e9f6e..65ab3801391 100644 --- a/arch/arm/dts/rk3399-puma.dtsi +++ b/arch/arm/dts/rk3399-puma.dtsi @@ -101,6 +101,24 @@ regulator-max-microvolt = <3300000>; }; + /* + * The Qseven BIOS_DISABLE signal on the RK3399-Q7 keeps the on-module + * eMMC and SPI flash powered-down initially (in fact it keeps the + * reset signal asserted). Even though it is an enable signal, we + * model this as a regulator. + */ + bios_enable: bios_enable { + compatible = "regulator-fixed"; + u-boot,dm-pre-reloc; + regulator-name = "bios_enable"; + enable-active-low; + gpio = <&gpio3 29 GPIO_ACTIVE_HIGH>; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + vccadc_ref: vccadc-ref { compatible = "regulator-fixed"; regulator-name = "vcc1v8_sys"; @@ -459,7 +477,7 @@ }; &pcie_phy { - status = "okay"; + status = "okay"; }; &pmu_io_domains { @@ -486,7 +504,7 @@ }; &sdmmc { - u-boot,dm-pre-reloc; + u-boot,dm-pre-reloc; clock-frequency = <150000000>; clock-freq-min-max = <100000 150000000>; supports-sd; @@ -533,10 +551,15 @@ status = "okay"; }; +&gpio3 { + u-boot,dm-pre-reloc; +}; + &pinctrl { /* Pins that are not explicitely used by any devices */ pinctrl-names = "default"; pinctrl-0 = <&puma_pin_hog>; + hog { puma_pin_hog: puma_pin_hog { rockchip,pins = @@ -576,7 +599,7 @@ i2c8 { i2c8_xfer_a: i2c8-xfer { rockchip,pins = <1 21 RK_FUNC_1 &pcfg_pull_up>, - <1 20 RK_FUNC_1 &pcfg_pull_up>; + <1 20 RK_FUNC_1 &pcfg_pull_up>; }; }; }; @@ -652,4 +675,3 @@ &spi5 { status = "okay"; }; - -- cgit v1.2.3 From 2ee3021ae1808828c74b7eb6ae68d8d511bc4c30 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Wed, 27 Sep 2017 23:03:14 +0530 Subject: rk3288: spl: Add dram_init_banksize Falcon mode, is updating DDR dt node configuration through spl_fixup_fdt() so add appropriate DDR base and size through dram_init_banksize. Signed-off-by: Jagan Teki Reviewed-by: Philipp Tomsich Acked-by: Philipp Tomsich --- arch/arm/mach-rockchip/rk3288-board-spl.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-rockchip/rk3288-board-spl.c b/arch/arm/mach-rockchip/rk3288-board-spl.c index 5239cbc37c4..7b7fd5a6f1a 100644 --- a/arch/arm/mach-rockchip/rk3288-board-spl.c +++ b/arch/arm/mach-rockchip/rk3288-board-spl.c @@ -19,7 +19,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -290,3 +292,18 @@ err: /* No way to report error here */ hang(); } + +#ifdef CONFIG_SPL_OS_BOOT + +#define PMU_BASE 0xff730000 +int dram_init_banksize(void) +{ + struct rk3288_pmu *const pmu = (void *)PMU_BASE; + size_t size = rockchip_sdram_size((phys_addr_t)&pmu->sys_reg[2]); + + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + gd->bd->bi_dram[0].size = size; + + return 0; +} +#endif -- cgit v1.2.3 From e19fa89c9d344201da25a7b67fdd9d6896af6847 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Wed, 13 Sep 2017 09:39:06 +0800 Subject: rockchip: enable TPL_SYSRESET for all rockchip SoCs With Makefiles testing for $(SPL_TPL_)SYSRESET, we need TPL_SYSRESET for do_reset() in TPL for Rockchip SoCs. References: 87c16d4 "drivers: spl: consistently use the $(SPL_TPL_) macro" Signed-off-by: Kever Yang Reviewed-by: Simon Glass Reviewed-by: Philipp Tomsich --- arch/arm/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f0135307df7..d6d9558c695 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1115,6 +1115,7 @@ config ARCH_ROCKCHIP imply FAT_WRITE imply USB_FUNCTION_FASTBOOT imply SPL_SYSRESET + imply TPL_SYSRESET imply ADC imply SARADC_ROCKCHIP -- cgit v1.2.3