1 /*
2 * Copyright (C) 2018 Marvell International Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 * https://spdx.org/licenses
6 */
7
8 /* MCI bus driver for Marvell ARMADA 8K and 8K+ SoCs */
9
10 #include <common/debug.h>
11 #include <drivers/delay_timer.h>
12 #include <drivers/marvell/mci.h>
13 #include <lib/mmio.h>
14
15 #include <mvebu.h>
16 #include <mvebu_def.h>
17 #include <plat_marvell.h>
18
19 /* /HB /Units /Direct_regs /Direct regs
20 * /Configuration Register Write/Read Data Register
21 */
22 #define MCI_WRITE_READ_DATA_REG(mci_index) \
23 MVEBU_MCI_REG_BASE_REMAP(mci_index)
24 /* /HB /Units /Direct_regs /Direct regs
25 * /Configuration Register Access Command Register
26 */
27 #define MCI_ACCESS_CMD_REG(mci_index) \
28 (MVEBU_MCI_REG_BASE_REMAP(mci_index) + 0x4)
29
30 /* Access Command fields :
31 * bit[3:0] - Sub command: 1 => Peripheral Config Register Read,
32 * 0 => Peripheral Config Register Write,
33 * 2 => Peripheral Assign ID request,
34 * 3 => Circular Config Write
35 * bit[5] - 1 => Local (same chip access) 0 => Remote
36 * bit[15:8] - Destination hop ID. Put Global ID (GID) here (see scheme below).
37 * bit[23:22] - 0x3 IHB PHY REG address space, 0x0 IHB Controller space
38 * bit[21:16] - Low 6 bits of offset. Hight 2 bits are taken from bit[28:27]
39 * of IHB_PHY_CTRL
40 * (must be set before any PHY register access occurs):
41 * /IHB_REG /IHB_REGInterchip Hopping Bus Registers
42 * /IHB Version Control Register
43 *
44 * ixi_ihb_top IHB PHY
45 * AXI ----------------------------- -------------
46 * <--| axi_hb_top | ihb_pipe_top |-->| |
47 * -->| GID=1 | GID=0 |<--| |
48 * ----------------------------- -------------
49 */
50 #define MCI_INDIRECT_CTRL_READ_CMD 0x1
51 #define MCI_INDIRECT_CTRL_ASSIGN_CMD 0x2
52 #define MCI_INDIRECT_CTRL_CIRCULAR_CMD 0x3
53 #define MCI_INDIRECT_CTRL_LOCAL_PKT (1 << 5)
54 #define MCI_INDIRECT_CTRL_CMD_DONE_OFFSET 6
55 #define MCI_INDIRECT_CTRL_CMD_DONE \
56 (1 << MCI_INDIRECT_CTRL_CMD_DONE_OFFSET)
57 #define MCI_INDIRECT_CTRL_DATA_READY_OFFSET 7
58 #define MCI_INDIRECT_CTRL_DATA_READY \
59 (1 << MCI_INDIRECT_CTRL_DATA_READY_OFFSET)
60 #define MCI_INDIRECT_CTRL_HOPID_OFFSET 8
61 #define MCI_INDIRECT_CTRL_HOPID(id) \
62 (((id) & 0xFF) << MCI_INDIRECT_CTRL_HOPID_OFFSET)
63 #define MCI_INDIRECT_CTRL_REG_CHIPID_OFFSET 16
64 #define MCI_INDIRECT_REG_CTRL_ADDR(reg_num) \
65 (reg_num << MCI_INDIRECT_CTRL_REG_CHIPID_OFFSET)
66
67 /* Hop ID values */
68 #define GID_IHB_PIPE 0
69 #define GID_AXI_HB 1
70 #define GID_IHB_EXT 2
71
72 #define MCI_DID_GLOBAL_ASSIGNMENT_REQUEST_REG 0x2
73 /* Target MCi Local ID (LID, which is = self DID) */
74 #define MCI_DID_GLOBAL_ASSIGN_REQ_MCI_LOCAL_ID(val) (((val) & 0xFF) << 16)
75 /* Bits [15:8]: Number of MCis on chip of target MCi */
76 #define MCI_DID_GLOBAL_ASSIGN_REQ_MCI_COUNT(val) (((val) & 0xFF) << 8)
77 /* Bits [7:0]: Number of hops on chip of target MCi */
78 #define MCI_DID_GLOBAL_ASSIGN_REQ_HOPS_NUM(val) (((val) & 0xFF) << 0)
79
80 /* IHB_REG domain registers */
81 /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers/
82 * Rx Memory Configuration Register (RX_MEM_CFG)
83 */
84 #define MCI_CTRL_RX_MEM_CFG_REG_NUM 0x0
85 #define MCI_CTRL_RX_TX_MEM_CFG_RQ_THRESH(val) (((val) & 0xFF) << 24)
86 #define MCI_CTRL_RX_TX_MEM_CFG_PQ_THRESH(val) (((val) & 0xFF) << 16)
87 #define MCI_CTRL_RX_TX_MEM_CFG_NQ_THRESH(val) (((val) & 0xFF) << 8)
88 #define MCI_CTRL_RX_TX_MEM_CFG_DELTA_THRESH(val) (((val) & 0xF) << 4)
89 #define MCI_CTRL_RX_TX_MEM_CFG_RTC(val) (((val) & 0x3) << 2)
90 #define MCI_CTRL_RX_TX_MEM_CFG_WTC(val) (((val) & 0x3) << 0)
91 #define MCI_CTRL_RX_MEM_CFG_REG_DEF_CP_VAL \
92 (MCI_CTRL_RX_TX_MEM_CFG_RQ_THRESH(0x07) | \
93 MCI_CTRL_RX_TX_MEM_CFG_PQ_THRESH(0x3f) | \
94 MCI_CTRL_RX_TX_MEM_CFG_NQ_THRESH(0x3f) | \
95 MCI_CTRL_RX_TX_MEM_CFG_DELTA_THRESH(0xf) | \
96 MCI_CTRL_RX_TX_MEM_CFG_RTC(1) | \
97 MCI_CTRL_RX_TX_MEM_CFG_WTC(1))
98
99 #define MCI_CTRL_RX_MEM_CFG_REG_DEF_AP_VAL \
100 (MCI_CTRL_RX_TX_MEM_CFG_RQ_THRESH(0x3f) | \
101 MCI_CTRL_RX_TX_MEM_CFG_PQ_THRESH(0x03) | \
102 MCI_CTRL_RX_TX_MEM_CFG_NQ_THRESH(0x3f) | \
103 MCI_CTRL_RX_TX_MEM_CFG_DELTA_THRESH(0xf) | \
104 MCI_CTRL_RX_TX_MEM_CFG_RTC(1) | \
105 MCI_CTRL_RX_TX_MEM_CFG_WTC(1))
106
107
108 /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers/
109 * Tx Memory Configuration Register (TX_MEM_CFG)
110 */
111 #define MCI_CTRL_TX_MEM_CFG_REG_NUM 0x1
112 /* field mapping for TX mem config register
113 * are the same as for RX register - see register above
114 */
115 #define MCI_CTRL_TX_MEM_CFG_REG_DEF_VAL \
116 (MCI_CTRL_RX_TX_MEM_CFG_RQ_THRESH(0x20) | \
117 MCI_CTRL_RX_TX_MEM_CFG_PQ_THRESH(0x20) | \
118 MCI_CTRL_RX_TX_MEM_CFG_NQ_THRESH(0x20) | \
119 MCI_CTRL_RX_TX_MEM_CFG_DELTA_THRESH(2) | \
120 MCI_CTRL_RX_TX_MEM_CFG_RTC(1) | \
121 MCI_CTRL_RX_TX_MEM_CFG_WTC(1))
122
123 /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers
124 * /IHB Link CRC Control
125 */
126 /* MCi Link CRC Control Register (MCi_CRC_CTRL) */
127 #define MCI_LINK_CRC_CTRL_REG_NUM 0x4
128
129 /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers
130 * /IHB Status Register
131 */
132 /* MCi Status Register (MCi_STS) */
133 #define MCI_CTRL_STATUS_REG_NUM 0x5
134 #define MCI_CTRL_STATUS_REG_PHY_READY (1 << 12)
135 #define MCI_CTRL_STATUS_REG_LINK_PRESENT (1 << 15)
136 #define MCI_CTRL_STATUS_REG_PHY_CID_VIO_OFFSET 24
137 #define MCI_CTRL_STATUS_REG_PHY_CID_VIO_MASK \
138 (0xF << MCI_CTRL_STATUS_REG_PHY_CID_VIO_OFFSET)
139 /* Expected successful Link result, including reserved bit */
140 #define MCI_CTRL_PHY_READY (MCI_CTRL_STATUS_REG_PHY_READY | \
141 MCI_CTRL_STATUS_REG_LINK_PRESENT | \
142 MCI_CTRL_STATUS_REG_PHY_CID_VIO_MASK)
143
144 /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers/
145 * MCi PHY Speed Settings Register (MCi_PHY_SETTING)
146 */
147 #define MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM 0x8
148 #define MCI_CTRL_MCI_PHY_SET_DLO_FIFO_FULL_TRESH(val) (((val) & 0xF) << 28)
149 #define MCI_CTRL_MCI_PHY_SET_PHY_MAX_SPEED(val) (((val) & 0xF) << 12)
150 #define MCI_CTRL_MCI_PHY_SET_PHYCLK_SEL(val) (((val) & 0xF) << 8)
151 #define MCI_CTRL_MCI_PHY_SET_REFCLK_FREQ_SEL(val) (((val) & 0xF) << 4)
152 #define MCI_CTRL_MCI_PHY_SET_AUTO_LINK_EN(val) (((val) & 0x1) << 1)
153 #define MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL \
154 (MCI_CTRL_MCI_PHY_SET_DLO_FIFO_FULL_TRESH(0x3) | \
155 MCI_CTRL_MCI_PHY_SET_PHY_MAX_SPEED(0x3) | \
156 MCI_CTRL_MCI_PHY_SET_PHYCLK_SEL(0x2) | \
157 MCI_CTRL_MCI_PHY_SET_REFCLK_FREQ_SEL(0x1))
158 #define MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL2 \
159 (MCI_CTRL_MCI_PHY_SET_DLO_FIFO_FULL_TRESH(0x3) | \
160 MCI_CTRL_MCI_PHY_SET_PHY_MAX_SPEED(0x3) | \
161 MCI_CTRL_MCI_PHY_SET_PHYCLK_SEL(0x5) | \
162 MCI_CTRL_MCI_PHY_SET_REFCLK_FREQ_SEL(0x1))
163
164 /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers
165 * /IHB Mode Config
166 */
167 #define MCI_CTRL_IHB_MODE_CFG_REG_NUM 0x25
168 #define MCI_CTRL_IHB_MODE_HBCLK_DIV(val) ((val) & 0xFF)
169 #define MCI_CTRL_IHB_MODE_CHUNK_MOD_OFFSET 8
170 #define MCI_CTRL_IHB_MODE_CHUNK_MOD \
171 (1 << MCI_CTRL_IHB_MODE_CHUNK_MOD_OFFSET)
172 #define MCI_CTRL_IHB_MODE_FWD_MOD_OFFSET 9
173 #define MCI_CTRL_IHB_MODE_FWD_MOD \
174 (1 << MCI_CTRL_IHB_MODE_FWD_MOD_OFFSET)
175 #define MCI_CTRL_IHB_MODE_SEQFF_FINE_MOD(val) (((val) & 0xF) << 12)
176 #define MCI_CTRL_IHB_MODE_RX_COMB_THRESH(val) (((val) & 0xFF) << 16)
177 #define MCI_CTRL_IHB_MODE_TX_COMB_THRESH(val) (((val) & 0xFF) << 24)
178
179 #define MCI_CTRL_IHB_MODE_CFG_REG_DEF_VAL \
180 (MCI_CTRL_IHB_MODE_HBCLK_DIV(6) | \
181 MCI_CTRL_IHB_MODE_FWD_MOD | \
182 MCI_CTRL_IHB_MODE_SEQFF_FINE_MOD(0xF) | \
183 MCI_CTRL_IHB_MODE_RX_COMB_THRESH(0x3f) | \
184 MCI_CTRL_IHB_MODE_TX_COMB_THRESH(0x40))
185 /* AXI_HB registers */
186 #define MCI_AXI_ACCESS_DATA_REG_NUM 0x0
187 #define MCI_AXI_ACCESS_PCIE_MODE 1
188 #define MCI_AXI_ACCESS_CACHE_CHECK_OFFSET 5
189 #define MCI_AXI_ACCESS_CACHE_CHECK \
190 (1 << MCI_AXI_ACCESS_CACHE_CHECK_OFFSET)
191 #define MCI_AXI_ACCESS_FORCE_POST_WR_OFFSET 6
192 #define MCI_AXI_ACCESS_FORCE_POST_WR \
193 (1 << MCI_AXI_ACCESS_FORCE_POST_WR_OFFSET)
194 #define MCI_AXI_ACCESS_DISABLE_CLK_GATING_OFFSET 9
195 #define MCI_AXI_ACCESS_DISABLE_CLK_GATING \
196 (1 << MCI_AXI_ACCESS_DISABLE_CLK_GATING_OFFSET)
197
198 /* /HB /Units /HB_REG /HB_REGHopping Bus Registers
199 * /Window 0 Address Mask Register
200 */
201 #define MCI_HB_CTRL_WIN0_ADDRESS_MASK_REG_NUM 0x2
202
203 /* /HB /Units /HB_REG /HB_REGHopping Bus Registers
204 * /Window 0 Destination Register
205 */
206 #define MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM 0x3
207 #define MCI_HB_CTRL_WIN0_DEST_VALID_FLAG(val) (((val) & 0x1) << 16)
208 #define MCI_HB_CTRL_WIN0_DEST_ID(val) (((val) & 0xFF) << 0)
209
210 /* /HB /Units /HB_REG /HB_REGHopping Bus Registers /Tx Control Register */
211 #define MCI_HB_CTRL_TX_CTRL_REG_NUM 0xD
212 #define MCI_HB_CTRL_TX_CTRL_PCIE_MODE_OFFSET 24
213 #define MCI_HB_CTRL_TX_CTRL_PCIE_MODE \
214 (1 << MCI_HB_CTRL_TX_CTRL_PCIE_MODE_OFFSET)
215 #define MCI_HB_CTRL_TX_CTRL_PRI_TH_QOS(val) (((val) & 0xF) << 12)
216 #define MCI_HB_CTRL_TX_CTRL_MAX_RD_CNT(val) (((val) & 0x1F) << 6)
217 #define MCI_HB_CTRL_TX_CTRL_MAX_WR_CNT(val) (((val) & 0x1F) << 0)
218
219 /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers
220 * /IHB Version Control Register
221 */
222 #define MCI_PHY_CTRL_REG_NUM 0x7
223 #define MCI_PHY_CTRL_MCI_MINOR 0x8 /* BITS [3:0] */
224 #define MCI_PHY_CTRL_MCI_MAJOR_OFFSET 4
225 #define MCI_PHY_CTRL_MCI_MAJOR \
226 (1 << MCI_PHY_CTRL_MCI_MAJOR_OFFSET)
227 #define MCI_PHY_CTRL_MCI_SLEEP_REQ_OFFSET 11
228 #define MCI_PHY_CTRL_MCI_SLEEP_REQ \
229 (1 << MCI_PHY_CTRL_MCI_SLEEP_REQ_OFFSET)
230 /* Host=1 / Device=0 PHY mode */
231 #define MCI_PHY_CTRL_MCI_PHY_MODE_OFFSET 24
232 #define MCI_PHY_CTRL_MCI_PHY_MODE_HOST \
233 (1 << MCI_PHY_CTRL_MCI_PHY_MODE_OFFSET)
234 /* Register=1 / PWM=0 interface */
235 #define MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE_OFFSET 25
236 #define MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE \
237 (1 << MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE_OFFSET)
238 /* PHY code InReset=1 */
239 #define MCI_PHY_CTRL_MCI_PHY_RESET_CORE_OFFSET 26
240 #define MCI_PHY_CTRL_MCI_PHY_RESET_CORE \
241 (1 << MCI_PHY_CTRL_MCI_PHY_RESET_CORE_OFFSET)
242 #define MCI_PHY_CTRL_PHY_ADDR_MSB_OFFSET 27
243 #define MCI_PHY_CTRL_PHY_ADDR_MSB(addr) \
244 (((addr) & 0x3) << \
245 MCI_PHY_CTRL_PHY_ADDR_MSB_OFFSET)
246 #define MCI_PHY_CTRL_PIDI_MODE_OFFSET 31
247 #define MCI_PHY_CTRL_PIDI_MODE \
248 (1U << MCI_PHY_CTRL_PIDI_MODE_OFFSET)
249
250 /* Number of times to wait for the MCI link ready after MCI configurations
251 * Normally takes 34-35 successive reads
252 */
253 #define LINK_READY_TIMEOUT 100
254
255 enum mci_register_type {
256 MCI_REG_TYPE_PHY = 0,
257 MCI_REG_TYPE_CTRL,
258 };
259
260 enum {
261 MCI_CMD_WRITE,
262 MCI_CMD_READ
263 };
264
265 /* Write wrapper callback for debug:
266 * will print written data in case LOG_LEVEL >= 40
267 */
mci_mmio_write_32(uintptr_t addr,uint32_t value)268 static void mci_mmio_write_32(uintptr_t addr, uint32_t value)
269 {
270 VERBOSE("Write:\t0x%x = 0x%x\n", (uint32_t)addr, value);
271 mmio_write_32(addr, value);
272 }
273 /* Read wrapper callback for debug:
274 * will print read data in case LOG_LEVEL >= 40
275 */
mci_mmio_read_32(uintptr_t addr)276 static uint32_t mci_mmio_read_32(uintptr_t addr)
277 {
278 uint32_t value;
279
280 value = mmio_read_32(addr);
281 VERBOSE("Read:\t0x%x = 0x%x\n", (uint32_t)addr, value);
282 return value;
283 }
284
285 /* MCI indirect access command completion polling:
286 * Each write/read command done via MCI indirect registers must be polled
287 * for command completions status.
288 *
289 * Returns 1 in case of error
290 * Returns 0 in case of command completed successfully.
291 */
mci_poll_command_completion(int mci_index,int command_type)292 static int mci_poll_command_completion(int mci_index, int command_type)
293 {
294 uint32_t mci_cmd_value = 0, retry_count = 100, ret = 0;
295 uint32_t completion_flags = MCI_INDIRECT_CTRL_CMD_DONE;
296
297 debug_enter();
298 /* Read commands require validating that requested data is ready */
299 if (command_type == MCI_CMD_READ)
300 completion_flags |= MCI_INDIRECT_CTRL_DATA_READY;
301
302 do {
303 /* wait 1 ms before each polling */
304 mdelay(1);
305 mci_cmd_value = mci_mmio_read_32(MCI_ACCESS_CMD_REG(mci_index));
306 } while (((mci_cmd_value & completion_flags) != completion_flags) &&
307 (retry_count-- > 0));
308
309 if (retry_count == 0) {
310 ERROR("%s: MCI command timeout (command status = 0x%x)\n",
311 __func__, mci_cmd_value);
312 ret = 1;
313 }
314
315 debug_exit();
316 return ret;
317 }
318
mci_read(int mci_idx,uint32_t cmd,uint32_t * value)319 int mci_read(int mci_idx, uint32_t cmd, uint32_t *value)
320 {
321 int rval;
322
323 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_idx), cmd);
324
325 rval = mci_poll_command_completion(mci_idx, MCI_CMD_READ);
326
327 *value = mci_mmio_read_32(MCI_WRITE_READ_DATA_REG(mci_idx));
328
329 return rval;
330 }
331
mci_write(int mci_idx,uint32_t cmd,uint32_t data)332 int mci_write(int mci_idx, uint32_t cmd, uint32_t data)
333 {
334 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_idx), data);
335 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_idx), cmd);
336
337 return mci_poll_command_completion(mci_idx, MCI_CMD_WRITE);
338 }
339
340 /* Perform 3 configurations in one command: PCI mode,
341 * queues separation and cache bit
342 */
mci_axi_set_pcie_mode(int mci_index)343 static int mci_axi_set_pcie_mode(int mci_index)
344 {
345 uint32_t reg_data, ret = 1;
346
347 debug_enter();
348 /* This configuration makes MCI IP behave consistently with AXI protocol
349 * It should be configured at one side only (for example locally at AP).
350 * The IP takes care of performing the same configurations at MCI on
351 * another side (for example remotely at CP).
352 */
353 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
354 MCI_AXI_ACCESS_PCIE_MODE |
355 MCI_AXI_ACCESS_CACHE_CHECK |
356 MCI_AXI_ACCESS_FORCE_POST_WR |
357 MCI_AXI_ACCESS_DISABLE_CLK_GATING);
358 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
359 MCI_INDIRECT_REG_CTRL_ADDR(
360 MCI_AXI_ACCESS_DATA_REG_NUM) |
361 MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) |
362 MCI_INDIRECT_CTRL_LOCAL_PKT |
363 MCI_INDIRECT_CTRL_CIRCULAR_CMD);
364
365 /* if Write command was successful, verify PCIe mode */
366 if (mci_poll_command_completion(mci_index, MCI_CMD_WRITE) == 0) {
367 /* Verify the PCIe mode selected */
368 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
369 MCI_INDIRECT_REG_CTRL_ADDR(
370 MCI_HB_CTRL_TX_CTRL_REG_NUM) |
371 MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) |
372 MCI_INDIRECT_CTRL_LOCAL_PKT |
373 MCI_INDIRECT_CTRL_READ_CMD);
374 /* if read was completed, verify PCIe mode */
375 if (mci_poll_command_completion(mci_index, MCI_CMD_READ) == 0) {
376 reg_data = mci_mmio_read_32(
377 MCI_WRITE_READ_DATA_REG(mci_index));
378 if (reg_data & MCI_HB_CTRL_TX_CTRL_PCIE_MODE)
379 ret = 0;
380 }
381 }
382
383 debug_exit();
384 return ret;
385 }
386
387 /* Reduce sequence FIFO timer expiration threshold */
mci_axi_set_fifo_thresh(int mci_index)388 static int mci_axi_set_fifo_thresh(int mci_index)
389 {
390 uint32_t reg_data, ret = 0;
391
392 debug_enter();
393 /* This configuration reduces sequence FIFO timer expiration threshold
394 * (to 0x7 instead of 0xA).
395 * In MCI 1.6 version this configuration prevents possible functional
396 * issues.
397 * In version 1.82 the configuration prevents performance degradation
398 */
399
400 /* Configure local AP side */
401 reg_data = MCI_PHY_CTRL_PIDI_MODE |
402 MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE |
403 MCI_PHY_CTRL_MCI_PHY_MODE_HOST |
404 MCI_PHY_CTRL_MCI_MAJOR |
405 MCI_PHY_CTRL_MCI_MINOR;
406 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), reg_data);
407 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
408 MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM) |
409 MCI_INDIRECT_CTRL_LOCAL_PKT);
410 ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
411
412 /* Reduce the threshold */
413 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
414 MCI_CTRL_IHB_MODE_CFG_REG_DEF_VAL);
415
416 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
417 MCI_INDIRECT_REG_CTRL_ADDR(
418 MCI_CTRL_IHB_MODE_CFG_REG_NUM) |
419 MCI_INDIRECT_CTRL_LOCAL_PKT);
420 ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
421
422 /* Exit PIDI mode */
423 reg_data = MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE |
424 MCI_PHY_CTRL_MCI_PHY_MODE_HOST |
425 MCI_PHY_CTRL_MCI_MAJOR |
426 MCI_PHY_CTRL_MCI_MINOR;
427 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), reg_data);
428 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
429 MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM) |
430 MCI_INDIRECT_CTRL_LOCAL_PKT);
431 ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
432
433 /* Configure remote CP side */
434 reg_data = MCI_PHY_CTRL_PIDI_MODE |
435 MCI_PHY_CTRL_MCI_MAJOR |
436 MCI_PHY_CTRL_MCI_MINOR |
437 MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE;
438 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), reg_data);
439 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
440 MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM) |
441 MCI_CTRL_IHB_MODE_FWD_MOD);
442 ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
443
444 /* Reduce the threshold */
445 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
446 MCI_CTRL_IHB_MODE_CFG_REG_DEF_VAL);
447 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
448 MCI_INDIRECT_REG_CTRL_ADDR(
449 MCI_CTRL_IHB_MODE_CFG_REG_NUM) |
450 MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT));
451 ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
452
453 /* Exit PIDI mode */
454 reg_data = MCI_PHY_CTRL_MCI_MAJOR |
455 MCI_PHY_CTRL_MCI_MINOR |
456 MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE;
457 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), reg_data);
458 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
459 MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM) |
460 MCI_CTRL_IHB_MODE_FWD_MOD);
461
462 ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
463
464 debug_exit();
465 return ret;
466 }
467
468 /* Configure:
469 * 1. AP & CP TX thresholds and delta configurations
470 * 2. DLO & DLI FIFO full threshold
471 * 3. RX thresholds and delta configurations
472 * 4. CP AR and AW outstanding
473 * 5. AP AR and AW outstanding
474 */
mci_axi_set_fifo_rx_tx_thresh(int mci_index)475 static int mci_axi_set_fifo_rx_tx_thresh(int mci_index)
476 {
477 uint32_t ret = 0;
478
479 debug_enter();
480 /* AP TX thresholds and delta configurations (IHB_reg 0x1) */
481 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
482 MCI_CTRL_TX_MEM_CFG_REG_DEF_VAL);
483 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
484 MCI_INDIRECT_REG_CTRL_ADDR(
485 MCI_CTRL_TX_MEM_CFG_REG_NUM) |
486 MCI_INDIRECT_CTRL_LOCAL_PKT);
487 ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
488
489 /* CP TX thresholds and delta configurations (IHB_reg 0x1) */
490 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
491 MCI_CTRL_TX_MEM_CFG_REG_DEF_VAL);
492 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
493 MCI_INDIRECT_REG_CTRL_ADDR(
494 MCI_CTRL_TX_MEM_CFG_REG_NUM) |
495 MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT));
496 ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
497
498 /* AP DLO & DLI FIFO full threshold & Auto-Link enable (IHB_reg 0x8) */
499 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
500 MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL |
501 MCI_CTRL_MCI_PHY_SET_AUTO_LINK_EN(1));
502 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
503 MCI_INDIRECT_REG_CTRL_ADDR(
504 MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM) |
505 MCI_INDIRECT_CTRL_LOCAL_PKT);
506 ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
507
508 /* CP DLO & DLI FIFO full threshold (IHB_reg 0x8) */
509 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
510 MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL);
511 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
512 MCI_INDIRECT_REG_CTRL_ADDR(
513 MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM) |
514 MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT));
515 ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
516
517 /* AP RX thresholds and delta configurations (IHB_reg 0x0) */
518 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
519 MCI_CTRL_RX_MEM_CFG_REG_DEF_AP_VAL);
520 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
521 MCI_INDIRECT_REG_CTRL_ADDR(
522 MCI_CTRL_RX_MEM_CFG_REG_NUM) |
523 MCI_INDIRECT_CTRL_LOCAL_PKT);
524 ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
525
526 /* CP RX thresholds and delta configurations (IHB_reg 0x0) */
527 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
528 MCI_CTRL_RX_MEM_CFG_REG_DEF_CP_VAL);
529 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
530 MCI_INDIRECT_REG_CTRL_ADDR(
531 MCI_CTRL_RX_MEM_CFG_REG_NUM) |
532 MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT));
533 ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
534
535 /* AP AR & AW maximum AXI outstanding request cfg (HB_reg 0xd) */
536 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
537 MCI_HB_CTRL_TX_CTRL_PRI_TH_QOS(8) |
538 MCI_HB_CTRL_TX_CTRL_MAX_RD_CNT(3) |
539 MCI_HB_CTRL_TX_CTRL_MAX_WR_CNT(3));
540 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
541 MCI_INDIRECT_REG_CTRL_ADDR(
542 MCI_HB_CTRL_TX_CTRL_REG_NUM) |
543 MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) |
544 MCI_INDIRECT_CTRL_LOCAL_PKT);
545 ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
546
547 /* CP AR & AW maximum AXI outstanding request cfg (HB_reg 0xd) */
548 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
549 MCI_HB_CTRL_TX_CTRL_PRI_TH_QOS(8) |
550 MCI_HB_CTRL_TX_CTRL_MAX_RD_CNT(0xB) |
551 MCI_HB_CTRL_TX_CTRL_MAX_WR_CNT(0x11));
552 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
553 MCI_INDIRECT_REG_CTRL_ADDR(
554 MCI_HB_CTRL_TX_CTRL_REG_NUM) |
555 MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT) |
556 MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB));
557 ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
558
559 debug_exit();
560 return ret;
561 }
562
563 /* configure MCI to allow read & write transactions to arrive at the same time.
564 * Without the below configuration, MCI won't sent response to CPU for
565 * transactions which arrived simultaneously and will lead to CPU hang.
566 * The below will configure MCI to be able to pass transactions from/to CP/AP.
567 */
mci_enable_simultaneous_transactions(int mci_index)568 static int mci_enable_simultaneous_transactions(int mci_index)
569 {
570 uint32_t ret = 0;
571
572 debug_enter();
573 /* ID assignment (assigning global ID offset to CP) */
574 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
575 MCI_DID_GLOBAL_ASSIGN_REQ_MCI_LOCAL_ID(2) |
576 MCI_DID_GLOBAL_ASSIGN_REQ_MCI_COUNT(2) |
577 MCI_DID_GLOBAL_ASSIGN_REQ_HOPS_NUM(2));
578 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
579 MCI_INDIRECT_REG_CTRL_ADDR(
580 MCI_DID_GLOBAL_ASSIGNMENT_REQUEST_REG) |
581 MCI_INDIRECT_CTRL_ASSIGN_CMD);
582 ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
583
584 /* Assigning dest. ID=3 to all transactions entering from AXI at AP */
585 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
586 MCI_HB_CTRL_WIN0_DEST_VALID_FLAG(1) |
587 MCI_HB_CTRL_WIN0_DEST_ID(3));
588 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
589 MCI_INDIRECT_REG_CTRL_ADDR(
590 MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM) |
591 MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) |
592 MCI_INDIRECT_CTRL_LOCAL_PKT);
593 ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
594
595 /* Assigning dest. ID=1 to all transactions entering from AXI at CP */
596 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
597 MCI_HB_CTRL_WIN0_DEST_VALID_FLAG(1) |
598 MCI_HB_CTRL_WIN0_DEST_ID(1));
599 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
600 MCI_INDIRECT_REG_CTRL_ADDR(
601 MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM) |
602 MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT) |
603 MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB));
604 ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
605
606 /* End address to all transactions entering from AXI at AP.
607 * This will lead to get match for any AXI address
608 * and receive destination ID=3
609 */
610 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), 0xffffffff);
611 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
612 MCI_INDIRECT_REG_CTRL_ADDR(
613 MCI_HB_CTRL_WIN0_ADDRESS_MASK_REG_NUM) |
614 MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) |
615 MCI_INDIRECT_CTRL_LOCAL_PKT);
616 ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
617
618 /* End address to all transactions entering from AXI at CP.
619 * This will lead to get match for any AXI address
620 * and receive destination ID=1
621 */
622 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), 0xffffffff);
623 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
624 MCI_INDIRECT_REG_CTRL_ADDR(
625 MCI_HB_CTRL_WIN0_ADDRESS_MASK_REG_NUM) |
626 MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT) |
627 MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB));
628 ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
629
630 debug_exit();
631 return ret;
632 }
633
634 /* Check if MCI simultaneous transaction was already enabled.
635 * Currently bootrom does this mci configuration only when the boot source is
636 * SAR_MCIX4, in other cases it should be done at this stage.
637 * It is worth noticing that in case of booting from uart, the bootrom
638 * flow is different and this mci initialization is skipped even if boot
639 * source is SAR_MCIX4. Therefore new verification bases on appropriate mci's
640 * register content: if the appropriate reg contains 0x0 it means that the
641 * bootrom didn't perform required mci configuration.
642 *
643 * Returns:
644 * 0 - configuration already done
645 * 1 - configuration missing
646 */
mci_simulatenous_trans_missing(int mci_index)647 static _Bool mci_simulatenous_trans_missing(int mci_index)
648 {
649 uint32_t reg, ret;
650
651 /* read 'Window 0 Destination ID assignment' from HB register 0x3
652 * (TX_CFG_W0_DST_ID) to check whether ID assignment was already
653 * performed by BootROM.
654 */
655 debug_enter();
656 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
657 MCI_INDIRECT_REG_CTRL_ADDR(
658 MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM) |
659 MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) |
660 MCI_INDIRECT_CTRL_LOCAL_PKT |
661 MCI_INDIRECT_CTRL_READ_CMD);
662 ret = mci_poll_command_completion(mci_index, MCI_CMD_READ);
663
664 reg = mci_mmio_read_32(MCI_WRITE_READ_DATA_REG(mci_index));
665
666 if (ret)
667 ERROR("Failed to verify MCI simultaneous read/write status\n");
668
669 debug_exit();
670 /* default ID assignment is 0, so if register doesn't contain zeros
671 * it means that bootrom already performed required configuration.
672 */
673 if (reg != 0)
674 return 0;
675
676 return 1;
677 }
678
679 /* For A1 revision, configure the MCI link for performance improvement:
680 * - set MCI to support read/write transactions to arrive at the same time
681 * - Switch AXI to PCIe mode
682 * - Reduce sequence FIFO threshold
683 * - Configure RX/TX FIFO thresholds
684 *
685 * Note:
686 * We don't exit on error code from any sub routine, to try (best effort) to
687 * complete the MCI configuration.
688 * (If we exit - Bootloader will surely fail to boot)
689 */
mci_configure(int mci_index)690 int mci_configure(int mci_index)
691 {
692 int rval;
693
694 debug_enter();
695 /* According to design guidelines the MCI simultaneous transaction
696 * shouldn't be enabled more then once - therefore make sure that it
697 * wasn't already enabled in bootrom.
698 */
699 if (mci_simulatenous_trans_missing(mci_index)) {
700 VERBOSE("Enabling MCI simultaneous transaction for mci%d\n",
701 mci_index);
702 /* set MCI to support read/write transactions
703 * to arrive at the same time
704 */
705 rval = mci_enable_simultaneous_transactions(mci_index);
706 if (rval)
707 ERROR("Failed to set MCI simultaneous read/write\n");
708 } else
709 VERBOSE("Skip MCI ID assignment - already done by bootrom\n");
710
711 /* Configure MCI for more consistent behavior with AXI protocol */
712 rval = mci_axi_set_pcie_mode(mci_index);
713 if (rval)
714 ERROR("Failed to set MCI to AXI PCIe mode\n");
715
716 /* reduce FIFO global threshold */
717 rval = mci_axi_set_fifo_thresh(mci_index);
718 if (rval)
719 ERROR("Failed to set MCI FIFO global threshold\n");
720
721 /* configure RX/TX FIFO thresholds */
722 rval = mci_axi_set_fifo_rx_tx_thresh(mci_index);
723 if (rval)
724 ERROR("Failed to set MCI RX/TX FIFO threshold\n");
725
726 debug_exit();
727 return 1;
728 }
729
mci_get_link_status(void)730 int mci_get_link_status(void)
731 {
732 uint32_t cmd, data;
733
734 cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_CTRL_STATUS_REG_NUM) |
735 MCI_INDIRECT_CTRL_LOCAL_PKT | MCI_INDIRECT_CTRL_READ_CMD);
736 if (mci_read(0, cmd, &data)) {
737 ERROR("Failed to read status register\n");
738 return -1;
739 }
740
741 /* Check if the link is ready */
742 if (data != MCI_CTRL_PHY_READY) {
743 ERROR("Bad link status %x\n", data);
744 return -1;
745 }
746
747 return 0;
748 }
749
mci_turn_link_down(void)750 void mci_turn_link_down(void)
751 {
752 uint32_t cmd, data;
753 int rval = 0;
754
755 debug_enter();
756
757 /* Turn off auto-link */
758 cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM) |
759 MCI_INDIRECT_CTRL_LOCAL_PKT);
760 data = (MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL2 |
761 MCI_CTRL_MCI_PHY_SET_AUTO_LINK_EN(0));
762 rval = mci_write(0, cmd, data);
763 if (rval)
764 ERROR("Failed to turn off auto-link\n");
765
766 /* Reset AP PHY */
767 cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM) |
768 MCI_INDIRECT_CTRL_LOCAL_PKT);
769 data = (MCI_PHY_CTRL_MCI_MINOR |
770 MCI_PHY_CTRL_MCI_MAJOR |
771 MCI_PHY_CTRL_MCI_PHY_MODE_HOST |
772 MCI_PHY_CTRL_MCI_PHY_RESET_CORE);
773 rval = mci_write(0, cmd, data);
774 if (rval)
775 ERROR("Failed to reset AP PHY\n");
776
777 /* Clear all status & CRC values */
778 cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_LINK_CRC_CTRL_REG_NUM) |
779 MCI_INDIRECT_CTRL_LOCAL_PKT);
780 data = 0x0;
781 mci_write(0, cmd, data);
782 cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_CTRL_STATUS_REG_NUM) |
783 MCI_INDIRECT_CTRL_LOCAL_PKT);
784 data = 0x0;
785 rval = mci_write(0, cmd, data);
786 if (rval)
787 ERROR("Failed to reset AP PHY\n");
788
789 /* Wait 5ms before un-reset the PHY */
790 mdelay(5);
791
792 /* Un-reset AP PHY */
793 cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM) |
794 MCI_INDIRECT_CTRL_LOCAL_PKT);
795 data = (MCI_PHY_CTRL_MCI_MINOR | MCI_PHY_CTRL_MCI_MAJOR |
796 MCI_PHY_CTRL_MCI_PHY_MODE_HOST);
797 rval = mci_write(0, cmd, data);
798 if (rval)
799 ERROR("Failed to un-reset AP PHY\n");
800
801 debug_exit();
802 }
803
mci_turn_link_on(void)804 void mci_turn_link_on(void)
805 {
806 uint32_t cmd, data;
807 int rval = 0;
808
809 debug_enter();
810 /* Turn on auto-link */
811 cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM) |
812 MCI_INDIRECT_CTRL_LOCAL_PKT);
813 data = (MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL2 |
814 MCI_CTRL_MCI_PHY_SET_AUTO_LINK_EN(1));
815 rval = mci_write(0, cmd, data);
816 if (rval)
817 ERROR("Failed to turn on auto-link\n");
818
819 debug_exit();
820 }
821
822 /* Initialize MCI for performance improvements */
mci_link_tune(int mci_index)823 int mci_link_tune(int mci_index)
824 {
825 int ret;
826
827 debug_enter();
828 INFO("MCI%d initialization:\n", mci_index);
829
830 ret = mci_configure(mci_index);
831
832 debug_exit();
833 return ret;
834 }
835