1 /*
2 * Arm SCP/MCP Software
3 * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "config_clock.h"
9 #include "scp_system_mmap.h"
10
11 #include <mod_dmc620.h>
12
13 #include <fwk_element.h>
14 #include <fwk_id.h>
15 #include <fwk_module.h>
16 #include <fwk_module_idx.h>
17
18 #define COL_BITS 2
19 #define BANK_BITS 4
20 #define RANK_BITS 1
21 #define ROW_BITS 5
22 #define BANK_HASH_ENABLE 1
23 #define MEM_TYPE 2
24 #define ADDR_DEC 0x68C
25 #define STRIPE_DEC 1
26 #define MEM_DEVICE_WIDTH 0
27 #define BANK_GROUP 3
28 #define MEM_CHANNEL 2
29 #define ADDRESS_CONTROL_NEXT_VAL ((BANK_HASH_ENABLE << 28) | \
30 (RANK_BITS << 24) | (BANK_BITS << 16) | \
31 (ROW_BITS << 8) | (COL_BITS))
32 #define DECODE_CONTROL_NEXT_VAL ((ADDR_DEC << 10) | (STRIPE_DEC << 4))
33 #define MEMORY_TYPE_NEXT_VAL ((BANK_GROUP << 16) | (MEM_DEVICE_WIDTH << 8) | \
34 (MEM_TYPE))
35
36 struct mod_dmc620_reg dmc_val = {
37 .ADDRESS_CONTROL_NEXT = ADDRESS_CONTROL_NEXT_VAL,
38 .DECODE_CONTROL_NEXT = DECODE_CONTROL_NEXT_VAL,
39 .FORMAT_CONTROL = 0x00000003,
40 .ADDRESS_MAP_NEXT = 0x00000002,
41 .LOW_POWER_CONTROL_NEXT = 0x00000010,
42 .TURNAROUND_CONTROL_NEXT = 0x1F0F0F0F,
43 .HIT_TURNAROUND_CONTROL_NEXT = 0x08909FBF,
44 .QOS_CLASS_CONTROL_NEXT = 0x00000FC8,
45 .ESCALATION_CONTROL_NEXT = 0x00080F00,
46 .QV_CONTROL_31_00_NEXT = 0x76543210,
47 .QV_CONTROL_63_32_NEXT = 0xFEDCBA98,
48 .RT_CONTROL_31_00_NEXT = 0x00000000,
49 .RT_CONTROL_63_32_NEXT = 0x00000000,
50 .TIMEOUT_CONTROL_NEXT = 0x00000001,
51 .CREDIT_CONTROL_NEXT = 0x00000F03,
52 .WRITE_PRIORITY_CONTROL_31_00_NEXT = 0x00000000,
53 .WRITE_PRIORITY_CONTROL_63_32_NEXT = 0xECA86421,
54 .QUEUE_THRESHOLD_CONTROL_31_00_NEXT = 0x00000008,
55 .QUEUE_THRESHOLD_CONTROL_63_32_NEXT = 0x00000000,
56 .ADDRESS_SHUTTER_31_00_NEXT = 0x11111110,
57 .ADDRESS_SHUTTER_63_32_NEXT = 0x11111111,
58 .ADDRESS_SHUTTER_95_64_NEXT = 0x11111111,
59 .ADDRESS_SHUTTER_127_96_NEXT = 0x11111111,
60 .ADDRESS_SHUTTER_159_128_NEXT = 0x11111111,
61 .ADDRESS_SHUTTER_191_160_NEXT = 0x11111111,
62 .MEMORY_ADDRESS_MAX_31_00_NEXT = 0xFFFF001F,
63 .MEMORY_ADDRESS_MAX_43_32_NEXT = 0x00000FFF,
64 .ACCESS_ADDRESS_NEXT = {
65 [0] = {.MIN_31_00 = 0x0000000F, .MIN_43_32 = 0x00000000},
66 [1] = {.MIN_31_00 = 0x0000000F, .MIN_43_32 = 0x00000000},
67 [2] = {.MIN_31_00 = 0x0000000F},
68 [3] = {.MIN_31_00 = 0x0000000F},
69 [4] = {.MIN_31_00 = 0x0000000F},
70 [5] = {.MIN_31_00 = 0x0000000F},
71 [6] = {.MIN_31_00 = 0x0000000F},
72 [7] = {.MIN_31_00 = 0x0000000F},
73 },
74 .DCI_REPLAY_TYPE_NEXT = 0x00000000,
75 .DCI_STRB = 0x00000007,
76 .DCI_DATA = 0x00000000,
77 .REFRESH_CONTROL_NEXT = 0x00000000,
78 .MEMORY_TYPE_NEXT = MEMORY_TYPE_NEXT_VAL,
79 .FEATURE_CONFIG = 0x00001800,
80 .FEATURE_CONTROL_NEXT = 0x00000000,
81 .MUX_CONTROL_NEXT = 0x00000000,
82 .T_REFI_NEXT = 0x90000618,
83 .T_RFC_NEXT = 0x06A8C230,
84 .T_MRR_NEXT = 0x00000001,
85 .T_MRW_NEXT = 0x00010018,
86 .T_RCD_NEXT = 0x00000014,
87 .T_RAS_NEXT = 0x00000034,
88 .T_RP_NEXT = 0x00000014,
89 .T_RPALL_NEXT = 0x00000014,
90 .T_RRD_NEXT = 0x04000805,
91 .T_ACT_WINDOW_NEXT = 0x00001010,
92 .T_RTR_NEXT = 0x14060804,
93 .T_RTW_NEXT = 0x000A0A0A,
94 .T_RTP_NEXT = 0x0000000C,
95 .T_WR_NEXT = 0x0000002C,
96 .T_WTR_NEXT = 0x00022019,
97 .T_WTW_NEXT = 0x14060804,
98 .T_XMPD_NEXT = 0x00000510,
99 .T_EP_NEXT = 0x00000008,
100 .T_XP_NEXT = 0x0014000A,
101 .T_ESR_NEXT = 0x00000009,
102 .T_XSR_NEXT = 0x04000110,
103 .T_ESRCK_NEXT = 0x00000010,
104 .T_CKXSR_NEXT = 0x00000010,
105 .T_CMD_NEXT = 0x00000000,
106 .T_PARITY_NEXT = 0x00001600,
107 .T_ZQCS_NEXT = 0x00000090,
108 .T_RW_ODT_CLR_NEXT = 0x0000005E,
109 .T_RDDATA_EN_NEXT = 0x00000000,
110 .T_PHYWRLAT_NEXT = 0x001F000E,
111 .T_PHYRDLAT_NEXT = 0x0000002E,
112 .RDLVL_CONTROL_NEXT = 0x00000000,
113 .RDLVL_MRS_NEXT = 0x00000424,
114 .T_RDLVL_EN_NEXT = 0x00000001,
115 .T_RDLVL_RR_NEXT = 0x0000001A,
116 .WRLVL_CONTROL_NEXT = 0x00100000,
117 .WRLVL_MRS_NEXT = 0x00000181,
118 .T_WRLVL_EN_NEXT = 0x00000018,
119 .T_WRLVL_WW_NEXT = 0x00000001,
120 .PHY_POWER_CONTROL_NEXT = 0x00000000,
121 .T_LPRESP_NEXT = 0x00000000,
122 .PHY_UPDATE_CONTROL_NEXT = 0x00000000,
123 .T_ODTH_NEXT = 0x00000006,
124 .ODT_TIMING_NEXT = 0x07003900,
125 .ODT_WR_CONTROL_31_00_NEXT = 0x08040201,
126 .ODT_WR_CONTROL_63_32_NEXT = 0x80402010,
127 .ODT_RD_CONTROL_31_00_NEXT = 0x00000000,
128 .ODT_RD_CONTROL_63_32_NEXT = 0x00000000,
129 .ERR0CTLR0 = DMC_ERR0CTRL0_ED_ENABLE |
130 DMC_ERR0CTRL0_DE_ENABLE |
131 DMC_ERR0CTRL0_UI_ENABLE |
132 DMC_ERR0CTRL0_FI_ENABLE |
133 DMC_ERR0CTRL0_CFI_ENABLE,
134 };
135
136 /* Table of DMC620 elements descriptions. */
137 static struct fwk_element dmc620_element_table[] = {
138 [0] = { .name = "DMC620-0",
139 .data = &((struct mod_dmc620_element_config) {
140 .dmc = SCP_DMC0,
141 .ddr_id = FWK_ID_ELEMENT_INIT(
142 FWK_MODULE_IDX_DDR_PHY500, 0),
143 .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK,
144 CLOCK_IDX_INTERCONNECT),
145 }),
146 },
147 [1] = { .name = "DMC620-1",
148 .data = &((struct mod_dmc620_element_config) {
149 .dmc = SCP_DMC1,
150 .ddr_id = FWK_ID_ELEMENT_INIT(
151 FWK_MODULE_IDX_DDR_PHY500, 1),
152 .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK,
153 CLOCK_IDX_INTERCONNECT),
154 }),
155 },
156 [2] = { 0 }, /* Termination description. */
157 };
158
dmc620_get_element_table(fwk_id_t module_id)159 static const struct fwk_element *dmc620_get_element_table(fwk_id_t module_id)
160 {
161 return dmc620_element_table;
162 }
163
direct_ddr_cmd(struct mod_dmc620_reg * dmc)164 static void direct_ddr_cmd(struct mod_dmc620_reg *dmc)
165 {
166 dmc->DIRECT_ADDR = 0x00000004;
167 dmc->DIRECT_CMD = 0x0001000A;
168 dmc->DIRECT_ADDR = 0x00000006;
169 dmc->DIRECT_CMD = 0x00030004;
170 dmc->DIRECT_ADDR = 0x00000000;
171 dmc->DIRECT_CMD = 0x0001000B;
172 dmc->DIRECT_ADDR = 0x00000001;
173 dmc->DIRECT_CMD = 0x0003000B;
174 dmc->DIRECT_ADDR = 0x000003E8;
175 dmc->DIRECT_CMD = 0x0001000D;
176 dmc->DIRECT_ADDR = 0x00000258;
177 dmc->DIRECT_CMD = 0x0001000D;
178 dmc->DIRECT_ADDR = 0x00010001;
179 dmc->DIRECT_CMD = 0x0003000B;
180 dmc->DIRECT_ADDR = 0x0000003C;
181 dmc->DIRECT_CMD = 0x0001000D;
182 dmc->DIRECT_ADDR = 0x00000000;
183 dmc->DIRECT_CMD = 0x00030000;
184 dmc->DIRECT_ADDR = 0x0000003C;
185 dmc->DIRECT_ADDR = 0x00000420;
186 dmc->DIRECT_CMD = 0x00030301;
187 dmc->DIRECT_ADDR = 0x00001000;
188 dmc->DIRECT_CMD = 0x00030601;
189 dmc->DIRECT_ADDR = 0x00000600;
190 dmc->DIRECT_CMD = 0x00030501;
191 dmc->DIRECT_ADDR = 0x00000000;
192 dmc->DIRECT_CMD = 0x30030401;
193 dmc->DIRECT_ADDR = 0x00000028;
194 dmc->DIRECT_CMD = 0x00030201;
195 dmc->DIRECT_ADDR = 0x00000001;
196 dmc->DIRECT_CMD = 0x00030101;
197 dmc->DIRECT_ADDR = 0x00000D50;
198 dmc->DIRECT_CMD = 0x00030001;
199 dmc->DIRECT_ADDR = 0x000003F6;
200 dmc->DIRECT_CMD = 0x0001000D;
201 dmc->DIRECT_ADDR = 0x0000000A;
202 dmc->DIRECT_CMD = 0x0001000D;
203 dmc->DIRECT_ADDR = 0x00000400;
204 dmc->DIRECT_CMD = 0x00030005;
205 dmc->DIRECT_ADDR = 0x000003FF;
206 dmc->DIRECT_CMD = 0x0001000D;
207
208 }
209
210 /* Configuration of the DMC620 module. */
211 const struct fwk_module_config config_dmc620 = {
212 .data =
213 &(struct mod_dmc620_module_config){
214 .dmc_val = &dmc_val,
215 .ddr_module_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_DDR_PHY500),
216 .ddr_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_DDR_PHY500, 0),
217 .direct_ddr_cmd = direct_ddr_cmd,
218 },
219
220 .elements = FWK_MODULE_DYNAMIC_ELEMENTS(dmc620_get_element_table),
221 };
222