요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
====================================
Samsung USB 2.0 PHY adaptation layer
====================================
1. Description
--------------
The architecture of the USB 2.0 PHY module in Samsung SoCs is similar
among many SoCs. In spite of the similarities it proved difficult to
create a one driver that would fit all these PHY controllers. Often
the differences were minor and were found in particular bits of the
registers of the PHY. In some rare cases the order of register writes or
the PHY powering up process had to be altered. This adaptation layer is
a compromise between having separate drivers and having a single driver
with added support for many special cases.
2. Files description
--------------------
- phy-samsung-usb2.c
This is the main file of the adaptation layer. This file contains
the probe function and provides two callbacks to the Generic PHY
Framework. This two callbacks are used to power on and power off the
phy. They carry out the common work that has to be done on all version
of the PHY module. Depending on which SoC was chosen they execute SoC
specific callbacks. The specific SoC version is selected by choosing
the appropriate compatible string. In addition, this file contains
struct of_device_id definitions for particular SoCs.
- phy-samsung-usb2.h
This is the include file. It declares the structures used by this
driver. In addition it should contain extern declarations for
structures that describe particular SoCs.
3. Supporting SoCs
------------------
To support a new SoC a new file should be added to the drivers/phy
directory. Each SoC's configuration is stored in an instance of the
struct samsung_usb2_phy_config::
struct samsung_usb2_phy_config {
const struct samsung_usb2_common_phy *phys;
int (*rate_to_clk)(unsigned long, u32 *);
unsigned int num_phys;
bool has_mode_switch;
};
The num_phys is the number of phys handled by the driver. `*phys` is an
array that contains the configuration for each phy. The has_mode_switch
property is a boolean flag that determines whether the SoC has USB host
and device on a single pair of pins. If so, a special register has to
be modified to change the internal routing of these pins between a USB
device or host module.
For example the configuration for Exynos 4210 is following::
const struct samsung_usb2_phy_config exynos4210_usb2_phy_config = {
.has_mode_switch = 0,
.num_phys = EXYNOS4210_NUM_PHYS,
.phys = exynos4210_phys,
.rate_to_clk = exynos4210_rate_to_clk,
}
- `int (*rate_to_clk)(unsigned long, u32 *)`
The rate_to_clk callback is to convert the rate of the clock
used as the reference clock for the PHY module to the value
that should be written in the hardware register.
The exynos4210_phys configuration array is as follows::
static const struct samsung_usb2_common_phy exynos4210_phys[] = {
{
.label = "device",
.id = EXYNOS4210_DEVICE,
.power_on = exynos4210_power_on,
.power_off = exynos4210_power_off,
},
{
.label = "host",
.id = EXYNOS4210_HOST,
.power_on = exynos4210_power_on,
.power_off = exynos4210_power_off,
},
{
.label = "hsic0",
.id = EXYNOS4210_HSIC0,
.power_on = exynos4210_power_on,
.power_off = exynos4210_power_off,
},
{
.label = "hsic1",
.id = EXYNOS4210_HSIC1,
.power_on = exynos4210_power_on,
.power_off = exynos4210_power_off,
},
{},
};
- `int (*power_on)(struct samsung_usb2_phy_instance *);`
`int (*power_off)(struct samsung_usb2_phy_instance *);`
These two callbacks are used to power on and power off the phy
by modifying appropriate registers.
Final change to the driver is adding appropriate compatible value to the
phy-samsung-usb2.c file. In case of Exynos 4210 the following lines were
added to the struct of_device_id samsung_usb2_phy_of_match[] array::
#ifdef CONFIG_PHY_EXYNOS4210_USB2
{
.compatible = "samsung,exynos4210-usb2-phy",
.data = &exynos4210_usb2_phy_config,
},
#endif
To add further flexibility to the driver the Kconfig file enables to
include support for selected SoCs in the compiled driver. The Kconfig
entry for Exynos 4210 is following::
config PHY_EXYNOS4210_USB2
bool "Support for Exynos 4210"
depends on PHY_SAMSUNG_USB2
depends on CPU_EXYNOS4210
help
Enable USB PHY support for Exynos 4210. This option requires that
Samsung USB 2.0 PHY driver is enabled and means that support for this
particular SoC is compiled in the driver. In case of Exynos 4210 four
phys are available - device, host, HSCI0 and HSCI1.
The newly created file that supports the new SoC has to be also added to the
Makefile. In case of Exynos 4210 the added line is following::
obj-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o
After completing these steps the support for the new SoC should be ready.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
Samsung USB 2.0 PHY adaptation layer의 목적
1-16여러 Samsung SoC의 USB 2.0 PHY module은 architecture가 비슷하지만 모든 controller를 하나의 단순 driver로 처리하기는 어렵습니다. 차이는 대개 특정 PHY register bit처럼 작지만, 드물게 register write 순서나 PHY power-up 과정 자체가 달라집니다.
이 adaptation layer는 SoC마다 완전히 별도 driver를 두는 방식과, 수많은 special case를 한 driver에 직접 넣는 방식 사이의 절충안입니다. 공통 제어는 core file에 두고 SoC별 차이는 configuration과 callback으로 분리합니다.
공통 흐름은 main driver가 담당하고 register 차이와 power sequence는 SoC별 파일에 둡니다.
====================================
Samsung USB 2.0 PHY adaptation layer
====================================
1. Description
--------------
The architecture of the USB 2.0 PHY module in Samsung SoCs is similar
among many SoCs. In spite of the similarities it proved difficult to
create a one driver that would fit all these PHY controllers. Often
the differences were minor and were found in particular bits of the
registers of the PHY. In some rare cases the order of register writes or
the PHY powering up process had to be altered. This adaptation layer is
a compromise between having separate drivers and having a single driver
with added support for many special cases.
Main file과 header의 책임
17-34`phy-samsung-usb2.c`는 adaptation layer의 main file입니다. Probe function과 Generic PHY Framework에 제공하는 power-on·power-off callback을 포함합니다. 두 callback은 모든 PHY version에 필요한 공통 작업을 수행한 뒤 선택된 SoC의 전용 callback을 실행합니다.
SoC version은 적절한 compatible string으로 선택되며, main file에는 각 SoC용 `struct of_device_id` 정의도 들어 있습니다.
`phy-samsung-usb2.h`는 driver가 사용하는 structure를 선언하는 include file입니다. 특정 SoC를 설명하는 structure의 `extern` declaration도 이 header에 추가해야 합니다.
2. Files description
--------------------
- phy-samsung-usb2.c
This is the main file of the adaptation layer. This file contains
the probe function and provides two callbacks to the Generic PHY
Framework. This two callbacks are used to power on and power off the
phy. They carry out the common work that has to be done on all version
of the PHY module. Depending on which SoC was chosen they execute SoC
specific callbacks. The specific SoC version is selected by choosing
the appropriate compatible string. In addition, this file contains
struct of_device_id definitions for particular SoCs.
- phy-samsung-usb2.h
This is the include file. It declares the structures used by this
driver. In addition it should contain extern declarations for
structures that describe particular SoCs.
새 SoC configuration과 reference clock
35-70새 SoC를 지원하려면 `drivers/phy` directory에 새 source file을 추가하고 `struct samsung_usb2_phy_config` instance에 configuration을 저장합니다. 이 structure는 `phys`, `rate_to_clk`, `num_phys`, `has_mode_switch`를 가집니다.
`num_phys`는 driver가 처리하는 PHY 수이고, `phys`는 각 PHY의 configuration array입니다. `has_mode_switch`는 USB host와 device가 동일 pin pair를 공유하는지를 나타냅니다. 공유한다면 special register를 바꿔 pin의 내부 routing을 device module과 host module 사이에서 전환해야 합니다.
Exynos 4210 예제의 `exynos4210_usb2_phy_config`는 mode switch를 사용하지 않고, `EXYNOS4210_NUM_PHYS`, `exynos4210_phys`, `exynos4210_rate_to_clk`를 연결합니다.
`rate_to_clk(unsigned long, u32 *)` callback은 PHY reference clock의 rate를 hardware register에 기록할 값으로 변환합니다.
3. Supporting SoCs
------------------
To support a new SoC a new file should be added to the drivers/phy
directory. Each SoC's configuration is stored in an instance of the
struct samsung_usb2_phy_config::
struct samsung_usb2_phy_config {
const struct samsung_usb2_common_phy *phys;
int (*rate_to_clk)(unsigned long, u32 *);
unsigned int num_phys;
bool has_mode_switch;
};
The num_phys is the number of phys handled by the driver. `*phys` is an
array that contains the configuration for each phy. The has_mode_switch
property is a boolean flag that determines whether the SoC has USB host
and device on a single pair of pins. If so, a special register has to
be modified to change the internal routing of these pins between a USB
device or host module.
For example the configuration for Exynos 4210 is following::
const struct samsung_usb2_phy_config exynos4210_usb2_phy_config = {
.has_mode_switch = 0,
.num_phys = EXYNOS4210_NUM_PHYS,
.phys = exynos4210_phys,
.rate_to_clk = exynos4210_rate_to_clk,
}
- `int (*rate_to_clk)(unsigned long, u32 *)`
The rate_to_clk callback is to convert the rate of the clock
used as the reference clock for the PHY module to the value
that should be written in the hardware register.
Exynos4210 PHY array와 power callback
71-106`exynos4210_phys` array는 네 PHY instance를 정의합니다. Label과 ID는 각각 `device`·`EXYNOS4210_DEVICE`, `host`·`EXYNOS4210_HOST`, `hsic0`·`EXYNOS4210_HSIC0`, `hsic1`·`EXYNOS4210_HSIC1`입니다.
각 instance는 `exynos4210_power_on`과 `exynos4210_power_off`를 연결하며 빈 sentinel entry `{}`로 array를 끝냅니다.
`power_on(struct samsung_usb2_phy_instance *)`과 `power_off(struct samsung_usb2_phy_instance *)` callback은 해당 SoC의 알맞은 register를 수정하여 PHY 전원을 켜고 끕니다.
The exynos4210_phys configuration array is as follows::
static const struct samsung_usb2_common_phy exynos4210_phys[] = {
{
.label = "device",
.id = EXYNOS4210_DEVICE,
.power_on = exynos4210_power_on,
.power_off = exynos4210_power_off,
},
{
.label = "host",
.id = EXYNOS4210_HOST,
.power_on = exynos4210_power_on,
.power_off = exynos4210_power_off,
},
{
.label = "hsic0",
.id = EXYNOS4210_HSIC0,
.power_on = exynos4210_power_on,
.power_off = exynos4210_power_off,
},
{
.label = "hsic1",
.id = EXYNOS4210_HSIC1,
.power_on = exynos4210_power_on,
.power_off = exynos4210_power_off,
},
{},
};
- `int (*power_on)(struct samsung_usb2_phy_instance *);`
`int (*power_off)(struct samsung_usb2_phy_instance *);`
These two callbacks are used to power on and power off the phy
by modifying appropriate registers.
DeviceTree compatible match 추가
107-117새 SoC의 마지막 driver 연결 단계는 `phy-samsung-usb2.c`의 `samsung_usb2_phy_of_match[]`에 compatible 값을 추가하는 것입니다.
Exynos4210 entry는 `CONFIG_PHY_EXYNOS4210_USB2`로 조건부 컴파일되며, compatible은 `samsung,exynos4210-usb2-phy`, data는 `&exynos4210_usb2_phy_config`입니다.
DeviceTree compatible이 SoC configuration data를 main adaptation driver에 연결합니다.
Final change to the driver is adding appropriate compatible value to the
phy-samsung-usb2.c file. In case of Exynos 4210 the following lines were
added to the struct of_device_id samsung_usb2_phy_of_match[] array::
#ifdef CONFIG_PHY_EXYNOS4210_USB2
{
.compatible = "samsung,exynos4210-usb2-phy",
.data = &exynos4210_usb2_phy_config,
},
#endif
SoC별 Kconfig 선택
118-131Kconfig는 compiled driver에 필요한 SoC 지원만 선택적으로 포함하게 합니다. Exynos4210의 `PHY_EXYNOS4210_USB2` option은 `Support for Exynos 4210`이라는 bool이며 `PHY_SAMSUNG_USB2`와 `CPU_EXYNOS4210`에 의존합니다.
이 option은 Samsung USB 2.0 PHY driver가 활성화된 상태에서 Exynos4210 전용 지원을 compile합니다. 원문 help는 사용 가능한 네 PHY를 device, host, `HSCI0`, `HSCI1`로 적고 있으며 이 표기를 그대로 보존합니다. 앞선 instance array의 symbol은 `HSIC0`, `HSIC1`입니다.
To add further flexibility to the driver the Kconfig file enables to
include support for selected SoCs in the compiled driver. The Kconfig
entry for Exynos 4210 is following::
config PHY_EXYNOS4210_USB2
bool "Support for Exynos 4210"
depends on PHY_SAMSUNG_USB2
depends on CPU_EXYNOS4210
help
Enable USB PHY support for Exynos 4210. This option requires that
Samsung USB 2.0 PHY driver is enabled and means that support for this
particular SoC is compiled in the driver. In case of Exynos 4210 four
phys are available - device, host, HSCI0 and HSCI1.
Makefile 연결과 완료 조건
132-137새 SoC 지원 source file을 Makefile에도 추가해야 합니다. Exynos4210은 `CONFIG_PHY_EXYNOS4210_USB2`가 선택됐을 때 `phy-exynos4210-usb2.o`를 build하도록 연결합니다.
SoC configuration, PHY array와 callback, compatible match, Kconfig, Makefile 단계를 모두 완료하면 새 SoC 지원 준비가 끝납니다.
Configuration에서 build 연결까지 모든 단계가 필요합니다.
The newly created file that supports the new SoC has to be also added to the
Makefile. In case of Exynos 4210 the added line is following::
obj-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o
After completing these steps the support for the new SoC should be ready.
요약과 해설
samsung-usb2.rst:1-137Samsung USB2 adaptation layer는 공통 probe·power 흐름과 SoC별 register sequence를 분리합니다. 새 SoC는 config와 PHY callback array를 정의하고 compatible match, Kconfig, Makefile을 모두 연결해야 합니다.