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

net: pcs: rzn1-miic: Add per-SoC control for MIIC register unlock/lock

Make MIIC accessory register unlock/lock behaviour selectable via SoC/OF
data. Add init_unlock_lock_regs and miic_write to struct miic_of_data so
the driver can either perform the traditional global unlock sequence (as
used on RZ/N1) or use a different policy for other SoCs (for example
RZ/T2H, which does not require leaving registers unlocked).

miic_reg_writel() now calls the per-SoC miic_write callback to perform
register writes. Provide miic_reg_writel_unlocked() as the default writer
and set it for the RZ/N1 OF data so existing platforms keep the same
behaviour. Add a miic_unlock_regs() helper that implements the accessory
register unlock sequence so the unlock/lock sequence can be reused where
needed (for example when a SoC requires explicit unlock/lock around
individual accesses).

This change is preparatory work for supporting RZ/T2H.

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-9-prabhakar.mahadev-lad.rj@bp.renesas.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Lad Prabhakar and committed by
Jakub Kicinski
41974731 882a8bb0

+24 -5
+24 -5
drivers/net/pcs/pcs-rzn1-miic.c
··· 155 155 * @sw_mode_mask: Switch mode mask 156 156 * @reset_ids: Reset names array 157 157 * @reset_count: Number of entries in the reset_ids array 158 + * @init_unlock_lock_regs: Flag to indicate if registers need to be unlocked 159 + * before access. 160 + * @miic_write: Function pointer to write a value to a MIIC register 158 161 */ 159 162 struct miic_of_data { 160 163 struct modctrl_match *match_table; ··· 172 169 u8 sw_mode_mask; 173 170 const char * const *reset_ids; 174 171 u8 reset_count; 172 + bool init_unlock_lock_regs; 173 + void (*miic_write)(struct miic *miic, int offset, u32 value); 175 174 }; 176 175 177 176 /** ··· 195 190 return container_of(pcs, struct miic_port, pcs); 196 191 } 197 192 198 - static void miic_reg_writel(struct miic *miic, int offset, u32 value) 193 + static void miic_unlock_regs(struct miic *miic) 194 + { 195 + /* Unprotect register writes */ 196 + writel(0x00A5, miic->base + MIIC_PRCMD); 197 + writel(0x0001, miic->base + MIIC_PRCMD); 198 + writel(0xFFFE, miic->base + MIIC_PRCMD); 199 + writel(0x0001, miic->base + MIIC_PRCMD); 200 + } 201 + 202 + static void miic_reg_writel_unlocked(struct miic *miic, int offset, u32 value) 199 203 { 200 204 writel(value, miic->base + offset); 205 + } 206 + 207 + static void miic_reg_writel(struct miic *miic, int offset, u32 value) 208 + { 209 + miic->of_data->miic_write(miic, offset, value); 201 210 } 202 211 203 212 static u32 miic_reg_readl(struct miic *miic, int offset) ··· 440 421 * is going to be used in conjunction with the Cortex-M3, this sequence 441 422 * will have to be moved in register write 442 423 */ 443 - miic_reg_writel(miic, MIIC_PRCMD, 0x00A5); 444 - miic_reg_writel(miic, MIIC_PRCMD, 0x0001); 445 - miic_reg_writel(miic, MIIC_PRCMD, 0xFFFE); 446 - miic_reg_writel(miic, MIIC_PRCMD, 0x0001); 424 + if (miic->of_data->init_unlock_lock_regs) 425 + miic_unlock_regs(miic); 447 426 448 427 /* TODO: Replace with FIELD_PREP() when compile-time constant 449 428 * restriction is lifted. Currently __ffs() returns 0 for sw_mode_mask. ··· 662 645 .miic_port_start = 1, 663 646 .miic_port_max = 5, 664 647 .sw_mode_mask = GENMASK(4, 0), 648 + .init_unlock_lock_regs = true, 649 + .miic_write = miic_reg_writel_unlocked, 665 650 }; 666 651 667 652 static const struct of_device_id miic_of_mtable[] = {