2 * Copyright (C) 2018 Marvell International Ltd.
4 * SPDX-License-Identifier: BSD-3-Clause
5 * https://spdx.org/licenses
8 /* MCI bus driver for Marvell ARMADA 8K and 8K+ SoCs */
10 #include <common/debug.h>
11 #include <drivers/delay_timer.h>
12 #include <drivers/marvell/mci.h>
16 #include <mvebu_def.h>
17 #include <plat_marvell.h>
19 /* /HB /Units /Direct_regs /Direct regs
20 * /Configuration Register Write/Read Data Register
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
27 #define MCI_ACCESS_CMD_REG(mci_index) \
28 (MVEBU_MCI_REG_BASE_REMAP(mci_index) + 0x4)
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]
40 * (must be set before any PHY register access occurs):
41 * /IHB_REG /IHB_REGInterchip Hopping Bus Registers
42 * /IHB Version Control Register
45 * AXI ----------------------------- -------------
46 * <--| axi_hb_top | ihb_pipe_top |-->| |
47 * -->| GID=1 | GID=0 |<--| |
48 * ----------------------------- -------------
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)
68 #define GID_IHB_PIPE 0
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)
80 /* IHB_REG domain registers */
81 /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers/
82 * Rx Memory Configuration Register (RX_MEM_CFG)
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))
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))
108 /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers/
109 * Tx Memory Configuration Register (TX_MEM_CFG)
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
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))
123 /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers
124 * /IHB Link CRC Control
126 /* MCi Link CRC Control Register (MCi_CRC_CTRL) */
127 #define MCI_LINK_CRC_CTRL_REG_NUM 0x4
129 /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers
130 * /IHB Status Register
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)
144 /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers/
145 * MCi PHY Speed Settings Register (MCi_PHY_SETTING)
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))
164 /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers
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)
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)
198 /* /HB /Units /HB_REG /HB_REGHopping Bus Registers
199 * /Window 0 Address Mask Register
201 #define MCI_HB_CTRL_WIN0_ADDRESS_MASK_REG_NUM 0x2
203 /* /HB /Units /HB_REG /HB_REGHopping Bus Registers
204 * /Window 0 Destination Register
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)
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)
219 /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers
220 * /IHB Version Control Register
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) \
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 (1 << MCI_PHY_CTRL_PIDI_MODE_OFFSET)
250 /* Number of times to wait for the MCI link ready after MCI configurations
251 * Normally takes 34-35 successive reads
253 #define LINK_READY_TIMEOUT 100
255 enum mci_register_type
{
256 MCI_REG_TYPE_PHY
= 0,
265 /* Write wrapper callback for debug:
266 * will print written data in case LOG_LEVEL >= 40
268 static void mci_mmio_write_32(uintptr_t addr
, uint32_t value
)
270 VERBOSE("Write:\t0x%x = 0x%x\n", (uint32_t)addr
, value
);
271 mmio_write_32(addr
, value
);
273 /* Read wrapper callback for debug:
274 * will print read data in case LOG_LEVEL >= 40
276 static uint32_t mci_mmio_read_32(uintptr_t addr
)
280 value
= mmio_read_32(addr
);
281 VERBOSE("Read:\t0x%x = 0x%x\n", (uint32_t)addr
, value
);
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.
289 * Returns 1 in case of error
290 * Returns 0 in case of command completed successfully.
292 static int mci_poll_command_completion(int mci_index
, int command_type
)
294 uint32_t mci_cmd_value
= 0, retry_count
= 100, ret
= 0;
295 uint32_t completion_flags
= MCI_INDIRECT_CTRL_CMD_DONE
;
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
;
303 /* wait 1 ms before each polling */
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));
309 if (retry_count
== 0) {
310 ERROR("%s: MCI command timeout (command status = 0x%x)\n",
311 __func__
, mci_cmd_value
);
319 int mci_read(int mci_idx
, uint32_t cmd
, uint32_t *value
)
323 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_idx
), cmd
);
325 rval
= mci_poll_command_completion(mci_idx
, MCI_CMD_READ
);
327 *value
= mci_mmio_read_32(MCI_WRITE_READ_DATA_REG(mci_idx
));
332 int mci_write(int mci_idx
, uint32_t cmd
, uint32_t data
)
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
);
337 return mci_poll_command_completion(mci_idx
, MCI_CMD_WRITE
);
340 /* Perform 3 configurations in one command: PCI mode,
341 * queues separation and cache bit
343 static int mci_axi_set_pcie_mode(int mci_index
)
345 uint32_t reg_data
, ret
= 1;
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).
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
);
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
)
387 /* Reduce sequence FIFO timer expiration threshold */
388 static int mci_axi_set_fifo_thresh(int mci_index
)
390 uint32_t reg_data
, ret
= 0;
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
397 * In version 1.82 the configuration prevents performance degradation
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
);
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
);
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
);
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
);
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
);
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
);
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
);
462 ret
|= mci_poll_command_completion(mci_index
, MCI_CMD_WRITE
);
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
475 static int mci_axi_set_fifo_rx_tx_thresh(int mci_index
)
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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.
568 static int mci_enable_simultaneous_transactions(int mci_index
)
573 /* ID assignment (assigning global ID offset to CP) */
574 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0),
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(0),
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
);
584 /* Assigning dest. ID=3 to all transactions entering from AXI at AP */
585 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0),
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(0),
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
);
595 /* Assigning dest. ID=1 to all transactions entering from AXI at CP */
596 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0),
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(0),
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
);
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
610 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0), 0xffffffff);
611 mci_mmio_write_32(MCI_ACCESS_CMD_REG(0),
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
);
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
622 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0), 0xffffffff);
623 mci_mmio_write_32(MCI_ACCESS_CMD_REG(0),
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
);
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.
644 * 0 - configuration already done
645 * 1 - configuration missing
647 static _Bool
mci_simulatenous_trans_missing(int mci_index
)
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.
656 mci_mmio_write_32(MCI_ACCESS_CMD_REG(0),
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
);
664 reg
= mci_mmio_read_32(MCI_WRITE_READ_DATA_REG(mci_index
));
667 ERROR("Failed to verify MCI simultaneous read/write status\n");
670 /* default ID assignment is 0, so if register doesn't contain zeros
671 * it means that bootrom already performed required configuration.
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
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)
690 int mci_configure(int mci_index
)
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.
699 if (mci_simulatenous_trans_missing(mci_index
)) {
700 VERBOSE("Enabling MCI simultaneous transaction\n");
701 /* set MCI to support read/write transactions
702 * to arrive at the same time
704 rval
= mci_enable_simultaneous_transactions(mci_index
);
706 ERROR("Failed to set MCI simultaneous read/write\n");
708 VERBOSE("Skip MCI ID assignment - already done by bootrom\n");
710 /* Configure MCI for more consistent behavior with AXI protocol */
711 rval
= mci_axi_set_pcie_mode(mci_index
);
713 ERROR("Failed to set MCI to AXI PCIe mode\n");
715 /* reduce FIFO global threshold */
716 rval
= mci_axi_set_fifo_thresh(mci_index
);
718 ERROR("Failed to set MCI FIFO global threshold\n");
720 /* configure RX/TX FIFO thresholds */
721 rval
= mci_axi_set_fifo_rx_tx_thresh(mci_index
);
723 ERROR("Failed to set MCI RX/TX FIFO threshold\n");
729 int mci_get_link_status(void)
733 cmd
= (MCI_INDIRECT_REG_CTRL_ADDR(MCI_CTRL_STATUS_REG_NUM
) |
734 MCI_INDIRECT_CTRL_LOCAL_PKT
| MCI_INDIRECT_CTRL_READ_CMD
);
735 if (mci_read(0, cmd
, &data
)) {
736 ERROR("Failed to read status register\n");
740 /* Check if the link is ready */
741 if (data
!= MCI_CTRL_PHY_READY
) {
742 ERROR("Bad link status %x\n", data
);
749 void mci_turn_link_down(void)
756 /* Turn off auto-link */
757 cmd
= (MCI_INDIRECT_REG_CTRL_ADDR(MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM
) |
758 MCI_INDIRECT_CTRL_LOCAL_PKT
);
759 data
= (MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL2
|
760 MCI_CTRL_MCI_PHY_SET_AUTO_LINK_EN(0));
761 rval
= mci_write(0, cmd
, data
);
763 ERROR("Failed to turn off auto-link\n");
766 cmd
= (MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM
) |
767 MCI_INDIRECT_CTRL_LOCAL_PKT
);
768 data
= (MCI_PHY_CTRL_MCI_MINOR
|
769 MCI_PHY_CTRL_MCI_MAJOR
|
770 MCI_PHY_CTRL_MCI_PHY_MODE_HOST
|
771 MCI_PHY_CTRL_MCI_PHY_RESET_CORE
);
772 rval
= mci_write(0, cmd
, data
);
774 ERROR("Failed to reset AP PHY\n");
776 /* Clear all status & CRC values */
777 cmd
= (MCI_INDIRECT_REG_CTRL_ADDR(MCI_LINK_CRC_CTRL_REG_NUM
) |
778 MCI_INDIRECT_CTRL_LOCAL_PKT
);
780 mci_write(0, cmd
, data
);
781 cmd
= (MCI_INDIRECT_REG_CTRL_ADDR(MCI_CTRL_STATUS_REG_NUM
) |
782 MCI_INDIRECT_CTRL_LOCAL_PKT
);
784 rval
= mci_write(0, cmd
, data
);
786 ERROR("Failed to reset AP PHY\n");
788 /* Wait 5ms before un-reset the PHY */
791 /* Un-reset AP PHY */
792 cmd
= (MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM
) |
793 MCI_INDIRECT_CTRL_LOCAL_PKT
);
794 data
= (MCI_PHY_CTRL_MCI_MINOR
| MCI_PHY_CTRL_MCI_MAJOR
|
795 MCI_PHY_CTRL_MCI_PHY_MODE_HOST
);
796 rval
= mci_write(0, cmd
, data
);
798 ERROR("Failed to un-reset AP PHY\n");
803 void mci_turn_link_on(void)
809 /* Turn on auto-link */
810 cmd
= (MCI_INDIRECT_REG_CTRL_ADDR(MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM
) |
811 MCI_INDIRECT_CTRL_LOCAL_PKT
);
812 data
= (MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL2
|
813 MCI_CTRL_MCI_PHY_SET_AUTO_LINK_EN(1));
814 rval
= mci_write(0, cmd
, data
);
816 ERROR("Failed to turn on auto-link\n");
821 /* Initialize MCI for performance improvements */
822 int mci_initialize(int mci_index
)
827 INFO("MCI%d initialization:\n", mci_index
);
829 ret
= mci_configure(mci_index
);