mirror of
https://git.openwrt.org/openwrt/openwrt.git
synced 2026-02-20 08:41:20 +01:00
realtek: mdio: use helper for smi topology setup
On RTL930x, RTL931x and even RTL838x the smi topology is configured very similar. There is a bus mapping (RTL930x and RTL931x) and a port mapping (all three). Define a common helper that can take care of this setup and call it before bus registration. Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de> Link: https://github.com/openwrt/openwrt/pull/22008 Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
parent
4026f8843f
commit
afbbf21714
1 changed files with 38 additions and 44 deletions
|
|
@ -44,6 +44,7 @@
|
|||
#define RTMDIO_838X_SMI_ACCESS_PHY_CTRL_2 (0xa1c0)
|
||||
#define RTMDIO_838X_SMI_ACCESS_PHY_CTRL_3 (0xa1c4)
|
||||
#define RTMDIO_838X_SMI_POLL_CTRL (0xa17c)
|
||||
#define RTMDIO_838X_SMI_PORT0_5_ADDR_CTRL (0xa1c8)
|
||||
|
||||
#define RTMDIO_839X_CMD_FAIL BIT(1)
|
||||
#define RTMDIO_839X_CMD_READ_C22 0
|
||||
|
|
@ -77,7 +78,7 @@
|
|||
#define RTMDIO_930X_SMI_10G_POLLING_REG0_CFG (0xCBB4)
|
||||
#define RTMDIO_930X_SMI_10G_POLLING_REG9_CFG (0xCBB8)
|
||||
#define RTMDIO_930X_SMI_10G_POLLING_REG10_CFG (0xCBBC)
|
||||
#define RTMDIO_930X_SMI_PORT0_5_ADDR (0xCB80)
|
||||
#define RTMDIO_930X_SMI_PORT0_5_ADDR_CTRL (0xCB80)
|
||||
|
||||
#define RTMDIO_931X_CMD_FAIL BIT(1)
|
||||
#define RTMDIO_931X_CMD_READ_C22 0
|
||||
|
|
@ -96,7 +97,7 @@
|
|||
#define RTMDIO_931X_SMI_INDRT_ACCESS_MMD_CTRL (0x0C18)
|
||||
#define RTMDIO_931X_MAC_L2_GLOBAL_CTRL2 (0x1358)
|
||||
#define RTMDIO_931X_SMI_PORT_POLLING_SEL (0x0C9C)
|
||||
#define RTMDIO_931X_SMI_PORT_ADDR (0x0C74)
|
||||
#define RTMDIO_931X_SMI_PORT_ADDR_CTRL (0x0C74)
|
||||
#define RTMDIO_931X_SMI_10GPHY_POLLING_SEL0 (0x0CF0)
|
||||
#define RTMDIO_931X_SMI_10GPHY_POLLING_SEL1 (0x0CF4)
|
||||
#define RTMDIO_931X_SMI_10GPHY_POLLING_SEL2 (0x0CF8)
|
||||
|
|
@ -183,6 +184,8 @@ struct rtmdio_ctrl {
|
|||
struct rtmdio_config {
|
||||
int cpu_port;
|
||||
int raw_page;
|
||||
int bus_map_base;
|
||||
int port_map_base;
|
||||
int (*read_mmd_phy)(struct mii_bus *bus, u32 port, u32 addr, u32 reg, u32 *val);
|
||||
int (*read_phy)(struct mii_bus *bus, u32 port, u32 page, u32 reg, u32 *val);
|
||||
int (*reset)(struct mii_bus *bus);
|
||||
|
|
@ -558,6 +561,31 @@ static int rtmdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void rtmdio_setup_smi_topology(struct mii_bus *bus)
|
||||
{
|
||||
struct rtmdio_ctrl *ctrl = bus->priv;
|
||||
u32 reg, mask, val;
|
||||
|
||||
for (int addr = 0; addr < ctrl->cfg->cpu_port; addr++) {
|
||||
if (ctrl->smi_bus[addr] < 0)
|
||||
continue;
|
||||
|
||||
if (ctrl->cfg->bus_map_base) {
|
||||
reg = (addr / 16) * 4;
|
||||
mask = 0x3 << ((addr % 16) * 2);
|
||||
val = ctrl->smi_bus[addr] << ((addr % 16) * 2);
|
||||
regmap_update_bits(ctrl->map, ctrl->cfg->bus_map_base + reg, mask, val);
|
||||
}
|
||||
|
||||
if (ctrl->cfg->port_map_base) {
|
||||
reg = (addr / 6) * 4;
|
||||
mask = 0x1f << ((addr % 6) * 5);
|
||||
val = ctrl->smi_addr[addr] << ((addr % 6) * 5);
|
||||
regmap_update_bits(ctrl->map, ctrl->cfg->port_map_base + reg, mask, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static u32 rtmdio_get_phy_id(struct phy_device *phydev)
|
||||
{
|
||||
if (!phydev)
|
||||
|
|
@ -670,23 +698,7 @@ static int rtmdio_839x_reset(struct mii_bus *bus)
|
|||
static int rtmdio_930x_reset(struct mii_bus *bus)
|
||||
{
|
||||
struct rtmdio_ctrl *ctrl = bus->priv;
|
||||
unsigned int reg, mask, val;
|
||||
|
||||
/* Define bus topology */
|
||||
for (int addr = 0; addr < ctrl->cfg->cpu_port; addr++) {
|
||||
if (ctrl->smi_bus[addr] < 0)
|
||||
continue;
|
||||
|
||||
reg = (addr / 6) * 4;
|
||||
mask = 0x1f << ((addr % 6) * 5);
|
||||
val = ctrl->smi_addr[addr] << (ffs(mask) - 1);
|
||||
regmap_update_bits(ctrl->map, RTMDIO_930X_SMI_PORT0_5_ADDR + reg, mask, val);
|
||||
|
||||
reg = (addr / 16) * 4;
|
||||
mask = 0x3 << ((addr % 16) * 2);
|
||||
val = ctrl->smi_bus[addr] << (ffs(mask) - 1);
|
||||
regmap_update_bits(ctrl->map, RTMDIO_930X_SMI_PORT0_15_POLLING_SEL + reg, mask, val);
|
||||
}
|
||||
unsigned int mask, val;
|
||||
|
||||
/* Define C22/C45 bus feature set */
|
||||
for (int addr = 0; addr < RTMDIO_MAX_SMI_BUS; addr++) {
|
||||
|
|
@ -762,43 +774,18 @@ static void rtmdio_930x_setup_polling(struct mii_bus *bus)
|
|||
static int rtmdio_931x_reset(struct mii_bus *bus)
|
||||
{
|
||||
struct rtmdio_ctrl *ctrl = bus->priv;
|
||||
u32 poll_sel[4] = { 0 };
|
||||
u32 poll_ctrl = 0;
|
||||
u32 c45_mask = 0;
|
||||
|
||||
pr_info("%s called\n", __func__);
|
||||
/* Disable port polling for configuration purposes */
|
||||
regmap_write(ctrl->map, RTMDIO_931X_SMI_PORT_POLLING_CTRL, 0);
|
||||
regmap_write(ctrl->map, RTMDIO_931X_SMI_PORT_POLLING_CTRL + 4, 0);
|
||||
msleep(100);
|
||||
|
||||
/* Mapping of port to phy-addresses on an SMI bus */
|
||||
for (int addr = 0; addr < ctrl->cfg->cpu_port; addr++) {
|
||||
u32 pos;
|
||||
|
||||
if (ctrl->smi_bus[addr] < 0)
|
||||
continue;
|
||||
|
||||
pos = (addr % 6) * 5;
|
||||
regmap_update_bits(ctrl->map, RTMDIO_931X_SMI_PORT_ADDR + (addr / 6) * 4,
|
||||
0x1f << pos, ctrl->smi_addr[addr] << pos);
|
||||
pos = (addr * 2) % 32;
|
||||
poll_sel[addr / 16] |= ctrl->smi_bus[addr] << pos;
|
||||
poll_ctrl |= BIT(20 + ctrl->smi_bus[addr]);
|
||||
}
|
||||
|
||||
/* Configure which SMI bus is behind which port number */
|
||||
for (int i = 0; i < RTMDIO_MAX_SMI_BUS; i++) {
|
||||
pr_info("poll sel %d, %08x\n", i, poll_sel[i]);
|
||||
regmap_write(ctrl->map, RTMDIO_931X_SMI_PORT_POLLING_SEL + (i * 4), poll_sel[i]);
|
||||
}
|
||||
|
||||
/* Define C22/C45 bus feature set */
|
||||
for (int i = 0; i < RTMDIO_MAX_SMI_BUS; i++) {
|
||||
if (ctrl->smi_bus_isc45[i])
|
||||
c45_mask |= 0x2 << (i * 2); /* Std. C45, non-standard is 0x3 */
|
||||
}
|
||||
pr_info("%s: c45_mask: %08x", __func__, c45_mask);
|
||||
regmap_update_bits(ctrl->map, RTMDIO_931X_SMI_GLB_CTRL1, GENMASK(7, 0), c45_mask);
|
||||
|
||||
return 0;
|
||||
|
|
@ -948,6 +935,8 @@ static int rtmdio_probe(struct platform_device *pdev)
|
|||
snprintf(bus->id, MII_BUS_ID_SIZE, "realtek-mdio");
|
||||
|
||||
device_set_node(&bus->dev, of_fwnode_handle(dev->of_node));
|
||||
|
||||
rtmdio_setup_smi_topology(bus);
|
||||
ret = devm_mdiobus_register(dev, bus);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
@ -961,6 +950,7 @@ static int rtmdio_probe(struct platform_device *pdev)
|
|||
static const struct rtmdio_config rtmdio_838x_cfg = {
|
||||
.cpu_port = 28,
|
||||
.raw_page = 4095,
|
||||
.port_map_base = RTMDIO_838X_SMI_PORT0_5_ADDR_CTRL,
|
||||
.read_mmd_phy = rtmdio_838x_read_mmd_phy,
|
||||
.read_phy = rtmdio_838x_read_phy,
|
||||
.reset = rtmdio_838x_reset,
|
||||
|
|
@ -982,6 +972,8 @@ static const struct rtmdio_config rtmdio_839x_cfg = {
|
|||
static const struct rtmdio_config rtmdio_930x_cfg = {
|
||||
.cpu_port = 28,
|
||||
.raw_page = 4095,
|
||||
.bus_map_base = RTMDIO_930X_SMI_PORT0_15_POLLING_SEL,
|
||||
.port_map_base = RTMDIO_930X_SMI_PORT0_5_ADDR_CTRL,
|
||||
.read_mmd_phy = rtmdio_930x_read_mmd_phy,
|
||||
.read_phy = rtmdio_930x_read_phy,
|
||||
.reset = rtmdio_930x_reset,
|
||||
|
|
@ -993,6 +985,8 @@ static const struct rtmdio_config rtmdio_930x_cfg = {
|
|||
static const struct rtmdio_config rtmdio_931x_cfg = {
|
||||
.cpu_port = 56,
|
||||
.raw_page = 8191,
|
||||
.bus_map_base = RTMDIO_931X_SMI_PORT_POLLING_SEL,
|
||||
.port_map_base = RTMDIO_931X_SMI_PORT_ADDR_CTRL,
|
||||
.read_mmd_phy = rtmdio_931x_read_mmd_phy,
|
||||
.read_phy = rtmdio_931x_read_phy,
|
||||
.reset = rtmdio_931x_reset,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue