Lines Matching +full:rx +full:- +full:pcs +full:- +full:input
1 // SPDX-License-Identifier: GPL-2.0
17 #include <linux/pcs-rzn1-miic.h>
23 #include <dt-bindings/net/pcs-rzn1-miic.h>
24 #include <dt-bindings/net/renesas,r9a09g077-pcs-miic.h>
56 #define MIIC_MODCTRL_CONF_NONE -1
61 * struct modctrl_match - Matching table entry for convctrl configuration
65 * then index 1 - 5 are CONV1 - CONV5 for RZ/N1 SoCs. In case
67 * index 0 - 3 are CONV0 - CONV3.
181 * struct miic - MII converter structure
184 * @lock: Lock used for read-modify-write access
197 * struct miic_of_data - OF data for MII converter
232 * struct miic_port - Per port MII converter struct
234 * @pcs: PCS structure associated to the port
240 struct phylink_pcs pcs; member
245 static struct miic_port *phylink_pcs_to_miic_port(struct phylink_pcs *pcs) in phylink_pcs_to_miic_port() argument
247 return container_of(pcs, struct miic_port, pcs); in phylink_pcs_to_miic_port()
253 writel(0x00A5, miic->base + MIIC_PRCMD); in miic_unlock_regs()
254 writel(0x0001, miic->base + MIIC_PRCMD); in miic_unlock_regs()
255 writel(0xFFFE, miic->base + MIIC_PRCMD); in miic_unlock_regs()
256 writel(0x0001, miic->base + MIIC_PRCMD); in miic_unlock_regs()
262 writel(0x0000, miic->base + MIIC_PRCMD); in miic_lock_regs()
267 writel(value, miic->base + offset); in miic_reg_writel_unlocked()
273 writel(value, miic->base + offset); in miic_reg_writel_locked()
279 miic->of_data->miic_write(miic, offset, value); in miic_reg_writel()
284 return readl(miic->base + offset); in miic_reg_readl()
291 spin_lock(&miic->lock); in miic_reg_rmw()
298 spin_unlock(&miic->lock); in miic_reg_rmw()
311 static int miic_config(struct phylink_pcs *pcs, unsigned int neg_mode, in miic_config() argument
315 struct miic_port *miic_port = phylink_pcs_to_miic_port(pcs); in miic_config()
316 struct miic *miic = miic_port->miic; in miic_config()
318 int port = miic_port->port; in miic_config()
340 return -EOPNOTSUPP; in miic_config()
350 if (interface != miic_port->interface) { in miic_config()
353 miic_port->interface = interface; in miic_config()
357 miic_converter_enable(miic, miic_port->port, 1); in miic_config()
362 static void miic_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, in miic_link_up() argument
365 struct miic_port *miic_port = phylink_pcs_to_miic_port(pcs); in miic_link_up()
366 struct miic *miic = miic_port->miic; in miic_link_up()
368 int port = miic_port->port; in miic_link_up()
373 /* No speed in MII through-mode */ in miic_link_up()
396 static int miic_pre_init(struct phylink_pcs *pcs) in miic_pre_init() argument
398 struct miic_port *miic_port = phylink_pcs_to_miic_port(pcs); in miic_pre_init()
399 struct miic *miic = miic_port->miic; in miic_pre_init()
402 /* Start RX clock if required */ in miic_pre_init()
403 if (pcs->rxc_always_on) { in miic_pre_init()
409 miic_port->interface = PHY_INTERFACE_MODE_RMII; in miic_pre_init()
415 miic_reg_rmw(miic, MIIC_CONVCTRL(miic_port->port), mask, val); in miic_pre_init()
417 miic_converter_enable(miic, miic_port->port, 1); in miic_pre_init()
439 return ERR_PTR(-ENODEV); in miic_create()
442 return ERR_PTR(-EINVAL); in miic_create()
444 /* The PCS pdev is attached to the parent node */ in miic_create()
447 return ERR_PTR(-ENODEV); in miic_create()
451 return ERR_PTR(-ENODEV); in miic_create()
458 put_device(&pdev->dev); in miic_create()
459 return ERR_PTR(-EPROBE_DEFER); in miic_create()
463 of_data = miic->of_data; in miic_create()
464 if (port > of_data->miic_port_max || port < of_data->miic_port_start) { in miic_create()
465 put_device(&pdev->dev); in miic_create()
466 return ERR_PTR(-EINVAL); in miic_create()
471 put_device(&pdev->dev); in miic_create()
472 return ERR_PTR(-ENOMEM); in miic_create()
475 device_link_add(dev, miic->dev, DL_FLAG_AUTOREMOVE_CONSUMER); in miic_create()
476 put_device(&pdev->dev); in miic_create()
478 miic_port->miic = miic; in miic_create()
479 miic_port->port = port - of_data->miic_port_start; in miic_create()
480 miic_port->pcs.ops = &miic_phylink_ops; in miic_create()
482 phy_interface_set_rgmii(miic_port->pcs.supported_interfaces); in miic_create()
483 __set_bit(PHY_INTERFACE_MODE_RMII, miic_port->pcs.supported_interfaces); in miic_create()
484 __set_bit(PHY_INTERFACE_MODE_MII, miic_port->pcs.supported_interfaces); in miic_create()
486 return &miic_port->pcs; in miic_create()
490 void miic_destroy(struct phylink_pcs *pcs) in miic_destroy() argument
492 struct miic_port *miic_port = phylink_pcs_to_miic_port(pcs); in miic_destroy()
494 miic_converter_enable(miic_port->miic, miic_port->port, 0); in miic_destroy()
501 u8 sw_mode_mask = miic->of_data->sw_mode_mask; in miic_init_hw()
505 * is going to be used in conjunction with the Cortex-M3, this sequence in miic_init_hw()
508 if (miic->of_data->init_unlock_lock_regs) in miic_init_hw()
511 /* TODO: Replace with FIELD_PREP() when compile-time constant in miic_init_hw()
517 for (port = 0; port < miic->of_data->miic_port_max; port++) { in miic_init_hw()
547 const struct miic_of_data *of_data = miic->of_data; in miic_dump_conf()
551 for (i = 0; i < of_data->conf_conv_count; i++) { in miic_dump_conf()
553 conf_name = of_data->conf_to_string[conf[i]]; in miic_dump_conf()
557 dev_err(miic->dev, "%s: %s\n", in miic_dump_conf()
558 of_data->index_to_string[i], conf_name); in miic_dump_conf()
564 const struct miic_of_data *of_data = miic->of_data; in miic_match_dt_conf()
568 for (i = 0; i < of_data->match_table_count; i++) { in miic_match_dt_conf()
569 table_entry = &of_data->match_table[i]; in miic_match_dt_conf()
571 if (miic_modctrl_match(table_entry->conv, dt_val, in miic_match_dt_conf()
572 miic->of_data->conf_conv_count)) { in miic_match_dt_conf()
573 *mode_cfg = table_entry->mode_cfg; in miic_match_dt_conf()
578 dev_err(miic->dev, "Failed to apply requested configuration\n"); in miic_match_dt_conf()
581 return -EINVAL; in miic_match_dt_conf()
586 struct device_node *np = miic->dev->of_node; in miic_parse_dt()
592 dt_val = kmalloc_array(miic->of_data->conf_conv_count, in miic_parse_dt()
595 return -ENOMEM; in miic_parse_dt()
599 if (of_property_read_u32(np, "renesas,miic-switch-portin", &conf) == 0) in miic_parse_dt()
607 port += !miic->of_data->miic_port_start; in miic_parse_dt()
608 if (of_property_read_u32(conv, "renesas,miic-input", &conf) == 0) in miic_parse_dt()
623 ret = reset_control_bulk_assert(miic->of_data->reset_count, miic->rsts); in miic_reset_control_bulk_assert()
625 dev_err(miic->dev, "failed to assert reset lines\n"); in miic_reset_control_bulk_assert()
630 const struct miic_of_data *of_data = miic->of_data; in miic_reset_control_init()
631 struct device *dev = miic->dev; in miic_reset_control_init()
635 if (!of_data->reset_count) in miic_reset_control_init()
638 for (i = 0; i < of_data->reset_count; i++) in miic_reset_control_init()
639 miic->rsts[i].id = of_data->reset_ids[i]; in miic_reset_control_init()
641 ret = devm_reset_control_bulk_get_exclusive(dev, of_data->reset_count, in miic_reset_control_init()
642 miic->rsts); in miic_reset_control_init()
647 ret = reset_control_bulk_deassert(of_data->reset_count, miic->rsts); in miic_reset_control_init()
662 struct device *dev = &pdev->dev; in miic_probe()
669 return -ENOMEM; in miic_probe()
671 miic->of_data = of_device_get_match_data(dev); in miic_probe()
672 miic->dev = dev; in miic_probe()
678 spin_lock_init(&miic->lock); in miic_probe()
679 miic->base = devm_platform_ioremap_resource(pdev, 0); in miic_probe()
680 if (IS_ERR(miic->base)) in miic_probe()
681 return PTR_ERR(miic->base); in miic_probe()
716 pm_runtime_put(&pdev->dev); in miic_remove()
751 { .compatible = "renesas,r9a09g077-miic", .data = &rzt2h_miic_of_data },
752 { .compatible = "renesas,rzn1-miic", .data = &rzn1_miic_of_data },
769 MODULE_DESCRIPTION("Renesas MII converter PCS driver");