diff options
33 files changed, 422 insertions, 183 deletions
diff --git a/arch/arm/dts/rk3288-evb.dts b/arch/arm/dts/rk3288-evb.dts index 3e1ee58a5e..3f03e1326c 100644 --- a/arch/arm/dts/rk3288-evb.dts +++ b/arch/arm/dts/rk3288-evb.dts @@ -17,7 +17,6 @@ }; &dmc { - rockchip,num-channels = <2>; rockchip,pctl-timing = <0x215 0xc8 0x0 0x35 0x26 0x2 0x70 0x2000d 0x6 0x0 0x8 0x4 0x17 0x24 0xd 0x6 0x4 0x8 0x4 0x76 0x4 0x0 0x30 0x0 @@ -25,8 +24,6 @@ 0x8 0x1f4>; rockchip,phy-timing = <0x48d7dd93 0x187008d8 0x121076 0x0 0xc3 0x6 0x2>; - /* Add a dummy value to cause of-platdata think this is bytes */ - rockchip,sdram-channel = /bits/ 8 <0x2 0xa 0x3 0x2 0x2 0x0 0xe 0xe 0xff>; rockchip,sdram-params = <0x20d266a4 0x5b6 2 533000000 6 9 0>; }; diff --git a/arch/arm/dts/rk3288-fennec.dts b/arch/arm/dts/rk3288-fennec.dts index 36e9f3dac5..66ddf8d655 100644 --- a/arch/arm/dts/rk3288-fennec.dts +++ b/arch/arm/dts/rk3288-fennec.dts @@ -17,7 +17,6 @@ }; &dmc { - rockchip,num-channels = <2>; rockchip,pctl-timing = <0x215 0xc8 0x0 0x35 0x26 0x2 0x70 0x2000d 0x6 0x0 0x8 0x4 0x17 0x24 0xd 0x6 0x4 0x8 0x4 0x76 0x4 0x0 0x30 0x0 @@ -25,8 +24,6 @@ 0x8 0x1f4>; rockchip,phy-timing = <0x48d7dd93 0x187008d8 0x121076 0x0 0xc3 0x6 0x2>; - /* Add a dummy value to cause of-platdata think this is bytes */ - rockchip,sdram-channel = /bits/ 8 <0x2 0xa 0x3 0x2 0x2 0x0 0xe 0xe 0xff>; rockchip,sdram-params = <0x20d266a4 0x5b6 2 533000000 6 9 0>; }; diff --git a/arch/arm/dts/rk3288-firefly.dts b/arch/arm/dts/rk3288-firefly.dts index 3176d5046b..97568a36ee 100644 --- a/arch/arm/dts/rk3288-firefly.dts +++ b/arch/arm/dts/rk3288-firefly.dts @@ -22,7 +22,6 @@ }; &dmc { - rockchip,num-channels = <2>; rockchip,pctl-timing = <0x29a 0xc8 0x1f8 0x42 0x4e 0x4 0xea 0xa 0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7 0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0 @@ -31,7 +30,6 @@ rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200 0xa60 0x40 0x10 0x0>; /* Add a dummy value to cause of-platdata think this is bytes */ - rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>; rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>; }; diff --git a/arch/arm/dts/rk3288-miniarm.dts b/arch/arm/dts/rk3288-miniarm.dts index c7410821d3..9083028579 100644 --- a/arch/arm/dts/rk3288-miniarm.dts +++ b/arch/arm/dts/rk3288-miniarm.dts @@ -17,7 +17,6 @@ }; &dmc { - rockchip,num-channels = <2>; rockchip,pctl-timing = <0x29a 0xc8 0x1f8 0x42 0x4e 0x4 0xea 0xa 0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7 0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0 @@ -25,8 +24,6 @@ 0x5 0x0>; rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200 0xa60 0x40 0x10 0x0>; - /* Add a dummy value to cause of-platdata think this is bytes */ - rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>; rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>; }; diff --git a/arch/arm/dts/rk3288-popmetal.dts b/arch/arm/dts/rk3288-popmetal.dts index 3f61a61f97..284d5eda7b 100644 --- a/arch/arm/dts/rk3288-popmetal.dts +++ b/arch/arm/dts/rk3288-popmetal.dts @@ -17,7 +17,6 @@ }; &dmc { - rockchip,num-channels = <2>; rockchip,pctl-timing = <0x29a 0xc8 0x1f8 0x42 0x4e 0x4 0xea 0xa 0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7 0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0 @@ -25,8 +24,6 @@ 0x5 0x0>; rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200 0xa60 0x40 0x10 0x0>; - /* Add a dummy value to cause of-platdata think this is bytes */ - rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>; rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>; }; diff --git a/arch/arm/dts/rk3288-rock2-square.dts b/arch/arm/dts/rk3288-rock2-square.dts index 2c30355f06..11c580a0b5 100644 --- a/arch/arm/dts/rk3288-rock2-square.dts +++ b/arch/arm/dts/rk3288-rock2-square.dts @@ -184,7 +184,6 @@ }; &dmc { - rockchip,num-channels = <2>; rockchip,pctl-timing = <0x29a 0xc8 0x1f8 0x42 0x4e 0x4 0xea 0xa 0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7 0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0 @@ -192,7 +191,6 @@ 0x5 0x0>; rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200 0xa60 0x40 0x10 0x0>; - rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>; rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>; }; diff --git a/arch/arm/dts/rk3288-veyron.dtsi b/arch/arm/dts/rk3288-veyron.dtsi index d9d51879f0..2ffe39cbf7 100644 --- a/arch/arm/dts/rk3288-veyron.dtsi +++ b/arch/arm/dts/rk3288-veyron.dtsi @@ -245,7 +245,6 @@ 533000 1150000 666000 1200000 >; - rockchip,num-channels = <2>; rockchip,pctl-timing = <0x29a 0xc8 0x1f4 0x42 0x4e 0x4 0xea 0xa 0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7 0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0 @@ -253,7 +252,6 @@ 0x5 0x0>; rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200 0xa60 0x40 0x10 0x0>; - rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>; rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>; }; diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3036.h b/arch/arm/include/asm/arch-rockchip/cru_rk3036.h index 7ecc8ee71c..aaef4b9d73 100644 --- a/arch/arm/include/asm/arch-rockchip/cru_rk3036.h +++ b/arch/arm/include/asm/arch-rockchip/cru_rk3036.h @@ -24,6 +24,12 @@ #define PERI_HCLK_HZ 148500000 #define PERI_PCLK_HZ 74250000 +/* Private data for the clock driver - used by rockchip_get_cru() */ +struct rk3036_clk_priv { + struct rk3036_cru *cru; + ulong rate; +}; + struct rk3036_cru { struct rk3036_pll { unsigned int con0; diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3288.h b/arch/arm/include/asm/arch-rockchip/cru_rk3288.h index 8a8ca9c9aa..d575f4a163 100644 --- a/arch/arm/include/asm/arch-rockchip/cru_rk3288.h +++ b/arch/arm/include/asm/arch-rockchip/cru_rk3288.h @@ -25,6 +25,13 @@ #define PERI_HCLK_HZ 148500000 #define PERI_PCLK_HZ 74250000 +/* Private data for the clock driver - used by rockchip_get_cru() */ +struct rk3288_clk_priv { + struct rk3288_grf *grf; + struct rk3288_cru *cru; + ulong rate; +}; + struct rk3288_cru { struct rk3288_pll { u32 con0; diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3399.h b/arch/arm/include/asm/arch-rockchip/cru_rk3399.h index 6776e484b7..98fba2bd75 100644 --- a/arch/arm/include/asm/arch-rockchip/cru_rk3399.h +++ b/arch/arm/include/asm/arch-rockchip/cru_rk3399.h @@ -9,6 +9,12 @@ #include <common.h> +/* Private data for the clock driver - used by rockchip_get_cru() */ +struct rk3399_clk_priv { + struct rk3399_cru *cru; + ulong rate; +}; + struct rk3399_pmucru { u32 ppll_con[6]; u32 reserved[0x1a]; diff --git a/arch/arm/include/asm/arch-rockchip/sdram.h b/arch/arm/include/asm/arch-rockchip/sdram.h index 82c3d07cbb..d7d67baa68 100644 --- a/arch/arm/include/asm/arch-rockchip/sdram.h +++ b/arch/arm/include/asm/arch-rockchip/sdram.h @@ -16,6 +16,11 @@ enum { }; struct rk3288_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; @@ -87,6 +92,16 @@ struct rk3288_base_params { u32 ddrconfig; u32 ddr_freq; u32 dramtype; + /* + * DDR Stride is address mapping for DRAM space + * Stride Ch 0 range Ch1 range Total + * 0x00 0-256MB 256MB-512MB 512MB + * 0x05 0-1GB 0-1GB 1GB + * 0x09 0-2GB 0-2GB 2GB + * 0x0d 0-4GB 0-4GB 4GB + * 0x17 N/A 0-4GB 4GB + * 0x1a 0-4GB 4GB-8GB 8GB + */ u32 stride; u32 odt; }; diff --git a/arch/arm/mach-rockchip/rk3036/Makefile b/arch/arm/mach-rockchip/rk3036/Makefile index 916a7a4378..20d28f7c21 100644 --- a/arch/arm/mach-rockchip/rk3036/Makefile +++ b/arch/arm/mach-rockchip/rk3036/Makefile @@ -4,6 +4,8 @@ # SPDX-License-Identifier: GPL-2.0+ # +obj-y += clk_rk3036.o + ifndef CONFIG_SPL_BUILD obj-y += syscon_rk3036.o endif diff --git a/arch/arm/mach-rockchip/rk3036/clk_rk3036.c b/arch/arm/mach-rockchip/rk3036/clk_rk3036.c new file mode 100644 index 0000000000..6a06afb103 --- /dev/null +++ b/arch/arm/mach-rockchip/rk3036/clk_rk3036.c @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2016 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <syscon.h> +#include <asm/arch/clock.h> +#include <asm/arch/cru_rk3036.h> + +int rockchip_get_clk(struct udevice **devp) +{ + return uclass_get_device_by_driver(UCLASS_CLK, + DM_GET_DRIVER(rockchip_rk3036_cru), devp); +} + +void *rockchip_get_cru(void) +{ + struct rk3036_clk_priv *priv; + struct udevice *dev; + int ret; + + ret = rockchip_get_clk(&dev); + if (ret) + return ERR_PTR(ret); + + priv = dev_get_priv(dev); + + return priv->cru; +} diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig index 94863a925e..c53d2e2033 100644 --- a/arch/arm/mach-rockchip/rk3288/Kconfig +++ b/arch/arm/mach-rockchip/rk3288/Kconfig @@ -81,9 +81,6 @@ config SPL_LIBCOMMON_SUPPORT config SPL_LIBGENERIC_SUPPORT default y -config SPL_MMC_SUPPORT - default y - config SPL_SERIAL_SUPPORT default y diff --git a/arch/arm/mach-rockchip/rk3288/clk_rk3288.c b/arch/arm/mach-rockchip/rk3288/clk_rk3288.c index 2099e349c1..a45b923a2c 100644 --- a/arch/arm/mach-rockchip/rk3288/clk_rk3288.c +++ b/arch/arm/mach-rockchip/rk3288/clk_rk3288.c @@ -9,9 +9,25 @@ #include <dm.h> #include <syscon.h> #include <asm/arch/clock.h> +#include <asm/arch/cru_rk3288.h> int rockchip_get_clk(struct udevice **devp) { return uclass_get_device_by_driver(UCLASS_CLK, DM_GET_DRIVER(rockchip_rk3288_cru), devp); } + +void *rockchip_get_cru(void) +{ + struct rk3288_clk_priv *priv; + struct udevice *dev; + int ret; + + ret = rockchip_get_clk(&dev); + if (ret) + return ERR_PTR(ret); + + priv = dev_get_priv(dev); + + return priv->cru; +} diff --git a/arch/arm/mach-rockchip/rk3288/rk3288.c b/arch/arm/mach-rockchip/rk3288/rk3288.c index 92f34bbbcb..acc3b7932a 100644 --- a/arch/arm/mach-rockchip/rk3288/rk3288.c +++ b/arch/arm/mach-rockchip/rk3288/rk3288.c @@ -6,7 +6,7 @@ #include <asm/io.h> #include <asm/arch/hardware.h> -#define GRF_SOC_CON2 0x24c +#define GRF_SOC_CON2 0xff77024c int arch_cpu_init(void) { diff --git a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c index 8020e9c6e2..be3d713202 100644 --- a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +++ b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c @@ -57,6 +57,10 @@ struct rk3288_sdram_params { struct regmap *map; }; +#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) { @@ -214,7 +218,7 @@ static void ddr_set_en_bst_odt(struct rk3288_grf *grf, uint channel, } static void pctl_cfg(u32 channel, struct rk3288_ddr_pctl *pctl, - const struct rk3288_sdram_params *sdram_params, + struct rk3288_sdram_params *sdram_params, struct rk3288_grf *grf) { unsigned int burstlen; @@ -264,7 +268,7 @@ static void pctl_cfg(u32 channel, struct rk3288_ddr_pctl *pctl, } static void phy_cfg(const struct chan_info *chan, u32 channel, - const struct rk3288_sdram_params *sdram_params) + struct rk3288_sdram_params *sdram_params) { struct rk3288_ddr_publ *publ = chan->publ; struct rk3288_msch *msch = chan->msch; @@ -446,7 +450,7 @@ static void set_bandwidth_ratio(const struct chan_info *chan, u32 channel, } static int data_training(const struct chan_info *chan, u32 channel, - const struct rk3288_sdram_params *sdram_params) + struct rk3288_sdram_params *sdram_params) { unsigned int j; int ret = 0; @@ -549,7 +553,7 @@ static void move_to_access_state(const struct chan_info *chan) } static void dram_cfg_rbc(const struct chan_info *chan, u32 chnum, - const struct rk3288_sdram_params *sdram_params) + struct rk3288_sdram_params *sdram_params) { struct rk3288_ddr_publ *publ = chan->publ; @@ -563,7 +567,7 @@ static void dram_cfg_rbc(const struct chan_info *chan, u32 chnum, } static void dram_all_config(const struct dram_info *dram, - const struct rk3288_sdram_params *sdram_params) + struct rk3288_sdram_params *sdram_params) { unsigned int chan; u32 sys_reg = 0; @@ -589,9 +593,191 @@ static void dram_all_config(const struct dram_info *dram, writel(sys_reg, &dram->pmu->sys_reg[2]); rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, sdram_params->base.stride); } +const int ddrconf_table[] = { + /* row col,bw */ + 0, + ((1 << 4) | 1), + ((2 << 4) | 1), + ((3 << 4) | 1), + ((4 << 4) | 1), + ((1 << 4) | 2), + ((2 << 4) | 2), + ((3 << 4) | 2), + ((1 << 4) | 0), + ((2 << 4) | 0), + ((3 << 4) | 0), + 0, + 0, + 0, + 0, + ((4 << 4) | 2), +}; + +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 (-1 == data_training(chan, channel, sdram_params)) { + 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 && + (-1 == data_training(chan, channel, sdram_params))) { + if (sdram_params->base.dramtype == LPDDR3) { + ddr_phy_ctl_reset(dram->cru, channel, 1); + udelay(10); + ddr_phy_ctl_reset(dram->cru, channel, 0); + udelay(10); + } + debug("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, - const struct rk3288_sdram_params *sdram_params) + struct rk3288_sdram_params *sdram_params) { int channel; int zqcr; @@ -619,12 +805,14 @@ static int sdram_init(struct dram_info *dram, 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); - if (channel >= sdram_params->num_channels) - continue; - dfi_cfg(pctl, sdram_params->base.dramtype); pctl_cfg(channel, pctl, sdram_params, dram->grf); @@ -658,16 +846,20 @@ static int sdram_init(struct dram_info *dram, 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 + * 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 | @@ -693,16 +885,8 @@ static int sdram_init(struct dram_info *dram, } } - if (-1 == data_training(chan, channel, sdram_params)) { - if (sdram_params->base.dramtype == LPDDR3) { - ddr_phy_ctl_reset(dram->cru, channel, 1); - udelay(10); - ddr_phy_ctl_reset(dram->cru, channel, 0); - udelay(10); - } - debug("failed!"); - return -EIO; - } + /* 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; @@ -710,12 +894,31 @@ static int sdram_init(struct dram_info *dram, 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(); } #endif /* CONFIG_SPL_BUILD */ @@ -743,7 +946,6 @@ size_t sdram_size_mb(struct rk3288_pmu *pmu) SYS_REG_BW_MASK)); row_3_4 = sys_reg >> SYS_REG_ROW_3_4_SHIFT(ch) & SYS_REG_ROW_3_4_MASK; - chipsize_mb = (1 << (cs0_row + col + bk + bw - 20)); if (rank > 1) @@ -815,21 +1017,10 @@ static int rk3288_dmc_ofdata_to_platdata(struct udevice *dev) struct rk3288_sdram_params *params = dev_get_platdata(dev); const void *blob = gd->fdt_blob; int node = dev->of_offset; - int i, ret; - - params->num_channels = fdtdec_get_int(blob, node, - "rockchip,num-channels", 1); - for (i = 0; i < params->num_channels; i++) { - ret = fdtdec_get_byte_array(blob, node, - "rockchip,sdram-channel", - (u8 *)¶ms->ch[i], - sizeof(params->ch[i])); - if (ret) { - debug("%s: Cannot read rockchip,sdram-channel\n", - __func__); - return -EINVAL; - } - } + int ret; + + /* Rk3288 supports dual-channel, set default channel num to 2 */ + params->num_channels = 2; ret = fdtdec_get_int_array(blob, node, "rockchip,pctl-timing", (u32 *)¶ms->pctl_timing, sizeof(params->pctl_timing) / sizeof(u32)); @@ -870,18 +1061,15 @@ 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 i, ret; + int ret; - for (i = 0; i < 2; i++) { - memcpy(&plat->ch[i], of_plat->rockchip_sdram_channel, - sizeof(plat->ch[i])); - } 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)); - plat->num_channels = of_plat->rockchip_num_channels; + /* 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); diff --git a/arch/arm/mach-rockchip/rk3399/Makefile b/arch/arm/mach-rockchip/rk3399/Makefile index 607f9c9612..98ebeac340 100644 --- a/arch/arm/mach-rockchip/rk3399/Makefile +++ b/arch/arm/mach-rockchip/rk3399/Makefile @@ -4,5 +4,6 @@ # SPDX-License-Identifier: GPL-2.0+ # +obj-y += clk_rk3399.o obj-y += rk3399.o obj-y += syscon_rk3399.o diff --git a/arch/arm/mach-rockchip/rk3399/clk_rk3399.c b/arch/arm/mach-rockchip/rk3399/clk_rk3399.c new file mode 100644 index 0000000000..7663591154 --- /dev/null +++ b/arch/arm/mach-rockchip/rk3399/clk_rk3399.c @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2016 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <syscon.h> +#include <asm/arch/clock.h> +#include <asm/arch/cru_rk3399.h> + +int rockchip_get_clk(struct udevice **devp) +{ + return uclass_get_device_by_driver(UCLASS_CLK, + DM_GET_DRIVER(rockchip_rk3399_pmuclk), devp); +} + +void *rockchip_get_cru(void) +{ + struct rk3399_clk_priv *priv; + struct udevice *dev; + int ret; + + ret = rockchip_get_clk(&dev); + if (ret) + return ERR_PTR(ret); + + priv = dev_get_priv(dev); + + return priv->cru; +} diff --git a/arch/arm/mach-rockchip/rk3399/rk3399.c b/arch/arm/mach-rockchip/rk3399/rk3399.c index b9d7629407..8bb950ebd1 100644 --- a/arch/arm/mach-rockchip/rk3399/rk3399.c +++ b/arch/arm/mach-rockchip/rk3399/rk3399.c @@ -6,6 +6,10 @@ #include <common.h> #include <asm/armv8/mmu.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> + +#define GRF_EMMCCORE_CON11 0xff77f02c static struct mm_region rk3399_mem_map[] = { { @@ -28,3 +32,13 @@ static struct mm_region rk3399_mem_map[] = { }; struct mm_region *mem_map = rk3399_mem_map; + +int arch_cpu_init(void) +{ + /* We do some SoC one time setting here. */ + + /* Emmc clock generator: disable the clock multipilier */ + rk_clrreg(GRF_EMMCCORE_CON11, 0x0ff); + + return 0; +} diff --git a/configs/evb-rk3288_defconfig b/configs/evb-rk3288_defconfig index fd8afe752b..8db9041a13 100644 --- a/configs/evb-rk3288_defconfig +++ b/configs/evb-rk3288_defconfig @@ -64,3 +64,4 @@ CONFIG_SYSRESET=y CONFIG_USE_TINY_PRINTF=y CONFIG_CMD_DHRYSTONE=y CONFIG_ERRNO_STR=y +CONFIG_ROCKCHIP_SPL_BACK_TO_BROM=y diff --git a/configs/fennec-rk3288_defconfig b/configs/fennec-rk3288_defconfig index 5b4d0f14d1..d5452004b7 100644 --- a/configs/fennec-rk3288_defconfig +++ b/configs/fennec-rk3288_defconfig @@ -63,3 +63,4 @@ CONFIG_SYSRESET=y CONFIG_USE_TINY_PRINTF=y CONFIG_CMD_DHRYSTONE=y CONFIG_ERRNO_STR=y +CONFIG_ROCKCHIP_SPL_BACK_TO_BROM=y diff --git a/configs/miniarm-rk3288_defconfig b/configs/miniarm-rk3288_defconfig index 394e4aa20e..888563bee1 100644 --- a/configs/miniarm-rk3288_defconfig +++ b/configs/miniarm-rk3288_defconfig @@ -62,3 +62,4 @@ CONFIG_SYSRESET=y CONFIG_USE_TINY_PRINTF=y CONFIG_CMD_DHRYSTONE=y CONFIG_ERRNO_STR=y +CONFIG_ROCKCHIP_SPL_BACK_TO_BROM=y diff --git a/configs/popmetal-rk3288_defconfig b/configs/popmetal-rk3288_defconfig index ff6a153d2c..1e70ae0390 100644 --- a/configs/popmetal-rk3288_defconfig +++ b/configs/popmetal-rk3288_defconfig @@ -62,3 +62,4 @@ CONFIG_SYSRESET=y CONFIG_USE_TINY_PRINTF=y CONFIG_CMD_DHRYSTONE=y CONFIG_ERRNO_STR=y +CONFIG_ROCKCHIP_SPL_BACK_TO_BROM=y diff --git a/doc/README.rockchip b/doc/README.rockchip index 69b926c52d..06ec80e523 100644 --- a/doc/README.rockchip +++ b/doc/README.rockchip @@ -149,7 +149,6 @@ Note: rk3036 SDMMC and debug uart use the same iomux, so if you boot from SD, th Using fastboot on rk3288 ======================== -- Define GPT partition layout like kylin_rk3036(see include/configs/kylin_rk3036.h) - Write GPT partition layout to mmc device which fastboot want to use it to store the image @@ -212,7 +211,6 @@ When booting you should see something like: Err: serial@ff690000 => - Future work =========== @@ -298,6 +296,15 @@ overhead and in SPL with a 32KB size limit some shortcuts have been taken. In general all Rockchip drivers should use these features, with SPL-specific modifications where required. +GPT partition layout +---------------------------- + +Rockchip use a unified GPT partition layout in open source support. +With this GPT partition layout, uboot can be compatilbe with other components, +like miniloader, trusted-os, arm-trust-firmware. + +There are some documents about partitions in the links below. +http://rockchip.wikidot.com/partitions -- Simon Glass <sjg@chromium.org> diff --git a/drivers/clk/rockchip/clk_rk3036.c b/drivers/clk/rockchip/clk_rk3036.c index 8899b0c62d..7e3bf96944 100644 --- a/drivers/clk/rockchip/clk_rk3036.c +++ b/drivers/clk/rockchip/clk_rk3036.c @@ -19,11 +19,6 @@ DECLARE_GLOBAL_DATA_PTR; -struct rk3036_clk_priv { - struct rk3036_cru *cru; - ulong rate; -}; - enum { VCO_MAX_HZ = 2400U * 1000000, VCO_MIN_HZ = 600 * 1000000, @@ -49,23 +44,6 @@ enum { static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 3, 1); static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1); -void *rockchip_get_cru(void) -{ - struct udevice *dev; - fdt_addr_t addr; - int ret; - - ret = uclass_get_device(UCLASS_CLK, 0, &dev); - if (ret) - return ERR_PTR(ret); - - addr = dev_get_addr(dev); - if (addr == FDT_ADDR_T_NONE) - return ERR_PTR(-EINVAL); - - return (void *)addr; -} - static int rkclk_set_pll(struct rk3036_cru *cru, enum rk_clk_id clk_id, const struct pll_div *div) { @@ -371,7 +349,7 @@ static const struct udevice_id rk3036_clk_ids[] = { { } }; -U_BOOT_DRIVER(clk_rk3036) = { +U_BOOT_DRIVER(rockchip_rk3036_cru) = { .name = "clk_rk3036", .id = UCLASS_CLK, .of_match = rk3036_clk_ids, diff --git a/drivers/clk/rockchip/clk_rk3288.c b/drivers/clk/rockchip/clk_rk3288.c index bd71a96927..ed97e87a95 100644 --- a/drivers/clk/rockchip/clk_rk3288.c +++ b/drivers/clk/rockchip/clk_rk3288.c @@ -30,12 +30,6 @@ struct rk3288_clk_plat { #endif }; -struct rk3288_clk_priv { - struct rk3288_grf *grf; - struct rk3288_cru *cru; - ulong rate; -}; - struct pll_div { u32 nr; u32 nf; @@ -140,21 +134,6 @@ static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 1); static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2); static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2); -void *rockchip_get_cru(void) -{ - struct rk3288_clk_priv *priv; - struct udevice *dev; - int ret; - - ret = rockchip_get_clk(&dev); - if (ret) - return ERR_PTR(ret); - - priv = dev_get_priv(dev); - - return priv->cru; -} - static int rkclk_set_pll(struct rk3288_cru *cru, enum rk_clk_id clk_id, const struct pll_div *div) { diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c index ea0ce2aab1..2e87e4b62d 100644 --- a/drivers/clk/rockchip/clk_rk3399.c +++ b/drivers/clk/rockchip/clk_rk3399.c @@ -18,11 +18,6 @@ DECLARE_GLOBAL_DATA_PTR; -struct rk3399_clk_priv { - struct rk3399_cru *cru; - ulong rate; -}; - struct rk3399_pmuclk_priv { struct rk3399_pmucru *pmucru; }; @@ -780,23 +775,6 @@ static struct clk_ops rk3399_clk_ops = { .set_rate = rk3399_clk_set_rate, }; -void *rockchip_get_cru(void) -{ - struct udevice *dev; - fdt_addr_t *addr; - int ret; - - ret = uclass_get_device_by_name(UCLASS_CLK, "clk_rk3399", &dev); - if (ret) - return ERR_PTR(ret); - - addr = dev_get_addr_ptr(dev); - if ((fdt_addr_t)addr == FDT_ADDR_T_NONE) - return ERR_PTR(-EINVAL); - - return addr; -} - static int rk3399_clk_probe(struct udevice *dev) { struct rk3399_clk_priv *priv = dev_get_priv(dev); @@ -990,7 +968,7 @@ static const struct udevice_id rk3399_pmuclk_ids[] = { { } }; -U_BOOT_DRIVER(pmuclk_rk3399) = { +U_BOOT_DRIVER(rockchip_rk3399_pmuclk) = { .name = "pmuclk_rk3399", .id = UCLASS_CLK, .of_match = rk3399_pmuclk_ids, diff --git a/include/configs/evb_rk3399.h b/include/configs/evb_rk3399.h index f4536405eb..8fdefa29c7 100644 --- a/include/configs/evb_rk3399.h +++ b/include/configs/evb_rk3399.h @@ -10,7 +10,7 @@ #include <configs/rk3399_common.h> #define CONFIG_ENV_IS_IN_MMC -#define CONFIG_SYS_MMC_ENV_DEV 0 +#define CONFIG_SYS_MMC_ENV_DEV 1 /* * SPL @ 32k for ~36k * ENV @ 96k diff --git a/include/configs/rk3036_common.h b/include/configs/rk3036_common.h index 724a3f40de..4eef3f8cc6 100644 --- a/include/configs/rk3036_common.h +++ b/include/configs/rk3036_common.h @@ -7,6 +7,7 @@ #define __CONFIG_RK3036_COMMON_H #include <asm/arch/hardware.h> +#include "rockchip-common.h" #define CONFIG_SYS_NO_FLASH #define CONFIG_NR_DRAM_BANKS 1 @@ -78,11 +79,6 @@ #define CONFIG_G_DNL_VENDOR_NUM 0x2207 #define CONFIG_G_DNL_PRODUCT_NUM 0x310a -/* Enable gpt partition table */ -#define CONFIG_CMD_GPT - -#include <config_distro_defaults.h> - #define ENV_MEM_LAYOUT_SETTINGS \ "scriptaddr=0x60000000\0" \ "pxefile_addr_r=0x60100000\0" \ @@ -90,17 +86,6 @@ "kernel_addr_r=0x62000000\0" \ "ramdisk_addr_r=0x64000000\0" -#define CONFIG_RANDOM_UUID -#define PARTS_DEFAULT \ - "uuid_disk=${uuid_gpt_disk};" \ - "name=boot,start=8M,size=64M,bootable,uuid=${uuid_gpt_boot};" \ - "name=rootfs,size=-,uuid=${uuid_gpt_rootfs};\0" \ - -/* First try to boot from SD (index 0), then eMMC (index 1 */ -#define BOOT_TARGET_DEVICES(func) \ - func(MMC, mmc, 0) \ - func(MMC, mmc, 1) - #include <config_distro_bootcmd.h> /* Linux fails to load the fdt if it's loaded above 512M on a evb-rk3036 board, diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h index cf6f3557f0..0868612c13 100644 --- a/include/configs/rk3288_common.h +++ b/include/configs/rk3288_common.h @@ -8,6 +8,7 @@ #define __CONFIG_RK3288_COMMON_H #include <asm/arch/hardware.h> +#include "rockchip-common.h" #define CONFIG_SKIP_LOWLEVEL_INIT_ONLY #define CONFIG_SYS_NO_FLASH @@ -89,11 +90,6 @@ #define CONFIG_G_DNL_VENDOR_NUM 0x2207 #define CONFIG_G_DNL_PRODUCT_NUM 0x320a -/* Enable gpt partition table */ -#define CONFIG_CMD_GPT - -#include <config_distro_defaults.h> - #define ENV_MEM_LAYOUT_SETTINGS \ "scriptaddr=0x00000000\0" \ "pxefile_addr_r=0x00100000\0" \ @@ -101,24 +97,13 @@ "kernel_addr_r=0x02000000\0" \ "ramdisk_addr_r=0x04000000\0" -#define CONFIG_RANDOM_UUID -#define PARTS_DEFAULT \ - "uuid_disk=${uuid_gpt_disk};" \ - "name=boot,start=8M,size=64M,bootable,uuid=${uuid_gpt_boot};" \ - "name=rootfs,size=-,uuid=${uuid_gpt_rootfs};\0" \ - -/* First try to boot from SD (index 0), then eMMC (index 1 */ -#define BOOT_TARGET_DEVICES(func) \ - func(MMC, mmc, 0) \ - func(MMC, mmc, 1) - #include <config_distro_bootcmd.h> -/* Linux fails to load the fdt if it's loaded above 512M on a Rock 2 board, so +/* Linux fails to load the fdt if it's loaded above 256M on a Rock 2 board, so * limit the fdt reallocation to that */ #define CONFIG_EXTRA_ENV_SETTINGS \ - "fdt_high=0x1fffffff\0" \ - "initrd_high=0x1fffffff\0" \ + "fdt_high=0x0fffffff\0" \ + "initrd_high=0x0fffffff\0" \ "partitions=" PARTS_DEFAULT \ ENV_MEM_LAYOUT_SETTINGS \ ROCKCHIP_DEVICE_SETTINGS \ diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h index bec004a6d8..d75feadab7 100644 --- a/include/configs/rk3399_common.h +++ b/include/configs/rk3399_common.h @@ -7,6 +7,8 @@ #ifndef __CONFIG_RK3399_COMMON_H #define __CONFIG_RK3399_COMMON_H +#include "rockchip-common.h" + #define CONFIG_SYS_NO_FLASH #define CONFIG_NR_DRAM_BANKS 1 #define CONFIG_ENV_SIZE 0x2000 @@ -52,7 +54,6 @@ #define CONFIG_SF_DEFAULT_SPEED 20000000 #ifndef CONFIG_SPL_BUILD -#include <config_distro_defaults.h> #define ENV_MEM_LAYOUT_SETTINGS \ "scriptaddr=0x00000000\0" \ @@ -61,19 +62,6 @@ "kernel_addr_r=0x02000000\0" \ "ramdisk_addr_r=0x04000000\0" -#define CONFIG_CMD_GPT -#define CONFIG_RANDOM_UUID -#define CONFIG_PARTITION_UUIDS -#define PARTS_DEFAULT \ - "uuid_disk=${uuid_gpt_disk};" \ - "name=boot,start=16M,size=32M,bootable;" \ - "name=rootfs,size=-,uuid=${uuid_gpt_rootfs};\0" \ - -/* First try to boot from SD (index 0), then eMMC (index 1) */ -#define BOOT_TARGET_DEVICES(func) \ - func(MMC, mmc, 0) \ - func(MMC, mmc, 1) - #include <config_distro_bootcmd.h> #define CONFIG_EXTRA_ENV_SETTINGS \ ENV_MEM_LAYOUT_SETTINGS \ diff --git a/include/configs/rockchip-common.h b/include/configs/rockchip-common.h new file mode 100644 index 0000000000..7ca1696a16 --- /dev/null +++ b/include/configs/rockchip-common.h @@ -0,0 +1,35 @@ +/* + * (C) Copyright 2016 Rockchip Electronics Co., Ltd + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ROCKCHIP_COMMON_H_ +#define _ROCKCHIP_COMMON_H_ +#include <linux/sizes.h> + +#ifndef CONFIG_SPL_BUILD +#include <config_distro_defaults.h> + +/* First try to boot from SD (index 0), then eMMC (index 1 */ +#define BOOT_TARGET_DEVICES(func) \ + func(MMC, mmc, 0) \ + func(MMC, mmc, 1) + + /* Enable gpt partition table */ +#define CONFIG_CMD_GPT +#define CONFIG_RANDOM_UUID +#define CONFIG_PARTITION_UUIDS +#define PARTS_DEFAULT \ + "uuid_disk=${uuid_gpt_disk};" \ + "name=loader1,start=32K,size=4000K,uuid=${uuid_gpt_loader1};" \ + "name=reserved1,size=64K,uuid=${uuid_gpt_reserved1};" \ + "name=reserved2,size=4M,uuid=${uuid_gpt_reserved2};" \ + "name=loader2,size=4MB,uuid=${uuid_gpt_loader2};" \ + "name=atf,size=4M,uuid=${uuid_gpt_atf};" \ + "name=boot,size=128M,bootable,uuid=${uuid_gpt_boot};" \ + "name=rootfs,size=-,uuid=${uuid_gpt_rootfs};\0" \ + +#endif + +#endif /* _ROCKCHIP_COMMON_H_ */ |