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 */
11 #include <delay_timer.h>
15 #include <mvebu_def.h>
16 #include <plat_marvell.h>
18 /* /HB /Units /Direct_regs /Direct regs
19 * /Configuration Register Write/Read Data Register
21 #define MCI_WRITE_READ_DATA_REG(mci_index) \
22 MVEBU_MCI_REG_BASE_REMAP(mci_index)
23 /* /HB /Units /Direct_regs /Direct regs
24 * /Configuration Register Access Command Register
26 #define MCI_ACCESS_CMD_REG(mci_index) \
27 (MVEBU_MCI_REG_BASE_REMAP(mci_index) + 0x4)
29 /* Access Command fields :
30 * bit[3:0] - Sub command: 1 => Peripheral Config Register Read,
31 * 0 => Peripheral Config Register Write,
32 * 2 => Peripheral Assign ID request,
33 * 3 => Circular Config Write
34 * bit[5] - 1 => Local (same chip access) 0 => Remote
35 * bit[15:8] - Destination hop ID. Put Global ID (GID) here (see scheme below).
36 * bit[23:22] - 0x3 IHB PHY REG address space, 0x0 IHB Controller space
37 * bit[21:16] - Low 6 bits of offset. Hight 2 bits are taken from bit[28:27]
39 * (must be set before any PHY register access occurs):
40 * /IHB_REG /IHB_REGInterchip Hopping Bus Registers
41 * /IHB Version Control Register
44 * AXI ----------------------------- -------------
45 * <--| axi_hb_top | ihb_pipe_top |-->| |
46 * -->| GID=1 | GID=0 |<--| |
47 * ----------------------------- -------------
49 #define MCI_INDIRECT_CTRL_READ_CMD 0x1
50 #define MCI_INDIRECT_CTRL_ASSIGN_CMD 0x2
51 #define MCI_INDIRECT_CTRL_CIRCULAR_CMD 0x3
52 #define MCI_INDIRECT_CTRL_LOCAL_PKT (1 << 5)
53 #define MCI_INDIRECT_CTRL_CMD_DONE_OFFSET 6
54 #define MCI_INDIRECT_CTRL_CMD_DONE \
55 (1 << MCI_INDIRECT_CTRL_CMD_DONE_OFFSET)
56 #define MCI_INDIRECT_CTRL_DATA_READY_OFFSET 7
57 #define MCI_INDIRECT_CTRL_DATA_READY \
58 (1 << MCI_INDIRECT_CTRL_DATA_READY_OFFSET)
59 #define MCI_INDIRECT_CTRL_HOPID_OFFSET 8
60 #define MCI_INDIRECT_CTRL_HOPID(id) \
61 (((id) & 0xFF) << MCI_INDIRECT_CTRL_HOPID_OFFSET)
62 #define MCI_INDIRECT_CTRL_REG_CHIPID_OFFSET 16
63 #define MCI_INDIRECT_REG_CTRL_ADDR(reg_num) \
64 (reg_num << MCI_INDIRECT_CTRL_REG_CHIPID_OFFSET)
67 #define GID_IHB_PIPE 0
71 #define MCI_DID_GLOBAL_ASSIGNMENT_REQUEST_REG 0x2
72 /* Target MCi Local ID (LID, which is = self DID) */
73 #define MCI_DID_GLOBAL_ASSIGN_REQ_MCI_LOCAL_ID(val) (((val) & 0xFF) << 16)
74 /* Bits [15:8]: Number of MCis on chip of target MCi */
75 #define MCI_DID_GLOBAL_ASSIGN_REQ_MCI_COUNT(val) (((val) & 0xFF) << 8)
76 /* Bits [7:0]: Number of hops on chip of target MCi */
77 #define MCI_DID_GLOBAL_ASSIGN_REQ_HOPS_NUM(val) (((val) & 0xFF) << 0)
79 /* IHB_REG domain registers */
80 /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers/
81 * Rx Memory Configuration Register (RX_MEM_CFG)
83 #define MCI_CTRL_RX_MEM_CFG_REG_NUM 0x0
84 #define MCI_CTRL_RX_TX_MEM_CFG_RQ_THRESH(val) (((val) & 0xFF) << 24)
85 #define MCI_CTRL_RX_TX_MEM_CFG_PQ_THRESH(val) (((val) & 0xFF) << 16)
86 #define MCI_CTRL_RX_TX_MEM_CFG_NQ_THRESH(val) (((val) & 0xFF) << 8)
87 #define MCI_CTRL_RX_TX_MEM_CFG_DELTA_THRESH(val) (((val) & 0xF) << 4)
88 #define MCI_CTRL_RX_TX_MEM_CFG_RTC(val) (((val) & 0x3) << 2)
89 #define MCI_CTRL_RX_TX_MEM_CFG_WTC(val) (((val) & 0x3) << 0)
90 #define MCI_CTRL_RX_MEM_CFG_REG_DEF_CP_VAL \
91 (MCI_CTRL_RX_TX_MEM_CFG_RQ_THRESH(0x07) | \
92 MCI_CTRL_RX_TX_MEM_CFG_PQ_THRESH(0x3f) | \
93 MCI_CTRL_RX_TX_MEM_CFG_NQ_THRESH(0x3f) | \
94 MCI_CTRL_RX_TX_MEM_CFG_DELTA_THRESH(0xf) | \
95 MCI_CTRL_RX_TX_MEM_CFG_RTC(1) | \
96 MCI_CTRL_RX_TX_MEM_CFG_WTC(1))
98 #define MCI_CTRL_RX_MEM_CFG_REG_DEF_AP_VAL \
99 (MCI_CTRL_RX_TX_MEM_CFG_RQ_THRESH(0x3f) | \
100 MCI_CTRL_RX_TX_MEM_CFG_PQ_THRESH(0x03) | \
101 MCI_CTRL_RX_TX_MEM_CFG_NQ_THRESH(0x3f) | \
102 MCI_CTRL_RX_TX_MEM_CFG_DELTA_THRESH(0xf) | \
103 MCI_CTRL_RX_TX_MEM_CFG_RTC(1) | \
104 MCI_CTRL_RX_TX_MEM_CFG_WTC(1))
107 /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers/
108 * Tx Memory Configuration Register (TX_MEM_CFG)
110 #define MCI_CTRL_TX_MEM_CFG_REG_NUM 0x1
111 /* field mapping for TX mem config register
112 * are the same as for RX register - see register above
114 #define MCI_CTRL_TX_MEM_CFG_REG_DEF_VAL \
115 (MCI_CTRL_RX_TX_MEM_CFG_RQ_THRESH(0x20) | \
116 MCI_CTRL_RX_TX_MEM_CFG_PQ_THRESH(0x20) | \
117 MCI_CTRL_RX_TX_MEM_CFG_NQ_THRESH(0x20) | \
118 MCI_CTRL_RX_TX_MEM_CFG_DELTA_THRESH(2) | \
119 MCI_CTRL_RX_TX_MEM_CFG_RTC(1) | \
120 MCI_CTRL_RX_TX_MEM_CFG_WTC(1))
122 /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers
123 * /IHB Link CRC Control
125 /* MCi Link CRC Control Register (MCi_CRC_CTRL) */
126 #define MCI_LINK_CRC_CTRL_REG_NUM 0x4
128 /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers
129 * /IHB Status Register
131 /* MCi Status Register (MCi_STS) */
132 #define MCI_CTRL_STATUS_REG_NUM 0x5
133 #define MCI_CTRL_STATUS_REG_PHY_READY (1 << 12)
134 #define MCI_CTRL_STATUS_REG_LINK_PRESENT (1 << 15)
135 #define MCI_CTRL_STATUS_REG_PHY_CID_VIO_OFFSET 24
136 #define MCI_CTRL_STATUS_REG_PHY_CID_VIO_MASK \
137 (0xF << MCI_CTRL_STATUS_REG_PHY_CID_VIO_OFFSET)
138 /* Expected successful Link result, including reserved bit */
139 #define MCI_CTRL_PHY_READY (MCI_CTRL_STATUS_REG_PHY_READY | \
140 MCI_CTRL_STATUS_REG_LINK_PRESENT | \
141 MCI_CTRL_STATUS_REG_PHY_CID_VIO_MASK)
143 /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers/
144 * MCi PHY Speed Settings Register (MCi_PHY_SETTING)
146 #define MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM 0x8
147 #define MCI_CTRL_MCI_PHY_SET_DLO_FIFO_FULL_TRESH(val) (((val) & 0xF) << 28)
148 #define MCI_CTRL_MCI_PHY_SET_PHY_MAX_SPEED(val) (((val) & 0xF) << 12)
149 #define MCI_CTRL_MCI_PHY_SET_PHYCLK_SEL(val) (((val) & 0xF) << 8)
150 #define MCI_CTRL_MCI_PHY_SET_REFCLK_FREQ_SEL(val) (((val) & 0xF) << 4)
151 #define MCI_CTRL_MCI_PHY_SET_AUTO_LINK_EN(val) (((val) & 0x1) << 1)
152 #define MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL \
153 (MCI_CTRL_MCI_PHY_SET_DLO_FIFO_FULL_TRESH(0x3) | \
154 MCI_CTRL_MCI_PHY_SET_PHY_MAX_SPEED(0x3) | \
155 MCI_CTRL_MCI_PHY_SET_PHYCLK_SEL(0x2) | \
156 MCI_CTRL_MCI_PHY_SET_REFCLK_FREQ_SEL(0x1))
157 #define MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL2 \
158 (MCI_CTRL_MCI_PHY_SET_DLO_FIFO_FULL_TRESH(0x3) | \
159 MCI_CTRL_MCI_PHY_SET_PHY_MAX_SPEED(0x3) | \
160 MCI_CTRL_MCI_PHY_SET_PHYCLK_SEL(0x5) | \
161 MCI_CTRL_MCI_PHY_SET_REFCLK_FREQ_SEL(0x1))
163 /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers
166 #define MCI_CTRL_IHB_MODE_CFG_REG_NUM 0x25
167 #define MCI_CTRL_IHB_MODE_HBCLK_DIV(val) ((val) & 0xFF)
168 #define MCI_CTRL_IHB_MODE_CHUNK_MOD_OFFSET 8
169 #define MCI_CTRL_IHB_MODE_CHUNK_MOD \
170 (1 << MCI_CTRL_IHB_MODE_CHUNK_MOD_OFFSET)
171 #define MCI_CTRL_IHB_MODE_FWD_MOD_OFFSET 9
172 #define MCI_CTRL_IHB_MODE_FWD_MOD \
173 (1 << MCI_CTRL_IHB_MODE_FWD_MOD_OFFSET)
174 #define MCI_CTRL_IHB_MODE_SEQFF_FINE_MOD(val) (((val) & 0xF) << 12)
175 #define MCI_CTRL_IHB_MODE_RX_COMB_THRESH(val) (((val) & 0xFF) << 16)
176 #define MCI_CTRL_IHB_MODE_TX_COMB_THRESH(val) (((val) & 0xFF) << 24)
178 #define MCI_CTRL_IHB_MODE_CFG_REG_DEF_VAL \
179 (MCI_CTRL_IHB_MODE_HBCLK_DIV(6) | \
180 MCI_CTRL_IHB_MODE_FWD_MOD | \
181 MCI_CTRL_IHB_MODE_SEQFF_FINE_MOD(0xF) | \
182 MCI_CTRL_IHB_MODE_RX_COMB_THRESH(0x3f) | \
183 MCI_CTRL_IHB_MODE_TX_COMB_THRESH(0x40))
184 /* AXI_HB registers */
185 #define MCI_AXI_ACCESS_DATA_REG_NUM 0x0
186 #define MCI_AXI_ACCESS_PCIE_MODE 1
187 #define MCI_AXI_ACCESS_CACHE_CHECK_OFFSET 5
188 #define MCI_AXI_ACCESS_CACHE_CHECK \
189 (1 << MCI_AXI_ACCESS_CACHE_CHECK_OFFSET)
190 #define MCI_AXI_ACCESS_FORCE_POST_WR_OFFSET 6
191 #define MCI_AXI_ACCESS_FORCE_POST_WR \
192 (1 << MCI_AXI_ACCESS_FORCE_POST_WR_OFFSET)
193 #define MCI_AXI_ACCESS_DISABLE_CLK_GATING_OFFSET 9
194 #define MCI_AXI_ACCESS_DISABLE_CLK_GATING \
195 (1 << MCI_AXI_ACCESS_DISABLE_CLK_GATING_OFFSET)
197 /* /HB /Units /HB_REG /HB_REGHopping Bus Registers
198 * /Window 0 Address Mask Register
200 #define MCI_HB_CTRL_WIN0_ADDRESS_MASK_REG_NUM 0x2
202 /* /HB /Units /HB_REG /HB_REGHopping Bus Registers
203 * /Window 0 Destination Register
205 #define MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM 0x3
206 #define MCI_HB_CTRL_WIN0_DEST_VALID_FLAG(val) (((val) & 0x1) << 16)
207 #define MCI_HB_CTRL_WIN0_DEST_ID(val) (((val) & 0xFF) << 0)
209 /* /HB /Units /HB_REG /HB_REGHopping Bus Registers /Tx Control Register */
210 #define MCI_HB_CTRL_TX_CTRL_REG_NUM 0xD
211 #define MCI_HB_CTRL_TX_CTRL_PCIE_MODE_OFFSET 24
212 #define MCI_HB_CTRL_TX_CTRL_PCIE_MODE \
213 (1 << MCI_HB_CTRL_TX_CTRL_PCIE_MODE_OFFSET)
214 #define MCI_HB_CTRL_TX_CTRL_PRI_TH_QOS(val) (((val) & 0xF) << 12)
215 #define MCI_HB_CTRL_TX_CTRL_MAX_RD_CNT(val) (((val) & 0x1F) << 6)
216 #define MCI_HB_CTRL_TX_CTRL_MAX_WR_CNT(val) (((val) & 0x1F) << 0)
218 /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers
219 * /IHB Version Control Register
221 #define MCI_PHY_CTRL_REG_NUM 0x7
222 #define MCI_PHY_CTRL_MCI_MINOR 0x8 /* BITS [3:0] */
223 #define MCI_PHY_CTRL_MCI_MAJOR_OFFSET 4
224 #define MCI_PHY_CTRL_MCI_MAJOR \
225 (1 << MCI_PHY_CTRL_MCI_MAJOR_OFFSET)
226 #define MCI_PHY_CTRL_MCI_SLEEP_REQ_OFFSET 11
227 #define MCI_PHY_CTRL_MCI_SLEEP_REQ \
228 (1 << MCI_PHY_CTRL_MCI_SLEEP_REQ_OFFSET)
229 /* Host=1 / Device=0 PHY mode */
230 #define MCI_PHY_CTRL_MCI_PHY_MODE_OFFSET 24
231 #define MCI_PHY_CTRL_MCI_PHY_MODE_HOST \
232 (1 << MCI_PHY_CTRL_MCI_PHY_MODE_OFFSET)
233 /* Register=1 / PWM=0 interface */
234 #define MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE_OFFSET 25
235 #define MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE \
236 (1 << MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE_OFFSET)
237 /* PHY code InReset=1 */
238 #define MCI_PHY_CTRL_MCI_PHY_RESET_CORE_OFFSET 26
239 #define MCI_PHY_CTRL_MCI_PHY_RESET_CORE \
240 (1 << MCI_PHY_CTRL_MCI_PHY_RESET_CORE_OFFSET)
241 #define MCI_PHY_CTRL_PHY_ADDR_MSB_OFFSET 27
242 #define MCI_PHY_CTRL_PHY_ADDR_MSB(addr) \
244 MCI_PHY_CTRL_PHY_ADDR_MSB_OFFSET)
245 #define MCI_PHY_CTRL_PIDI_MODE_OFFSET 31
246 #define MCI_PHY_CTRL_PIDI_MODE \
247 (1 << MCI_PHY_CTRL_PIDI_MODE_OFFSET)
249 /* Number of times to wait for the MCI link ready after MCI configurations
250 * Normally takes 34-35 successive reads
252 #define LINK_READY_TIMEOUT 100
254 enum mci_register_type
{
255 MCI_REG_TYPE_PHY
= 0,
264 /* Write wrapper callback for debug:
265 * will print written data in case LOG_LEVEL >= 40
267 static void mci_mmio_write_32(uintptr_t addr
, uint32_t value
)
269 VERBOSE("Write:\t0x%x = 0x%x\n", (uint32_t)addr
, value
);
270 mmio_write_32(addr
, value
);
272 /* Read wrapper callback for debug:
273 * will print read data in case LOG_LEVEL >= 40
275 static uint32_t mci_mmio_read_32(uintptr_t addr
)
279 value
= mmio_read_32(addr
);
280 VERBOSE("Read:\t0x%x = 0x%x\n", (uint32_t)addr
, value
);
284 /* MCI indirect access command completion polling:
285 * Each write/read command done via MCI indirect registers must be polled
286 * for command completions status.
288 * Returns 1 in case of error
289 * Returns 0 in case of command completed successfully.
291 static int mci_poll_command_completion(int mci_index
, int command_type
)
293 uint32_t mci_cmd_value
= 0, retry_count
= 100, ret
= 0;
294 uint32_t completion_flags
= MCI_INDIRECT_CTRL_CMD_DONE
;
297 /* Read commands require validating that requested data is ready */
298 if (command_type
== MCI_CMD_READ
)
299 completion_flags
|= MCI_INDIRECT_CTRL_DATA_READY
;
302 /* wait 1 ms before each polling */
304 mci_cmd_value
= mci_mmio_read_32(MCI_ACCESS_CMD_REG(mci_index
));
305 } while (((mci_cmd_value
& completion_flags
) != completion_flags
) &&
306 (retry_count
-- > 0));
308 if (retry_count
== 0) {
309 ERROR("%s: MCI command timeout (command status = 0x%x)\n",
310 __func__
, mci_cmd_value
);
318 int mci_read(int mci_idx
, uint32_t cmd
, uint32_t *value
)
322 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_idx
), cmd
);
324 rval
= mci_poll_command_completion(mci_idx
, MCI_CMD_READ
);
326 *value
= mci_mmio_read_32(MCI_WRITE_READ_DATA_REG(mci_idx
));
331 int mci_write(int mci_idx
, uint32_t cmd
, uint32_t data
)
333 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_idx
), data
);
334 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_idx
), cmd
);
336 return mci_poll_command_completion(mci_idx
, MCI_CMD_WRITE
);
339 /* Perform 3 configurations in one command: PCI mode,
340 * queues separation and cache bit
342 static int mci_axi_set_pcie_mode(int mci_index
)
344 uint32_t reg_data
, ret
= 1;
347 /* This configuration makes MCI IP behave consistently with AXI protocol
348 * It should be configured at one side only (for example locally at AP).
349 * The IP takes care of performing the same configurations at MCI on
350 * another side (for example remotely at CP).
352 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index
),
353 MCI_AXI_ACCESS_PCIE_MODE
|
354 MCI_AXI_ACCESS_CACHE_CHECK
|
355 MCI_AXI_ACCESS_FORCE_POST_WR
|
356 MCI_AXI_ACCESS_DISABLE_CLK_GATING
);
357 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index
),
358 MCI_INDIRECT_REG_CTRL_ADDR(
359 MCI_AXI_ACCESS_DATA_REG_NUM
) |
360 MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB
) |
361 MCI_INDIRECT_CTRL_LOCAL_PKT
|
362 MCI_INDIRECT_CTRL_CIRCULAR_CMD
);
364 /* if Write command was successful, verify PCIe mode */
365 if (mci_poll_command_completion(mci_index
, MCI_CMD_WRITE
) == 0) {
366 /* Verify the PCIe mode selected */
367 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index
),
368 MCI_INDIRECT_REG_CTRL_ADDR(
369 MCI_HB_CTRL_TX_CTRL_REG_NUM
) |
370 MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB
) |
371 MCI_INDIRECT_CTRL_LOCAL_PKT
|
372 MCI_INDIRECT_CTRL_READ_CMD
);
373 /* if read was completed, verify PCIe mode */
374 if (mci_poll_command_completion(mci_index
, MCI_CMD_READ
) == 0) {
375 reg_data
= mci_mmio_read_32(
376 MCI_WRITE_READ_DATA_REG(mci_index
));
377 if (reg_data
& MCI_HB_CTRL_TX_CTRL_PCIE_MODE
)
386 /* Reduce sequence FIFO timer expiration threshold */
387 static int mci_axi_set_fifo_thresh(int mci_index
)
389 uint32_t reg_data
, ret
= 0;
392 /* This configuration reduces sequence FIFO timer expiration threshold
393 * (to 0x7 instead of 0xA).
394 * In MCI 1.6 version this configuration prevents possible functional
396 * In version 1.82 the configuration prevents performance degradation
399 /* Configure local AP side */
400 reg_data
= MCI_PHY_CTRL_PIDI_MODE
|
401 MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE
|
402 MCI_PHY_CTRL_MCI_PHY_MODE_HOST
|
403 MCI_PHY_CTRL_MCI_MAJOR
|
404 MCI_PHY_CTRL_MCI_MINOR
;
405 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index
), reg_data
);
406 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index
),
407 MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM
) |
408 MCI_INDIRECT_CTRL_LOCAL_PKT
);
409 ret
|= mci_poll_command_completion(mci_index
, MCI_CMD_WRITE
);
411 /* Reduce the threshold */
412 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index
),
413 MCI_CTRL_IHB_MODE_CFG_REG_DEF_VAL
);
415 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index
),
416 MCI_INDIRECT_REG_CTRL_ADDR(
417 MCI_CTRL_IHB_MODE_CFG_REG_NUM
) |
418 MCI_INDIRECT_CTRL_LOCAL_PKT
);
419 ret
|= mci_poll_command_completion(mci_index
, MCI_CMD_WRITE
);
422 reg_data
= MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE
|
423 MCI_PHY_CTRL_MCI_PHY_MODE_HOST
|
424 MCI_PHY_CTRL_MCI_MAJOR
|
425 MCI_PHY_CTRL_MCI_MINOR
;
426 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index
), reg_data
);
427 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index
),
428 MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM
) |
429 MCI_INDIRECT_CTRL_LOCAL_PKT
);
430 ret
|= mci_poll_command_completion(mci_index
, MCI_CMD_WRITE
);
432 /* Configure remote CP side */
433 reg_data
= MCI_PHY_CTRL_PIDI_MODE
|
434 MCI_PHY_CTRL_MCI_MAJOR
|
435 MCI_PHY_CTRL_MCI_MINOR
|
436 MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE
;
437 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index
), reg_data
);
438 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index
),
439 MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM
) |
440 MCI_CTRL_IHB_MODE_FWD_MOD
);
441 ret
|= mci_poll_command_completion(mci_index
, MCI_CMD_WRITE
);
443 /* Reduce the threshold */
444 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index
),
445 MCI_CTRL_IHB_MODE_CFG_REG_DEF_VAL
);
446 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index
),
447 MCI_INDIRECT_REG_CTRL_ADDR(
448 MCI_CTRL_IHB_MODE_CFG_REG_NUM
) |
449 MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT
));
450 ret
|= mci_poll_command_completion(mci_index
, MCI_CMD_WRITE
);
453 reg_data
= MCI_PHY_CTRL_MCI_MAJOR
|
454 MCI_PHY_CTRL_MCI_MINOR
|
455 MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE
;
456 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index
), reg_data
);
457 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index
),
458 MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM
) |
459 MCI_CTRL_IHB_MODE_FWD_MOD
);
461 ret
|= mci_poll_command_completion(mci_index
, MCI_CMD_WRITE
);
468 * 1. AP & CP TX thresholds and delta configurations
469 * 2. DLO & DLI FIFO full threshold
470 * 3. RX thresholds and delta configurations
471 * 4. CP AR and AW outstanding
472 * 5. AP AR and AW outstanding
474 static int mci_axi_set_fifo_rx_tx_thresh(int mci_index
)
479 /* AP TX thresholds and delta configurations (IHB_reg 0x1) */
480 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index
),
481 MCI_CTRL_TX_MEM_CFG_REG_DEF_VAL
);
482 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index
),
483 MCI_INDIRECT_REG_CTRL_ADDR(
484 MCI_CTRL_TX_MEM_CFG_REG_NUM
) |
485 MCI_INDIRECT_CTRL_LOCAL_PKT
);
486 ret
|= mci_poll_command_completion(mci_index
, MCI_CMD_WRITE
);
488 /* CP TX thresholds and delta configurations (IHB_reg 0x1) */
489 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index
),
490 MCI_CTRL_TX_MEM_CFG_REG_DEF_VAL
);
491 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index
),
492 MCI_INDIRECT_REG_CTRL_ADDR(
493 MCI_CTRL_TX_MEM_CFG_REG_NUM
) |
494 MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT
));
495 ret
|= mci_poll_command_completion(mci_index
, MCI_CMD_WRITE
);
497 /* AP DLO & DLI FIFO full threshold & Auto-Link enable (IHB_reg 0x8) */
498 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index
),
499 MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL
|
500 MCI_CTRL_MCI_PHY_SET_AUTO_LINK_EN(1));
501 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index
),
502 MCI_INDIRECT_REG_CTRL_ADDR(
503 MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM
) |
504 MCI_INDIRECT_CTRL_LOCAL_PKT
);
505 ret
|= mci_poll_command_completion(mci_index
, MCI_CMD_WRITE
);
507 /* CP DLO & DLI FIFO full threshold (IHB_reg 0x8) */
508 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index
),
509 MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL
);
510 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index
),
511 MCI_INDIRECT_REG_CTRL_ADDR(
512 MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM
) |
513 MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT
));
514 ret
|= mci_poll_command_completion(mci_index
, MCI_CMD_WRITE
);
516 /* AP RX thresholds and delta configurations (IHB_reg 0x0) */
517 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index
),
518 MCI_CTRL_RX_MEM_CFG_REG_DEF_AP_VAL
);
519 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index
),
520 MCI_INDIRECT_REG_CTRL_ADDR(
521 MCI_CTRL_RX_MEM_CFG_REG_NUM
) |
522 MCI_INDIRECT_CTRL_LOCAL_PKT
);
523 ret
|= mci_poll_command_completion(mci_index
, MCI_CMD_WRITE
);
525 /* CP RX thresholds and delta configurations (IHB_reg 0x0) */
526 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index
),
527 MCI_CTRL_RX_MEM_CFG_REG_DEF_CP_VAL
);
528 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index
),
529 MCI_INDIRECT_REG_CTRL_ADDR(
530 MCI_CTRL_RX_MEM_CFG_REG_NUM
) |
531 MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT
));
532 ret
|= mci_poll_command_completion(mci_index
, MCI_CMD_WRITE
);
534 /* AP AR & AW maximum AXI outstanding request cfg (HB_reg 0xd) */
535 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index
),
536 MCI_HB_CTRL_TX_CTRL_PRI_TH_QOS(8) |
537 MCI_HB_CTRL_TX_CTRL_MAX_RD_CNT(3) |
538 MCI_HB_CTRL_TX_CTRL_MAX_WR_CNT(3));
539 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index
),
540 MCI_INDIRECT_REG_CTRL_ADDR(
541 MCI_HB_CTRL_TX_CTRL_REG_NUM
) |
542 MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB
) |
543 MCI_INDIRECT_CTRL_LOCAL_PKT
);
544 ret
|= mci_poll_command_completion(mci_index
, MCI_CMD_WRITE
);
546 /* CP AR & AW maximum AXI outstanding request cfg (HB_reg 0xd) */
547 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index
),
548 MCI_HB_CTRL_TX_CTRL_PRI_TH_QOS(8) |
549 MCI_HB_CTRL_TX_CTRL_MAX_RD_CNT(0xB) |
550 MCI_HB_CTRL_TX_CTRL_MAX_WR_CNT(0x11));
551 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index
),
552 MCI_INDIRECT_REG_CTRL_ADDR(
553 MCI_HB_CTRL_TX_CTRL_REG_NUM
) |
554 MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT
) |
555 MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB
));
556 ret
|= mci_poll_command_completion(mci_index
, MCI_CMD_WRITE
);
562 /* configure MCI to allow read & write transactions to arrive at the same time.
563 * Without the below configuration, MCI won't sent response to CPU for
564 * transactions which arrived simultaneously and will lead to CPU hang.
565 * The below will configure MCI to be able to pass transactions from/to CP/AP.
567 static int mci_enable_simultaneous_transactions(int mci_index
)
572 /* ID assignment (assigning global ID offset to CP) */
573 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0),
574 MCI_DID_GLOBAL_ASSIGN_REQ_MCI_LOCAL_ID(2) |
575 MCI_DID_GLOBAL_ASSIGN_REQ_MCI_COUNT(2) |
576 MCI_DID_GLOBAL_ASSIGN_REQ_HOPS_NUM(2));
577 mci_mmio_write_32(MCI_ACCESS_CMD_REG(0),
578 MCI_INDIRECT_REG_CTRL_ADDR(
579 MCI_DID_GLOBAL_ASSIGNMENT_REQUEST_REG
) |
580 MCI_INDIRECT_CTRL_ASSIGN_CMD
);
581 ret
|= mci_poll_command_completion(mci_index
, MCI_CMD_WRITE
);
583 /* Assigning dest. ID=3 to all transactions entering from AXI at AP */
584 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0),
585 MCI_HB_CTRL_WIN0_DEST_VALID_FLAG(1) |
586 MCI_HB_CTRL_WIN0_DEST_ID(3));
587 mci_mmio_write_32(MCI_ACCESS_CMD_REG(0),
588 MCI_INDIRECT_REG_CTRL_ADDR(
589 MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM
) |
590 MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB
) |
591 MCI_INDIRECT_CTRL_LOCAL_PKT
);
592 ret
|= mci_poll_command_completion(mci_index
, MCI_CMD_WRITE
);
594 /* Assigning dest. ID=1 to all transactions entering from AXI at CP */
595 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0),
596 MCI_HB_CTRL_WIN0_DEST_VALID_FLAG(1) |
597 MCI_HB_CTRL_WIN0_DEST_ID(1));
598 mci_mmio_write_32(MCI_ACCESS_CMD_REG(0),
599 MCI_INDIRECT_REG_CTRL_ADDR(
600 MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM
) |
601 MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT
) |
602 MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB
));
603 ret
|= mci_poll_command_completion(mci_index
, MCI_CMD_WRITE
);
605 /* End address to all transactions entering from AXI at AP.
606 * This will lead to get match for any AXI address
607 * and receive destination ID=3
609 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0), 0xffffffff);
610 mci_mmio_write_32(MCI_ACCESS_CMD_REG(0),
611 MCI_INDIRECT_REG_CTRL_ADDR(
612 MCI_HB_CTRL_WIN0_ADDRESS_MASK_REG_NUM
) |
613 MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB
) |
614 MCI_INDIRECT_CTRL_LOCAL_PKT
);
615 ret
|= mci_poll_command_completion(mci_index
, MCI_CMD_WRITE
);
617 /* End address to all transactions entering from AXI at CP.
618 * This will lead to get match for any AXI address
619 * and receive destination ID=1
621 mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0), 0xffffffff);
622 mci_mmio_write_32(MCI_ACCESS_CMD_REG(0),
623 MCI_INDIRECT_REG_CTRL_ADDR(
624 MCI_HB_CTRL_WIN0_ADDRESS_MASK_REG_NUM
) |
625 MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT
) |
626 MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB
));
627 ret
|= mci_poll_command_completion(mci_index
, MCI_CMD_WRITE
);
633 /* Check if MCI simultaneous transaction was already enabled.
634 * Currently bootrom does this mci configuration only when the boot source is
635 * SAR_MCIX4, in other cases it should be done at this stage.
636 * It is worth noticing that in case of booting from uart, the bootrom
637 * flow is different and this mci initialization is skipped even if boot
638 * source is SAR_MCIX4. Therefore new verification bases on appropriate mci's
639 * register content: if the appropriate reg contains 0x0 it means that the
640 * bootrom didn't perform required mci configuration.
643 * 0 - configuration already done
644 * 1 - configuration missing
646 static _Bool
mci_simulatenous_trans_missing(int mci_index
)
650 /* read 'Window 0 Destination ID assignment' from HB register 0x3
651 * (TX_CFG_W0_DST_ID) to check whether ID assignment was already
652 * performed by BootROM.
655 mci_mmio_write_32(MCI_ACCESS_CMD_REG(0),
656 MCI_INDIRECT_REG_CTRL_ADDR(
657 MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM
) |
658 MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB
) |
659 MCI_INDIRECT_CTRL_LOCAL_PKT
|
660 MCI_INDIRECT_CTRL_READ_CMD
);
661 ret
= mci_poll_command_completion(mci_index
, MCI_CMD_READ
);
663 reg
= mci_mmio_read_32(MCI_WRITE_READ_DATA_REG(mci_index
));
666 ERROR("Failed to verify MCI simultaneous read/write status\n");
669 /* default ID assignment is 0, so if register doesn't contain zeros
670 * it means that bootrom already performed required configuration.
678 /* For A1 revision, configure the MCI link for performance improvement:
679 * - set MCI to support read/write transactions to arrive at the same time
680 * - Switch AXI to PCIe mode
681 * - Reduce sequence FIFO threshold
682 * - Configure RX/TX FIFO thresholds
685 * We don't exit on error code from any sub routine, to try (best effort) to
686 * complete the MCI configuration.
687 * (If we exit - Bootloader will surely fail to boot)
689 int mci_configure(int mci_index
)
694 /* According to design guidelines the MCI simultaneous transaction
695 * shouldn't be enabled more then once - therefore make sure that it
696 * wasn't already enabled in bootrom.
698 if (mci_simulatenous_trans_missing(mci_index
)) {
699 VERBOSE("Enabling MCI simultaneous transaction\n");
700 /* set MCI to support read/write transactions
701 * to arrive at the same time
703 rval
= mci_enable_simultaneous_transactions(mci_index
);
705 ERROR("Failed to set MCI simultaneous read/write\n");
707 VERBOSE("Skip MCI ID assignment - already done by bootrom\n");
709 /* Configure MCI for more consistent behavior with AXI protocol */
710 rval
= mci_axi_set_pcie_mode(mci_index
);
712 ERROR("Failed to set MCI to AXI PCIe mode\n");
714 /* reduce FIFO global threshold */
715 rval
= mci_axi_set_fifo_thresh(mci_index
);
717 ERROR("Failed to set MCI FIFO global threshold\n");
719 /* configure RX/TX FIFO thresholds */
720 rval
= mci_axi_set_fifo_rx_tx_thresh(mci_index
);
722 ERROR("Failed to set MCI RX/TX FIFO threshold\n");
728 int mci_get_link_status(void)
732 cmd
= (MCI_INDIRECT_REG_CTRL_ADDR(MCI_CTRL_STATUS_REG_NUM
) |
733 MCI_INDIRECT_CTRL_LOCAL_PKT
| MCI_INDIRECT_CTRL_READ_CMD
);
734 if (mci_read(0, cmd
, &data
)) {
735 ERROR("Failed to read status register\n");
739 /* Check if the link is ready */
740 if (data
!= MCI_CTRL_PHY_READY
) {
741 ERROR("Bad link status %x\n", data
);
748 void mci_turn_link_down(void)
755 /* Turn off auto-link */
756 cmd
= (MCI_INDIRECT_REG_CTRL_ADDR(MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM
) |
757 MCI_INDIRECT_CTRL_LOCAL_PKT
);
758 data
= (MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL2
|
759 MCI_CTRL_MCI_PHY_SET_AUTO_LINK_EN(0));
760 rval
= mci_write(0, cmd
, data
);
762 ERROR("Failed to turn off auto-link\n");
765 cmd
= (MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM
) |
766 MCI_INDIRECT_CTRL_LOCAL_PKT
);
767 data
= (MCI_PHY_CTRL_MCI_MINOR
|
768 MCI_PHY_CTRL_MCI_MAJOR
|
769 MCI_PHY_CTRL_MCI_PHY_MODE_HOST
|
770 MCI_PHY_CTRL_MCI_PHY_RESET_CORE
);
771 rval
= mci_write(0, cmd
, data
);
773 ERROR("Failed to reset AP PHY\n");
775 /* Clear all status & CRC values */
776 cmd
= (MCI_INDIRECT_REG_CTRL_ADDR(MCI_LINK_CRC_CTRL_REG_NUM
) |
777 MCI_INDIRECT_CTRL_LOCAL_PKT
);
779 mci_write(0, cmd
, data
);
780 cmd
= (MCI_INDIRECT_REG_CTRL_ADDR(MCI_CTRL_STATUS_REG_NUM
) |
781 MCI_INDIRECT_CTRL_LOCAL_PKT
);
783 rval
= mci_write(0, cmd
, data
);
785 ERROR("Failed to reset AP PHY\n");
787 /* Wait 5ms before un-reset the PHY */
790 /* Un-reset AP PHY */
791 cmd
= (MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM
) |
792 MCI_INDIRECT_CTRL_LOCAL_PKT
);
793 data
= (MCI_PHY_CTRL_MCI_MINOR
| MCI_PHY_CTRL_MCI_MAJOR
|
794 MCI_PHY_CTRL_MCI_PHY_MODE_HOST
);
795 rval
= mci_write(0, cmd
, data
);
797 ERROR("Failed to un-reset AP PHY\n");
802 void mci_turn_link_on(void)
808 /* Turn on auto-link */
809 cmd
= (MCI_INDIRECT_REG_CTRL_ADDR(MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM
) |
810 MCI_INDIRECT_CTRL_LOCAL_PKT
);
811 data
= (MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL2
|
812 MCI_CTRL_MCI_PHY_SET_AUTO_LINK_EN(1));
813 rval
= mci_write(0, cmd
, data
);
815 ERROR("Failed to turn on auto-link\n");
820 /* Initialize MCI for performance improvements */
821 int mci_initialize(int mci_index
)
826 INFO("MCI%d initialization:\n", mci_index
);
828 ret
= mci_configure(mci_index
);