From: Lad Prabhakar Add support for the Renesas RZ/T2H MIIC by defining SoC-specific modctrl match tables, register map, and string representations for converters and ports. Signed-off-by: Lad Prabhakar --- v1->v2: - Dropped regx in config description. - Used "renesas,r9a09g077-miic" as compatible for RZ/T2H. --- drivers/net/pcs/Kconfig | 11 +++-- drivers/net/pcs/pcs-rzn1-miic.c | 82 +++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 5 deletions(-) diff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig index f6aa437473de..76dbc11d9575 100644 --- a/drivers/net/pcs/Kconfig +++ b/drivers/net/pcs/Kconfig @@ -26,11 +26,12 @@ config PCS_MTK_LYNXI which is part of MediaTek's SoC and Ethernet switch ICs. config PCS_RZN1_MIIC - tristate "Renesas RZ/N1 MII converter" - depends on OF && (ARCH_RZN1 || COMPILE_TEST) + tristate "Renesas RZ/N1, RZ/N2H, RZ/T2H MII converter" + depends on OF + depends on ARCH_RZN1 || ARCH_R9A09G077 || ARCH_R9A09G087 || COMPILE_TEST help - This module provides a driver for the MII converter that is available - on RZ/N1 SoCs. This PCS converts MII to RMII/RGMII or can be set in - pass-through mode for MII. + This module provides a driver for the MII converter available on + Renesas RZ/N1, RZ/N2H, and RZ/T2H SoCs. This PCS converts MII to + RMII/RGMII, or can be set in pass-through mode for MII. endmenu diff --git a/drivers/net/pcs/pcs-rzn1-miic.c b/drivers/net/pcs/pcs-rzn1-miic.c index 86d4dccd694e..5ec36bf042cd 100644 --- a/drivers/net/pcs/pcs-rzn1-miic.c +++ b/drivers/net/pcs/pcs-rzn1-miic.c @@ -21,6 +21,7 @@ #include #include #include +#include #define MIIC_PRCMD 0x0 #define MIIC_ESID_CODE 0x4 @@ -125,6 +126,57 @@ static const char * const index_to_string[] = { "CONV5", }; +static struct modctrl_match rzt2h_modctrl_match_table[] = { + {0x0, {ETHSS_GMAC0_PORT, ETHSS_ETHSW_PORT0, ETHSS_ETHSW_PORT1, + ETHSS_ETHSW_PORT2, ETHSS_GMAC1_PORT}}, + + {0x1, {MIIC_MODCTRL_CONF_NONE, ETHSS_ESC_PORT0, ETHSS_ESC_PORT1, + ETHSS_GMAC2_PORT, ETHSS_GMAC1_PORT}}, + + {0x2, {ETHSS_GMAC0_PORT, ETHSS_ESC_PORT0, ETHSS_ESC_PORT1, + ETHSS_ETHSW_PORT2, ETHSS_GMAC1_PORT}}, + + {0x3, {MIIC_MODCTRL_CONF_NONE, ETHSS_ESC_PORT0, ETHSS_ESC_PORT1, + ETHSS_ESC_PORT2, ETHSS_GMAC1_PORT}}, + + {0x4, {ETHSS_GMAC0_PORT, ETHSS_ETHSW_PORT0, ETHSS_ESC_PORT1, + ETHSS_ESC_PORT2, ETHSS_GMAC1_PORT}}, + + {0x5, {ETHSS_GMAC0_PORT, ETHSS_ETHSW_PORT0, ETHSS_ESC_PORT1, + ETHSS_ETHSW_PORT2, ETHSS_GMAC1_PORT}}, + + {0x6, {ETHSS_GMAC0_PORT, ETHSS_ETHSW_PORT0, ETHSS_ETHSW_PORT1, + ETHSS_GMAC2_PORT, ETHSS_GMAC1_PORT}}, + + {0x7, {MIIC_MODCTRL_CONF_NONE, ETHSS_GMAC0_PORT, ETHSS_GMAC1_PORT, + ETHSS_GMAC2_PORT, MIIC_MODCTRL_CONF_NONE}} +}; + +static const char * const rzt2h_conf_to_string[] = { + [ETHSS_GMAC0_PORT] = "GMAC0_PORT", + [ETHSS_GMAC1_PORT] = "GMAC1_PORT", + [ETHSS_GMAC2_PORT] = "GMAC2_PORT", + [ETHSS_ESC_PORT0] = "ETHERCAT_PORT0", + [ETHSS_ESC_PORT1] = "ETHERCAT_PORT1", + [ETHSS_ESC_PORT2] = "ETHERCAT_PORT2", + [ETHSS_ETHSW_PORT0] = "SWITCH_PORT0", + [ETHSS_ETHSW_PORT1] = "SWITCH_PORT1", + [ETHSS_ETHSW_PORT2] = "SWITCH_PORT2", +}; + +static const char * const rzt2h_index_to_string[] = { + "SWITCH_PORTIN", + "CONV0", + "CONV1", + "CONV2", + "CONV3", +}; + +static const char * const rzt2h_reset_ids[] = { + "rst", + "crst", +}; + /** * struct miic - MII converter structure * @base: base address of the MII converter @@ -203,11 +255,24 @@ static inline void miic_unlock_regs(struct miic *miic) writel(0x0001, miic->base + MIIC_PRCMD); } +static inline void miic_lock_regs(struct miic *miic) +{ + /* Protect register writes */ + writel(0x0000, miic->base + MIIC_PRCMD); +} + static void miic_reg_writel_unlocked(struct miic *miic, int offset, u32 value) { writel(value, miic->base + offset); } +static void miic_reg_writel_locked(struct miic *miic, int offset, u32 value) +{ + miic_unlock_regs(miic); + writel(value, miic->base + offset); + miic_lock_regs(miic); +} + static void miic_reg_writel(struct miic *miic, int offset, u32 value) { miic->of_data->miic_write(miic, offset, value); @@ -645,7 +710,24 @@ static struct miic_of_data rzn1_miic_of_data = { .miic_write = miic_reg_writel_unlocked, }; +static struct miic_of_data rzt2h_miic_of_data = { + .match_table = rzt2h_modctrl_match_table, + .match_table_count = ARRAY_SIZE(rzt2h_modctrl_match_table), + .conf_conv_count = 5, + .conf_to_string = rzt2h_conf_to_string, + .conf_to_string_count = ARRAY_SIZE(rzt2h_conf_to_string), + .index_to_string = rzt2h_index_to_string, + .index_to_string_count = ARRAY_SIZE(rzt2h_index_to_string), + .miic_port_start = 0, + .miic_port_max = 4, + .sw_mode_mask = GENMASK(2, 0), + .reset_ids = rzt2h_reset_ids, + .reset_count = ARRAY_SIZE(rzt2h_reset_ids), + .miic_write = miic_reg_writel_locked, +}; + static const struct of_device_id miic_of_mtable[] = { + { .compatible = "renesas,r9a09g077-miic", .data = &rzt2h_miic_of_data }, { .compatible = "renesas,rzn1-miic", .data = &rzn1_miic_of_data }, { /* sentinel */ } }; -- 2.51.0