Back to home page

OSCL-LXR

 
 

    


0001 ====================================
0002 Samsung USB 2.0 PHY adaptation layer
0003 ====================================
0004 
0005 1. Description
0006 --------------
0007 
0008 The architecture of the USB 2.0 PHY module in Samsung SoCs is similar
0009 among many SoCs. In spite of the similarities it proved difficult to
0010 create a one driver that would fit all these PHY controllers. Often
0011 the differences were minor and were found in particular bits of the
0012 registers of the PHY. In some rare cases the order of register writes or
0013 the PHY powering up process had to be altered. This adaptation layer is
0014 a compromise between having separate drivers and having a single driver
0015 with added support for many special cases.
0016 
0017 2. Files description
0018 --------------------
0019 
0020 - phy-samsung-usb2.c
0021    This is the main file of the adaptation layer. This file contains
0022    the probe function and provides two callbacks to the Generic PHY
0023    Framework. This two callbacks are used to power on and power off the
0024    phy. They carry out the common work that has to be done on all version
0025    of the PHY module. Depending on which SoC was chosen they execute SoC
0026    specific callbacks. The specific SoC version is selected by choosing
0027    the appropriate compatible string. In addition, this file contains
0028    struct of_device_id definitions for particular SoCs.
0029 
0030 - phy-samsung-usb2.h
0031    This is the include file. It declares the structures used by this
0032    driver. In addition it should contain extern declarations for
0033    structures that describe particular SoCs.
0034 
0035 3. Supporting SoCs
0036 ------------------
0037 
0038 To support a new SoC a new file should be added to the drivers/phy
0039 directory. Each SoC's configuration is stored in an instance of the
0040 struct samsung_usb2_phy_config::
0041 
0042   struct samsung_usb2_phy_config {
0043         const struct samsung_usb2_common_phy *phys;
0044         int (*rate_to_clk)(unsigned long, u32 *);
0045         unsigned int num_phys;
0046         bool has_mode_switch;
0047   };
0048 
0049 The num_phys is the number of phys handled by the driver. `*phys` is an
0050 array that contains the configuration for each phy. The has_mode_switch
0051 property is a boolean flag that determines whether the SoC has USB host
0052 and device on a single pair of pins. If so, a special register has to
0053 be modified to change the internal routing of these pins between a USB
0054 device or host module.
0055 
0056 For example the configuration for Exynos 4210 is following::
0057 
0058   const struct samsung_usb2_phy_config exynos4210_usb2_phy_config = {
0059         .has_mode_switch        = 0,
0060         .num_phys               = EXYNOS4210_NUM_PHYS,
0061         .phys                   = exynos4210_phys,
0062         .rate_to_clk            = exynos4210_rate_to_clk,
0063   }
0064 
0065 - `int (*rate_to_clk)(unsigned long, u32 *)`
0066 
0067         The rate_to_clk callback is to convert the rate of the clock
0068         used as the reference clock for the PHY module to the value
0069         that should be written in the hardware register.
0070 
0071 The exynos4210_phys configuration array is as follows::
0072 
0073   static const struct samsung_usb2_common_phy exynos4210_phys[] = {
0074         {
0075                 .label          = "device",
0076                 .id             = EXYNOS4210_DEVICE,
0077                 .power_on       = exynos4210_power_on,
0078                 .power_off      = exynos4210_power_off,
0079         },
0080         {
0081                 .label          = "host",
0082                 .id             = EXYNOS4210_HOST,
0083                 .power_on       = exynos4210_power_on,
0084                 .power_off      = exynos4210_power_off,
0085         },
0086         {
0087                 .label          = "hsic0",
0088                 .id             = EXYNOS4210_HSIC0,
0089                 .power_on       = exynos4210_power_on,
0090                 .power_off      = exynos4210_power_off,
0091         },
0092         {
0093                 .label          = "hsic1",
0094                 .id             = EXYNOS4210_HSIC1,
0095                 .power_on       = exynos4210_power_on,
0096                 .power_off      = exynos4210_power_off,
0097         },
0098         {},
0099   };
0100 
0101 - `int (*power_on)(struct samsung_usb2_phy_instance *);`
0102   `int (*power_off)(struct samsung_usb2_phy_instance *);`
0103 
0104         These two callbacks are used to power on and power off the phy
0105         by modifying appropriate registers.
0106 
0107 Final change to the driver is adding appropriate compatible value to the
0108 phy-samsung-usb2.c file. In case of Exynos 4210 the following lines were
0109 added to the struct of_device_id samsung_usb2_phy_of_match[] array::
0110 
0111   #ifdef CONFIG_PHY_EXYNOS4210_USB2
0112         {
0113                 .compatible = "samsung,exynos4210-usb2-phy",
0114                 .data = &exynos4210_usb2_phy_config,
0115         },
0116   #endif
0117 
0118 To add further flexibility to the driver the Kconfig file enables to
0119 include support for selected SoCs in the compiled driver. The Kconfig
0120 entry for Exynos 4210 is following::
0121 
0122   config PHY_EXYNOS4210_USB2
0123         bool "Support for Exynos 4210"
0124         depends on PHY_SAMSUNG_USB2
0125         depends on CPU_EXYNOS4210
0126         help
0127           Enable USB PHY support for Exynos 4210. This option requires that
0128           Samsung USB 2.0 PHY driver is enabled and means that support for this
0129           particular SoC is compiled in the driver. In case of Exynos 4210 four
0130           phys are available - device, host, HSCI0 and HSCI1.
0131 
0132 The newly created file that supports the new SoC has to be also added to the
0133 Makefile. In case of Exynos 4210 the added line is following::
0134 
0135   obj-$(CONFIG_PHY_EXYNOS4210_USB2)       += phy-exynos4210-usb2.o
0136 
0137 After completing these steps the support for the new SoC should be ready.