summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ram/rockchip/sdram_rk3399.c43
1 files changed, 33 insertions, 10 deletions
diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index 8a261e0fe9..1a33951525 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -65,11 +65,17 @@ struct dram_info {
struct rk3399_pmucru *pmucru;
struct rk3399_pmusgrf_regs *pmusgrf;
struct rk3399_ddr_cic_regs *cic;
+ const struct sdram_rk3399_ops *ops;
#endif
struct ram_info info;
struct rk3399_pmugrf_regs *pmugrf;
};
+struct sdram_rk3399_ops {
+ int (*data_training)(struct dram_info *dram, u32 channel, u8 rank,
+ struct rk3399_sdram_params *sdram);
+};
+
#if defined(CONFIG_TPL_BUILD) || \
(!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
@@ -1464,6 +1470,23 @@ static void dram_all_config(struct dram_info *dram,
clrsetbits_le32(&dram->cru->glb_rst_con, 0x3, 0x3);
}
+static int default_data_training(struct dram_info *dram, u32 channel, u8 rank,
+ struct rk3399_sdram_params *params)
+{
+ u8 training_flag = PI_READ_GATE_TRAINING;
+
+ /*
+ * LPDDR3 CA training msut be trigger before
+ * other training.
+ * DDR3 is not have CA training.
+ */
+
+ if (params->base.dramtype == LPDDR3)
+ training_flag |= PI_CA_TRAINING;
+
+ return data_training(dram, channel, params, training_flag);
+}
+
static int switch_to_phy_index1(struct dram_info *dram,
const struct rk3399_sdram_params *params)
{
@@ -1626,7 +1649,6 @@ static int sdram_init(struct dram_info *dram,
{
unsigned char dramtype = params->base.dramtype;
unsigned int ddr_freq = params->base.ddr_freq;
- u32 training_flag = PI_READ_GATE_TRAINING;
int channel, ch, rank;
int ret;
@@ -1654,16 +1676,12 @@ static int sdram_init(struct dram_info *dram,
params->ch[ch].cap_info.rank = rank;
- /*
- * LPDDR3 CA training msut be trigger before
- * other training.
- * DDR3 is not have CA training.
- */
- if (params->base.dramtype == LPDDR3)
- training_flag |= PI_CA_TRAINING;
-
- if (!(data_training(dram, ch, params, training_flag)))
+ ret = dram->ops->data_training(dram, ch, rank, params);
+ if (!ret) {
+ debug("%s: data trained for rank %d, ch %d\n",
+ __func__, rank, ch);
break;
+ }
}
/* Computed rank with associated channel number */
params->ch[ch].cap_info.rank = rank;
@@ -1759,6 +1777,10 @@ static int conv_of_platdata(struct udevice *dev)
}
#endif
+static const struct sdram_rk3399_ops rk3399_ops = {
+ .data_training = default_data_training,
+};
+
static int rk3399_dmc_init(struct udevice *dev)
{
struct dram_info *priv = dev_get_priv(dev);
@@ -1776,6 +1798,7 @@ static int rk3399_dmc_init(struct udevice *dev)
return ret;
#endif
+ priv->ops = &rk3399_ops;
priv->cic = syscon_get_first_range(ROCKCHIP_SYSCON_CIC);
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);