]> Git Repo - u-boot.git/blob - board/phytium/pomelo/ddr.c
Merge branch 'master' of https://source.denx.de/u-boot/custodians/u-boot-sh
[u-boot.git] / board / phytium / pomelo / ddr.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2021
4  * lixinde         <[email protected]>
5  * weichangzheng   <[email protected]>
6  */
7
8 #include <stdio.h>
9 #include <linux/arm-smccc.h>
10 #include <init.h>
11 #include "cpu.h"
12
13 struct ddr_spd {
14         /******************* read from spd *****************/
15         u8  dimm_type;  /* 1: RDIMM;2: UDIMM;3: SODIMM;4: LRDIMM */
16         u8  data_width; /* 0: x4; 1: x8; 2: x16 */
17         u8  mirror_type;/* 0: stardard; 1: mirror */
18         u8  ecc_type;   /* 0: no-ecc; 1:ecc */
19         u8  dram_type;  /* 0xB: DDR3; 0xC: DDR4 */
20         u8  rank_num;
21         u8  row_num;
22         u8  col_num;
23
24         u8  bg_num;     /*only DDR4*/
25         u8  bank_num;
26         u16 module_manufacturer_id;
27         u16 taamin;
28         u16 trcdmin;
29
30         u16 trpmin;
31         u16 trasmin;
32         u16 trcmin;
33         u16 tfawmin;
34
35         u16 trrd_smin;  /*only DDR4*/
36         u16 trrd_lmin;  /*only DDR4*/
37         u16 tccd_lmin;  /*only DDR4*/
38         u16 twrmin;
39
40         u16 twtr_smin;  /*only DDR4*/
41         u16 twtr_lmin;  /*only DDR4*/
42         u16 twtrmin;    /*only DDR3*/
43         u16 trrdmin;    /*only DDR3*/
44
45         /******************* RCD control words *****************/
46         u8  f0rc03; /*bit[3:2]:CS               bit[1:0]:CA  */
47         u8  f0rc04; /*bit[3:2]:ODT              bit[1:0]:CKE */
48         u8  f0rc05; /*bit[3:2]:CLK-A side       bit[1:0]:CLK-B side */
49         u8  bc00;
50         u8  bc01;
51         u8  bc02;
52         u8  bc03;
53         u8  bc04;
54
55         u8  bc05;
56         u8  f5bc5x;
57         u8  f5bc6x;
58         /******************* LRDIMM special *****************/
59         u8  vrefdq_pr0;
60         u8  vrefdq_mdram;
61         u8  rtt_mdram_1866;
62         u8  rtt_mdram_2400;
63         u8  rtt_mdram_3200;
64
65         u8  drive_dram;
66         u8  odt_dram_1866;
67         u8  odt_dram_2400;
68         u8  odt_dram_3200;
69         u8  park_dram_1866;
70         u8  park_dram_2400;
71         u8  park_dram_3200;
72         u8  rcd_num;
73 } __attribute((aligned(4)));
74
75 struct mcu_config {
76         u32 magic;
77         u32 version;
78         u32 size;
79         u8 rev1[4];
80
81         u8 ch_enable;
82         u8 misc1_enable;
83         u8 misc2_enable;
84         u8 force_spd_enable;
85         u8 misc3_enable;
86         u8 train_debug;
87         u8 train_recover;
88         u8 rev2[9];
89
90         struct ddr_spd ddr_spd_info[2];
91 } __attribute((aligned(4)));
92
93 static void get_mcu_up_info_default(struct mcu_config *pm)
94 {
95         pm->magic               = PARAMETER_MCU_MAGIC;
96         pm->version             = PARAM_MCU_VERSION;
97         pm->size                = PARAM_MCU_SIZE;
98         pm->ch_enable           = PARAM_CH_ENABLE;
99         pm->misc1_enable        = PARAM_ECC_ENABLE;
100         pm->force_spd_enable    = PARAM_FORCE_SPD_DISABLE;
101         pm->misc3_enable        = PARAM_MCU_MISC_ENABLE;
102         pm->train_recover       = 0x0;
103 }
104
105 static u8 init_dimm_param(u8 ch, struct mcu_config *pm)
106 {
107         debug("manual config dimm info...\n");
108         pm->ddr_spd_info[ch].dimm_type = UDIMM_TYPE;
109         pm->ddr_spd_info[ch].data_width = DIMM_X8;
110         pm->ddr_spd_info[ch].mirror_type = NO_MIRROR;
111         pm->ddr_spd_info[ch].ecc_type = NO_ECC_TYPE;
112         pm->ddr_spd_info[ch].dram_type = DDR4_TYPE;
113         pm->ddr_spd_info[ch].rank_num = 1;
114         pm->ddr_spd_info[ch].row_num  = 16;
115         pm->ddr_spd_info[ch].col_num = 10;
116         pm->ddr_spd_info[ch].bg_num = 4;
117         pm->ddr_spd_info[ch].bank_num = 4;
118         pm->ddr_spd_info[ch].taamin = 13750;
119         pm->ddr_spd_info[ch].trcdmin = 13750;
120
121         pm->ddr_spd_info[ch].trpmin = 13750;
122         pm->ddr_spd_info[ch].trasmin = 32000;
123         pm->ddr_spd_info[ch].trcmin =  45750;
124         pm->ddr_spd_info[ch].tfawmin = 21000;
125
126         pm->ddr_spd_info[ch].trrd_smin = 3000;
127         pm->ddr_spd_info[ch].trrd_lmin = 4900;
128         pm->ddr_spd_info[ch].tccd_lmin = 5000;
129         pm->ddr_spd_info[ch].twrmin = 15000;
130
131         pm->ddr_spd_info[ch].twtr_smin = 2500;
132         pm->ddr_spd_info[ch].twtr_lmin = 7500;
133
134         return 0;
135 }
136
137 void get_default_mcu_info(u8 *data)
138 {
139         get_mcu_up_info_default((struct mcu_config *)data);
140 }
141
142 void fix_mcu_info(u8 *data)
143 {
144         struct mcu_config *mcu_info = (struct mcu_config *)data;
145
146         for (int ch = 0; ch < 2; ch++)
147                 init_dimm_param(ch, mcu_info);
148 }
149
150 void ddr_init(void)
151 {
152         u8 buffer[0x100];
153         struct arm_smccc_res res;
154
155         get_default_mcu_info(buffer);
156         fix_mcu_info(buffer);
157
158         arm_smccc_smc(CPU_INIT_MEM, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
159         if (res.a0 != 0)
160                 panic("DRAM init failed :0x%lx\n", res.a0);
161 }
This page took 0.035839 seconds and 4 git commands to generate.