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