drivers: net: ipq9574: Add base files from ipq6018

Change-Id: Ia40182ad332955c73b6a904081cc45cfabc10673
Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@codeaurora.org>
This commit is contained in:
Selvam Sathappan Periakaruppan 2021-04-01 00:57:37 +05:30
parent 78653a94a6
commit 06c8e8eac3
15 changed files with 5397 additions and 0 deletions

View file

@ -0,0 +1,395 @@
/*
**************************************************************************
* Copyright (c) 2016-2019, 2021, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#ifndef __EDMA_REGS__
#define __EDMA_REGS__
#define IPQ9574_EDMA_CFG_BASE 0x3ab00000
/*
* IPQ9574 EDMA register offsets
*/
#define IPQ9574_EDMA_REG_MAS_CTRL 0x0
#define IPQ9574_EDMA_REG_PORT_CTRL 0x4
#define IPQ9574_EDMA_REG_VLAN_CTRL 0x8
#define IPQ9574_EDMA_REG_RXDESC2FILL_MAP_0 0x18
#define IPQ9574_EDMA_REG_RXDESC2FILL_MAP_1 0x1c
#define IPQ9574_EDMA_REG_TXQ_CTRL 0x20
#define IPQ9574_EDMA_REG_TXQ_CTRL_2 0x24
#define IPQ9574_EDMA_REG_TXQ_FC_0 0x28
#define IPQ9574_EDMA_REG_TXQ_FC_1 0x30
#define IPQ9574_EDMA_REG_TXQ_FC_2 0x34
#define IPQ9574_EDMA_REG_TXQ_FC_3 0x38
#define IPQ9574_EDMA_REG_RXQ_CTRL 0x3c
#define IPQ9574_EDMA_REG_RX_TX_FULL_QID 0x40
#define IPQ9574_EDMA_REG_RXQ_FC_THRE 0x44
#define IPQ9574_EDMA_REG_DMAR_CTRL 0x48
#define IPQ9574_EDMA_REG_AXIR_CTRL 0x4c
#define IPQ9574_EDMA_REG_AXIW_CTRL 0x50
#define IPQ9574_EDMA_REG_MIN_MSS 0x54
#define IPQ9574_EDMA_REG_LOOPBACK_CTRL 0x58
#define IPQ9574_EDMA_REG_MISC_INT_STAT 0x5c
#define IPQ9574_EDMA_REG_MISC_INT_MASK 0x60
#define IPQ9574_EDMA_REG_DBG_CTRL 0x64
#define IPQ9574_EDMA_REG_DBG_DATA 0x68
#define IPQ9574_EDMA_REG_TXDESC_BA(n) (0x1000 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TXDESC_PROD_IDX(n) (0x1004 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TXDESC_CONS_IDX(n) (0x1008 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TXDESC_RING_SIZE(n) (0x100c + (0x1000 * n))
#define IPQ9574_EDMA_REG_TXDESC_CTRL(n) (0x1010 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TXCMPL_BA(n) (0x79000 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TXCMPL_PROD_IDX(n) (0x79004 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TXCMPL_CONS_IDX(n) (0x79008 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TXCMPL_RING_SIZE(n) (0x7900c + (0x1000 * n))
#define IPQ9574_EDMA_REG_TXCMPL_UGT_THRE(n) (0x79010 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TXCMPL_CTRL(n) (0x79014 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TXCMPL_BPC(n) (0x79018 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TX_INT_STAT(n) (0x91000 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TX_INT_MASK(n) (0x91004 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TX_MOD_TIMER(n) (0x91008 + (0x1000 * n))
#define IPQ9574_EDMA_REG_TX_INT_CTRL(n) (0x9100c + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXFILL_BA(n) (0x29000 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXFILL_PROD_IDX(n) (0x29004 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXFILL_CONS_IDX(n) (0x29008 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXFILL_RING_SIZE(n) (0x2900c + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXFILL_BUFFER1_SIZE(n) (0x29010 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXFILL_FC_THRE(n) (0x29014 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXFILL_UGT_THRE(n) (0x29018 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXFILL_RING_EN(n) (0x2901c + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXFILL_DISABLE(n) (0x29020 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXFILL_DISABLE_DONE(n) (0x29024 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXFILL_INT_STAT(n) (0x31000 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXFILL_INT_MASK(n) (0x31004 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXDESC_BA(n) (0x39000 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXDESC_PROD_IDX(n) (0x39004 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXDESC_CONS_IDX(n) (0x39008 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXDESC_RING_SIZE(n) (0x3900c + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXDESC_FC_THRE(n) (0x39010 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXDESC_UGT_THRE(n) (0x39014 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXDESC_CTRL(n) (0x39018 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXDESC_BPC(n) (0x3901c + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXDESC_INT_STAT(n) (0x49000 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RXDESC_INT_MASK(n) (0x49004 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RX_MOD_TIMER(n) (0x49008 + (0x1000 * n))
#define IPQ9574_EDMA_REG_RX_INT_CTRL(n) (0x4900c + (0x1000 * n))
#define IPQ9574_EDMA_QID2RID_TABLE_MEM(q) (0x5a000 + (0x4 * q))
#define IPQ9574_EDMA_REG_RXRING_PC(n) (0x5A200 + (0x10 * n))
#define IPQ9574_EDMA_REG_RXRING_BC_0(n) (0x5A204 + (0x10 * n))
#define IPQ9574_EDMA_REG_RXRING_BC_1(n) (0x5A208 + (0x10 * n))
#define IPQ9574_EDMA_REG_TXRING_PC(n) (0x74000 + (0x10 * n))
#define IPQ9574_EDMA_REG_TXRING_BC_0(n) (0x74004 + (0x10 * n))
#define IPQ9574_EDMA_REG_TXRING_BC_1(n) (0x74008 + (0x10 * n))
/*
* EDMA_REG_PORT_CTRL register
*/
#define IPQ9574_EDMA_PORT_CTRL_EN 0x3
#define IPQ9574_EDMA_PORT_CTRL_PAD_EN 0x1
/*
* EDMA_REG_TXQ_CTRL register
*/
#define IPQ9574_EDMA_TXDESC_PF_THRE_MASK 0xf
#define IPQ9574_EDMA_TXDESC_PF_THRE_SHIFT 0
#define IPQ9574_EDMA_TXCMPL_WB_THRE_MASK 0xf
#define IPQ9574_EDMA_TXCMPL_WB_THRE_SHIFT 4
#define IPQ9574_EDMA_TXDESC_PKT_SRAM_THRE_MASK 0xff
#define IPQ9574_EDMA_TXDESC_PKT_SRAM_THRE_SHIFT 8
#define IPQ9574_EDMA_TXCMPL_WB_TIMER_MASK 0xffff
#define IPQ9574_EDMA_TXCMPL_WB_TIMER_SHIFT 16
/*
* EDMA_REG_RXQ_CTRL register
*/
#define IPQ9574_EDMA_RXFILL_PF_THRE_MASK 0xf
#define IPQ9574_EDMA_RXFILL_PF_THRE_SHIFT 0
#define IPQ9574_EDMA_RXDESC_WB_THRE_MASK 0xf
#define IPQ9574_EDMA_RXDESC_WB_THRE_SHIFT 4
#define IPQ9574_EDMA_RXDESC_WB_TIMER_MASK 0xffff
#define IPQ9574_EDMA_RXDESC_WB_TIMER_SHIFT 16
/*
* EDMA_REG_RX_TX_FULL_QID register
*/
#define IPQ9574_EDMA_RX_DESC_FULL_QID_MASK 0xff
#define IPQ9574_EDMA_RX_DESC_FULL_QID_SHIFT 0
#define IPQ9574_EDMA_TX_CMPL_BUF_FULL_QID_MASK 0xff
#define IPQ9574_EDMA_TX_CMPL_BUF_FULL_QID_SHIFT 8
#define IPQ9574_EDMA_TX_SRAM_FULL_QID_MASK 0x1f
#define IPQ9574_EDMA_TX_SRAM_FULL_QID_SHIFT 16
/*
* EDMA_REG_RXQ_FC_THRE reister
*/
#define IPQ9574_EDMA_RXFILL_FIFO_XOFF_THRE_MASK 0x1f
#define IPQ9574_EDMA_RXFILL_FIFO_XOFF_THRE_SHIFT 0
#define IPQ9574_EDMA_DESC_FIFO_XOFF_THRE_MASK 0x3f
#define IPQ9574_EDMA_DESC_FIFO_XOFF_THRE_SHIFT 16
/*
* EDMA_REG_DMAR_CTRL register
*/
#define IPQ9574_EDMA_DMAR_REQ_PRI_MASK 0x7
#define IPQ9574_EDMA_DMAR_REQ_PRI_SHIFT 0
#define IPQ9574_EDMA_DMAR_BURST_LEN_MASK 0x1
#define IPQ9574_EDMA_DMAR_BURST_LEN_SHIFT 3
#define IPQ9574_EDMA_DMAR_TXDATA_OUTSTANDING_NUM_MASK 0x1f
#define IPQ9574_EDMA_DMAR_TXDATA_OUTSTANDING_NUM_SHIFT 4
#define IPQ9574_EDMA_DMAR_TXDESC_OUTSTANDING_NUM_MASK 0x7
#define IPQ9574_EDMA_DMAR_TXDESC_OUTSTANDING_NUM_SHIFT 9
#define IPQ9574_EDMA_DMAR_RXFILL_OUTSTANDING_NUM_MASK 0x7
#define IPQ9574_EDMA_DMAR_RXFILL_OUTSTANDING_NUM_SHIFT 12
/*
* EDMA DISABLE
*/
#define IPQ9574_EDMA_DISABLE 0
/*
* EDMA_REG_TXDESC_PROD_IDX register
*/
#define IPQ9574_EDMA_TXDESC_PROD_IDX_MASK 0xffff
/*
* EDMA_REG_TXDESC_CONS_IDX register
*/
#define IPQ9574_EDMA_TXDESC_CONS_IDX_MASK 0xffff
/*
* EDMA_REG_TXDESC_RING_SIZE register
*/
#define IPQ9574_EDMA_TXDESC_RING_SIZE_MASK 0xffff
/*
* EDMA_REG_TXDESC_CTRL register
*/
#define IPQ9574_EDMA_TXDESC_ARB_GRP_ID_MASK 0x3
#define IPQ9574_EDMA_TXDESC_ARB_GRP_ID_SHIFT 4
#define IPQ9574_EDMA_TXDESC_FC_GRP_ID_MASK 0x7
#define IPQ9574_EDMA_TXDESC_FC_GRP_ID_SHIFT 1
#define IPQ9574_EDMA_TXDESC_TX_EN 0x1
/*
* EDMA_REG_TXCMPL_PROD_IDX register
*/
#define IPQ9574_EDMA_TXCMPL_PROD_IDX_MASK 0xffff
/*
* EDMA_REG_TXCMPL_CONS_IDX register
*/
#define IPQ9574_EDMA_TXCMPL_CONS_IDX_MASK 0xffff
/*
* EDMA_REG_TXCMPL_RING_SIZE register
*/
#define IPQ9574_EDMA_TXCMPL_RING_SIZE_MASK 0xffff
/*
* EDMA_REG_TXCMPL_UGT_THRE register
*/
#define IPQ9574_EDMA_TXCMPL_LOW_THRE_MASK 0xffff
#define IPQ9574_EDMA_TXCMPL_LOW_THRE_SHIFT 0
#define IPQ9574_EDMA_TXCMPL_FC_THRE_MASK 0x3f
#define IPQ9574_EDMA_TXCMPL_FC_THRE_SHIFT 16
/*
* EDMA_REG_TXCMPL_CTRL register
*/
#define IPQ9574_EDMA_TXCMPL_RET_MODE_BUFF_ADDR 0x0
#define IPQ9574_EDMA_TXCMPL_RET_MODE_OPAQUE 0x1
/*
* EDMA_REG_TX_MOD_TIMER register
*/
#define IPQ9574_EDMA_TX_MOD_TIMER_INIT_MASK 0xffff
#define IPQ9574_EDMA_TX_MOD_TIMER_INIT_SHIFT 0
/*
* EDMA_REG_TX_INT_CTRL register
*/
#define IPQ9574_EDMA_TX_INT_MASK 0x3
/*
* EDMA_REG_RXFILL_PROD_IDX register
*/
#define IPQ9574_EDMA_RXFILL_PROD_IDX_MASK 0xffff
/*
* EDMA_REG_RXFILL_CONS_IDX register
*/
#define IPQ9574_EDMA_RXFILL_CONS_IDX_MASK 0xffff
/*
* EDMA_REG_RXFILL_RING_SIZE register
*/
#define IPQ9574_EDMA_RXFILL_RING_SIZE_MASK 0xffff
#define IPQ9574_EDMA_RXFILL_BUF_SIZE_MASK 0x3fff
#define IPQ9574_EDMA_RXFILL_BUF_SIZE_SHIFT 16
/*
* EDMA_REG_RXFILL_FC_THRE register
*/
#define IPQ9574_EDMA_RXFILL_FC_XON_THRE_MASK 0x7ff
#define IPQ9574_EDMA_RXFILL_FC_XON_THRE_SHIFT 12
#define IPQ9574_EDMA_RXFILL_FC_XOFF_THRE_MASK 0x7ff
#define IPQ9574_EDMA_RXFILL_FC_XOFF_THRE_SHIFT 0
/*
* EDMA_REG_RXFILL_UGT_THRE register
*/
#define IPQ9574_EDMA_RXFILL_LOW_THRE_MASK 0xffff
#define IPQ9574_EDMA_RXFILL_LOW_THRE_SHIFT 0
/*
* EDMA_REG_RXFILL_RING_EN register
*/
#define IPQ9574_EDMA_RXFILL_RING_EN 0x1
/*
* EDMA_REG_RXFILL_INT_MASK register
*/
#define IPQ9574_EDMA_RXFILL_INT_MASK 0x1
/*
* EDMA_REG_RXDESC_PROD_IDX register
*/
#define IPQ9574_EDMA_RXDESC_PROD_IDX_MASK 0xffff
/*
* EDMA_REG_RXDESC_CONS_IDX register
*/
#define IPQ9574_EDMA_RXDESC_CONS_IDX_MASK 0xffff
/*
* EDMA_REG_RXDESC_RING_SIZE register
*/
#define IPQ9574_EDMA_RXDESC_RING_SIZE_MASK 0xffff
#define IPQ9574_EDMA_RXDESC_PL_OFFSET_MASK 0x1ff
#define IPQ9574_EDMA_RXDESC_PL_OFFSET_SHIFT 16
/*
* EDMA_REG_RXDESC_FC_THRE register
*/
#define IPQ9574_EDMA_RXDESC_FC_XON_THRE_MASK 0x7ff
#define IPQ9574_EDMA_RXDESC_FC_XON_THRE_SHIFT 12
#define IPQ9574_EDMA_RXDESC_FC_XOFF_THRE_MASK 0x7ff
#define IPQ9574_EDMA_RXDESC_FC_XOFF_THRE_SHIFT 0
/*
* EDMA_REG_RXDESC_UGT_THRE register
*/
#define IPQ9574_EDMA_RXDESC_LOW_THRE_MASK 0xffff
#define IPQ9574_EDMA_RXDESC_LOW_THRE_SHIFT 0
/*
* EDMA_REG_RXDESC_CTRL register
*/
#define IPQ9574_EDMA_RXDESC_STAG_REMOVE_EN 0x8
#define IPQ9574_EDMA_RXDESC_CTAG_REMOVE_EN 0x4
#define IPQ9574_EDMA_RXDESC_QDISC_EN 0x2
#define IPQ9574_EDMA_RXDESC_RX_EN 0x1
/*
* EDMA_REG_TX_INT_MASK register
*/
#define IPQ9574_EDMA_TX_INT_MASK_PKT_INT 0x1
#define IPQ9574_EDMA_TX_INT_MASK_UGT_INT 0x2
/*
* EDMA_REG_RXDESC_INT_STAT register
*/
#define IPQ9574_EDMA_RXDESC_INT_STAT_PKT_INT 0x1
#define IPQ9574_EDMA_RXDESC_INT_STAT_UGT_INT 0x2
/*
* EDMA_REG_RXDESC_INT_MASK register
*/
#define IPQ9574_EDMA_RXDESC_INT_MASK_PKT_INT 0x1
#define IPQ9574_EDMA_RXDESC_INT_MASK_TIMER_INT_DIS 0x2
#define IPQ9574_EDMA_MASK_INT_DISABLE 0x0
#define IPQ9574_EDMA_MASK_INT_CLEAR 0x0
/*
* EDMA_REG_RX_MOD_TIMER register
*/
#define IPQ9574_EDMA_RX_MOD_TIMER_INIT_MASK 0xffff
#define IPQ9574_EDMA_RX_MOD_TIMER_INIT_SHIFT 0
/*
* EDMA QID2RID register sizes
*/
#define IPQ9574_EDMA_QID2RID_DEPTH 0x40
#define IPQ9574_EDMA_QID2RID_QUEUES_PER_ENTRY 8
/*
* TXDESC shift values
*/
#define IPQ9574_EDMA_TXDESC_MORE_SHIFT 31
#define IPQ9574_EDMA_TXDESC_TSO_EN_SHIFT 30
#define IPQ9574_EDMA_TXDESC_PREHEADER_SHIFT 29
#define IPQ9574_EDMA_TXDESC_POOL_ID_SHIFT 24
#define IPQ9574_EDMA_TXDESC_POOL_ID_MASK 0x1f
#define IPQ9574_EDMA_TXDESC_DATA_OFFSET_SHIFT 16
#define IPQ9574_EDMA_TXDESC_DATA_OFFSET_MASK 0xff
#define IPQ9574_EDMA_TXDESC_DATA_LENGTH_SHIFT 0
#define IPQ9574_EDMA_TXDESC_DATA_LENGTH_MASK 0xffff
#define IPQ9574_EDMA_PREHDR_DSTINFO_PORTID_IND 0x20
#define IPQ9574_EDMA_PREHDR_PORTNUM_BITS 0x0fff
#define IPQ9574_EDMA_RING_DMA_MASK 0xffffffff
/*
* RXDESC shift values
*/
#define IPQ9574_EDMA_RXDESC_RX_RXFILL_CNT_MASK 0x000f
#define IPQ9574_EDMA_RXDESC_RX_RXFILL_CNT_SHIFT 16
#define IPQ9574_EDMA_RXDESC_PKT_SIZE_MASK 0x3fff
#define IPQ9574_EDMA_RXDESC_PKT_SIZE_SHIFT 0
#define IPQ9574_EDMA_RXDESC_RXD_VALID_MASK 0x1
#define IPQ9574_EDMA_RXDESC_RXD_VALID_SHIFT 31
#define IPQ9574_EDMA_RXDESC_PACKET_LEN_MASK 0x3fff
#define IPQ9574_EDMA_RXDESC_RING_INT_STATUS_MASK 0x3
#define IPQ9574_EDMA_RING_DISABLE 0
#define IPQ9574_EDMA_TXCMPL_RING_INT_STATUS_MASK 0x3
#define IPQ9574_EDMA_TXCMPL_RETMODE_OPAQUE 0x0
#define IPQ9574_EDMA_RXFILL_RING_INT_STATUS_MASK 0x1
/*
* TODO tune the timer and threshold values
*/
#define IPQ9574_EDMA_RXFILL_FIFO_XOFF_THRE 0x3
#define IPQ9574_EDMA_RXFILL_PF_THRE 0x3
#define IPQ9574_EDMA_RXDESC_WB_THRE 0x0
#define IPQ9574_EDMA_RXDESC_WB_TIMER 0x2
#define IPQ9574_EDMA_RXDESC_XON_THRE 50
#define IPQ9574_EDMA_RXDESC_XOFF_THRE 30
#define IPQ9574_EDMA_RXDESC_LOW_THRE 0
#define IPQ9574_EDMA_RX_MOD_TIMER_INIT 1000
#define IPQ9574_EDMA_TXDESC_PF_THRE 0x3
#define IPQ9574_EDMA_TXCMPL_WB_THRE 0X0
#define IPQ9574_EDMA_TXDESC_PKT_SRAM_THRE 0x20
#define IPQ9574_EDMA_TXCMPL_WB_TIMER 0x2
#define IPQ9574_EDMA_TX_MOD_TIMER 150
#endif /* __EDMA_REGS__ */

