1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Renesas RZ/G2L USBPHY control driver 4 * 5 * Copyright (C) 2021 Renesas Electronics Corporation 6 */ 7 8 #include <linux/io.h> 9 #include <linux/module.h> 10 #include <linux/of.h> 11 #include <linux/platform_device.h> 12 #include <linux/pm_runtime.h> 13 #include <linux/reset.h> 14 #include <linux/reset-controller.h> 15 16 #define RESET 0x000 17 18 #define RESET_SEL_PLLRESET BIT(12) 19 #define RESET_PLLRESET BIT(8) 20 21 #define RESET_SEL_P2RESET BIT(5) 22 #define RESET_SEL_P1RESET BIT(4) 23 #define RESET_PHYRST_2 BIT(1) 24 #define RESET_PHYRST_1 BIT(0) 25 26 #define PHY_RESET_PORT2 (RESET_SEL_P2RESET | RESET_PHYRST_2) 27 #define PHY_RESET_PORT1 (RESET_SEL_P1RESET | RESET_PHYRST_1) 28 29 #define NUM_PORTS 2 30 31 struct rzg2l_usbphy_ctrl_priv { 32 struct reset_controller_dev rcdev; 33 struct reset_control *rstc; 34 void __iomem *base; 35 36 spinlock_t lock; 37 }; 38 39 #define rcdev_to_priv(x) container_of(x, struct rzg2l_usbphy_ctrl_priv, rcdev) 40 41 static int rzg2l_usbphy_ctrl_assert(struct reset_controller_dev *rcdev, 42 unsigned long id) 43 { 44 struct rzg2l_usbphy_ctrl_priv *priv = rcdev_to_priv(rcdev); 45 u32 port_mask = PHY_RESET_PORT1 | PHY_RESET_PORT2; 46 void __iomem *base = priv->base; 47 unsigned long flags; 48 u32 val; 49 50 spin_lock_irqsave(&priv->lock, flags); 51 val = readl(base + RESET); 52 val |= id ? PHY_RESET_PORT2 : PHY_RESET_PORT1; 53 if (port_mask == (val & port_mask)) 54 val |= RESET_PLLRESET; 55 writel(val, base + RESET); 56 spin_unlock_irqrestore(&priv->lock, flags); 57 58 return 0; 59 } 60 61 static int rzg2l_usbphy_ctrl_deassert(struct reset_controller_dev *rcdev, 62 unsigned long id) 63 { 64 struct rzg2l_usbphy_ctrl_priv *priv = rcdev_to_priv(rcdev); 65 void __iomem *base = priv->base; 66 unsigned long flags; 67 u32 val; 68 69 spin_lock_irqsave(&priv->lock, flags); 70 val = readl(base + RESET); 71 72 val |= RESET_SEL_PLLRESET; 73 val &= ~(RESET_PLLRESET | (id ? PHY_RESET_PORT2 : PHY_RESET_PORT1)); 74 writel(val, base + RESET); 75 spin_unlock_irqrestore(&priv->lock, flags); 76 77 return 0; 78 } 79 80 static int rzg2l_usbphy_ctrl_status(struct reset_controller_dev *rcdev, 81 unsigned long id) 82 { 83 struct rzg2l_usbphy_ctrl_priv *priv = rcdev_to_priv(rcdev); 84 u32 port_mask; 85 86 port_mask = id ? PHY_RESET_PORT2 : PHY_RESET_PORT1; 87 88 return !!(readl(priv->base + RESET) & port_mask); 89 } 90 91 static const struct of_device_id rzg2l_usbphy_ctrl_match_table[] = { 92 { .compatible = "renesas,rzg2l-usbphy-ctrl" }, 93 { /* Sentinel */ } 94 }; 95 MODULE_DEVICE_TABLE(of, rzg2l_usbphy_ctrl_match_table); 96 97 static const struct reset_control_ops rzg2l_usbphy_ctrl_reset_ops = { 98 .assert = rzg2l_usbphy_ctrl_assert, 99 .deassert = rzg2l_usbphy_ctrl_deassert, 100 .status = rzg2l_usbphy_ctrl_status, 101 }; 102 103 static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev) 104 { 105 struct device *dev = &pdev->dev; 106 struct rzg2l_usbphy_ctrl_priv *priv; 107 unsigned long flags; 108 int error; 109 u32 val; 110 111 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 112 if (!priv) 113 return -ENOMEM; 114 115 priv->base = devm_platform_ioremap_resource(pdev, 0); 116 if (IS_ERR(priv->base)) 117 return PTR_ERR(priv->base); 118 119 priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); 120 if (IS_ERR(priv->rstc)) 121 return dev_err_probe(dev, PTR_ERR(priv->rstc), 122 "failed to get reset\n"); 123 124 reset_control_deassert(priv->rstc); 125 126 priv->rcdev.ops = &rzg2l_usbphy_ctrl_reset_ops; 127 priv->rcdev.of_reset_n_cells = 1; 128 priv->rcdev.nr_resets = NUM_PORTS; 129 priv->rcdev.of_node = dev->of_node; 130 priv->rcdev.dev = dev; 131 132 error = devm_reset_controller_register(dev, &priv->rcdev); 133 if (error) 134 return error; 135 136 spin_lock_init(&priv->lock); 137 dev_set_drvdata(dev, priv); 138 139 pm_runtime_enable(&pdev->dev); 140 pm_runtime_resume_and_get(&pdev->dev); 141 142 /* put pll and phy into reset state */ 143 spin_lock_irqsave(&priv->lock, flags); 144 val = readl(priv->base + RESET); 145 val |= RESET_SEL_PLLRESET | RESET_PLLRESET | PHY_RESET_PORT2 | PHY_RESET_PORT1; 146 writel(val, priv->base + RESET); 147 spin_unlock_irqrestore(&priv->lock, flags); 148 149 return 0; 150 } 151 152 static int rzg2l_usbphy_ctrl_remove(struct platform_device *pdev) 153 { 154 struct rzg2l_usbphy_ctrl_priv *priv = dev_get_drvdata(&pdev->dev); 155 156 pm_runtime_put(&pdev->dev); 157 pm_runtime_disable(&pdev->dev); 158 reset_control_assert(priv->rstc); 159 160 return 0; 161 } 162 163 static struct platform_driver rzg2l_usbphy_ctrl_driver = { 164 .driver = { 165 .name = "rzg2l_usbphy_ctrl", 166 .of_match_table = rzg2l_usbphy_ctrl_match_table, 167 }, 168 .probe = rzg2l_usbphy_ctrl_probe, 169 .remove = rzg2l_usbphy_ctrl_remove, 170 }; 171 module_platform_driver(rzg2l_usbphy_ctrl_driver); 172 173 MODULE_LICENSE("GPL v2"); 174 MODULE_DESCRIPTION("Renesas RZ/G2L USBPHY Control"); 175 MODULE_AUTHOR("biju.das.jz@bp.renesas.com>"); 176