[PATCH v5 1/2] phy: Add new Exynos5 USB 3.0 PHY driver

Vivek Gautam gautam.vivek at samsung.com
Sun Apr 27 22:47:53 PDT 2014


Hi Tomasz,


On Sat, Apr 26, 2014 at 4:33 AM, Tomasz Figa <tomasz.figa at gmail.com> wrote:
> Hi Vivek,
>
>
> On 22.04.2014 10:03, Vivek Gautam wrote:
>>
>> Add a new driver for the USB 3.0 PHY on Exynos5 series of SoCs.
>> The new driver uses the generic PHY framework and will interact
>> with DWC3 controller present on Exynos5 series of SoCs.
>> Thereby, removing old phy-samsung-usb3 driver and related code
>> used untill now which was based on usb/phy framework.
>>
>> Signed-off-by: Vivek Gautam <gautam.vivek at samsung.com>
>> ---
>>   .../devicetree/bindings/phy/samsung-phy.txt        |   40 ++
>>   drivers/phy/Kconfig                                |   11 +
>>   drivers/phy/Makefile                               |    1 +
>>   drivers/phy/phy-exynos5-usbdrd.c                   |  629
>> ++++++++++++++++++++
>>   4 files changed, 681 insertions(+)
>>   create mode 100644 drivers/phy/phy-exynos5-usbdrd.c
>>
>> diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt
>> b/Documentation/devicetree/bindings/phy/samsung-phy.txt
>> index b422e38..51efe4c 100644
>> --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt
>> +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
>> @@ -114,3 +114,43 @@ Example:
>>                 compatible = "samsung,exynos-sataphy-i2c";
>>                 reg = <0x38>;
>>         };
>> +
>> +Samsung Exynos5 SoC series USB DRD PHY controller

[snip]

>> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
>> index 3bb05f1..8a5d2b4 100644
>> --- a/drivers/phy/Kconfig
>> +++ b/drivers/phy/Kconfig
>> @@ -166,4 +166,15 @@ config PHY_XGENE
>>         help
>>           This option enables support for APM X-Gene SoC multi-purpose
>> PHY.
>>
>> +config PHY_EXYNOS5_USBDRD
>> +       tristate "Exynos5 SoC series USB DRD PHY driver"
>> +       depends on ARCH_EXYNOS5 && OF
>> +       depends on HAS_IOMEM
>> +       select GENERIC_PHY
>> +       select MFD_SYSCON
>> +       help
>> +         Enable USB DRD PHY support for Exynos 5 SoC series.
>> +         This driver provides PHY interface for USB 3.0 DRD controller
>> +         present on Exynos5 SoC series.
>> +
>
>
> I think you should probably keep the entries sorted, so this one should be
> somewhere around other EXYNOS PHYs.

Right, thanks for pointing this out.
Will move this along with other PHY_EXYNOS USB* configs.

>
>
>>   endmenu
>> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
>> index 2faf78e..31baa0c 100644
>> --- a/drivers/phy/Makefile
>> +++ b/drivers/phy/Makefile
>> @@ -18,3 +18,4 @@ obj-$(CONFIG_PHY_EXYNOS4210_USB2)     +=
>> phy-exynos4210-usb2.o
>>   obj-$(CONFIG_PHY_EXYNOS4X12_USB2)     += phy-exynos4x12-usb2.o
>>   obj-$(CONFIG_PHY_EXYNOS5250_USB2)     += phy-exynos5250-usb2.o
>>   obj-$(CONFIG_PHY_XGENE)                       += phy-xgene.o
>> +obj-$(CONFIG_PHY_EXYNOS5_USBDRD)       += phy-exynos5-usbdrd.o
>
>
> Ditto.

Ok