View file

@ -18,6 +18,30 @@
#include <asm/u-boot.h>
#include <asm/arch-qca-common/qca_common.h>
#define CLK_TOGGLE_ENABLE 0x1
#define GCC_NSS_PPE_RESET 0x01868014
/*
* PPE ASSERT and DEASSERT values
*/
#define PPE_ASSERT 0xf0000
#define PPE_DEASSERT 0x0
/*
* EDMA HW ASSERT and DEASSERT values
*/
#define GCC_EDMA_HW_RESET_ASSERT 0x300000
#define GCC_EDMA_HW_RESET_DEASSERT 0x0
/*
* NSS Port ASSERT and DEASSERT values
*/
#define NSS_PORT1_ASSERT 0x1000003
#define NSS_PORT2_ASSERT 0x200000c
#define NSS_PORT3_ASSERT 0x4000030
#define NSS_PORT4_ASSERT 0x8000300
#define NSS_PORT5_ASSERT 0x10000c00
#define BLSP1_UART0_BASE 0x078AF000
#define UART_PORT_ID(reg) ((reg - BLSP1_UART0_BASE) / 0x1000)

View file

@ -95,6 +95,14 @@ CONFIG_CMD_NFS=y
# CONFIG_CMD_DNS is not set
# CONFIG_CMD_LINK_LOCAL is not set
#
# Network PHY
#
CONFIG_QCA8075_PHY=y
CONFIG_IPQ9574_QCA_AQUANTIA_PHY=y
# CONFIG_QCA8033_PHY is not set
CONFIG_QCA8081_PHY=y
#
# Misc commands
#

View file

@ -86,6 +86,9 @@ obj-$(CONFIG_IPQ807X_EDMA) += ipq807x/ipq807x_uniphy.o
obj-$(CONFIG_IPQ6018_EDMA) += ipq6018/ipq6018_edma.o
obj-$(CONFIG_IPQ6018_EDMA) += ipq6018/ipq6018_ppe.o
obj-$(CONFIG_IPQ6018_EDMA) += ipq6018/ipq6018_uniphy.o
obj-$(CONFIG_IPQ9574_EDMA) += ipq9574/ipq9574_ppe.o
obj-$(CONFIG_IPQ9574_EDMA) += ipq9574/ipq9574_uniphy.o
obj-$(CONFIG_IPQ9574_EDMA) += ipq9574/ipq9574_edma.o
obj-$(CONFIG_IPQ5018_GMAC) += ipq5018/ipq5018_gmac.o
obj-$(CONFIG_IPQ5018_GMAC) += ipq5018/ipq5018_uniphy.o
obj-$(CONFIG_IPQ5018_MDIO) += ipq5018/ipq5018_mdio.o

