162306a36Sopenharmony_ci====================================
262306a36Sopenharmony_ciSamsung USB 2.0 PHY adaptation layer
362306a36Sopenharmony_ci====================================
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci1. Description
662306a36Sopenharmony_ci--------------
762306a36Sopenharmony_ci
862306a36Sopenharmony_ciThe architecture of the USB 2.0 PHY module in Samsung SoCs is similar
962306a36Sopenharmony_ciamong many SoCs. In spite of the similarities it proved difficult to
1062306a36Sopenharmony_cicreate a one driver that would fit all these PHY controllers. Often
1162306a36Sopenharmony_cithe differences were minor and were found in particular bits of the
1262306a36Sopenharmony_ciregisters of the PHY. In some rare cases the order of register writes or
1362306a36Sopenharmony_cithe PHY powering up process had to be altered. This adaptation layer is
1462306a36Sopenharmony_cia compromise between having separate drivers and having a single driver
1562306a36Sopenharmony_ciwith added support for many special cases.
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci2. Files description
1862306a36Sopenharmony_ci--------------------
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci- phy-samsung-usb2.c
2162306a36Sopenharmony_ci   This is the main file of the adaptation layer. This file contains
2262306a36Sopenharmony_ci   the probe function and provides two callbacks to the Generic PHY
2362306a36Sopenharmony_ci   Framework. This two callbacks are used to power on and power off the
2462306a36Sopenharmony_ci   phy. They carry out the common work that has to be done on all version
2562306a36Sopenharmony_ci   of the PHY module. Depending on which SoC was chosen they execute SoC
2662306a36Sopenharmony_ci   specific callbacks. The specific SoC version is selected by choosing
2762306a36Sopenharmony_ci   the appropriate compatible string. In addition, this file contains
2862306a36Sopenharmony_ci   struct of_device_id definitions for particular SoCs.
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci- phy-samsung-usb2.h
3162306a36Sopenharmony_ci   This is the include file. It declares the structures used by this
3262306a36Sopenharmony_ci   driver. In addition it should contain extern declarations for
3362306a36Sopenharmony_ci   structures that describe particular SoCs.
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci3. Supporting SoCs
3662306a36Sopenharmony_ci------------------
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ciTo support a new SoC a new file should be added to the drivers/phy
3962306a36Sopenharmony_cidirectory. Each SoC's configuration is stored in an instance of the
4062306a36Sopenharmony_cistruct samsung_usb2_phy_config::
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci  struct samsung_usb2_phy_config {
4362306a36Sopenharmony_ci	const struct samsung_usb2_common_phy *phys;
4462306a36Sopenharmony_ci	int (*rate_to_clk)(unsigned long, u32 *);
4562306a36Sopenharmony_ci	unsigned int num_phys;
4662306a36Sopenharmony_ci	bool has_mode_switch;
4762306a36Sopenharmony_ci  };
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ciThe num_phys is the number of phys handled by the driver. `*phys` is an
5062306a36Sopenharmony_ciarray that contains the configuration for each phy. The has_mode_switch
5162306a36Sopenharmony_ciproperty is a boolean flag that determines whether the SoC has USB host
5262306a36Sopenharmony_ciand device on a single pair of pins. If so, a special register has to
5362306a36Sopenharmony_cibe modified to change the internal routing of these pins between a USB
5462306a36Sopenharmony_cidevice or host module.
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ciFor example the configuration for Exynos 4210 is following::
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci  const struct samsung_usb2_phy_config exynos4210_usb2_phy_config = {
5962306a36Sopenharmony_ci	.has_mode_switch        = 0,
6062306a36Sopenharmony_ci	.num_phys		= EXYNOS4210_NUM_PHYS,
6162306a36Sopenharmony_ci	.phys			= exynos4210_phys,
6262306a36Sopenharmony_ci	.rate_to_clk		= exynos4210_rate_to_clk,
6362306a36Sopenharmony_ci  }
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci- `int (*rate_to_clk)(unsigned long, u32 *)`
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	The rate_to_clk callback is to convert the rate of the clock
6862306a36Sopenharmony_ci	used as the reference clock for the PHY module to the value
6962306a36Sopenharmony_ci	that should be written in the hardware register.
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ciThe exynos4210_phys configuration array is as follows::
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci  static const struct samsung_usb2_common_phy exynos4210_phys[] = {
7462306a36Sopenharmony_ci	{
7562306a36Sopenharmony_ci		.label		= "device",
7662306a36Sopenharmony_ci		.id		= EXYNOS4210_DEVICE,
7762306a36Sopenharmony_ci		.power_on	= exynos4210_power_on,
7862306a36Sopenharmony_ci		.power_off	= exynos4210_power_off,
7962306a36Sopenharmony_ci	},
8062306a36Sopenharmony_ci	{
8162306a36Sopenharmony_ci		.label		= "host",
8262306a36Sopenharmony_ci		.id		= EXYNOS4210_HOST,
8362306a36Sopenharmony_ci		.power_on	= exynos4210_power_on,
8462306a36Sopenharmony_ci		.power_off	= exynos4210_power_off,
8562306a36Sopenharmony_ci	},
8662306a36Sopenharmony_ci	{
8762306a36Sopenharmony_ci		.label		= "hsic0",
8862306a36Sopenharmony_ci		.id		= EXYNOS4210_HSIC0,
8962306a36Sopenharmony_ci		.power_on	= exynos4210_power_on,
9062306a36Sopenharmony_ci		.power_off	= exynos4210_power_off,
9162306a36Sopenharmony_ci	},
9262306a36Sopenharmony_ci	{
9362306a36Sopenharmony_ci		.label		= "hsic1",
9462306a36Sopenharmony_ci		.id		= EXYNOS4210_HSIC1,
9562306a36Sopenharmony_ci		.power_on	= exynos4210_power_on,
9662306a36Sopenharmony_ci		.power_off	= exynos4210_power_off,
9762306a36Sopenharmony_ci	},
9862306a36Sopenharmony_ci	{},
9962306a36Sopenharmony_ci  };
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci- `int (*power_on)(struct samsung_usb2_phy_instance *);`
10262306a36Sopenharmony_ci  `int (*power_off)(struct samsung_usb2_phy_instance *);`
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	These two callbacks are used to power on and power off the phy
10562306a36Sopenharmony_ci	by modifying appropriate registers.
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ciFinal change to the driver is adding appropriate compatible value to the
10862306a36Sopenharmony_ciphy-samsung-usb2.c file. In case of Exynos 4210 the following lines were
10962306a36Sopenharmony_ciadded to the struct of_device_id samsung_usb2_phy_of_match[] array::
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci  #ifdef CONFIG_PHY_EXYNOS4210_USB2
11262306a36Sopenharmony_ci	{
11362306a36Sopenharmony_ci		.compatible = "samsung,exynos4210-usb2-phy",
11462306a36Sopenharmony_ci		.data = &exynos4210_usb2_phy_config,
11562306a36Sopenharmony_ci	},
11662306a36Sopenharmony_ci  #endif
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ciTo add further flexibility to the driver the Kconfig file enables to
11962306a36Sopenharmony_ciinclude support for selected SoCs in the compiled driver. The Kconfig
12062306a36Sopenharmony_cientry for Exynos 4210 is following::
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci  config PHY_EXYNOS4210_USB2
12362306a36Sopenharmony_ci	bool "Support for Exynos 4210"
12462306a36Sopenharmony_ci	depends on PHY_SAMSUNG_USB2
12562306a36Sopenharmony_ci	depends on CPU_EXYNOS4210
12662306a36Sopenharmony_ci	help
12762306a36Sopenharmony_ci	  Enable USB PHY support for Exynos 4210. This option requires that
12862306a36Sopenharmony_ci	  Samsung USB 2.0 PHY driver is enabled and means that support for this
12962306a36Sopenharmony_ci	  particular SoC is compiled in the driver. In case of Exynos 4210 four
13062306a36Sopenharmony_ci	  phys are available - device, host, HSCI0 and HSCI1.
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ciThe newly created file that supports the new SoC has to be also added to the
13362306a36Sopenharmony_ciMakefile. In case of Exynos 4210 the added line is following::
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci  obj-$(CONFIG_PHY_EXYNOS4210_USB2)       += phy-exynos4210-usb2.o
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ciAfter completing these steps the support for the new SoC should be ready.
138