blob: 721504e03af161305105aeb0e5b3addf35e57297 [file] [log] [blame]
Konstantin Porotchkin01c84d42018-02-26 16:01:57 +02001/*
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 <debug.h>
11#include <delay_timer.h>
12#include <mmio.h>
13#include <mci.h>
14#include <mvebu.h>
15#include <mvebu_def.h>
16#include <plat_marvell.h>
17
18/* /HB /Units /Direct_regs /Direct regs
19 * /Configuration Register Write/Read Data Register
20 */
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
25 */
26#define MCI_ACCESS_CMD_REG(mci_index) \
27 (MVEBU_MCI_REG_BASE_REMAP(mci_index) + 0x4)
28
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]
38 * of IHB_PHY_CTRL
39 * (must be set before any PHY register access occurs):
40 * /IHB_REG /IHB_REGInterchip Hopping Bus Registers
41 * /IHB Version Control Register
42 *
43 * ixi_ihb_top IHB PHY
44 * AXI ----------------------------- -------------
45 * <--| axi_hb_top | ihb_pipe_top |-->| |
46 * -->| GID=1 | GID=0 |<--| |
47 * ----------------------------- -------------
48 */
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)
65
66/* Hop ID values */
67#define GID_IHB_PIPE 0
68#define GID_AXI_HB 1
69#define GID_IHB_EXT 2
70
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)
78
79/* IHB_REG domain registers */
80/* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers/
81 * Rx Memory Configuration Register (RX_MEM_CFG)
82 */
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))
97
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))
105
106
107/* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers/
108 * Tx Memory Configuration Register (TX_MEM_CFG)
109 */
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
113 */
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))
121
122/* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers
123 * /IHB Link CRC Control
124 */
125/* MCi Link CRC Control Register (MCi_CRC_CTRL) */
126#define MCI_LINK_CRC_CTRL_REG_NUM 0x4
127
128/* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers
129 * /IHB Status Register
130 */
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)
142
143/* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers/
144 * MCi PHY Speed Settings Register (MCi_PHY_SETTING)
145 */
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))
162
163/* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers
164 * /IHB Mode Config
165 */
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)
177
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)
196
197/* /HB /Units /HB_REG /HB_REGHopping Bus Registers
198 * /Window 0 Address Mask Register
199 */
200#define MCI_HB_CTRL_WIN0_ADDRESS_MASK_REG_NUM 0x2
201
202/* /HB /Units /HB_REG /HB_REGHopping Bus Registers
203 * /Window 0 Destination Register
204 */
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)
208
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)
217
218/* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers
219 * /IHB Version Control Register
220 */
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) \
243 (((addr) & 0x3) << \
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)
248
249/* Number of times to wait for the MCI link ready after MCI configurations
250 * Normally takes 34-35 successive reads
251 */
252#define LINK_READY_TIMEOUT 100
253
254enum mci_register_type {
255 MCI_REG_TYPE_PHY = 0,
256 MCI_REG_TYPE_CTRL,
257};
258
259enum {
260 MCI_CMD_WRITE,
261 MCI_CMD_READ
262};
263
264/* Write wrapper callback for debug:
265 * will print written data in case LOG_LEVEL >= 40
266 */
267static void mci_mmio_write_32(uintptr_t addr, uint32_t value)
268{
269 VERBOSE("Write:\t0x%x = 0x%x\n", (uint32_t)addr, value);
270 mmio_write_32(addr, value);
271}
272/* Read wrapper callback for debug:
273 * will print read data in case LOG_LEVEL >= 40
274 */
275static uint32_t mci_mmio_read_32(uintptr_t addr)
276{
277 uint32_t value;
278
279 value = mmio_read_32(addr);
280 VERBOSE("Read:\t0x%x = 0x%x\n", (uint32_t)addr, value);
281 return value;
282}
283
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.
287 *
288 * Returns 1 in case of error
289 * Returns 0 in case of command completed successfully.
290 */
291static int mci_poll_command_completion(int mci_index, int command_type)
292{
293 uint32_t mci_cmd_value = 0, retry_count = 100, ret = 0;
294 uint32_t completion_flags = MCI_INDIRECT_CTRL_CMD_DONE;
295
296 debug_enter();
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;
300
301 do {
302 /* wait 1 ms before each polling */
303 mdelay(1);
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));
307
308 if (retry_count == 0) {
309 ERROR("%s: MCI command timeout (command status = 0x%x)\n",
310 __func__, mci_cmd_value);
311 ret = 1;
312 }
313
314 debug_exit();
315 return ret;
316}
317
318int mci_read(int mci_idx, uint32_t cmd, uint32_t *value)
319{
320 int rval;
321
322 mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_idx), cmd);
323
324 rval = mci_poll_command_completion(mci_idx, MCI_CMD_READ);
325
326 *value = mci_mmio_read_32(MCI_WRITE_READ_DATA_REG(mci_idx));
327
328 return rval;
329}
330
331int mci_write(int mci_idx, uint32_t cmd, uint32_t data)
332{
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);
335
336 return mci_poll_command_completion(mci_idx, MCI_CMD_WRITE);
337}
338
339/* Perform 3 configurations in one command: PCI mode,
340 * queues separation and cache bit
341 */
342static int mci_axi_set_pcie_mode(int mci_index)
343{
344 uint32_t reg_data, ret = 1;
345
346 debug_enter();
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).
351 */
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);
363
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)
378 ret = 0;
379 }
380 }
381
382 debug_exit();
383 return ret;
384}
385
386/* Reduce sequence FIFO timer expiration threshold */
387static int mci_axi_set_fifo_thresh(int mci_index)
388{
389 uint32_t reg_data, ret = 0;
390
391 debug_enter();
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
395 * issues.
396 * In version 1.82 the configuration prevents performance degradation
397 */
398
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);
410
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);
414
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);
420
421 /* Exit PIDI mode */
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);
431
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);
442
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);
451
452 /* Exit PIDI mode */
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);
460
461 ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
462
463 debug_exit();
464 return ret;
465}
466
467/* Configure:
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
473 */
474static int mci_axi_set_fifo_rx_tx_thresh(int mci_index)
475{
476 uint32_t ret = 0;
477
478 debug_enter();
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);
487
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);
496
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);
506
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);
515
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);
524
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);
533
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);
545
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);
557
558 debug_exit();
559 return ret;
560}
561
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.
566 */
567static int mci_enable_simultaneous_transactions(int mci_index)
568{
569 uint32_t ret = 0;
570
571 debug_enter();
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);
582
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);
593
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);
604
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
608 */
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);
616
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
620 */
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);
628
629 debug_exit();
630 return ret;
631}
632
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.
641 *
642 * Returns:
643 * 0 - configuration already done
644 * 1 - configuration missing
645 */
646static _Bool mci_simulatenous_trans_missing(int mci_index)
647{
648 uint32_t reg, ret;
649
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.
653 */
654 debug_enter();
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);
662
663 reg = mci_mmio_read_32(MCI_WRITE_READ_DATA_REG(mci_index));
664
665 if (ret)
666 ERROR("Failed to verify MCI simultaneous read/write status\n");
667
668 debug_exit();
669 /* default ID assignment is 0, so if register doesn't contain zeros
670 * it means that bootrom already performed required configuration.
671 */
672 if (reg != 0)
673 return 0;
674
675 return 1;
676}
677
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
683 *
684 * Note:
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)
688 */
689int mci_configure(int mci_index)
690{
691 int rval;
692
693 debug_enter();
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.
697 */
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
702 */
703 rval = mci_enable_simultaneous_transactions(mci_index);
704 if (rval)
705 ERROR("Failed to set MCI simultaneous read/write\n");
706 } else
707 VERBOSE("Skip MCI ID assignment - already done by bootrom\n");
708
709 /* Configure MCI for more consistent behavior with AXI protocol */
710 rval = mci_axi_set_pcie_mode(mci_index);
711 if (rval)
712 ERROR("Failed to set MCI to AXI PCIe mode\n");
713
714 /* reduce FIFO global threshold */
715 rval = mci_axi_set_fifo_thresh(mci_index);
716 if (rval)
717 ERROR("Failed to set MCI FIFO global threshold\n");
718
719 /* configure RX/TX FIFO thresholds */
720 rval = mci_axi_set_fifo_rx_tx_thresh(mci_index);
721 if (rval)
722 ERROR("Failed to set MCI RX/TX FIFO threshold\n");
723
724 debug_exit();
725 return 1;
726}
727
728int mci_get_link_status(void)
729{
730 uint32_t cmd, data;
731
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");
736 return -1;
737 }
738
739 /* Check if the link is ready */
740 if (data != MCI_CTRL_PHY_READY) {
741 ERROR("Bad link status %x\n", data);
742 return -1;
743 }
744
745 return 0;
746}
747
748void mci_turn_link_down(void)
749{
750 uint32_t cmd, data;
751 int rval = 0;
752
753 debug_enter();
754
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);
761 if (rval)
762 ERROR("Failed to turn off auto-link\n");
763
764 /* Reset AP PHY */
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);
772 if (rval)
773 ERROR("Failed to reset AP PHY\n");
774
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);
778 data = 0x0;
779 mci_write(0, cmd, data);
780 cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_CTRL_STATUS_REG_NUM) |
781 MCI_INDIRECT_CTRL_LOCAL_PKT);
782 data = 0x0;
783 rval = mci_write(0, cmd, data);
784 if (rval)
785 ERROR("Failed to reset AP PHY\n");
786
787 /* Wait 5ms before un-reset the PHY */
788 mdelay(5);
789
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);
796 if (rval)
797 ERROR("Failed to un-reset AP PHY\n");
798
799 debug_exit();
800}
801
802void mci_turn_link_on(void)
803{
804 uint32_t cmd, data;
805 int rval = 0;
806
807 debug_enter();
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);
814 if (rval)
815 ERROR("Failed to turn on auto-link\n");
816
817 debug_exit();
818}
819
820/* Initialize MCI for performance improvements */
821int mci_initialize(int mci_index)
822{
823 int ret;
824
825 debug_enter();
826 INFO("MCI%d initialization:\n", mci_index);
827
828 ret = mci_configure(mci_index);
829
830 debug_exit();
831 return ret;
832}