View file

@ -0,0 +1,597 @@
/*
* Copyright (c) 2017-2019, 2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <common.h>
#include <net.h>
#include <asm-generic/errno.h>
#include <asm/io.h>
#include <malloc.h>
#include <phy.h>
#include <miiphy.h>
#include "ipq_phy.h"
#include "ipq9574_aquantia_phy.h"
#include <crc.h>
#include <mmc.h>
#include <asm/errno.h>
#include <nand.h>
#include <spi_flash.h>
#include <spi.h>
#include <asm/global_data.h>
#include <fdtdec.h>
DECLARE_GLOBAL_DATA_PTR;
typedef struct {
unsigned int image_type;
unsigned int header_vsn_num;
unsigned int image_src;
unsigned char *image_dest_ptr;
unsigned int image_size;
unsigned int code_size;
unsigned char *signature_ptr;
unsigned int signature_size;
unsigned char *cert_chain_ptr;
unsigned int cert_chain_size;
} mbn_header_t;
mbn_header_t *fwimg_header;
static int debug = 0;
#ifdef CONFIG_QCA_MMC
extern qca_mmc mmc_host;
static qca_mmc *host = &mmc_host;
#endif
extern int ipq_mdio_write(int mii_id,
int regnum, u16 value);
extern int ipq_mdio_read(int mii_id,
int regnum, ushort *data);
extern int ipq_sw_mdio_init(const char *);
extern void eth_clock_enable(void);
static int program_ethphy_fw(unsigned int phy_addr,
uint32_t load_addr,uint32_t file_size );
static qca_smem_flash_info_t *sfi = &qca_smem_flash_info;
u16 aq_phy_reg_write(u32 dev_id, u32 phy_id,
u32 reg_id, u16 reg_val)
{
ipq_mdio_write(phy_id, reg_id, reg_val);
return 0;
}
u16 aq_phy_reg_read(u32 dev_id, u32 phy_id, u32 reg_id)
{
return ipq_mdio_read(phy_id, reg_id, NULL);
}
u8 aq_phy_get_link_status(u32 dev_id, u32 phy_id)
{
u16 phy_data;
uint32_t reg;
reg = AQ_PHY_AUTO_STATUS_REG | AQUANTIA_MII_ADDR_C45;
phy_data = aq_phy_reg_read(dev_id, phy_id, reg);
phy_data = aq_phy_reg_read(dev_id, phy_id, reg);
if (((phy_data >> 2) & 0x1) & PORT_LINK_UP)
return 0;
return 1;
}
u32 aq_phy_get_duplex(u32 dev_id, u32 phy_id, fal_port_duplex_t *duplex)
{
u16 phy_data;
uint32_t reg;
reg = AQ_PHY_LINK_STATUS_REG | AQUANTIA_MII_ADDR_C45;
phy_data = aq_phy_reg_read(dev_id, phy_id, reg);
/*
* Read duplex
*/
phy_data = phy_data & 0x1;
if (phy_data & 0x1)
*duplex = FAL_FULL_DUPLEX;
else
*duplex = FAL_HALF_DUPLEX;
return 0;
}
u32 aq_phy_get_speed(u32 dev_id, u32 phy_id, fal_port_speed_t *speed)
{
u16 phy_data;
uint32_t reg;
reg = AQ_PHY_LINK_STATUS_REG | AQUANTIA_MII_ADDR_C45;
phy_data = aq_phy_reg_read(dev_id, phy_id, reg);
switch ((phy_data >> 1) & 0x7) {
case SPEED_10G:
*speed = FAL_SPEED_10000;
break;
case SPEED_5G:
*speed = FAL_SPEED_5000;
break;
case SPEED_2_5G:
*speed = FAL_SPEED_2500;
break;
case SPEED_1000MBS:
*speed = FAL_SPEED_1000;
break;
case SPEED_100MBS:
*speed = FAL_SPEED_100;
break;
case SPEED_10MBS:
*speed = FAL_SPEED_10;
break;
default:
return -EINVAL;
}
return 0;
}
void aquantia_phy_restart_autoneg(u32 phy_id)
{
u16 phy_data;
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_PHY_XS_REGISTERS,
AQUANTIA_PHY_XS_USX_TRANSMIT));
if (!(phy_data & AQUANTIA_PHY_USX_AUTONEG_ENABLE))
aq_phy_reg_write(0x0, phy_id,AQUANTIA_REG_ADDRESS(
AQUANTIA_MMD_PHY_XS_REGISTERS,
AQUANTIA_PHY_XS_USX_TRANSMIT),
phy_data | AQUANTIA_PHY_USX_AUTONEG_ENABLE);
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_AUTONEG,
AQUANTIA_AUTONEG_STANDARD_CONTROL1));
phy_data |= AQUANTIA_CTRL_AUTONEGOTIATION_ENABLE;
aq_phy_reg_write(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_AUTONEG,
AQUANTIA_AUTONEG_STANDARD_CONTROL1),
phy_data | AQUANTIA_CTRL_RESTART_AUTONEGOTIATION);
}
int ipq_qca_aquantia_phy_init(struct phy_ops **ops, u32 phy_id)
{
u16 phy_data;
struct phy_ops *aq_phy_ops;
aq_phy_ops = (struct phy_ops *)malloc(sizeof(struct phy_ops));
if (!aq_phy_ops)
return -ENOMEM;
aq_phy_ops->phy_get_link_status = aq_phy_get_link_status;
aq_phy_ops->phy_get_speed = aq_phy_get_speed;
aq_phy_ops->phy_get_duplex = aq_phy_get_duplex;
*ops = aq_phy_ops;
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(1, QCA_PHY_ID1));
printf ("PHY ID1: 0x%x\n", phy_data);
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(1, QCA_PHY_ID2));
printf ("PHY ID2: 0x%x\n", phy_data);
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_PHY_XS_REGISTERS,
AQUANTIA_PHY_XS_USX_TRANSMIT));
phy_data |= AQUANTIA_PHY_USX_AUTONEG_ENABLE;
aq_phy_reg_write(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_PHY_XS_REGISTERS,
AQUANTIA_PHY_XS_USX_TRANSMIT), phy_data);
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_AUTONEG,
AQUANTIA_AUTONEG_TRANSMIT_VENDOR_INTR_MASK));
phy_data |= AQUANTIA_INTR_LINK_STATUS_CHANGE;
aq_phy_reg_write(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_AUTONEG,
AQUANTIA_AUTONEG_TRANSMIT_VENDOR_INTR_MASK), phy_data);
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_GLOABLE_REGISTERS,
AQUANTIA_GLOBAL_INTR_STANDARD_MASK));
phy_data |= AQUANTIA_ALL_VENDOR_ALARMS_INTERRUPT_MASK;
aq_phy_reg_write(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_GLOABLE_REGISTERS,
AQUANTIA_GLOBAL_INTR_STANDARD_MASK), phy_data);
phy_data = aq_phy_reg_read(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_GLOABLE_REGISTERS,
AQUANTIA_GLOBAL_INTR_VENDOR_MASK));
phy_data |= AQUANTIA_AUTO_AND_ALARMS_INTR_MASK;
aq_phy_reg_write(0x0, phy_id, AQUANTIA_REG_ADDRESS(AQUANTIA_MMD_GLOABLE_REGISTERS,
AQUANTIA_GLOBAL_INTR_VENDOR_MASK), phy_data);
return 0;
}
static int do_aq_phy_restart(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
unsigned int phy_addr = AQU_PHY_ADDR;
if (argc > 2)
return CMD_RET_USAGE;
if (argc == 2)
phy_addr = simple_strtoul(argv[1], NULL, 16);
aquantia_phy_restart_autoneg(phy_addr);
return 0;
}
int ipq_board_fw_download(unsigned int phy_addr)
{
char runcmd[256];
int ret,i=0;
uint32_t start; /* block number */
uint32_t size; /* no. of blocks */
qca_part_entry_t ethphyfw;
unsigned int *ethphyfw_load_addr = NULL;
struct { char *name; qca_part_entry_t *part; } entries[] = {
{ "0:ETHPHYFW", &ethphyfw },
};
#ifdef CONFIG_QCA_MMC
block_dev_desc_t *blk_dev;
disk_partition_t disk_info;
#endif
/* check the smem info to see which flash used for booting */
if (sfi->flash_type == SMEM_BOOT_SPI_FLASH) {
if (debug) {
printf("Using nor device \n");
}
} else if (sfi->flash_type == SMEM_BOOT_NAND_FLASH) {
if (debug) {
printf("Using nand device 0\n");
}
} else if (sfi->flash_type == SMEM_BOOT_MMC_FLASH) {
if (debug) {
printf("Using MMC device\n");
}
} else {
printf("Unsupported BOOT flash type\n");
return -1;
}
ret = smem_getpart(entries[i].name, &start, &size);
if (ret < 0) {
debug("cdp: get part failed for %s\n", entries[i].name);
} else {
qca_set_part_entry(entries[i].name, sfi, entries[i].part, start, size);
}
if ((sfi->flash_type == SMEM_BOOT_NAND_FLASH) ||
(sfi->flash_type == SMEM_BOOT_SPI_FLASH)) {
ethphyfw_load_addr = (uint *)malloc(ethphyfw.size);
if (ethphyfw_load_addr == NULL) {
printf("ETHPHYFW Loading failed\n");
return -1;
} else {
memset(ethphyfw_load_addr, 0, ethphyfw.size);
}
}
if (sfi->flash_type == SMEM_BOOT_NAND_FLASH) {
/*
* Kernel is in a separate partition
*/
snprintf(runcmd, sizeof(runcmd),
/* NOR is treated as psuedo NAND */
"nand read 0x%p 0x%llx 0x%llx && ",
ethphyfw_load_addr, ethphyfw.offset, ethphyfw.size);
if (debug)
printf("%s", runcmd);
if (run_command(runcmd, 0) != CMD_RET_SUCCESS) {
free(ethphyfw_load_addr);
return CMD_RET_FAILURE;
}
} else if (sfi->flash_type == SMEM_BOOT_SPI_FLASH) {
snprintf(runcmd, sizeof(runcmd),
"sf probe && " "sf read 0x%p 0x%llx 0x%llx && ",
ethphyfw_load_addr, ethphyfw.offset, ethphyfw.size);
if (debug)
printf("%s", runcmd);
if (run_command(runcmd, 0) != CMD_RET_SUCCESS) {
free(ethphyfw_load_addr);
return CMD_RET_FAILURE;
}
#ifdef CONFIG_QCA_MMC
} else if (sfi->flash_type == SMEM_BOOT_MMC_FLASH ) {
blk_dev = mmc_get_dev(host->dev_num);
ret = get_partition_info_efi_by_name(blk_dev,
"0:ETHPHYFW", &disk_info);
ethphyfw_load_addr = (uint *)malloc(((uint)disk_info.size) *
((uint)disk_info.blksz));
if (ethphyfw_load_addr == NULL) {
printf("ETHPHYFW Loading failed\n");
return -1;
} else {
memset(ethphyfw_load_addr, 0,
(((uint)disk_info.size) *
((uint)disk_info.blksz)));
}
if (ret == 0) {
snprintf(runcmd, sizeof(runcmd),
"mmc read 0x%p 0x%X 0x%X",
ethphyfw_load_addr,
(uint)disk_info.start, (uint)disk_info.size);
if (run_command(runcmd, 0) != CMD_RET_SUCCESS) {
free(ethphyfw_load_addr);
return CMD_RET_FAILURE;
}
}
#endif
}
fwimg_header = (mbn_header_t *)(ethphyfw_load_addr);
if (fwimg_header->image_type == 0x13 &&
fwimg_header->header_vsn_num == 0x3) {
program_ethphy_fw(phy_addr,
(uint32_t)(((uint32_t)ethphyfw_load_addr)
+ sizeof(mbn_header_t)),
(uint32_t)(fwimg_header->image_size));
} else {
printf("bad magic on ETHPHYFW partition\n");
free(ethphyfw_load_addr);
return -1;
}
free(ethphyfw_load_addr);
return 0;
}
#define AQ_PHY_IMAGE_HEADER_CONTENT_OFFSET_HHD 0x300
static int program_ethphy_fw(unsigned int phy_addr, uint32_t load_addr, uint32_t file_size)
{
int i;
uint8_t *buf;
uint16_t file_crc;
uint16_t computed_crc;
uint32_t reg1, reg2;
uint16_t recorded_ggp8_val;
uint16_t daisy_chain_dis;
uint32_t primary_header_ptr = 0x00000000;
uint32_t primary_iram_ptr = 0x00000000;
uint32_t primary_dram_ptr = 0x00000000;
uint32_t primary_iram_sz = 0x00000000;
uint32_t primary_dram_sz = 0x00000000;
uint32_t phy_img_hdr_off;
uint32_t byte_sz;
uint32_t dword_sz;
uint32_t byte_ptr;
uint16_t msw = 0;
uint16_t lsw = 0;
uint8_t msb1;
uint8_t msb2;
uint8_t lsb1;
uint8_t lsb2;
uint16_t mailbox_crc;
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x300), 0xdead);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x301), 0xbeaf);
reg1 = aq_phy_reg_read(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x300));
reg2 = aq_phy_reg_read(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x301));
if(reg1 != 0xdead && reg2 != 0xbeaf) {
printf("PHY::Scratchpad Read/Write test fail\n");
return 0;
}
buf = (uint8_t *)load_addr;
file_crc = buf[file_size - 2] << 8 | buf[file_size - 1];
computed_crc = cyg_crc16(buf, file_size - 2);
if (file_crc != computed_crc) {
printf("CRC check failed on phy fw file\n");
return 0;
} else {
printf ("CRC check good on phy fw file (0x%04X)\n",computed_crc);
}
daisy_chain_dis = aq_phy_reg_read(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc452));
if (!(daisy_chain_dis & 0x1))
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc452), 0x1);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc471), 0x40);
recorded_ggp8_val = aq_phy_reg_read(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc447));
if ((recorded_ggp8_val & 0x1f) != phy_addr)
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc447), phy_addr);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc441), 0x4000);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc001), 0x41);
primary_header_ptr = (((buf[0x9] & 0x0F) << 8) | buf[0x8]) << 12;
phy_img_hdr_off = AQ_PHY_IMAGE_HEADER_CONTENT_OFFSET_HHD;
primary_iram_ptr = (buf[primary_header_ptr + phy_img_hdr_off + 0x4 + 2] << 16) |
(buf[primary_header_ptr + phy_img_hdr_off + 0x4 + 1] << 8) |
buf[primary_header_ptr + phy_img_hdr_off + 0x4];
primary_iram_sz = (buf[primary_header_ptr + phy_img_hdr_off + 0x7 + 2] << 16) |
(buf[primary_header_ptr + phy_img_hdr_off + 0x7 + 1] << 8) |
buf[primary_header_ptr + phy_img_hdr_off + 0x7];
primary_dram_ptr = (buf[primary_header_ptr + phy_img_hdr_off + 0xA + 2] << 16) |
(buf[primary_header_ptr + phy_img_hdr_off + 0xA + 1] << 8) |
buf[primary_header_ptr + phy_img_hdr_off + 0xA];
primary_dram_sz = (buf[primary_header_ptr + phy_img_hdr_off + 0xD + 2] << 16) |
(buf[primary_header_ptr + phy_img_hdr_off + 0xD + 1] << 8) |
buf[primary_header_ptr + phy_img_hdr_off + 0xD];
primary_iram_ptr += primary_header_ptr;
primary_dram_ptr += primary_header_ptr;
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x200), 0x1000);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x200), 0x0);
computed_crc = 0;
printf("PHYFW:Loading IRAM...........");
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x202), 0x4000);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x203), 0x0);
byte_sz = primary_iram_sz;
dword_sz = byte_sz >> 2;
byte_ptr = primary_iram_ptr;
for (i = 0; i < dword_sz; i++) {
lsw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
byte_ptr += 2;
msw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
byte_ptr += 2;
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x204), msw);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x205), lsw);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x200), 0xc000);
msb1 = msw >> 8;
msb2 = msw & 0xFF;
lsb1 = lsw >> 8;
lsb2 = lsw & 0xFF;
computed_crc = cyg_crc16_computed(&msb1, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&msb2, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&lsb1, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&lsb2, 0x1, computed_crc);
}
switch (byte_sz & 0x3) {
case 0x1:
lsw = buf[byte_ptr++];
msw = 0x0000;
break;
case 0x2:
lsw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
byte_ptr += 2;
msw = 0x0000;
break;
case 0x3:
lsw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
byte_ptr += 2;
msw = buf[byte_ptr++];
break;
}
if (byte_sz & 0x3) {
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x204), msw);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x205), lsw);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x200), 0xc000);
msb1 = msw >> 8;
msb2 = msw & 0xFF;
lsb1 = lsw >> 8;
lsb2 = lsw & 0xFF;
computed_crc = cyg_crc16_computed(&msb1, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&msb2, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&lsb1, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&lsb2, 0x1, computed_crc);
}
printf("done.\n");
printf("PHYFW:Loading DRAM..............");
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x202), 0x3ffe);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x203), 0x0);
byte_sz = primary_dram_sz;
dword_sz = byte_sz >> 2;
byte_ptr = primary_dram_ptr;
for (i = 0; i < dword_sz; i++) {
lsw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
byte_ptr += 2;
msw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
byte_ptr += 2;
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x204), msw);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x205), lsw);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x200), 0xc000);
msb1 = msw >> 8;
msb2 = msw & 0xFF;
lsb1 = lsw >> 8;
lsb2 = lsw & 0xFF;
computed_crc = cyg_crc16_computed(&msb1, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&msb2, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&lsb1, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&lsb2, 0x1, computed_crc);
}
switch (byte_sz & 0x3) {
case 0x1:
lsw = buf[byte_ptr++];
msw = 0x0000;
break;
case 0x2:
lsw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
byte_ptr += 2;
msw = 0x0000;
break;
case 0x3:
lsw = (buf[byte_ptr + 1] << 8) | buf[byte_ptr];
byte_ptr += 2;
msw = buf[byte_ptr++];
break;
}
if (byte_sz & 0x3) {
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x204), msw);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x205), lsw);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x200), 0xc000);
msb1 = msw >> 8;
msb2 = msw & 0xFF;
lsb1 = lsw >> 8;
lsb2 = lsw & 0xFF;
computed_crc = cyg_crc16_computed(&msb1, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&msb2, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&lsb1, 0x1, computed_crc);
computed_crc = cyg_crc16_computed(&lsb2, 0x1, computed_crc);
}
printf("done.\n");
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc441), 0x2010);
mailbox_crc = aq_phy_reg_read(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x201));
if (mailbox_crc != computed_crc) {
printf("phy fw image load CRC-16 (0x%X) does not match calculated CRC-16 (0x%X)\n", mailbox_crc, computed_crc);
return 0;
} else
printf("phy fw image load good CRC-16 matches (0x%X)\n", mailbox_crc);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0x0), 0x0);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc001), 0x41);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc001), 0x8041);
mdelay(100);
aq_phy_reg_write(0x0, phy_addr, AQUANTIA_REG_ADDRESS(0x1e, 0xc001), 0x40);
mdelay(100);
aquantia_phy_restart_autoneg(phy_addr);
return 0;
}
static int do_load_fw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
unsigned int phy_addr = AQU_PHY_ADDR;
int node, aquantia_port;
if (argc > 2)
return CMD_RET_USAGE;
if (argc == 2)
phy_addr = simple_strtoul(argv[1], NULL, 16);
node = fdt_path_offset(gd->fdt_blob, "/ess-switch");
if (node < 0) {
printf("Error: ess-switch not specified in dts");
return 0;
}
aquantia_port = fdtdec_get_uint(gd->fdt_blob, node, "aquantia_port", -1);
if (aquantia_port < 0) {
printf("Error: aquantia_port not specified in dts");
return 0;
}
aquantia_port = fdtdec_get_uint(gd->fdt_blob, node, "aquantia_gpio", -1);
if (aquantia_port < 0) {
printf("Error: aquantia_gpio not specified in dts");
return 0;
}
miiphy_init();
eth_clock_enable();
ipq_sw_mdio_init("IPQ MDIO0");
ipq_board_fw_download(phy_addr);
return 0;
}
U_BOOT_CMD(
aq_load_fw, 5, 1, do_load_fw,
"LOAD aq-fw-binary",
""
);
U_BOOT_CMD(
aq_phy_restart, 5, 1, do_aq_phy_restart,
"Restart Aquantia phy",
""
);

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2017-2019, 2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#define AQUANTIA_MII_ADDR_C45 (1<<30)
#define AQUANTIA_REG_ADDRESS(dev_ad, reg_num) (AQUANTIA_MII_ADDR_C45 |\
((dev_ad & 0x1f) << 16) | (reg_num & 0xFFFF))
#define AQUANTIA_MMD_PHY_XS_REGISTERS 4
#define AQUANTIA_PHY_XS_USX_TRANSMIT 0xc441
#define AQUANTIA_PHY_USX_AUTONEG_ENABLE 0x8
#define AQUANTIA_MMD_AUTONEG 0x7
#define AQUANTIA_AUTONEG_TRANSMIT_VENDOR_INTR_MASK 0xD401
#define AQUANTIA_INTR_LINK_STATUS_CHANGE 0x0001
#define AQUANTIA_MMD_GLOABLE_REGISTERS 0x1E
#define AQUANTIA_GLOBAL_INTR_STANDARD_MASK 0xff00
#define AQUANTIA_ALL_VENDOR_ALARMS_INTERRUPT_MASK 0x0001
#define AQUANTIA_GLOBAL_INTR_VENDOR_MASK 0xff01
#define AQUANTIA_AUTO_AND_ALARMS_INTR_MASK 0x1001
#define AQUANTIA_AUTONEG_STANDARD_CONTROL1 0
#define AQUANTIA_CTRL_AUTONEGOTIATION_ENABLE 0x1000
#define AQUANTIA_CTRL_RESTART_AUTONEGOTIATION 0x0200
#define AQ_PHY_AUTO_STATUS_REG 0x70001
#define PORT_LINK_DOWN 0
#define PORT_LINK_UP 1
#define AQ_PHY_LINK_STATUS_REG 0x7c800
#define SPEED_5G 5
#define SPEED_2_5G 4
#define SPEED_10G 3
#define SPEED_1000MBS 2
#define SPEED_100MBS 1
#define SPEED_10MBS 0

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,327 @@
/*
**************************************************************************
* Copyright (c) 2016-2019, 2021, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#ifndef __IPQ9574_EDMA__
#define __IPQ9574_EDMA__
#define IPQ9574_NSS_DP_START_PHY_PORT 1
#define IPQ9574_NSS_DP_MAX_PHY_PORTS 5
#define IPQ9574_EDMA_BUF_SIZE 2000
#define IPQ9574_EDMA_DEVICE_NODE_NAME "edma"
#define IPQ9574_EDMA_RX_BUFF_SIZE (IPQ9574_EDMA_BUF_SIZE + IPQ9574_EDMA_RX_PREHDR_SIZE)
#define IPQ9574_EDMA_RX_PREHDR_SIZE (sizeof(struct ipq9574_edma_rx_preheader))
#define IPQ9574_EDMA_TX_PREHDR_SIZE (sizeof(struct ipq9574_edma_tx_preheader))
#define IPQ9574_EDMA_TXDESC_RING_SIZE 8
#define IPQ9574_EDMA_TXCMPL_RING_SIZE 8
#define IPQ9574_EDMA_RXDESC_RING_SIZE 16
#define IPQ9574_EDMA_RXFILL_RING_SIZE 16
#define IPQ9574_EDMA_START_GMACS IPQ9574_NSS_DP_START_PHY_PORT
#define IPQ9574_EDMA_MAX_GMACS IPQ9574_NSS_DP_MAX_PHY_PORTS
#define IPQ9574_EDMA_TX_BUF_SIZE (1540 + IPQ9574_EDMA_TX_PREHDR_SIZE)
#define IPQ9574_EDMA_MAX_TXCMPL_RINGS 24 /* Max TxCmpl rings */
#define IPQ9574_EDMA_MAX_RXDESC_RINGS 16 /* Max RxDesc rings */
#define IPQ9574_EDMA_MAX_RXFILL_RINGS 8 /* Max RxFill rings */
#define IPQ9574_EDMA_MAX_TXDESC_RINGS 24 /* Max TxDesc rings */
#define IPQ9574_EDMA_GET_DESC(R, i, type) (&(((type *)((R)->desc))[i]))
#define IPQ9574_EDMA_RXFILL_DESC(R, i) IPQ9574_EDMA_GET_DESC(R, i, struct ipq9574_edma_rxfill_desc)
#define IPQ9574_EDMA_RXDESC_DESC(R, i) IPQ9574_EDMA_GET_DESC(R, i, struct ipq9574_edma_rxdesc_desc)
#define IPQ9574_EDMA_TXDESC_DESC(R, i) IPQ9574_EDMA_GET_DESC(R, i, struct ipq9574_edma_txdesc_desc)
#define IPQ9574_EDMA_TXCMPL_DESC(R, i) IPQ9574_EDMA_GET_DESC(R, i, struct ipq9574_edma_txcmpl_desc)
#define IPQ9574_EDMA_RXPH_SRC_INFO_TYPE_GET(rxph) (((rxph)->src_info >> 8) & 0xf0)
#define IPQ9574_EDMA_DEV 1
#define IPQ9574_EDMA_TX_QUEUE 1
#define IPQ9574_EDMA_RX_QUEUE 1
#define IPQ9574_EDMA_TX_DESC_RING_START 0
#define IPQ9574_EDMA_TX_DESC_RING_NOS 1
#define IPQ9574_EDMA_TX_DESC_RING_SIZE \
(IPQ9574_EDMA_TX_DESC_RING_START + IPQ9574_EDMA_TX_DESC_RING_NOS)
#define IPQ9574_EDMA_TX_CMPL_RING_START 0
#define IPQ9574_EDMA_TX_CMPL_RING_NOS 8
#define IPQ9574_EDMA_TX_CMPL_RING_SIZE \
(IPQ9574_EDMA_TX_CMPL_RING_START + IPQ9574_EDMA_TX_CMPL_RING_NOS)
#define IPQ9574_EDMA_RX_DESC_RING_START 15
#define IPQ9574_EDMA_RX_DESC_RING_NOS 1
#define IPQ9574_EDMA_RX_DESC_RING_SIZE \
(IPQ9574_EDMA_RX_DESC_RING_START + IPQ9574_EDMA_RX_DESC_RING_NOS)
#define IPQ9574_EDMA_RX_FILL_RING_START 7
#define IPQ9574_EDMA_RX_FILL_RING_NOS 1
#define IPQ9574_EDMA_RX_FILL_RING_SIZE \
(IPQ9574_EDMA_RX_FILL_RING_START + IPQ9574_EDMA_RX_FILL_RING_NOS)
#define IPQ9574_EDMA_TX_IMR_NORMAL_MASK 1
#define IPQ9574_EDMA_RX_IMR_NORMAL_MASK 1
#define IPQ9574_EDMA_INTR_CLEAR_TYPE 0
#define IPQ9574_EDMA_INTR_SW_IDX_W_TYPE 0
#define IPQ9574_EDMA_RSS_TYPE_NONE 0x1
#define NETDEV_TX_BUSY 1
#define PSGMIIPHY_PLL_VCO_RELATED_CTRL 0x0009878c
#define PSGMIIPHY_PLL_VCO_VAL 0x2803
#define PSGMIIPHY_VCO_CALIBRATION_CTRL 0x0009809c
#define PSGMIIPHY_VCO_VAL 0x4ADA
#define PSGMIIPHY_VCO_RST_VAL 0xADA
#define RGMII_TCSR_ESS_CFG 0x01953000
#define ESS_RGMII_CTRL 0x0C000004
/*
* Tx descriptor
*/
struct ipq9574_edma_txdesc_desc {
uint32_t buffer_addr;
/* buffer address */
uint32_t word1;
/* more bit, TSO, preheader, pool, offset and length */
};
/*
* TxCmpl descriptor
*/
struct ipq9574_edma_txcmpl_desc {
uint32_t buffer_addr; /* buffer address/opaque */
uint32_t status; /* status */
};
/*
* Rx descriptor
*/
struct ipq9574_edma_rxdesc_desc {
uint32_t buffer_addr; /* buffer address */
uint32_t status; /* status */
};
/*
* RxFill descriptor
*/
struct ipq9574_edma_rxfill_desc {
uint32_t buffer_addr; /* Buffer address */
uint32_t word1; /* opaque_ind and buffer size */
};
/*
* Tx descriptor ring
*/
struct ipq9574_edma_txdesc_ring {
uint32_t id; /* TXDESC ring number */
void *desc; /* descriptor ring virtual address */
dma_addr_t dma; /* descriptor ring physical address */
uint16_t count; /* number of descriptors */
};
/*
* TxCmpl ring
*/
struct ipq9574_edma_txcmpl_ring {
uint32_t id; /* TXCMPL ring number */
void *desc; /* descriptor ring virtual address */
dma_addr_t dma; /* descriptor ring physical address */
uint16_t count; /* number of descriptors in the ring */
};
/*
* RxFill ring
*/
struct ipq9574_edma_rxfill_ring {
uint32_t id; /* RXFILL ring number */
void *desc; /* descriptor ring virtual address */
dma_addr_t dma; /* descriptor ring physical address */
uint16_t count; /* number of descriptors in the ring */
};
/*
* RxDesc ring
*/
struct ipq9574_edma_rxdesc_ring {
uint32_t id; /* RXDESC ring number */
struct ipq9574_edma_rxfill_ring *rxfill; /* RXFILL ring used */
void *desc; /* descriptor ring virtual address */
dma_addr_t dma; /* descriptor ring physical address */
uint16_t count; /* number of descriptors in the ring */
};
/*
* EDMA Tx Preheader
*/
struct ipq9574_edma_tx_preheader {
uint32_t opaque; /* Opaque, contains skb pointer */
uint16_t src_info; /* Src information */
uint16_t dst_info; /* Dest information */
uint32_t tx_pre2; /* SVLAN & CVLAN flag, drop prec, hash value */
uint32_t tx_pre3; /* STAG, CTAG */
uint32_t tx_pre4; /* CPU code, L3 & L4 offset, service code */
uint32_t tx_pre5; /* IP addr index, ACL index */
uint32_t tx_pre6; /* IP payload checksum, copy2cpu, timestamp, dscp */
uint32_t tx_pre7; /* Timestamp, QoS TAG */
};
/*
* EDMA Rx Preheader
*/
struct ipq9574_edma_rx_preheader {
uint32_t opaque; /* Opaque, contains skb pointer*/
uint16_t src_info; /* Src information */
uint16_t dst_info; /* Dest information */
uint32_t rx_pre2; /* SVLAN & CVLAN flag, drop prec, hash value */
uint32_t rx_pre3; /* STAG, CTAG */
uint32_t rx_pre4; /* CPU code, L3 & L4 offset, service code */
uint32_t rx_pre5; /* IP addr index, ACL index */
uint32_t rx_pre6; /* IP payload checksum, copy2cpu, timestamp, dscp */
uint32_t rx_pre7; /* Timestamp, QoS TAG */
};
enum ipq9574_edma_tx {
EDMA_TX_OK = 0, /* Tx success */
EDMA_TX_DESC = 1, /* Not enough descriptors */
EDMA_TX_FAIL = 2, /* Tx failure */
};
/* per core queue related information */
struct queue_per_cpu_info {
u32 tx_mask; /* tx interrupt mask */
u32 rx_mask; /* rx interrupt mask */
u32 tx_status; /* tx interrupt status */
u32 rx_status; /* rx interrupt status */
u32 tx_start; /* tx queue start */
u32 rx_start; /* rx queue start */
struct ipq9574_edma_common_info *c_info; /* edma common info */
};
/* edma hw specific data */
struct ipq9574_edma_hw {
unsigned long __iomem *hw_addr; /* inner register address */
u8 intr_clear_type; /* interrupt clear */
u8 intr_sw_idx_w; /* To do chk type interrupt software index */
u16 rx_buff_size; /* To do chk type Rx buffer size */
u8 rss_type; /* rss protocol type */
uint16_t rx_payload_offset; /* start of the payload offset */
uint32_t flags; /* internal flags */
int active; /* status */
struct ipq9574_edma_txdesc_ring *txdesc_ring; /* Tx Descriptor Ring, SW is producer */
struct ipq9574_edma_txcmpl_ring *txcmpl_ring; /* Tx Completion Ring, SW is consumer */
struct ipq9574_edma_rxdesc_ring *rxdesc_ring; /* Rx Descriptor Ring, SW is consumer */
struct ipq9574_edma_rxfill_ring *rxfill_ring; /* Rx Fill Ring, SW is producer */
uint32_t txdesc_rings; /* Number of TxDesc rings */
uint32_t txdesc_ring_start; /* Id of first TXDESC ring */
uint32_t txdesc_ring_end; /* Id of the last TXDESC ring */
uint32_t txcmpl_rings; /* Number of TxCmpl rings */
uint32_t txcmpl_ring_start; /* Id of first TXCMPL ring */
uint32_t txcmpl_ring_end; /* Id of last TXCMPL ring */
uint32_t rxfill_rings; /* Number of RxFill rings */
uint32_t rxfill_ring_start; /* Id of first RxFill ring */
uint32_t rxfill_ring_end; /* Id of last RxFill ring */
uint32_t rxdesc_rings; /* Number of RxDesc rings */
uint32_t rxdesc_ring_start; /* Id of first RxDesc ring */
uint32_t rxdesc_ring_end; /* Id of last RxDesc ring */
uint32_t tx_intr_mask; /* tx interrupt mask */
uint32_t rx_intr_mask; /* rx interrupt mask */
uint32_t rxfill_intr_mask; /* Rx fill ring interrupt mask */
uint32_t rxdesc_intr_mask; /* Rx Desc ring interrupt mask */
uint32_t txcmpl_intr_mask; /* Tx Cmpl ring interrupt mask */
uint32_t misc_intr_mask; /* misc interrupt interrupt mask */
};
struct ipq9574_edma_common_info {
struct ipq9574_edma_hw hw;
};
#define MAX_PHY 6
struct ipq9574_eth_dev {
u8 *phy_address;
uint no_of_phys;
uint interface;
uint speed;
uint duplex;
uint sw_configured;
uint mac_unit;
uint mac_ps;
int link_printed;
u32 padding;
struct eth_device *dev;
struct ipq9574_edma_common_info *c_info;
struct phy_ops *ops[MAX_PHY];
const char phy_name[MDIO_NAME_LEN];
} __attribute__ ((aligned(8)));
static inline void* ipq9574_alloc_mem(u32 size)
{
void *p = malloc(size);
if (p != NULL)
memset(p, 0, size);
return p;
}
static inline void* ipq9574_alloc_memalign(u32 size)
{
void *p = memalign(CONFIG_SYS_CACHELINE_SIZE, size);
if (p != NULL)
memset(p, 0, size);
return p;
}
static inline void ipq9574_free_mem(void *ptr)
{
if (ptr)
free(ptr);
}
uint32_t ipq9574_edma_reg_read(uint32_t reg_off);
void ipq9574_edma_reg_write(uint32_t reg_off, uint32_t val);
extern int get_eth_mac_address(uchar *enetaddr, uint no_of_macs);
typedef struct {
uint count;
u8 addr[7];
} ipq9574_edma_phy_addr_t;
/* ipq9574 edma Paramaters */
typedef struct {
uint base;
int unit;
uint mac_conn_to_phy;
phy_interface_t phy;
ipq9574_edma_phy_addr_t phy_addr;
char phy_name[MDIO_NAME_LEN];
} ipq9574_edma_board_cfg_t;
extern void ipq9574_ppe_provision_init(void);
extern void ipq9574_port_mac_clock_reset(int port);
extern void ipq9574_speed_clock_set(int port, int speed_clock1, int speed_clock2);
extern void ipq9574_pqsgmii_speed_set(int port, int speed, int status);
extern void ipq9574_uxsgmii_speed_set(int port, int speed, int duplex, int status);
extern void ppe_port_mux_mac_type_set(int port_id, int mode);
extern void ppe_port_bridge_txmac_set(int port, int status);
extern void ipq9574_10g_r_speed_set(int port, int status);
extern int phy_status_get_from_ppe(int port_id);
extern void ipq9574_ppe_acl_set(int rule_id, int rule_type, int pkt_type, int l4_port_no, int l4_port_mask, int permit, int deny);
extern void ppe_uniphy_mode_set(uint32_t uniphy_index, uint32_t mode);
#endif /* ___IPQ9574_EDMA__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,255 @@
/*
**************************************************************************
* Copyright (c) 2016-2019, 2021, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
#include <common.h>
#include <net.h>
#include <asm-generic/errno.h>
#include <asm/io.h>
#include <malloc.h>
#include <phy.h>
#include <net.h>
#include <miiphy.h>
#define GCC_NSS_PORT1_RX_CMD_RCGR 0x01868020
#define GCC_NSS_PORT1_RX_CFG_RCGR 0x01868024
#define GCC_NSS_PORT1_RX_MISC 0x01868400
#define IPQ9574_PPE_BASE_ADDR 0x3a000000
#define IPQ9574_PPE_REG_SIZE 0x1000000
#define PORT4 4
#define PORT5 5
#define PORT_GMAC_TYPE 1
#define PORT_XGMAC_TYPE 2
struct port_mux_ctrl {
uint32_t port3_pcs_sel:2;
uint32_t port4_pcs_sel:2;
uint32_t port5_pcs_sel:2;
uint32_t port5_gmac_sel:1;
uint32_t pcs0_ch4_sel:1;
uint32_t pcs0_ch0_sel:1;
uint32_t _reserved0:23;
};
union port_mux_ctrl_u {
uint32_t val;
struct port_mux_ctrl bf;
};
enum {
TCP_PKT,
UDP_PKT,
};
#define ADPT_ACL_HPPE_IPV4_DIP_RULE 4
#define MAX_RULE 512
struct ipo_rule_reg {
uint32_t rule_field_0:32;
uint32_t rule_field_1:20;
uint32_t fake_mac_header:1;
uint32_t range_en:1;
uint32_t inverse_en:1;
uint32_t rule_type:4;
uint32_t src_type:2;
uint32_t src_0:3;
uint32_t src_1:5;
uint32_t pri:9;
uint32_t res_chain:1;
uint32_t post_routing_en:1;
uint32_t _reserved0:16;
};
union ipo_rule_reg_u {
uint32_t val[3];
struct ipo_rule_reg bf;
};
struct ipo_mask_reg {
uint32_t maskfield_0:32;
uint32_t maskfield_1:21;
uint32_t _reserved0:11;
};
union ipo_mask_reg_u {
uint32_t val[2];
struct ipo_mask_reg bf;
};
struct ipo_action {
uint32_t dest_info_change_en:1;
uint32_t fwd_cmd:2;
uint32_t _reserved0:29;
uint32_t _reserved1:32;
uint32_t _reserved2:32;
uint32_t _reserved3:32;
uint32_t _reserved4:32;
};
union ipo_action_u {
uint32_t val[5];
struct ipo_action bf;
};
#define IPQ9574_PORT_MUX_CTRL 0x10
#define CPPE_PORT3_PCS_SEL_PCS0_CHANNEL2 0
#define CPPE_PORT3_PCS_SEL_PCS0_CHANNEL4 1
#define CPPE_PORT4_PCS_SEL_PCS0_CHANNEL3 0
#define CPPE_PORT4_PCS_SEL_PCS0_SGMIIPLUS 1
#define CPPE_PORT5_PCS_SEL_PCS0_CHANNEL4 0
#define CPPE_PORT5_PCS_SEL_PCS1_CHANNEL0 1
#define CPPE_PORT5_GMAC_SEL_GMAC 0
#define CPPE_PORT5_GMAC_SEL_XGMAC 1
#define CPPE_PCS0_CHANNEL4_SEL_PORT5_CLOCK 0x0
#define CPPE_PCS0_CHANNEL4_SEL_PORT3_CLOCK 0x1
#define CPPE_PCS0_CHANNEL0_SEL_PSGMII 0x0
#define CPPE_PCS0_CHANNEL0_SEL_SGMIIPLUS 0x1
#define CPPE_DETECTION_PHY_FAILURE 0xFFFF
#define PORT_PHY_STATUS_ADDRESS 0x44
#define PORT_PHY_STATUS_PORT5_1_OFFSET 16
#define IPQ9574_PPE_IPE_L3_BASE_ADDR 0x200000
#define IPQ9574_PPE_L3_VP_PORT_TBL_ADDR (IPQ9574_PPE_IPE_L3_BASE_ADDR + 0x1000)
#define IPQ9574_PPE_L3_VP_PORT_TBL_INC 0x10
#define IPQ9574_PPE_QUEUE_MANAGER_BASE_ADDR 0x800000
#define IPQ9574_PPE_UCAST_QUEUE_MAP_TBL_ADDR 0x10000
#define IPQ9574_PPE_UCAST_QUEUE_MAP_TBL_INC 0x10
#define IPQ9574_PPE_QM_UQM_TBL (IPQ9574_PPE_QUEUE_MANAGER_BASE_ADDR +\
IPQ9574_PPE_UCAST_QUEUE_MAP_TBL_ADDR)
#define IPQ9574_PPE_UCAST_PRIORITY_MAP_TBL_ADDR 0x42000
#define IPQ9574_PPE_QM_UPM_TBL (IPQ9574_PPE_QUEUE_MANAGER_BASE_ADDR +\
IPQ9574_PPE_UCAST_PRIORITY_MAP_TBL_ADDR)
#define IPQ9574_PPE_STP_BASE 0x060100
#define IPQ9574_PPE_MAC_ENABLE 0x001000
#define IPQ9574_PPE_MAC_SPEED 0x001004
#define IPQ9574_PPE_MAC_MIB_CTL 0x001034
#define IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR 0x400000
#define IPQ9574_PPE_L0_FLOW_PORT_MAP_TBL_ADDR 0x8000
#define IPQ9574_PPE_L0_FLOW_PORT_MAP_TBL_INC 0x10
#define IPQ9574_PPE_L0_FLOW_PORT_MAP_TBL (IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR +\
IPQ9574_PPE_L0_FLOW_PORT_MAP_TBL_ADDR)
#define IPQ9574_PPE_L0_FLOW_MAP_TBL_ADDR 0x2000
#define IPQ9574_PPE_L0_FLOW_MAP_TBL_INC 0x10
#define IPQ9574_PPE_L0_FLOW_MAP_TBL (IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR +\
IPQ9574_PPE_L0_FLOW_MAP_TBL_ADDR)
#define IPQ9574_PPE_L1_FLOW_PORT_MAP_TBL_ADDR 0x46000
#define IPQ9574_PPE_L1_FLOW_PORT_MAP_TBL_INC 0x10
#define IPQ9574_PPE_L1_FLOW_PORT_MAP_TBL (IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR +\
IPQ9574_PPE_L1_FLOW_PORT_MAP_TBL_ADDR)
#define IPQ9574_PPE_L1_FLOW_MAP_TBL_ADDR 0x40000
#define IPQ9574_PPE_L1_FLOW_MAP_TBL_INC 0x10
#define IPQ9574_PPE_L1_FLOW_MAP_TBL (IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR +\
IPQ9574_PPE_L1_FLOW_MAP_TBL_ADDR)
#define IPQ9574_PPE_L0_C_SP_CFG_TBL_ADDR 0x4000
#define IPQ9574_PPE_L0_C_SP_CFG_TBL (IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR +\
IPQ9574_PPE_L0_C_SP_CFG_TBL_ADDR)
#define IPQ9574_PPE_L1_C_SP_CFG_TBL_ADDR 0x42000
#define IPQ9574_PPE_L1_C_SP_CFG_TBL (IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR +\
IPQ9574_PPE_L1_C_SP_CFG_TBL_ADDR)
#define IPQ9574_PPE_L0_E_SP_CFG_TBL_ADDR 0x6000
#define IPQ9574_PPE_L0_E_SP_CFG_TBL (IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR +\
IPQ9574_PPE_L0_E_SP_CFG_TBL_ADDR)
#define IPQ9574_PPE_L1_E_SP_CFG_TBL_ADDR 0x44000
#define IPQ9574_PPE_L1_E_SP_CFG_TBL (IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR +\
IPQ9574_PPE_L1_E_SP_CFG_TBL_ADDR)
#define IPQ9574_PPE_FPGA_GPIO_BASE_ADDR 0x01008000
#define IPQ9574_PPE_MAC_PORT_MUX_OFFSET 0x10
#define IPQ9574_PPE_FPGA_GPIO_OFFSET 0xc000
#define IPQ9574_PPE_FPGA_SCHED_OFFSET 0x47a000
#define IPQ9574_PPE_TDM_CFG_DEPTH_OFFSET 0xb000
#define IPQ9574_PPE_TDM_SCHED_DEPTH_OFFSET 0x400000
#define IPQ9574_PPE_PORT_BRIDGE_CTRL_OFFSET 0x060300
#define IPQ9574_PPE_TDM_CFG_DEPTH_VAL 0x80000064
#define IPQ9574_PPE_MAC_PORT_MUX_OFFSET_VAL 0x15
#define IPQ9574_PPE_TDM_SCHED_DEPTH_VAL 0x32
#define IPQ9574_PPE_TDM_CFG_VALID 0x20
#define IPQ9574_PPE_TDM_CFG_DIR_INGRESS 0x0
#define IPQ9574_PPE_TDM_CFG_DIR_EGRESS 0x10
#define IPQ9574_PPE_PORT_EDMA 0x0
#define IPQ9574_PPE_PORT_QTI1 0x1
#define IPQ9574_PPE_PORT_QTI2 0x2
#define IPQ9574_PPE_PORT_QTI3 0x3
#define IPQ9574_PPE_PORT_QTI4 0x4
#define IPQ9574_PPE_PORT_XGMAC1 0x5
#define IPQ9574_PPE_PORT_XGMAC2 0x6
#define IPQ9574_PPE_PORT_CRYPTO1 0x7
#define IPQ9574_PPE_PORT_BRIDGE_CTRL_PROMISC_EN 0x20000
#define IPQ9574_PPE_PORT_BRIDGE_CTRL_TXMAC_EN 0x10000
#define IPQ9574_PPE_PORT_BRIDGE_CTRL_PORT_ISOLATION_BMP 0x7f00
#define IPQ9574_PPE_PORT_BRIDGE_CTRL_STATION_LRN_EN 0x8
#define IPQ9574_PPE_PORT_BRIDGE_CTRL_NEW_ADDR_LRN_EN 0x1
#define IPQ9574_PPE_PORT_EDMA_BITPOS 0x1
#define IPQ9574_PPE_PORT_QTI1_BITPOS (1 << IPQ9574_PPE_PORT_QTI1)
#define IPQ9574_PPE_PORT_QTI2_BITPOS (1 << IPQ9574_PPE_PORT_QTI2)
#define IPQ9574_PPE_PORT_QTI3_BITPOS (1 << IPQ9574_PPE_PORT_QTI3)
#define IPQ9574_PPE_PORT_QTI4_BITPOS (1 << IPQ9574_PPE_PORT_QTI4)
#define IPQ9574_PPE_PORT_XGMAC1_BITPOS (1 << IPQ9574_PPE_PORT_XGMAC1)
#define IPQ9574_PPE_PORT_XGMAC2_BITPOS (1 << IPQ9574_PPE_PORT_XGMAC2)
#define IPQ9574_PPE_PORT_CRYPTO1_BITPOS (1 << IPQ9574_PPE_PORT_CRYPTO1)
#define PPE_SWITCH_NSS_SWITCH_XGMAC0 0x3000
#define NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION 0x4000
#define USS (1 << 31)
#define SS(i) (i << 29)
#define JD (1 << 16)
#define TE (1 << 0)
#define NSS_SWITCH_XGMAC_MAC_RX_CONFIGURATION 0x4000
#define MAC_RX_CONFIGURATION_ADDRESS 0x4
#define RE (1 << 0)
#define ACS (1 << 1)
#define CST (1 << 2)
#define MAC_PACKET_FILTER_INC 0x4000
#define MAC_PACKET_FILTER_ADDRESS 0x8
#define XGMAC_SPEED_SELECT_10000M 0
#define XGMAC_SPEED_SELECT_5000M 1
#define XGMAC_SPEED_SELECT_2500M 2
#define XGMAC_SPEED_SELECT_1000M 3
#define IPE_L2_BASE_ADDR 0x060000
#define PORT_BRIDGE_CTRL_ADDRESS 0x300
#define PORT_BRIDGE_CTRL_INC 0x4
#define TX_MAC_EN (1 << 16)
#define IPO_CSR_BASE_ADDR 0x0b0000
#define IPO_RULE_REG_ADDRESS 0x0
#define IPO_RULE_REG_INC 0x10
#define IPO_MASK_REG_ADDRESS 0x2000
#define IPO_MASK_REG_INC 0x10
#define IPO_ACTION_ADDRESS 0x8000
#define IPO_ACTION_INC 0x20

View file

@ -0,0 +1,367 @@
/*
* Copyright (c) 2017-2019, 2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <common.h>
#include <net.h>
#include <asm-generic/errno.h>
#include <asm/io.h>
#include <malloc.h>
#include <phy.h>
#include <net.h>
#include <miiphy.h>
#include <asm/arch-ipq9574/edma_regs.h>
#include "ipq9574_edma.h"
#include "ipq9574_uniphy.h"
#include "ipq_phy.h"
extern int ipq_mdio_write(int mii_id,
int regnum, u16 value);
extern int ipq_mdio_read(int mii_id,
int regnum, ushort *data);
extern void qca8075_phy_serdes_reset(u32 phy_id);
void csr1_write(int phy_id, int addr, int value)
{
int addr_h, addr_l, ahb_h, ahb_l, phy;
phy=phy_id<<(0x10);
addr_h=(addr&0xffffff)>>8;
addr_l=((addr&0xff)<<2)|(0x20<<(0xa));
ahb_l=(addr_l&0xffff)|(0x7A00000|phy);
ahb_h=(0x7A083FC|phy);
writel(addr_h,ahb_h);
writel(value,ahb_l);
}
int csr1_read(int phy_id, int addr )
{
int addr_h ,addr_l,ahb_h, ahb_l, phy;
phy=phy_id<<(0x10);
addr_h=(addr&0xffffff)>>8;
addr_l=((addr&0xff)<<2)|(0x20<<(0xa));
ahb_l=(addr_l&0xffff)|(0x7A00000|phy);
ahb_h=(0x7A083FC|phy);
writel(addr_h, ahb_h);
return readl(ahb_l);
}
static int ppe_uniphy_calibration(uint32_t uniphy_index)
{
int retries = 100, calibration_done = 0;
uint32_t reg_value = 0;
while(calibration_done != UNIPHY_CALIBRATION_DONE) {
mdelay(1);
if (retries-- == 0) {
printf("uniphy callibration time out!\n");
return -1;
}
reg_value = readl(PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
+ PPE_UNIPHY_OFFSET_CALIB_4);
calibration_done = (reg_value >> 0x7) & 0x1;
}
return 0;
}
static void ppe_gcc_uniphy_xpcs_reset(uint32_t uniphy_index, bool enable)
{
uint32_t reg_value;
reg_value = readl(GCC_UNIPHY0_MISC + (uniphy_index * GCC_UNIPHY_REG_INC));
if(enable)
reg_value |= GCC_UNIPHY_USXGMII_XPCS_RESET;
else
reg_value &= ~GCC_UNIPHY_USXGMII_XPCS_RESET;
writel(reg_value, GCC_UNIPHY0_MISC + (uniphy_index * GCC_UNIPHY_REG_INC));
}
static void ppe_gcc_uniphy_soft_reset(uint32_t uniphy_index)
{
uint32_t reg_value;
reg_value = readl(GCC_UNIPHY0_MISC + (uniphy_index * GCC_UNIPHY_REG_INC));
if (uniphy_index == 0)
reg_value |= GCC_UNIPHY_PSGMII_SOFT_RESET;
else
reg_value |= GCC_UNIPHY_SGMII_SOFT_RESET;
writel(reg_value, GCC_UNIPHY0_MISC + (uniphy_index * GCC_UNIPHY_REG_INC));
udelay(500);
if (uniphy_index == 0)
reg_value &= ~GCC_UNIPHY_PSGMII_SOFT_RESET;
else
reg_value &= ~GCC_UNIPHY_SGMII_SOFT_RESET;
writel(reg_value, GCC_UNIPHY0_MISC + (uniphy_index * GCC_UNIPHY_REG_INC));
}
static void ppe_uniphy_psgmii_mode_set(uint32_t uniphy_index)
{
ppe_gcc_uniphy_xpcs_reset(uniphy_index, true);
writel(0x220, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
+ PPE_UNIPHY_MODE_CONTROL);
ppe_gcc_uniphy_soft_reset(uniphy_index);
ppe_uniphy_calibration(uniphy_index);
qca8075_phy_serdes_reset(0);
}
static void ppe_uniphy_qsgmii_mode_set(uint32_t uniphy_index)
{
ppe_gcc_uniphy_xpcs_reset(uniphy_index, true);
writel(0x120, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
+ PPE_UNIPHY_MODE_CONTROL);
ppe_gcc_uniphy_soft_reset(uniphy_index);
}
static void ppe_uniphy_sgmii_mode_set(uint32_t uniphy_index, uint32_t mode)
{
writel(UNIPHY_MISC2_REG_SGMII_MODE, PPE_UNIPHY_BASE +
(uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_MISC2_REG_OFFSET);
writel(UNIPHY_PLL_RESET_REG_VALUE, PPE_UNIPHY_BASE +
(uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_PLL_RESET_REG_OFFSET);
mdelay(500);
writel(UNIPHY_PLL_RESET_REG_DEFAULT_VALUE, PPE_UNIPHY_BASE +
(uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_PLL_RESET_REG_OFFSET);
mdelay(500);
ppe_gcc_uniphy_xpcs_reset(uniphy_index, true);
if (uniphy_index == 0) {
writel(0x0, GCC_UNIPHY0_PORT4_RX_CBCR);
writel(0x0, GCC_UNIPHY0_PORT4_TX_CBCR);
writel(0x0, GCC_NSS_PORT4_RX_CBCR);
writel(0x0, GCC_NSS_PORT4_TX_CBCR);
} else {
writel(0x0, GCC_UNIPHY1_PORT5_RX_CBCR);
writel(0x0, GCC_UNIPHY1_PORT5_TX_CBCR);
writel(0x0, GCC_NSS_PORT5_RX_CBCR);
writel(0x0, GCC_NSS_PORT5_RX_CBCR);
}
switch (mode) {
case PORT_WRAPPER_SGMII_FIBER:
writel(0x400, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
+ PPE_UNIPHY_MODE_CONTROL);
break;
case PORT_WRAPPER_SGMII0_RGMII4:
case PORT_WRAPPER_SGMII1_RGMII4:
case PORT_WRAPPER_SGMII4_RGMII4:
writel(0x420, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
+ PPE_UNIPHY_MODE_CONTROL);
break;
case PORT_WRAPPER_SGMII_PLUS:
writel(0x820, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
+ PPE_UNIPHY_MODE_CONTROL);
break;
default:
printf("SGMII Config. wrongly");
break;
}
ppe_gcc_uniphy_soft_reset(uniphy_index);
if (uniphy_index == 0) {
writel(0x1, GCC_UNIPHY0_PORT4_RX_CBCR);
writel(0x1, GCC_UNIPHY0_PORT4_TX_CBCR);
writel(0x1, GCC_NSS_PORT4_RX_CBCR);
writel(0x1, GCC_NSS_PORT4_TX_CBCR);
} else {
writel(0x1, GCC_UNIPHY1_PORT5_RX_CBCR);
writel(0x1, GCC_UNIPHY1_PORT5_TX_CBCR);
writel(0x1, GCC_NSS_PORT5_RX_CBCR);
writel(0x1, GCC_NSS_PORT5_RX_CBCR);
}
ppe_uniphy_calibration(uniphy_index);
}
static int ppe_uniphy_10g_r_linkup(uint32_t uniphy_index)
{
uint32_t reg_value = 0;
uint32_t retries = 100, linkup = 0;
while (linkup != UNIPHY_10GR_LINKUP) {
mdelay(1);
if (retries-- == 0)
return -1;
reg_value = csr1_read(uniphy_index, SR_XS_PCS_KR_STS1_ADDRESS);
linkup = (reg_value >> 12) & UNIPHY_10GR_LINKUP;
}
mdelay(10);
return 0;
}
static void ppe_uniphy_10g_r_mode_set(uint32_t uniphy_index)
{
ppe_gcc_uniphy_xpcs_reset(uniphy_index, true);
writel(0x1021, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
+ PPE_UNIPHY_MODE_CONTROL);
writel(0x1C0, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
+ UNIPHY_INSTANCE_LINK_DETECT);
ppe_gcc_uniphy_soft_reset(uniphy_index);
ppe_uniphy_calibration(uniphy_index);
ppe_gcc_uniphy_xpcs_reset(uniphy_index, false);
}
static void ppe_uniphy_usxgmii_mode_set(uint32_t uniphy_index)
{
uint32_t reg_value = 0;
writel(UNIPHY_MISC2_REG_VALUE, PPE_UNIPHY_BASE +
(uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_MISC2_REG_OFFSET);
writel(UNIPHY_PLL_RESET_REG_VALUE, PPE_UNIPHY_BASE +
(uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_PLL_RESET_REG_OFFSET);
mdelay(500);
writel(UNIPHY_PLL_RESET_REG_DEFAULT_VALUE, PPE_UNIPHY_BASE +
(uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_PLL_RESET_REG_OFFSET);
mdelay(500);
ppe_gcc_uniphy_xpcs_reset(uniphy_index, true);
writel(0x1021, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
+ PPE_UNIPHY_MODE_CONTROL);
ppe_gcc_uniphy_soft_reset(uniphy_index);
ppe_uniphy_calibration(uniphy_index);
ppe_gcc_uniphy_xpcs_reset(uniphy_index, false);
ppe_uniphy_10g_r_linkup(uniphy_index);
reg_value = csr1_read(uniphy_index, VR_XS_PCS_DIG_CTRL1_ADDRESS);
reg_value |= USXG_EN;
csr1_write(uniphy_index, VR_XS_PCS_DIG_CTRL1_ADDRESS, reg_value);
reg_value = csr1_read(uniphy_index, VR_MII_AN_CTRL_ADDRESS);
reg_value |= MII_AN_INTR_EN;
reg_value |= MII_CTRL;
csr1_write(uniphy_index, VR_MII_AN_CTRL_ADDRESS, reg_value);
reg_value = csr1_read(uniphy_index, SR_MII_CTRL_ADDRESS);
reg_value |= AN_ENABLE;
reg_value &= ~SS5;
reg_value |= SS6 | SS13 | DUPLEX_MODE;
csr1_write(uniphy_index, SR_MII_CTRL_ADDRESS, reg_value);
}
void ppe_uniphy_mode_set(uint32_t uniphy_index, uint32_t mode)
{
switch(mode) {
case PORT_WRAPPER_PSGMII:
ppe_uniphy_psgmii_mode_set(uniphy_index);
break;
case PORT_WRAPPER_QSGMII:
ppe_uniphy_qsgmii_mode_set(uniphy_index);
break;
case PORT_WRAPPER_SGMII0_RGMII4:
case PORT_WRAPPER_SGMII1_RGMII4:
case PORT_WRAPPER_SGMII4_RGMII4:
case PORT_WRAPPER_SGMII_PLUS:
case PORT_WRAPPER_SGMII_FIBER:
ppe_uniphy_sgmii_mode_set(uniphy_index, mode);
break;
case PORT_WRAPPER_USXGMII:
ppe_uniphy_usxgmii_mode_set(uniphy_index);
break;
case PORT_WRAPPER_10GBASE_R:
ppe_uniphy_10g_r_mode_set(uniphy_index);
break;
default:
break;
}
}
void ppe_uniphy_usxgmii_autoneg_completed(uint32_t uniphy_index)
{
uint32_t autoneg_complete = 0, retries = 100;
uint32_t reg_value = 0;
while (autoneg_complete != 0x1) {
mdelay(1);
if (retries-- == 0)
{
return;
}
reg_value = csr1_read(uniphy_index, VR_MII_AN_INTR_STS);
autoneg_complete = reg_value & 0x1;
}
reg_value &= ~CL37_ANCMPLT_INTR;
csr1_write(uniphy_index, VR_MII_AN_INTR_STS, reg_value);
}
void ppe_uniphy_usxgmii_speed_set(uint32_t uniphy_index, int speed)
{
uint32_t reg_value = 0;
reg_value = csr1_read(uniphy_index, SR_MII_CTRL_ADDRESS);
reg_value |= DUPLEX_MODE;
switch(speed) {
case 0:
reg_value &=~SS5;
reg_value &=~SS6;
reg_value &=~SS13;
break;
case 1:
reg_value &=~SS5;
reg_value &=~SS6;
reg_value |=SS13;
break;
case 2:
reg_value &=~SS5;
reg_value |=SS6;
reg_value &=~SS13;
break;
case 3:
reg_value &=~SS5;
reg_value |=SS6;
reg_value |=SS13;
break;
case 4:
reg_value |=SS5;
reg_value &=~SS6;
reg_value &=~SS13;
break;
case 5:
reg_value |=SS5;
reg_value &=~SS6;
reg_value |=SS13;
break;
}
csr1_write(uniphy_index, SR_MII_CTRL_ADDRESS, reg_value);
}
void ppe_uniphy_usxgmii_duplex_set(uint32_t uniphy_index, int duplex)
{
uint32_t reg_value = 0;
reg_value = csr1_read(uniphy_index, SR_MII_CTRL_ADDRESS);
if (duplex & 0x1)
reg_value |= DUPLEX_MODE;
else
reg_value &= ~DUPLEX_MODE;
csr1_write(uniphy_index, SR_MII_CTRL_ADDRESS, reg_value);
}
void ppe_uniphy_usxgmii_port_reset(uint32_t uniphy_index)
{
uint32_t reg_value = 0;
reg_value = csr1_read(uniphy_index, VR_XS_PCS_DIG_CTRL1_ADDRESS);
reg_value |= USRA_RST;
csr1_write(uniphy_index, VR_XS_PCS_DIG_CTRL1_ADDRESS, reg_value);
}

View file

@ -0,0 +1,86 @@
/*
* Copyright (c) 2017-2019, 2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#define PPE_UNIPHY_INSTANCE0 0
#define PPE_UNIPHY_INSTANCE1 1
#define GCC_UNIPHY1_PORT5_RX_CBCR 0x1856110
#define GCC_UNIPHY1_PORT5_TX_CBCR 0x1856114
#define GCC_NSS_PORT5_RX_CBCR 0x1868260
#define GCC_NSS_PORT5_TX_CBCR 0x1868264
#define GCC_UNIPHY0_PORT4_RX_CBCR 0x1856028
#define GCC_UNIPHY0_PORT4_TX_CBCR 0x185602C
#define GCC_NSS_PORT4_RX_CBCR 0x1868258
#define GCC_NSS_PORT4_TX_CBCR 0x186825C
#define GCC_UNIPHY0_MISC 0x01856004
#define GCC_UNIPHY_REG_INC 0x100
#define GCC_UNIPHY_USXGMII_XPCS_RESET 0x4
#define PPE_UNIPHY_OFFSET_CALIB_4 0x1E0
#define UNIPHY_CALIBRATION_DONE 0x1
#define GCC_UNIPHY_PSGMII_SOFT_RESET 0x3ff2
#define GCC_UNIPHY_SGMII_SOFT_RESET 0x32
#define PPE_UNIPHY_BASE 0X07A00000
#define PPE_UNIPHY_REG_INC 0x10000
#define PPE_UNIPHY_MODE_CONTROL 0x46C
#define UNIPHY_XPCS_MODE (1 << 12)
#define UNIPHY_SG_PLUS_MODE (1 << 11)
#define UNIPHY_SG_MODE (1 << 10)
#define UNIPHY_CH0_PSGMII_QSGMII (1 << 9)
#define UNIPHY_CH0_QSGMII_SGMII (1 << 8)
#define UNIPHY_CH4_CH1_0_SGMII (1 << 2)
#define UNIPHY_CH1_CH0_SGMII (1 << 1)
#define UNIPHY_CH0_ATHR_CSCO_MODE_25M (1 << 0)
#define UNIPHY_INSTANCE_LINK_DETECT 0x570
#define UNIPHY_MISC2_REG_OFFSET 0x218
#define UNIPHY_MISC2_REG_SGMII_MODE 0x30
#define UNIPHY_MISC2_REG_SGMII_PLUS_MODE 0x50
#define UNIPHY_MISC2_REG_VALUE 0x70
#define UNIPHY_PLL_RESET_REG_OFFSET 0x780
#define UNIPHY_PLL_RESET_REG_VALUE 0x02bf
#define UNIPHY_PLL_RESET_REG_DEFAULT_VALUE 0x02ff
#define SR_XS_PCS_KR_STS1_ADDRESS 0x30020
#define UNIPHY_10GR_LINKUP 0x1
#define VR_XS_PCS_DIG_CTRL1_ADDRESS 0x38000
#define USXG_EN (1 << 9)
#define USRA_RST (1 << 10)
#define VR_MII_AN_CTRL_ADDRESS 0x1f8001
#define MII_AN_INTR_EN (1 << 0)
#define MII_CTRL (1 << 8)
#define SR_MII_CTRL_ADDRESS 0x1f0000
#define AN_ENABLE (1 << 12)
#define SS5 (1 << 5)
#define SS6 (1 << 6)
#define SS13 (1 << 13)
#define DUPLEX_MODE (1 << 8)
#define VR_MII_AN_INTR_STS 0x1f8002
#define CL37_ANCMPLT_INTR (1 << 0)
void ppe_uniphy_mode_set(uint32_t uniphy_index, uint32_t mode);
void ppe_uniphy_usxgmii_port_reset(uint32_t uniphy_index);
void ppe_uniphy_usxgmii_duplex_set(uint32_t uniphy_index, int duplex);
void ppe_uniphy_usxgmii_speed_set(uint32_t uniphy_index, int speed);
void ppe_uniphy_usxgmii_autoneg_completed(uint32_t uniphy_index);

View file

@ -18,6 +18,7 @@
#include <net.h>
#define PHY_MAX 6
#define IPQ9574_PHY_MAX 5
#define IPQ6018_PHY_MAX 5
#define MDIO_CTRL_0_REG 0x00090040
#define MDIO_CTRL_0_DIV(x) (x << 0)

View file

@ -290,6 +290,21 @@ extern loff_t board_env_size;
#define RPM_VERSION 3
#endif
#define CONFIG_IPQ9574_EDMA 1
#define CONFIG_IPQ9574_BRIDGED_MODE 1
#define CONFIG_NET_RETRY_COUNT 5
#define CONFIG_SYS_RX_ETH_BUFFER 16
#define CONFIG_CMD_PING
#define CONFIG_CMD_DHCP
#define CONFIG_MII
#define CONFIG_CMD_MII
#define CONFIG_IPADDR 192.168.10.10
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_SERVERIP 192.168.10.1
#define CONFIG_CMD_TFTPPUT
#define CONFIG_IPQ_MDIO 1
#define CONFIG_IPQ_ETH_INIT_DEFER
/*
* CRASH DUMP ENABLE
*/

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2019, 2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __DT_BINDINGS_IPQ9574_ETH_H__
#define __DT_BINDINGS_IPQ9574_ETH_H__
/* ESS Switch Mac Modes */
#define PORT_WRAPPER_PSGMII 0x0
#define PORT_WRAPPER_SGMII 0x1
#define PORT_WRAPPER_USXGMII 0x2
#define PORT_WRAPPER_QSGMII 0x5
#define PORT_WRAPPER_SGMII_PLUS 0x6
#define PORT_WRAPPER_10GBASE_R 0x7
#define PORT_WRAPPER_SGMII_FIBER 0x8
#define UNUSED 0xFF
/* ETH PHY Types */
#define MALIBU_PHY_TYPE 0x1
#define QCA8081_PHY_TYPE 0x2
#define AQ_PHY_TYPE 0x3
#endif