xref: /OK3568_Linux_fs/kernel/Documentation/driver-api/phy/samsung-usb2.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun====================================
2*4882a593SmuzhiyunSamsung USB 2.0 PHY adaptation layer
3*4882a593Smuzhiyun====================================
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun1. Description
6*4882a593Smuzhiyun--------------
7*4882a593Smuzhiyun
8*4882a593SmuzhiyunThe architecture of the USB 2.0 PHY module in Samsung SoCs is similar
9*4882a593Smuzhiyunamong many SoCs. In spite of the similarities it proved difficult to
10*4882a593Smuzhiyuncreate a one driver that would fit all these PHY controllers. Often
11*4882a593Smuzhiyunthe differences were minor and were found in particular bits of the
12*4882a593Smuzhiyunregisters of the PHY. In some rare cases the order of register writes or
13*4882a593Smuzhiyunthe PHY powering up process had to be altered. This adaptation layer is
14*4882a593Smuzhiyuna compromise between having separate drivers and having a single driver
15*4882a593Smuzhiyunwith added support for many special cases.
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun2. Files description
18*4882a593Smuzhiyun--------------------
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun- phy-samsung-usb2.c
21*4882a593Smuzhiyun   This is the main file of the adaptation layer. This file contains
22*4882a593Smuzhiyun   the probe function and provides two callbacks to the Generic PHY
23*4882a593Smuzhiyun   Framework. This two callbacks are used to power on and power off the
24*4882a593Smuzhiyun   phy. They carry out the common work that has to be done on all version
25*4882a593Smuzhiyun   of the PHY module. Depending on which SoC was chosen they execute SoC
26*4882a593Smuzhiyun   specific callbacks. The specific SoC version is selected by choosing
27*4882a593Smuzhiyun   the appropriate compatible string. In addition, this file contains
28*4882a593Smuzhiyun   struct of_device_id definitions for particular SoCs.
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun- phy-samsung-usb2.h
31*4882a593Smuzhiyun   This is the include file. It declares the structures used by this
32*4882a593Smuzhiyun   driver. In addition it should contain extern declarations for
33*4882a593Smuzhiyun   structures that describe particular SoCs.
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun3. Supporting SoCs
36*4882a593Smuzhiyun------------------
37*4882a593Smuzhiyun
38*4882a593SmuzhiyunTo support a new SoC a new file should be added to the drivers/phy
39*4882a593Smuzhiyundirectory. Each SoC's configuration is stored in an instance of the
40*4882a593Smuzhiyunstruct samsung_usb2_phy_config::
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun  struct samsung_usb2_phy_config {
43*4882a593Smuzhiyun	const struct samsung_usb2_common_phy *phys;
44*4882a593Smuzhiyun	int (*rate_to_clk)(unsigned long, u32 *);
45*4882a593Smuzhiyun	unsigned int num_phys;
46*4882a593Smuzhiyun	bool has_mode_switch;
47*4882a593Smuzhiyun  };
48*4882a593Smuzhiyun
49*4882a593SmuzhiyunThe num_phys is the number of phys handled by the driver. `*phys` is an
50*4882a593Smuzhiyunarray that contains the configuration for each phy. The has_mode_switch
51*4882a593Smuzhiyunproperty is a boolean flag that determines whether the SoC has USB host
52*4882a593Smuzhiyunand device on a single pair of pins. If so, a special register has to
53*4882a593Smuzhiyunbe modified to change the internal routing of these pins between a USB
54*4882a593Smuzhiyundevice or host module.
55*4882a593Smuzhiyun
56*4882a593SmuzhiyunFor example the configuration for Exynos 4210 is following::
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun  const struct samsung_usb2_phy_config exynos4210_usb2_phy_config = {
59*4882a593Smuzhiyun	.has_mode_switch        = 0,
60*4882a593Smuzhiyun	.num_phys		= EXYNOS4210_NUM_PHYS,
61*4882a593Smuzhiyun	.phys			= exynos4210_phys,
62*4882a593Smuzhiyun	.rate_to_clk		= exynos4210_rate_to_clk,
63*4882a593Smuzhiyun  }
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun- `int (*rate_to_clk)(unsigned long, u32 *)`
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun	The rate_to_clk callback is to convert the rate of the clock
68*4882a593Smuzhiyun	used as the reference clock for the PHY module to the value
69*4882a593Smuzhiyun	that should be written in the hardware register.
70*4882a593Smuzhiyun
71*4882a593SmuzhiyunThe exynos4210_phys configuration array is as follows::
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun  static const struct samsung_usb2_common_phy exynos4210_phys[] = {
74*4882a593Smuzhiyun	{
75*4882a593Smuzhiyun		.label		= "device",
76*4882a593Smuzhiyun		.id		= EXYNOS4210_DEVICE,
77*4882a593Smuzhiyun		.power_on	= exynos4210_power_on,
78*4882a593Smuzhiyun		.power_off	= exynos4210_power_off,
79*4882a593Smuzhiyun	},
80*4882a593Smuzhiyun	{
81*4882a593Smuzhiyun		.label		= "host",
82*4882a593Smuzhiyun		.id		= EXYNOS4210_HOST,
83*4882a593Smuzhiyun		.power_on	= exynos4210_power_on,
84*4882a593Smuzhiyun		.power_off	= exynos4210_power_off,
85*4882a593Smuzhiyun	},
86*4882a593Smuzhiyun	{
87*4882a593Smuzhiyun		.label		= "hsic0",
88*4882a593Smuzhiyun		.id		= EXYNOS4210_HSIC0,
89*4882a593Smuzhiyun		.power_on	= exynos4210_power_on,
90*4882a593Smuzhiyun		.power_off	= exynos4210_power_off,
91*4882a593Smuzhiyun	},
92*4882a593Smuzhiyun	{
93*4882a593Smuzhiyun		.label		= "hsic1",
94*4882a593Smuzhiyun		.id		= EXYNOS4210_HSIC1,
95*4882a593Smuzhiyun		.power_on	= exynos4210_power_on,
96*4882a593Smuzhiyun		.power_off	= exynos4210_power_off,
97*4882a593Smuzhiyun	},
98*4882a593Smuzhiyun	{},
99*4882a593Smuzhiyun  };
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun- `int (*power_on)(struct samsung_usb2_phy_instance *);`
102*4882a593Smuzhiyun  `int (*power_off)(struct samsung_usb2_phy_instance *);`
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun	These two callbacks are used to power on and power off the phy
105*4882a593Smuzhiyun	by modifying appropriate registers.
106*4882a593Smuzhiyun
107*4882a593SmuzhiyunFinal change to the driver is adding appropriate compatible value to the
108*4882a593Smuzhiyunphy-samsung-usb2.c file. In case of Exynos 4210 the following lines were
109*4882a593Smuzhiyunadded to the struct of_device_id samsung_usb2_phy_of_match[] array::
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun  #ifdef CONFIG_PHY_EXYNOS4210_USB2
112*4882a593Smuzhiyun	{
113*4882a593Smuzhiyun		.compatible = "samsung,exynos4210-usb2-phy",
114*4882a593Smuzhiyun		.data = &exynos4210_usb2_phy_config,
115*4882a593Smuzhiyun	},
116*4882a593Smuzhiyun  #endif
117*4882a593Smuzhiyun
118*4882a593SmuzhiyunTo add further flexibility to the driver the Kconfig file enables to
119*4882a593Smuzhiyuninclude support for selected SoCs in the compiled driver. The Kconfig
120*4882a593Smuzhiyunentry for Exynos 4210 is following::
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun  config PHY_EXYNOS4210_USB2
123*4882a593Smuzhiyun	bool "Support for Exynos 4210"
124*4882a593Smuzhiyun	depends on PHY_SAMSUNG_USB2
125*4882a593Smuzhiyun	depends on CPU_EXYNOS4210
126*4882a593Smuzhiyun	help
127*4882a593Smuzhiyun	  Enable USB PHY support for Exynos 4210. This option requires that
128*4882a593Smuzhiyun	  Samsung USB 2.0 PHY driver is enabled and means that support for this
129*4882a593Smuzhiyun	  particular SoC is compiled in the driver. In case of Exynos 4210 four
130*4882a593Smuzhiyun	  phys are available - device, host, HSCI0 and HSCI1.
131*4882a593Smuzhiyun
132*4882a593SmuzhiyunThe newly created file that supports the new SoC has to be also added to the
133*4882a593SmuzhiyunMakefile. In case of Exynos 4210 the added line is following::
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun  obj-$(CONFIG_PHY_EXYNOS4210_USB2)       += phy-exynos4210-usb2.o
136*4882a593Smuzhiyun
137*4882a593SmuzhiyunAfter completing these steps the support for the new SoC should be ready.
138