0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/clk.h>
0013 #include <linux/clk-provider.h>
0014 #include <linux/device.h>
0015 #include <linux/init.h>
0016 #include <linux/io.h>
0017 #include <linux/module.h>
0018 #include <linux/of_device.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/pm.h>
0021 #include <linux/pm_runtime.h>
0022 #include <linux/reset.h>
0023 #include <linux/slab.h>
0024
0025 #define USB20_CLKSET0 0x00
0026 #define CLKSET0_INTCLK_EN BIT(11)
0027 #define CLKSET0_PRIVATE BIT(0)
0028 #define CLKSET0_EXTAL_ONLY (CLKSET0_INTCLK_EN | CLKSET0_PRIVATE)
0029
0030 static const struct clk_bulk_data rcar_usb2_clocks[] = {
0031 { .id = "ehci_ohci", },
0032 { .id = "hs-usb-if", },
0033 };
0034
0035 struct usb2_clock_sel_priv {
0036 void __iomem *base;
0037 struct clk_hw hw;
0038 struct clk_bulk_data clks[ARRAY_SIZE(rcar_usb2_clocks)];
0039 struct reset_control *rsts;
0040 bool extal;
0041 bool xtal;
0042 };
0043 #define to_priv(_hw) container_of(_hw, struct usb2_clock_sel_priv, hw)
0044
0045 static void usb2_clock_sel_enable_extal_only(struct usb2_clock_sel_priv *priv)
0046 {
0047 u16 val = readw(priv->base + USB20_CLKSET0);
0048
0049 pr_debug("%s: enter %d %d %x\n", __func__,
0050 priv->extal, priv->xtal, val);
0051
0052 if (priv->extal && !priv->xtal && val != CLKSET0_EXTAL_ONLY)
0053 writew(CLKSET0_EXTAL_ONLY, priv->base + USB20_CLKSET0);
0054 }
0055
0056 static void usb2_clock_sel_disable_extal_only(struct usb2_clock_sel_priv *priv)
0057 {
0058 if (priv->extal && !priv->xtal)
0059 writew(CLKSET0_PRIVATE, priv->base + USB20_CLKSET0);
0060 }
0061
0062 static int usb2_clock_sel_enable(struct clk_hw *hw)
0063 {
0064 struct usb2_clock_sel_priv *priv = to_priv(hw);
0065 int ret;
0066
0067 ret = reset_control_deassert(priv->rsts);
0068 if (ret)
0069 return ret;
0070
0071 ret = clk_bulk_prepare_enable(ARRAY_SIZE(priv->clks), priv->clks);
0072 if (ret) {
0073 reset_control_assert(priv->rsts);
0074 return ret;
0075 }
0076
0077 usb2_clock_sel_enable_extal_only(priv);
0078
0079 return 0;
0080 }
0081
0082 static void usb2_clock_sel_disable(struct clk_hw *hw)
0083 {
0084 struct usb2_clock_sel_priv *priv = to_priv(hw);
0085
0086 usb2_clock_sel_disable_extal_only(priv);
0087
0088 clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clks), priv->clks);
0089 reset_control_assert(priv->rsts);
0090 }
0091
0092
0093
0094
0095
0096
0097
0098 static const struct clk_ops usb2_clock_sel_clock_ops = {
0099 .enable = usb2_clock_sel_enable,
0100 .disable = usb2_clock_sel_disable,
0101 };
0102
0103 static const struct of_device_id rcar_usb2_clock_sel_match[] = {
0104 { .compatible = "renesas,rcar-gen3-usb2-clock-sel" },
0105 { }
0106 };
0107
0108 static int rcar_usb2_clock_sel_suspend(struct device *dev)
0109 {
0110 struct usb2_clock_sel_priv *priv = dev_get_drvdata(dev);
0111
0112 usb2_clock_sel_disable_extal_only(priv);
0113 pm_runtime_put(dev);
0114
0115 return 0;
0116 }
0117
0118 static int rcar_usb2_clock_sel_resume(struct device *dev)
0119 {
0120 struct usb2_clock_sel_priv *priv = dev_get_drvdata(dev);
0121
0122 pm_runtime_get_sync(dev);
0123 usb2_clock_sel_enable_extal_only(priv);
0124
0125 return 0;
0126 }
0127
0128 static int rcar_usb2_clock_sel_remove(struct platform_device *pdev)
0129 {
0130 struct device *dev = &pdev->dev;
0131
0132 of_clk_del_provider(dev->of_node);
0133 pm_runtime_put(dev);
0134 pm_runtime_disable(dev);
0135
0136 return 0;
0137 }
0138
0139 static int rcar_usb2_clock_sel_probe(struct platform_device *pdev)
0140 {
0141 struct device *dev = &pdev->dev;
0142 struct device_node *np = dev->of_node;
0143 struct usb2_clock_sel_priv *priv;
0144 struct clk *clk;
0145 struct clk_init_data init = {};
0146 int ret;
0147
0148 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0149 if (!priv)
0150 return -ENOMEM;
0151
0152 priv->base = devm_platform_ioremap_resource(pdev, 0);
0153 if (IS_ERR(priv->base))
0154 return PTR_ERR(priv->base);
0155
0156 memcpy(priv->clks, rcar_usb2_clocks, sizeof(priv->clks));
0157 ret = devm_clk_bulk_get(dev, ARRAY_SIZE(priv->clks), priv->clks);
0158 if (ret < 0)
0159 return ret;
0160
0161 priv->rsts = devm_reset_control_array_get_shared(dev);
0162 if (IS_ERR(priv->rsts))
0163 return PTR_ERR(priv->rsts);
0164
0165 clk = devm_clk_get(dev, "usb_extal");
0166 if (!IS_ERR(clk) && !clk_prepare_enable(clk)) {
0167 priv->extal = !!clk_get_rate(clk);
0168 clk_disable_unprepare(clk);
0169 }
0170 clk = devm_clk_get(dev, "usb_xtal");
0171 if (!IS_ERR(clk) && !clk_prepare_enable(clk)) {
0172 priv->xtal = !!clk_get_rate(clk);
0173 clk_disable_unprepare(clk);
0174 }
0175
0176 if (!priv->extal && !priv->xtal) {
0177 dev_err(dev, "This driver needs usb_extal or usb_xtal\n");
0178 return -ENOENT;
0179 }
0180
0181 pm_runtime_enable(dev);
0182 pm_runtime_get_sync(dev);
0183 platform_set_drvdata(pdev, priv);
0184 dev_set_drvdata(dev, priv);
0185
0186 init.name = "rcar_usb2_clock_sel";
0187 init.ops = &usb2_clock_sel_clock_ops;
0188 priv->hw.init = &init;
0189
0190 ret = devm_clk_hw_register(dev, &priv->hw);
0191 if (ret)
0192 goto pm_put;
0193
0194 ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &priv->hw);
0195 if (ret)
0196 goto pm_put;
0197
0198 return 0;
0199
0200 pm_put:
0201 pm_runtime_put(dev);
0202 pm_runtime_disable(dev);
0203 return ret;
0204 }
0205
0206 static const struct dev_pm_ops rcar_usb2_clock_sel_pm_ops = {
0207 .suspend = rcar_usb2_clock_sel_suspend,
0208 .resume = rcar_usb2_clock_sel_resume,
0209 };
0210
0211 static struct platform_driver rcar_usb2_clock_sel_driver = {
0212 .driver = {
0213 .name = "rcar-usb2-clock-sel",
0214 .of_match_table = rcar_usb2_clock_sel_match,
0215 .pm = &rcar_usb2_clock_sel_pm_ops,
0216 },
0217 .probe = rcar_usb2_clock_sel_probe,
0218 .remove = rcar_usb2_clock_sel_remove,
0219 };
0220 builtin_platform_driver(rcar_usb2_clock_sel_driver);
0221
0222 MODULE_DESCRIPTION("Renesas R-Car USB2 clock selector Driver");
0223 MODULE_LICENSE("GPL v2");