summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJagan Teki <jagan@amarulasolutions.com>2019-07-16 17:27:07 +0530
committerKever Yang <kever.yang@rock-chips.com>2019-07-20 23:59:44 +0800
commitba607fafd12e44735b6f3bc352b686101efc9155 (patch)
tree11d8bbd1f3e29f82651c77758ac7417eb08aed15
parenta735550bb8471a170247fad5376d0086b15ddedd (diff)
ram: rk3399: Configure phy IO in ds odt
Some dramtypes like lpddr4 initialization would required to configure phy IO even after pctl_cfg and after set_ds_odt. For those cases the set_ds_odt would be an initial call to setup the phy. To satisfy all the cases, trigger phy IO from set_ds_odt. Signed-off-by: Jagan Teki <jagan@amarulasolutions.com> Reviewed-by: Kever Yang <Kever.yang@rock-chips.com>
-rw-r--r--drivers/ram/rockchip/sdram_rk3399.c327
1 files changed, 162 insertions, 165 deletions
diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index 5568ad9846..cca809a7e3 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -188,6 +188,166 @@ static void set_memory_map(const struct chan_info *chan, u32 channel,
writel(0x2EC7FFFF, &denali_pi[34]);
}
+static int phy_io_config(const struct chan_info *chan,
+ const struct rk3399_sdram_params *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 (params->base.dramtype == LPDDR4) {
+ /* LPDDR4 */
+ vref_mode_dq = 0x6;
+ vref_value_dq = 0x1f;
+ vref_mode_ac = 0x6;
+ vref_value_ac = 0x1f;
+ } else if (params->base.dramtype == LPDDR3) {
+ if (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 (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 (params->base.dramtype == LPDDR4)
+ mode_sel = 0x6;
+ else if (params->base.dramtype == LPDDR3)
+ mode_sel = 0x0;
+ else if (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 (params->base.ddr_freq < 400)
+ speed = 0x0;
+ else if (params->base.ddr_freq < 800)
+ speed = 0x1;
+ else if (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 void set_ds_odt(const struct chan_info *chan,
const struct rk3399_sdram_params *params)
{
@@ -332,6 +492,8 @@ static void set_ds_odt(const struct chan_info *chan,
/* phy_pad_fdbk_term 1bit DENALI_PHY_930 offset_17 */
clrsetbits_le32(&denali_phy[930], 0x1 << 17, reg_value);
+
+ phy_io_config(chan, params);
}
static void pctl_start(struct dram_info *dram, u8 channel)
@@ -376,166 +538,6 @@ static void pctl_start(struct dram_info *dram, u8 channel)
dram->pwrup_srefresh_exit[channel]);
}
-static int phy_io_config(const struct chan_info *chan,
- const struct rk3399_sdram_params *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 (params->base.dramtype == LPDDR4) {
- /* LPDDR4 */
- vref_mode_dq = 0x6;
- vref_value_dq = 0x1f;
- vref_mode_ac = 0x6;
- vref_value_ac = 0x1f;
- } else if (params->base.dramtype == LPDDR3) {
- if (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 (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 (params->base.dramtype == LPDDR4)
- mode_sel = 0x6;
- else if (params->base.dramtype == LPDDR3)
- mode_sel = 0x0;
- else if (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 (params->base.ddr_freq < 400)
- speed = 0x0;
- else if (params->base.ddr_freq < 800)
- speed = 0x1;
- else if (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(struct dram_info *dram, const struct chan_info *chan,
u32 channel, const struct rk3399_sdram_params *params)
{
@@ -545,7 +547,6 @@ static int pctl_cfg(struct dram_info *dram, const struct chan_info *chan,
const u32 *params_ctl = params->pctl_regs.denali_ctl;
const u32 *params_phy = params->phy_regs.denali_phy;
u32 tmp, tmp1, tmp2;
- int ret;
/*
* work around controller bug:
@@ -623,10 +624,6 @@ static int pctl_cfg(struct dram_info *dram, const struct chan_info *chan,
tmp = (readl(&denali_phy[467]) >> 16) & 0xff;
clrsetbits_le32(&denali_phy[467], 0xff << 16, (tmp + 0x10) << 16);
- ret = phy_io_config(chan, params);
- if (ret)
- return ret;
-
return 0;
}