Merge git://git.denx.de/u-boot-rockchip

This commit is contained in:
Tom Rini
2016-11-02 09:41:20 -04:00
33 changed files with 421 additions and 182 deletions

View File

@@ -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>;
};

View File

@@ -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>;
};

View File

@@ -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>;
};

View File

@@ -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>;
};

View File

@@ -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>;
};

View File

@@ -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>;
};

View File

@@ -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>;
};

View File

@@ -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;

View File

@@ -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;

View File

@@ -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];

View File

@@ -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;
};

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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)
{

View File

@@ -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;
int ret;
params->num_channels = fdtdec_get_int(blob, node,
"rockchip,num-channels", 1);
for (i = 0; i < params->num_channels; i++) {
ret = fdtdec_get_byte_array(blob, node,
"rockchip,sdram-channel",
(u8 *)&params->ch[i],
sizeof(params->ch[i]));
if (ret) {
debug("%s: Cannot read rockchip,sdram-channel\n",
__func__);
return -EINVAL;
}
}
/* 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 *)&params->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);

View File

@@ -4,5 +4,6 @@
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += clk_rk3399.o
obj-y += rk3399.o
obj-y += syscon_rk3399.o

View File

@@ -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;
}

View File

@@ -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;
}