mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2025-12-10 07:44:53 +01:00
drivers: net: ipq9574: Add separate QCA8075 phy driver
Previous platforms assume qca8075 phy address starts from 0. This patch adds a separate qca8075 phy driver for ipq9574 platform and handles cases where qca8075 phy addr doesn't start with 0. Change-Id: I59a596d692b1663af638af358335056661bdf199 Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@codeaurora.org>
This commit is contained in:
parent
eeeee570e7
commit
ba61e78389
7 changed files with 1096 additions and 18 deletions
|
|
@ -15,4 +15,7 @@ config SYS_CONFIG_NAME
|
|||
config IPQ9574_QCA_AQUANTIA_PHY
|
||||
bool "Enable Aquantia PHY support for ipq9574"
|
||||
|
||||
config IPQ9574_QCA8075_PHY
|
||||
bool "Enable Malibu PHY support for ipq9574"
|
||||
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -98,10 +98,11 @@ CONFIG_CMD_NFS=y
|
|||
#
|
||||
# Network PHY
|
||||
#
|
||||
CONFIG_QCA8075_PHY=y
|
||||
# CONFIG_QCA8075_PHY is not set
|
||||
CONFIG_IPQ9574_QCA_AQUANTIA_PHY=y
|
||||
# CONFIG_QCA8033_PHY is not set
|
||||
CONFIG_QCA8081_PHY=y
|
||||
CONFIG_IPQ9574_QCA8075_PHY=y
|
||||
|
||||
#
|
||||
# Misc commands
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ obj-$(CONFIG_IPQ5018_GMAC) += ipq5018/athrs17_phy.o
|
|||
obj-$(CONFIG_IPQ_MDIO) += ipq_common/ipq_mdio.o
|
||||
obj-$(CONFIG_GEPHY) += ipq_common/ipq_gephy.o
|
||||
obj-$(CONFIG_QCA8075_PHY) += ipq_common/ipq_qca8075.o
|
||||
obj-$(CONFIG_IPQ9574_QCA8075_PHY) += ipq9574/ipq9574_qca8075.o
|
||||
obj-$(CONFIG_QCA8033_PHY) += ipq_common/ipq_qca8033.o
|
||||
obj-$(CONFIG_QCA8081_PHY) += ipq_common/ipq_qca8081.o
|
||||
obj-$(CONFIG_QCA_AQUANTIA_PHY) += ipq807x/ipq807x_aquantia_phy.o
|
||||
|
|
|
|||
|
|
@ -52,9 +52,9 @@ int sgmii_mode[2] = {0};
|
|||
#ifndef CONFIG_IPQ9574_RUMI
|
||||
extern int ipq_sw_mdio_init(const char *);
|
||||
extern int ipq_mdio_read(int mii_id, int regnum, ushort *data);
|
||||
extern void ipq_qca8075_phy_map_ops(struct phy_ops **ops);
|
||||
extern int ipq_qca8075_phy_init(struct phy_ops **ops);
|
||||
extern void qca8075_phy_interface_set_mode(uint32_t phy_id, uint32_t mode);
|
||||
extern void ipq9574_qca8075_phy_map_ops(struct phy_ops **ops);
|
||||
extern int ipq9574_qca8075_phy_init(struct phy_ops **ops, u32 phy_id);
|
||||
extern void ipq9574_qca8075_phy_interface_set_mode(uint32_t phy_id, uint32_t mode);
|
||||
extern int ipq_qca8033_phy_init(struct phy_ops **ops, u32 phy_id);
|
||||
extern int ipq_qca8081_phy_init(struct phy_ops **ops, u32 phy_id);
|
||||
extern int ipq_qca_aquantia_phy_init(struct phy_ops **ops, u32 phy_id);
|
||||
|
|
@ -963,7 +963,7 @@ static int ipq9574_eth_init(struct eth_device *eth_dev, bd_t *this)
|
|||
char *dp[] = {"Half", "Full"};
|
||||
int linkup=0;
|
||||
int clk[4] = {0};
|
||||
int phy_addr, node, aquantia_port[2] = {-1}, aquantia_port_cnt = -1;
|
||||
int phy_addr, node, aquantia_port[2] = {-1, -1}, aquantia_port_cnt = -1;
|
||||
int phy_node = -1, res = -1;
|
||||
int sgmii_mode;
|
||||
|
||||
|
|
@ -1215,7 +1215,6 @@ static int ipq9574_eth_init(struct eth_device *eth_dev, bd_t *this)
|
|||
ipq9574_speed_clock_set(i, clk);
|
||||
|
||||
ipq9574_port_mac_clock_reset(i);
|
||||
|
||||
if (i == aquantia_port[0] || i == aquantia_port[1])
|
||||
ipq9574_uxsgmii_speed_set(i, mac_speed, duplex, status);
|
||||
else
|
||||
|
|
@ -1894,7 +1893,7 @@ int ipq9574_edma_init(void *edma_board_cfg)
|
|||
int phy_id;
|
||||
uint32_t phy_chip_id, phy_chip_id1, phy_chip_id2;
|
||||
static int sw_init_done = 0;
|
||||
int node, phy_addr, aquantia_port[2] = {-1}, aquantia_port_cnt = -1;
|
||||
int node, phy_addr, aquantia_port[2] = {-1, -1}, aquantia_port_cnt = -1;
|
||||
int mode, phy_node = -1, res = -1;
|
||||
|
||||
node = fdt_path_offset(gd->fdt_blob, "/ess-switch");
|
||||
|
|
@ -2017,25 +2016,24 @@ int ipq9574_edma_init(void *edma_board_cfg)
|
|||
phy_chip_id2 = ipq_mdio_read(phy_addr, (1<<30) |(1<<16) | QCA_PHY_ID2, NULL);
|
||||
phy_chip_id = (phy_chip_id1 << 16) | phy_chip_id2;
|
||||
}
|
||||
pr_debug("phy_id is: 0x%x, phy_chip_id1 = 0x%x, phy_chip_id2 = 0x%x, phy_chip_id = 0x%x\n",
|
||||
phy_id, phy_chip_id1, phy_chip_id2, phy_chip_id);
|
||||
pr_debug("phy_id is: 0x%x, phy_addr = 0x%x, phy_chip_id1 = 0x%x, phy_chip_id2 = 0x%x, phy_chip_id = 0x%x\n",
|
||||
phy_id, phy_addr, phy_chip_id1, phy_chip_id2, phy_chip_id);
|
||||
switch(phy_chip_id) {
|
||||
case QCA8075_PHY_V1_0_5P:
|
||||
case QCA8075_PHY_V1_1_5P:
|
||||
case QCA8075_PHY_V1_1_2P:
|
||||
|
||||
if (!sw_init_done) {
|
||||
if (ipq_qca8075_phy_init(&ipq9574_edma_dev[i]->ops[phy_id]) == 0) {
|
||||
if (ipq9574_qca8075_phy_init(&ipq9574_edma_dev[i]->ops[phy_id], phy_addr) == 0) {
|
||||
sw_init_done = 1;
|
||||
}
|
||||
} else {
|
||||
ipq_qca8075_phy_map_ops(&ipq9574_edma_dev[i]->ops[phy_id]);
|
||||
ipq9574_qca8075_phy_map_ops(&ipq9574_edma_dev[i]->ops[phy_id]);
|
||||
}
|
||||
|
||||
if (mode == EPORT_WRAPPER_PSGMII)
|
||||
qca8075_phy_interface_set_mode(0x0, 0x0);
|
||||
ipq9574_qca8075_phy_interface_set_mode(phy_addr, 0x0);
|
||||
else if (mode == EPORT_WRAPPER_QSGMII)
|
||||
qca8075_phy_interface_set_mode(0x0, 0x4);
|
||||
ipq9574_qca8075_phy_interface_set_mode(phy_addr, 0x4);
|
||||
break;
|
||||
#ifdef CONFIG_QCA8033_PHY
|
||||
case QCA8033_PHY:
|
||||
|
|
@ -2065,8 +2063,8 @@ int ipq9574_edma_init(void *edma_board_cfg)
|
|||
break;
|
||||
#endif
|
||||
default:
|
||||
printf("\nphy id not matching, calling default qca807x ops");
|
||||
ipq_qca8075_phy_map_ops(&ipq9574_edma_dev[i]->ops[phy_id]);
|
||||
printf("\nphy chip id: 0x%x id not matching for phy id: 0x%x",
|
||||
phy_chip_id, phy_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
584
drivers/net/ipq9574/ipq9574_qca8075.c
Normal file
584
drivers/net/ipq9574/ipq9574_qca8075.c
Normal file
|
|
@ -0,0 +1,584 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2017, 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 <asm-generic/errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <malloc.h>
|
||||
#include <net.h>
|
||||
#include <phy.h>
|
||||
#include <miiphy.h>
|
||||
#include "ipq_phy.h"
|
||||
#include "ipq9574_qca8075.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);
|
||||
|
||||
struct phy_ops *ipq9574_qca8075_ops;
|
||||
static u32 ipq9574_qca8075_id;
|
||||
static u16 ipq9574_qca8075_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;
|
||||
}
|
||||
|
||||
static u16 ipq9574_qca8075_phy_reg_read(u32 dev_id, u32 phy_id, u32 reg_id)
|
||||
{
|
||||
return ipq_mdio_read(phy_id, reg_id, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* phy4 prfer medium
|
||||
* get phy4 prefer medum, fiber or copper;
|
||||
*/
|
||||
static qca8075_phy_medium_t __phy_prefer_medium_get(u32 dev_id,
|
||||
u32 phy_id)
|
||||
{
|
||||
u16 phy_medium;
|
||||
phy_medium =
|
||||
ipq9574_qca8075_phy_reg_read(dev_id, phy_id,
|
||||
QCA8075_PHY_CHIP_CONFIG);
|
||||
|
||||
return ((phy_medium & QCA8075_PHY4_PREFER_FIBER) ?
|
||||
QCA8075_PHY_MEDIUM_FIBER : QCA8075_PHY_MEDIUM_COPPER);
|
||||
}
|
||||
|
||||
/*
|
||||
* phy4 activer medium
|
||||
* get phy4 current active medium, fiber or copper;
|
||||
*/
|
||||
static qca8075_phy_medium_t __phy_active_medium_get(u32 dev_id,
|
||||
u32 phy_id)
|
||||
{
|
||||
u16 phy_data = 0;
|
||||
u32 phy_mode;
|
||||
|
||||
phy_mode = ipq9574_qca8075_phy_reg_read(dev_id, phy_id,
|
||||
QCA8075_PHY_CHIP_CONFIG);
|
||||
phy_mode &= 0x000f;
|
||||
|
||||
if (phy_mode == QCA8075_PHY_PSGMII_AMDET) {
|
||||
phy_data = ipq9574_qca8075_phy_reg_read(dev_id,
|
||||
phy_id, QCA8075_PHY_SGMII_STATUS);
|
||||
|
||||
if ((phy_data & QCA8075_PHY4_AUTO_COPPER_SELECT)) {
|
||||
return QCA8075_PHY_MEDIUM_COPPER;
|
||||
} else if ((phy_data & QCA8075_PHY4_AUTO_BX1000_SELECT)) {
|
||||
/* PHY_MEDIUM_FIBER_BX1000 */
|
||||
return QCA8075_PHY_MEDIUM_FIBER;
|
||||
} else if ((phy_data & QCA8075_PHY4_AUTO_FX100_SELECT)) {
|
||||
/* PHY_MEDIUM_FIBER_FX100 */
|
||||
return QCA8075_PHY_MEDIUM_FIBER;
|
||||
}
|
||||
/* link down */
|
||||
return __phy_prefer_medium_get(dev_id, phy_id);
|
||||
} else if ((phy_mode == QCA8075_PHY_PSGMII_BASET) ||
|
||||
(phy_mode == QCA8075_PHY_SGMII_BASET)) {
|
||||
return QCA8075_PHY_MEDIUM_COPPER;
|
||||
} else if ((phy_mode == QCA8075_PHY_PSGMII_BX1000) ||
|
||||
(phy_mode == QCA8075_PHY_PSGMII_FX100)) {
|
||||
return QCA8075_PHY_MEDIUM_FIBER;
|
||||
} else {
|
||||
return QCA8075_PHY_MEDIUM_COPPER;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* phy4 copper page or fiber page select
|
||||
* set phy4 copper or fiber page
|
||||
*/
|
||||
|
||||
static u8 __phy_reg_pages_sel(u32 dev_id, u32 phy_id,
|
||||
qca8075_phy_reg_pages_t phy_reg_pages)
|
||||
{
|
||||
u16 reg_pages;
|
||||
reg_pages = ipq9574_qca8075_phy_reg_read(dev_id,
|
||||
phy_id, QCA8075_PHY_CHIP_CONFIG);
|
||||
|
||||
if (phy_reg_pages == QCA8075_PHY_COPPER_PAGES) {
|
||||
reg_pages |= 0x8000;
|
||||
} else if (phy_reg_pages == QCA8075_PHY_SGBX_PAGES) {
|
||||
reg_pages &= ~0x8000;
|
||||
} else
|
||||
return -EINVAL;
|
||||
|
||||
ipq9574_qca8075_phy_reg_write(dev_id, phy_id,
|
||||
QCA8075_PHY_CHIP_CONFIG, reg_pages);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* phy4 reg pages selection by active medium
|
||||
* phy4 reg pages selection
|
||||
*/
|
||||
static u32 __phy_reg_pages_sel_by_active_medium(u32 dev_id,
|
||||
u32 phy_id)
|
||||
{
|
||||
qca8075_phy_medium_t phy_medium;
|
||||
qca8075_phy_reg_pages_t reg_pages;
|
||||
|
||||
phy_medium = __phy_active_medium_get(dev_id, phy_id);
|
||||
if (phy_medium == QCA8075_PHY_MEDIUM_FIBER) {
|
||||
reg_pages = QCA8075_PHY_SGBX_PAGES;
|
||||
} else if (phy_medium == QCA8075_PHY_MEDIUM_COPPER) {
|
||||
reg_pages = QCA8075_PHY_COPPER_PAGES;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return __phy_reg_pages_sel(dev_id, phy_id, reg_pages);
|
||||
}
|
||||
|
||||
static u8 ipq9574_qca8075_phy_get_link_status(u32 dev_id, u32 phy_id)
|
||||
{
|
||||
u16 phy_data;
|
||||
if (phy_id == COMBO_PHY_ID)
|
||||
__phy_reg_pages_sel_by_active_medium(dev_id, phy_id);
|
||||
phy_data = ipq9574_qca8075_phy_reg_read(dev_id,
|
||||
phy_id, QCA8075_PHY_SPEC_STATUS);
|
||||
if (phy_data & QCA8075_STATUS_LINK_PASS)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static u32 ipq9574_qca8075_phy_get_duplex(u32 dev_id, u32 phy_id,
|
||||
fal_port_duplex_t * duplex)
|
||||
{
|
||||
u16 phy_data;
|
||||
|
||||
if (phy_id == COMBO_PHY_ID) {
|
||||
__phy_reg_pages_sel_by_active_medium(dev_id, phy_id);
|
||||
}
|
||||
|
||||
phy_data = ipq9574_qca8075_phy_reg_read(dev_id, phy_id,
|
||||
QCA8075_PHY_SPEC_STATUS);
|
||||
|
||||
/*
|
||||
* Read duplex
|
||||
*/
|
||||
if (phy_data & QCA8075_STATUS_FULL_DUPLEX)
|
||||
*duplex = FAL_FULL_DUPLEX;
|
||||
else
|
||||
*duplex = FAL_HALF_DUPLEX;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 ipq9574_qca8075_phy_get_speed(u32 dev_id, u32 phy_id,
|
||||
fal_port_speed_t * speed)
|
||||
{
|
||||
u16 phy_data;
|
||||
|
||||
if (phy_id == COMBO_PHY_ID) {
|
||||
__phy_reg_pages_sel_by_active_medium(dev_id, phy_id);
|
||||
}
|
||||
phy_data = ipq9574_qca8075_phy_reg_read(dev_id,
|
||||
phy_id, QCA8075_PHY_SPEC_STATUS);
|
||||
|
||||
switch (phy_data & QCA8075_STATUS_SPEED_MASK) {
|
||||
case QCA8075_STATUS_SPEED_1000MBS:
|
||||
*speed = FAL_SPEED_1000;
|
||||
break;
|
||||
case QCA8075_STATUS_SPEED_100MBS:
|
||||
*speed = FAL_SPEED_100;
|
||||
break;
|
||||
case QCA8075_STATUS_SPEED_10MBS:
|
||||
*speed = FAL_SPEED_10;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 ipq9574_qca8075_phy_mmd_write(u32 dev_id, u32 phy_id,
|
||||
u16 mmd_num, u16 reg_id, u16 reg_val)
|
||||
{
|
||||
ipq9574_qca8075_phy_reg_write(dev_id, phy_id,
|
||||
QCA8075_MMD_CTRL_REG, mmd_num);
|
||||
ipq9574_qca8075_phy_reg_write(dev_id, phy_id,
|
||||
QCA8075_MMD_DATA_REG, reg_id);
|
||||
ipq9574_qca8075_phy_reg_write(dev_id, phy_id,
|
||||
QCA8075_MMD_CTRL_REG,
|
||||
0x4000 | mmd_num);
|
||||
ipq9574_qca8075_phy_reg_write(dev_id, phy_id,
|
||||
QCA8075_MMD_DATA_REG, reg_val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u16 ipq9574_qca8075_phy_mmd_read(u32 dev_id, u32 phy_id,
|
||||
u16 mmd_num, u16 reg_id)
|
||||
{
|
||||
ipq9574_qca8075_phy_reg_write(dev_id, phy_id,
|
||||
QCA8075_MMD_CTRL_REG, mmd_num);
|
||||
ipq9574_qca8075_phy_reg_write(dev_id, phy_id,
|
||||
QCA8075_MMD_DATA_REG, reg_id);
|
||||
ipq9574_qca8075_phy_reg_write(dev_id, phy_id,
|
||||
QCA8075_MMD_CTRL_REG,
|
||||
0x4000 | mmd_num);
|
||||
return ipq9574_qca8075_phy_reg_read(dev_id, phy_id,
|
||||
QCA8075_MMD_DATA_REG);
|
||||
}
|
||||
|
||||
/*
|
||||
* get phy4 medium is 100fx
|
||||
*/
|
||||
static u8 __medium_is_fiber_100fx(u32 dev_id, u32 phy_id)
|
||||
{
|
||||
u16 phy_data;
|
||||
phy_data = ipq9574_qca8075_phy_reg_read(dev_id, phy_id,
|
||||
QCA8075_PHY_SGMII_STATUS);
|
||||
|
||||
if (phy_data & QCA8075_PHY4_AUTO_FX100_SELECT) {
|
||||
return 1;
|
||||
}
|
||||
/* Link down */
|
||||
if ((!(phy_data & QCA8075_PHY4_AUTO_COPPER_SELECT)) &&
|
||||
(!(phy_data & QCA8075_PHY4_AUTO_BX1000_SELECT)) &&
|
||||
(!(phy_data & QCA8075_PHY4_AUTO_SGMII_SELECT))) {
|
||||
|
||||
phy_data = ipq9574_qca8075_phy_reg_read(dev_id, phy_id,
|
||||
QCA8075_PHY_CHIP_CONFIG);
|
||||
if ((phy_data & QCA8075_PHY4_PREFER_FIBER)
|
||||
&& (!(phy_data & QCA8075_PHY4_FIBER_MODE_1000BX))) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ipq9574_qca8075_phy_set_hibernate - set hibernate status
|
||||
* set hibernate status
|
||||
*/
|
||||
static u32 ipq9574_qca8075_phy_set_hibernate(u32 dev_id, u32 phy_id, u8 enable)
|
||||
{
|
||||
u16 phy_data;
|
||||
|
||||
ipq9574_qca8075_phy_reg_write(dev_id, phy_id, QCA8075_DEBUG_PORT_ADDRESS,
|
||||
QCA8075_DEBUG_PHY_HIBERNATION_CTRL);
|
||||
|
||||
phy_data = ipq9574_qca8075_phy_reg_read(dev_id, phy_id,
|
||||
QCA8075_DEBUG_PORT_DATA);
|
||||
|
||||
if (enable) {
|
||||
phy_data |= 0x8000;
|
||||
} else {
|
||||
phy_data &= ~0x8000;
|
||||
}
|
||||
|
||||
ipq9574_qca8075_phy_reg_write(dev_id, phy_id, QCA8075_DEBUG_PORT_DATA, phy_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ipq9574_qca8075_restart_autoneg - restart the phy autoneg
|
||||
*/
|
||||
static u32 ipq9574_qca8075_phy_restart_autoneg(u32 dev_id, u32 phy_id)
|
||||
{
|
||||
u16 phy_data;
|
||||
|
||||
if (phy_id == COMBO_PHY_ID) {
|
||||
if (__medium_is_fiber_100fx(dev_id, phy_id))
|
||||
return -1;
|
||||
__phy_reg_pages_sel_by_active_medium(dev_id, phy_id);
|
||||
}
|
||||
phy_data = ipq9574_qca8075_phy_reg_read(dev_id, phy_id, QCA8075_PHY_CONTROL);
|
||||
phy_data |= QCA8075_CTRL_AUTONEGOTIATION_ENABLE;
|
||||
ipq9574_qca8075_phy_reg_write(dev_id, phy_id, QCA8075_PHY_CONTROL,
|
||||
phy_data | QCA8075_CTRL_RESTART_AUTONEGOTIATION);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ipq9574_qca8075_phy_get_8023az status
|
||||
* get 8023az status
|
||||
*/
|
||||
static u32 ipq9574_qca8075_phy_get_8023az(u32 dev_id, u32 phy_id, u8 *enable)
|
||||
{
|
||||
u16 phy_data;
|
||||
if (phy_id == COMBO_PHY_ID) {
|
||||
if (QCA8075_PHY_MEDIUM_COPPER !=
|
||||
__phy_active_medium_get(dev_id, phy_id))
|
||||
return -1;
|
||||
}
|
||||
*enable = 0;
|
||||
|
||||
phy_data = ipq9574_qca8075_phy_mmd_read(dev_id, phy_id, QCA8075_PHY_MMD7_NUM,
|
||||
QCA8075_PHY_MMD7_ADDR_8023AZ_EEE_CTRL);
|
||||
|
||||
if ((phy_data & 0x0004) && (phy_data & 0x0002))
|
||||
*enable = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ipq9574_qca8075_phy_set_powersave - set power saving status
|
||||
*/
|
||||
static u32 ipq9574_qca8075_phy_set_powersave(u32 dev_id, u32 phy_id, u8 enable)
|
||||
{
|
||||
u16 phy_data;
|
||||
u8 status = 0;
|
||||
|
||||
if (phy_id == COMBO_PHY_ID) {
|
||||
if (QCA8075_PHY_MEDIUM_COPPER !=
|
||||
__phy_active_medium_get(dev_id, phy_id))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
ipq9574_qca8075_phy_get_8023az(dev_id, phy_id, &status);
|
||||
if (!status) {
|
||||
phy_data = ipq9574_qca8075_phy_mmd_read(dev_id, phy_id,
|
||||
QCA8075_PHY_MMD3_NUM,
|
||||
QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL);
|
||||
phy_data &= ~(1 << 14);
|
||||
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id,
|
||||
QCA8075_PHY_MMD3_NUM,
|
||||
QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL,
|
||||
phy_data);
|
||||
}
|
||||
phy_data = ipq9574_qca8075_phy_mmd_read(dev_id, phy_id,
|
||||
QCA8075_PHY_MMD3_NUM,
|
||||
QCA8075_PHY_MMD3_ADDR_CLD_CTRL5);
|
||||
phy_data &= ~(1 << 14);
|
||||
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD3_NUM,
|
||||
QCA8075_PHY_MMD3_ADDR_CLD_CTRL5,
|
||||
phy_data);
|
||||
|
||||
phy_data = ipq9574_qca8075_phy_mmd_read(dev_id, phy_id,
|
||||
QCA8075_PHY_MMD3_NUM,
|
||||
QCA8075_PHY_MMD3_ADDR_CLD_CTRL3);
|
||||
phy_data &= ~(1 << 15);
|
||||
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD3_NUM,
|
||||
QCA8075_PHY_MMD3_ADDR_CLD_CTRL3, phy_data);
|
||||
|
||||
} else {
|
||||
phy_data = ipq9574_qca8075_phy_mmd_read(dev_id, phy_id,
|
||||
QCA8075_PHY_MMD3_NUM,
|
||||
QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL);
|
||||
phy_data |= (1 << 14);
|
||||
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD3_NUM,
|
||||
QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL,
|
||||
phy_data);
|
||||
|
||||
phy_data = ipq9574_qca8075_phy_mmd_read(dev_id, phy_id,
|
||||
QCA8075_PHY_MMD3_NUM,
|
||||
QCA8075_PHY_MMD3_ADDR_CLD_CTRL5);
|
||||
phy_data |= (1 << 14);
|
||||
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD3_NUM,
|
||||
QCA8075_PHY_MMD3_ADDR_CLD_CTRL5, phy_data);
|
||||
|
||||
phy_data = ipq9574_qca8075_phy_mmd_read(dev_id, phy_id,
|
||||
QCA8075_PHY_MMD3_NUM,
|
||||
QCA8075_PHY_MMD3_ADDR_CLD_CTRL3);
|
||||
phy_data |= (1 << 15);
|
||||
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD3_NUM,
|
||||
QCA8075_PHY_MMD3_ADDR_CLD_CTRL3, phy_data);
|
||||
|
||||
}
|
||||
ipq9574_qca8075_phy_reg_write(dev_id, phy_id, QCA8075_PHY_CONTROL, 0x9040);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ipq9574_qca8075_phy_set_802.3az
|
||||
*/
|
||||
static u32 ipq9574_qca8075_phy_set_8023az(u32 dev_id, u32 phy_id, u8 enable)
|
||||
{
|
||||
u16 phy_data;
|
||||
|
||||
if (phy_id == COMBO_PHY_ID) {
|
||||
if (QCA8075_PHY_MEDIUM_COPPER !=
|
||||
__phy_active_medium_get(dev_id, phy_id))
|
||||
return -1;
|
||||
}
|
||||
phy_data = ipq9574_qca8075_phy_mmd_read(dev_id, phy_id, QCA8075_PHY_MMD7_NUM,
|
||||
QCA8075_PHY_MMD7_ADDR_8023AZ_EEE_CTRL);
|
||||
if (enable) {
|
||||
phy_data |= 0x0006;
|
||||
|
||||
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD7_NUM,
|
||||
QCA8075_PHY_MMD7_ADDR_8023AZ_EEE_CTRL, phy_data);
|
||||
if (ipq9574_qca8075_id == QCA8075_PHY_V1_0_5P) {
|
||||
/*
|
||||
* Workaround to avoid packet loss and < 10m cable
|
||||
* 1000M link not stable under az enable
|
||||
*/
|
||||
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id,
|
||||
QCA8075_PHY_MMD3_NUM,
|
||||
QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL,
|
||||
AZ_TIMER_CTRL_ADJUST_VALUE);
|
||||
|
||||
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id,
|
||||
QCA8075_PHY_MMD3_NUM,
|
||||
QCA8075_PHY_MMD3_ADDR_8023AZ_CLD_CTRL,
|
||||
AZ_CLD_CTRL_ADJUST_VALUE);
|
||||
}
|
||||
} else {
|
||||
phy_data &= ~0x0006;
|
||||
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD7_NUM,
|
||||
QCA8075_PHY_MMD7_ADDR_8023AZ_EEE_CTRL, phy_data);
|
||||
if (ipq9574_qca8075_id == QCA8075_PHY_V1_0_5P) {
|
||||
ipq9574_qca8075_phy_mmd_write(dev_id, phy_id,
|
||||
QCA8075_PHY_MMD3_NUM,
|
||||
QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL,
|
||||
AZ_TIMER_CTRL_DEFAULT_VALUE);
|
||||
}
|
||||
}
|
||||
ipq9574_qca8075_phy_restart_autoneg(dev_id, phy_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ipq9574_qca8075_phy_map_ops(struct phy_ops **ops)
|
||||
{
|
||||
*ops = ipq9574_qca8075_ops;
|
||||
}
|
||||
|
||||
void ipq9574_qca8075_phy_serdes_reset(u32 phy_id)
|
||||
{
|
||||
ipq9574_qca8075_phy_reg_write(0,
|
||||
phy_id + QCA8075_PHY_PSGMII_ADDR_INC,
|
||||
QCA8075_MODE_RESET_REG,
|
||||
QCA8075_MODE_CHANAGE_RESET);
|
||||
mdelay(100);
|
||||
ipq9574_qca8075_phy_reg_write(0,
|
||||
phy_id + QCA8075_PHY_PSGMII_ADDR_INC,
|
||||
QCA8075_MODE_RESET_REG,
|
||||
QCA8075_MODE_RESET_DEFAULT_VALUE);
|
||||
|
||||
}
|
||||
|
||||
static u16 ipq9574_qca8075_phy_interface_get_mode(u32 phy_id)
|
||||
{
|
||||
u16 phy_data;
|
||||
|
||||
phy_data = ipq9574_qca8075_phy_reg_read(0,
|
||||
phy_id + QCA8075_PHY_MAX_ADDR_INC,
|
||||
QCA8075_PHY_CHIP_CONFIG);
|
||||
phy_data &= 0x000f;
|
||||
return phy_data;
|
||||
}
|
||||
|
||||
void ipq9574_qca8075_phy_interface_set_mode(u32 phy_id, u32 mode)
|
||||
{
|
||||
u16 phy_data;
|
||||
|
||||
phy_data = ipq9574_qca8075_phy_interface_get_mode(phy_id);
|
||||
if (phy_data != mode) {
|
||||
phy_data = ipq9574_qca8075_phy_reg_read(0,
|
||||
phy_id + QCA8075_PHY_MAX_ADDR_INC,
|
||||
QCA8075_PHY_CHIP_CONFIG);
|
||||
phy_data &= 0xfff0;
|
||||
ipq9574_qca8075_phy_reg_write(0,
|
||||
phy_id + QCA8075_PHY_MAX_ADDR_INC,
|
||||
QCA8075_PHY_CHIP_CONFIG,
|
||||
phy_data | mode);
|
||||
ipq9574_qca8075_phy_serdes_reset(phy_id);
|
||||
}
|
||||
}
|
||||
|
||||
int ipq9574_qca8075_phy_init(struct phy_ops **ops, u32 phy_id)
|
||||
{
|
||||
u16 phy_data;
|
||||
u32 port_id = 0;
|
||||
u32 first_phy_id;
|
||||
|
||||
first_phy_id = phy_id;
|
||||
ipq9574_qca8075_ops = (struct phy_ops *)malloc(sizeof(struct phy_ops));
|
||||
if (!ipq9574_qca8075_ops)
|
||||
return -ENOMEM;
|
||||
|
||||
ipq9574_qca8075_ops->phy_get_link_status = ipq9574_qca8075_phy_get_link_status;
|
||||
ipq9574_qca8075_ops->phy_get_speed = ipq9574_qca8075_phy_get_speed;
|
||||
ipq9574_qca8075_ops->phy_get_duplex = ipq9574_qca8075_phy_get_duplex;
|
||||
*ops = ipq9574_qca8075_ops;
|
||||
|
||||
ipq9574_qca8075_id = phy_data = ipq9574_qca8075_phy_reg_read(0x0, phy_id, QCA8075_PHY_ID1);
|
||||
printf ("PHY ID1: 0x%x\n", phy_data);
|
||||
phy_data = ipq9574_qca8075_phy_reg_read(0x0, phy_id, QCA8075_PHY_ID2);
|
||||
printf ("PHY ID2: 0x%x\n", phy_data);
|
||||
ipq9574_qca8075_id = (ipq9574_qca8075_id << 16) | phy_data;
|
||||
|
||||
if (ipq9574_qca8075_id == QCA8075_PHY_V1_0_5P) {
|
||||
phy_data = ipq9574_qca8075_phy_mmd_read(0, PSGMII_ID,
|
||||
QCA8075_PHY_MMD1_NUM, QCA8075_PSGMII_FIFI_CTRL);
|
||||
phy_data &= 0xbfff;
|
||||
ipq9574_qca8075_phy_mmd_write(0, PSGMII_ID, QCA8075_PHY_MMD1_NUM,
|
||||
QCA8075_PSGMII_FIFI_CTRL, phy_data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable phy power saving function by default
|
||||
*/
|
||||
if ((ipq9574_qca8075_id == QCA8075_PHY_V1_0_5P) ||
|
||||
(ipq9574_qca8075_id == QCA8075_PHY_V1_1_5P) ||
|
||||
(ipq9574_qca8075_id == QCA8075_PHY_V1_1_2P)) {
|
||||
for (port_id = 0; port_id < 5; port_id++) {
|
||||
/*enable phy power saving function by default */
|
||||
phy_id = first_phy_id + port_id;
|
||||
ipq9574_qca8075_phy_set_8023az(0x0, phy_id, 0x1);
|
||||
ipq9574_qca8075_phy_set_powersave(0x0, phy_id, 0x1);
|
||||
ipq9574_qca8075_phy_set_hibernate(0x0, phy_id, 0x1);
|
||||
|
||||
/*
|
||||
* change malibu control_dac[2:0] of MMD7 0x801A bit[9:7]
|
||||
* from 111 to 101
|
||||
*/
|
||||
phy_data = ipq9574_qca8075_phy_mmd_read(0, phy_id,
|
||||
QCA8075_PHY_MMD7_NUM, QCA8075_PHY_MMD7_DAC_CTRL);
|
||||
phy_data &= ~QCA8075_DAC_CTRL_MASK;
|
||||
phy_data |= QCA8075_DAC_CTRL_VALUE;
|
||||
ipq9574_qca8075_phy_mmd_write(0, phy_id, QCA8075_PHY_MMD7_NUM,
|
||||
QCA8075_PHY_MMD7_DAC_CTRL, phy_data);
|
||||
|
||||
/* add 10M and 100M link LED behavior for QFN board*/
|
||||
phy_data = ipq9574_qca8075_phy_mmd_read(0, phy_id, QCA8075_PHY_MMD7_NUM,
|
||||
QCA8075_PHY_MMD7_LED_1000_CTRL1);
|
||||
phy_data &= ~QCA8075_LED_1000_CTRL1_100_10_MASK;
|
||||
phy_data |= QCA8075_LED_1000_CTRL1_100_10_MASK;
|
||||
ipq9574_qca8075_phy_mmd_write(0 , phy_id, QCA8075_PHY_MMD7_NUM,
|
||||
QCA8075_PHY_MMD7_LED_1000_CTRL1, phy_data);
|
||||
}
|
||||
}
|
||||
if ((ipq9574_qca8075_id == QCA8075_PHY_V1_1_2P) && (first_phy_id >= 0x3)) {
|
||||
phy_id = first_phy_id - 0x3;
|
||||
}
|
||||
else {
|
||||
phy_id = first_phy_id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable AZ transmitting ability
|
||||
*/
|
||||
ipq9574_qca8075_phy_mmd_write(0, phy_id + 5, QCA8075_PHY_MMD1_NUM,
|
||||
QCA8075_PSGMII_MODE_CTRL,
|
||||
QCA8075_PHY_PSGMII_MODE_CTRL_ADJUST_VALUE);
|
||||
|
||||
/* adjust psgmii serdes tx amp */
|
||||
ipq9574_qca8075_phy_reg_write(0, phy_id + 5, QCA8075_PSGMII_TX_DRIVER_1_CTRL,
|
||||
QCA8075_PHY_PSGMII_REDUCE_SERDES_TX_AMP);
|
||||
|
||||
/* to avoid psgmii module goes into hibernation, work with psgmii self test*/
|
||||
phy_data = ipq9574_qca8075_phy_mmd_read(0, phy_id + 4, QCA8075_PHY_MMD3_NUM, 0x805a);
|
||||
phy_data &= (~(1 << 1));
|
||||
ipq9574_qca8075_phy_mmd_write(0, phy_id + 4, QCA8075_PHY_MMD3_NUM, 0x805a, phy_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
491
drivers/net/ipq9574/ipq9574_qca8075.h
Normal file
491
drivers/net/ipq9574/ipq9574_qca8075.h
Normal file
|
|
@ -0,0 +1,491 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2017, 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 _QCA8075_PHY_H_
|
||||
#define _QCA8075_PHY_H_
|
||||
|
||||
#define QCA8075_PHY_CONTROL 0
|
||||
#define QCA8075_PHY_STATUS 1
|
||||
#define QCA8075_PHY_ID1 2
|
||||
#define QCA8075_PHY_ID2 3
|
||||
#define QCA8075_AUTONEG_ADVERT 4
|
||||
#define QCA8075_LINK_PARTNER_ABILITY 5
|
||||
#define QCA8075_AUTONEG_EXPANSION 6
|
||||
#define QCA8075_NEXT_PAGE_TRANSMIT 7
|
||||
#define QCA8075_LINK_PARTNER_NEXT_PAGE 8
|
||||
#define QCA8075_1000BASET_CONTROL 9
|
||||
#define QCA8075_1000BASET_STATUS 10
|
||||
#define QCA8075_MMD_CTRL_REG 13
|
||||
#define QCA8075_MMD_DATA_REG 14
|
||||
#define QCA8075_EXTENDED_STATUS 15
|
||||
#define QCA8075_PHY_SPEC_CONTROL 16
|
||||
#define QCA8075_PHY_SPEC_STATUS 17
|
||||
#define QCA8075_PHY_INTR_MASK 18
|
||||
#define QCA8075_PHY_INTR_STATUS 19
|
||||
#define QCA8075_PHY_CDT_CONTROL 22
|
||||
#define QCA8075_PHY_CDT_STATUS 28
|
||||
#define QCA8075_DEBUG_PORT_ADDRESS 29
|
||||
#define QCA8075_DEBUG_PORT_DATA 30
|
||||
#define COMBO_PHY_ID 4
|
||||
#define PSGMII_ID 5
|
||||
|
||||
#define QCA8075_DEBUG_PHY_HIBERNATION_CTRL 0xb
|
||||
#define QCA8075_DEBUG_PHY_POWER_SAVING_CTRL 0x29
|
||||
#define QCA8075_PHY_MMD7_ADDR_8023AZ_EEE_CTRL 0x3c
|
||||
#define QCA8075_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL 0x805a
|
||||
#define QCA8075_PHY_MMD3_WOL_MAGIC_MAC_CTRL1 0x804a
|
||||
#define QCA8075_PHY_MMD3_WOL_MAGIC_MAC_CTRL2 0x804b
|
||||
#define QCA8075_PHY_MMD3_WOL_MAGIC_MAC_CTRL3 0x804c
|
||||
#define QCA8075_PHY_MMD3_WOL_CTRL 0x8012
|
||||
|
||||
#define QCA8075_PSGMII_FIFI_CTRL 0x6e
|
||||
#define QCA8075_PSGMII_CALIB_CTRL 0x27
|
||||
#define QCA8075_PSGMII_MODE_CTRL 0x6d
|
||||
#define QCA8075_PHY_PSGMII_MODE_CTRL_ADJUST_VALUE 0x220c
|
||||
|
||||
#define QCA8075_PHY_MMD7_NUM 7
|
||||
#define QCA8075_PHY_MMD3_NUM 3
|
||||
#define QCA8075_PHY_MMD1_NUM 1
|
||||
|
||||
#define QCA8075_PHY_SGMII_STATUS 0x1a /* sgmii_status Register */
|
||||
#define QCA8075_PHY4_AUTO_SGMII_SELECT 0x40
|
||||
#define QCA8075_PHY4_AUTO_COPPER_SELECT 0x20
|
||||
#define QCA8075_PHY4_AUTO_BX1000_SELECT 0x10
|
||||
#define QCA8075_PHY4_AUTO_FX100_SELECT 0x8
|
||||
|
||||
#define QCA8075_MODE_RESET_REG 0x0
|
||||
#define QCA8075_MODE_CHANAGE_RESET 0x0
|
||||
#define QCA8075_MODE_RESET_DEFAULT_VALUE 0x5f
|
||||
#define QCA8075_PHY_MAX_ADDR_INC 0x4
|
||||
#define QCA8075_PHY_PSGMII_ADDR_INC 0x5
|
||||
|
||||
#define QCA8075_PHY_CHIP_CONFIG 0x1f /* Chip Configuration Register */
|
||||
#define BT_BX_SG_REG_SELECT BIT_15
|
||||
#define BT_BX_SG_REG_SELECT_OFFSET 15
|
||||
#define BT_BX_SG_REG_SELECT_LEN 1
|
||||
#define QCA8075_SG_BX_PAGES 0x0
|
||||
#define QCA8075_SG_COPPER_PAGES 0x1
|
||||
|
||||
#define QCA8075_PHY_PSGMII_BASET 0x0
|
||||
#define QCA8075_PHY_PSGMII_BX1000 0x1
|
||||
#define QCA8075_PHY_PSGMII_FX100 0x2
|
||||
#define QCA8075_PHY_PSGMII_AMDET 0x3
|
||||
#define QCA8075_PHY_SGMII_BASET 0x4
|
||||
|
||||
#define QCA8075_PHY4_PREFER_FIBER 0x400
|
||||
#define PHY4_PREFER_COPPER 0x0
|
||||
#define PHY4_PREFER_FIBER 0x1
|
||||
|
||||
#define QCA8075_PHY4_FIBER_MODE_1000BX 0x100
|
||||
#define AUTO_100FX_FIBER 0x0
|
||||
#define AUTO_1000BX_FIBER 0x1
|
||||
|
||||
#define QCA8075_PHY_MDIX 0x0020
|
||||
#define QCA8075_PHY_MDIX_AUTO 0x0060
|
||||
#define QCA8075_PHY_MDIX_STATUS 0x0040
|
||||
|
||||
#define MODE_CFG_QUAL BIT_4
|
||||
#define MODE_CFG_QUAL_OFFSET 4
|
||||
#define MODE_CFG_QUAL_LEN 4
|
||||
|
||||
#define MODE_CFG BIT_0
|
||||
#define MODE_CFG_OFFSET 0
|
||||
#define MODE_CFG_LEN 4
|
||||
|
||||
#define QCA8075_PHY_MMD3_ADDR_8023AZ_CLD_CTRL 0x8007
|
||||
#define QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL 0x804e
|
||||
#define QCA8075_PHY_MMD3_ADDR_CLD_CTRL5 0x8005
|
||||
#define QCA8075_PHY_MMD3_ADDR_CLD_CTRL3 0x8003
|
||||
|
||||
#define AZ_TIMER_CTRL_DEFAULT_VALUE 0x3062
|
||||
#define AZ_CLD_CTRL_DEFAULT_VALUE 0x83f6
|
||||
#define AZ_TIMER_CTRL_ADJUST_VALUE 0x7062
|
||||
#define AZ_CLD_CTRL_ADJUST_VALUE 0x8396
|
||||
|
||||
/*debug port */
|
||||
#define QCA8075_DEBUG_PORT_RGMII_MODE 18
|
||||
#define QCA8075_DEBUG_PORT_RGMII_MODE_EN 0x0008
|
||||
|
||||
#define QCA8075_DEBUG_PORT_RX_DELAY 0
|
||||
#define QCA8075_DEBUG_PORT_RX_DELAY_EN 0x8000
|
||||
|
||||
#define QCA8075_DEBUG_PORT_TX_DELAY 5
|
||||
#define QCA8075_DEBUG_PORT_TX_DELAY_EN 0x0100
|
||||
|
||||
/* PHY Registers Field */
|
||||
|
||||
/* Control Register fields offset:0 */
|
||||
/* bits 6,13: 10=1000, 01=100, 00=10 */
|
||||
#define QCA8075_CTRL_SPEED_MSB 0x0040
|
||||
|
||||
/* Collision test enable */
|
||||
#define QCA8075_CTRL_COLL_TEST_ENABLE 0x0080
|
||||
|
||||
/* FDX =1, half duplex =0 */
|
||||
#define QCA8075_CTRL_FULL_DUPLEX 0x0100
|
||||
|
||||
/* Restart auto negotiation */
|
||||
#define QCA8075_CTRL_RESTART_AUTONEGOTIATION 0x0200
|
||||
|
||||
/* Isolate PHY from MII */
|
||||
#define QCA8075_CTRL_ISOLATE 0x0400
|
||||
|
||||
/* Power down */
|
||||
#define QCA8075_CTRL_POWER_DOWN 0x0800
|
||||
|
||||
/* Auto Neg Enable */
|
||||
#define QCA8075_CTRL_AUTONEGOTIATION_ENABLE 0x1000
|
||||
|
||||
/* Local Loopback Enable */
|
||||
#define QCA8075_LOCAL_LOOPBACK_ENABLE 0x4000
|
||||
|
||||
/* bits 6,13: 10=1000, 01=100, 00=10 */
|
||||
#define QCA8075_CTRL_SPEED_LSB 0x2000
|
||||
|
||||
/* 0 = normal, 1 = loopback */
|
||||
#define QCA8075_CTRL_LOOPBACK 0x4000
|
||||
#define QCA8075_CTRL_SOFTWARE_RESET 0x8000
|
||||
|
||||
#define QCA8075_CTRL_SPEED_MASK 0x2040
|
||||
#define QCA8075_CTRL_SPEED_1000 0x0040
|
||||
#define QCA8075_CTRL_SPEED_100 0x2000
|
||||
#define QCA8075_CTRL_SPEED_10 0x0000
|
||||
|
||||
#define QCA8075_RESET_DONE(phy_control) \
|
||||
(((phy_control) & (QCA8075_CTRL_SOFTWARE_RESET)) == 0)
|
||||
|
||||
/* Status Register fields offset:1 */
|
||||
/* Extended register capabilities */
|
||||
#define QCA8075_STATUS_EXTENDED_CAPS 0x0001
|
||||
|
||||
/* Jabber Detected */
|
||||
#define QCA8075_STATUS_JABBER_DETECT 0x0002
|
||||
|
||||
/* Link Status 1 = link */
|
||||
#define QCA8075_STATUS_LINK_STATUS_UP 0x0004
|
||||
|
||||
/* Auto Neg Capable */
|
||||
#define QCA8075_STATUS_AUTONEG_CAPS 0x0008
|
||||
|
||||
/* Remote Fault Detect */
|
||||
#define QCA8075_STATUS_REMOTE_FAULT 0x0010
|
||||
|
||||
/* Auto Neg Complete */
|
||||
#define QCA8075_STATUS_AUTO_NEG_DONE 0x0020
|
||||
|
||||
/* Preamble may be suppressed */
|
||||
#define QCA8075_STATUS_PREAMBLE_SUPPRESS 0x0040
|
||||
|
||||
/* Ext. status info in Reg 0x0F */
|
||||
#define QCA8075_STATUS_EXTENDED_STATUS 0x0100
|
||||
|
||||
/* 100T2 Half Duplex Capable */
|
||||
#define QCA8075_STATUS_100T2_HD_CAPS 0x0200
|
||||
|
||||
/* 100T2 Full Duplex Capable */
|
||||
#define QCA8075_STATUS_100T2_FD_CAPS 0x0400
|
||||
|
||||
/* 10T Half Duplex Capable */
|
||||
#define QCA8075_STATUS_10T_HD_CAPS 0x0800
|
||||
|
||||
/* 10T Full Duplex Capable */
|
||||
#define QCA8075_STATUS_10T_FD_CAPS 0x1000
|
||||
|
||||
/* 100X Half Duplex Capable */
|
||||
#define QCA8075_STATUS_100X_HD_CAPS 0x2000
|
||||
|
||||
/* 100X Full Duplex Capable */
|
||||
#define QCA8075_STATUS_100X_FD_CAPS 0x4000
|
||||
|
||||
/* 100T4 Capable */
|
||||
#define QCA8075_STATUS_100T4_CAPS 0x8000
|
||||
|
||||
/* extended status register capabilities */
|
||||
|
||||
#define QCA8075_STATUS_1000T_HD_CAPS 0x1000
|
||||
|
||||
#define QCA8075_STATUS_1000T_FD_CAPS 0x2000
|
||||
|
||||
#define QCA8075_STATUS_1000X_HD_CAPS 0x4000
|
||||
|
||||
#define QCA8075_STATUS_1000X_FD_CAPS 0x8000
|
||||
|
||||
#define QCA8075_AUTONEG_DONE(ip_phy_status) \
|
||||
(((ip_phy_status) & (QCA8075_STATUS_AUTO_NEG_DONE)) == \
|
||||
(QCA8075_STATUS_AUTO_NEG_DONE))
|
||||
|
||||
/* PHY identifier1 offset:2 */
|
||||
//Organizationally Unique Identifier bits 3:18
|
||||
|
||||
/* PHY identifier2 offset:3 */
|
||||
//Organizationally Unique Identifier bits 19:24
|
||||
|
||||
/* Auto-Negotiation Advertisement register. offset:4 */
|
||||
/* indicates IEEE 802.3 CSMA/CD */
|
||||
#define QCA8075_ADVERTISE_SELECTOR_FIELD 0x0001
|
||||
|
||||
/* 10T Half Duplex Capable */
|
||||
#define QCA8075_ADVERTISE_10HALF 0x0020
|
||||
|
||||
/* 10T Full Duplex Capable */
|
||||
#define QCA8075_ADVERTISE_10FULL 0x0040
|
||||
|
||||
/* 100TX Half Duplex Capable */
|
||||
#define QCA8075_ADVERTISE_100HALF 0x0080
|
||||
|
||||
/* 100TX Full Duplex Capable */
|
||||
#define QCA8075_ADVERTISE_100FULL 0x0100
|
||||
|
||||
/* 100T4 Capable */
|
||||
#define QCA8075_ADVERTISE_100T4 0x0200
|
||||
|
||||
/* Pause operation desired */
|
||||
#define QCA8075_ADVERTISE_PAUSE 0x0400
|
||||
|
||||
/* Asymmetric Pause Direction bit */
|
||||
#define QCA8075_ADVERTISE_ASYM_PAUSE 0x0800
|
||||
|
||||
/* Remote Fault detected */
|
||||
#define QCA8075_ADVERTISE_REMOTE_FAULT 0x2000
|
||||
|
||||
/* Next Page ability supported */
|
||||
#define QCA8075_ADVERTISE_NEXT_PAGE 0x8000
|
||||
|
||||
/* 100TX Half Duplex Capable */
|
||||
#define QCA8075_ADVERTISE_1000HALF 0x0100
|
||||
|
||||
/* 100TX Full Duplex Capable */
|
||||
#define QCA8075_ADVERTISE_1000FULL 0x0200
|
||||
|
||||
#define QCA8075_ADVERTISE_ALL \
|
||||
(QCA8075_ADVERTISE_10HALF | QCA8075_ADVERTISE_10FULL | \
|
||||
QCA8075_ADVERTISE_100HALF | QCA8075_ADVERTISE_100FULL | \
|
||||
QCA8075_ADVERTISE_1000FULL)
|
||||
|
||||
#define QCA8075_ADVERTISE_MEGA_ALL \
|
||||
(QCA8075_ADVERTISE_10HALF | QCA8075_ADVERTISE_10FULL | \
|
||||
QCA8075_ADVERTISE_100HALF | QCA8075_ADVERTISE_100FULL)
|
||||
|
||||
#define QCA8075_BX_ADVERTISE_1000FULL 0x0020
|
||||
#define QCA8075_BX_ADVERTISE_1000HALF 0x0040
|
||||
#define QCA8075_BX_ADVERTISE_PAUSE 0x0080
|
||||
#define QCA8075_BX_ADVERTISE_ASYM_PAUSE 0x0100
|
||||
|
||||
#define QCA8075_BX_ADVERTISE_ALL \
|
||||
(QCA8075_BX_ADVERTISE_ASYM_PAUSE | QCA8075_BX_ADVERTISE_PAUSE | \
|
||||
QCA8075_BX_ADVERTISE_1000HALF | QCA8075_BX_ADVERTISE_1000FULL)
|
||||
|
||||
/* Link Partner ability offset:5 */
|
||||
/* Same as advertise selector */
|
||||
#define QCA8075_LINK_SLCT 0x001f
|
||||
|
||||
/* Can do 10mbps half-duplex */
|
||||
#define QCA8075_LINK_10BASETX_HALF_DUPLEX 0x0020
|
||||
|
||||
/* Can do 10mbps full-duplex */
|
||||
#define QCA8075_LINK_10BASETX_FULL_DUPLEX 0x0040
|
||||
|
||||
/* Can do 100mbps half-duplex */
|
||||
#define QCA8075_LINK_100BASETX_HALF_DUPLEX 0x0080
|
||||
|
||||
/* Can do 100mbps full-duplex */
|
||||
#define QCA8075_LINK_100BASETX_FULL_DUPLEX 0x0100
|
||||
|
||||
/* Can do 1000mbps full-duplex */
|
||||
#define QCA8075_LINK_1000BASETX_FULL_DUPLEX 0x0800
|
||||
|
||||
/* Can do 1000mbps half-duplex */
|
||||
#define QCA8075_LINK_1000BASETX_HALF_DUPLEX 0x0400
|
||||
|
||||
/* 100BASE-T4 */
|
||||
#define QCA8075_LINK_100BASE4 0x0200
|
||||
|
||||
/* PAUSE */
|
||||
#define QCA8075_LINK_PAUSE 0x0400
|
||||
|
||||
/* Asymmetrical PAUSE */
|
||||
#define QCA8075_LINK_ASYPAUSE 0x0800
|
||||
|
||||
/* Link partner faulted */
|
||||
#define QCA8075_LINK_RFAULT 0x2000
|
||||
|
||||
/* Link partner acked us */
|
||||
#define QCA8075_LINK_LPACK 0x4000
|
||||
|
||||
/* Next page bit */
|
||||
#define QCA8075_LINK_NPAGE 0x8000
|
||||
|
||||
/* Auto-Negotiation Expansion Register offset:6 */
|
||||
|
||||
/* Next Page Transmit Register offset:7 */
|
||||
|
||||
/* Link partner Next Page Register offset:8 */
|
||||
|
||||
/* 1000BASE-T Control Register offset:9 */
|
||||
/* Advertise 1000T HD capability */
|
||||
#define QCA8075_CTL_1000T_HD_CAPS 0x0100
|
||||
|
||||
/* Advertise 1000T FD capability */
|
||||
#define QCA8075_CTL_1000T_FD_CAPS 0x0200
|
||||
|
||||
/* 1=Repeater/switch device port 0=DTE device */
|
||||
#define QCA8075_CTL_1000T_REPEATER_DTE 0x0400
|
||||
|
||||
/* 1=Configure PHY as Master 0=Configure PHY as Slave */
|
||||
#define QCA8075_CTL_1000T_MS_VALUE 0x0800
|
||||
|
||||
/* 1=Master/Slave manual config value 0=Automatic Master/Slave config */
|
||||
#define QCA8075_CTL_1000T_MS_ENABLE 0x1000
|
||||
|
||||
/* Normal Operation */
|
||||
#define QCA8075_CTL_1000T_TEST_MODE_NORMAL 0x0000
|
||||
|
||||
/* Transmit Waveform test */
|
||||
#define QCA8075_CTL_1000T_TEST_MODE_1 0x2000
|
||||
|
||||
/* Master Transmit Jitter test */
|
||||
#define QCA8075_CTL_1000T_TEST_MODE_2 0x4000
|
||||
|
||||
/* Slave Transmit Jitter test */
|
||||
#define QCA8075_CTL_1000T_TEST_MODE_3 0x6000
|
||||
|
||||
/* Transmitter Distortion test */
|
||||
#define QCA8075_CTL_1000T_TEST_MODE_4 0x8000
|
||||
#define QCA8075_CTL_1000T_SPEED_MASK 0x0300
|
||||
#define QCA8075_CTL_1000T_DEFAULT_CAP_MASK 0x0300
|
||||
|
||||
/* 1000BASE-T Status Register offset:10 */
|
||||
/* LP is 1000T HD capable */
|
||||
#define QCA8075_STATUS_1000T_LP_HD_CAPS 0x0400
|
||||
|
||||
/* LP is 1000T FD capable */
|
||||
#define QCA8075_STATUS_1000T_LP_FD_CAPS 0x0800
|
||||
|
||||
/* Remote receiver OK */
|
||||
#define QCA8075_STATUS_1000T_REMOTE_RX_STATUS 0x1000
|
||||
|
||||
/* Local receiver OK */
|
||||
#define QCA8075_STATUS_1000T_LOCAL_RX_STATUS 0x2000
|
||||
|
||||
/* 1=Local TX is Master, 0=Slave */
|
||||
#define QCA8075_STATUS_1000T_MS_CONFIG_RES 0x4000
|
||||
|
||||
#define QCA8075_STATUS_1000T_MS_CONFIG_FAULT 0x8000
|
||||
|
||||
/* Master/Slave config fault */
|
||||
#define QCA8075_STATUS_1000T_REMOTE_RX_STATUS_SHIFT 12
|
||||
#define QCA8075_STATUS_1000T_LOCAL_RX_STATUS_SHIFT 13
|
||||
|
||||
/* Phy Specific Control Register offset:16 */
|
||||
/* 1=Jabber Function disabled */
|
||||
#define QCA8075_CTL_JABBER_DISABLE 0x0001
|
||||
|
||||
/* 1=Polarity Reversal enabled */
|
||||
#define QCA8075_CTL_POLARITY_REVERSAL 0x0002
|
||||
|
||||
/* 1=SQE Test enabled */
|
||||
#define QCA8075_CTL_SQE_TEST 0x0004
|
||||
#define QCA8075_CTL_MAC_POWERDOWN 0x0008
|
||||
|
||||
/* 1=CLK125 low, 0=CLK125 toggling
|
||||
#define QCA8075_CTL_CLK125_DISABLE 0x0010
|
||||
*/
|
||||
/* MDI Crossover Mode bits 6:5 */
|
||||
/* Manual MDI configuration */
|
||||
#define QCA8075_CTL_MDI_MANUAL_MODE 0x0000
|
||||
|
||||
/* Manual MDIX configuration */
|
||||
#define QCA8075_CTL_MDIX_MANUAL_MODE 0x0020
|
||||
|
||||
/* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */
|
||||
#define QCA8075_CTL_AUTO_X_1000T 0x0040
|
||||
|
||||
/* Auto crossover enabled all speeds */
|
||||
#define QCA8075_CTL_AUTO_X_MODE 0x0060
|
||||
|
||||
/* 1=Enable Extended 10BASE-T distance
|
||||
* (Lower 10BASE-T RX Threshold)
|
||||
* 0=Normal 10BASE-T RX Threshold */
|
||||
#define QCA8075_CTL_10BT_EXT_DIST_ENABLE 0x0080
|
||||
|
||||
/* 1=5-Bit interface in 100BASE-TX
|
||||
* 0=MII interface in 100BASE-TX */
|
||||
#define QCA8075_CTL_MII_5BIT_ENABLE 0x0100
|
||||
|
||||
/* 1=Scrambler disable */
|
||||
#define QCA8075_CTL_SCRAMBLER_DISABLE 0x0200
|
||||
|
||||
/* 1=Force link good */
|
||||
#define QCA8075_CTL_FORCE_LINK_GOOD 0x0400
|
||||
|
||||
/* 1=Assert CRS on Transmit */
|
||||
#define QCA8075_CTL_ASSERT_CRS_ON_TX 0x0800
|
||||
|
||||
#define QCA8075_CTL_POLARITY_REVERSAL_SHIFT 1
|
||||
#define QCA8075_CTL_AUTO_X_MODE_SHIFT 5
|
||||
#define QCA8075_CTL_10BT_EXT_DIST_ENABLE_SHIFT 7
|
||||
|
||||
|
||||
/* Phy Specific status fields offset:17 */
|
||||
/* 1=Speed & Duplex resolved */
|
||||
#define QCA8075_STATUS_LINK_PASS 0x0400
|
||||
#define QCA8075_STATUS_RESOVLED 0x0800
|
||||
|
||||
/* 1=Duplex 0=Half Duplex */
|
||||
#define QCA8075_STATUS_FULL_DUPLEX 0x2000
|
||||
|
||||
/* Speed, bits 14:15 */
|
||||
#define QCA8075_STATUS_SPEED 0xC000
|
||||
#define QCA8075_STATUS_SPEED_MASK 0xC000
|
||||
|
||||
/* 00=10Mbs */
|
||||
#define QCA8075_STATUS_SPEED_10MBS 0x0000
|
||||
|
||||
/* 01=100Mbs */
|
||||
#define QCA8075_STATUS_SPEED_100MBS 0x4000
|
||||
|
||||
/* 10=1000Mbs */
|
||||
#define QCA8075_STATUS_SPEED_1000MBS 0x8000
|
||||
#define QCA8075_SPEED_DUPLEX_RESOVLED(phy_status) \
|
||||
(((phy_status) & \
|
||||
(QCA8075_STATUS_RESOVLED)) == \
|
||||
(QCA8075_STATUS_RESOVLED))
|
||||
|
||||
/*phy debug port1 register offset:29 */
|
||||
/*phy debug port2 register offset:30 */
|
||||
|
||||
/*QCA8075 interrupt flag */
|
||||
#define QCA8075_INTR_SPEED_CHANGE 0x4000
|
||||
#define QCA8075_INTR_DUPLEX_CHANGE 0x2000
|
||||
#define QCA8075_INTR_STATUS_UP_CHANGE 0x0400
|
||||
#define QCA8075_INTR_STATUS_DOWN_CHANGE 0x0800
|
||||
#define QCA8075_INTR_BX_FX_STATUS_DOWN_CHANGE 0x0100
|
||||
#define QCA8075_INTR_BX_FX_STATUS_UP_CHANGE 0x0080
|
||||
#define QCA8075_INTR_MEDIA_STATUS_CHANGE 0x1000
|
||||
#define QCA8075_INTR_WOL 0x0001
|
||||
#define QCA8075_INTR_POE 0x0002
|
||||
|
||||
#define QCA8075_PHY_PSGMII_REDUCE_SERDES_TX_AMP 0x8a
|
||||
#define QCA8075_DAC_CTRL_MASK 0x380
|
||||
#define QCA8075_PHY_MMD7_DAC_CTRL 0x801a
|
||||
#define QCA8075_DAC_CTRL_VALUE 0x280
|
||||
#define QCA8075_PHY_MMD7_NUM 7
|
||||
#define QCA8075_PSGMII_TX_DRIVER_1_CTRL 0xb
|
||||
#define QCA8075_PHY_MMD7_LED_1000_CTRL1 0x8076
|
||||
#define QCA8075_LED_1000_CTRL1_100_10_MASK 0x30
|
||||
|
||||
#define RUN_CDT 0x8000
|
||||
#define CABLE_LENGTH_UNIT 0x0400
|
||||
#define QCA8075_MAX_TRIES 100
|
||||
|
||||
#endif /* _QCA8075_PHY_H_ */
|
||||
|
|
@ -32,7 +32,7 @@ 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);
|
||||
extern void ipq9574_qca8075_phy_serdes_reset(u32 phy_id);
|
||||
|
||||
void csr1_write(int phy_id, int addr, int value)
|
||||
{
|
||||
|
|
@ -197,7 +197,7 @@ static void ppe_uniphy_psgmii_mode_set(uint32_t uniphy_index)
|
|||
ppe_uniphy_reset(UNIPHY2_SOFT_RESET, false);
|
||||
}
|
||||
ppe_uniphy_calibration(uniphy_index);
|
||||
qca8075_phy_serdes_reset(0);
|
||||
ipq9574_qca8075_phy_serdes_reset(0x10);
|
||||
}
|
||||
|
||||
static void ppe_uniphy_qsgmii_mode_set(uint32_t uniphy_index)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue