ethernet: setup tx_amp from efuse [1/1]

PD#SWPL-3552

Problem:
tx_v show different for each chip

Solution:
add new function to setup

Verify:
co-work with analog on G12B SOCKET board

Change-Id: I1f2711b9414464c7044efc3f3128cc3c3808cfc5
Signed-off-by: Zhuo Wang <zhuo.wang@amlogic.com>
This commit is contained in:
Zhuo Wang
2018-12-25 16:16:50 +08:00
committed by Luan Yuan
parent 1a9acf1676
commit 24c730912e
2 changed files with 93 additions and 2 deletions

View File

@@ -31,6 +31,7 @@
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/phy.h>
#include <linux/amlogic/scpi_protocol.h>
#define SMI_ADDR_TSTWRITE 23
@@ -105,7 +106,76 @@ void internal_config(struct phy_device *phydev)
phy_write(phydev, 0x14, 0x441A); /* A8_CONFIG */
pr_info("internal phy init\n");
}
/*fetch tx_amp from uboot*/
#if 0
int myAtoi(char *str)
{
int i = 0;
int res = 0;
for (i = 0; str[i] != '\0'; ++i)
res = res*10 + str[i] - '0';
return res;
}
#endif
unsigned int tx_amp;
module_param_named(tx_amp, tx_amp,
uint, 0644);
static char tx_amp_str[5] = "0";
static int __init get_tx_amp(char *s)
{
int ret = 0;
if (s != NULL)
sprintf(tx_amp_str, "%s", s);
if (strcmp(tx_amp_str, "0") == 0)
tx_amp = 0;
else
ret = kstrtouint(tx_amp_str, 0, &tx_amp);
return 0;
}
__setup("tx_amp=", get_tx_amp);
void custom_internal_config(struct phy_device *phydev)
{
unsigned int efuse_valid = 0;
unsigned int env_valid = 0;
unsigned int efuse_amp = 0;
unsigned int setup_amp = 0;
/*we will setup env tx_amp first to debug,
*if env tx_amp ==0 we will use the efuse
*/
efuse_amp = scpi_get_ethernet_calc();
efuse_valid = (efuse_amp >> 3);
env_valid = (tx_amp >> 7);
if (env_valid || efuse_valid) {
/*env valid use env tx_amp*/
if (env_valid) {
/*debug mode use env tx_amp*/
setup_amp = tx_amp & (~0x80);
pr_info("debug mode tx_amp = %d\n", setup_amp);
} else {
/* efuse is valid but env not*/
setup_amp = efuse_amp;
pr_info("use efuse tx_amp = %d\n", setup_amp);
}
/*Enable Analog and DSP register Bank access by*/
phy_write(phydev, 0x14, 0x0000);
phy_write(phydev, 0x14, 0x0400);
phy_write(phydev, 0x14, 0x0000);
phy_write(phydev, 0x14, 0x0400);
phy_write(phydev, 0x17, setup_amp);
phy_write(phydev, 0x14, 0x4418);
pr_info("set phy setup_amp = %d\n", setup_amp);
} else {
/*env not set, efuse not valid return*/
pr_info("env not set, efuse also invalid\n");
}
}
void reset_internal_phy(struct phy_device *phydev)
{
int value;
@@ -243,6 +313,11 @@ static int internal_config_init(struct phy_device *phydev)
return genphy_config_init(phydev);
}
static int custom_internal_config_init(struct phy_device *phydev)
{
custom_internal_config(phydev);
return genphy_config_init(phydev);
}
unsigned int support_internal_phy_wol;
int internal_phy_suspend(struct phy_device *phydev)
{
@@ -284,7 +359,8 @@ void internal_phy_remove(struct phy_device *phydev)
value = phy_read(phydev, 0x18);
phy_write(phydev, 0x18, value | 0x1);
}
static struct phy_driver amlogic_internal_driver[] = { {
static struct phy_driver amlogic_internal_driver[] = {
{
.phy_id = 0x01814400,
.name = "amlogic internal phy",
.phy_id_mask = 0x0fffffff,
@@ -297,12 +373,27 @@ static struct phy_driver amlogic_internal_driver[] = { {
.suspend = internal_phy_suspend,
.resume = internal_phy_resume,
.remove = internal_phy_remove,
}, {
.phy_id = 0x01803301,
.name = "custom internal phy",
.phy_id_mask = 0x0fffffff,
.config_init = custom_internal_config_init,
/*1 means power down reset, 0 means marm reset*/
/*bit 0-7,value f:count_sec=15*/
.features = 0x10f,
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
.suspend = genphy_suspend,
.resume = genphy_resume,
.remove = internal_phy_remove,
} };
module_phy_driver(amlogic_internal_driver);
static struct mdio_device_id __maybe_unused amlogic_tbl[] = {
{ 0x01814400, 0xfffffff0 },
{ 0x01803301, 0xfffffff0 },
{ }
};

View File

@@ -233,7 +233,7 @@ static int dwmac_meson_cfg_ctrl(void __iomem *base_addr)
/*config phyid should between a 0~0xffffffff*/
/*please don't use 44000181, this has been used by internal phy*/
writel(0x33000180, ETH_PHY_config_addr + ETH_PHY_CNTL0);
writel(0x33010180, ETH_PHY_config_addr + ETH_PHY_CNTL0);
/*use_phy_smi | use_phy_ip | co_clkin from eth_phy_top*/
writel(0x260, ETH_PHY_config_addr + ETH_PHY_CNTL2);