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