Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: pcs: rzn1-miic: Add RZ/T2H MIIC support

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 <prabhakar.mahadev-lad.rj@bp.renesas.com>
Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Link: https://patch.msgid.link/20250910204132.319975-10-prabhakar.mahadev-lad.rj@bp.renesas.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Lad Prabhakar and committed by
Jakub Kicinski
08f89e42 41974731

+88 -5
+6 -5
drivers/net/pcs/Kconfig
··· 26 26 which is part of MediaTek's SoC and Ethernet switch ICs. 27 27 28 28 config PCS_RZN1_MIIC 29 - tristate "Renesas RZ/N1 MII converter" 30 - depends on OF && (ARCH_RZN1 || COMPILE_TEST) 29 + tristate "Renesas RZ/N1, RZ/N2H, RZ/T2H MII converter" 30 + depends on OF 31 + depends on ARCH_RZN1 || ARCH_R9A09G077 || ARCH_R9A09G087 || COMPILE_TEST 31 32 help 32 - This module provides a driver for the MII converter that is available 33 - on RZ/N1 SoCs. This PCS converts MII to RMII/RGMII or can be set in 34 - pass-through mode for MII. 33 + This module provides a driver for the MII converter available on 34 + Renesas RZ/N1, RZ/N2H, and RZ/T2H SoCs. This PCS converts MII to 35 + RMII/RGMII, or can be set in pass-through mode for MII. 35 36 36 37 endmenu
+82
drivers/net/pcs/pcs-rzn1-miic.c
··· 21 21 #include <linux/reset.h> 22 22 #include <linux/slab.h> 23 23 #include <dt-bindings/net/pcs-rzn1-miic.h> 24 + #include <dt-bindings/net/renesas,r9a09g077-pcs-miic.h> 24 25 25 26 #define MIIC_PRCMD 0x0 26 27 #define MIIC_ESID_CODE 0x4 ··· 126 125 "CONV5", 127 126 }; 128 127 128 + static struct modctrl_match rzt2h_modctrl_match_table[] = { 129 + {0x0, {ETHSS_GMAC0_PORT, ETHSS_ETHSW_PORT0, ETHSS_ETHSW_PORT1, 130 + ETHSS_ETHSW_PORT2, ETHSS_GMAC1_PORT}}, 131 + 132 + {0x1, {MIIC_MODCTRL_CONF_NONE, ETHSS_ESC_PORT0, ETHSS_ESC_PORT1, 133 + ETHSS_GMAC2_PORT, ETHSS_GMAC1_PORT}}, 134 + 135 + {0x2, {ETHSS_GMAC0_PORT, ETHSS_ESC_PORT0, ETHSS_ESC_PORT1, 136 + ETHSS_ETHSW_PORT2, ETHSS_GMAC1_PORT}}, 137 + 138 + {0x3, {MIIC_MODCTRL_CONF_NONE, ETHSS_ESC_PORT0, ETHSS_ESC_PORT1, 139 + ETHSS_ESC_PORT2, ETHSS_GMAC1_PORT}}, 140 + 141 + {0x4, {ETHSS_GMAC0_PORT, ETHSS_ETHSW_PORT0, ETHSS_ESC_PORT1, 142 + ETHSS_ESC_PORT2, ETHSS_GMAC1_PORT}}, 143 + 144 + {0x5, {ETHSS_GMAC0_PORT, ETHSS_ETHSW_PORT0, ETHSS_ESC_PORT1, 145 + ETHSS_ETHSW_PORT2, ETHSS_GMAC1_PORT}}, 146 + 147 + {0x6, {ETHSS_GMAC0_PORT, ETHSS_ETHSW_PORT0, ETHSS_ETHSW_PORT1, 148 + ETHSS_GMAC2_PORT, ETHSS_GMAC1_PORT}}, 149 + 150 + {0x7, {MIIC_MODCTRL_CONF_NONE, ETHSS_GMAC0_PORT, ETHSS_GMAC1_PORT, 151 + ETHSS_GMAC2_PORT, MIIC_MODCTRL_CONF_NONE}} 152 + }; 153 + 154 + static const char * const rzt2h_conf_to_string[] = { 155 + [ETHSS_GMAC0_PORT] = "GMAC0_PORT", 156 + [ETHSS_GMAC1_PORT] = "GMAC1_PORT", 157 + [ETHSS_GMAC2_PORT] = "GMAC2_PORT", 158 + [ETHSS_ESC_PORT0] = "ETHERCAT_PORT0", 159 + [ETHSS_ESC_PORT1] = "ETHERCAT_PORT1", 160 + [ETHSS_ESC_PORT2] = "ETHERCAT_PORT2", 161 + [ETHSS_ETHSW_PORT0] = "SWITCH_PORT0", 162 + [ETHSS_ETHSW_PORT1] = "SWITCH_PORT1", 163 + [ETHSS_ETHSW_PORT2] = "SWITCH_PORT2", 164 + }; 165 + 166 + static const char * const rzt2h_index_to_string[] = { 167 + "SWITCH_PORTIN", 168 + "CONV0", 169 + "CONV1", 170 + "CONV2", 171 + "CONV3", 172 + }; 173 + 174 + static const char * const rzt2h_reset_ids[] = { 175 + "rst", 176 + "crst", 177 + }; 178 + 129 179 /** 130 180 * struct miic - MII converter structure 131 181 * @base: base address of the MII converter ··· 256 204 writel(0x0001, miic->base + MIIC_PRCMD); 257 205 } 258 206 207 + static void miic_lock_regs(struct miic *miic) 208 + { 209 + /* Protect register writes */ 210 + writel(0x0000, miic->base + MIIC_PRCMD); 211 + } 212 + 259 213 static void miic_reg_writel_unlocked(struct miic *miic, int offset, u32 value) 260 214 { 261 215 writel(value, miic->base + offset); 216 + } 217 + 218 + static void miic_reg_writel_locked(struct miic *miic, int offset, u32 value) 219 + { 220 + miic_unlock_regs(miic); 221 + writel(value, miic->base + offset); 222 + miic_lock_regs(miic); 262 223 } 263 224 264 225 static void miic_reg_writel(struct miic *miic, int offset, u32 value) ··· 731 666 .miic_write = miic_reg_writel_unlocked, 732 667 }; 733 668 669 + static struct miic_of_data rzt2h_miic_of_data = { 670 + .match_table = rzt2h_modctrl_match_table, 671 + .match_table_count = ARRAY_SIZE(rzt2h_modctrl_match_table), 672 + .conf_conv_count = 5, 673 + .conf_to_string = rzt2h_conf_to_string, 674 + .conf_to_string_count = ARRAY_SIZE(rzt2h_conf_to_string), 675 + .index_to_string = rzt2h_index_to_string, 676 + .index_to_string_count = ARRAY_SIZE(rzt2h_index_to_string), 677 + .miic_port_start = 0, 678 + .miic_port_max = 4, 679 + .sw_mode_mask = GENMASK(2, 0), 680 + .reset_ids = rzt2h_reset_ids, 681 + .reset_count = ARRAY_SIZE(rzt2h_reset_ids), 682 + .miic_write = miic_reg_writel_locked, 683 + }; 684 + 734 685 static const struct of_device_id miic_of_mtable[] = { 686 + { .compatible = "renesas,r9a09g077-miic", .data = &rzt2h_miic_of_data }, 735 687 { .compatible = "renesas,rzn1-miic", .data = &rzn1_miic_of_data }, 736 688 { /* sentinel */ } 737 689 };