Message ID | 1495628244-28406-1-git-send-email-yoshihiro.shimoda.uh@renesas.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Geert Uytterhoeven |
Headers | show |
Hi Shimoda-san, On Wed, May 24, 2017 at 2:17 PM, Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> wrote: > The USB 3.0 PHY modules of R-Car Gen3 SoCs have: > - Spread spectrum clock (ssc). > - Using USB 2.0 EXTAL clock instead of USB 3.0 clock. > - Enabling VBUS detection for usb3.0 peripheral. > > So, this driver supports these features. > > Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> > --- > This patch is based on the latest linux-phy.git / next branch and > "[PATCH v5 3/3] phy: Group vendor specific phy drivers" patch. > > I discussed with Geert-san about this driver on the ML: > https://patchwork.kernel.org/patch/9731759/ > > Changes from v1: > - Changes from dev_info to dev_vdbg in rcar_gen3_phy_usb3_init(). > > .../devicetree/bindings/phy/rcar-gen3-phy-usb3.txt | 47 +++++ > MAINTAINERS | 4 +- > drivers/phy/renesas/Kconfig | 7 + > drivers/phy/renesas/Makefile | 1 + > drivers/phy/renesas/phy-rcar-gen3-usb3.c | 207 +++++++++++++++++++++ > 5 files changed, 264 insertions(+), 2 deletions(-) > create mode 100644 Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb3.txt > create mode 100644 drivers/phy/renesas/phy-rcar-gen3-usb3.c > > diff --git a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb3.txt b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb3.txt > new file mode 100644 > index 0000000..e58ba6b > --- /dev/null > +++ b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb3.txt > @@ -0,0 +1,47 @@ > +* Renesas R-Car generation 3 USB 3.0 PHY > + > +This file provides information on what the device node for the R-Car generation > +3 USB 3.0 PHY contains. > +If you want to enable spread spectrum clock (ssc), you should use USB_EXTAL > +instead of USB3_CLK. However, if you don't want to these features, you don't > +need this driver. > + > +Required properties: > +- compatible: "renesas,r8a7795-usb3-phy" if the device is a part of an R8A7795 > + SoC. > + "renesas,r8a7796-usb3-phy" if the device is a part of an R8A7796 > + SoC. > + "renesas,rcar-gen3-usb3-phy" for a generic R-Car Gen3 compatible > + device. > + > + When compatible with the generic version, nodes must list the > + SoC-specific version corresponding to the platform first > + followed by the generic version. > + > +- reg: offset and length of the USB 3.0 PHY register block. > +- clocks: A list of phandles and clock-specifier pairs. > +- clock-names: Name of the clocks. > + - The funcional clock must be "usb3-if". > + - The usb3's external clock must be "usb3s_clk". If you want to use the ssc, > + the clock-frequency must be 0. Given you have "renesas,ssc-range" to enable ssc, I think it doesn't matter if the clock frequency is 0 or not, so the "if you..." part can be removed. > + - The usb2's external clock must be "usb_extal". If you want to use the ssc, > + the clock-frequenvy must not be 0. frequency Here it does matter, as you need this clock for ssc. BTW, the driver can fallback to the other clock if ssc cannot be used. > +Optional properties: > +- renesas,ssc-range: Enable/disable spread spectrum clock (ssc) by using > + the following values as u32: > + - 0 (or the property doesn't exist): disable the ssc > + - 4980: enable the ssc as -4980 ppm > + - 4492: enable the ssc as -4492 ppm > + - 4003: enable the ssc as -4003 ppm Using ssc or not sounds like software policy, not hardware description? Can this be decided at runtime? > --- /dev/null > +++ b/drivers/phy/renesas/phy-rcar-gen3-usb3.c > +static const struct of_device_id rcar_gen3_phy_usb3_match_table[] = { > + { .compatible = "renesas,r8a7795-usb3-phy" }, > + { .compatible = "renesas,r8a7796-usb3-phy" }, As the driver matches against the generic compatible property, the above two lines can be removed. > + { .compatible = "renesas,rcar-gen3-usb3-phy" }, > + { } > +}; > +MODULE_DEVICE_TABLE(of, rcar_gen3_phy_usb3_match_table); Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Hi Geert-san, > From: Geert Uytterhoeven > Sent: Wednesday, May 24, 2017 9:39 PM > > Hi Shimoda-san, > > On Wed, May 24, 2017 at 2:17 PM, Yoshihiro Shimoda > <yoshihiro.shimoda.uh@renesas.com> wrote: > > The USB 3.0 PHY modules of R-Car Gen3 SoCs have: > > - Spread spectrum clock (ssc). > > - Using USB 2.0 EXTAL clock instead of USB 3.0 clock. > > - Enabling VBUS detection for usb3.0 peripheral. > > > > So, this driver supports these features. > > > > Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> > > --- <snip> > > diff --git a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb3.txt > b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb3.txt > > new file mode 100644 > > index 0000000..e58ba6b > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb3.txt > > +* Renesas R-Car generation 3 USB 3.0 PHY > > + > > +This file provides information on what the device node for the R-Car generation > > +3 USB 3.0 PHY contains. > > +If you want to enable spread spectrum clock (ssc), you should use USB_EXTAL > > +instead of USB3_CLK. However, if you don't want to these features, you don't > > +need this driver. > > + > > +Required properties: > > +- compatible: "renesas,r8a7795-usb3-phy" if the device is a part of an R8A7795 > > + SoC. > > + "renesas,r8a7796-usb3-phy" if the device is a part of an R8A7796 > > + SoC. > > + "renesas,rcar-gen3-usb3-phy" for a generic R-Car Gen3 compatible > > + device. > > + > > + When compatible with the generic version, nodes must list the > > + SoC-specific version corresponding to the platform first > > + followed by the generic version. > > + > > +- reg: offset and length of the USB 3.0 PHY register block. > > +- clocks: A list of phandles and clock-specifier pairs. > > +- clock-names: Name of the clocks. > > + - The funcional clock must be "usb3-if". > > + - The usb3's external clock must be "usb3s_clk". If you want to use the ssc, > > + the clock-frequency must be 0. > > Given you have "renesas,ssc-range" to enable ssc, I think it doesn't matter > if the clock frequency is 0 or not, so the "if you..." part can be removed. I see. If both usb3s_clk and usb_extal are not 0 and "ssc-range" is enabled, the driver should choose usb_extal and enable the ssc. So, I understand "if you.." part can be removed. Thanks! > > + - The usb2's external clock must be "usb_extal". If you want to use the ssc, > > + the clock-frequenvy must not be 0. > > frequency Oops, I will fix it. > Here it does matter, as you need this clock for ssc. > BTW, the driver can fallback to the other clock if ssc cannot be used. > > > +Optional properties: > > +- renesas,ssc-range: Enable/disable spread spectrum clock (ssc) by using > > + the following values as u32: > > + - 0 (or the property doesn't exist): disable the ssc > > + - 4980: enable the ssc as -4980 ppm > > + - 4492: enable the ssc as -4492 ppm > > + - 4003: enable the ssc as -4003 ppm > > Using ssc or not sounds like software policy, not hardware description? > Can this be decided at runtime? I'm thinking this is hardware description :) This setting needs before usb3.0 controller starts. So, this cannot be decided at runtime. I found phy/brcm-sata-phy.txt also had a similar property "brcm,enable-ssc". > > --- /dev/null > > +++ b/drivers/phy/renesas/phy-rcar-gen3-usb3.c > > > +static const struct of_device_id rcar_gen3_phy_usb3_match_table[] = { > > + { .compatible = "renesas,r8a7795-usb3-phy" }, > > + { .compatible = "renesas,r8a7796-usb3-phy" }, > > As the driver matches against the generic compatible property, the above two > lines can be removed. I got it. I will remove it. Best regards, Yoshihiro Shimoda > > + { .compatible = "renesas,rcar-gen3-usb3-phy" }, > > + { } > > +}; > > +MODULE_DEVICE_TABLE(of, rcar_gen3_phy_usb3_match_table); > > Gr{oetje,eeting}s, > > Geert > > -- > Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org > > In personal conversations with technical people, I call myself a hacker. But > when I'm talking to journalists I just say "programmer" or something like that. > -- Linus Torvalds
diff --git a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb3.txt b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb3.txt new file mode 100644 index 0000000..e58ba6b --- /dev/null +++ b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb3.txt @@ -0,0 +1,47 @@ +* Renesas R-Car generation 3 USB 3.0 PHY + +This file provides information on what the device node for the R-Car generation +3 USB 3.0 PHY contains. +If you want to enable spread spectrum clock (ssc), you should use USB_EXTAL +instead of USB3_CLK. However, if you don't want to these features, you don't +need this driver. + +Required properties: +- compatible: "renesas,r8a7795-usb3-phy" if the device is a part of an R8A7795 + SoC. + "renesas,r8a7796-usb3-phy" if the device is a part of an R8A7796 + SoC. + "renesas,rcar-gen3-usb3-phy" for a generic R-Car Gen3 compatible + device. + + When compatible with the generic version, nodes must list the + SoC-specific version corresponding to the platform first + followed by the generic version. + +- reg: offset and length of the USB 3.0 PHY register block. +- clocks: A list of phandles and clock-specifier pairs. +- clock-names: Name of the clocks. + - The funcional clock must be "usb3-if". + - The usb3's external clock must be "usb3s_clk". If you want to use the ssc, + the clock-frequency must be 0. + - The usb2's external clock must be "usb_extal". If you want to use the ssc, + the clock-frequenvy must not be 0. +- #phy-cells: see phy-bindings.txt in the same directory, must be <0>. + +Optional properties: +- renesas,ssc-range: Enable/disable spread spectrum clock (ssc) by using + the following values as u32: + - 0 (or the property doesn't exist): disable the ssc + - 4980: enable the ssc as -4980 ppm + - 4492: enable the ssc as -4492 ppm + - 4003: enable the ssc as -4003 ppm + +Example (R-Car H3): + + usb-phy@e65ee000 { + compatible = "renesas,r8a7795-usb3-phy", + "renesas,rcar-gen3-usb3-phy"; + reg = <0 0xe65ee000 0 0x90>; + clocks = <&cpg CPG_MOD 328>, <&usb3s0_clk>, <&usb_extal>; + clock-names = "usb3-if", "usb3s_clk", "usb_extal"; + }; diff --git a/MAINTAINERS b/MAINTAINERS index a47d3da..d711d53 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10829,11 +10829,11 @@ L: linux-iio@vger.kernel.org S: Supported F: drivers/iio/adc/rcar_gyro_adc.c -RENESAS USB2 PHY DRIVER +RENESAS USB PHY DRIVER M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> L: linux-renesas-soc@vger.kernel.org S: Maintained -F: drivers/phy/renesas/phy-rcar-gen3-usb2.c +F: drivers/phy/renesas/phy-rcar-gen3-usb*.c RESET CONTROLLER FRAMEWORK M: Philipp Zabel <p.zabel@pengutronix.de> diff --git a/drivers/phy/renesas/Kconfig b/drivers/phy/renesas/Kconfig index 432e271..4377064 100644 --- a/drivers/phy/renesas/Kconfig +++ b/drivers/phy/renesas/Kconfig @@ -15,3 +15,10 @@ config PHY_RCAR_GEN3_USB2 select GENERIC_PHY help Support for USB 2.0 PHY found on Renesas R-Car generation 3 SoCs. + +config PHY_RCAR_GEN3_USB3 + tristate "Renesas R-Car generation 3 USB 3.0 PHY driver" + depends on ARCH_RENESAS + select GENERIC_PHY + help + Support for USB 3.0 PHY found on Renesas R-Car generation 3 SoCs. diff --git a/drivers/phy/renesas/Makefile b/drivers/phy/renesas/Makefile index 695241a..8b60259 100644 --- a/drivers/phy/renesas/Makefile +++ b/drivers/phy/renesas/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o obj-$(CONFIG_PHY_RCAR_GEN3_USB2) += phy-rcar-gen3-usb2.o +obj-$(CONFIG_PHY_RCAR_GEN3_USB3) += phy-rcar-gen3-usb3.o diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb3.c b/drivers/phy/renesas/phy-rcar-gen3-usb3.c new file mode 100644 index 0000000..dcc40ad --- /dev/null +++ b/drivers/phy/renesas/phy-rcar-gen3-usb3.c @@ -0,0 +1,207 @@ +/* + * Renesas R-Car Gen3 for USB3.0 PHY driver + * + * Copyright (C) 2017 Renesas Electronics Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/phy/phy.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> + +#define USB30_CLKSET0 0x034 +#define USB30_CLKSET1 0x036 +#define USB30_SSC_SET 0x038 +#define USB30_VBUS_EN 0x064 + +#define CLKSET0_RESERVED 0x05c0 +#define CLKSET0_USB_EXTAL (CLKSET0_RESERVED | 0x0002) + +#define CLKSET1_PLL_MULTI_SHIFT 6 +#define CLKSET1_PLL_MULTI_USB_EXTAL (0x64 << CLKSET1_PLL_MULTI_SHIFT) +#define CLKSET1_REF_CLKDIV_USB_EXTAL BIT(3) +#define CLKSET1_RESERVED_1 BIT(1) +#define CLKSET1_REF_CLK_SEL_USB_EXTAL 0 +#define CLKSET1_USB_EXTAL (CLKSET1_PLL_MULTI_USB_EXTAL | \ + CLKSET1_REF_CLKDIV_USB_EXTAL | \ + CLKSET1_RESERVED_1 | \ + CLKSET1_REF_CLK_SEL_USB_EXTAL) + +#define SSC_SET_SSC_EN BIT(12) +#define SSC_SET_RANGE_SHIFT 9 +#define SSC_SET_RANGE_4980 (0x0 << SSC_SET_RANGE_SHIFT) +#define SSC_SET_RANGE_4492 (0x1 << SSC_SET_RANGE_SHIFT) +#define SSC_SET_RANGE_4003 (0x2 << SSC_SET_RANGE_SHIFT) + +#define VBUS_EN_VBUS_EN BIT(1) + +struct rcar_gen3_usb3 { + void __iomem *base; + struct phy *phy; + u32 ssc_range; + bool usb3s_clk; + bool usb_extal; +}; + +static void rcar_gen3_phy_usb3_enable_ssc(struct rcar_gen3_usb3 *r) +{ + u16 val = SSC_SET_SSC_EN; + + switch (r->ssc_range) { + case 4980: + val |= SSC_SET_RANGE_4980; + break; + case 4492: + val |= SSC_SET_RANGE_4492; + break; + case 4003: + val |= SSC_SET_RANGE_4003; + break; + default: + dev_err(&r->phy->dev, "%s: unsupported range (%x)\n", __func__, + r->ssc_range); + return; + } + + writew(val, r->base + USB30_SSC_SET); +} + +static void rcar_gen3_phy_usb3_select_usb_extal(struct rcar_gen3_usb3 *r) +{ + writew(CLKSET0_USB_EXTAL, r->base + USB30_CLKSET0); + writew(CLKSET1_USB_EXTAL, r->base + USB30_CLKSET1); +} + +static int rcar_gen3_phy_usb3_init(struct phy *p) +{ + struct rcar_gen3_usb3 *r = phy_get_drvdata(p); + + dev_vdbg(&r->phy->dev, "%s: enter (%d, %d, %d)\n", __func__, + r->usb3s_clk, r->usb_extal, r->ssc_range); + + if (!r->usb3s_clk && r->usb_extal) { + rcar_gen3_phy_usb3_select_usb_extal(r); + /* SSC can be enabled when usb_extal is used */ + if (r->ssc_range) + rcar_gen3_phy_usb3_enable_ssc(r); + } + + /* Enables VBUS detection anyway */ + writew(VBUS_EN_VBUS_EN, r->base + USB30_VBUS_EN); + + return 0; +} + +static const struct phy_ops rcar_gen3_phy_usb3_ops = { + .init = rcar_gen3_phy_usb3_init, + .owner = THIS_MODULE, +}; + +static const struct of_device_id rcar_gen3_phy_usb3_match_table[] = { + { .compatible = "renesas,r8a7795-usb3-phy" }, + { .compatible = "renesas,r8a7796-usb3-phy" }, + { .compatible = "renesas,rcar-gen3-usb3-phy" }, + { } +}; +MODULE_DEVICE_TABLE(of, rcar_gen3_phy_usb3_match_table); + +static int rcar_gen3_phy_usb3_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct rcar_gen3_usb3 *r; + struct phy_provider *provider; + struct resource *res; + int ret = 0; + struct clk *clk; + + if (!dev->of_node) { + dev_err(dev, "This driver needs device tree\n"); + return -EINVAL; + } + + r = devm_kzalloc(dev, sizeof(*r), GFP_KERNEL); + if (!r) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + r->base = devm_ioremap_resource(dev, res); + if (IS_ERR(r->base)) + return PTR_ERR(r->base); + + clk = devm_clk_get(dev, "usb3s_clk"); + if (!IS_ERR(clk) && !clk_prepare_enable(clk)) { + r->usb3s_clk = !!clk_get_rate(clk); + clk_disable_unprepare(clk); + } + clk = devm_clk_get(dev, "usb_extal"); + if (!IS_ERR(clk) && !clk_prepare_enable(clk)) { + r->usb_extal = !!clk_get_rate(clk); + clk_disable_unprepare(clk); + } + + if (!r->usb3s_clk && !r->usb_extal) { + dev_err(dev, "This driver needs usb3s_clk and/or usb_extal\n"); + ret = -EINVAL; + goto error; + } + + /* + * devm_phy_create() will call pm_runtime_enable(&phy->dev); + * And then, phy-core will manage runtime pm for this device. + */ + pm_runtime_enable(dev); + + r->phy = devm_phy_create(dev, NULL, &rcar_gen3_phy_usb3_ops); + if (IS_ERR(r->phy)) { + dev_err(dev, "Failed to create USB3 PHY\n"); + ret = PTR_ERR(r->phy); + goto error; + } + + of_property_read_u32(dev->of_node, "renesas,ssc-range", &r->ssc_range); + + platform_set_drvdata(pdev, r); + phy_set_drvdata(r->phy, r); + + provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + if (IS_ERR(provider)) { + dev_err(dev, "Failed to register PHY provider\n"); + ret = PTR_ERR(provider); + goto error; + } + + return 0; + +error: + pm_runtime_disable(dev); + + return ret; +} + +static int rcar_gen3_phy_usb3_remove(struct platform_device *pdev) +{ + pm_runtime_disable(&pdev->dev); + + return 0; +}; + +static struct platform_driver rcar_gen3_phy_usb3_driver = { + .driver = { + .name = "phy_rcar_gen3_usb3", + .of_match_table = rcar_gen3_phy_usb3_match_table, + }, + .probe = rcar_gen3_phy_usb3_probe, + .remove = rcar_gen3_phy_usb3_remove, +}; +module_platform_driver(rcar_gen3_phy_usb3_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Renesas R-Car Gen3 USB 3.0 PHY"); +MODULE_AUTHOR("Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>");
The USB 3.0 PHY modules of R-Car Gen3 SoCs have: - Spread spectrum clock (ssc). - Using USB 2.0 EXTAL clock instead of USB 3.0 clock. - Enabling VBUS detection for usb3.0 peripheral. So, this driver supports these features. Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> --- This patch is based on the latest linux-phy.git / next branch and "[PATCH v5 3/3] phy: Group vendor specific phy drivers" patch. I discussed with Geert-san about this driver on the ML: https://patchwork.kernel.org/patch/9731759/ Changes from v1: - Changes from dev_info to dev_vdbg in rcar_gen3_phy_usb3_init(). .../devicetree/bindings/phy/rcar-gen3-phy-usb3.txt | 47 +++++ MAINTAINERS | 4 +- drivers/phy/renesas/Kconfig | 7 + drivers/phy/renesas/Makefile | 1 + drivers/phy/renesas/phy-rcar-gen3-usb3.c | 207 +++++++++++++++++++++ 5 files changed, 264 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb3.txt create mode 100644 drivers/phy/renesas/phy-rcar-gen3-usb3.c