DDR_MR3
>;
-#ifdef DDR_PHY_CAL_SKIP
- st,phy-cal = <
- DDR_DX0DLLCR
- DDR_DX0DQTR
- DDR_DX0DQSTR
- DDR_DX1DLLCR
- DDR_DX1DQTR
- DDR_DX1DQSTR
- DDR_DX2DLLCR
- DDR_DX2DQTR
- DDR_DX2DQSTR
- DDR_DX3DLLCR
- DDR_DX3DQTR
- DDR_DX3DQSTR
- >;
-
-#endif
-
status = "okay";
};
};
#undef DDR_ODTCR
#undef DDR_ZQ0CR1
#undef DDR_DX0GCR
-#undef DDR_DX0DLLCR
-#undef DDR_DX0DQTR
-#undef DDR_DX0DQSTR
#undef DDR_DX1GCR
-#undef DDR_DX1DLLCR
-#undef DDR_DX1DQTR
-#undef DDR_DX1DQSTR
#undef DDR_DX2GCR
-#undef DDR_DX2DLLCR
-#undef DDR_DX2DQTR
-#undef DDR_DX2DQSTR
#undef DDR_DX3GCR
-#undef DDR_DX3DLLCR
-#undef DDR_DX3DQTR
-#undef DDR_DX3DQSTR
#define DDR_ODTCR 0x00010000
#define DDR_ZQ0CR1 0x00000038
#define DDR_DX0GCR 0x0000CE81
-#define DDR_DX0DLLCR 0x40000000
-#define DDR_DX0DQTR 0xFFFFFFFF
-#define DDR_DX0DQSTR 0x3DB02000
#define DDR_DX1GCR 0x0000CE81
-#define DDR_DX1DLLCR 0x40000000
-#define DDR_DX1DQTR 0xFFFFFFFF
-#define DDR_DX1DQSTR 0x3DB02000
#define DDR_DX2GCR 0x0000CE80
-#define DDR_DX2DLLCR 0x40000000
-#define DDR_DX2DQTR 0xFFFFFFFF
-#define DDR_DX2DQSTR 0x3DB02000
#define DDR_DX3GCR 0x0000CE80
-#define DDR_DX3DLLCR 0x40000000
-#define DDR_DX3DQTR 0xFFFFFFFF
-#define DDR_DX3DQSTR 0x3DB02000
#include "stm32mp15-ddr.dtsi"
#define DDR_ODTCR 0x00010000
#define DDR_ZQ0CR1 0x00000038
#define DDR_DX0GCR 0x0000CE81
-#define DDR_DX0DLLCR 0x40000000
-#define DDR_DX0DQTR 0xFFFFFFFF
-#define DDR_DX0DQSTR 0x3DB02000
#define DDR_DX1GCR 0x0000CE81
-#define DDR_DX1DLLCR 0x40000000
-#define DDR_DX1DQTR 0xFFFFFFFF
-#define DDR_DX1DQSTR 0x3DB02000
#define DDR_DX2GCR 0x0000CE81
-#define DDR_DX2DLLCR 0x40000000
-#define DDR_DX2DQTR 0xFFFFFFFF
-#define DDR_DX2DQSTR 0x3DB02000
#define DDR_DX3GCR 0x0000CE81
-#define DDR_DX3DLLCR 0x40000000
-#define DDR_DX3DQTR 0xFFFFFFFF
-#define DDR_DX3DQSTR 0x3DB02000
#include "stm32mp15-ddr.dtsi"
#define DDR_ODTCR 0x00010000
#define DDR_ZQ0CR1 0x00000038
#define DDR_DX0GCR 0x0000CE81
-#define DDR_DX0DLLCR 0x40000000
-#define DDR_DX0DQTR 0xFFFFFFFF
-#define DDR_DX0DQSTR 0x3DB02000
#define DDR_DX1GCR 0x0000CE81
-#define DDR_DX1DLLCR 0x40000000
-#define DDR_DX1DQTR 0xFFFFFFFF
-#define DDR_DX1DQSTR 0x3DB02000
#define DDR_DX2GCR 0x0000CE81
-#define DDR_DX2DLLCR 0x40000000
-#define DDR_DX2DQTR 0xFFFFFFFF
-#define DDR_DX2DQSTR 0x3DB02000
#define DDR_DX3GCR 0x0000CE81
-#define DDR_DX3DLLCR 0x40000000
-#define DDR_DX3DQTR 0xFFFFFFFF
-#define DDR_DX3DQSTR 0x3DB02000
#include "stm32mp15-ddr.dtsi"
#define DDR_ODTCR 0x00010000
#define DDR_ZQ0CR1 0x00000038
#define DDR_DX0GCR 0x0000CE81
-#define DDR_DX0DLLCR 0x40000000
-#define DDR_DX0DQTR 0xFFFFFFFF
-#define DDR_DX0DQSTR 0x3DB02000
#define DDR_DX1GCR 0x0000CE81
-#define DDR_DX1DLLCR 0x40000000
-#define DDR_DX1DQTR 0xFFFFFFFF
-#define DDR_DX1DQSTR 0x3DB02000
#define DDR_DX2GCR 0x0000CE81
-#define DDR_DX2DLLCR 0x40000000
-#define DDR_DX2DQTR 0xFFFFFFFF
-#define DDR_DX2DQSTR 0x3DB02000
#define DDR_DX3GCR 0x0000CE81
-#define DDR_DX3DLLCR 0x40000000
-#define DDR_DX3DQTR 0xFFFFFFFF
-#define DDR_DX3DQSTR 0x3DB02000
#include "stm32mp15-ddr.dtsi"
#define DDR_ODTCR 0x00010000
#define DDR_ZQ0CR1 0x00000038
#define DDR_DX0GCR 0x0000CE81
-#define DDR_DX0DLLCR 0x40000000
-#define DDR_DX0DQTR 0xFFFFFFFF
-#define DDR_DX0DQSTR 0x3DB02000
#define DDR_DX1GCR 0x0000CE81
-#define DDR_DX1DLLCR 0x40000000
-#define DDR_DX1DQTR 0xFFFFFFFF
-#define DDR_DX1DQSTR 0x3DB02000
#define DDR_DX2GCR 0x0000CE81
-#define DDR_DX2DLLCR 0x40000000
-#define DDR_DX2DQTR 0xFFFFFFFF
-#define DDR_DX2DQSTR 0x3DB02000
#define DDR_DX3GCR 0x0000CE81
-#define DDR_DX3DLLCR 0x40000000
-#define DDR_DX3DQTR 0xFFFFFFFF
-#define DDR_DX3DQSTR 0x3DB02000
#include "stm32mp15-ddr.dtsi"
#define DDR_ODTCR 0x00010000
#define DDR_ZQ0CR1 0x00000038
#define DDR_DX0GCR 0x0000CE81
-#define DDR_DX0DLLCR 0x40000000
-#define DDR_DX0DQTR 0xFFFFFFFF
-#define DDR_DX0DQSTR 0x3DB02000
#define DDR_DX1GCR 0x0000CE81
-#define DDR_DX1DLLCR 0x40000000
-#define DDR_DX1DQTR 0xFFFFFFFF
-#define DDR_DX1DQSTR 0x3DB02000
#define DDR_DX2GCR 0x0000CE81
-#define DDR_DX2DLLCR 0x40000000
-#define DDR_DX2DQTR 0xFFFFFFFF
-#define DDR_DX2DQSTR 0x3DB02000
#define DDR_DX3GCR 0x0000CE81
-#define DDR_DX3DLLCR 0x40000000
-#define DDR_DX3DQTR 0xFFFFFFFF
-#define DDR_DX3DQSTR 0x3DB02000
#include "stm32mp15-ddr.dtsi"
MR2
MR3
-- st,phy-cal : phy cal depending of calibration or tuning of DDR
- This parameter is optional; when it is absent the built-in PHY
- calibration is done.
- for STM32MP15x: 12 values are requested in this order
- DX0DLLCR
- DX0DQTR
- DX0DQSTR
- DX1DLLCR
- DX1DQTR
- DX1DQSTR
- DX2DLLCR
- DX2DQTR
- DX2DQSTR
- DX3DLLCR
- DX3DQTR
- DX3DQSTR
-
Example:
/ {
0x00000000 /*MR3*/
>;
- st,phy-cal = <
- 0x40000000 /*DX0DLLCR*/
- 0xFFFFFFFF /*DX0DQTR*/
- 0x3DB02000 /*DX0DQSTR*/
- 0x40000000 /*DX1DLLCR*/
- 0xFFFFFFFF /*DX1DQTR*/
- 0x3DB02000 /*DX1DQSTR*/
- 0x40000000 /*DX2DLLCR*/
- 0xFFFFFFFF /*DX2DQTR*/
- 0x3DB02000 /*DX2DQSTR*/
- 0x40000000 /*DX3DLLCR*/
- 0xFFFFFFFF /*DX3DQTR*/
- 0x3DB02000 /*DX3DQSTR*/
- >;
-
status = "okay";
};
};
#define DDRPHY_REG_REG_SIZE 11 /* st,phy-reg */
#define DDRPHY_REG_TIMING_SIZE 10 /* st,phy-timing */
-#define DDRPHY_REG_CAL_SIZE 12 /* st,phy-cal */
#define DDRCTL_REG_REG(x) DDRCTL_REG(x, stm32mp1_ddrctrl_reg)
static const struct reg_desc ddr_reg[DDRCTL_REG_REG_SIZE] = {
DDRPHY_REG_TIMING(mr3),
};
-#define DDRPHY_REG_CAL(x) DDRPHY_REG(x, stm32mp1_ddrphy_cal)
-static const struct reg_desc ddrphy_cal[DDRPHY_REG_CAL_SIZE] = {
- DDRPHY_REG_CAL(dx0dllcr),
- DDRPHY_REG_CAL(dx0dqtr),
- DDRPHY_REG_CAL(dx0dqstr),
- DDRPHY_REG_CAL(dx1dllcr),
- DDRPHY_REG_CAL(dx1dqtr),
- DDRPHY_REG_CAL(dx1dqstr),
- DDRPHY_REG_CAL(dx2dllcr),
- DDRPHY_REG_CAL(dx2dqtr),
- DDRPHY_REG_CAL(dx2dqstr),
- DDRPHY_REG_CAL(dx3dllcr),
- DDRPHY_REG_CAL(dx3dqtr),
- DDRPHY_REG_CAL(dx3dqstr),
-};
-
/**************************************************************
* DYNAMIC REGISTERS: only used for debug purpose (read/modify)
**************************************************************/
DDRPHY_REG_DYN(zq0sr1),
DDRPHY_REG_DYN(dx0gsr0),
DDRPHY_REG_DYN(dx0gsr1),
+ DDRPHY_REG_DYN(dx0dllcr),
+ DDRPHY_REG_DYN(dx0dqtr),
+ DDRPHY_REG_DYN(dx0dqstr),
DDRPHY_REG_DYN(dx1gsr0),
DDRPHY_REG_DYN(dx1gsr1),
+ DDRPHY_REG_DYN(dx1dllcr),
+ DDRPHY_REG_DYN(dx1dqtr),
+ DDRPHY_REG_DYN(dx1dqstr),
DDRPHY_REG_DYN(dx2gsr0),
DDRPHY_REG_DYN(dx2gsr1),
+ DDRPHY_REG_DYN(dx2dllcr),
+ DDRPHY_REG_DYN(dx2dqtr),
+ DDRPHY_REG_DYN(dx2dqstr),
DDRPHY_REG_DYN(dx3gsr0),
DDRPHY_REG_DYN(dx3gsr1),
+ DDRPHY_REG_DYN(dx3dllcr),
+ DDRPHY_REG_DYN(dx3dqtr),
+ DDRPHY_REG_DYN(dx3dqstr),
};
#define DDRPHY_REG_DYN_SIZE ARRAY_SIZE(ddrphy_dyn)
REG_MAP,
REGPHY_REG,
REGPHY_TIMING,
- REGPHY_CAL,
#ifdef CONFIG_STM32MP1_DDR_INTERACTIVE
/* dynamic registers => managed in driver or not changed,
* can be dumped in interactive mode
enum base_type base;
};
-#define DDRPHY_REG_CAL(x) DDRPHY_REG(x, stm32mp1_ddrphy_cal)
-
const struct ddr_reg_info ddr_registers[REG_TYPE_NB] = {
[REG_REG] = {
"static", ddr_reg, DDRCTL_REG_REG_SIZE, DDR_BASE},
"static", ddrphy_reg, DDRPHY_REG_REG_SIZE, DDRPHY_BASE},
[REGPHY_TIMING] = {
"timing", ddrphy_timing, DDRPHY_REG_TIMING_SIZE, DDRPHY_BASE},
-[REGPHY_CAL] = {
- "cal", ddrphy_cal, DDRPHY_REG_CAL_SIZE, DDRPHY_BASE},
#ifdef CONFIG_STM32MP1_DDR_INTERACTIVE
[REG_DYN] = {
"dyn", ddr_dyn, DDR_REG_DYN_SIZE, DDR_BASE},
case REGPHY_TIMING:
par_addr = (u32)&config->p_timing;
break;
- case REGPHY_CAL:
- par_addr = (u32)&config->p_cal;
- break;
case REG_DYN:
case REGPHY_DYN:
case REG_TYPE_NB:
*/
set_reg(priv, REGPHY_REG, &config->p_reg);
set_reg(priv, REGPHY_TIMING, &config->p_timing);
- if (config->p_cal_present)
- set_reg(priv, REGPHY_CAL, &config->p_cal);
if (INTERACTIVE(STEP_PHY_INIT))
goto start;
wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL);
- if (config->p_cal_present) {
- log_debug("DDR DQS training skipped.\n");
- } else {
- log_debug("DDR DQS training : ");
+ log_debug("DDR DQS training : ");
/* 8. Disable Auto refresh and power down by setting
* - RFSHCTL3.dis_au_refresh = 1
* - PWRCTL.powerdown_en = 0
* - DFIMISC.dfiinit_complete_en = 0
*/
- stm32mp1_refresh_disable(priv->ctl);
+ stm32mp1_refresh_disable(priv->ctl);
/* 9. Program PUBL PGCR to enable refresh during training and rank to train
* not done => keep the programed value in PGCR
*/
/* 10. configure PUBL PIR register to specify which training step to run */
- /* RVTRN is excuted only on LPDDR2/LPDDR3 */
- if (config->c_reg.mstr & DDRCTRL_MSTR_DDR3)
- pir = DDRPHYC_PIR_QSTRN;
- else
- pir = DDRPHYC_PIR_QSTRN | DDRPHYC_PIR_RVTRN;
- stm32mp1_ddrphy_init(priv->phy, pir);
+ /* RVTRN is excuted only on LPDDR2/LPDDR3 */
+ if (config->c_reg.mstr & DDRCTRL_MSTR_DDR3)
+ pir = DDRPHYC_PIR_QSTRN;
+ else
+ pir = DDRPHYC_PIR_QSTRN | DDRPHYC_PIR_RVTRN;
+ stm32mp1_ddrphy_init(priv->phy, pir);
/* 11. monitor PUB PGSR.IDONE to poll cpmpletion of training sequence */
- ddrphy_idone_wait(priv->phy);
+ ddrphy_idone_wait(priv->phy);
/* 12. set back registers in step 8 to the orginal values if desidered */
- stm32mp1_refresh_restore(priv->ctl, config->c_reg.rfshctl3,
- config->c_reg.pwrctl);
- } /* if (config->p_cal_present) */
+ stm32mp1_refresh_restore(priv->ctl, config->c_reg.rfshctl3,
+ config->c_reg.pwrctl);
/* enable uMCTL2 AXI port 0 and 1 */
setbits_le32(&priv->ctl->pctrl_0, DDRCTRL_PCTRL_N_PORT_EN);
u32 mr3;
};
-struct stm32mp1_ddrphy_cal {
- u32 dx0dllcr;
- u32 dx0dqtr;
- u32 dx0dqstr;
- u32 dx1dllcr;
- u32 dx1dqtr;
- u32 dx1dqstr;
- u32 dx2dllcr;
- u32 dx2dqtr;
- u32 dx2dqstr;
- u32 dx3dllcr;
- u32 dx3dqtr;
- u32 dx3dqstr;
-};
-
struct stm32mp1_ddr_info {
const char *name;
u32 speed; /* in kHZ */
struct stm32mp1_ddrctrl_perf c_perf;
struct stm32mp1_ddrphy_reg p_reg;
struct stm32mp1_ddrphy_timing p_timing;
- struct stm32mp1_ddrphy_cal p_cal;
- bool p_cal_present;
};
int stm32mp1_ddr_clk_enable(struct ddr_info *priv, u32 mem_speed);
"help displays help\n"
"info displays DDR information\n"
"info <param> <val> changes DDR information\n"
- " with <param> = step, name, size, speed or cal\n"
+ " with <param> = step, name, size or speed\n"
"freq displays the DDR PHY frequency in kHz\n"
"freq <freq> changes the DDR PHY frequency\n"
"param [type|reg] prints input parameters\n"
"\nwith for [type|reg]:\n"
" all registers if absent\n"
" <type> = ctl, phy\n"
- " or one category (static, timing, map, perf, cal, dyn)\n"
+ " or one category (static, timing, map, perf, dyn)\n"
" <reg> = name of the register\n"
};
printf("name = %s\n", config->info.name);
printf("size = 0x%x\n", config->info.size);
printf("speed = %d kHz\n", config->info.speed);
- printf("cal = %d\n", config->p_cal_present);
return;
}
}
return;
}
- if (!strcmp(argv[1], "cal")) {
- if (strict_strtoul(argv[2], 10, &value) < 0 ||
- (value != 0 && value != 1)) {
- printf("invalid value %s\n", argv[2]);
- } else {
- config->p_cal_present = value;
- printf("cal = %d\n", config->p_cal_present);
- }
- return;
- }
printf("argument %s invalid\n", argv[1]);
}
{ .name = x, \
.offset = offsetof(struct stm32mp1_ddr_config, y), \
.size = sizeof(config.y) / sizeof(u32), \
- .present = z, \
}
#define CTL_PARAM(x) PARAM("st,ctl-"#x, c_##x, NULL)
#define PHY_PARAM(x) PARAM("st,phy-"#x, p_##x, NULL)
-#define PHY_PARAM_OPT(x) PARAM("st,phy-"#x, p_##x, &config.p_##x##_present)
const struct {
const char *name; /* name in DT */
const u32 offset; /* offset in config struct */
const u32 size; /* size of parameters */
- bool * const present; /* presence indication for opt */
} param[] = {
CTL_PARAM(reg),
CTL_PARAM(timing),
CTL_PARAM(map),
CTL_PARAM(perf),
PHY_PARAM(reg),
- PHY_PARAM(timing),
- PHY_PARAM_OPT(cal)
+ PHY_PARAM(timing)
};
config.info.speed = ofnode_read_u32_default(node, "st,mem-speed", 0);
param[idx].size);
dev_dbg(dev, "%s: %s[0x%x] = %d\n", __func__,
param[idx].name, param[idx].size, ret);
- if (ret &&
- (ret != -FDT_ERR_NOTFOUND || !param[idx].present)) {
+ if (ret) {
dev_err(dev, "Cannot read %s, error=%d\n",
param[idx].name, ret);
return -EINVAL;
}
- if (param[idx].present) {
- /* save presence of optional parameters */
- *param[idx].present = true;
- if (ret == -FDT_ERR_NOTFOUND) {
- *param[idx].present = false;
-#ifdef CONFIG_STM32MP1_DDR_INTERACTIVE
- /* reset values if used later */
- memset((void *)((u32)&config +
- param[idx].offset),
- 0, param[idx].size * sizeof(u32));
-#endif
- }
- }
}
ret = clk_get_by_name(dev, "axidcg", &axidcg);