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