>
>
>> diff --git a/drivers/phy/phy-exynos5-usbdrd.c
>> b/drivers/phy/phy-exynos5-usbdrd.c
>> new file mode 100644
>> index 0000000..89d7ae8
>> --- /dev/null
>> +++ b/drivers/phy/phy-exynos5-usbdrd.c
>> @@ -0,0 +1,629 @@
>> +/*
>> + * Samsung EXYNOS5 SoC series USB DRD PHY driver
>> + *
>> + * Phy provider for USB 3.0 DRD controller on Exynos5 SoC series
>> + *
>> + * Copyright (C) 2014 Samsung Electronics Co., Ltd.
>> + * Author: Vivek Gautam <gautam.vivek at samsung.com>
>> + *

[snip]

>> +       } phys[EXYNOS5_DRDPHYS_NUM];
>> +       unsigned int extrefclk;
>> +       struct clk *ref_clk;
>> +       unsigned long ref_rate;
>> +};
>> +
>> +#define to_usbdrd_phy(inst) \
>> +       container_of((inst), struct exynos5_usbdrd_phy, \
>> +                    phys[(inst)->index]);
>
>
> This should be made a static inline to enforce type checking.

Ok, will make this as static inline routine, so that compiler don't
skip type checking.

>
>
>> +
>> +/*
>> + * exynos5_rate_to_clk() converts the supplied clock rate to the value
>> that
>> + * can be written to the phy register.
>> + */
>> +static unsigned int exynos5_rate_to_clk(unsigned long rate)
>> +{
>> +       unsigned int clksel;
>> +
>> +       /* EXYNOS5_FSEL_MASK */
>> +
>> +       switch (rate) {
>> +       case 9600 * KHZ:
>> +               clksel = EXYNOS5_FSEL_9MHZ6;
>> +               break;
>> +       case 10 * MHZ:
>> +               clksel = EXYNOS5_FSEL_10MHZ;
>> +               break;
>> +       case 12 * MHZ:
>> +               clksel = EXYNOS5_FSEL_12MHZ;
>> +               break;
>> +       case 19200 * KHZ:
>> +               clksel = EXYNOS5_FSEL_19MHZ2;
>> +               break;
>> +       case 20 * MHZ:
>> +               clksel = EXYNOS5_FSEL_20MHZ;
>> +               break;
>> +       case 24 * MHZ:
>> +               clksel = EXYNOS5_FSEL_24MHZ;
>> +               break;
>> +       case 50 * MHZ:
>> +               clksel = EXYNOS5_FSEL_50MHZ;
>> +               break;
>> +       default:
>> +               clksel = -EINVAL;
>
>
> Based on clksel (and return value of this function) being unsigned I don't
> think this is a good idea. You should probably adapt the approach from
> Exynos USB 2 PHY, where a function like this return an integer status code
> and returns the bitfield value through a pointer passed as another argument.

Right, will amend this as suggested.

>
>
>> +       }
>> +
>> +       return clksel;
>> +}
>> +
>> +static void exynos5_usbdrd_phy_isol(struct phy_usb_instance *inst,
>> +                                               unsigned int on)
>> +{
>> +       if (!inst->reg_pmu)
>> +               return;
>> +
>> +       regmap_update_bits(inst->reg_pmu, inst->pmu_offset,
>> +                          EXYNOS5_USBDRD_PMU_ISOL, ~on);
>
>
> I don't think ~on is correct here. Even if technically it produces the
> correct value, because bit 0 is being changed here, this should be fixed. If
> EXYNOS5_USBDRD_PMU_ISOL wasn't BIT(0), then always 1 would be written, as on
> could be 0 or 1 and ~on respectively 0xffffffff or 0xfffffffe.
>
> I'd suggest something like this:
>
> unsigned int val = on ? 0 : EXYNOS5_USBDRD_PMU_ISOL;

Sure will change this as suggested.

[snip]

>> +const struct usbdrd_phy_config exynos5_usbdrd_phy_cfg[] = {
>> +       {
>> +               .id             = EXYNOS5_DRDPHY_UTMI,
>> +               .phy_isol       = exynos5_usbdrd_phy_isol,
>> +               .phy_init       = exynos5_usbdrd_utmi_init,
>> +               .set_refclk     = exynos5_usbdrd_utmi_set_refclk,
>> +       },
>> +       {
>> +               .id             = EXYNOS5_DRDPHY_PIPE3,
>> +               .phy_isol       = exynos5_usbdrd_phy_isol,
>> +               .phy_init       = exynos5_usbdrd_pipe3_init,
>> +               .set_refclk     = exynos5_usbdrd_pipe3_set_refclk,
>> +       },
>> +       {},
>
>
> You seem to use a fixed number of PHYs. Do you still need this sentinel
> entry?

Right, we don't need this sentinel entry since we have limited the
number of PHYs to EXYNOS5_DRDPHYS_NUM.
Will remove this.

>
>
>> +};

[snip]

>> +
>> +       match = of_match_node(exynos5_usbdrd_phy_of_match,
>> pdev->dev.of_node);
>> +       if (!match) {
>
>
> This can't happen, otherwise probe() wouldn't be called at all.
True, will remove this check.



-- 
Best Regards
Vivek Gautam
Samsung R&D Institute, Bangalore
India



More information about the linux-arm-kernel mailing list