1031542fcSKonstantin Porotchkin /* 2031542fcSKonstantin Porotchkin * Copyright (C) 2018 Marvell International Ltd. 3031542fcSKonstantin Porotchkin * 4031542fcSKonstantin Porotchkin * SPDX-License-Identifier: BSD-3-Clause 5031542fcSKonstantin Porotchkin * https://spdx.org/licenses 6031542fcSKonstantin Porotchkin */ 7031542fcSKonstantin Porotchkin 8031542fcSKonstantin Porotchkin /* MCI bus driver for Marvell ARMADA 8K and 8K+ SoCs */ 9031542fcSKonstantin Porotchkin 1009d40e0eSAntonio Nino Diaz #include <common/debug.h> 1109d40e0eSAntonio Nino Diaz #include <drivers/delay_timer.h> 1209d40e0eSAntonio Nino Diaz #include <drivers/marvell/mci.h> 1309d40e0eSAntonio Nino Diaz #include <lib/mmio.h> 1409d40e0eSAntonio Nino Diaz 15031542fcSKonstantin Porotchkin #include <mvebu.h> 16031542fcSKonstantin Porotchkin #include <mvebu_def.h> 17031542fcSKonstantin Porotchkin #include <plat_marvell.h> 18031542fcSKonstantin Porotchkin 19031542fcSKonstantin Porotchkin /* /HB /Units /Direct_regs /Direct regs 20031542fcSKonstantin Porotchkin * /Configuration Register Write/Read Data Register 21031542fcSKonstantin Porotchkin */ 22031542fcSKonstantin Porotchkin #define MCI_WRITE_READ_DATA_REG(mci_index) \ 23031542fcSKonstantin Porotchkin MVEBU_MCI_REG_BASE_REMAP(mci_index) 24031542fcSKonstantin Porotchkin /* /HB /Units /Direct_regs /Direct regs 25031542fcSKonstantin Porotchkin * /Configuration Register Access Command Register 26031542fcSKonstantin Porotchkin */ 27031542fcSKonstantin Porotchkin #define MCI_ACCESS_CMD_REG(mci_index) \ 28031542fcSKonstantin Porotchkin (MVEBU_MCI_REG_BASE_REMAP(mci_index) + 0x4) 29031542fcSKonstantin Porotchkin 30031542fcSKonstantin Porotchkin /* Access Command fields : 31031542fcSKonstantin Porotchkin * bit[3:0] - Sub command: 1 => Peripheral Config Register Read, 32031542fcSKonstantin Porotchkin * 0 => Peripheral Config Register Write, 33031542fcSKonstantin Porotchkin * 2 => Peripheral Assign ID request, 34031542fcSKonstantin Porotchkin * 3 => Circular Config Write 35031542fcSKonstantin Porotchkin * bit[5] - 1 => Local (same chip access) 0 => Remote 36031542fcSKonstantin Porotchkin * bit[15:8] - Destination hop ID. Put Global ID (GID) here (see scheme below). 37031542fcSKonstantin Porotchkin * bit[23:22] - 0x3 IHB PHY REG address space, 0x0 IHB Controller space 38031542fcSKonstantin Porotchkin * bit[21:16] - Low 6 bits of offset. Hight 2 bits are taken from bit[28:27] 39031542fcSKonstantin Porotchkin * of IHB_PHY_CTRL 40031542fcSKonstantin Porotchkin * (must be set before any PHY register access occurs): 41031542fcSKonstantin Porotchkin * /IHB_REG /IHB_REGInterchip Hopping Bus Registers 42031542fcSKonstantin Porotchkin * /IHB Version Control Register 43031542fcSKonstantin Porotchkin * 44031542fcSKonstantin Porotchkin * ixi_ihb_top IHB PHY 45031542fcSKonstantin Porotchkin * AXI ----------------------------- ------------- 46031542fcSKonstantin Porotchkin * <--| axi_hb_top | ihb_pipe_top |-->| | 47031542fcSKonstantin Porotchkin * -->| GID=1 | GID=0 |<--| | 48031542fcSKonstantin Porotchkin * ----------------------------- ------------- 49031542fcSKonstantin Porotchkin */ 50031542fcSKonstantin Porotchkin #define MCI_INDIRECT_CTRL_READ_CMD 0x1 51031542fcSKonstantin Porotchkin #define MCI_INDIRECT_CTRL_ASSIGN_CMD 0x2 52031542fcSKonstantin Porotchkin #define MCI_INDIRECT_CTRL_CIRCULAR_CMD 0x3 53031542fcSKonstantin Porotchkin #define MCI_INDIRECT_CTRL_LOCAL_PKT (1 << 5) 54031542fcSKonstantin Porotchkin #define MCI_INDIRECT_CTRL_CMD_DONE_OFFSET 6 55031542fcSKonstantin Porotchkin #define MCI_INDIRECT_CTRL_CMD_DONE \ 56031542fcSKonstantin Porotchkin (1 << MCI_INDIRECT_CTRL_CMD_DONE_OFFSET) 57031542fcSKonstantin Porotchkin #define MCI_INDIRECT_CTRL_DATA_READY_OFFSET 7 58031542fcSKonstantin Porotchkin #define MCI_INDIRECT_CTRL_DATA_READY \ 59031542fcSKonstantin Porotchkin (1 << MCI_INDIRECT_CTRL_DATA_READY_OFFSET) 60031542fcSKonstantin Porotchkin #define MCI_INDIRECT_CTRL_HOPID_OFFSET 8 61031542fcSKonstantin Porotchkin #define MCI_INDIRECT_CTRL_HOPID(id) \ 62031542fcSKonstantin Porotchkin (((id) & 0xFF) << MCI_INDIRECT_CTRL_HOPID_OFFSET) 63031542fcSKonstantin Porotchkin #define MCI_INDIRECT_CTRL_REG_CHIPID_OFFSET 16 64031542fcSKonstantin Porotchkin #define MCI_INDIRECT_REG_CTRL_ADDR(reg_num) \ 65031542fcSKonstantin Porotchkin (reg_num << MCI_INDIRECT_CTRL_REG_CHIPID_OFFSET) 66031542fcSKonstantin Porotchkin 67031542fcSKonstantin Porotchkin /* Hop ID values */ 68031542fcSKonstantin Porotchkin #define GID_IHB_PIPE 0 69031542fcSKonstantin Porotchkin #define GID_AXI_HB 1 70031542fcSKonstantin Porotchkin #define GID_IHB_EXT 2 71031542fcSKonstantin Porotchkin 72031542fcSKonstantin Porotchkin #define MCI_DID_GLOBAL_ASSIGNMENT_REQUEST_REG 0x2 73031542fcSKonstantin Porotchkin /* Target MCi Local ID (LID, which is = self DID) */ 74031542fcSKonstantin Porotchkin #define MCI_DID_GLOBAL_ASSIGN_REQ_MCI_LOCAL_ID(val) (((val) & 0xFF) << 16) 75031542fcSKonstantin Porotchkin /* Bits [15:8]: Number of MCis on chip of target MCi */ 76031542fcSKonstantin Porotchkin #define MCI_DID_GLOBAL_ASSIGN_REQ_MCI_COUNT(val) (((val) & 0xFF) << 8) 77031542fcSKonstantin Porotchkin /* Bits [7:0]: Number of hops on chip of target MCi */ 78031542fcSKonstantin Porotchkin #define MCI_DID_GLOBAL_ASSIGN_REQ_HOPS_NUM(val) (((val) & 0xFF) << 0) 79031542fcSKonstantin Porotchkin 80031542fcSKonstantin Porotchkin /* IHB_REG domain registers */ 81031542fcSKonstantin Porotchkin /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers/ 82031542fcSKonstantin Porotchkin * Rx Memory Configuration Register (RX_MEM_CFG) 83031542fcSKonstantin Porotchkin */ 84031542fcSKonstantin Porotchkin #define MCI_CTRL_RX_MEM_CFG_REG_NUM 0x0 85031542fcSKonstantin Porotchkin #define MCI_CTRL_RX_TX_MEM_CFG_RQ_THRESH(val) (((val) & 0xFF) << 24) 86031542fcSKonstantin Porotchkin #define MCI_CTRL_RX_TX_MEM_CFG_PQ_THRESH(val) (((val) & 0xFF) << 16) 87031542fcSKonstantin Porotchkin #define MCI_CTRL_RX_TX_MEM_CFG_NQ_THRESH(val) (((val) & 0xFF) << 8) 88031542fcSKonstantin Porotchkin #define MCI_CTRL_RX_TX_MEM_CFG_DELTA_THRESH(val) (((val) & 0xF) << 4) 89031542fcSKonstantin Porotchkin #define MCI_CTRL_RX_TX_MEM_CFG_RTC(val) (((val) & 0x3) << 2) 90031542fcSKonstantin Porotchkin #define MCI_CTRL_RX_TX_MEM_CFG_WTC(val) (((val) & 0x3) << 0) 91031542fcSKonstantin Porotchkin #define MCI_CTRL_RX_MEM_CFG_REG_DEF_CP_VAL \ 92031542fcSKonstantin Porotchkin (MCI_CTRL_RX_TX_MEM_CFG_RQ_THRESH(0x07) | \ 93031542fcSKonstantin Porotchkin MCI_CTRL_RX_TX_MEM_CFG_PQ_THRESH(0x3f) | \ 94031542fcSKonstantin Porotchkin MCI_CTRL_RX_TX_MEM_CFG_NQ_THRESH(0x3f) | \ 95031542fcSKonstantin Porotchkin MCI_CTRL_RX_TX_MEM_CFG_DELTA_THRESH(0xf) | \ 96031542fcSKonstantin Porotchkin MCI_CTRL_RX_TX_MEM_CFG_RTC(1) | \ 97031542fcSKonstantin Porotchkin MCI_CTRL_RX_TX_MEM_CFG_WTC(1)) 98031542fcSKonstantin Porotchkin 99031542fcSKonstantin Porotchkin #define MCI_CTRL_RX_MEM_CFG_REG_DEF_AP_VAL \ 100031542fcSKonstantin Porotchkin (MCI_CTRL_RX_TX_MEM_CFG_RQ_THRESH(0x3f) | \ 101031542fcSKonstantin Porotchkin MCI_CTRL_RX_TX_MEM_CFG_PQ_THRESH(0x03) | \ 102031542fcSKonstantin Porotchkin MCI_CTRL_RX_TX_MEM_CFG_NQ_THRESH(0x3f) | \ 103031542fcSKonstantin Porotchkin MCI_CTRL_RX_TX_MEM_CFG_DELTA_THRESH(0xf) | \ 104031542fcSKonstantin Porotchkin MCI_CTRL_RX_TX_MEM_CFG_RTC(1) | \ 105031542fcSKonstantin Porotchkin MCI_CTRL_RX_TX_MEM_CFG_WTC(1)) 106031542fcSKonstantin Porotchkin 107031542fcSKonstantin Porotchkin 108031542fcSKonstantin Porotchkin /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers/ 109031542fcSKonstantin Porotchkin * Tx Memory Configuration Register (TX_MEM_CFG) 110031542fcSKonstantin Porotchkin */ 111031542fcSKonstantin Porotchkin #define MCI_CTRL_TX_MEM_CFG_REG_NUM 0x1 112031542fcSKonstantin Porotchkin /* field mapping for TX mem config register 113031542fcSKonstantin Porotchkin * are the same as for RX register - see register above 114031542fcSKonstantin Porotchkin */ 115031542fcSKonstantin Porotchkin #define MCI_CTRL_TX_MEM_CFG_REG_DEF_VAL \ 116031542fcSKonstantin Porotchkin (MCI_CTRL_RX_TX_MEM_CFG_RQ_THRESH(0x20) | \ 117031542fcSKonstantin Porotchkin MCI_CTRL_RX_TX_MEM_CFG_PQ_THRESH(0x20) | \ 118031542fcSKonstantin Porotchkin MCI_CTRL_RX_TX_MEM_CFG_NQ_THRESH(0x20) | \ 119031542fcSKonstantin Porotchkin MCI_CTRL_RX_TX_MEM_CFG_DELTA_THRESH(2) | \ 120031542fcSKonstantin Porotchkin MCI_CTRL_RX_TX_MEM_CFG_RTC(1) | \ 121031542fcSKonstantin Porotchkin MCI_CTRL_RX_TX_MEM_CFG_WTC(1)) 122031542fcSKonstantin Porotchkin 123031542fcSKonstantin Porotchkin /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers 124031542fcSKonstantin Porotchkin * /IHB Link CRC Control 125031542fcSKonstantin Porotchkin */ 126031542fcSKonstantin Porotchkin /* MCi Link CRC Control Register (MCi_CRC_CTRL) */ 127031542fcSKonstantin Porotchkin #define MCI_LINK_CRC_CTRL_REG_NUM 0x4 128031542fcSKonstantin Porotchkin 129031542fcSKonstantin Porotchkin /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers 130031542fcSKonstantin Porotchkin * /IHB Status Register 131031542fcSKonstantin Porotchkin */ 132031542fcSKonstantin Porotchkin /* MCi Status Register (MCi_STS) */ 133031542fcSKonstantin Porotchkin #define MCI_CTRL_STATUS_REG_NUM 0x5 134031542fcSKonstantin Porotchkin #define MCI_CTRL_STATUS_REG_PHY_READY (1 << 12) 135031542fcSKonstantin Porotchkin #define MCI_CTRL_STATUS_REG_LINK_PRESENT (1 << 15) 136031542fcSKonstantin Porotchkin #define MCI_CTRL_STATUS_REG_PHY_CID_VIO_OFFSET 24 137031542fcSKonstantin Porotchkin #define MCI_CTRL_STATUS_REG_PHY_CID_VIO_MASK \ 138031542fcSKonstantin Porotchkin (0xF << MCI_CTRL_STATUS_REG_PHY_CID_VIO_OFFSET) 139031542fcSKonstantin Porotchkin /* Expected successful Link result, including reserved bit */ 140031542fcSKonstantin Porotchkin #define MCI_CTRL_PHY_READY (MCI_CTRL_STATUS_REG_PHY_READY | \ 141031542fcSKonstantin Porotchkin MCI_CTRL_STATUS_REG_LINK_PRESENT | \ 142031542fcSKonstantin Porotchkin MCI_CTRL_STATUS_REG_PHY_CID_VIO_MASK) 143031542fcSKonstantin Porotchkin 144031542fcSKonstantin Porotchkin /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers/ 145031542fcSKonstantin Porotchkin * MCi PHY Speed Settings Register (MCi_PHY_SETTING) 146031542fcSKonstantin Porotchkin */ 147031542fcSKonstantin Porotchkin #define MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM 0x8 148031542fcSKonstantin Porotchkin #define MCI_CTRL_MCI_PHY_SET_DLO_FIFO_FULL_TRESH(val) (((val) & 0xF) << 28) 149031542fcSKonstantin Porotchkin #define MCI_CTRL_MCI_PHY_SET_PHY_MAX_SPEED(val) (((val) & 0xF) << 12) 150031542fcSKonstantin Porotchkin #define MCI_CTRL_MCI_PHY_SET_PHYCLK_SEL(val) (((val) & 0xF) << 8) 151031542fcSKonstantin Porotchkin #define MCI_CTRL_MCI_PHY_SET_REFCLK_FREQ_SEL(val) (((val) & 0xF) << 4) 152031542fcSKonstantin Porotchkin #define MCI_CTRL_MCI_PHY_SET_AUTO_LINK_EN(val) (((val) & 0x1) << 1) 153031542fcSKonstantin Porotchkin #define MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL \ 154031542fcSKonstantin Porotchkin (MCI_CTRL_MCI_PHY_SET_DLO_FIFO_FULL_TRESH(0x3) | \ 155031542fcSKonstantin Porotchkin MCI_CTRL_MCI_PHY_SET_PHY_MAX_SPEED(0x3) | \ 156031542fcSKonstantin Porotchkin MCI_CTRL_MCI_PHY_SET_PHYCLK_SEL(0x2) | \ 157031542fcSKonstantin Porotchkin MCI_CTRL_MCI_PHY_SET_REFCLK_FREQ_SEL(0x1)) 158031542fcSKonstantin Porotchkin #define MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL2 \ 159031542fcSKonstantin Porotchkin (MCI_CTRL_MCI_PHY_SET_DLO_FIFO_FULL_TRESH(0x3) | \ 160031542fcSKonstantin Porotchkin MCI_CTRL_MCI_PHY_SET_PHY_MAX_SPEED(0x3) | \ 161031542fcSKonstantin Porotchkin MCI_CTRL_MCI_PHY_SET_PHYCLK_SEL(0x5) | \ 162031542fcSKonstantin Porotchkin MCI_CTRL_MCI_PHY_SET_REFCLK_FREQ_SEL(0x1)) 163031542fcSKonstantin Porotchkin 164031542fcSKonstantin Porotchkin /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers 165031542fcSKonstantin Porotchkin * /IHB Mode Config 166031542fcSKonstantin Porotchkin */ 167031542fcSKonstantin Porotchkin #define MCI_CTRL_IHB_MODE_CFG_REG_NUM 0x25 168031542fcSKonstantin Porotchkin #define MCI_CTRL_IHB_MODE_HBCLK_DIV(val) ((val) & 0xFF) 169031542fcSKonstantin Porotchkin #define MCI_CTRL_IHB_MODE_CHUNK_MOD_OFFSET 8 170031542fcSKonstantin Porotchkin #define MCI_CTRL_IHB_MODE_CHUNK_MOD \ 171031542fcSKonstantin Porotchkin (1 << MCI_CTRL_IHB_MODE_CHUNK_MOD_OFFSET) 172031542fcSKonstantin Porotchkin #define MCI_CTRL_IHB_MODE_FWD_MOD_OFFSET 9 173031542fcSKonstantin Porotchkin #define MCI_CTRL_IHB_MODE_FWD_MOD \ 174031542fcSKonstantin Porotchkin (1 << MCI_CTRL_IHB_MODE_FWD_MOD_OFFSET) 175031542fcSKonstantin Porotchkin #define MCI_CTRL_IHB_MODE_SEQFF_FINE_MOD(val) (((val) & 0xF) << 12) 176031542fcSKonstantin Porotchkin #define MCI_CTRL_IHB_MODE_RX_COMB_THRESH(val) (((val) & 0xFF) << 16) 177031542fcSKonstantin Porotchkin #define MCI_CTRL_IHB_MODE_TX_COMB_THRESH(val) (((val) & 0xFF) << 24) 178031542fcSKonstantin Porotchkin 179031542fcSKonstantin Porotchkin #define MCI_CTRL_IHB_MODE_CFG_REG_DEF_VAL \ 180031542fcSKonstantin Porotchkin (MCI_CTRL_IHB_MODE_HBCLK_DIV(6) | \ 181031542fcSKonstantin Porotchkin MCI_CTRL_IHB_MODE_FWD_MOD | \ 182031542fcSKonstantin Porotchkin MCI_CTRL_IHB_MODE_SEQFF_FINE_MOD(0xF) | \ 183031542fcSKonstantin Porotchkin MCI_CTRL_IHB_MODE_RX_COMB_THRESH(0x3f) | \ 184031542fcSKonstantin Porotchkin MCI_CTRL_IHB_MODE_TX_COMB_THRESH(0x40)) 185031542fcSKonstantin Porotchkin /* AXI_HB registers */ 186031542fcSKonstantin Porotchkin #define MCI_AXI_ACCESS_DATA_REG_NUM 0x0 187031542fcSKonstantin Porotchkin #define MCI_AXI_ACCESS_PCIE_MODE 1 188031542fcSKonstantin Porotchkin #define MCI_AXI_ACCESS_CACHE_CHECK_OFFSET 5 189031542fcSKonstantin Porotchkin #define MCI_AXI_ACCESS_CACHE_CHECK \ 190031542fcSKonstantin Porotchkin (1 << MCI_AXI_ACCESS_CACHE_CHECK_OFFSET) 191031542fcSKonstantin Porotchkin #define MCI_AXI_ACCESS_FORCE_POST_WR_OFFSET 6 192031542fcSKonstantin Porotchkin #define MCI_AXI_ACCESS_FORCE_POST_WR \ 193031542fcSKonstantin Porotchkin (1 << MCI_AXI_ACCESS_FORCE_POST_WR_OFFSET) 194031542fcSKonstantin Porotchkin #define MCI_AXI_ACCESS_DISABLE_CLK_GATING_OFFSET 9 195031542fcSKonstantin Porotchkin #define MCI_AXI_ACCESS_DISABLE_CLK_GATING \ 196031542fcSKonstantin Porotchkin (1 << MCI_AXI_ACCESS_DISABLE_CLK_GATING_OFFSET) 197031542fcSKonstantin Porotchkin 198031542fcSKonstantin Porotchkin /* /HB /Units /HB_REG /HB_REGHopping Bus Registers 199031542fcSKonstantin Porotchkin * /Window 0 Address Mask Register 200031542fcSKonstantin Porotchkin */ 201031542fcSKonstantin Porotchkin #define MCI_HB_CTRL_WIN0_ADDRESS_MASK_REG_NUM 0x2 202031542fcSKonstantin Porotchkin 203031542fcSKonstantin Porotchkin /* /HB /Units /HB_REG /HB_REGHopping Bus Registers 204031542fcSKonstantin Porotchkin * /Window 0 Destination Register 205031542fcSKonstantin Porotchkin */ 206031542fcSKonstantin Porotchkin #define MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM 0x3 207031542fcSKonstantin Porotchkin #define MCI_HB_CTRL_WIN0_DEST_VALID_FLAG(val) (((val) & 0x1) << 16) 208031542fcSKonstantin Porotchkin #define MCI_HB_CTRL_WIN0_DEST_ID(val) (((val) & 0xFF) << 0) 209031542fcSKonstantin Porotchkin 210031542fcSKonstantin Porotchkin /* /HB /Units /HB_REG /HB_REGHopping Bus Registers /Tx Control Register */ 211031542fcSKonstantin Porotchkin #define MCI_HB_CTRL_TX_CTRL_REG_NUM 0xD 212031542fcSKonstantin Porotchkin #define MCI_HB_CTRL_TX_CTRL_PCIE_MODE_OFFSET 24 213031542fcSKonstantin Porotchkin #define MCI_HB_CTRL_TX_CTRL_PCIE_MODE \ 214031542fcSKonstantin Porotchkin (1 << MCI_HB_CTRL_TX_CTRL_PCIE_MODE_OFFSET) 215031542fcSKonstantin Porotchkin #define MCI_HB_CTRL_TX_CTRL_PRI_TH_QOS(val) (((val) & 0xF) << 12) 216031542fcSKonstantin Porotchkin #define MCI_HB_CTRL_TX_CTRL_MAX_RD_CNT(val) (((val) & 0x1F) << 6) 217031542fcSKonstantin Porotchkin #define MCI_HB_CTRL_TX_CTRL_MAX_WR_CNT(val) (((val) & 0x1F) << 0) 218031542fcSKonstantin Porotchkin 219031542fcSKonstantin Porotchkin /* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers 220031542fcSKonstantin Porotchkin * /IHB Version Control Register 221031542fcSKonstantin Porotchkin */ 222031542fcSKonstantin Porotchkin #define MCI_PHY_CTRL_REG_NUM 0x7 223031542fcSKonstantin Porotchkin #define MCI_PHY_CTRL_MCI_MINOR 0x8 /* BITS [3:0] */ 224031542fcSKonstantin Porotchkin #define MCI_PHY_CTRL_MCI_MAJOR_OFFSET 4 225031542fcSKonstantin Porotchkin #define MCI_PHY_CTRL_MCI_MAJOR \ 226031542fcSKonstantin Porotchkin (1 << MCI_PHY_CTRL_MCI_MAJOR_OFFSET) 227031542fcSKonstantin Porotchkin #define MCI_PHY_CTRL_MCI_SLEEP_REQ_OFFSET 11 228031542fcSKonstantin Porotchkin #define MCI_PHY_CTRL_MCI_SLEEP_REQ \ 229031542fcSKonstantin Porotchkin (1 << MCI_PHY_CTRL_MCI_SLEEP_REQ_OFFSET) 230031542fcSKonstantin Porotchkin /* Host=1 / Device=0 PHY mode */ 231031542fcSKonstantin Porotchkin #define MCI_PHY_CTRL_MCI_PHY_MODE_OFFSET 24 232031542fcSKonstantin Porotchkin #define MCI_PHY_CTRL_MCI_PHY_MODE_HOST \ 233031542fcSKonstantin Porotchkin (1 << MCI_PHY_CTRL_MCI_PHY_MODE_OFFSET) 234031542fcSKonstantin Porotchkin /* Register=1 / PWM=0 interface */ 235031542fcSKonstantin Porotchkin #define MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE_OFFSET 25 236031542fcSKonstantin Porotchkin #define MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE \ 237031542fcSKonstantin Porotchkin (1 << MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE_OFFSET) 238031542fcSKonstantin Porotchkin /* PHY code InReset=1 */ 239031542fcSKonstantin Porotchkin #define MCI_PHY_CTRL_MCI_PHY_RESET_CORE_OFFSET 26 240031542fcSKonstantin Porotchkin #define MCI_PHY_CTRL_MCI_PHY_RESET_CORE \ 241031542fcSKonstantin Porotchkin (1 << MCI_PHY_CTRL_MCI_PHY_RESET_CORE_OFFSET) 242031542fcSKonstantin Porotchkin #define MCI_PHY_CTRL_PHY_ADDR_MSB_OFFSET 27 243031542fcSKonstantin Porotchkin #define MCI_PHY_CTRL_PHY_ADDR_MSB(addr) \ 244031542fcSKonstantin Porotchkin (((addr) & 0x3) << \ 245031542fcSKonstantin Porotchkin MCI_PHY_CTRL_PHY_ADDR_MSB_OFFSET) 246031542fcSKonstantin Porotchkin #define MCI_PHY_CTRL_PIDI_MODE_OFFSET 31 247031542fcSKonstantin Porotchkin #define MCI_PHY_CTRL_PIDI_MODE \ 248*b19498b9SJustin Chadwell (1U << MCI_PHY_CTRL_PIDI_MODE_OFFSET) 249031542fcSKonstantin Porotchkin 250031542fcSKonstantin Porotchkin /* Number of times to wait for the MCI link ready after MCI configurations 251031542fcSKonstantin Porotchkin * Normally takes 34-35 successive reads 252031542fcSKonstantin Porotchkin */ 253031542fcSKonstantin Porotchkin #define LINK_READY_TIMEOUT 100 254031542fcSKonstantin Porotchkin 255031542fcSKonstantin Porotchkin enum mci_register_type { 256031542fcSKonstantin Porotchkin MCI_REG_TYPE_PHY = 0, 257031542fcSKonstantin Porotchkin MCI_REG_TYPE_CTRL, 258031542fcSKonstantin Porotchkin }; 259031542fcSKonstantin Porotchkin 260031542fcSKonstantin Porotchkin enum { 261031542fcSKonstantin Porotchkin MCI_CMD_WRITE, 262031542fcSKonstantin Porotchkin MCI_CMD_READ 263031542fcSKonstantin Porotchkin }; 264031542fcSKonstantin Porotchkin 265031542fcSKonstantin Porotchkin /* Write wrapper callback for debug: 266031542fcSKonstantin Porotchkin * will print written data in case LOG_LEVEL >= 40 267031542fcSKonstantin Porotchkin */ 268031542fcSKonstantin Porotchkin static void mci_mmio_write_32(uintptr_t addr, uint32_t value) 269031542fcSKonstantin Porotchkin { 270031542fcSKonstantin Porotchkin VERBOSE("Write:\t0x%x = 0x%x\n", (uint32_t)addr, value); 271031542fcSKonstantin Porotchkin mmio_write_32(addr, value); 272031542fcSKonstantin Porotchkin } 273031542fcSKonstantin Porotchkin /* Read wrapper callback for debug: 274031542fcSKonstantin Porotchkin * will print read data in case LOG_LEVEL >= 40 275031542fcSKonstantin Porotchkin */ 276031542fcSKonstantin Porotchkin static uint32_t mci_mmio_read_32(uintptr_t addr) 277031542fcSKonstantin Porotchkin { 278031542fcSKonstantin Porotchkin uint32_t value; 279031542fcSKonstantin Porotchkin 280031542fcSKonstantin Porotchkin value = mmio_read_32(addr); 281031542fcSKonstantin Porotchkin VERBOSE("Read:\t0x%x = 0x%x\n", (uint32_t)addr, value); 282031542fcSKonstantin Porotchkin return value; 283031542fcSKonstantin Porotchkin } 284031542fcSKonstantin Porotchkin 285031542fcSKonstantin Porotchkin /* MCI indirect access command completion polling: 286031542fcSKonstantin Porotchkin * Each write/read command done via MCI indirect registers must be polled 287031542fcSKonstantin Porotchkin * for command completions status. 288031542fcSKonstantin Porotchkin * 289031542fcSKonstantin Porotchkin * Returns 1 in case of error 290031542fcSKonstantin Porotchkin * Returns 0 in case of command completed successfully. 291031542fcSKonstantin Porotchkin */ 292031542fcSKonstantin Porotchkin static int mci_poll_command_completion(int mci_index, int command_type) 293031542fcSKonstantin Porotchkin { 294031542fcSKonstantin Porotchkin uint32_t mci_cmd_value = 0, retry_count = 100, ret = 0; 295031542fcSKonstantin Porotchkin uint32_t completion_flags = MCI_INDIRECT_CTRL_CMD_DONE; 296031542fcSKonstantin Porotchkin 297031542fcSKonstantin Porotchkin debug_enter(); 298031542fcSKonstantin Porotchkin /* Read commands require validating that requested data is ready */ 299031542fcSKonstantin Porotchkin if (command_type == MCI_CMD_READ) 300031542fcSKonstantin Porotchkin completion_flags |= MCI_INDIRECT_CTRL_DATA_READY; 301031542fcSKonstantin Porotchkin 302031542fcSKonstantin Porotchkin do { 303031542fcSKonstantin Porotchkin /* wait 1 ms before each polling */ 304031542fcSKonstantin Porotchkin mdelay(1); 305031542fcSKonstantin Porotchkin mci_cmd_value = mci_mmio_read_32(MCI_ACCESS_CMD_REG(mci_index)); 306031542fcSKonstantin Porotchkin } while (((mci_cmd_value & completion_flags) != completion_flags) && 307031542fcSKonstantin Porotchkin (retry_count-- > 0)); 308031542fcSKonstantin Porotchkin 309031542fcSKonstantin Porotchkin if (retry_count == 0) { 310031542fcSKonstantin Porotchkin ERROR("%s: MCI command timeout (command status = 0x%x)\n", 311031542fcSKonstantin Porotchkin __func__, mci_cmd_value); 312031542fcSKonstantin Porotchkin ret = 1; 313031542fcSKonstantin Porotchkin } 314031542fcSKonstantin Porotchkin 315031542fcSKonstantin Porotchkin debug_exit(); 316031542fcSKonstantin Porotchkin return ret; 317031542fcSKonstantin Porotchkin } 318031542fcSKonstantin Porotchkin 319031542fcSKonstantin Porotchkin int mci_read(int mci_idx, uint32_t cmd, uint32_t *value) 320031542fcSKonstantin Porotchkin { 321031542fcSKonstantin Porotchkin int rval; 322031542fcSKonstantin Porotchkin 323031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_idx), cmd); 324031542fcSKonstantin Porotchkin 325031542fcSKonstantin Porotchkin rval = mci_poll_command_completion(mci_idx, MCI_CMD_READ); 326031542fcSKonstantin Porotchkin 327031542fcSKonstantin Porotchkin *value = mci_mmio_read_32(MCI_WRITE_READ_DATA_REG(mci_idx)); 328031542fcSKonstantin Porotchkin 329031542fcSKonstantin Porotchkin return rval; 330031542fcSKonstantin Porotchkin } 331031542fcSKonstantin Porotchkin 332031542fcSKonstantin Porotchkin int mci_write(int mci_idx, uint32_t cmd, uint32_t data) 333031542fcSKonstantin Porotchkin { 334031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_idx), data); 335031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_idx), cmd); 336031542fcSKonstantin Porotchkin 337031542fcSKonstantin Porotchkin return mci_poll_command_completion(mci_idx, MCI_CMD_WRITE); 338031542fcSKonstantin Porotchkin } 339031542fcSKonstantin Porotchkin 340031542fcSKonstantin Porotchkin /* Perform 3 configurations in one command: PCI mode, 341031542fcSKonstantin Porotchkin * queues separation and cache bit 342031542fcSKonstantin Porotchkin */ 343031542fcSKonstantin Porotchkin static int mci_axi_set_pcie_mode(int mci_index) 344031542fcSKonstantin Porotchkin { 345031542fcSKonstantin Porotchkin uint32_t reg_data, ret = 1; 346031542fcSKonstantin Porotchkin 347031542fcSKonstantin Porotchkin debug_enter(); 348031542fcSKonstantin Porotchkin /* This configuration makes MCI IP behave consistently with AXI protocol 349031542fcSKonstantin Porotchkin * It should be configured at one side only (for example locally at AP). 350031542fcSKonstantin Porotchkin * The IP takes care of performing the same configurations at MCI on 351031542fcSKonstantin Porotchkin * another side (for example remotely at CP). 352031542fcSKonstantin Porotchkin */ 353031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), 354031542fcSKonstantin Porotchkin MCI_AXI_ACCESS_PCIE_MODE | 355031542fcSKonstantin Porotchkin MCI_AXI_ACCESS_CACHE_CHECK | 356031542fcSKonstantin Porotchkin MCI_AXI_ACCESS_FORCE_POST_WR | 357031542fcSKonstantin Porotchkin MCI_AXI_ACCESS_DISABLE_CLK_GATING); 358031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), 359031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR( 360031542fcSKonstantin Porotchkin MCI_AXI_ACCESS_DATA_REG_NUM) | 361031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) | 362031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_LOCAL_PKT | 363031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_CIRCULAR_CMD); 364031542fcSKonstantin Porotchkin 365031542fcSKonstantin Porotchkin /* if Write command was successful, verify PCIe mode */ 366031542fcSKonstantin Porotchkin if (mci_poll_command_completion(mci_index, MCI_CMD_WRITE) == 0) { 367031542fcSKonstantin Porotchkin /* Verify the PCIe mode selected */ 368031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), 369031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR( 370031542fcSKonstantin Porotchkin MCI_HB_CTRL_TX_CTRL_REG_NUM) | 371031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) | 372031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_LOCAL_PKT | 373031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_READ_CMD); 374031542fcSKonstantin Porotchkin /* if read was completed, verify PCIe mode */ 375031542fcSKonstantin Porotchkin if (mci_poll_command_completion(mci_index, MCI_CMD_READ) == 0) { 376031542fcSKonstantin Porotchkin reg_data = mci_mmio_read_32( 377031542fcSKonstantin Porotchkin MCI_WRITE_READ_DATA_REG(mci_index)); 378031542fcSKonstantin Porotchkin if (reg_data & MCI_HB_CTRL_TX_CTRL_PCIE_MODE) 379031542fcSKonstantin Porotchkin ret = 0; 380031542fcSKonstantin Porotchkin } 381031542fcSKonstantin Porotchkin } 382031542fcSKonstantin Porotchkin 383031542fcSKonstantin Porotchkin debug_exit(); 384031542fcSKonstantin Porotchkin return ret; 385031542fcSKonstantin Porotchkin } 386031542fcSKonstantin Porotchkin 387031542fcSKonstantin Porotchkin /* Reduce sequence FIFO timer expiration threshold */ 388031542fcSKonstantin Porotchkin static int mci_axi_set_fifo_thresh(int mci_index) 389031542fcSKonstantin Porotchkin { 390031542fcSKonstantin Porotchkin uint32_t reg_data, ret = 0; 391031542fcSKonstantin Porotchkin 392031542fcSKonstantin Porotchkin debug_enter(); 393031542fcSKonstantin Porotchkin /* This configuration reduces sequence FIFO timer expiration threshold 394031542fcSKonstantin Porotchkin * (to 0x7 instead of 0xA). 395031542fcSKonstantin Porotchkin * In MCI 1.6 version this configuration prevents possible functional 396031542fcSKonstantin Porotchkin * issues. 397031542fcSKonstantin Porotchkin * In version 1.82 the configuration prevents performance degradation 398031542fcSKonstantin Porotchkin */ 399031542fcSKonstantin Porotchkin 400031542fcSKonstantin Porotchkin /* Configure local AP side */ 401031542fcSKonstantin Porotchkin reg_data = MCI_PHY_CTRL_PIDI_MODE | 402031542fcSKonstantin Porotchkin MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE | 403031542fcSKonstantin Porotchkin MCI_PHY_CTRL_MCI_PHY_MODE_HOST | 404031542fcSKonstantin Porotchkin MCI_PHY_CTRL_MCI_MAJOR | 405031542fcSKonstantin Porotchkin MCI_PHY_CTRL_MCI_MINOR; 406031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), reg_data); 407031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), 408031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM) | 409031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_LOCAL_PKT); 410031542fcSKonstantin Porotchkin ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); 411031542fcSKonstantin Porotchkin 412031542fcSKonstantin Porotchkin /* Reduce the threshold */ 413031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), 414031542fcSKonstantin Porotchkin MCI_CTRL_IHB_MODE_CFG_REG_DEF_VAL); 415031542fcSKonstantin Porotchkin 416031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), 417031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR( 418031542fcSKonstantin Porotchkin MCI_CTRL_IHB_MODE_CFG_REG_NUM) | 419031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_LOCAL_PKT); 420031542fcSKonstantin Porotchkin ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); 421031542fcSKonstantin Porotchkin 422031542fcSKonstantin Porotchkin /* Exit PIDI mode */ 423031542fcSKonstantin Porotchkin reg_data = MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE | 424031542fcSKonstantin Porotchkin MCI_PHY_CTRL_MCI_PHY_MODE_HOST | 425031542fcSKonstantin Porotchkin MCI_PHY_CTRL_MCI_MAJOR | 426031542fcSKonstantin Porotchkin MCI_PHY_CTRL_MCI_MINOR; 427031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), reg_data); 428031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), 429031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM) | 430031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_LOCAL_PKT); 431031542fcSKonstantin Porotchkin ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); 432031542fcSKonstantin Porotchkin 433031542fcSKonstantin Porotchkin /* Configure remote CP side */ 434031542fcSKonstantin Porotchkin reg_data = MCI_PHY_CTRL_PIDI_MODE | 435031542fcSKonstantin Porotchkin MCI_PHY_CTRL_MCI_MAJOR | 436031542fcSKonstantin Porotchkin MCI_PHY_CTRL_MCI_MINOR | 437031542fcSKonstantin Porotchkin MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE; 438031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), reg_data); 439031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), 440031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM) | 441031542fcSKonstantin Porotchkin MCI_CTRL_IHB_MODE_FWD_MOD); 442031542fcSKonstantin Porotchkin ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); 443031542fcSKonstantin Porotchkin 444031542fcSKonstantin Porotchkin /* Reduce the threshold */ 445031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), 446031542fcSKonstantin Porotchkin MCI_CTRL_IHB_MODE_CFG_REG_DEF_VAL); 447031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), 448031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR( 449031542fcSKonstantin Porotchkin MCI_CTRL_IHB_MODE_CFG_REG_NUM) | 450031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT)); 451031542fcSKonstantin Porotchkin ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); 452031542fcSKonstantin Porotchkin 453031542fcSKonstantin Porotchkin /* Exit PIDI mode */ 454031542fcSKonstantin Porotchkin reg_data = MCI_PHY_CTRL_MCI_MAJOR | 455031542fcSKonstantin Porotchkin MCI_PHY_CTRL_MCI_MINOR | 456031542fcSKonstantin Porotchkin MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE; 457031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), reg_data); 458031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), 459031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM) | 460031542fcSKonstantin Porotchkin MCI_CTRL_IHB_MODE_FWD_MOD); 461031542fcSKonstantin Porotchkin 462031542fcSKonstantin Porotchkin ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); 463031542fcSKonstantin Porotchkin 464031542fcSKonstantin Porotchkin debug_exit(); 465031542fcSKonstantin Porotchkin return ret; 466031542fcSKonstantin Porotchkin } 467031542fcSKonstantin Porotchkin 468031542fcSKonstantin Porotchkin /* Configure: 469031542fcSKonstantin Porotchkin * 1. AP & CP TX thresholds and delta configurations 470031542fcSKonstantin Porotchkin * 2. DLO & DLI FIFO full threshold 471031542fcSKonstantin Porotchkin * 3. RX thresholds and delta configurations 472031542fcSKonstantin Porotchkin * 4. CP AR and AW outstanding 473031542fcSKonstantin Porotchkin * 5. AP AR and AW outstanding 474031542fcSKonstantin Porotchkin */ 475031542fcSKonstantin Porotchkin static int mci_axi_set_fifo_rx_tx_thresh(int mci_index) 476031542fcSKonstantin Porotchkin { 477031542fcSKonstantin Porotchkin uint32_t ret = 0; 478031542fcSKonstantin Porotchkin 479031542fcSKonstantin Porotchkin debug_enter(); 480031542fcSKonstantin Porotchkin /* AP TX thresholds and delta configurations (IHB_reg 0x1) */ 481031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), 482031542fcSKonstantin Porotchkin MCI_CTRL_TX_MEM_CFG_REG_DEF_VAL); 483031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), 484031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR( 485031542fcSKonstantin Porotchkin MCI_CTRL_TX_MEM_CFG_REG_NUM) | 486031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_LOCAL_PKT); 487031542fcSKonstantin Porotchkin ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); 488031542fcSKonstantin Porotchkin 489031542fcSKonstantin Porotchkin /* CP TX thresholds and delta configurations (IHB_reg 0x1) */ 490031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), 491031542fcSKonstantin Porotchkin MCI_CTRL_TX_MEM_CFG_REG_DEF_VAL); 492031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), 493031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR( 494031542fcSKonstantin Porotchkin MCI_CTRL_TX_MEM_CFG_REG_NUM) | 495031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT)); 496031542fcSKonstantin Porotchkin ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); 497031542fcSKonstantin Porotchkin 498031542fcSKonstantin Porotchkin /* AP DLO & DLI FIFO full threshold & Auto-Link enable (IHB_reg 0x8) */ 499031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), 500031542fcSKonstantin Porotchkin MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL | 501031542fcSKonstantin Porotchkin MCI_CTRL_MCI_PHY_SET_AUTO_LINK_EN(1)); 502031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), 503031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR( 504031542fcSKonstantin Porotchkin MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM) | 505031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_LOCAL_PKT); 506031542fcSKonstantin Porotchkin ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); 507031542fcSKonstantin Porotchkin 508031542fcSKonstantin Porotchkin /* CP DLO & DLI FIFO full threshold (IHB_reg 0x8) */ 509031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), 510031542fcSKonstantin Porotchkin MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL); 511031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), 512031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR( 513031542fcSKonstantin Porotchkin MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM) | 514031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT)); 515031542fcSKonstantin Porotchkin ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); 516031542fcSKonstantin Porotchkin 517031542fcSKonstantin Porotchkin /* AP RX thresholds and delta configurations (IHB_reg 0x0) */ 518031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), 519031542fcSKonstantin Porotchkin MCI_CTRL_RX_MEM_CFG_REG_DEF_AP_VAL); 520031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), 521031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR( 522031542fcSKonstantin Porotchkin MCI_CTRL_RX_MEM_CFG_REG_NUM) | 523031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_LOCAL_PKT); 524031542fcSKonstantin Porotchkin ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); 525031542fcSKonstantin Porotchkin 526031542fcSKonstantin Porotchkin /* CP RX thresholds and delta configurations (IHB_reg 0x0) */ 527031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), 528031542fcSKonstantin Porotchkin MCI_CTRL_RX_MEM_CFG_REG_DEF_CP_VAL); 529031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), 530031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR( 531031542fcSKonstantin Porotchkin MCI_CTRL_RX_MEM_CFG_REG_NUM) | 532031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT)); 533031542fcSKonstantin Porotchkin ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); 534031542fcSKonstantin Porotchkin 535031542fcSKonstantin Porotchkin /* AP AR & AW maximum AXI outstanding request cfg (HB_reg 0xd) */ 536031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), 537031542fcSKonstantin Porotchkin MCI_HB_CTRL_TX_CTRL_PRI_TH_QOS(8) | 538031542fcSKonstantin Porotchkin MCI_HB_CTRL_TX_CTRL_MAX_RD_CNT(3) | 539031542fcSKonstantin Porotchkin MCI_HB_CTRL_TX_CTRL_MAX_WR_CNT(3)); 540031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), 541031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR( 542031542fcSKonstantin Porotchkin MCI_HB_CTRL_TX_CTRL_REG_NUM) | 543031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) | 544031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_LOCAL_PKT); 545031542fcSKonstantin Porotchkin ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); 546031542fcSKonstantin Porotchkin 547031542fcSKonstantin Porotchkin /* CP AR & AW maximum AXI outstanding request cfg (HB_reg 0xd) */ 548031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), 549031542fcSKonstantin Porotchkin MCI_HB_CTRL_TX_CTRL_PRI_TH_QOS(8) | 550031542fcSKonstantin Porotchkin MCI_HB_CTRL_TX_CTRL_MAX_RD_CNT(0xB) | 551031542fcSKonstantin Porotchkin MCI_HB_CTRL_TX_CTRL_MAX_WR_CNT(0x11)); 552031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index), 553031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR( 554031542fcSKonstantin Porotchkin MCI_HB_CTRL_TX_CTRL_REG_NUM) | 555031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT) | 556031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB)); 557031542fcSKonstantin Porotchkin ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); 558031542fcSKonstantin Porotchkin 559031542fcSKonstantin Porotchkin debug_exit(); 560031542fcSKonstantin Porotchkin return ret; 561031542fcSKonstantin Porotchkin } 562031542fcSKonstantin Porotchkin 563031542fcSKonstantin Porotchkin /* configure MCI to allow read & write transactions to arrive at the same time. 564031542fcSKonstantin Porotchkin * Without the below configuration, MCI won't sent response to CPU for 565031542fcSKonstantin Porotchkin * transactions which arrived simultaneously and will lead to CPU hang. 566031542fcSKonstantin Porotchkin * The below will configure MCI to be able to pass transactions from/to CP/AP. 567031542fcSKonstantin Porotchkin */ 568031542fcSKonstantin Porotchkin static int mci_enable_simultaneous_transactions(int mci_index) 569031542fcSKonstantin Porotchkin { 570031542fcSKonstantin Porotchkin uint32_t ret = 0; 571031542fcSKonstantin Porotchkin 572031542fcSKonstantin Porotchkin debug_enter(); 573031542fcSKonstantin Porotchkin /* ID assignment (assigning global ID offset to CP) */ 574031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0), 575031542fcSKonstantin Porotchkin MCI_DID_GLOBAL_ASSIGN_REQ_MCI_LOCAL_ID(2) | 576031542fcSKonstantin Porotchkin MCI_DID_GLOBAL_ASSIGN_REQ_MCI_COUNT(2) | 577031542fcSKonstantin Porotchkin MCI_DID_GLOBAL_ASSIGN_REQ_HOPS_NUM(2)); 578031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(0), 579031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR( 580031542fcSKonstantin Porotchkin MCI_DID_GLOBAL_ASSIGNMENT_REQUEST_REG) | 581031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_ASSIGN_CMD); 582031542fcSKonstantin Porotchkin ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); 583031542fcSKonstantin Porotchkin 584031542fcSKonstantin Porotchkin /* Assigning dest. ID=3 to all transactions entering from AXI at AP */ 585031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0), 586031542fcSKonstantin Porotchkin MCI_HB_CTRL_WIN0_DEST_VALID_FLAG(1) | 587031542fcSKonstantin Porotchkin MCI_HB_CTRL_WIN0_DEST_ID(3)); 588031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(0), 589031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR( 590031542fcSKonstantin Porotchkin MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM) | 591031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) | 592031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_LOCAL_PKT); 593031542fcSKonstantin Porotchkin ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); 594031542fcSKonstantin Porotchkin 595031542fcSKonstantin Porotchkin /* Assigning dest. ID=1 to all transactions entering from AXI at CP */ 596031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0), 597031542fcSKonstantin Porotchkin MCI_HB_CTRL_WIN0_DEST_VALID_FLAG(1) | 598031542fcSKonstantin Porotchkin MCI_HB_CTRL_WIN0_DEST_ID(1)); 599031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(0), 600031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR( 601031542fcSKonstantin Porotchkin MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM) | 602031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT) | 603031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB)); 604031542fcSKonstantin Porotchkin ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); 605031542fcSKonstantin Porotchkin 606031542fcSKonstantin Porotchkin /* End address to all transactions entering from AXI at AP. 607031542fcSKonstantin Porotchkin * This will lead to get match for any AXI address 608031542fcSKonstantin Porotchkin * and receive destination ID=3 609031542fcSKonstantin Porotchkin */ 610031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0), 0xffffffff); 611031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(0), 612031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR( 613031542fcSKonstantin Porotchkin MCI_HB_CTRL_WIN0_ADDRESS_MASK_REG_NUM) | 614031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) | 615031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_LOCAL_PKT); 616031542fcSKonstantin Porotchkin ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); 617031542fcSKonstantin Porotchkin 618031542fcSKonstantin Porotchkin /* End address to all transactions entering from AXI at CP. 619031542fcSKonstantin Porotchkin * This will lead to get match for any AXI address 620031542fcSKonstantin Porotchkin * and receive destination ID=1 621031542fcSKonstantin Porotchkin */ 622031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0), 0xffffffff); 623031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(0), 624031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR( 625031542fcSKonstantin Porotchkin MCI_HB_CTRL_WIN0_ADDRESS_MASK_REG_NUM) | 626031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT) | 627031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB)); 628031542fcSKonstantin Porotchkin ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE); 629031542fcSKonstantin Porotchkin 630031542fcSKonstantin Porotchkin debug_exit(); 631031542fcSKonstantin Porotchkin return ret; 632031542fcSKonstantin Porotchkin } 633031542fcSKonstantin Porotchkin 634031542fcSKonstantin Porotchkin /* Check if MCI simultaneous transaction was already enabled. 635031542fcSKonstantin Porotchkin * Currently bootrom does this mci configuration only when the boot source is 636031542fcSKonstantin Porotchkin * SAR_MCIX4, in other cases it should be done at this stage. 637031542fcSKonstantin Porotchkin * It is worth noticing that in case of booting from uart, the bootrom 638031542fcSKonstantin Porotchkin * flow is different and this mci initialization is skipped even if boot 639031542fcSKonstantin Porotchkin * source is SAR_MCIX4. Therefore new verification bases on appropriate mci's 640031542fcSKonstantin Porotchkin * register content: if the appropriate reg contains 0x0 it means that the 641031542fcSKonstantin Porotchkin * bootrom didn't perform required mci configuration. 642031542fcSKonstantin Porotchkin * 643031542fcSKonstantin Porotchkin * Returns: 644031542fcSKonstantin Porotchkin * 0 - configuration already done 645031542fcSKonstantin Porotchkin * 1 - configuration missing 646031542fcSKonstantin Porotchkin */ 647031542fcSKonstantin Porotchkin static _Bool mci_simulatenous_trans_missing(int mci_index) 648031542fcSKonstantin Porotchkin { 649031542fcSKonstantin Porotchkin uint32_t reg, ret; 650031542fcSKonstantin Porotchkin 651031542fcSKonstantin Porotchkin /* read 'Window 0 Destination ID assignment' from HB register 0x3 652031542fcSKonstantin Porotchkin * (TX_CFG_W0_DST_ID) to check whether ID assignment was already 653031542fcSKonstantin Porotchkin * performed by BootROM. 654031542fcSKonstantin Porotchkin */ 655031542fcSKonstantin Porotchkin debug_enter(); 656031542fcSKonstantin Porotchkin mci_mmio_write_32(MCI_ACCESS_CMD_REG(0), 657031542fcSKonstantin Porotchkin MCI_INDIRECT_REG_CTRL_ADDR( 658031542fcSKonstantin Porotchkin MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM) | 659031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) | 660031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_LOCAL_PKT | 661031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_READ_CMD); 662031542fcSKonstantin Porotchkin ret = mci_poll_command_completion(mci_index, MCI_CMD_READ); 663031542fcSKonstantin Porotchkin 664031542fcSKonstantin Porotchkin reg = mci_mmio_read_32(MCI_WRITE_READ_DATA_REG(mci_index)); 665031542fcSKonstantin Porotchkin 666031542fcSKonstantin Porotchkin if (ret) 667031542fcSKonstantin Porotchkin ERROR("Failed to verify MCI simultaneous read/write status\n"); 668031542fcSKonstantin Porotchkin 669031542fcSKonstantin Porotchkin debug_exit(); 670031542fcSKonstantin Porotchkin /* default ID assignment is 0, so if register doesn't contain zeros 671031542fcSKonstantin Porotchkin * it means that bootrom already performed required configuration. 672031542fcSKonstantin Porotchkin */ 673031542fcSKonstantin Porotchkin if (reg != 0) 674031542fcSKonstantin Porotchkin return 0; 675031542fcSKonstantin Porotchkin 676031542fcSKonstantin Porotchkin return 1; 677031542fcSKonstantin Porotchkin } 678031542fcSKonstantin Porotchkin 679031542fcSKonstantin Porotchkin /* For A1 revision, configure the MCI link for performance improvement: 680031542fcSKonstantin Porotchkin * - set MCI to support read/write transactions to arrive at the same time 681031542fcSKonstantin Porotchkin * - Switch AXI to PCIe mode 682031542fcSKonstantin Porotchkin * - Reduce sequence FIFO threshold 683031542fcSKonstantin Porotchkin * - Configure RX/TX FIFO thresholds 684031542fcSKonstantin Porotchkin * 685031542fcSKonstantin Porotchkin * Note: 686031542fcSKonstantin Porotchkin * We don't exit on error code from any sub routine, to try (best effort) to 687031542fcSKonstantin Porotchkin * complete the MCI configuration. 688031542fcSKonstantin Porotchkin * (If we exit - Bootloader will surely fail to boot) 689031542fcSKonstantin Porotchkin */ 690031542fcSKonstantin Porotchkin int mci_configure(int mci_index) 691031542fcSKonstantin Porotchkin { 692031542fcSKonstantin Porotchkin int rval; 693031542fcSKonstantin Porotchkin 694031542fcSKonstantin Porotchkin debug_enter(); 695031542fcSKonstantin Porotchkin /* According to design guidelines the MCI simultaneous transaction 696031542fcSKonstantin Porotchkin * shouldn't be enabled more then once - therefore make sure that it 697031542fcSKonstantin Porotchkin * wasn't already enabled in bootrom. 698031542fcSKonstantin Porotchkin */ 699031542fcSKonstantin Porotchkin if (mci_simulatenous_trans_missing(mci_index)) { 700031542fcSKonstantin Porotchkin VERBOSE("Enabling MCI simultaneous transaction\n"); 701031542fcSKonstantin Porotchkin /* set MCI to support read/write transactions 702031542fcSKonstantin Porotchkin * to arrive at the same time 703031542fcSKonstantin Porotchkin */ 704031542fcSKonstantin Porotchkin rval = mci_enable_simultaneous_transactions(mci_index); 705031542fcSKonstantin Porotchkin if (rval) 706031542fcSKonstantin Porotchkin ERROR("Failed to set MCI simultaneous read/write\n"); 707031542fcSKonstantin Porotchkin } else 708031542fcSKonstantin Porotchkin VERBOSE("Skip MCI ID assignment - already done by bootrom\n"); 709031542fcSKonstantin Porotchkin 710031542fcSKonstantin Porotchkin /* Configure MCI for more consistent behavior with AXI protocol */ 711031542fcSKonstantin Porotchkin rval = mci_axi_set_pcie_mode(mci_index); 712031542fcSKonstantin Porotchkin if (rval) 713031542fcSKonstantin Porotchkin ERROR("Failed to set MCI to AXI PCIe mode\n"); 714031542fcSKonstantin Porotchkin 715031542fcSKonstantin Porotchkin /* reduce FIFO global threshold */ 716031542fcSKonstantin Porotchkin rval = mci_axi_set_fifo_thresh(mci_index); 717031542fcSKonstantin Porotchkin if (rval) 718031542fcSKonstantin Porotchkin ERROR("Failed to set MCI FIFO global threshold\n"); 719031542fcSKonstantin Porotchkin 720031542fcSKonstantin Porotchkin /* configure RX/TX FIFO thresholds */ 721031542fcSKonstantin Porotchkin rval = mci_axi_set_fifo_rx_tx_thresh(mci_index); 722031542fcSKonstantin Porotchkin if (rval) 723031542fcSKonstantin Porotchkin ERROR("Failed to set MCI RX/TX FIFO threshold\n"); 724031542fcSKonstantin Porotchkin 725031542fcSKonstantin Porotchkin debug_exit(); 726031542fcSKonstantin Porotchkin return 1; 727031542fcSKonstantin Porotchkin } 728031542fcSKonstantin Porotchkin 729031542fcSKonstantin Porotchkin int mci_get_link_status(void) 730031542fcSKonstantin Porotchkin { 731031542fcSKonstantin Porotchkin uint32_t cmd, data; 732031542fcSKonstantin Porotchkin 733031542fcSKonstantin Porotchkin cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_CTRL_STATUS_REG_NUM) | 734031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_LOCAL_PKT | MCI_INDIRECT_CTRL_READ_CMD); 735031542fcSKonstantin Porotchkin if (mci_read(0, cmd, &data)) { 736031542fcSKonstantin Porotchkin ERROR("Failed to read status register\n"); 737031542fcSKonstantin Porotchkin return -1; 738031542fcSKonstantin Porotchkin } 739031542fcSKonstantin Porotchkin 740031542fcSKonstantin Porotchkin /* Check if the link is ready */ 741031542fcSKonstantin Porotchkin if (data != MCI_CTRL_PHY_READY) { 742031542fcSKonstantin Porotchkin ERROR("Bad link status %x\n", data); 743031542fcSKonstantin Porotchkin return -1; 744031542fcSKonstantin Porotchkin } 745031542fcSKonstantin Porotchkin 746031542fcSKonstantin Porotchkin return 0; 747031542fcSKonstantin Porotchkin } 748031542fcSKonstantin Porotchkin 749031542fcSKonstantin Porotchkin void mci_turn_link_down(void) 750031542fcSKonstantin Porotchkin { 751031542fcSKonstantin Porotchkin uint32_t cmd, data; 752031542fcSKonstantin Porotchkin int rval = 0; 753031542fcSKonstantin Porotchkin 754031542fcSKonstantin Porotchkin debug_enter(); 755031542fcSKonstantin Porotchkin 756031542fcSKonstantin Porotchkin /* Turn off auto-link */ 757031542fcSKonstantin Porotchkin cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM) | 758031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_LOCAL_PKT); 759031542fcSKonstantin Porotchkin data = (MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL2 | 760031542fcSKonstantin Porotchkin MCI_CTRL_MCI_PHY_SET_AUTO_LINK_EN(0)); 761031542fcSKonstantin Porotchkin rval = mci_write(0, cmd, data); 762031542fcSKonstantin Porotchkin if (rval) 763031542fcSKonstantin Porotchkin ERROR("Failed to turn off auto-link\n"); 764031542fcSKonstantin Porotchkin 765031542fcSKonstantin Porotchkin /* Reset AP PHY */ 766031542fcSKonstantin Porotchkin cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM) | 767031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_LOCAL_PKT); 768031542fcSKonstantin Porotchkin data = (MCI_PHY_CTRL_MCI_MINOR | 769031542fcSKonstantin Porotchkin MCI_PHY_CTRL_MCI_MAJOR | 770031542fcSKonstantin Porotchkin MCI_PHY_CTRL_MCI_PHY_MODE_HOST | 771031542fcSKonstantin Porotchkin MCI_PHY_CTRL_MCI_PHY_RESET_CORE); 772031542fcSKonstantin Porotchkin rval = mci_write(0, cmd, data); 773031542fcSKonstantin Porotchkin if (rval) 774031542fcSKonstantin Porotchkin ERROR("Failed to reset AP PHY\n"); 775031542fcSKonstantin Porotchkin 776031542fcSKonstantin Porotchkin /* Clear all status & CRC values */ 777031542fcSKonstantin Porotchkin cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_LINK_CRC_CTRL_REG_NUM) | 778031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_LOCAL_PKT); 779031542fcSKonstantin Porotchkin data = 0x0; 780031542fcSKonstantin Porotchkin mci_write(0, cmd, data); 781031542fcSKonstantin Porotchkin cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_CTRL_STATUS_REG_NUM) | 782031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_LOCAL_PKT); 783031542fcSKonstantin Porotchkin data = 0x0; 784031542fcSKonstantin Porotchkin rval = mci_write(0, cmd, data); 785031542fcSKonstantin Porotchkin if (rval) 786031542fcSKonstantin Porotchkin ERROR("Failed to reset AP PHY\n"); 787031542fcSKonstantin Porotchkin 788031542fcSKonstantin Porotchkin /* Wait 5ms before un-reset the PHY */ 789031542fcSKonstantin Porotchkin mdelay(5); 790031542fcSKonstantin Porotchkin 791031542fcSKonstantin Porotchkin /* Un-reset AP PHY */ 792031542fcSKonstantin Porotchkin cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM) | 793031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_LOCAL_PKT); 794031542fcSKonstantin Porotchkin data = (MCI_PHY_CTRL_MCI_MINOR | MCI_PHY_CTRL_MCI_MAJOR | 795031542fcSKonstantin Porotchkin MCI_PHY_CTRL_MCI_PHY_MODE_HOST); 796031542fcSKonstantin Porotchkin rval = mci_write(0, cmd, data); 797031542fcSKonstantin Porotchkin if (rval) 798031542fcSKonstantin Porotchkin ERROR("Failed to un-reset AP PHY\n"); 799031542fcSKonstantin Porotchkin 800031542fcSKonstantin Porotchkin debug_exit(); 801031542fcSKonstantin Porotchkin } 802031542fcSKonstantin Porotchkin 803031542fcSKonstantin Porotchkin void mci_turn_link_on(void) 804031542fcSKonstantin Porotchkin { 805031542fcSKonstantin Porotchkin uint32_t cmd, data; 806031542fcSKonstantin Porotchkin int rval = 0; 807031542fcSKonstantin Porotchkin 808031542fcSKonstantin Porotchkin debug_enter(); 809031542fcSKonstantin Porotchkin /* Turn on auto-link */ 810031542fcSKonstantin Porotchkin cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM) | 811031542fcSKonstantin Porotchkin MCI_INDIRECT_CTRL_LOCAL_PKT); 812031542fcSKonstantin Porotchkin data = (MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL2 | 813031542fcSKonstantin Porotchkin MCI_CTRL_MCI_PHY_SET_AUTO_LINK_EN(1)); 814031542fcSKonstantin Porotchkin rval = mci_write(0, cmd, data); 815031542fcSKonstantin Porotchkin if (rval) 816031542fcSKonstantin Porotchkin ERROR("Failed to turn on auto-link\n"); 817031542fcSKonstantin Porotchkin 818031542fcSKonstantin Porotchkin debug_exit(); 819031542fcSKonstantin Porotchkin } 820031542fcSKonstantin Porotchkin 821031542fcSKonstantin Porotchkin /* Initialize MCI for performance improvements */ 822031542fcSKonstantin Porotchkin int mci_initialize(int mci_index) 823031542fcSKonstantin Porotchkin { 824031542fcSKonstantin Porotchkin int ret; 825031542fcSKonstantin Porotchkin 826031542fcSKonstantin Porotchkin debug_enter(); 827031542fcSKonstantin Porotchkin INFO("MCI%d initialization:\n", mci_index); 828031542fcSKonstantin Porotchkin 829031542fcSKonstantin Porotchkin ret = mci_configure(mci_index); 830031542fcSKonstantin Porotchkin 831031542fcSKonstantin Porotchkin debug_exit(); 832031542fcSKonstantin Porotchkin return ret; 833031542fcSKonstantin Porotchkin } 834