1*54fd6939SJiyong Park /*
2*54fd6939SJiyong Park * Copyright 2021 NXP
3*54fd6939SJiyong Park *
4*54fd6939SJiyong Park * SPDX-License-Identifier: BSD-3-Clause
5*54fd6939SJiyong Park *
6*54fd6939SJiyong Park */
7*54fd6939SJiyong Park
8*54fd6939SJiyong Park #include <errno.h>
9*54fd6939SJiyong Park #include <stdbool.h>
10*54fd6939SJiyong Park #include <stdint.h>
11*54fd6939SJiyong Park #include <stdio.h>
12*54fd6939SJiyong Park #include <stdlib.h>
13*54fd6939SJiyong Park
14*54fd6939SJiyong Park #include <common/debug.h>
15*54fd6939SJiyong Park #include <ddr.h>
16*54fd6939SJiyong Park
cal_ddr_sdram_clk_cntl(struct ddr_cfg_regs * regs,const struct memctl_opt * popts)17*54fd6939SJiyong Park static void cal_ddr_sdram_clk_cntl(struct ddr_cfg_regs *regs,
18*54fd6939SJiyong Park const struct memctl_opt *popts)
19*54fd6939SJiyong Park {
20*54fd6939SJiyong Park const unsigned int clk_adj = popts->clk_adj;
21*54fd6939SJiyong Park const unsigned int ss_en = 0U;
22*54fd6939SJiyong Park
23*54fd6939SJiyong Park regs->clk_cntl = ((ss_en & U(0x1)) << 31U) |
24*54fd6939SJiyong Park ((clk_adj & U(0x1F)) << 22U);
25*54fd6939SJiyong Park debug("clk_cntl = 0x%x\n", regs->clk_cntl);
26*54fd6939SJiyong Park }
27*54fd6939SJiyong Park
cal_ddr_cdr(struct ddr_cfg_regs * regs,const struct memctl_opt * popts)28*54fd6939SJiyong Park static void cal_ddr_cdr(struct ddr_cfg_regs *regs,
29*54fd6939SJiyong Park const struct memctl_opt *popts)
30*54fd6939SJiyong Park {
31*54fd6939SJiyong Park regs->cdr[0] = popts->ddr_cdr1;
32*54fd6939SJiyong Park regs->cdr[1] = popts->ddr_cdr2;
33*54fd6939SJiyong Park debug("cdr[0] = 0x%x\n", regs->cdr[0]);
34*54fd6939SJiyong Park debug("cdr[1] = 0x%x\n", regs->cdr[1]);
35*54fd6939SJiyong Park }
36*54fd6939SJiyong Park
cal_ddr_wrlvl_cntl(struct ddr_cfg_regs * regs,const struct memctl_opt * popts)37*54fd6939SJiyong Park static void cal_ddr_wrlvl_cntl(struct ddr_cfg_regs *regs,
38*54fd6939SJiyong Park const struct memctl_opt *popts)
39*54fd6939SJiyong Park {
40*54fd6939SJiyong Park const unsigned int wrlvl_en = 1U; /* enabled */
41*54fd6939SJiyong Park const unsigned int wrlvl_mrd = U(0x6); /* > 40nCK */
42*54fd6939SJiyong Park const unsigned int wrlvl_odten = U(0x7); /* 128 */
43*54fd6939SJiyong Park const unsigned int wrlvl_dqsen = U(0x5); /* > 25nCK */
44*54fd6939SJiyong Park const unsigned int wrlvl_wlr = U(0x6); /* > tWLO + 6 */
45*54fd6939SJiyong Park const unsigned int wrlvl_smpl = popts->wrlvl_override ?
46*54fd6939SJiyong Park popts->wrlvl_sample : U(0xf);
47*54fd6939SJiyong Park const unsigned int wrlvl_start = popts->wrlvl_start;
48*54fd6939SJiyong Park
49*54fd6939SJiyong Park regs->wrlvl_cntl[0] = ((wrlvl_en & U(0x1)) << 31U) |
50*54fd6939SJiyong Park ((wrlvl_mrd & U(0x7)) << 24U) |
51*54fd6939SJiyong Park ((wrlvl_odten & U(0x7)) << 20U) |
52*54fd6939SJiyong Park ((wrlvl_dqsen & U(0x7)) << 16U) |
53*54fd6939SJiyong Park ((wrlvl_smpl & U(0xf)) << 12U) |
54*54fd6939SJiyong Park ((wrlvl_wlr & U(0x7)) << 8U) |
55*54fd6939SJiyong Park ((wrlvl_start & U(0x1F)) << 0U);
56*54fd6939SJiyong Park regs->wrlvl_cntl[1] = popts->wrlvl_ctl_2;
57*54fd6939SJiyong Park regs->wrlvl_cntl[2] = popts->wrlvl_ctl_3;
58*54fd6939SJiyong Park debug("wrlvl_cntl[0] = 0x%x\n", regs->wrlvl_cntl[0]);
59*54fd6939SJiyong Park debug("wrlvl_cntl[1] = 0x%x\n", regs->wrlvl_cntl[1]);
60*54fd6939SJiyong Park debug("wrlvl_cntl[2] = 0x%x\n", regs->wrlvl_cntl[2]);
61*54fd6939SJiyong Park
62*54fd6939SJiyong Park }
63*54fd6939SJiyong Park
cal_ddr_dbg(struct ddr_cfg_regs * regs,const struct memctl_opt * popts)64*54fd6939SJiyong Park static void cal_ddr_dbg(struct ddr_cfg_regs *regs,
65*54fd6939SJiyong Park const struct memctl_opt *popts)
66*54fd6939SJiyong Park {
67*54fd6939SJiyong Park if (popts->cswl_override != 0) {
68*54fd6939SJiyong Park regs->debug[18] = popts->cswl_override;
69*54fd6939SJiyong Park }
70*54fd6939SJiyong Park
71*54fd6939SJiyong Park #ifdef CONFIG_SYS_FSL_DDR_EMU
72*54fd6939SJiyong Park /* disable DDR training for emulator */
73*54fd6939SJiyong Park regs->debug[2] = U(0x00000400);
74*54fd6939SJiyong Park regs->debug[4] = U(0xff800800);
75*54fd6939SJiyong Park regs->debug[5] = U(0x08000800);
76*54fd6939SJiyong Park regs->debug[6] = U(0x08000800);
77*54fd6939SJiyong Park regs->debug[7] = U(0x08000800);
78*54fd6939SJiyong Park regs->debug[8] = U(0x08000800);
79*54fd6939SJiyong Park #endif
80*54fd6939SJiyong Park if (popts->cpo_sample != 0U) {
81*54fd6939SJiyong Park regs->debug[28] = popts->cpo_sample;
82*54fd6939SJiyong Park debug("debug[28] = 0x%x\n", regs->debug[28]);
83*54fd6939SJiyong Park }
84*54fd6939SJiyong Park }
85*54fd6939SJiyong Park
compute_ddr_phy(struct ddr_info * priv)86*54fd6939SJiyong Park int compute_ddr_phy(struct ddr_info *priv)
87*54fd6939SJiyong Park {
88*54fd6939SJiyong Park const struct memctl_opt *popts = &priv->opt;
89*54fd6939SJiyong Park struct ddr_cfg_regs *regs = &priv->ddr_reg;
90*54fd6939SJiyong Park
91*54fd6939SJiyong Park cal_ddr_sdram_clk_cntl(regs, popts);
92*54fd6939SJiyong Park cal_ddr_cdr(regs, popts);
93*54fd6939SJiyong Park cal_ddr_wrlvl_cntl(regs, popts);
94*54fd6939SJiyong Park cal_ddr_dbg(regs, popts);
95*54fd6939SJiyong Park
96*54fd6939SJiyong Park return 0;
97*54fd6939SJiyong Park }
98