usb PHY linux驱动
?
本文以imx6ul?SoC為例。
?
涉及目錄及文件:
-
dts: linux-4.14.141\arch\arm\boot\dts\imx6ul.dtsi
-
controller: drivers\usb\chipidea
-
phy: drivers\usb\phy
?
幾點說明:
1)4.13?kernel
2)4.13內核中全部是usb2.0的PHY驅動,沒有usb3.0的驅動。也許usb3.0的PHY都不需要初始化,直接就可以使用,如femtoPHY。
3)imx6ul的usb?controller和phy都集成在SoC中
?
?
?
1. dts配置
\linux-4.14.141\arch\arm\boot\dts\imx6ul.dtsi
usbotg1: usb@02184000 {compatible = "fsl,imx6ul-usb", "fsl,imx27-usb";reg = <0x02184000 0x200>;interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;clocks = <&clks IMX6UL_CLK_USBOH3>;fsl,usbphy = <&usbphy1>;fsl,usbmisc = <&usbmisc 0>;fsl,anatop = <&anatop>;ahb-burst-config = <0x0>;tx-burst-size-dword = <0x10>;rx-burst-size-dword = <0x10>;status = "disabled"; };usbphy1: usbphy@020c9000 {compatible = "fsl,imx6ul-usbphy", "fsl,imx23-usbphy";reg = <0x020c9000 0x1000>;interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;clocks = <&clks IMX6UL_CLK_USBPHY1>;phy-3p0-supply = <®_3p0>;fsl,anatop = <&anatop>; };?
?
?
2.?usb?controller
drivers/usb/chipidea/ci_hdrc_imx.c
static const struct of_device_id ci_hdrc_imx_dt_ids[] = {{ .compatible = "fsl,imx23-usb", .data = &imx23_usb_data},{ .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},......{ .compatible = "fsl,imx6ul-usb", .data = &imx6ul_usb_data},{ .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data},{ /* sentinel */ } };static struct platform_driver ci_hdrc_imx_driver = {.probe = ci_hdrc_imx_probe,.remove = ci_hdrc_imx_remove,.shutdown = ci_hdrc_imx_shutdown,.driver = {.name = "imx_usb",.of_match_table = ci_hdrc_imx_dt_ids,.pm = &ci_hdrc_imx_pm_ops,}, };drivers/usb/chipidea/core.c
static struct platform_driver ci_hdrc_driver = {.probe = ci_hdrc_probe,.remove = ci_hdrc_remove,.driver = {.name = "ci_hdrc",.pm = &ci_pm_ops,}, };?
2.1 首先根據"fsl,imx6ul-usb"進行dts?match,執行ci_hdrc_imx_probe。在此函數中:
1)首先獲得devm_usb_get_phy_by_phandle("fsl,usbphy") 獲得phy,"fsl,usbphy"在dts中有定義
2)然后調用ci_hdrc_add_device添加platform?device ("ci_hdrc"),下一步會match?相應的platform?driver
函數流程如下:
chipidea/ci_hdrc_imx.c: ci_hdrc_imx_probe ->?devm_usb_get_phy_by_phandle |?ci_hdrc_add_device ->?chipidea/core.c: platform_device_add("ci_hdrc")
?
2.2 初始化PHY
1)上述添加platform?device ("ci_hdrc")后,會match到相應的platform?driver,然后執行ci_hdrc_probe
2)在ci_hdrc_probe中初始化usb?phy
函數流程如下:
chipidea/core.c: ci_hdrc_probe -> ci_usb_phy_init -> phy.h: usb_phy_init -> (phy->init)
?
?
3.? usb PHY
drivers/usb/phy/phy-mxs-usb.c
在該文件中主要實現PHY的相關操作函數,然后被controller調用進行初始化。
?
1)根據"fsl,imx6ul-usbphy"進行dts?match,match到后執行mxs_phy_probe
static const struct of_device_id mxs_phy_dt_ids[] = {{ .compatible = "fsl,imx6sx-usbphy", .data = &imx6sx_phy_data, },{ .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, },{ .compatible = "fsl,imx6q-usbphy", .data = &imx6q_phy_data, },{ .compatible = "fsl,imx23-usbphy", .data = &imx23_phy_data, },{ .compatible = "fsl,vf610-usbphy", .data = &vf610_phy_data, },{ .compatible = "fsl,imx6ul-usbphy", .data = &imx6ul_phy_data, },{ /* sentinel */ } };?
2)在mxs_phy_probe中先設置phy的相關操作函數
mxs_phy->phy.io_priv = base;mxs_phy->phy.dev = &pdev->dev;mxs_phy->phy.label = DRIVER_NAME;mxs_phy->phy.init = mxs_phy_init;mxs_phy->phy.shutdown = mxs_phy_shutdown;mxs_phy->phy.set_suspend = mxs_phy_suspend;mxs_phy->phy.notify_connect = mxs_phy_on_connect;mxs_phy->phy.notify_disconnect = mxs_phy_on_disconnect;mxs_phy->phy.type = USB_PHY_TYPE_USB2;mxs_phy->phy.set_wakeup = mxs_phy_set_wakeup;?
3)最后通過usb_add_phy_dev(&mxs_phy->phy)添加usb?PHY,被host或device?controller?driver使用。
?
?
4.?register
4.1?usb phy
1)usb?phy?register?base?address?
從上面可以得出usb?phy及地址是020c_9000,這也符合dts中的地址定義
?
2)在phy-mxs-usb.c中定義的寄存器地址偏移
#define HW_USBPHY_PWD 0x00 #define HW_USBPHY_TX 0x10 #define HW_USBPHY_CTRL 0x30 #define HW_USBPHY_CTRL_SET 0x34 #define HW_USBPHY_CTRL_CLR 0x38 #define HW_USBPHY_DEBUG_SET 0x54 #define HW_USBPHY_DEBUG_CLR 0x58 #define HW_USBPHY_IP 0x90 #define HW_USBPHY_IP_SET 0x94 #define HW_USBPHY_IP_CLR 0x98?
4.2 usb?controller
1)usb?controller?register?base?address?
從上面可以得出usb?phy及地址是0218_4000,這也符合dts中的地址定義
?
2)在chipidea/ci.h中定義的寄存器地址偏移
#define ID_ID 0x0 #define ID_HWGENERAL 0x4 #define ID_HWHOST 0x8 #define ID_HWDEVICE 0xc #define ID_HWTXBUF 0x10 #define ID_HWRXBUF 0x14 #define ID_SBUSCFG 0x90?
?
?
總結
以上是生活随笔為你收集整理的usb PHY linux驱动的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Teleport Ultra/Pro 1
- 下一篇: 本周最嗨马斯克,特斯拉股价一周飙涨33%