1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2017-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 4
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 DMC500 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