From f70575805708cabdedea7498aaa3f710fde4d920 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Wed, 31 Jan 2024 03:29:01 +0000 Subject: [PATCH] add lvds1024*800 --- kernel/drivers/net/phy/motorcomm.c | 215 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 201 insertions(+), 14 deletions(-) diff --git a/kernel/drivers/net/phy/motorcomm.c b/kernel/drivers/net/phy/motorcomm.c index 2469a6a..1fd72a3 100644 --- a/kernel/drivers/net/phy/motorcomm.c +++ b/kernel/drivers/net/phy/motorcomm.c @@ -8,9 +8,12 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/netdevice.h> +#include <linux/of_device.h> #include <linux/phy.h> #define PHY_ID_YT8511 0x0000010a +#define PHY_ID_YT8512 0x00000118 +#define PHY_ID_YT8512B 0x00000128 #define PHY_ID_YT8531S 0x4f51e91a #define PHY_ID_YT8531 0x4f51e91b @@ -40,6 +43,33 @@ #define YT8511_DELAY_GE_TX_DIS (0x2 << 4) #define YT8511_DELAY_FE_TX_EN (0xf << 12) #define YT8511_DELAY_FE_TX_DIS (0x2 << 12) + +#define YT8512_EXTREG_AFE_PLL 0x50 +#define YT8512_EXTREG_EXTEND_COMBO 0x4000 +#define YT8512_EXTREG_LED0 0x40c0 +#define YT8512_EXTREG_LED1 0x40c3 + +#define YT8512_EXTREG_SLEEP_CONTROL1 0x2027 + +#define YT_SOFTWARE_RESET 0x8000 + +#define YT8512_CONFIG_PLL_REFCLK_SEL_EN 0x0040 +#define YT8512_CONTROL1_RMII_EN 0x0001 +#define YT8512_LED0_ACT_BLK_IND 0x1000 +#define YT8512_LED0_DIS_LED_AN_TRY 0x0001 +#define YT8512_LED0_BT_BLK_EN 0x0002 +#define YT8512_LED0_HT_BLK_EN 0x0004 +#define YT8512_LED0_COL_BLK_EN 0x0008 +#define YT8512_LED0_BT_ON_EN 0x0010 +#define YT8512_LED1_BT_ON_EN 0x0010 +#define YT8512_LED1_TXACT_BLK_EN 0x0100 +#define YT8512_LED1_RXACT_BLK_EN 0x0200 +#define YT8512_SPEED_MODE 0xc000 +#define YT8512_DUPLEX 0x2000 + +#define YT8512_SPEED_MODE_BIT 14 +#define YT8512_DUPLEX_BIT 13 +#define YT8512_EN_SLEEP_SW_BIT 15 /* if system depends on ethernet packet to restore from sleep, * please define this macro to 1 otherwise, define it to 0. @@ -153,16 +183,6 @@ return phy_restore_page(phydev, oldpage, ret); } -static inline void phy_lock_mdio_bus(struct phy_device *phydev) -{ - mutex_lock(&phydev->mdio.bus->mdio_lock); -} - -static inline void phy_unlock_mdio_bus(struct phy_device *phydev) -{ - mutex_unlock(&phydev->mdio.bus->mdio_lock); -} - static u32 ytphy_read_ext(struct phy_device *phydev, u32 regnum) { int ret; @@ -212,6 +232,150 @@ return ret; return ret; +} + +static int yt8512_clk_init(struct phy_device *phydev) +{ + struct device_node *node = phydev->mdio.dev.of_node; + const char *strings = NULL; + int ret; + int val; + + if (node && node->parent && node->parent->parent) { + ret = of_property_read_string(node->parent->parent, + "clock_in_out", &strings); + if (!ret) { + if (!strcmp(strings, "input")) + return 0; + } + } + + val = ytphy_read_ext(phydev, YT8512_EXTREG_AFE_PLL); + if (val < 0) + return val; + + val |= YT8512_CONFIG_PLL_REFCLK_SEL_EN; + + ret = ytphy_write_ext(phydev, YT8512_EXTREG_AFE_PLL, val); + if (ret < 0) + return ret; + + val = ytphy_read_ext(phydev, YT8512_EXTREG_EXTEND_COMBO); + if (val < 0) + return val; + + val |= YT8512_CONTROL1_RMII_EN; + + ret = ytphy_write_ext(phydev, YT8512_EXTREG_EXTEND_COMBO, val); + if (ret < 0) + return ret; + + val = phy_read(phydev, MII_BMCR); + if (val < 0) + return val; + + val |= YT_SOFTWARE_RESET; + ret = phy_write(phydev, MII_BMCR, val); + + return ret; +} + +static int yt8512_led_init(struct phy_device *phydev) +{ + int ret; + int val; + int mask; + + val = ytphy_read_ext(phydev, YT8512_EXTREG_LED0); + if (val < 0) + return val; + + val |= YT8512_LED0_ACT_BLK_IND; + + mask = YT8512_LED0_DIS_LED_AN_TRY | YT8512_LED0_BT_BLK_EN | + YT8512_LED0_HT_BLK_EN | YT8512_LED0_COL_BLK_EN | + YT8512_LED0_BT_ON_EN; + val &= ~mask; + + ret = ytphy_write_ext(phydev, YT8512_EXTREG_LED0, val); + if (ret < 0) + return ret; + + val = ytphy_read_ext(phydev, YT8512_EXTREG_LED1); + if (val < 0) + return val; + + val |= YT8512_LED1_BT_ON_EN; + + mask = YT8512_LED1_TXACT_BLK_EN | YT8512_LED1_RXACT_BLK_EN; + val &= ~mask; + + ret = ytphy_write_ext(phydev, YT8512_LED1_BT_ON_EN, val); + + return ret; +} + +static int yt8512_config_init(struct phy_device *phydev) +{ + int ret; + int val; + + ret = yt8512_clk_init(phydev); + if (ret < 0) + return ret; + + ret = yt8512_led_init(phydev); + if (ret < 0) + return ret; + + /* disable auto sleep */ + val = ytphy_read_ext(phydev, YT8512_EXTREG_SLEEP_CONTROL1); + if (val < 0) + return val; + + val &= (~BIT(YT8512_EN_SLEEP_SW_BIT)); + + ret = ytphy_write_ext(phydev, YT8512_EXTREG_SLEEP_CONTROL1, val); + if (ret < 0) + return ret; + + return ret; +} + +static int yt8512_read_status(struct phy_device *phydev) +{ + int ret; + int val; + int speed, speed_mode, duplex; + + ret = genphy_update_link(phydev); + if (ret) + return ret; + + val = phy_read(phydev, REG_PHY_SPEC_STATUS); + if (val < 0) + return val; + + duplex = (val & YT8512_DUPLEX) >> YT8512_DUPLEX_BIT; + speed_mode = (val & YT8512_SPEED_MODE) >> YT8512_SPEED_MODE_BIT; + switch (speed_mode) { + case 0: + speed = SPEED_10; + break; + case 1: + speed = SPEED_100; + break; + case 2: + case 3: + default: + speed = SPEED_UNKNOWN; + break; + } + + phydev->speed = speed; + phydev->duplex = duplex; + + return 0; } static int yt8521_soft_reset(struct phy_device *phydev) @@ -573,7 +737,7 @@ static int yt8531_config_init(struct phy_device *phydev) { - int ret = 0; + int ret = 0, val; #if (YTPHY8531A_XTAL_INIT) ret = yt8531a_xtal_init(phydev); @@ -591,10 +755,17 @@ return ret; /* RXC, PHY_CLK_OUT and RXData Drive strength: - * Drive strength of RXC = 4, PHY_CLK_OUT = 3, RXD0 = 4 (default) - * If the io voltage is 3.3v, PHY_CLK_OUT = 2, set 0xa010 = 0x9acf + * Drive strength of RXC = 6, PHY_CLK_OUT = 3, RXD0 = 4 (default 1.8v) + * If the io voltage is 3.3v, PHY_CLK_OUT = 2, set 0xa010 = 0xdacf */ - ret = ytphy_write_ext(phydev, 0xa010, 0x9bcf); + ret = ytphy_write_ext(phydev, 0xa010, 0xdbcf); + if (ret < 0) + return ret; + + /* Change 100M default BGS voltage from 0x294c to 0x274c */ + val = ytphy_read_ext(phydev, 0x57); + val = (val & ~(0xf << 8)) | (7 << 8); + ret = ytphy_write_ext(phydev, 0x57, val); if (ret < 0) return ret; @@ -610,6 +781,20 @@ .resume = genphy_resume, .read_page = yt8511_read_page, .write_page = yt8511_write_page, + }, { + PHY_ID_MATCH_EXACT(PHY_ID_YT8512), + .name = "YT8512 Ethernet", + .config_init = yt8512_config_init, + .read_status = yt8512_read_status, + .suspend = genphy_suspend, + .resume = genphy_resume, + }, { + PHY_ID_MATCH_EXACT(PHY_ID_YT8512B), + .name = "YT8512B Ethernet", + .config_init = yt8512_config_init, + .read_status = yt8512_read_status, + .suspend = genphy_suspend, + .resume = genphy_resume, }, { /* same as 8521 */ PHY_ID_MATCH_EXACT(PHY_ID_YT8531S), @@ -648,6 +833,8 @@ static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = { { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) }, + { PHY_ID_MATCH_EXACT(PHY_ID_YT8512) }, + { PHY_ID_MATCH_EXACT(PHY_ID_YT8512B) }, { PHY_ID_MATCH_EXACT(PHY_ID_YT8531S) }, { PHY_ID_MATCH_EXACT(PHY_ID_YT8531) }, { /* sentinal */ } -- Gitblit v1.6.2