From: Huang, Tao Date: Wed, 11 Nov 2015 06:22:45 +0000 (+0800) Subject: Revert "phy: backport generic phy framework from kernel-3.18" X-Git-Tag: firefly_0821_release~3620 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=f5905620fdf1bec563447fa0d02f6f2e53ebb0c6;p=firefly-linux-kernel-4.4.55.git Revert "phy: backport generic phy framework from kernel-3.18" This reverts commit 23805582e3bbb67ba5b6c3952ac7a9f77b9913ce. --- diff --git a/Documentation/devicetree/bindings/phy/apm-xgene-phy.txt b/Documentation/devicetree/bindings/phy/apm-xgene-phy.txt deleted file mode 100644 index 5f3a65a9dd88..000000000000 --- a/Documentation/devicetree/bindings/phy/apm-xgene-phy.txt +++ /dev/null @@ -1,79 +0,0 @@ -* APM X-Gene 15Gbps Multi-purpose PHY nodes - -PHY nodes are defined to describe on-chip 15Gbps Multi-purpose PHY. Each -PHY (pair of lanes) has its own node. - -Required properties: -- compatible : Shall be "apm,xgene-phy". -- reg : PHY memory resource is the SDS PHY access resource. -- #phy-cells : Shall be 1 as it expects one argument for setting - the mode of the PHY. Possible values are 0 (SATA), - 1 (SGMII), 2 (PCIe), 3 (USB), and 4 (XFI). - -Optional properties: -- status : Shall be "ok" if enabled or "disabled" if disabled. - Default is "ok". -- clocks : Reference to the clock entry. -- apm,tx-eye-tuning : Manual control to fine tune the capture of the serial - bit lines from the automatic calibrated position. - Two set of 3-tuple setting for each (up to 3) - supported link speed on the host. Range from 0 to - 127 in unit of one bit period. Default is 10. -- apm,tx-eye-direction : Eye tuning manual control direction. 0 means sample - data earlier than the nominal sampling point. 1 means - sample data later than the nominal sampling point. - Two set of 3-tuple setting for each (up to 3) - supported link speed on the host. Default is 0. -- apm,tx-boost-gain : Frequency boost AC (LSB 3-bit) and DC (2-bit) - gain control. Two set of 3-tuple setting for each - (up to 3) supported link speed on the host. Range is - between 0 to 31 in unit of dB. Default is 3. -- apm,tx-amplitude : Amplitude control. Two set of 3-tuple setting for - each (up to 3) supported link speed on the host. - Range is between 0 to 199500 in unit of uV. - Default is 199500 uV. -- apm,tx-pre-cursor1 : 1st pre-cursor emphasis taps control. Two set of - 3-tuple setting for each (up to 3) supported link - speed on the host. Range is 0 to 273000 in unit of - uV. Default is 0. -- apm,tx-pre-cursor2 : 2st pre-cursor emphasis taps control. Two set of - 3-tuple setting for each (up to 3) supported link - speed on the host. Range is 0 to 127400 in unit uV. - Default is 0x0. -- apm,tx-post-cursor : Post-cursor emphasis taps control. Two set of - 3-tuple setting for Gen1, Gen2, and Gen3. Range is - between 0 to 0x1f in unit of 18.2mV. Default is 0xf. -- apm,tx-speed : Tx operating speed. One set of 3-tuple for each - supported link speed on the host. - 0 = 1-2Gbps - 1 = 2-4Gbps (1st tuple default) - 2 = 4-8Gbps - 3 = 8-15Gbps (2nd tuple default) - 4 = 2.5-4Gbps - 5 = 4-5Gbps - 6 = 5-6Gbps - 7 = 6-16Gbps (3rd tuple default) - -NOTE: PHY override parameters are board specific setting. - -Example: - phy1: phy@1f21a000 { - compatible = "apm,xgene-phy"; - reg = <0x0 0x1f21a000 0x0 0x100>; - #phy-cells = <1>; - status = "disabled"; - }; - - phy2: phy@1f22a000 { - compatible = "apm,xgene-phy"; - reg = <0x0 0x1f22a000 0x0 0x100>; - #phy-cells = <1>; - status = "ok"; - }; - - phy3: phy@1f23a000 { - compatible = "apm,xgene-phy"; - reg = <0x0 0x1f23a000 0x0 0x100>; - #phy-cells = <1>; - status = "ok"; - }; diff --git a/Documentation/devicetree/bindings/phy/bcm-phy.txt b/Documentation/devicetree/bindings/phy/bcm-phy.txt deleted file mode 100644 index 3dc8b3d2ffbb..000000000000 --- a/Documentation/devicetree/bindings/phy/bcm-phy.txt +++ /dev/null @@ -1,15 +0,0 @@ -BROADCOM KONA USB2 PHY - -Required properties: - - compatible: brcm,kona-usb2-phy - - reg: offset and length of the PHY registers - - #phy-cells: must be 0 -Refer to phy/phy-bindings.txt for the generic PHY binding properties - -Example: - - usbphy: usb-phy@3f130000 { - compatible = "brcm,kona-usb2-phy"; - reg = <0x3f130000 0x28>; - #phy-cells = <0>; - }; diff --git a/Documentation/devicetree/bindings/phy/berlin-sata-phy.txt b/Documentation/devicetree/bindings/phy/berlin-sata-phy.txt deleted file mode 100644 index 88f8c23384c0..000000000000 --- a/Documentation/devicetree/bindings/phy/berlin-sata-phy.txt +++ /dev/null @@ -1,34 +0,0 @@ -Berlin SATA PHY ---------------- - -Required properties: -- compatible: should be "marvell,berlin2q-sata-phy" -- address-cells: should be 1 -- size-cells: should be 0 -- phy-cells: from the generic PHY bindings, must be 1 -- reg: address and length of the register -- clocks: reference to the clock entry - -Sub-nodes: -Each PHY should be represented as a sub-node. - -Sub-nodes required properties: -- reg: the PHY number - -Example: - sata_phy: phy@f7e900a0 { - compatible = "marvell,berlin2q-sata-phy"; - reg = <0xf7e900a0 0x200>; - clocks = <&chip CLKID_SATA>; - #address-cells = <1>; - #size-cells = <0>; - #phy-cells = <1>; - - sata-phy@0 { - reg = <0>; - }; - - sata-phy@1 { - reg = <1>; - }; - }; diff --git a/Documentation/devicetree/bindings/phy/hix5hd2-phy.txt b/Documentation/devicetree/bindings/phy/hix5hd2-phy.txt deleted file mode 100644 index 296168b74d24..000000000000 --- a/Documentation/devicetree/bindings/phy/hix5hd2-phy.txt +++ /dev/null @@ -1,22 +0,0 @@ -Hisilicon hix5hd2 SATA PHY ------------------------ - -Required properties: -- compatible: should be "hisilicon,hix5hd2-sata-phy" -- reg: offset and length of the PHY registers -- #phy-cells: must be 0 -Refer to phy/phy-bindings.txt for the generic PHY binding properties - -Optional Properties: -- hisilicon,peripheral-syscon: phandle of syscon used to control peripheral. -- hisilicon,power-reg: offset and bit number within peripheral-syscon, - register of controlling sata power supply. - -Example: - sata_phy: phy@f9900000 { - compatible = "hisilicon,hix5hd2-sata-phy"; - reg = <0xf9900000 0x10000>; - #phy-cells = <0>; - hisilicon,peripheral-syscon = <&peripheral_ctrl>; - hisilicon,power-reg = <0x8 10>; - }; diff --git a/Documentation/devicetree/bindings/phy/phy-bindings.txt b/Documentation/devicetree/bindings/phy/phy-bindings.txt deleted file mode 100644 index 1293c321754c..000000000000 --- a/Documentation/devicetree/bindings/phy/phy-bindings.txt +++ /dev/null @@ -1,70 +0,0 @@ -This document explains only the device tree data binding. For general -information about PHY subsystem refer to Documentation/phy.txt - -PHY device node -=============== - -Required Properties: -#phy-cells: Number of cells in a PHY specifier; The meaning of all those - cells is defined by the binding for the phy node. The PHY - provider can use the values in cells to find the appropriate - PHY. - -Optional Properties: -phy-supply: Phandle to a regulator that provides power to the PHY. This - regulator will be managed during the PHY power on/off sequence. - -For example: - -phys: phy { - compatible = "xxx"; - reg = <...>; - . - . - #phy-cells = <1>; - . - . -}; - -That node describes an IP block (PHY provider) that implements 2 different PHYs. -In order to differentiate between these 2 PHYs, an additional specifier should be -given while trying to get a reference to it. - -PHY user node -============= - -Required Properties: -phys : the phandle for the PHY device (used by the PHY subsystem) -phy-names : the names of the PHY corresponding to the PHYs present in the - *phys* phandle - -Example 1: -usb1: usb_otg_ss@xxx { - compatible = "xxx"; - reg = ; - . - . - phys = <&usb2_phy>, <&usb3_phy>; - phy-names = "usb2phy", "usb3phy"; - . - . -}; - -This node represents a controller that uses two PHYs, one for usb2 and one for -usb3. - -Example 2: -usb2: usb_otg_ss@xxx { - compatible = "xxx"; - reg = ; - . - . - phys = <&phys 1>; - phy-names = "usbphy"; - . - . -}; - -This node represents a controller that uses one of the PHYs of the PHY provider -device defined previously. Note that the phy handle has an additional specifier -"1" to differentiate between the two PHYs. diff --git a/Documentation/devicetree/bindings/phy/phy-miphy365x.txt b/Documentation/devicetree/bindings/phy/phy-miphy365x.txt deleted file mode 100644 index 42c880886cf7..000000000000 --- a/Documentation/devicetree/bindings/phy/phy-miphy365x.txt +++ /dev/null @@ -1,76 +0,0 @@ -STMicroelectronics STi MIPHY365x PHY binding -============================================ - -This binding describes a miphy device that is used to control PHY hardware -for SATA and PCIe. - -Required properties (controller (parent) node): -- compatible : Should be "st,miphy365x-phy" -- st,syscfg : Should be a phandle of the system configuration register group - which contain the SATA, PCIe mode setting bits - -Required nodes : A sub-node is required for each channel the controller - provides. Address range information including the usual - 'reg' and 'reg-names' properties are used inside these - nodes to describe the controller's topology. These nodes - are translated by the driver's .xlate() function. - -Required properties (port (child) node): -- #phy-cells : Should be 1 (See second example) - Cell after port phandle is device type from: - - MIPHY_TYPE_SATA - - MIPHY_TYPE_PCI -- reg : Address and length of register sets for each device in - "reg-names" -- reg-names : The names of the register addresses corresponding to the - registers filled in "reg": - - sata: For SATA devices - - pcie: For PCIe devices - - syscfg: To specify the syscfg based config register - -Optional properties (port (child) node): -- st,sata-gen : Generation of locally attached SATA IP. Expected values - are {1,2,3). If not supplied generation 1 hardware will - be expected -- st,pcie-tx-pol-inv : Bool property to invert the polarity PCIe Tx (Txn/Txp) -- st,sata-tx-pol-inv : Bool property to invert the polarity SATA Tx (Txn/Txp) - -Example: - - miphy365x_phy: miphy365x@fe382000 { - compatible = "st,miphy365x-phy"; - st,syscfg = <&syscfg_rear>; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - phy_port0: port@fe382000 { - reg = <0xfe382000 0x100>, <0xfe394000 0x100>, <0x824 0x4>; - reg-names = "sata", "pcie", "syscfg"; - #phy-cells = <1>; - st,sata-gen = <3>; - }; - - phy_port1: port@fe38a000 { - reg = <0xfe38a000 0x100>, <0xfe804000 0x100>, <0x828 0x4>;; - reg-names = "sata", "pcie", "syscfg"; - #phy-cells = <1>; - st,pcie-tx-pol-inv; - }; - }; - -Specifying phy control of devices -================================= - -Device nodes should specify the configuration required in their "phys" -property, containing a phandle to the phy port node and a device type. - -Example: - -#include - - sata0: sata@fe380000 { - ... - phys = <&phy_port0 MIPHY_TYPE_SATA>; - ... - }; diff --git a/Documentation/devicetree/bindings/phy/phy-stih407-usb.txt b/Documentation/devicetree/bindings/phy/phy-stih407-usb.txt deleted file mode 100644 index 1ef8228db73b..000000000000 --- a/Documentation/devicetree/bindings/phy/phy-stih407-usb.txt +++ /dev/null @@ -1,30 +0,0 @@ -ST STiH407 USB PHY controller - -This file documents the dt bindings for the usb picoPHY driver which is the PHY for both USB2 and USB3 -host controllers (when controlling usb2/1.1 devices) available on STiH407 SoC family from STMicroelectronics. - -Required properties: -- compatible : should be "st,stih407-usb2-phy" -- reg : contain the offset and length of the system configuration registers - used as glue logic to control & parameter phy -- reg-names : the names of the system configuration registers in "reg", should be "param" and "reg" -- st,syscfg : sysconfig register to manage phy parameter at driver level -- resets : list of phandle and reset specifier pairs. There should be two entries, one - for the whole phy and one for the port -- reset-names : list of reset signal names. Should be "global" and "port" -See: Documentation/devicetree/bindings/reset/st,sti-powerdown.txt -See: Documentation/devicetree/bindings/reset/reset.txt - -Example: - -usb2_picophy0: usbpicophy@f8 { - compatible = "st,stih407-usb2-phy"; - reg = <0xf8 0x04>, /* syscfg 5062 */ - <0xf4 0x04>; /* syscfg 5061 */ - reg-names = "param", "ctrl"; - #phy-cells = <0>; - st,syscfg = <&syscfg_core>; - resets = <&softreset STIH407_PICOPHY_SOFTRESET>, - <&picophyreset STIH407_PICOPHY0_RESET>; - reset-names = "global", "port"; -}; diff --git a/Documentation/devicetree/bindings/phy/phy-stih41x-usb.txt b/Documentation/devicetree/bindings/phy/phy-stih41x-usb.txt deleted file mode 100644 index 00944a05ee6b..000000000000 --- a/Documentation/devicetree/bindings/phy/phy-stih41x-usb.txt +++ /dev/null @@ -1,24 +0,0 @@ -STMicroelectronics STiH41x USB PHY binding ------------------------------------------- - -This file contains documentation for the usb phy found in STiH415/6 SoCs from -STMicroelectronics. - -Required properties: -- compatible : should be "st,stih416-usb-phy" or "st,stih415-usb-phy" -- st,syscfg : should be a phandle of the syscfg node -- clock-names : must contain "osc_phy" -- clocks : must contain an entry for each name in clock-names. -See: Documentation/devicetree/bindings/clock/clock-bindings.txt -- #phy-cells : must be 0 for this phy -See: Documentation/devicetree/bindings/phy/phy-bindings.txt - -Example: - -usb2_phy: usb2phy@0 { - compatible = "st,stih416-usb-phy"; - #phy-cell = <0>; - st,syscfg = <&syscfg_rear>; - clocks = <&clk_sysin>; - clock-names = "osc_phy"; -}; diff --git a/Documentation/devicetree/bindings/phy/qcom-apq8064-sata-phy.txt b/Documentation/devicetree/bindings/phy/qcom-apq8064-sata-phy.txt deleted file mode 100644 index 952f6c96bab9..000000000000 --- a/Documentation/devicetree/bindings/phy/qcom-apq8064-sata-phy.txt +++ /dev/null @@ -1,24 +0,0 @@ -Qualcomm APQ8064 SATA PHY Controller ------------------------------------- - -SATA PHY nodes are defined to describe on-chip SATA Physical layer controllers. -Each SATA PHY controller should have its own node. - -Required properties: -- compatible: compatible list, contains "qcom,apq8064-sata-phy". -- reg: offset and length of the SATA PHY register set; -- #phy-cells: must be zero -- clocks: a list of phandles and clock-specifier pairs, one for each entry in - clock-names. -- clock-names: must be "cfg" for phy config clock. - -Example: - sata_phy: sata-phy@1b400000 { - compatible = "qcom,apq8064-sata-phy"; - reg = <0x1b400000 0x200>; - - clocks = <&gcc SATA_PHY_CFG_CLK>; - clock-names = "cfg"; - - #phy-cells = <0>; - }; diff --git a/Documentation/devicetree/bindings/phy/qcom-dwc3-usb-phy.txt b/Documentation/devicetree/bindings/phy/qcom-dwc3-usb-phy.txt deleted file mode 100644 index 86f2dbe07ed4..000000000000 --- a/Documentation/devicetree/bindings/phy/qcom-dwc3-usb-phy.txt +++ /dev/null @@ -1,39 +0,0 @@ -Qualcomm DWC3 HS AND SS PHY CONTROLLER --------------------------------------- - -DWC3 PHY nodes are defined to describe on-chip Synopsis Physical layer -controllers. Each DWC3 PHY controller should have its own node. - -Required properties: -- compatible: should contain one of the following: - - "qcom,dwc3-hs-usb-phy" for High Speed Synopsis PHY controller - - "qcom,dwc3-ss-usb-phy" for Super Speed Synopsis PHY controller -- reg: offset and length of the DWC3 PHY controller register set -- #phy-cells: must be zero -- clocks: a list of phandles and clock-specifier pairs, one for each entry in - clock-names. -- clock-names: Should contain "ref" for the PHY reference clock - -Optional clocks: - "xo" External reference clock - -Example: - phy@100f8800 { - compatible = "qcom,dwc3-hs-usb-phy"; - reg = <0x100f8800 0x30>; - clocks = <&gcc USB30_0_UTMI_CLK>; - clock-names = "ref"; - #phy-cells = <0>; - - status = "ok"; - }; - - phy@100f8830 { - compatible = "qcom,dwc3-ss-usb-phy"; - reg = <0x100f8830 0x30>; - clocks = <&gcc USB30_0_MASTER_CLK>; - clock-names = "ref"; - #phy-cells = <0>; - - status = "ok"; - }; diff --git a/Documentation/devicetree/bindings/phy/qcom-ipq806x-sata-phy.txt b/Documentation/devicetree/bindings/phy/qcom-ipq806x-sata-phy.txt deleted file mode 100644 index 76bfbd056202..000000000000 --- a/Documentation/devicetree/bindings/phy/qcom-ipq806x-sata-phy.txt +++ /dev/null @@ -1,23 +0,0 @@ -Qualcomm IPQ806x SATA PHY Controller ------------------------------------- - -SATA PHY nodes are defined to describe on-chip SATA Physical layer controllers. -Each SATA PHY controller should have its own node. - -Required properties: -- compatible: compatible list, contains "qcom,ipq806x-sata-phy" -- reg: offset and length of the SATA PHY register set; -- #phy-cells: must be zero -- clocks: must be exactly one entry -- clock-names: must be "cfg" - -Example: - sata_phy: sata-phy@1b400000 { - compatible = "qcom,ipq806x-sata-phy"; - reg = <0x1b400000 0x200>; - - clocks = <&gcc SATA_PHY_CFG_CLK>; - clock-names = "cfg"; - - #phy-cells = <0>; - }; diff --git a/Documentation/devicetree/bindings/phy/rcar-gen2-phy.txt b/Documentation/devicetree/bindings/phy/rcar-gen2-phy.txt deleted file mode 100644 index 00fc52a034b7..000000000000 --- a/Documentation/devicetree/bindings/phy/rcar-gen2-phy.txt +++ /dev/null @@ -1,51 +0,0 @@ -* Renesas R-Car generation 2 USB PHY - -This file provides information on what the device node for the R-Car generation -2 USB PHY contains. - -Required properties: -- compatible: "renesas,usb-phy-r8a7790" if the device is a part of R8A7790 SoC. - "renesas,usb-phy-r8a7791" if the device is a part of R8A7791 SoC. -- reg: offset and length of the register block. -- #address-cells: number of address cells for the USB channel subnodes, must - be <1>. -- #size-cells: number of size cells for the USB channel subnodes, must be <0>. -- clocks: clock phandle and specifier pair. -- clock-names: string, clock input name, must be "usbhs". - -The USB PHY device tree node should have the subnodes corresponding to the USB -channels. These subnodes must contain the following properties: -- reg: the USB controller selector; see the table below for the values. -- #phy-cells: see phy-bindings.txt in the same directory, must be <1>. - -The phandle's argument in the PHY specifier is the USB controller selector for -the USB channel; see the selector meanings below: - -+-----------+---------------+---------------+ -|\ Selector | | | -+ --------- + 0 | 1 | -| Channel \| | | -+-----------+---------------+---------------+ -| 0 | PCI EHCI/OHCI | HS-USB | -| 2 | PCI EHCI/OHCI | xHCI | -+-----------+---------------+---------------+ - -Example (Lager board): - - usb-phy@e6590100 { - compatible = "renesas,usb-phy-r8a7790"; - reg = <0 0xe6590100 0 0x100>; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&mstp7_clks R8A7790_CLK_HSUSB>; - clock-names = "usbhs"; - - usb-channel@0 { - reg = <0>; - #phy-cells = <1>; - }; - usb-channel@2 { - reg = <2>; - #phy-cells = <1>; - }; - }; diff --git a/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt deleted file mode 100644 index 18ccc2fb2fec..000000000000 --- a/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt +++ /dev/null @@ -1,17 +0,0 @@ -ROCKCHIP USB2 PHY - -Required properties: - - compatible: rockchip,rk3288-usb-phy - - rockchip,grf : phandle to the syscon managing the "general - register files" - - #phy-cells: must be 1 -Refer to phy/phy-bindings.txt for the generic PHY binding -properties - -Example: - - usbphy: phy { - #phy-cells = <1>; - compatible = "rockchip,rk3288-usb-phy"; - rockchip,grf = <&grf>; - }; diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt deleted file mode 100644 index 15e0f2c7130f..000000000000 --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt +++ /dev/null @@ -1,169 +0,0 @@ -Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY -------------------------------------------------- - -Required properties: -- compatible : should be "samsung,s5pv210-mipi-video-phy"; -- reg : offset and length of the MIPI DPHY register set; -- #phy-cells : from the generic phy bindings, must be 1; - -For "samsung,s5pv210-mipi-video-phy" compatible PHYs the second cell in -the PHY specifier identifies the PHY and its meaning is as follows: - 0 - MIPI CSIS 0, - 1 - MIPI DSIM 0, - 2 - MIPI CSIS 1, - 3 - MIPI DSIM 1. - -Samsung EXYNOS SoC series Display Port PHY -------------------------------------------------- - -Required properties: -- compatible : should be one of the following supported values: - - "samsung,exynos5250-dp-video-phy" - - "samsung,exynos5420-dp-video-phy" -- samsung,pmu-syscon: phandle for PMU system controller interface, used to - control pmu registers for power isolation. -- #phy-cells : from the generic PHY bindings, must be 0; - -Samsung S5P/EXYNOS SoC series USB PHY -------------------------------------------------- - -Required properties: -- compatible : should be one of the listed compatibles: - - "samsung,exynos3250-usb2-phy" - - "samsung,exynos4210-usb2-phy" - - "samsung,exynos4x12-usb2-phy" - - "samsung,exynos5250-usb2-phy" - - "samsung,s5pv210-usb2-phy" -- reg : a list of registers used by phy driver - - first and obligatory is the location of phy modules registers -- samsung,sysreg-phandle - handle to syscon used to control the system registers -- samsung,pmureg-phandle - handle to syscon used to control PMU registers -- #phy-cells : from the generic phy bindings, must be 1; -- clocks and clock-names: - - the "phy" clock is required by the phy module, used as a gate - - the "ref" clock is used to get the rate of the clock provided to the - PHY module - -The first phandle argument in the PHY specifier identifies the PHY, its -meaning is compatible dependent. For the currently supported SoCs (Exynos 4210 -and Exynos 4212) it is as follows: - 0 - USB device ("device"), - 1 - USB host ("host"), - 2 - HSIC0 ("hsic0"), - 3 - HSIC1 ("hsic1"), -Exynos3250 has only USB device phy available as phy 0. - -Exynos 4210 and Exynos 4212 use mode switching and require that mode switch -register is supplied. - -Example: - -For Exynos 4412 (compatible with Exynos 4212): - -usbphy: phy@125b0000 { - compatible = "samsung,exynos4x12-usb2-phy"; - reg = <0x125b0000 0x100>; - clocks = <&clock 305>, <&clock 2>; - clock-names = "phy", "ref"; - status = "okay"; - #phy-cells = <1>; - samsung,sysreg-phandle = <&sys_reg>; - samsung,pmureg-phandle = <&pmu_reg>; -}; - -Then the PHY can be used in other nodes such as: - -phy-consumer@12340000 { - phys = <&usbphy 2>; - phy-names = "phy"; -}; - -Refer to DT bindings documentation of particular PHY consumer devices for more -information about required PHYs and the way of specification. - -Samsung SATA PHY Controller ---------------------------- - -SATA PHY nodes are defined to describe on-chip SATA Physical layer controllers. -Each SATA PHY controller should have its own node. - -Required properties: -- compatible : compatible list, contains "samsung,exynos5250-sata-phy" -- reg : offset and length of the SATA PHY register set; -- #phy-cells : must be zero -- clocks : must be exactly one entry -- clock-names : must be "sata_phyctrl" -- samsung,exynos-sataphy-i2c-phandle : a phandle to the I2C device, no arguments -- samsung,syscon-phandle : a phandle to the PMU system controller, no arguments - -Example: - sata_phy: sata-phy@12170000 { - compatible = "samsung,exynos5250-sata-phy"; - reg = <0x12170000 0x1ff>; - clocks = <&clock 287>; - clock-names = "sata_phyctrl"; - #phy-cells = <0>; - samsung,exynos-sataphy-i2c-phandle = <&sata_phy_i2c>; - samsung,syscon-phandle = <&pmu_syscon>; - }; - -Device-Tree bindings for sataphy i2c client driver --------------------------------------------------- - -Required properties: -compatible: Should be "samsung,exynos-sataphy-i2c" -- reg: I2C address of the sataphy i2c device. - -Example: - - sata_phy_i2c:sata-phy@38 { - compatible = "samsung,exynos-sataphy-i2c"; - reg = <0x38>; - }; - -Samsung Exynos5 SoC series USB DRD PHY controller --------------------------------------------------- - -Required properties: -- compatible : Should be set to one of the following supported values: - - "samsung,exynos5250-usbdrd-phy" - for exynos5250 SoC, - - "samsung,exynos5420-usbdrd-phy" - for exynos5420 SoC. -- reg : Register offset and length of USB DRD PHY register set; -- clocks: Clock IDs array as required by the controller -- clock-names: names of clocks correseponding to IDs in the clock property; - Required clocks: - - phy: main PHY clock (same as USB DRD controller i.e. DWC3 IP clock), - used for register access. - - ref: PHY's reference clock (usually crystal clock), used for - PHY operations, associated by phy name. It is used to - determine bit values for clock settings register. - For Exynos5420 this is given as 'sclk_usbphy30' in CMU. -- samsung,pmu-syscon: phandle for PMU system controller interface, used to - control pmu registers for power isolation. -- #phy-cells : from the generic PHY bindings, must be 1; - -For "samsung,exynos5250-usbdrd-phy" and "samsung,exynos5420-usbdrd-phy" -compatible PHYs, the second cell in the PHY specifier identifies the -PHY id, which is interpreted as follows: - 0 - UTMI+ type phy, - 1 - PIPE3 type phy, - -Example: - usbdrd_phy: usbphy@12100000 { - compatible = "samsung,exynos5250-usbdrd-phy"; - reg = <0x12100000 0x100>; - clocks = <&clock 286>, <&clock 1>; - clock-names = "phy", "ref"; - samsung,pmu-syscon = <&pmu_system_controller>; - #phy-cells = <1>; - }; - -- aliases: For SoCs like Exynos5420 having multiple USB 3.0 DRD PHY controllers, - 'usbdrd_phy' nodes should have numbered alias in the aliases node, - in the form of usbdrdphyN, N = 0, 1... (depending on number of - controllers). -Example: - aliases { - usbdrdphy0 = &usb3_phy0; - usbdrdphy1 = &usb3_phy1; - }; diff --git a/Documentation/devicetree/bindings/phy/st-spear-miphy.txt b/Documentation/devicetree/bindings/phy/st-spear-miphy.txt deleted file mode 100644 index 2a6bfdcc09b3..000000000000 --- a/Documentation/devicetree/bindings/phy/st-spear-miphy.txt +++ /dev/null @@ -1,15 +0,0 @@ -ST SPEAr miphy DT details -========================= - -ST Microelectronics SPEAr miphy is a phy controller supporting PCIe and SATA. - -Required properties: -- compatible : should be "st,spear1310-miphy" or "st,spear1340-miphy" -- reg : offset and length of the PHY register set. -- misc: phandle for the syscon node to access misc registers -- #phy-cells : from the generic PHY bindings, must be 1. - - cell[1]: 0 if phy used for SATA, 1 for PCIe. - -Optional properties: -- phy-id: Instance id of the phy. Only required when there are multiple phys - present on a implementation. diff --git a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt deleted file mode 100644 index 16528b9eb561..000000000000 --- a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt +++ /dev/null @@ -1,37 +0,0 @@ -Allwinner sun4i USB PHY ------------------------ - -Required properties: -- compatible : should be one of - * allwinner,sun4i-a10-usb-phy - * allwinner,sun5i-a13-usb-phy - * allwinner,sun6i-a31-usb-phy - * allwinner,sun7i-a20-usb-phy -- reg : a list of offset + length pairs -- reg-names : - * "phy_ctrl" - * "pmu1" - * "pmu2" for sun4i, sun6i or sun7i -- #phy-cells : from the generic phy bindings, must be 1 -- clocks : phandle + clock specifier for the phy clocks -- clock-names : - * "usb_phy" for sun4i, sun5i or sun7i - * "usb0_phy", "usb1_phy" and "usb2_phy" for sun6i -- resets : a list of phandle + reset specifier pairs -- reset-names : - * "usb0_reset" - * "usb1_reset" - * "usb2_reset" for sun4i, sun6i or sun7i - -Example: - usbphy: phy@0x01c13400 { - #phy-cells = <1>; - compatible = "allwinner,sun4i-a10-usb-phy"; - /* phy base regs, phy1 pmu reg, phy2 pmu reg */ - reg = <0x01c13400 0x10 0x01c14800 0x4 0x01c1c800 0x4>; - reg-names = "phy_ctrl", "pmu1", "pmu2"; - clocks = <&usb_clk 8>; - clock-names = "usb_phy"; - resets = <&usb_clk 1>, <&usb_clk 2>; - reset-names = "usb1_reset", "usb2_reset"; - }; diff --git a/Documentation/devicetree/bindings/phy/ti-phy.txt b/Documentation/devicetree/bindings/phy/ti-phy.txt deleted file mode 100644 index 305e3df3d9b1..000000000000 --- a/Documentation/devicetree/bindings/phy/ti-phy.txt +++ /dev/null @@ -1,102 +0,0 @@ -TI PHY: DT DOCUMENTATION FOR PHYs in TI PLATFORMs - -OMAP CONTROL PHY - -Required properties: - - compatible: Should be one of - "ti,control-phy-otghs" - if it has otghs_control mailbox register as on OMAP4. - "ti,control-phy-usb2" - if it has Power down bit in control_dev_conf register - e.g. USB2_PHY on OMAP5. - "ti,control-phy-pipe3" - if it has DPLL and individual Rx & Tx power control - e.g. USB3 PHY and SATA PHY on OMAP5. - "ti,control-phy-pcie" - for pcie to support external clock for pcie and to - set PCS delay value. - e.g. PCIE PHY in DRA7x - "ti,control-phy-usb2-dra7" - if it has power down register like USB2 PHY on - DRA7 platform. - "ti,control-phy-usb2-am437" - if it has power down register like USB2 PHY on - AM437 platform. - - reg : register ranges as listed in the reg-names property - - reg-names: "otghs_control" for control-phy-otghs - "power", "pcie_pcs" and "control_sma" for control-phy-pcie - "power" for all other types - -omap_control_usb: omap-control-usb@4a002300 { - compatible = "ti,control-phy-otghs"; - reg = <0x4a00233c 0x4>; - reg-names = "otghs_control"; -}; - -OMAP USB2 PHY - -Required properties: - - compatible: Should be "ti,omap-usb2" - - reg : Address and length of the register set for the device. - - #phy-cells: determine the number of cells that should be given in the - phandle while referencing this phy. - - clocks: a list of phandles and clock-specifier pairs, one for each entry in - clock-names. - - clock-names: should include: - * "wkupclk" - wakeup clock. - * "refclk" - reference clock (optional). - -Optional properties: - - ctrl-module : phandle of the control module used by PHY driver to power on - the PHY. - -This is usually a subnode of ocp2scp to which it is connected. - -usb2phy@4a0ad080 { - compatible = "ti,omap-usb2"; - reg = <0x4a0ad080 0x58>; - ctrl-module = <&omap_control_usb>; - #phy-cells = <0>; - clocks = <&usb_phy_cm_clk32k>, <&usb_otg_ss_refclk960m>; - clock-names = "wkupclk", "refclk"; -}; - -TI PIPE3 PHY - -Required properties: - - compatible: Should be "ti,phy-usb3", "ti,phy-pipe3-sata" or - "ti,phy-pipe3-pcie. "ti,omap-usb3" is deprecated. - - reg : Address and length of the register set for the device. - - reg-names: The names of the register addresses corresponding to the registers - filled in "reg". - - #phy-cells: determine the number of cells that should be given in the - phandle while referencing this phy. - - clocks: a list of phandles and clock-specifier pairs, one for each entry in - clock-names. - - clock-names: should include: - * "wkupclk" - wakeup clock. - * "sysclk" - system clock. - * "refclk" - reference clock. - * "dpll_ref" - external dpll ref clk - * "dpll_ref_m2" - external dpll ref clk - * "phy-div" - divider for apll - * "div-clk" - apll clock - -Optional properties: - - ctrl-module : phandle of the control module used by PHY driver to power on - the PHY. - - id: If there are multiple instance of the same type, in order to - differentiate between each instance "id" can be used (e.g., multi-lane PCIe - PHY). If "id" is not provided, it is set to default value of '1'. - -This is usually a subnode of ocp2scp to which it is connected. - -usb3phy@4a084400 { - compatible = "ti,phy-usb3"; - reg = <0x4a084400 0x80>, - <0x4a084800 0x64>, - <0x4a084c00 0x40>; - reg-names = "phy_rx", "phy_tx", "pll_ctrl"; - ctrl-module = <&omap_control_usb>; - #phy-cells = <0>; - clocks = <&usb_phy_cm_clk32k>, - <&sys_clkin>, - <&usb_otg_ss_refclk960m>; - clock-names = "wkupclk", - "sysclk", - "refclk"; -}; diff --git a/drivers/Kconfig b/drivers/Kconfig index 27d02dccf21b..5ed28e0d644a 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -168,8 +168,6 @@ source "drivers/ipack/Kconfig" source "drivers/reset/Kconfig" -source "drivers/phy/Kconfig" - source "drivers/gator/Kconfig" source "drivers/headset_observe/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index c7d1ba752f5a..79708d325faf 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -8,8 +8,6 @@ obj-y += irqchip/ obj-y += bus/ -obj-$(CONFIG_GENERIC_PHY) += phy/ - # GPIO must come after pinctrl as gpios may need to mux pins etc obj-y += pinctrl/ obj-y += gpio/ diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig deleted file mode 100644 index 2a436e607f99..000000000000 --- a/drivers/phy/Kconfig +++ /dev/null @@ -1,259 +0,0 @@ -# -# PHY -# - -menu "PHY Subsystem" - -config GENERIC_PHY - bool "PHY Core" - help - Generic PHY support. - - This framework is designed to provide a generic interface for PHY - devices present in the kernel. This layer will have the generic - API by which phy drivers can create PHY using the phy framework and - phy users can obtain reference to the PHY. All the users of this - framework should select this config. - -config PHY_BERLIN_SATA - tristate "Marvell Berlin SATA PHY driver" - depends on ARCH_BERLIN && HAS_IOMEM && OF - select GENERIC_PHY - help - Enable this to support the SATA PHY on Marvell Berlin SoCs. - -config PHY_EXYNOS_MIPI_VIDEO - tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver" - depends on HAS_IOMEM - depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST - select GENERIC_PHY - default y if ARCH_S5PV210 || ARCH_EXYNOS - help - Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung S5P - and EXYNOS SoCs. - -config PHY_MVEBU_SATA - def_bool y - depends on ARCH_DOVE || MACH_DOVE || MACH_KIRKWOOD - depends on OF - select GENERIC_PHY - -config PHY_MIPHY365X - tristate "STMicroelectronics MIPHY365X PHY driver for STiH41x series" - depends on ARCH_STI - depends on HAS_IOMEM - depends on OF - select GENERIC_PHY - help - Enable this to support the miphy transceiver (for SATA/PCIE) - that is part of STMicroelectronics STiH41x SoC series. - -config PHY_RCAR_GEN2 - tristate "Renesas R-Car generation 2 USB PHY driver" - depends on ARCH_SHMOBILE - depends on GENERIC_PHY - help - Support for USB PHY found on Renesas R-Car generation 2 SoCs. - -config OMAP_CONTROL_PHY - tristate "OMAP CONTROL PHY Driver" - depends on ARCH_OMAP2PLUS || COMPILE_TEST - help - Enable this to add support for the PHY part present in the control - module. This driver has API to power on the USB2 PHY and to write to - the mailbox. The mailbox is present only in omap4 and the register to - power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has an - additional register to power on USB3 PHY/SATA PHY/PCIE PHY - (PIPE3 PHY). - -config OMAP_USB2 - tristate "OMAP USB2 PHY Driver" - depends on ARCH_OMAP2PLUS - depends on USB_PHY - select GENERIC_PHY - select OMAP_CONTROL_PHY - depends on OMAP_OCP2SCP - help - Enable this to support the transceiver that is part of SOC. This - driver takes care of all the PHY functionality apart from comparator. - The USB OTG controller communicates with the comparator using this - driver. - -config TI_PIPE3 - tristate "TI PIPE3 PHY Driver" - depends on ARCH_OMAP2PLUS || COMPILE_TEST - select GENERIC_PHY - select OMAP_CONTROL_PHY - depends on OMAP_OCP2SCP - help - Enable this to support the PIPE3 PHY that is part of TI SOCs. This - driver takes care of all the PHY functionality apart from comparator. - This driver interacts with the "OMAP Control PHY Driver" to power - on/off the PHY. - -config TWL4030_USB - tristate "TWL4030 USB Transceiver Driver" - depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS - depends on USB_PHY - select GENERIC_PHY - help - Enable this to support the USB OTG transceiver on TWL4030 - family chips (including the TWL5030 and TPS659x0 devices). - This transceiver supports high and full speed devices plus, - in host mode, low speed. - -config PHY_EXYNOS_DP_VIDEO - tristate "EXYNOS SoC series Display Port PHY driver" - depends on OF - depends on ARCH_EXYNOS || COMPILE_TEST - default ARCH_EXYNOS - select GENERIC_PHY - help - Support for Display Port PHY found on Samsung EXYNOS SoCs. - -config BCM_KONA_USB2_PHY - tristate "Broadcom Kona USB2 PHY Driver" - depends on HAS_IOMEM - select GENERIC_PHY - help - Enable this to support the Broadcom Kona USB 2.0 PHY. - -config PHY_EXYNOS5250_SATA - tristate "Exynos5250 Sata SerDes/PHY driver" - depends on SOC_EXYNOS5250 - depends on HAS_IOMEM - depends on OF - select GENERIC_PHY - select I2C - select I2C_S3C2410 - select MFD_SYSCON - help - Enable this to support SATA SerDes/Phy found on Samsung's - Exynos5250 based SoCs.This SerDes/Phy supports SATA 1.5 Gb/s, - SATA 3.0 Gb/s, SATA 6.0 Gb/s speeds. It supports one SATA host - port to accept one SATA device. - -config PHY_HIX5HD2_SATA - tristate "HIX5HD2 SATA PHY Driver" - depends on ARCH_HIX5HD2 && OF && HAS_IOMEM - select GENERIC_PHY - select MFD_SYSCON - help - Support for SATA PHY on Hisilicon hix5hd2 Soc. - -config PHY_SUN4I_USB - tristate "Allwinner sunxi SoC USB PHY driver" - depends on ARCH_SUNXI && HAS_IOMEM && OF - depends on RESET_CONTROLLER - select GENERIC_PHY - help - Enable this to support the transceiver that is part of Allwinner - sunxi SoCs. - - This driver controls the entire USB PHY block, both the USB OTG - parts, as well as the 2 regular USB 2 host PHYs. - -config PHY_SAMSUNG_USB2 - tristate "Samsung USB 2.0 PHY driver" - depends on HAS_IOMEM - depends on USB_EHCI_EXYNOS || USB_OHCI_EXYNOS || USB_DWC2 - select GENERIC_PHY - select MFD_SYSCON - default ARCH_EXYNOS - help - Enable this to support the Samsung USB 2.0 PHY driver for Samsung - SoCs. This driver provides the interface for USB 2.0 PHY. Support - for particular PHYs will be enabled based on the SoC type in addition - to this driver. - -config PHY_S5PV210_USB2 - bool "Support for S5PV210" - depends on PHY_SAMSUNG_USB2 - depends on ARCH_S5PV210 - help - Enable USB PHY support for S5PV210. 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 S5PV210 two phys - are available - device and host. - -config PHY_EXYNOS4210_USB2 - bool - depends on PHY_SAMSUNG_USB2 - default CPU_EXYNOS4210 - -config PHY_EXYNOS4X12_USB2 - bool - depends on PHY_SAMSUNG_USB2 - default SOC_EXYNOS3250 || SOC_EXYNOS4212 || SOC_EXYNOS4412 - -config PHY_EXYNOS5250_USB2 - bool - depends on PHY_SAMSUNG_USB2 - default SOC_EXYNOS5250 || SOC_EXYNOS5420 - -config PHY_EXYNOS5_USBDRD - tristate "Exynos5 SoC series USB DRD PHY driver" - depends on ARCH_EXYNOS5 && OF - depends on HAS_IOMEM - depends on USB_DWC3_EXYNOS - select GENERIC_PHY - select MFD_SYSCON - default y - help - Enable USB DRD PHY support for Exynos 5 SoC series. - This driver provides PHY interface for USB 3.0 DRD controller - present on Exynos5 SoC series. - -config PHY_QCOM_APQ8064_SATA - tristate "Qualcomm APQ8064 SATA SerDes/PHY driver" - depends on ARCH_QCOM - depends on HAS_IOMEM - depends on OF - select GENERIC_PHY - -config PHY_QCOM_IPQ806X_SATA - tristate "Qualcomm IPQ806x SATA SerDes/PHY driver" - depends on ARCH_QCOM - depends on HAS_IOMEM - depends on OF - select GENERIC_PHY - -config PHY_ST_SPEAR1310_MIPHY - tristate "ST SPEAR1310-MIPHY driver" - select GENERIC_PHY - depends on MACH_SPEAR1310 || COMPILE_TEST - help - Support for ST SPEAr1310 MIPHY which can be used for PCIe and SATA. - -config PHY_ST_SPEAR1340_MIPHY - tristate "ST SPEAR1340-MIPHY driver" - select GENERIC_PHY - depends on MACH_SPEAR1340 || COMPILE_TEST - help - Support for ST SPEAr1340 MIPHY which can be used for PCIe and SATA. - -config PHY_XGENE - tristate "APM X-Gene 15Gbps PHY support" - depends on HAS_IOMEM && OF && (ARM64 || COMPILE_TEST) - select GENERIC_PHY - help - This option enables support for APM X-Gene SoC multi-purpose PHY. - -config PHY_STIH407_USB - tristate "STMicroelectronics USB2 picoPHY driver for STiH407 family" - depends on RESET_CONTROLLER - depends on ARCH_STI || COMPILE_TEST - select GENERIC_PHY - help - Enable this support to enable the picoPHY device used by USB2 - and USB3 controllers on STMicroelectronics STiH407 SoC families. - -config PHY_STIH41X_USB - tristate "STMicroelectronics USB2 PHY driver for STiH41x series" - depends on ARCH_STI - select GENERIC_PHY - help - Enable this to support the USB transceiver that is part of - STMicroelectronics STiH41x SoC series. - -endmenu diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile deleted file mode 100644 index c4590fce082f..000000000000 --- a/drivers/phy/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -# -# Makefile for the phy drivers. -# - -obj-$(CONFIG_GENERIC_PHY) += phy-core.o -obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o -obj-$(CONFIG_BCM_KONA_USB2_PHY) += phy-bcm-kona-usb2.o -obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o -obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o -obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o -obj-$(CONFIG_PHY_MIPHY365X) += phy-miphy365x.o -obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o -obj-$(CONFIG_OMAP_CONTROL_PHY) += phy-omap-control.o -obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o -obj-$(CONFIG_TI_PIPE3) += phy-ti-pipe3.o -obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o -obj-$(CONFIG_PHY_EXYNOS5250_SATA) += phy-exynos5250-sata.o -obj-$(CONFIG_PHY_HIX5HD2_SATA) += phy-hix5hd2-sata.o -obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o -obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-exynos-usb2.o -phy-exynos-usb2-y += phy-samsung-usb2.o -phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o -phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o -phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o -phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o -obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o -obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o -obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o -obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o -obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o -obj-$(CONFIG_PHY_XGENE) += phy-xgene.o -obj-$(CONFIG_PHY_STIH407_USB) += phy-stih407-usb.o -obj-$(CONFIG_PHY_STIH41X_USB) += phy-stih41x-usb.o diff --git a/drivers/phy/phy-bcm-kona-usb2.c b/drivers/phy/phy-bcm-kona-usb2.c deleted file mode 100644 index c1e0ca335c0e..000000000000 --- a/drivers/phy/phy-bcm-kona-usb2.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * phy-bcm-kona-usb2.c - Broadcom Kona USB2 Phy Driver - * - * Copyright (C) 2013 Linaro Limited - * Matt Porter - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define OTGCTL (0) -#define OTGCTL_OTGSTAT2 BIT(31) -#define OTGCTL_OTGSTAT1 BIT(30) -#define OTGCTL_PRST_N_SW BIT(11) -#define OTGCTL_HRESET_N BIT(10) -#define OTGCTL_UTMI_LINE_STATE1 BIT(9) -#define OTGCTL_UTMI_LINE_STATE0 BIT(8) - -#define P1CTL (8) -#define P1CTL_SOFT_RESET BIT(1) -#define P1CTL_NON_DRIVING BIT(0) - -struct bcm_kona_usb { - void __iomem *regs; -}; - -static void bcm_kona_usb_phy_power(struct bcm_kona_usb *phy, int on) -{ - u32 val; - - val = readl(phy->regs + OTGCTL); - if (on) { - /* Configure and power PHY */ - val &= ~(OTGCTL_OTGSTAT2 | OTGCTL_OTGSTAT1 | - OTGCTL_UTMI_LINE_STATE1 | OTGCTL_UTMI_LINE_STATE0); - val |= OTGCTL_PRST_N_SW | OTGCTL_HRESET_N; - } else { - val &= ~(OTGCTL_PRST_N_SW | OTGCTL_HRESET_N); - } - writel(val, phy->regs + OTGCTL); -} - -static int bcm_kona_usb_phy_init(struct phy *gphy) -{ - struct bcm_kona_usb *phy = phy_get_drvdata(gphy); - u32 val; - - /* Soft reset PHY */ - val = readl(phy->regs + P1CTL); - val &= ~P1CTL_NON_DRIVING; - val |= P1CTL_SOFT_RESET; - writel(val, phy->regs + P1CTL); - writel(val & ~P1CTL_SOFT_RESET, phy->regs + P1CTL); - /* Reset needs to be asserted for 2ms */ - mdelay(2); - writel(val | P1CTL_SOFT_RESET, phy->regs + P1CTL); - - return 0; -} - -static int bcm_kona_usb_phy_power_on(struct phy *gphy) -{ - struct bcm_kona_usb *phy = phy_get_drvdata(gphy); - - bcm_kona_usb_phy_power(phy, 1); - - return 0; -} - -static int bcm_kona_usb_phy_power_off(struct phy *gphy) -{ - struct bcm_kona_usb *phy = phy_get_drvdata(gphy); - - bcm_kona_usb_phy_power(phy, 0); - - return 0; -} - -static struct phy_ops ops = { - .init = bcm_kona_usb_phy_init, - .power_on = bcm_kona_usb_phy_power_on, - .power_off = bcm_kona_usb_phy_power_off, - .owner = THIS_MODULE, -}; - -static int bcm_kona_usb2_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct bcm_kona_usb *phy; - struct resource *res; - struct phy *gphy; - struct phy_provider *phy_provider; - - phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); - if (!phy) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - phy->regs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(phy->regs)) - return PTR_ERR(phy->regs); - - platform_set_drvdata(pdev, phy); - - gphy = devm_phy_create(dev, NULL, &ops, NULL); - if (IS_ERR(gphy)) - return PTR_ERR(gphy); - - /* The Kona PHY supports an 8-bit wide UTMI interface */ - phy_set_bus_width(gphy, 8); - - phy_set_drvdata(gphy, phy); - - phy_provider = devm_of_phy_provider_register(dev, - of_phy_simple_xlate); - - return PTR_ERR_OR_ZERO(phy_provider); -} - -static const struct of_device_id bcm_kona_usb2_dt_ids[] = { - { .compatible = "brcm,kona-usb2-phy" }, - { /* sentinel */ } -}; - -MODULE_DEVICE_TABLE(of, bcm_kona_usb2_dt_ids); - -static struct platform_driver bcm_kona_usb2_driver = { - .probe = bcm_kona_usb2_probe, - .driver = { - .name = "bcm-kona-usb2", - .of_match_table = bcm_kona_usb2_dt_ids, - }, -}; - -module_platform_driver(bcm_kona_usb2_driver); - -MODULE_ALIAS("platform:bcm-kona-usb2"); -MODULE_AUTHOR("Matt Porter "); -MODULE_DESCRIPTION("BCM Kona USB 2.0 PHY driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/phy-berlin-sata.c b/drivers/phy/phy-berlin-sata.c deleted file mode 100644 index 69ced52d72aa..000000000000 --- a/drivers/phy/phy-berlin-sata.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Marvell Berlin SATA PHY driver - * - * Copyright (C) 2014 Marvell Technology Group Ltd. - * - * Antoine Ténart - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include -#include -#include - -#define HOST_VSA_ADDR 0x0 -#define HOST_VSA_DATA 0x4 -#define PORT_SCR_CTL 0x2c -#define PORT_VSR_ADDR 0x78 -#define PORT_VSR_DATA 0x7c - -#define CONTROL_REGISTER 0x0 -#define MBUS_SIZE_CONTROL 0x4 - -#define POWER_DOWN_PHY0 BIT(6) -#define POWER_DOWN_PHY1 BIT(14) -#define MBUS_WRITE_REQUEST_SIZE_128 (BIT(2) << 16) -#define MBUS_READ_REQUEST_SIZE_128 (BIT(2) << 19) - -#define PHY_BASE 0x200 - -/* register 0x01 */ -#define REF_FREF_SEL_25 BIT(0) -#define PHY_MODE_SATA (0x0 << 5) - -/* register 0x02 */ -#define USE_MAX_PLL_RATE BIT(12) - -/* register 0x23 */ -#define DATA_BIT_WIDTH_10 (0x0 << 10) -#define DATA_BIT_WIDTH_20 (0x1 << 10) -#define DATA_BIT_WIDTH_40 (0x2 << 10) - -/* register 0x25 */ -#define PHY_GEN_MAX_1_5 (0x0 << 10) -#define PHY_GEN_MAX_3_0 (0x1 << 10) -#define PHY_GEN_MAX_6_0 (0x2 << 10) - -struct phy_berlin_desc { - struct phy *phy; - u32 power_bit; - unsigned index; -}; - -struct phy_berlin_priv { - void __iomem *base; - spinlock_t lock; - struct clk *clk; - struct phy_berlin_desc **phys; - unsigned nphys; -}; - -static inline void phy_berlin_sata_reg_setbits(void __iomem *ctrl_reg, u32 reg, - u32 mask, u32 val) -{ - u32 regval; - - /* select register */ - writel(PHY_BASE + reg, ctrl_reg + PORT_VSR_ADDR); - - /* set bits */ - regval = readl(ctrl_reg + PORT_VSR_DATA); - regval &= ~mask; - regval |= val; - writel(regval, ctrl_reg + PORT_VSR_DATA); -} - -static int phy_berlin_sata_power_on(struct phy *phy) -{ - struct phy_berlin_desc *desc = phy_get_drvdata(phy); - struct phy_berlin_priv *priv = dev_get_drvdata(phy->dev.parent); - void __iomem *ctrl_reg = priv->base + 0x60 + (desc->index * 0x80); - int ret = 0; - u32 regval; - - clk_prepare_enable(priv->clk); - - spin_lock(&priv->lock); - - /* Power on PHY */ - writel(CONTROL_REGISTER, priv->base + HOST_VSA_ADDR); - regval = readl(priv->base + HOST_VSA_DATA); - regval &= ~desc->power_bit; - writel(regval, priv->base + HOST_VSA_DATA); - - /* Configure MBus */ - writel(MBUS_SIZE_CONTROL, priv->base + HOST_VSA_ADDR); - regval = readl(priv->base + HOST_VSA_DATA); - regval |= MBUS_WRITE_REQUEST_SIZE_128 | MBUS_READ_REQUEST_SIZE_128; - writel(regval, priv->base + HOST_VSA_DATA); - - /* set PHY mode and ref freq to 25 MHz */ - phy_berlin_sata_reg_setbits(ctrl_reg, 0x1, 0xff, - REF_FREF_SEL_25 | PHY_MODE_SATA); - - /* set PHY up to 6 Gbps */ - phy_berlin_sata_reg_setbits(ctrl_reg, 0x25, 0xc00, PHY_GEN_MAX_6_0); - - /* set 40 bits width */ - phy_berlin_sata_reg_setbits(ctrl_reg, 0x23, 0xc00, DATA_BIT_WIDTH_40); - - /* use max pll rate */ - phy_berlin_sata_reg_setbits(ctrl_reg, 0x2, 0x0, USE_MAX_PLL_RATE); - - /* set Gen3 controller speed */ - regval = readl(ctrl_reg + PORT_SCR_CTL); - regval &= ~GENMASK(7, 4); - regval |= 0x30; - writel(regval, ctrl_reg + PORT_SCR_CTL); - - spin_unlock(&priv->lock); - - clk_disable_unprepare(priv->clk); - - return ret; -} - -static int phy_berlin_sata_power_off(struct phy *phy) -{ - struct phy_berlin_desc *desc = phy_get_drvdata(phy); - struct phy_berlin_priv *priv = dev_get_drvdata(phy->dev.parent); - u32 regval; - - clk_prepare_enable(priv->clk); - - spin_lock(&priv->lock); - - /* Power down PHY */ - writel(CONTROL_REGISTER, priv->base + HOST_VSA_ADDR); - regval = readl(priv->base + HOST_VSA_DATA); - regval |= desc->power_bit; - writel(regval, priv->base + HOST_VSA_DATA); - - spin_unlock(&priv->lock); - - clk_disable_unprepare(priv->clk); - - return 0; -} - -static struct phy *phy_berlin_sata_phy_xlate(struct device *dev, - struct of_phandle_args *args) -{ - struct phy_berlin_priv *priv = dev_get_drvdata(dev); - int i; - - if (WARN_ON(args->args[0] >= priv->nphys)) - return ERR_PTR(-ENODEV); - - for (i = 0; i < priv->nphys; i++) { - if (priv->phys[i]->index == args->args[0]) - break; - } - - if (i == priv->nphys) - return ERR_PTR(-ENODEV); - - return priv->phys[i]->phy; -} - -static struct phy_ops phy_berlin_sata_ops = { - .power_on = phy_berlin_sata_power_on, - .power_off = phy_berlin_sata_power_off, - .owner = THIS_MODULE, -}; - -static u32 phy_berlin_power_down_bits[] = { - POWER_DOWN_PHY0, - POWER_DOWN_PHY1, -}; - -static int phy_berlin_sata_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct device_node *child; - struct phy *phy; - struct phy_provider *phy_provider; - struct phy_berlin_priv *priv; - struct resource *res; - int i = 0; - u32 phy_id; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -EINVAL; - - priv->base = devm_ioremap(dev, res->start, resource_size(res)); - if (!priv->base) - return -ENOMEM; - - priv->clk = devm_clk_get(dev, NULL); - if (IS_ERR(priv->clk)) - return PTR_ERR(priv->clk); - - priv->nphys = of_get_child_count(dev->of_node); - if (priv->nphys == 0) - return -ENODEV; - - priv->phys = devm_kzalloc(dev, priv->nphys * sizeof(*priv->phys), - GFP_KERNEL); - if (!priv->phys) - return -ENOMEM; - - dev_set_drvdata(dev, priv); - spin_lock_init(&priv->lock); - - for_each_available_child_of_node(dev->of_node, child) { - struct phy_berlin_desc *phy_desc; - - if (of_property_read_u32(child, "reg", &phy_id)) { - dev_err(dev, "missing reg property in node %s\n", - child->name); - return -EINVAL; - } - - if (phy_id >= ARRAY_SIZE(phy_berlin_power_down_bits)) { - dev_err(dev, "invalid reg in node %s\n", child->name); - return -EINVAL; - } - - phy_desc = devm_kzalloc(dev, sizeof(*phy_desc), GFP_KERNEL); - if (!phy_desc) - return -ENOMEM; - - phy = devm_phy_create(dev, NULL, &phy_berlin_sata_ops, NULL); - if (IS_ERR(phy)) { - dev_err(dev, "failed to create PHY %d\n", phy_id); - return PTR_ERR(phy); - } - - phy_desc->phy = phy; - phy_desc->power_bit = phy_berlin_power_down_bits[phy_id]; - phy_desc->index = phy_id; - phy_set_drvdata(phy, phy_desc); - - priv->phys[i++] = phy_desc; - - /* Make sure the PHY is off */ - phy_berlin_sata_power_off(phy); - } - - phy_provider = - devm_of_phy_provider_register(dev, phy_berlin_sata_phy_xlate); - if (IS_ERR(phy_provider)) - return PTR_ERR(phy_provider); - - return 0; -} - -static const struct of_device_id phy_berlin_sata_of_match[] = { - { .compatible = "marvell,berlin2q-sata-phy" }, - { }, -}; - -static struct platform_driver phy_berlin_sata_driver = { - .probe = phy_berlin_sata_probe, - .driver = { - .name = "phy-berlin-sata", - .of_match_table = phy_berlin_sata_of_match, - }, -}; -module_platform_driver(phy_berlin_sata_driver); - -MODULE_DESCRIPTION("Marvell Berlin SATA PHY driver"); -MODULE_AUTHOR("Antoine Ténart "); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c deleted file mode 100644 index ff5eec5af817..000000000000 --- a/drivers/phy/phy-core.c +++ /dev/null @@ -1,872 +0,0 @@ -/* - * phy-core.c -- Generic Phy framework. - * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com - * - * Author: Kishon Vijay Abraham I - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct class *phy_class; -static DEFINE_MUTEX(phy_provider_mutex); -static LIST_HEAD(phy_provider_list); -static DEFINE_IDA(phy_ida); - -static void devm_phy_release(struct device *dev, void *res) -{ - struct phy *phy = *(struct phy **)res; - - phy_put(phy); -} - -static void devm_phy_provider_release(struct device *dev, void *res) -{ - struct phy_provider *phy_provider = *(struct phy_provider **)res; - - of_phy_provider_unregister(phy_provider); -} - -static void devm_phy_consume(struct device *dev, void *res) -{ - struct phy *phy = *(struct phy **)res; - - phy_destroy(phy); -} - -static int devm_phy_match(struct device *dev, void *res, void *match_data) -{ - return res == match_data; -} - -static struct phy *phy_lookup(struct device *device, const char *port) -{ - unsigned int count; - struct phy *phy; - struct device *dev; - struct phy_consumer *consumers; - struct class_dev_iter iter; - - class_dev_iter_init(&iter, phy_class, NULL, NULL); - while ((dev = class_dev_iter_next(&iter))) { - phy = to_phy(dev); - - if (!phy->init_data) - continue; - count = phy->init_data->num_consumers; - consumers = phy->init_data->consumers; - while (count--) { - if (!strcmp(consumers->dev_name, dev_name(device)) && - !strcmp(consumers->port, port)) { - class_dev_iter_exit(&iter); - return phy; - } - consumers++; - } - } - - class_dev_iter_exit(&iter); - return ERR_PTR(-ENODEV); -} - -static struct phy_provider *of_phy_provider_lookup(struct device_node *node) -{ - struct phy_provider *phy_provider; - struct device_node *child; - - list_for_each_entry(phy_provider, &phy_provider_list, list) { - if (phy_provider->dev->of_node == node) - return phy_provider; - - for_each_child_of_node(phy_provider->dev->of_node, child) - if (child == node) - return phy_provider; - } - - return ERR_PTR(-EPROBE_DEFER); -} - -int phy_pm_runtime_get(struct phy *phy) -{ - int ret; - - if (!pm_runtime_enabled(&phy->dev)) - return -ENOTSUPP; - - ret = pm_runtime_get(&phy->dev); - if (ret < 0 && ret != -EINPROGRESS) - pm_runtime_put_noidle(&phy->dev); - - return ret; -} -EXPORT_SYMBOL_GPL(phy_pm_runtime_get); - -int phy_pm_runtime_get_sync(struct phy *phy) -{ - int ret; - - if (!pm_runtime_enabled(&phy->dev)) - return -ENOTSUPP; - - ret = pm_runtime_get_sync(&phy->dev); - if (ret < 0) - pm_runtime_put_sync(&phy->dev); - - return ret; -} -EXPORT_SYMBOL_GPL(phy_pm_runtime_get_sync); - -int phy_pm_runtime_put(struct phy *phy) -{ - if (!pm_runtime_enabled(&phy->dev)) - return -ENOTSUPP; - - return pm_runtime_put(&phy->dev); -} -EXPORT_SYMBOL_GPL(phy_pm_runtime_put); - -int phy_pm_runtime_put_sync(struct phy *phy) -{ - if (!pm_runtime_enabled(&phy->dev)) - return -ENOTSUPP; - - return pm_runtime_put_sync(&phy->dev); -} -EXPORT_SYMBOL_GPL(phy_pm_runtime_put_sync); - -void phy_pm_runtime_allow(struct phy *phy) -{ - if (!pm_runtime_enabled(&phy->dev)) - return; - - pm_runtime_allow(&phy->dev); -} -EXPORT_SYMBOL_GPL(phy_pm_runtime_allow); - -void phy_pm_runtime_forbid(struct phy *phy) -{ - if (!pm_runtime_enabled(&phy->dev)) - return; - - pm_runtime_forbid(&phy->dev); -} -EXPORT_SYMBOL_GPL(phy_pm_runtime_forbid); - -int phy_init(struct phy *phy) -{ - int ret; - - if (!phy) - return 0; - - ret = phy_pm_runtime_get_sync(phy); - if (ret < 0 && ret != -ENOTSUPP) - return ret; - - mutex_lock(&phy->mutex); - if (phy->init_count == 0 && phy->ops->init) { - ret = phy->ops->init(phy); - if (ret < 0) { - dev_err(&phy->dev, "phy init failed --> %d\n", ret); - goto out; - } - } else { - ret = 0; /* Override possible ret == -ENOTSUPP */ - } - ++phy->init_count; - -out: - mutex_unlock(&phy->mutex); - phy_pm_runtime_put(phy); - return ret; -} -EXPORT_SYMBOL_GPL(phy_init); - -int phy_exit(struct phy *phy) -{ - int ret; - - if (!phy) - return 0; - - ret = phy_pm_runtime_get_sync(phy); - if (ret < 0 && ret != -ENOTSUPP) - return ret; - - mutex_lock(&phy->mutex); - if (phy->init_count == 1 && phy->ops->exit) { - ret = phy->ops->exit(phy); - if (ret < 0) { - dev_err(&phy->dev, "phy exit failed --> %d\n", ret); - goto out; - } - } - --phy->init_count; - -out: - mutex_unlock(&phy->mutex); - phy_pm_runtime_put(phy); - return ret; -} -EXPORT_SYMBOL_GPL(phy_exit); - -int phy_power_on(struct phy *phy) -{ - int ret; - - if (!phy) - return 0; - - if (phy->pwr) { - ret = regulator_enable(phy->pwr); - if (ret) - return ret; - } - - ret = phy_pm_runtime_get_sync(phy); - if (ret < 0 && ret != -ENOTSUPP) - return ret; - - mutex_lock(&phy->mutex); - if (phy->power_count == 0 && phy->ops->power_on) { - ret = phy->ops->power_on(phy); - if (ret < 0) { - dev_err(&phy->dev, "phy poweron failed --> %d\n", ret); - goto out; - } - } else { - ret = 0; /* Override possible ret == -ENOTSUPP */ - } - ++phy->power_count; - mutex_unlock(&phy->mutex); - return 0; - -out: - mutex_unlock(&phy->mutex); - phy_pm_runtime_put_sync(phy); - if (phy->pwr) - regulator_disable(phy->pwr); - - return ret; -} -EXPORT_SYMBOL_GPL(phy_power_on); - -int phy_power_off(struct phy *phy) -{ - int ret; - - if (!phy) - return 0; - - mutex_lock(&phy->mutex); - if (phy->power_count == 1 && phy->ops->power_off) { - ret = phy->ops->power_off(phy); - if (ret < 0) { - dev_err(&phy->dev, "phy poweroff failed --> %d\n", ret); - mutex_unlock(&phy->mutex); - return ret; - } - } - --phy->power_count; - mutex_unlock(&phy->mutex); - phy_pm_runtime_put(phy); - - if (phy->pwr) - regulator_disable(phy->pwr); - - return 0; -} -EXPORT_SYMBOL_GPL(phy_power_off); - -/** - * _of_phy_get() - lookup and obtain a reference to a phy by phandle - * @np: device_node for which to get the phy - * @index: the index of the phy - * - * Returns the phy associated with the given phandle value, - * after getting a refcount to it or -ENODEV if there is no such phy or - * -EPROBE_DEFER if there is a phandle to the phy, but the device is - * not yet loaded. This function uses of_xlate call back function provided - * while registering the phy_provider to find the phy instance. - */ -static struct phy *_of_phy_get(struct device_node *np, int index) -{ - int ret; - struct phy_provider *phy_provider; - struct phy *phy = NULL; - struct of_phandle_args args; - - ret = of_parse_phandle_with_args(np, "phys", "#phy-cells", - index, &args); - if (ret) - return ERR_PTR(-ENODEV); - - mutex_lock(&phy_provider_mutex); - phy_provider = of_phy_provider_lookup(args.np); - if (IS_ERR(phy_provider) || !try_module_get(phy_provider->owner)) { - phy = ERR_PTR(-EPROBE_DEFER); - goto err0; - } - - phy = phy_provider->of_xlate(phy_provider->dev, &args); - module_put(phy_provider->owner); - -err0: - mutex_unlock(&phy_provider_mutex); - of_node_put(args.np); - - return phy; -} - -/** - * of_phy_get() - lookup and obtain a reference to a phy using a device_node. - * @np: device_node for which to get the phy - * @con_id: name of the phy from device's point of view - * - * Returns the phy driver, after getting a refcount to it; or - * -ENODEV if there is no such phy. The caller is responsible for - * calling phy_put() to release that count. - */ -struct phy *of_phy_get(struct device_node *np, const char *con_id) -{ - struct phy *phy = NULL; - int index = 0; - - if (con_id) - index = of_property_match_string(np, "phy-names", con_id); - - phy = _of_phy_get(np, index); - if (IS_ERR(phy)) - return phy; - - if (!try_module_get(phy->ops->owner)) - return ERR_PTR(-EPROBE_DEFER); - - get_device(&phy->dev); - - return phy; -} -EXPORT_SYMBOL_GPL(of_phy_get); - -/** - * phy_put() - release the PHY - * @phy: the phy returned by phy_get() - * - * Releases a refcount the caller received from phy_get(). - */ -void phy_put(struct phy *phy) -{ - if (!phy || IS_ERR(phy)) - return; - - module_put(phy->ops->owner); - put_device(&phy->dev); -} -EXPORT_SYMBOL_GPL(phy_put); - -/** - * devm_phy_put() - release the PHY - * @dev: device that wants to release this phy - * @phy: the phy returned by devm_phy_get() - * - * destroys the devres associated with this phy and invokes phy_put - * to release the phy. - */ -void devm_phy_put(struct device *dev, struct phy *phy) -{ - int r; - - if (!phy) - return; - - r = devres_destroy(dev, devm_phy_release, devm_phy_match, phy); - dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n"); -} -EXPORT_SYMBOL_GPL(devm_phy_put); - -/** - * of_phy_simple_xlate() - returns the phy instance from phy provider - * @dev: the PHY provider device - * @args: of_phandle_args (not used here) - * - * Intended to be used by phy provider for the common case where #phy-cells is - * 0. For other cases where #phy-cells is greater than '0', the phy provider - * should provide a custom of_xlate function that reads the *args* and returns - * the appropriate phy. - */ -struct phy *of_phy_simple_xlate(struct device *dev, struct of_phandle_args - *args) -{ - struct phy *phy; - struct class_dev_iter iter; - struct device_node *node = dev->of_node; - struct device_node *child; - - class_dev_iter_init(&iter, phy_class, NULL, NULL); - while ((dev = class_dev_iter_next(&iter))) { - phy = to_phy(dev); - if (node != phy->dev.of_node) { - for_each_child_of_node(node, child) { - if (child == phy->dev.of_node) - goto phy_found; - } - continue; - } - -phy_found: - class_dev_iter_exit(&iter); - return phy; - } - - class_dev_iter_exit(&iter); - return ERR_PTR(-ENODEV); -} -EXPORT_SYMBOL_GPL(of_phy_simple_xlate); - -/** - * phy_get() - lookup and obtain a reference to a phy. - * @dev: device that requests this phy - * @string: the phy name as given in the dt data or the name of the controller - * port for non-dt case - * - * Returns the phy driver, after getting a refcount to it; or - * -ENODEV if there is no such phy. The caller is responsible for - * calling phy_put() to release that count. - */ -struct phy *phy_get(struct device *dev, const char *string) -{ - int index = 0; - struct phy *phy; - - if (string == NULL) { - dev_WARN(dev, "missing string\n"); - return ERR_PTR(-EINVAL); - } - - if (dev->of_node) { - index = of_property_match_string(dev->of_node, "phy-names", - string); - phy = _of_phy_get(dev->of_node, index); - } else { - phy = phy_lookup(dev, string); - } - if (IS_ERR(phy)) - return phy; - - if (!try_module_get(phy->ops->owner)) - return ERR_PTR(-EPROBE_DEFER); - - get_device(&phy->dev); - - return phy; -} -EXPORT_SYMBOL_GPL(phy_get); - -/** - * phy_optional_get() - lookup and obtain a reference to an optional phy. - * @dev: device that requests this phy - * @string: the phy name as given in the dt data or the name of the controller - * port for non-dt case - * - * Returns the phy driver, after getting a refcount to it; or - * NULL if there is no such phy. The caller is responsible for - * calling phy_put() to release that count. - */ -struct phy *phy_optional_get(struct device *dev, const char *string) -{ - struct phy *phy = phy_get(dev, string); - - if (PTR_ERR(phy) == -ENODEV) - phy = NULL; - - return phy; -} -EXPORT_SYMBOL_GPL(phy_optional_get); - -/** - * devm_phy_get() - lookup and obtain a reference to a phy. - * @dev: device that requests this phy - * @string: the phy name as given in the dt data or phy device name - * for non-dt case - * - * Gets the phy using phy_get(), and associates a device with it using - * devres. On driver detach, release function is invoked on the devres data, - * then, devres data is freed. - */ -struct phy *devm_phy_get(struct device *dev, const char *string) -{ - struct phy **ptr, *phy; - - ptr = devres_alloc(devm_phy_release, sizeof(*ptr), GFP_KERNEL); - if (!ptr) - return ERR_PTR(-ENOMEM); - - phy = phy_get(dev, string); - if (!IS_ERR(phy)) { - *ptr = phy; - devres_add(dev, ptr); - } else { - devres_free(ptr); - } - - return phy; -} -EXPORT_SYMBOL_GPL(devm_phy_get); - -/** - * devm_phy_optional_get() - lookup and obtain a reference to an optional phy. - * @dev: device that requests this phy - * @string: the phy name as given in the dt data or phy device name - * for non-dt case - * - * Gets the phy using phy_get(), and associates a device with it using - * devres. On driver detach, release function is invoked on the devres - * data, then, devres data is freed. This differs to devm_phy_get() in - * that if the phy does not exist, it is not considered an error and - * -ENODEV will not be returned. Instead the NULL phy is returned, - * which can be passed to all other phy consumer calls. - */ -struct phy *devm_phy_optional_get(struct device *dev, const char *string) -{ - struct phy *phy = devm_phy_get(dev, string); - - if (PTR_ERR(phy) == -ENODEV) - phy = NULL; - - return phy; -} -EXPORT_SYMBOL_GPL(devm_phy_optional_get); - -/** - * devm_of_phy_get() - lookup and obtain a reference to a phy. - * @dev: device that requests this phy - * @np: node containing the phy - * @con_id: name of the phy from device's point of view - * - * Gets the phy using of_phy_get(), and associates a device with it using - * devres. On driver detach, release function is invoked on the devres data, - * then, devres data is freed. - */ -struct phy *devm_of_phy_get(struct device *dev, struct device_node *np, - const char *con_id) -{ - struct phy **ptr, *phy; - - ptr = devres_alloc(devm_phy_release, sizeof(*ptr), GFP_KERNEL); - if (!ptr) - return ERR_PTR(-ENOMEM); - - phy = of_phy_get(np, con_id); - if (!IS_ERR(phy)) { - *ptr = phy; - devres_add(dev, ptr); - } else { - devres_free(ptr); - } - - return phy; -} -EXPORT_SYMBOL_GPL(devm_of_phy_get); - -/** - * phy_create() - create a new phy - * @dev: device that is creating the new phy - * @node: device node of the phy - * @ops: function pointers for performing phy operations - * @init_data: contains the list of PHY consumers or NULL - * - * Called to create a phy using phy framework. - */ -struct phy *phy_create(struct device *dev, struct device_node *node, - const struct phy_ops *ops, - struct phy_init_data *init_data) -{ - int ret; - int id; - struct phy *phy; - - if (WARN_ON(!dev)) - return ERR_PTR(-EINVAL); - - phy = kzalloc(sizeof(*phy), GFP_KERNEL); - if (!phy) - return ERR_PTR(-ENOMEM); - - id = ida_simple_get(&phy_ida, 0, 0, GFP_KERNEL); - if (id < 0) { - dev_err(dev, "unable to get id\n"); - ret = id; - goto free_phy; - } - - /* phy-supply */ - phy->pwr = regulator_get_optional(dev, "phy"); - if (IS_ERR(phy->pwr)) { - if (PTR_ERR(phy->pwr) == -EPROBE_DEFER) { - ret = -EPROBE_DEFER; - goto free_ida; - } - phy->pwr = NULL; - } - - device_initialize(&phy->dev); - mutex_init(&phy->mutex); - - phy->dev.class = phy_class; - phy->dev.parent = dev; - phy->dev.of_node = node ?: dev->of_node; - phy->id = id; - phy->ops = ops; - phy->init_data = init_data; - - ret = dev_set_name(&phy->dev, "phy-%s.%d", dev_name(dev), id); - if (ret) - goto put_dev; - - ret = device_add(&phy->dev); - if (ret) - goto put_dev; - - if (pm_runtime_enabled(dev)) { - pm_runtime_enable(&phy->dev); - pm_runtime_no_callbacks(&phy->dev); - } - - return phy; - -put_dev: - put_device(&phy->dev); /* calls phy_release() which frees resources */ - return ERR_PTR(ret); - -free_ida: - ida_simple_remove(&phy_ida, phy->id); - -free_phy: - kfree(phy); - return ERR_PTR(ret); -} -EXPORT_SYMBOL_GPL(phy_create); - -/** - * devm_phy_create() - create a new phy - * @dev: device that is creating the new phy - * @node: device node of the phy - * @ops: function pointers for performing phy operations - * @init_data: contains the list of PHY consumers or NULL - * - * Creates a new PHY device adding it to the PHY class. - * While at that, it also associates the device with the phy using devres. - * On driver detach, release function is invoked on the devres data, - * then, devres data is freed. - */ -struct phy *devm_phy_create(struct device *dev, struct device_node *node, - const struct phy_ops *ops, - struct phy_init_data *init_data) -{ - struct phy **ptr, *phy; - - ptr = devres_alloc(devm_phy_consume, sizeof(*ptr), GFP_KERNEL); - if (!ptr) - return ERR_PTR(-ENOMEM); - - phy = phy_create(dev, node, ops, init_data); - if (!IS_ERR(phy)) { - *ptr = phy; - devres_add(dev, ptr); - } else { - devres_free(ptr); - } - - return phy; -} -EXPORT_SYMBOL_GPL(devm_phy_create); - -/** - * phy_destroy() - destroy the phy - * @phy: the phy to be destroyed - * - * Called to destroy the phy. - */ -void phy_destroy(struct phy *phy) -{ - pm_runtime_disable(&phy->dev); - device_unregister(&phy->dev); -} -EXPORT_SYMBOL_GPL(phy_destroy); - -/** - * devm_phy_destroy() - destroy the PHY - * @dev: device that wants to release this phy - * @phy: the phy returned by devm_phy_get() - * - * destroys the devres associated with this phy and invokes phy_destroy - * to destroy the phy. - */ -void devm_phy_destroy(struct device *dev, struct phy *phy) -{ - int r; - - r = devres_destroy(dev, devm_phy_consume, devm_phy_match, phy); - dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n"); -} -EXPORT_SYMBOL_GPL(devm_phy_destroy); - -/** - * __of_phy_provider_register() - create/register phy provider with the framework - * @dev: struct device of the phy provider - * @owner: the module owner containing of_xlate - * @of_xlate: function pointer to obtain phy instance from phy provider - * - * Creates struct phy_provider from dev and of_xlate function pointer. - * This is used in the case of dt boot for finding the phy instance from - * phy provider. - */ -struct phy_provider *__of_phy_provider_register(struct device *dev, - struct module *owner, struct phy * (*of_xlate)(struct device *dev, - struct of_phandle_args *args)) -{ - struct phy_provider *phy_provider; - - phy_provider = kzalloc(sizeof(*phy_provider), GFP_KERNEL); - if (!phy_provider) - return ERR_PTR(-ENOMEM); - - phy_provider->dev = dev; - phy_provider->owner = owner; - phy_provider->of_xlate = of_xlate; - - mutex_lock(&phy_provider_mutex); - list_add_tail(&phy_provider->list, &phy_provider_list); - mutex_unlock(&phy_provider_mutex); - - return phy_provider; -} -EXPORT_SYMBOL_GPL(__of_phy_provider_register); - -/** - * __devm_of_phy_provider_register() - create/register phy provider with the - * framework - * @dev: struct device of the phy provider - * @owner: the module owner containing of_xlate - * @of_xlate: function pointer to obtain phy instance from phy provider - * - * Creates struct phy_provider from dev and of_xlate function pointer. - * This is used in the case of dt boot for finding the phy instance from - * phy provider. While at that, it also associates the device with the - * phy provider using devres. On driver detach, release function is invoked - * on the devres data, then, devres data is freed. - */ -struct phy_provider *__devm_of_phy_provider_register(struct device *dev, - struct module *owner, struct phy * (*of_xlate)(struct device *dev, - struct of_phandle_args *args)) -{ - struct phy_provider **ptr, *phy_provider; - - ptr = devres_alloc(devm_phy_provider_release, sizeof(*ptr), GFP_KERNEL); - if (!ptr) - return ERR_PTR(-ENOMEM); - - phy_provider = __of_phy_provider_register(dev, owner, of_xlate); - if (!IS_ERR(phy_provider)) { - *ptr = phy_provider; - devres_add(dev, ptr); - } else { - devres_free(ptr); - } - - return phy_provider; -} -EXPORT_SYMBOL_GPL(__devm_of_phy_provider_register); - -/** - * of_phy_provider_unregister() - unregister phy provider from the framework - * @phy_provider: phy provider returned by of_phy_provider_register() - * - * Removes the phy_provider created using of_phy_provider_register(). - */ -void of_phy_provider_unregister(struct phy_provider *phy_provider) -{ - if (IS_ERR(phy_provider)) - return; - - mutex_lock(&phy_provider_mutex); - list_del(&phy_provider->list); - kfree(phy_provider); - mutex_unlock(&phy_provider_mutex); -} -EXPORT_SYMBOL_GPL(of_phy_provider_unregister); - -/** - * devm_of_phy_provider_unregister() - remove phy provider from the framework - * @dev: struct device of the phy provider - * - * destroys the devres associated with this phy provider and invokes - * of_phy_provider_unregister to unregister the phy provider. - */ -void devm_of_phy_provider_unregister(struct device *dev, - struct phy_provider *phy_provider) { - int r; - - r = devres_destroy(dev, devm_phy_provider_release, devm_phy_match, - phy_provider); - dev_WARN_ONCE(dev, r, "couldn't find PHY provider device resource\n"); -} -EXPORT_SYMBOL_GPL(devm_of_phy_provider_unregister); - -/** - * phy_release() - release the phy - * @dev: the dev member within phy - * - * When the last reference to the device is removed, it is called - * from the embedded kobject as release method. - */ -static void phy_release(struct device *dev) -{ - struct phy *phy; - - phy = to_phy(dev); - dev_vdbg(dev, "releasing '%s'\n", dev_name(dev)); - regulator_put(phy->pwr); - ida_simple_remove(&phy_ida, phy->id); - kfree(phy); -} - -static int __init phy_core_init(void) -{ - phy_class = class_create(THIS_MODULE, "phy"); - if (IS_ERR(phy_class)) { - pr_err("failed to create phy class --> %ld\n", - PTR_ERR(phy_class)); - return PTR_ERR(phy_class); - } - - phy_class->dev_release = phy_release; - - return 0; -} -module_init(phy_core_init); - -static void __exit phy_core_exit(void) -{ - class_destroy(phy_class); -} -module_exit(phy_core_exit); - -MODULE_DESCRIPTION("Generic PHY Framework"); -MODULE_AUTHOR("Kishon Vijay Abraham I "); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/phy-exynos-dp-video.c b/drivers/phy/phy-exynos-dp-video.c deleted file mode 100644 index 84f49e5a3f24..000000000000 --- a/drivers/phy/phy-exynos-dp-video.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Samsung EXYNOS SoC series Display Port PHY driver - * - * Copyright (C) 2013 Samsung Electronics Co., Ltd. - * Author: Jingoo Han - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct exynos_dp_video_phy_drvdata { - u32 phy_ctrl_offset; -}; - -struct exynos_dp_video_phy { - struct regmap *regs; - const struct exynos_dp_video_phy_drvdata *drvdata; -}; - -static void exynos_dp_video_phy_pwr_isol(struct exynos_dp_video_phy *state, - unsigned int on) -{ - unsigned int val; - - if (IS_ERR(state->regs)) - return; - - val = on ? 0 : EXYNOS5_PHY_ENABLE; - - regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset, - EXYNOS5_PHY_ENABLE, val); -} - -static int exynos_dp_video_phy_power_on(struct phy *phy) -{ - struct exynos_dp_video_phy *state = phy_get_drvdata(phy); - - /* Disable power isolation on DP-PHY */ - exynos_dp_video_phy_pwr_isol(state, 0); - - return 0; -} - -static int exynos_dp_video_phy_power_off(struct phy *phy) -{ - struct exynos_dp_video_phy *state = phy_get_drvdata(phy); - - /* Enable power isolation on DP-PHY */ - exynos_dp_video_phy_pwr_isol(state, 1); - - return 0; -} - -static struct phy_ops exynos_dp_video_phy_ops = { - .power_on = exynos_dp_video_phy_power_on, - .power_off = exynos_dp_video_phy_power_off, - .owner = THIS_MODULE, -}; - -static const struct exynos_dp_video_phy_drvdata exynos5250_dp_video_phy = { - .phy_ctrl_offset = EXYNOS5_DPTX_PHY_CONTROL, -}; - -static const struct exynos_dp_video_phy_drvdata exynos5420_dp_video_phy = { - .phy_ctrl_offset = EXYNOS5420_DPTX_PHY_CONTROL, -}; - -static const struct of_device_id exynos_dp_video_phy_of_match[] = { - { - .compatible = "samsung,exynos5250-dp-video-phy", - .data = &exynos5250_dp_video_phy, - }, { - .compatible = "samsung,exynos5420-dp-video-phy", - .data = &exynos5420_dp_video_phy, - }, - { }, -}; -MODULE_DEVICE_TABLE(of, exynos_dp_video_phy_of_match); - -static int exynos_dp_video_phy_probe(struct platform_device *pdev) -{ - struct exynos_dp_video_phy *state; - struct device *dev = &pdev->dev; - const struct of_device_id *match; - struct phy_provider *phy_provider; - struct phy *phy; - - state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); - if (!state) - return -ENOMEM; - - state->regs = syscon_regmap_lookup_by_phandle(dev->of_node, - "samsung,pmu-syscon"); - if (IS_ERR(state->regs)) { - dev_err(dev, "Failed to lookup PMU regmap\n"); - return PTR_ERR(state->regs); - } - - match = of_match_node(exynos_dp_video_phy_of_match, dev->of_node); - state->drvdata = match->data; - - phy = devm_phy_create(dev, NULL, &exynos_dp_video_phy_ops, NULL); - if (IS_ERR(phy)) { - dev_err(dev, "failed to create Display Port PHY\n"); - return PTR_ERR(phy); - } - phy_set_drvdata(phy, state); - - phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); - - return PTR_ERR_OR_ZERO(phy_provider); -} - -static struct platform_driver exynos_dp_video_phy_driver = { - .probe = exynos_dp_video_phy_probe, - .driver = { - .name = "exynos-dp-video-phy", - .of_match_table = exynos_dp_video_phy_of_match, - } -}; -module_platform_driver(exynos_dp_video_phy_driver); - -MODULE_AUTHOR("Jingoo Han "); -MODULE_DESCRIPTION("Samsung EXYNOS SoC DP PHY driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c deleted file mode 100644 index 6a9bef138617..000000000000 --- a/drivers/phy/phy-exynos-mipi-video.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY driver - * - * Copyright (C) 2013 Samsung Electronics Co., Ltd. - * Author: Sylwester Nawrocki - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* MIPI_PHYn_CONTROL register offset: n = 0..1 */ -#define EXYNOS_MIPI_PHY_CONTROL(n) ((n) * 4) -#define EXYNOS_MIPI_PHY_ENABLE (1 << 0) -#define EXYNOS_MIPI_PHY_SRESETN (1 << 1) -#define EXYNOS_MIPI_PHY_MRESETN (1 << 2) -#define EXYNOS_MIPI_PHY_RESET_MASK (3 << 1) - -enum exynos_mipi_phy_id { - EXYNOS_MIPI_PHY_ID_CSIS0, - EXYNOS_MIPI_PHY_ID_DSIM0, - EXYNOS_MIPI_PHY_ID_CSIS1, - EXYNOS_MIPI_PHY_ID_DSIM1, - EXYNOS_MIPI_PHYS_NUM -}; - -#define is_mipi_dsim_phy_id(id) \ - ((id) == EXYNOS_MIPI_PHY_ID_DSIM0 || (id) == EXYNOS_MIPI_PHY_ID_DSIM1) - -struct exynos_mipi_video_phy { - spinlock_t slock; - struct video_phy_desc { - struct phy *phy; - unsigned int index; - } phys[EXYNOS_MIPI_PHYS_NUM]; - void __iomem *regs; -}; - -static int __set_phy_state(struct exynos_mipi_video_phy *state, - enum exynos_mipi_phy_id id, unsigned int on) -{ - void __iomem *addr; - u32 reg, reset; - - addr = state->regs + EXYNOS_MIPI_PHY_CONTROL(id / 2); - - if (is_mipi_dsim_phy_id(id)) - reset = EXYNOS_MIPI_PHY_MRESETN; - else - reset = EXYNOS_MIPI_PHY_SRESETN; - - spin_lock(&state->slock); - reg = readl(addr); - if (on) - reg |= reset; - else - reg &= ~reset; - writel(reg, addr); - - /* Clear ENABLE bit only if MRESETN, SRESETN bits are not set. */ - if (on) - reg |= EXYNOS_MIPI_PHY_ENABLE; - else if (!(reg & EXYNOS_MIPI_PHY_RESET_MASK)) - reg &= ~EXYNOS_MIPI_PHY_ENABLE; - - writel(reg, addr); - spin_unlock(&state->slock); - return 0; -} - -#define to_mipi_video_phy(desc) \ - container_of((desc), struct exynos_mipi_video_phy, phys[(desc)->index]); - -static int exynos_mipi_video_phy_power_on(struct phy *phy) -{ - struct video_phy_desc *phy_desc = phy_get_drvdata(phy); - struct exynos_mipi_video_phy *state = to_mipi_video_phy(phy_desc); - - return __set_phy_state(state, phy_desc->index, 1); -} - -static int exynos_mipi_video_phy_power_off(struct phy *phy) -{ - struct video_phy_desc *phy_desc = phy_get_drvdata(phy); - struct exynos_mipi_video_phy *state = to_mipi_video_phy(phy_desc); - - return __set_phy_state(state, phy_desc->index, 0); -} - -static struct phy *exynos_mipi_video_phy_xlate(struct device *dev, - struct of_phandle_args *args) -{ - struct exynos_mipi_video_phy *state = dev_get_drvdata(dev); - - if (WARN_ON(args->args[0] >= EXYNOS_MIPI_PHYS_NUM)) - return ERR_PTR(-ENODEV); - - return state->phys[args->args[0]].phy; -} - -static struct phy_ops exynos_mipi_video_phy_ops = { - .power_on = exynos_mipi_video_phy_power_on, - .power_off = exynos_mipi_video_phy_power_off, - .owner = THIS_MODULE, -}; - -static int exynos_mipi_video_phy_probe(struct platform_device *pdev) -{ - struct exynos_mipi_video_phy *state; - struct device *dev = &pdev->dev; - struct resource *res; - struct phy_provider *phy_provider; - unsigned int i; - - state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); - if (!state) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - state->regs = devm_ioremap_resource(dev, res); - if (IS_ERR(state->regs)) - return PTR_ERR(state->regs); - - dev_set_drvdata(dev, state); - spin_lock_init(&state->slock); - - for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) { - struct phy *phy = devm_phy_create(dev, NULL, - &exynos_mipi_video_phy_ops, NULL); - if (IS_ERR(phy)) { - dev_err(dev, "failed to create PHY %d\n", i); - return PTR_ERR(phy); - } - - state->phys[i].phy = phy; - state->phys[i].index = i; - phy_set_drvdata(phy, &state->phys[i]); - } - - phy_provider = devm_of_phy_provider_register(dev, - exynos_mipi_video_phy_xlate); - - return PTR_ERR_OR_ZERO(phy_provider); -} - -static const struct of_device_id exynos_mipi_video_phy_of_match[] = { - { .compatible = "samsung,s5pv210-mipi-video-phy" }, - { }, -}; -MODULE_DEVICE_TABLE(of, exynos_mipi_video_phy_of_match); - -static struct platform_driver exynos_mipi_video_phy_driver = { - .probe = exynos_mipi_video_phy_probe, - .driver = { - .of_match_table = exynos_mipi_video_phy_of_match, - .name = "exynos-mipi-video-phy", - } -}; -module_platform_driver(exynos_mipi_video_phy_driver); - -MODULE_DESCRIPTION("Samsung S5P/EXYNOS SoC MIPI CSI-2/DSI PHY driver"); -MODULE_AUTHOR("Sylwester Nawrocki "); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/phy-exynos4210-usb2.c b/drivers/phy/phy-exynos4210-usb2.c deleted file mode 100644 index 236a52ad94eb..000000000000 --- a/drivers/phy/phy-exynos4210-usb2.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Samsung SoC USB 1.1/2.0 PHY driver - Exynos 4210 support - * - * Copyright (C) 2013 Samsung Electronics Co., Ltd. - * Author: Kamil Debski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include "phy-samsung-usb2.h" - -/* Exynos USB PHY registers */ - -/* PHY power control */ -#define EXYNOS_4210_UPHYPWR 0x0 - -#define EXYNOS_4210_UPHYPWR_PHY0_SUSPEND BIT(0) -#define EXYNOS_4210_UPHYPWR_PHY0_PWR BIT(3) -#define EXYNOS_4210_UPHYPWR_PHY0_OTG_PWR BIT(4) -#define EXYNOS_4210_UPHYPWR_PHY0_SLEEP BIT(5) -#define EXYNOS_4210_UPHYPWR_PHY0 ( \ - EXYNOS_4210_UPHYPWR_PHY0_SUSPEND | \ - EXYNOS_4210_UPHYPWR_PHY0_PWR | \ - EXYNOS_4210_UPHYPWR_PHY0_OTG_PWR | \ - EXYNOS_4210_UPHYPWR_PHY0_SLEEP) - -#define EXYNOS_4210_UPHYPWR_PHY1_SUSPEND BIT(6) -#define EXYNOS_4210_UPHYPWR_PHY1_PWR BIT(7) -#define EXYNOS_4210_UPHYPWR_PHY1_SLEEP BIT(8) -#define EXYNOS_4210_UPHYPWR_PHY1 ( \ - EXYNOS_4210_UPHYPWR_PHY1_SUSPEND | \ - EXYNOS_4210_UPHYPWR_PHY1_PWR | \ - EXYNOS_4210_UPHYPWR_PHY1_SLEEP) - -#define EXYNOS_4210_UPHYPWR_HSIC0_SUSPEND BIT(9) -#define EXYNOS_4210_UPHYPWR_HSIC0_SLEEP BIT(10) -#define EXYNOS_4210_UPHYPWR_HSIC0 ( \ - EXYNOS_4210_UPHYPWR_HSIC0_SUSPEND | \ - EXYNOS_4210_UPHYPWR_HSIC0_SLEEP) - -#define EXYNOS_4210_UPHYPWR_HSIC1_SUSPEND BIT(11) -#define EXYNOS_4210_UPHYPWR_HSIC1_SLEEP BIT(12) -#define EXYNOS_4210_UPHYPWR_HSIC1 ( \ - EXYNOS_4210_UPHYPWR_HSIC1_SUSPEND | \ - EXYNOS_4210_UPHYPWR_HSIC1_SLEEP) - -/* PHY clock control */ -#define EXYNOS_4210_UPHYCLK 0x4 - -#define EXYNOS_4210_UPHYCLK_PHYFSEL_MASK (0x3 << 0) -#define EXYNOS_4210_UPHYCLK_PHYFSEL_OFFSET 0 -#define EXYNOS_4210_UPHYCLK_PHYFSEL_48MHZ (0x0 << 0) -#define EXYNOS_4210_UPHYCLK_PHYFSEL_24MHZ (0x3 << 0) -#define EXYNOS_4210_UPHYCLK_PHYFSEL_12MHZ (0x2 << 0) - -#define EXYNOS_4210_UPHYCLK_PHY0_ID_PULLUP BIT(2) -#define EXYNOS_4210_UPHYCLK_PHY0_COMMON_ON BIT(4) -#define EXYNOS_4210_UPHYCLK_PHY1_COMMON_ON BIT(7) - -/* PHY reset control */ -#define EXYNOS_4210_UPHYRST 0x8 - -#define EXYNOS_4210_URSTCON_PHY0 BIT(0) -#define EXYNOS_4210_URSTCON_OTG_HLINK BIT(1) -#define EXYNOS_4210_URSTCON_OTG_PHYLINK BIT(2) -#define EXYNOS_4210_URSTCON_PHY1_ALL BIT(3) -#define EXYNOS_4210_URSTCON_PHY1_P0 BIT(4) -#define EXYNOS_4210_URSTCON_PHY1_P1P2 BIT(5) -#define EXYNOS_4210_URSTCON_HOST_LINK_ALL BIT(6) -#define EXYNOS_4210_URSTCON_HOST_LINK_P0 BIT(7) -#define EXYNOS_4210_URSTCON_HOST_LINK_P1 BIT(8) -#define EXYNOS_4210_URSTCON_HOST_LINK_P2 BIT(9) - -/* Isolation, configured in the power management unit */ -#define EXYNOS_4210_USB_ISOL_DEVICE_OFFSET 0x704 -#define EXYNOS_4210_USB_ISOL_DEVICE BIT(0) -#define EXYNOS_4210_USB_ISOL_HOST_OFFSET 0x708 -#define EXYNOS_4210_USB_ISOL_HOST BIT(0) - -/* USBYPHY1 Floating prevention */ -#define EXYNOS_4210_UPHY1CON 0x34 -#define EXYNOS_4210_UPHY1CON_FLOAT_PREVENTION 0x1 - -/* Mode switching SUB Device <-> Host */ -#define EXYNOS_4210_MODE_SWITCH_OFFSET 0x21c -#define EXYNOS_4210_MODE_SWITCH_MASK 1 -#define EXYNOS_4210_MODE_SWITCH_DEVICE 0 -#define EXYNOS_4210_MODE_SWITCH_HOST 1 - -enum exynos4210_phy_id { - EXYNOS4210_DEVICE, - EXYNOS4210_HOST, - EXYNOS4210_HSIC0, - EXYNOS4210_HSIC1, - EXYNOS4210_NUM_PHYS, -}; - -/* - * exynos4210_rate_to_clk() converts the supplied clock rate to the value that - * can be written to the phy register. - */ -static int exynos4210_rate_to_clk(unsigned long rate, u32 *reg) -{ - switch (rate) { - case 12 * MHZ: - *reg = EXYNOS_4210_UPHYCLK_PHYFSEL_12MHZ; - break; - case 24 * MHZ: - *reg = EXYNOS_4210_UPHYCLK_PHYFSEL_24MHZ; - break; - case 48 * MHZ: - *reg = EXYNOS_4210_UPHYCLK_PHYFSEL_48MHZ; - break; - default: - return -EINVAL; - } - - return 0; -} - -static void exynos4210_isol(struct samsung_usb2_phy_instance *inst, bool on) -{ - struct samsung_usb2_phy_driver *drv = inst->drv; - u32 offset; - u32 mask; - - switch (inst->cfg->id) { - case EXYNOS4210_DEVICE: - offset = EXYNOS_4210_USB_ISOL_DEVICE_OFFSET; - mask = EXYNOS_4210_USB_ISOL_DEVICE; - break; - case EXYNOS4210_HOST: - offset = EXYNOS_4210_USB_ISOL_HOST_OFFSET; - mask = EXYNOS_4210_USB_ISOL_HOST; - break; - default: - return; - }; - - regmap_update_bits(drv->reg_pmu, offset, mask, on ? 0 : mask); -} - -static void exynos4210_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on) -{ - struct samsung_usb2_phy_driver *drv = inst->drv; - u32 rstbits = 0; - u32 phypwr = 0; - u32 rst; - u32 pwr; - u32 clk; - - switch (inst->cfg->id) { - case EXYNOS4210_DEVICE: - phypwr = EXYNOS_4210_UPHYPWR_PHY0; - rstbits = EXYNOS_4210_URSTCON_PHY0; - break; - case EXYNOS4210_HOST: - phypwr = EXYNOS_4210_UPHYPWR_PHY1; - rstbits = EXYNOS_4210_URSTCON_PHY1_ALL | - EXYNOS_4210_URSTCON_PHY1_P0 | - EXYNOS_4210_URSTCON_PHY1_P1P2 | - EXYNOS_4210_URSTCON_HOST_LINK_ALL | - EXYNOS_4210_URSTCON_HOST_LINK_P0; - writel(on, drv->reg_phy + EXYNOS_4210_UPHY1CON); - break; - case EXYNOS4210_HSIC0: - phypwr = EXYNOS_4210_UPHYPWR_HSIC0; - rstbits = EXYNOS_4210_URSTCON_PHY1_P1P2 | - EXYNOS_4210_URSTCON_HOST_LINK_P1; - break; - case EXYNOS4210_HSIC1: - phypwr = EXYNOS_4210_UPHYPWR_HSIC1; - rstbits = EXYNOS_4210_URSTCON_PHY1_P1P2 | - EXYNOS_4210_URSTCON_HOST_LINK_P2; - break; - }; - - if (on) { - clk = readl(drv->reg_phy + EXYNOS_4210_UPHYCLK); - clk &= ~EXYNOS_4210_UPHYCLK_PHYFSEL_MASK; - clk |= drv->ref_reg_val << EXYNOS_4210_UPHYCLK_PHYFSEL_OFFSET; - writel(clk, drv->reg_phy + EXYNOS_4210_UPHYCLK); - - pwr = readl(drv->reg_phy + EXYNOS_4210_UPHYPWR); - pwr &= ~phypwr; - writel(pwr, drv->reg_phy + EXYNOS_4210_UPHYPWR); - - rst = readl(drv->reg_phy + EXYNOS_4210_UPHYRST); - rst |= rstbits; - writel(rst, drv->reg_phy + EXYNOS_4210_UPHYRST); - udelay(10); - rst &= ~rstbits; - writel(rst, drv->reg_phy + EXYNOS_4210_UPHYRST); - /* The following delay is necessary for the reset sequence to be - * completed */ - udelay(80); - } else { - pwr = readl(drv->reg_phy + EXYNOS_4210_UPHYPWR); - pwr |= phypwr; - writel(pwr, drv->reg_phy + EXYNOS_4210_UPHYPWR); - } -} - -static int exynos4210_power_on(struct samsung_usb2_phy_instance *inst) -{ - /* Order of initialisation is important - first power then isolation */ - exynos4210_phy_pwr(inst, 1); - exynos4210_isol(inst, 0); - - return 0; -} - -static int exynos4210_power_off(struct samsung_usb2_phy_instance *inst) -{ - exynos4210_isol(inst, 1); - exynos4210_phy_pwr(inst, 0); - - return 0; -} - - -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, - }, - {}, -}; - -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, -}; diff --git a/drivers/phy/phy-exynos4x12-usb2.c b/drivers/phy/phy-exynos4x12-usb2.c deleted file mode 100644 index 0b9de88579b1..000000000000 --- a/drivers/phy/phy-exynos4x12-usb2.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Samsung SoC USB 1.1/2.0 PHY driver - Exynos 4x12 support - * - * Copyright (C) 2013 Samsung Electronics Co., Ltd. - * Author: Kamil Debski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include "phy-samsung-usb2.h" - -/* Exynos USB PHY registers */ - -/* PHY power control */ -#define EXYNOS_4x12_UPHYPWR 0x0 - -#define EXYNOS_4x12_UPHYPWR_PHY0_SUSPEND BIT(0) -#define EXYNOS_4x12_UPHYPWR_PHY0_PWR BIT(3) -#define EXYNOS_4x12_UPHYPWR_PHY0_OTG_PWR BIT(4) -#define EXYNOS_4x12_UPHYPWR_PHY0_SLEEP BIT(5) -#define EXYNOS_4x12_UPHYPWR_PHY0 ( \ - EXYNOS_4x12_UPHYPWR_PHY0_SUSPEND | \ - EXYNOS_4x12_UPHYPWR_PHY0_PWR | \ - EXYNOS_4x12_UPHYPWR_PHY0_OTG_PWR | \ - EXYNOS_4x12_UPHYPWR_PHY0_SLEEP) - -#define EXYNOS_4x12_UPHYPWR_PHY1_SUSPEND BIT(6) -#define EXYNOS_4x12_UPHYPWR_PHY1_PWR BIT(7) -#define EXYNOS_4x12_UPHYPWR_PHY1_SLEEP BIT(8) -#define EXYNOS_4x12_UPHYPWR_PHY1 ( \ - EXYNOS_4x12_UPHYPWR_PHY1_SUSPEND | \ - EXYNOS_4x12_UPHYPWR_PHY1_PWR | \ - EXYNOS_4x12_UPHYPWR_PHY1_SLEEP) - -#define EXYNOS_4x12_UPHYPWR_HSIC0_SUSPEND BIT(9) -#define EXYNOS_4x12_UPHYPWR_HSIC0_PWR BIT(10) -#define EXYNOS_4x12_UPHYPWR_HSIC0_SLEEP BIT(11) -#define EXYNOS_4x12_UPHYPWR_HSIC0 ( \ - EXYNOS_4x12_UPHYPWR_HSIC0_SUSPEND | \ - EXYNOS_4x12_UPHYPWR_HSIC0_PWR | \ - EXYNOS_4x12_UPHYPWR_HSIC0_SLEEP) - -#define EXYNOS_4x12_UPHYPWR_HSIC1_SUSPEND BIT(12) -#define EXYNOS_4x12_UPHYPWR_HSIC1_PWR BIT(13) -#define EXYNOS_4x12_UPHYPWR_HSIC1_SLEEP BIT(14) -#define EXYNOS_4x12_UPHYPWR_HSIC1 ( \ - EXYNOS_4x12_UPHYPWR_HSIC1_SUSPEND | \ - EXYNOS_4x12_UPHYPWR_HSIC1_PWR | \ - EXYNOS_4x12_UPHYPWR_HSIC1_SLEEP) - -/* PHY clock control */ -#define EXYNOS_4x12_UPHYCLK 0x4 - -#define EXYNOS_4x12_UPHYCLK_PHYFSEL_MASK (0x7 << 0) -#define EXYNOS_4x12_UPHYCLK_PHYFSEL_OFFSET 0 -#define EXYNOS_4x12_UPHYCLK_PHYFSEL_9MHZ6 (0x0 << 0) -#define EXYNOS_4x12_UPHYCLK_PHYFSEL_10MHZ (0x1 << 0) -#define EXYNOS_4x12_UPHYCLK_PHYFSEL_12MHZ (0x2 << 0) -#define EXYNOS_4x12_UPHYCLK_PHYFSEL_19MHZ2 (0x3 << 0) -#define EXYNOS_4x12_UPHYCLK_PHYFSEL_20MHZ (0x4 << 0) -#define EXYNOS_4x12_UPHYCLK_PHYFSEL_24MHZ (0x5 << 0) -#define EXYNOS_4x12_UPHYCLK_PHYFSEL_50MHZ (0x7 << 0) - -#define EXYNOS_3250_UPHYCLK_REFCLKSEL (0x2 << 8) - -#define EXYNOS_4x12_UPHYCLK_PHY0_ID_PULLUP BIT(3) -#define EXYNOS_4x12_UPHYCLK_PHY0_COMMON_ON BIT(4) -#define EXYNOS_4x12_UPHYCLK_PHY1_COMMON_ON BIT(7) - -#define EXYNOS_4x12_UPHYCLK_HSIC_REFCLK_MASK (0x7f << 10) -#define EXYNOS_4x12_UPHYCLK_HSIC_REFCLK_OFFSET 10 -#define EXYNOS_4x12_UPHYCLK_HSIC_REFCLK_12MHZ (0x24 << 10) -#define EXYNOS_4x12_UPHYCLK_HSIC_REFCLK_15MHZ (0x1c << 10) -#define EXYNOS_4x12_UPHYCLK_HSIC_REFCLK_16MHZ (0x1a << 10) -#define EXYNOS_4x12_UPHYCLK_HSIC_REFCLK_19MHZ2 (0x15 << 10) -#define EXYNOS_4x12_UPHYCLK_HSIC_REFCLK_20MHZ (0x14 << 10) - -/* PHY reset control */ -#define EXYNOS_4x12_UPHYRST 0x8 - -#define EXYNOS_4x12_URSTCON_PHY0 BIT(0) -#define EXYNOS_4x12_URSTCON_OTG_HLINK BIT(1) -#define EXYNOS_4x12_URSTCON_OTG_PHYLINK BIT(2) -#define EXYNOS_4x12_URSTCON_HOST_PHY BIT(3) -/* The following bit defines are presented in the - * order taken from the Exynos4412 reference manual. - * - * During experiments with the hardware and debugging - * it was determined that the hardware behaves contrary - * to the manual. - * - * The following bit values were chaned accordingly to the - * results of real hardware experiments. - */ -#define EXYNOS_4x12_URSTCON_PHY1 BIT(4) -#define EXYNOS_4x12_URSTCON_HSIC0 BIT(6) -#define EXYNOS_4x12_URSTCON_HSIC1 BIT(5) -#define EXYNOS_4x12_URSTCON_HOST_LINK_ALL BIT(7) -#define EXYNOS_4x12_URSTCON_HOST_LINK_P0 BIT(10) -#define EXYNOS_4x12_URSTCON_HOST_LINK_P1 BIT(9) -#define EXYNOS_4x12_URSTCON_HOST_LINK_P2 BIT(8) - -/* Isolation, configured in the power management unit */ -#define EXYNOS_4x12_USB_ISOL_OFFSET 0x704 -#define EXYNOS_4x12_USB_ISOL_OTG BIT(0) -#define EXYNOS_4x12_USB_ISOL_HSIC0_OFFSET 0x708 -#define EXYNOS_4x12_USB_ISOL_HSIC0 BIT(0) -#define EXYNOS_4x12_USB_ISOL_HSIC1_OFFSET 0x70c -#define EXYNOS_4x12_USB_ISOL_HSIC1 BIT(0) - -/* Mode switching SUB Device <-> Host */ -#define EXYNOS_4x12_MODE_SWITCH_OFFSET 0x21c -#define EXYNOS_4x12_MODE_SWITCH_MASK 1 -#define EXYNOS_4x12_MODE_SWITCH_DEVICE 0 -#define EXYNOS_4x12_MODE_SWITCH_HOST 1 - -enum exynos4x12_phy_id { - EXYNOS4x12_DEVICE, - EXYNOS4x12_HOST, - EXYNOS4x12_HSIC0, - EXYNOS4x12_HSIC1, - EXYNOS4x12_NUM_PHYS, -}; - -/* - * exynos4x12_rate_to_clk() converts the supplied clock rate to the value that - * can be written to the phy register. - */ -static int exynos4x12_rate_to_clk(unsigned long rate, u32 *reg) -{ - /* EXYNOS_4x12_UPHYCLK_PHYFSEL_MASK */ - - switch (rate) { - case 9600 * KHZ: - *reg = EXYNOS_4x12_UPHYCLK_PHYFSEL_9MHZ6; - break; - case 10 * MHZ: - *reg = EXYNOS_4x12_UPHYCLK_PHYFSEL_10MHZ; - break; - case 12 * MHZ: - *reg = EXYNOS_4x12_UPHYCLK_PHYFSEL_12MHZ; - break; - case 19200 * KHZ: - *reg = EXYNOS_4x12_UPHYCLK_PHYFSEL_19MHZ2; - break; - case 20 * MHZ: - *reg = EXYNOS_4x12_UPHYCLK_PHYFSEL_20MHZ; - break; - case 24 * MHZ: - *reg = EXYNOS_4x12_UPHYCLK_PHYFSEL_24MHZ; - break; - case 50 * MHZ: - *reg = EXYNOS_4x12_UPHYCLK_PHYFSEL_50MHZ; - break; - default: - return -EINVAL; - } - - return 0; -} - -static void exynos4x12_isol(struct samsung_usb2_phy_instance *inst, bool on) -{ - struct samsung_usb2_phy_driver *drv = inst->drv; - u32 offset; - u32 mask; - - switch (inst->cfg->id) { - case EXYNOS4x12_DEVICE: - case EXYNOS4x12_HOST: - offset = EXYNOS_4x12_USB_ISOL_OFFSET; - mask = EXYNOS_4x12_USB_ISOL_OTG; - break; - case EXYNOS4x12_HSIC0: - offset = EXYNOS_4x12_USB_ISOL_HSIC0_OFFSET; - mask = EXYNOS_4x12_USB_ISOL_HSIC0; - break; - case EXYNOS4x12_HSIC1: - offset = EXYNOS_4x12_USB_ISOL_HSIC1_OFFSET; - mask = EXYNOS_4x12_USB_ISOL_HSIC1; - break; - default: - return; - }; - - regmap_update_bits(drv->reg_pmu, offset, mask, on ? 0 : mask); -} - -static void exynos4x12_setup_clk(struct samsung_usb2_phy_instance *inst) -{ - struct samsung_usb2_phy_driver *drv = inst->drv; - u32 clk; - - clk = readl(drv->reg_phy + EXYNOS_4x12_UPHYCLK); - clk &= ~EXYNOS_4x12_UPHYCLK_PHYFSEL_MASK; - - if (drv->cfg->has_refclk_sel) - clk = EXYNOS_3250_UPHYCLK_REFCLKSEL; - - clk |= drv->ref_reg_val << EXYNOS_4x12_UPHYCLK_PHYFSEL_OFFSET; - clk |= EXYNOS_4x12_UPHYCLK_PHY1_COMMON_ON; - writel(clk, drv->reg_phy + EXYNOS_4x12_UPHYCLK); -} - -static void exynos4x12_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on) -{ - struct samsung_usb2_phy_driver *drv = inst->drv; - u32 rstbits = 0; - u32 phypwr = 0; - u32 rst; - u32 pwr; - - switch (inst->cfg->id) { - case EXYNOS4x12_DEVICE: - phypwr = EXYNOS_4x12_UPHYPWR_PHY0; - rstbits = EXYNOS_4x12_URSTCON_PHY0; - break; - case EXYNOS4x12_HOST: - phypwr = EXYNOS_4x12_UPHYPWR_PHY1; - rstbits = EXYNOS_4x12_URSTCON_HOST_PHY | - EXYNOS_4x12_URSTCON_PHY1 | - EXYNOS_4x12_URSTCON_HOST_LINK_P0; - break; - case EXYNOS4x12_HSIC0: - phypwr = EXYNOS_4x12_UPHYPWR_HSIC0; - rstbits = EXYNOS_4x12_URSTCON_HSIC0 | - EXYNOS_4x12_URSTCON_HOST_LINK_P1; - break; - case EXYNOS4x12_HSIC1: - phypwr = EXYNOS_4x12_UPHYPWR_HSIC1; - rstbits = EXYNOS_4x12_URSTCON_HSIC1 | - EXYNOS_4x12_URSTCON_HOST_LINK_P1; - break; - }; - - if (on) { - pwr = readl(drv->reg_phy + EXYNOS_4x12_UPHYPWR); - pwr &= ~phypwr; - writel(pwr, drv->reg_phy + EXYNOS_4x12_UPHYPWR); - - rst = readl(drv->reg_phy + EXYNOS_4x12_UPHYRST); - rst |= rstbits; - writel(rst, drv->reg_phy + EXYNOS_4x12_UPHYRST); - udelay(10); - rst &= ~rstbits; - writel(rst, drv->reg_phy + EXYNOS_4x12_UPHYRST); - /* The following delay is necessary for the reset sequence to be - * completed */ - udelay(80); - } else { - pwr = readl(drv->reg_phy + EXYNOS_4x12_UPHYPWR); - pwr |= phypwr; - writel(pwr, drv->reg_phy + EXYNOS_4x12_UPHYPWR); - } -} - -static void exynos4x12_power_on_int(struct samsung_usb2_phy_instance *inst) -{ - if (inst->int_cnt++ > 0) - return; - - exynos4x12_setup_clk(inst); - exynos4x12_isol(inst, 0); - exynos4x12_phy_pwr(inst, 1); -} - -static int exynos4x12_power_on(struct samsung_usb2_phy_instance *inst) -{ - struct samsung_usb2_phy_driver *drv = inst->drv; - - if (inst->ext_cnt++ > 0) - return 0; - - if (inst->cfg->id == EXYNOS4x12_HOST) { - regmap_update_bits(drv->reg_sys, EXYNOS_4x12_MODE_SWITCH_OFFSET, - EXYNOS_4x12_MODE_SWITCH_MASK, - EXYNOS_4x12_MODE_SWITCH_HOST); - exynos4x12_power_on_int(&drv->instances[EXYNOS4x12_DEVICE]); - } - - if (inst->cfg->id == EXYNOS4x12_DEVICE && drv->cfg->has_mode_switch) - regmap_update_bits(drv->reg_sys, EXYNOS_4x12_MODE_SWITCH_OFFSET, - EXYNOS_4x12_MODE_SWITCH_MASK, - EXYNOS_4x12_MODE_SWITCH_DEVICE); - - if (inst->cfg->id == EXYNOS4x12_HSIC0 || - inst->cfg->id == EXYNOS4x12_HSIC1) { - exynos4x12_power_on_int(&drv->instances[EXYNOS4x12_DEVICE]); - exynos4x12_power_on_int(&drv->instances[EXYNOS4x12_HOST]); - } - - exynos4x12_power_on_int(inst); - - return 0; -} - -static void exynos4x12_power_off_int(struct samsung_usb2_phy_instance *inst) -{ - if (inst->int_cnt-- > 1) - return; - - exynos4x12_isol(inst, 1); - exynos4x12_phy_pwr(inst, 0); -} - -static int exynos4x12_power_off(struct samsung_usb2_phy_instance *inst) -{ - struct samsung_usb2_phy_driver *drv = inst->drv; - - if (inst->ext_cnt-- > 1) - return 0; - - if (inst->cfg->id == EXYNOS4x12_DEVICE && drv->cfg->has_mode_switch) - regmap_update_bits(drv->reg_sys, EXYNOS_4x12_MODE_SWITCH_OFFSET, - EXYNOS_4x12_MODE_SWITCH_MASK, - EXYNOS_4x12_MODE_SWITCH_HOST); - - if (inst->cfg->id == EXYNOS4x12_HOST) - exynos4x12_power_off_int(&drv->instances[EXYNOS4x12_DEVICE]); - - if (inst->cfg->id == EXYNOS4x12_HSIC0 || - inst->cfg->id == EXYNOS4x12_HSIC1) { - exynos4x12_power_off_int(&drv->instances[EXYNOS4x12_DEVICE]); - exynos4x12_power_off_int(&drv->instances[EXYNOS4x12_HOST]); - } - - exynos4x12_power_off_int(inst); - - return 0; -} - - -static const struct samsung_usb2_common_phy exynos4x12_phys[] = { - { - .label = "device", - .id = EXYNOS4x12_DEVICE, - .power_on = exynos4x12_power_on, - .power_off = exynos4x12_power_off, - }, - { - .label = "host", - .id = EXYNOS4x12_HOST, - .power_on = exynos4x12_power_on, - .power_off = exynos4x12_power_off, - }, - { - .label = "hsic0", - .id = EXYNOS4x12_HSIC0, - .power_on = exynos4x12_power_on, - .power_off = exynos4x12_power_off, - }, - { - .label = "hsic1", - .id = EXYNOS4x12_HSIC1, - .power_on = exynos4x12_power_on, - .power_off = exynos4x12_power_off, - }, - {}, -}; - -const struct samsung_usb2_phy_config exynos3250_usb2_phy_config = { - .has_refclk_sel = 1, - .num_phys = 1, - .phys = exynos4x12_phys, - .rate_to_clk = exynos4x12_rate_to_clk, -}; - -const struct samsung_usb2_phy_config exynos4x12_usb2_phy_config = { - .has_mode_switch = 1, - .num_phys = EXYNOS4x12_NUM_PHYS, - .phys = exynos4x12_phys, - .rate_to_clk = exynos4x12_rate_to_clk, -}; diff --git a/drivers/phy/phy-exynos5-usbdrd.c b/drivers/phy/phy-exynos5-usbdrd.c deleted file mode 100644 index f756aca871db..000000000000 --- a/drivers/phy/phy-exynos5-usbdrd.c +++ /dev/null @@ -1,677 +0,0 @@ -/* - * Samsung EXYNOS5 SoC series USB DRD PHY driver - * - * Phy provider for USB 3.0 DRD controller on Exynos5 SoC series - * - * Copyright (C) 2014 Samsung Electronics Co., Ltd. - * Author: Vivek Gautam - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Exynos USB PHY registers */ -#define EXYNOS5_FSEL_9MHZ6 0x0 -#define EXYNOS5_FSEL_10MHZ 0x1 -#define EXYNOS5_FSEL_12MHZ 0x2 -#define EXYNOS5_FSEL_19MHZ2 0x3 -#define EXYNOS5_FSEL_20MHZ 0x4 -#define EXYNOS5_FSEL_24MHZ 0x5 -#define EXYNOS5_FSEL_50MHZ 0x7 - -/* EXYNOS5: USB 3.0 DRD PHY registers */ -#define EXYNOS5_DRD_LINKSYSTEM 0x04 - -#define LINKSYSTEM_FLADJ_MASK (0x3f << 1) -#define LINKSYSTEM_FLADJ(_x) ((_x) << 1) -#define LINKSYSTEM_XHCI_VERSION_CONTROL BIT(27) - -#define EXYNOS5_DRD_PHYUTMI 0x08 - -#define PHYUTMI_OTGDISABLE BIT(6) -#define PHYUTMI_FORCESUSPEND BIT(1) -#define PHYUTMI_FORCESLEEP BIT(0) - -#define EXYNOS5_DRD_PHYPIPE 0x0c - -#define EXYNOS5_DRD_PHYCLKRST 0x10 - -#define PHYCLKRST_EN_UTMISUSPEND BIT(31) - -#define PHYCLKRST_SSC_REFCLKSEL_MASK (0xff << 23) -#define PHYCLKRST_SSC_REFCLKSEL(_x) ((_x) << 23) - -#define PHYCLKRST_SSC_RANGE_MASK (0x03 << 21) -#define PHYCLKRST_SSC_RANGE(_x) ((_x) << 21) - -#define PHYCLKRST_SSC_EN BIT(20) -#define PHYCLKRST_REF_SSP_EN BIT(19) -#define PHYCLKRST_REF_CLKDIV2 BIT(18) - -#define PHYCLKRST_MPLL_MULTIPLIER_MASK (0x7f << 11) -#define PHYCLKRST_MPLL_MULTIPLIER_100MHZ_REF (0x19 << 11) -#define PHYCLKRST_MPLL_MULTIPLIER_50M_REF (0x32 << 11) -#define PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF (0x68 << 11) -#define PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF (0x7d << 11) -#define PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF (0x02 << 11) - -#define PHYCLKRST_FSEL_UTMI_MASK (0x7 << 5) -#define PHYCLKRST_FSEL_PIPE_MASK (0x7 << 8) -#define PHYCLKRST_FSEL(_x) ((_x) << 5) -#define PHYCLKRST_FSEL_PAD_100MHZ (0x27 << 5) -#define PHYCLKRST_FSEL_PAD_24MHZ (0x2a << 5) -#define PHYCLKRST_FSEL_PAD_20MHZ (0x31 << 5) -#define PHYCLKRST_FSEL_PAD_19_2MHZ (0x38 << 5) - -#define PHYCLKRST_RETENABLEN BIT(4) - -#define PHYCLKRST_REFCLKSEL_MASK (0x03 << 2) -#define PHYCLKRST_REFCLKSEL_PAD_REFCLK (0x2 << 2) -#define PHYCLKRST_REFCLKSEL_EXT_REFCLK (0x3 << 2) - -#define PHYCLKRST_PORTRESET BIT(1) -#define PHYCLKRST_COMMONONN BIT(0) - -#define EXYNOS5_DRD_PHYREG0 0x14 -#define EXYNOS5_DRD_PHYREG1 0x18 - -#define EXYNOS5_DRD_PHYPARAM0 0x1c - -#define PHYPARAM0_REF_USE_PAD BIT(31) -#define PHYPARAM0_REF_LOSLEVEL_MASK (0x1f << 26) -#define PHYPARAM0_REF_LOSLEVEL (0x9 << 26) - -#define EXYNOS5_DRD_PHYPARAM1 0x20 - -#define PHYPARAM1_PCS_TXDEEMPH_MASK (0x1f << 0) -#define PHYPARAM1_PCS_TXDEEMPH (0x1c) - -#define EXYNOS5_DRD_PHYTERM 0x24 - -#define EXYNOS5_DRD_PHYTEST 0x28 - -#define PHYTEST_POWERDOWN_SSP BIT(3) -#define PHYTEST_POWERDOWN_HSP BIT(2) - -#define EXYNOS5_DRD_PHYADP 0x2c - -#define EXYNOS5_DRD_PHYUTMICLKSEL 0x30 - -#define PHYUTMICLKSEL_UTMI_CLKSEL BIT(2) - -#define EXYNOS5_DRD_PHYRESUME 0x34 -#define EXYNOS5_DRD_LINKPORT 0x44 - -#define KHZ 1000 -#define MHZ (KHZ * KHZ) - -enum exynos5_usbdrd_phy_id { - EXYNOS5_DRDPHY_UTMI, - EXYNOS5_DRDPHY_PIPE3, - EXYNOS5_DRDPHYS_NUM, -}; - -struct phy_usb_instance; -struct exynos5_usbdrd_phy; - -struct exynos5_usbdrd_phy_config { - u32 id; - void (*phy_isol)(struct phy_usb_instance *inst, u32 on); - void (*phy_init)(struct exynos5_usbdrd_phy *phy_drd); - unsigned int (*set_refclk)(struct phy_usb_instance *inst); -}; - -struct exynos5_usbdrd_phy_drvdata { - const struct exynos5_usbdrd_phy_config *phy_cfg; - u32 pmu_offset_usbdrd0_phy; - u32 pmu_offset_usbdrd1_phy; -}; - -/** - * struct exynos5_usbdrd_phy - driver data for USB 3.0 PHY - * @dev: pointer to device instance of this platform device - * @reg_phy: usb phy controller register memory base - * @clk: phy clock for register access - * @drv_data: pointer to SoC level driver data structure - * @phys[]: array for 'EXYNOS5_DRDPHYS_NUM' number of PHY - * instances each with its 'phy' and 'phy_cfg'. - * @extrefclk: frequency select settings when using 'separate - * reference clocks' for SS and HS operations - * @ref_clk: reference clock to PHY block from which PHY's - * operational clocks are derived - * @ref_rate: rate of above reference clock - */ -struct exynos5_usbdrd_phy { - struct device *dev; - void __iomem *reg_phy; - struct clk *clk; - const struct exynos5_usbdrd_phy_drvdata *drv_data; - struct phy_usb_instance { - struct phy *phy; - u32 index; - struct regmap *reg_pmu; - u32 pmu_offset; - const struct exynos5_usbdrd_phy_config *phy_cfg; - } phys[EXYNOS5_DRDPHYS_NUM]; - u32 extrefclk; - struct clk *ref_clk; - struct regulator *vbus; -}; - -static inline -struct exynos5_usbdrd_phy *to_usbdrd_phy(struct phy_usb_instance *inst) -{ - return container_of((inst), struct exynos5_usbdrd_phy, - phys[(inst)->index]); -} - -/* - * exynos5_rate_to_clk() converts the supplied clock rate to the value that - * can be written to the phy register. - */ -static unsigned int exynos5_rate_to_clk(unsigned long rate, u32 *reg) -{ - /* EXYNOS5_FSEL_MASK */ - - switch (rate) { - case 9600 * KHZ: - *reg = EXYNOS5_FSEL_9MHZ6; - break; - case 10 * MHZ: - *reg = EXYNOS5_FSEL_10MHZ; - break; - case 12 * MHZ: - *reg = EXYNOS5_FSEL_12MHZ; - break; - case 19200 * KHZ: - *reg = EXYNOS5_FSEL_19MHZ2; - break; - case 20 * MHZ: - *reg = EXYNOS5_FSEL_20MHZ; - break; - case 24 * MHZ: - *reg = EXYNOS5_FSEL_24MHZ; - break; - case 50 * MHZ: - *reg = EXYNOS5_FSEL_50MHZ; - break; - default: - return -EINVAL; - } - - return 0; -} - -static void exynos5_usbdrd_phy_isol(struct phy_usb_instance *inst, - unsigned int on) -{ - unsigned int val; - - if (!inst->reg_pmu) - return; - - val = on ? 0 : EXYNOS5_PHY_ENABLE; - - regmap_update_bits(inst->reg_pmu, inst->pmu_offset, - EXYNOS5_PHY_ENABLE, val); -} - -/* - * Sets the pipe3 phy's clk as EXTREFCLK (XXTI) which is internal clock - * from clock core. Further sets multiplier values and spread spectrum - * clock settings for SuperSpeed operations. - */ -static unsigned int -exynos5_usbdrd_pipe3_set_refclk(struct phy_usb_instance *inst) -{ - static u32 reg; - struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); - - /* restore any previous reference clock settings */ - reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); - - /* Use EXTREFCLK as ref clock */ - reg &= ~PHYCLKRST_REFCLKSEL_MASK; - reg |= PHYCLKRST_REFCLKSEL_EXT_REFCLK; - - /* FSEL settings corresponding to reference clock */ - reg &= ~PHYCLKRST_FSEL_PIPE_MASK | - PHYCLKRST_MPLL_MULTIPLIER_MASK | - PHYCLKRST_SSC_REFCLKSEL_MASK; - switch (phy_drd->extrefclk) { - case EXYNOS5_FSEL_50MHZ: - reg |= (PHYCLKRST_MPLL_MULTIPLIER_50M_REF | - PHYCLKRST_SSC_REFCLKSEL(0x00)); - break; - case EXYNOS5_FSEL_24MHZ: - reg |= (PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF | - PHYCLKRST_SSC_REFCLKSEL(0x88)); - break; - case EXYNOS5_FSEL_20MHZ: - reg |= (PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF | - PHYCLKRST_SSC_REFCLKSEL(0x00)); - break; - case EXYNOS5_FSEL_19MHZ2: - reg |= (PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF | - PHYCLKRST_SSC_REFCLKSEL(0x88)); - break; - default: - dev_dbg(phy_drd->dev, "unsupported ref clk\n"); - break; - } - - return reg; -} - -/* - * Sets the utmi phy's clk as EXTREFCLK (XXTI) which is internal clock - * from clock core. Further sets the FSEL values for HighSpeed operations. - */ -static unsigned int -exynos5_usbdrd_utmi_set_refclk(struct phy_usb_instance *inst) -{ - static u32 reg; - struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); - - /* restore any previous reference clock settings */ - reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); - - reg &= ~PHYCLKRST_REFCLKSEL_MASK; - reg |= PHYCLKRST_REFCLKSEL_EXT_REFCLK; - - reg &= ~PHYCLKRST_FSEL_UTMI_MASK | - PHYCLKRST_MPLL_MULTIPLIER_MASK | - PHYCLKRST_SSC_REFCLKSEL_MASK; - reg |= PHYCLKRST_FSEL(phy_drd->extrefclk); - - return reg; -} - -static void exynos5_usbdrd_pipe3_init(struct exynos5_usbdrd_phy *phy_drd) -{ - u32 reg; - - reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM1); - /* Set Tx De-Emphasis level */ - reg &= ~PHYPARAM1_PCS_TXDEEMPH_MASK; - reg |= PHYPARAM1_PCS_TXDEEMPH; - writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM1); - - reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); - reg &= ~PHYTEST_POWERDOWN_SSP; - writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); -} - -static void exynos5_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) -{ - u32 reg; - - reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM0); - /* Set Loss-of-Signal Detector sensitivity */ - reg &= ~PHYPARAM0_REF_LOSLEVEL_MASK; - reg |= PHYPARAM0_REF_LOSLEVEL; - writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM0); - - reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM1); - /* Set Tx De-Emphasis level */ - reg &= ~PHYPARAM1_PCS_TXDEEMPH_MASK; - reg |= PHYPARAM1_PCS_TXDEEMPH; - writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM1); - - /* UTMI Power Control */ - writel(PHYUTMI_OTGDISABLE, phy_drd->reg_phy + EXYNOS5_DRD_PHYUTMI); - - reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); - reg &= ~PHYTEST_POWERDOWN_HSP; - writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); -} - -static int exynos5_usbdrd_phy_init(struct phy *phy) -{ - int ret; - u32 reg; - struct phy_usb_instance *inst = phy_get_drvdata(phy); - struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); - - ret = clk_prepare_enable(phy_drd->clk); - if (ret) - return ret; - - /* Reset USB 3.0 PHY */ - writel(0x0, phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0); - writel(0x0, phy_drd->reg_phy + EXYNOS5_DRD_PHYRESUME); - - /* - * Setting the Frame length Adj value[6:1] to default 0x20 - * See xHCI 1.0 spec, 5.2.4 - */ - reg = LINKSYSTEM_XHCI_VERSION_CONTROL | - LINKSYSTEM_FLADJ(0x20); - writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_LINKSYSTEM); - - reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM0); - /* Select PHY CLK source */ - reg &= ~PHYPARAM0_REF_USE_PAD; - writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM0); - - /* This bit must be set for both HS and SS operations */ - reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYUTMICLKSEL); - reg |= PHYUTMICLKSEL_UTMI_CLKSEL; - writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYUTMICLKSEL); - - /* UTMI or PIPE3 specific init */ - inst->phy_cfg->phy_init(phy_drd); - - /* reference clock settings */ - reg = inst->phy_cfg->set_refclk(inst); - - /* Digital power supply in normal operating mode */ - reg |= PHYCLKRST_RETENABLEN | - /* Enable ref clock for SS function */ - PHYCLKRST_REF_SSP_EN | - /* Enable spread spectrum */ - PHYCLKRST_SSC_EN | - /* Power down HS Bias and PLL blocks in suspend mode */ - PHYCLKRST_COMMONONN | - /* Reset the port */ - PHYCLKRST_PORTRESET; - - writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); - - udelay(10); - - reg &= ~PHYCLKRST_PORTRESET; - writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); - - clk_disable_unprepare(phy_drd->clk); - - return 0; -} - -static int exynos5_usbdrd_phy_exit(struct phy *phy) -{ - int ret; - u32 reg; - struct phy_usb_instance *inst = phy_get_drvdata(phy); - struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); - - ret = clk_prepare_enable(phy_drd->clk); - if (ret) - return ret; - - reg = PHYUTMI_OTGDISABLE | - PHYUTMI_FORCESUSPEND | - PHYUTMI_FORCESLEEP; - writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYUTMI); - - /* Resetting the PHYCLKRST enable bits to reduce leakage current */ - reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); - reg &= ~(PHYCLKRST_REF_SSP_EN | - PHYCLKRST_SSC_EN | - PHYCLKRST_COMMONONN); - writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); - - /* Control PHYTEST to remove leakage current */ - reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); - reg |= PHYTEST_POWERDOWN_SSP | - PHYTEST_POWERDOWN_HSP; - writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); - - clk_disable_unprepare(phy_drd->clk); - - return 0; -} - -static int exynos5_usbdrd_phy_power_on(struct phy *phy) -{ - int ret; - struct phy_usb_instance *inst = phy_get_drvdata(phy); - struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); - - dev_dbg(phy_drd->dev, "Request to power_on usbdrd_phy phy\n"); - - clk_prepare_enable(phy_drd->ref_clk); - - /* Enable VBUS supply */ - if (phy_drd->vbus) { - ret = regulator_enable(phy_drd->vbus); - if (ret) { - dev_err(phy_drd->dev, "Failed to enable VBUS supply\n"); - goto fail_vbus; - } - } - - /* Power-on PHY*/ - inst->phy_cfg->phy_isol(inst, 0); - - return 0; - -fail_vbus: - clk_disable_unprepare(phy_drd->ref_clk); - - return ret; -} - -static int exynos5_usbdrd_phy_power_off(struct phy *phy) -{ - struct phy_usb_instance *inst = phy_get_drvdata(phy); - struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); - - dev_dbg(phy_drd->dev, "Request to power_off usbdrd_phy phy\n"); - - /* Power-off the PHY */ - inst->phy_cfg->phy_isol(inst, 1); - - /* Disable VBUS supply */ - if (phy_drd->vbus) - regulator_disable(phy_drd->vbus); - - clk_disable_unprepare(phy_drd->ref_clk); - - return 0; -} - -static struct phy *exynos5_usbdrd_phy_xlate(struct device *dev, - struct of_phandle_args *args) -{ - struct exynos5_usbdrd_phy *phy_drd = dev_get_drvdata(dev); - - if (WARN_ON(args->args[0] > EXYNOS5_DRDPHYS_NUM)) - return ERR_PTR(-ENODEV); - - return phy_drd->phys[args->args[0]].phy; -} - -static struct phy_ops exynos5_usbdrd_phy_ops = { - .init = exynos5_usbdrd_phy_init, - .exit = exynos5_usbdrd_phy_exit, - .power_on = exynos5_usbdrd_phy_power_on, - .power_off = exynos5_usbdrd_phy_power_off, - .owner = THIS_MODULE, -}; - -static const struct exynos5_usbdrd_phy_config phy_cfg_exynos5[] = { - { - .id = EXYNOS5_DRDPHY_UTMI, - .phy_isol = exynos5_usbdrd_phy_isol, - .phy_init = exynos5_usbdrd_utmi_init, - .set_refclk = exynos5_usbdrd_utmi_set_refclk, - }, - { - .id = EXYNOS5_DRDPHY_PIPE3, - .phy_isol = exynos5_usbdrd_phy_isol, - .phy_init = exynos5_usbdrd_pipe3_init, - .set_refclk = exynos5_usbdrd_pipe3_set_refclk, - }, -}; - -static const struct exynos5_usbdrd_phy_drvdata exynos5420_usbdrd_phy = { - .phy_cfg = phy_cfg_exynos5, - .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, - .pmu_offset_usbdrd1_phy = EXYNOS5420_USBDRD1_PHY_CONTROL, -}; - -static const struct exynos5_usbdrd_phy_drvdata exynos5250_usbdrd_phy = { - .phy_cfg = phy_cfg_exynos5, - .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, -}; - -static const struct of_device_id exynos5_usbdrd_phy_of_match[] = { - { - .compatible = "samsung,exynos5250-usbdrd-phy", - .data = &exynos5250_usbdrd_phy - }, { - .compatible = "samsung,exynos5420-usbdrd-phy", - .data = &exynos5420_usbdrd_phy - }, - { }, -}; -MODULE_DEVICE_TABLE(of, exynos5_usbdrd_phy_of_match); - -static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct device_node *node = dev->of_node; - struct exynos5_usbdrd_phy *phy_drd; - struct phy_provider *phy_provider; - struct resource *res; - const struct of_device_id *match; - const struct exynos5_usbdrd_phy_drvdata *drv_data; - struct regmap *reg_pmu; - u32 pmu_offset; - unsigned long ref_rate; - int i, ret; - int channel; - - phy_drd = devm_kzalloc(dev, sizeof(*phy_drd), GFP_KERNEL); - if (!phy_drd) - return -ENOMEM; - - dev_set_drvdata(dev, phy_drd); - phy_drd->dev = dev; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - phy_drd->reg_phy = devm_ioremap_resource(dev, res); - if (IS_ERR(phy_drd->reg_phy)) - return PTR_ERR(phy_drd->reg_phy); - - match = of_match_node(exynos5_usbdrd_phy_of_match, pdev->dev.of_node); - - drv_data = match->data; - phy_drd->drv_data = drv_data; - - phy_drd->clk = devm_clk_get(dev, "phy"); - if (IS_ERR(phy_drd->clk)) { - dev_err(dev, "Failed to get clock of phy controller\n"); - return PTR_ERR(phy_drd->clk); - } - - phy_drd->ref_clk = devm_clk_get(dev, "ref"); - if (IS_ERR(phy_drd->ref_clk)) { - dev_err(dev, "Failed to get reference clock of usbdrd phy\n"); - return PTR_ERR(phy_drd->ref_clk); - } - ref_rate = clk_get_rate(phy_drd->ref_clk); - - ret = exynos5_rate_to_clk(ref_rate, &phy_drd->extrefclk); - if (ret) { - dev_err(phy_drd->dev, "Clock rate (%ld) not supported\n", - ref_rate); - return ret; - } - - reg_pmu = syscon_regmap_lookup_by_phandle(dev->of_node, - "samsung,pmu-syscon"); - if (IS_ERR(reg_pmu)) { - dev_err(dev, "Failed to lookup PMU regmap\n"); - return PTR_ERR(reg_pmu); - } - - /* - * Exynos5420 SoC has multiple channels for USB 3.0 PHY, with - * each having separate power control registers. - * 'channel' facilitates to set such registers. - */ - channel = of_alias_get_id(node, "usbdrdphy"); - if (channel < 0) - dev_dbg(dev, "Not a multi-controller usbdrd phy\n"); - - switch (channel) { - case 1: - pmu_offset = phy_drd->drv_data->pmu_offset_usbdrd1_phy; - break; - case 0: - default: - pmu_offset = phy_drd->drv_data->pmu_offset_usbdrd0_phy; - break; - } - - /* Get Vbus regulator */ - phy_drd->vbus = devm_regulator_get(dev, "vbus"); - if (IS_ERR(phy_drd->vbus)) { - ret = PTR_ERR(phy_drd->vbus); - if (ret == -EPROBE_DEFER) - return ret; - - dev_warn(dev, "Failed to get VBUS supply regulator\n"); - phy_drd->vbus = NULL; - } - - dev_vdbg(dev, "Creating usbdrd_phy phy\n"); - - for (i = 0; i < EXYNOS5_DRDPHYS_NUM; i++) { - struct phy *phy = devm_phy_create(dev, NULL, - &exynos5_usbdrd_phy_ops, - NULL); - if (IS_ERR(phy)) { - dev_err(dev, "Failed to create usbdrd_phy phy\n"); - return PTR_ERR(phy); - } - - phy_drd->phys[i].phy = phy; - phy_drd->phys[i].index = i; - phy_drd->phys[i].reg_pmu = reg_pmu; - phy_drd->phys[i].pmu_offset = pmu_offset; - phy_drd->phys[i].phy_cfg = &drv_data->phy_cfg[i]; - phy_set_drvdata(phy, &phy_drd->phys[i]); - } - - phy_provider = devm_of_phy_provider_register(dev, - exynos5_usbdrd_phy_xlate); - if (IS_ERR(phy_provider)) { - dev_err(phy_drd->dev, "Failed to register phy provider\n"); - return PTR_ERR(phy_provider); - } - - return 0; -} - -static struct platform_driver exynos5_usb3drd_phy = { - .probe = exynos5_usbdrd_phy_probe, - .driver = { - .of_match_table = exynos5_usbdrd_phy_of_match, - .name = "exynos5_usb3drd_phy", - } -}; - -module_platform_driver(exynos5_usb3drd_phy); -MODULE_DESCRIPTION("Samsung EXYNOS5 SoCs USB 3.0 DRD controller PHY driver"); -MODULE_AUTHOR("Vivek Gautam "); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:exynos5_usb3drd_phy"); diff --git a/drivers/phy/phy-exynos5250-sata.c b/drivers/phy/phy-exynos5250-sata.c deleted file mode 100644 index 54cf4ae60d29..000000000000 --- a/drivers/phy/phy-exynos5250-sata.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Samsung SATA SerDes(PHY) driver - * - * Copyright (C) 2013 Samsung Electronics Co., Ltd. - * Authors: Girish K S - * Yuvaraj Kumar C D - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SATAPHY_CONTROL_OFFSET 0x0724 -#define EXYNOS5_SATAPHY_PMU_ENABLE BIT(0) -#define EXYNOS5_SATA_RESET 0x4 -#define RESET_GLOBAL_RST_N BIT(0) -#define RESET_CMN_RST_N BIT(1) -#define RESET_CMN_BLOCK_RST_N BIT(2) -#define RESET_CMN_I2C_RST_N BIT(3) -#define RESET_TX_RX_PIPE_RST_N BIT(4) -#define RESET_TX_RX_BLOCK_RST_N BIT(5) -#define RESET_TX_RX_I2C_RST_N (BIT(6) | BIT(7)) -#define LINK_RESET 0xf0000 -#define EXYNOS5_SATA_MODE0 0x10 -#define SATA_SPD_GEN3 BIT(1) -#define EXYNOS5_SATA_CTRL0 0x14 -#define CTRL0_P0_PHY_CALIBRATED_SEL BIT(9) -#define CTRL0_P0_PHY_CALIBRATED BIT(8) -#define EXYNOS5_SATA_PHSATA_CTRLM 0xe0 -#define PHCTRLM_REF_RATE BIT(1) -#define PHCTRLM_HIGH_SPEED BIT(0) -#define EXYNOS5_SATA_PHSATA_STATM 0xf0 -#define PHSTATM_PLL_LOCKED BIT(0) - -#define PHY_PLL_TIMEOUT (usecs_to_jiffies(1000)) - -struct exynos_sata_phy { - struct phy *phy; - struct clk *phyclk; - void __iomem *regs; - struct regmap *pmureg; - struct i2c_client *client; -}; - -static int wait_for_reg_status(void __iomem *base, u32 reg, u32 checkbit, - u32 status) -{ - unsigned long timeout = jiffies + PHY_PLL_TIMEOUT; - - while (time_before(jiffies, timeout)) { - if ((readl(base + reg) & checkbit) == status) - return 0; - } - - return -EFAULT; -} - -static int exynos_sata_phy_power_on(struct phy *phy) -{ - struct exynos_sata_phy *sata_phy = phy_get_drvdata(phy); - - return regmap_update_bits(sata_phy->pmureg, SATAPHY_CONTROL_OFFSET, - EXYNOS5_SATAPHY_PMU_ENABLE, true); - -} - -static int exynos_sata_phy_power_off(struct phy *phy) -{ - struct exynos_sata_phy *sata_phy = phy_get_drvdata(phy); - - return regmap_update_bits(sata_phy->pmureg, SATAPHY_CONTROL_OFFSET, - EXYNOS5_SATAPHY_PMU_ENABLE, false); - -} - -static int exynos_sata_phy_init(struct phy *phy) -{ - u32 val = 0; - int ret = 0; - u8 buf[] = { 0x3a, 0x0b }; - struct exynos_sata_phy *sata_phy = phy_get_drvdata(phy); - - ret = regmap_update_bits(sata_phy->pmureg, SATAPHY_CONTROL_OFFSET, - EXYNOS5_SATAPHY_PMU_ENABLE, true); - if (ret != 0) - dev_err(&sata_phy->phy->dev, "phy init failed\n"); - - writel(val, sata_phy->regs + EXYNOS5_SATA_RESET); - - val = readl(sata_phy->regs + EXYNOS5_SATA_RESET); - val |= RESET_GLOBAL_RST_N | RESET_CMN_RST_N | RESET_CMN_BLOCK_RST_N - | RESET_CMN_I2C_RST_N | RESET_TX_RX_PIPE_RST_N - | RESET_TX_RX_BLOCK_RST_N | RESET_TX_RX_I2C_RST_N; - writel(val, sata_phy->regs + EXYNOS5_SATA_RESET); - - val = readl(sata_phy->regs + EXYNOS5_SATA_RESET); - val |= LINK_RESET; - writel(val, sata_phy->regs + EXYNOS5_SATA_RESET); - - val = readl(sata_phy->regs + EXYNOS5_SATA_RESET); - val |= RESET_CMN_RST_N; - writel(val, sata_phy->regs + EXYNOS5_SATA_RESET); - - val = readl(sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM); - val &= ~PHCTRLM_REF_RATE; - writel(val, sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM); - - /* High speed enable for Gen3 */ - val = readl(sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM); - val |= PHCTRLM_HIGH_SPEED; - writel(val, sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM); - - val = readl(sata_phy->regs + EXYNOS5_SATA_CTRL0); - val |= CTRL0_P0_PHY_CALIBRATED_SEL | CTRL0_P0_PHY_CALIBRATED; - writel(val, sata_phy->regs + EXYNOS5_SATA_CTRL0); - - val = readl(sata_phy->regs + EXYNOS5_SATA_MODE0); - val |= SATA_SPD_GEN3; - writel(val, sata_phy->regs + EXYNOS5_SATA_MODE0); - - ret = i2c_master_send(sata_phy->client, buf, sizeof(buf)); - if (ret < 0) - return ret; - - /* release cmu reset */ - val = readl(sata_phy->regs + EXYNOS5_SATA_RESET); - val &= ~RESET_CMN_RST_N; - writel(val, sata_phy->regs + EXYNOS5_SATA_RESET); - - val = readl(sata_phy->regs + EXYNOS5_SATA_RESET); - val |= RESET_CMN_RST_N; - writel(val, sata_phy->regs + EXYNOS5_SATA_RESET); - - ret = wait_for_reg_status(sata_phy->regs, - EXYNOS5_SATA_PHSATA_STATM, - PHSTATM_PLL_LOCKED, 1); - if (ret < 0) - dev_err(&sata_phy->phy->dev, - "PHY PLL locking failed\n"); - return ret; -} - -static struct phy_ops exynos_sata_phy_ops = { - .init = exynos_sata_phy_init, - .power_on = exynos_sata_phy_power_on, - .power_off = exynos_sata_phy_power_off, - .owner = THIS_MODULE, -}; - -static int exynos_sata_phy_probe(struct platform_device *pdev) -{ - struct exynos_sata_phy *sata_phy; - struct device *dev = &pdev->dev; - struct resource *res; - struct phy_provider *phy_provider; - struct device_node *node; - int ret = 0; - - sata_phy = devm_kzalloc(dev, sizeof(*sata_phy), GFP_KERNEL); - if (!sata_phy) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - sata_phy->regs = devm_ioremap_resource(dev, res); - if (IS_ERR(sata_phy->regs)) - return PTR_ERR(sata_phy->regs); - - sata_phy->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node, - "samsung,syscon-phandle"); - if (IS_ERR(sata_phy->pmureg)) { - dev_err(dev, "syscon regmap lookup failed.\n"); - return PTR_ERR(sata_phy->pmureg); - } - - node = of_parse_phandle(dev->of_node, - "samsung,exynos-sataphy-i2c-phandle", 0); - if (!node) - return -EINVAL; - - sata_phy->client = of_find_i2c_device_by_node(node); - if (!sata_phy->client) - return -EPROBE_DEFER; - - dev_set_drvdata(dev, sata_phy); - - sata_phy->phyclk = devm_clk_get(dev, "sata_phyctrl"); - if (IS_ERR(sata_phy->phyclk)) { - dev_err(dev, "failed to get clk for PHY\n"); - return PTR_ERR(sata_phy->phyclk); - } - - ret = clk_prepare_enable(sata_phy->phyclk); - if (ret < 0) { - dev_err(dev, "failed to enable source clk\n"); - return ret; - } - - sata_phy->phy = devm_phy_create(dev, NULL, &exynos_sata_phy_ops, NULL); - if (IS_ERR(sata_phy->phy)) { - clk_disable_unprepare(sata_phy->phyclk); - dev_err(dev, "failed to create PHY\n"); - return PTR_ERR(sata_phy->phy); - } - - phy_set_drvdata(sata_phy->phy, sata_phy); - - phy_provider = devm_of_phy_provider_register(dev, - of_phy_simple_xlate); - if (IS_ERR(phy_provider)) { - clk_disable_unprepare(sata_phy->phyclk); - return PTR_ERR(phy_provider); - } - - return 0; -} - -static const struct of_device_id exynos_sata_phy_of_match[] = { - { .compatible = "samsung,exynos5250-sata-phy" }, - { }, -}; -MODULE_DEVICE_TABLE(of, exynos_sata_phy_of_match); - -static struct platform_driver exynos_sata_phy_driver = { - .probe = exynos_sata_phy_probe, - .driver = { - .of_match_table = exynos_sata_phy_of_match, - .name = "samsung,sata-phy", - } -}; -module_platform_driver(exynos_sata_phy_driver); - -MODULE_DESCRIPTION("Samsung SerDes PHY driver"); -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Girish K S "); -MODULE_AUTHOR("Yuvaraj C D "); diff --git a/drivers/phy/phy-exynos5250-usb2.c b/drivers/phy/phy-exynos5250-usb2.c deleted file mode 100644 index 1c139aa0d074..000000000000 --- a/drivers/phy/phy-exynos5250-usb2.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Samsung SoC USB 1.1/2.0 PHY driver - Exynos 5250 support - * - * Copyright (C) 2013 Samsung Electronics Co., Ltd. - * Author: Kamil Debski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include "phy-samsung-usb2.h" - -/* Exynos USB PHY registers */ -#define EXYNOS_5250_REFCLKSEL_CRYSTAL 0x0 -#define EXYNOS_5250_REFCLKSEL_XO 0x1 -#define EXYNOS_5250_REFCLKSEL_CLKCORE 0x2 - -#define EXYNOS_5250_FSEL_9MHZ6 0x0 -#define EXYNOS_5250_FSEL_10MHZ 0x1 -#define EXYNOS_5250_FSEL_12MHZ 0x2 -#define EXYNOS_5250_FSEL_19MHZ2 0x3 -#define EXYNOS_5250_FSEL_20MHZ 0x4 -#define EXYNOS_5250_FSEL_24MHZ 0x5 -#define EXYNOS_5250_FSEL_50MHZ 0x7 - -/* Normal host */ -#define EXYNOS_5250_HOSTPHYCTRL0 0x0 - -#define EXYNOS_5250_HOSTPHYCTRL0_PHYSWRSTALL BIT(31) -#define EXYNOS_5250_HOSTPHYCTRL0_REFCLKSEL_SHIFT 19 -#define EXYNOS_5250_HOSTPHYCTRL0_REFCLKSEL_MASK \ - (0x3 << EXYNOS_5250_HOSTPHYCTRL0_REFCLKSEL_SHIFT) -#define EXYNOS_5250_HOSTPHYCTRL0_FSEL_SHIFT 16 -#define EXYNOS_5250_HOSTPHYCTRL0_FSEL_MASK \ - (0x7 << EXYNOS_5250_HOSTPHYCTRL0_FSEL_SHIFT) -#define EXYNOS_5250_HOSTPHYCTRL0_TESTBURNIN BIT(11) -#define EXYNOS_5250_HOSTPHYCTRL0_RETENABLE BIT(10) -#define EXYNOS_5250_HOSTPHYCTRL0_COMMON_ON_N BIT(9) -#define EXYNOS_5250_HOSTPHYCTRL0_VATESTENB_MASK (0x3 << 7) -#define EXYNOS_5250_HOSTPHYCTRL0_VATESTENB_DUAL (0x0 << 7) -#define EXYNOS_5250_HOSTPHYCTRL0_VATESTENB_ID0 (0x1 << 7) -#define EXYNOS_5250_HOSTPHYCTRL0_VATESTENB_ANALOGTEST (0x2 << 7) -#define EXYNOS_5250_HOSTPHYCTRL0_SIDDQ BIT(6) -#define EXYNOS_5250_HOSTPHYCTRL0_FORCESLEEP BIT(5) -#define EXYNOS_5250_HOSTPHYCTRL0_FORCESUSPEND BIT(4) -#define EXYNOS_5250_HOSTPHYCTRL0_WORDINTERFACE BIT(3) -#define EXYNOS_5250_HOSTPHYCTRL0_UTMISWRST BIT(2) -#define EXYNOS_5250_HOSTPHYCTRL0_LINKSWRST BIT(1) -#define EXYNOS_5250_HOSTPHYCTRL0_PHYSWRST BIT(0) - -/* HSIC0 & HSIC1 */ -#define EXYNOS_5250_HSICPHYCTRL1 0x10 -#define EXYNOS_5250_HSICPHYCTRL2 0x20 - -#define EXYNOS_5250_HSICPHYCTRLX_REFCLKSEL_MASK (0x3 << 23) -#define EXYNOS_5250_HSICPHYCTRLX_REFCLKSEL_DEFAULT (0x2 << 23) -#define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_MASK (0x7f << 16) -#define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_12 (0x24 << 16) -#define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_15 (0x1c << 16) -#define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_16 (0x1a << 16) -#define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_19_2 (0x15 << 16) -#define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_20 (0x14 << 16) -#define EXYNOS_5250_HSICPHYCTRLX_SIDDQ BIT(6) -#define EXYNOS_5250_HSICPHYCTRLX_FORCESLEEP BIT(5) -#define EXYNOS_5250_HSICPHYCTRLX_FORCESUSPEND BIT(4) -#define EXYNOS_5250_HSICPHYCTRLX_WORDINTERFACE BIT(3) -#define EXYNOS_5250_HSICPHYCTRLX_UTMISWRST BIT(2) -#define EXYNOS_5250_HSICPHYCTRLX_PHYSWRST BIT(0) - -/* EHCI control */ -#define EXYNOS_5250_HOSTEHCICTRL 0x30 -#define EXYNOS_5250_HOSTEHCICTRL_ENAINCRXALIGN BIT(29) -#define EXYNOS_5250_HOSTEHCICTRL_ENAINCR4 BIT(28) -#define EXYNOS_5250_HOSTEHCICTRL_ENAINCR8 BIT(27) -#define EXYNOS_5250_HOSTEHCICTRL_ENAINCR16 BIT(26) -#define EXYNOS_5250_HOSTEHCICTRL_AUTOPPDONOVRCUREN BIT(25) -#define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL0_SHIFT 19 -#define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL0_MASK \ - (0x3f << EXYNOS_5250_HOSTEHCICTRL_FLADJVAL0_SHIFT) -#define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL1_SHIFT 13 -#define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL1_MASK \ - (0x3f << EXYNOS_5250_HOSTEHCICTRL_FLADJVAL1_SHIFT) -#define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL2_SHIFT 7 -#define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL0_MASK \ - (0x3f << EXYNOS_5250_HOSTEHCICTRL_FLADJVAL0_SHIFT) -#define EXYNOS_5250_HOSTEHCICTRL_FLADJVALHOST_SHIFT 1 -#define EXYNOS_5250_HOSTEHCICTRL_FLADJVALHOST_MASK \ - (0x1 << EXYNOS_5250_HOSTEHCICTRL_FLADJVALHOST_SHIFT) -#define EXYNOS_5250_HOSTEHCICTRL_SIMULATIONMODE BIT(0) - -/* OHCI control */ -#define EXYNOS_5250_HOSTOHCICTRL 0x34 -#define EXYNOS_5250_HOSTOHCICTRL_FRAMELENVAL_SHIFT 1 -#define EXYNOS_5250_HOSTOHCICTRL_FRAMELENVAL_MASK \ - (0x3ff << EXYNOS_5250_HOSTOHCICTRL_FRAMELENVAL_SHIFT) -#define EXYNOS_5250_HOSTOHCICTRL_FRAMELENVALEN BIT(0) - -/* USBOTG */ -#define EXYNOS_5250_USBOTGSYS 0x38 -#define EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET BIT(14) -#define EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG BIT(13) -#define EXYNOS_5250_USBOTGSYS_PHY_SW_RST BIT(12) -#define EXYNOS_5250_USBOTGSYS_REFCLKSEL_SHIFT 9 -#define EXYNOS_5250_USBOTGSYS_REFCLKSEL_MASK \ - (0x3 << EXYNOS_5250_USBOTGSYS_REFCLKSEL_SHIFT) -#define EXYNOS_5250_USBOTGSYS_ID_PULLUP BIT(8) -#define EXYNOS_5250_USBOTGSYS_COMMON_ON BIT(7) -#define EXYNOS_5250_USBOTGSYS_FSEL_SHIFT 4 -#define EXYNOS_5250_USBOTGSYS_FSEL_MASK \ - (0x3 << EXYNOS_5250_USBOTGSYS_FSEL_SHIFT) -#define EXYNOS_5250_USBOTGSYS_FORCE_SLEEP BIT(3) -#define EXYNOS_5250_USBOTGSYS_OTGDISABLE BIT(2) -#define EXYNOS_5250_USBOTGSYS_SIDDQ_UOTG BIT(1) -#define EXYNOS_5250_USBOTGSYS_FORCE_SUSPEND BIT(0) - -/* Isolation, configured in the power management unit */ -#define EXYNOS_5250_USB_ISOL_OTG_OFFSET 0x704 -#define EXYNOS_5250_USB_ISOL_OTG BIT(0) -#define EXYNOS_5250_USB_ISOL_HOST_OFFSET 0x708 -#define EXYNOS_5250_USB_ISOL_HOST BIT(0) - -/* Mode swtich register */ -#define EXYNOS_5250_MODE_SWITCH_OFFSET 0x230 -#define EXYNOS_5250_MODE_SWITCH_MASK 1 -#define EXYNOS_5250_MODE_SWITCH_DEVICE 0 -#define EXYNOS_5250_MODE_SWITCH_HOST 1 - -enum exynos4x12_phy_id { - EXYNOS5250_DEVICE, - EXYNOS5250_HOST, - EXYNOS5250_HSIC0, - EXYNOS5250_HSIC1, - EXYNOS5250_NUM_PHYS, -}; - -/* - * exynos5250_rate_to_clk() converts the supplied clock rate to the value that - * can be written to the phy register. - */ -static int exynos5250_rate_to_clk(unsigned long rate, u32 *reg) -{ - /* EXYNOS_5250_FSEL_MASK */ - - switch (rate) { - case 9600 * KHZ: - *reg = EXYNOS_5250_FSEL_9MHZ6; - break; - case 10 * MHZ: - *reg = EXYNOS_5250_FSEL_10MHZ; - break; - case 12 * MHZ: - *reg = EXYNOS_5250_FSEL_12MHZ; - break; - case 19200 * KHZ: - *reg = EXYNOS_5250_FSEL_19MHZ2; - break; - case 20 * MHZ: - *reg = EXYNOS_5250_FSEL_20MHZ; - break; - case 24 * MHZ: - *reg = EXYNOS_5250_FSEL_24MHZ; - break; - case 50 * MHZ: - *reg = EXYNOS_5250_FSEL_50MHZ; - break; - default: - return -EINVAL; - } - - return 0; -} - -static void exynos5250_isol(struct samsung_usb2_phy_instance *inst, bool on) -{ - struct samsung_usb2_phy_driver *drv = inst->drv; - u32 offset; - u32 mask; - - switch (inst->cfg->id) { - case EXYNOS5250_DEVICE: - offset = EXYNOS_5250_USB_ISOL_OTG_OFFSET; - mask = EXYNOS_5250_USB_ISOL_OTG; - break; - case EXYNOS5250_HOST: - offset = EXYNOS_5250_USB_ISOL_HOST_OFFSET; - mask = EXYNOS_5250_USB_ISOL_HOST; - break; - default: - return; - }; - - regmap_update_bits(drv->reg_pmu, offset, mask, on ? 0 : mask); -} - -static int exynos5250_power_on(struct samsung_usb2_phy_instance *inst) -{ - struct samsung_usb2_phy_driver *drv = inst->drv; - u32 ctrl0; - u32 otg; - u32 ehci; - u32 ohci; - u32 hsic; - - switch (inst->cfg->id) { - case EXYNOS5250_DEVICE: - regmap_update_bits(drv->reg_sys, - EXYNOS_5250_MODE_SWITCH_OFFSET, - EXYNOS_5250_MODE_SWITCH_MASK, - EXYNOS_5250_MODE_SWITCH_DEVICE); - - /* OTG configuration */ - otg = readl(drv->reg_phy + EXYNOS_5250_USBOTGSYS); - /* The clock */ - otg &= ~EXYNOS_5250_USBOTGSYS_FSEL_MASK; - otg |= drv->ref_reg_val << EXYNOS_5250_USBOTGSYS_FSEL_SHIFT; - /* Reset */ - otg &= ~(EXYNOS_5250_USBOTGSYS_FORCE_SUSPEND | - EXYNOS_5250_USBOTGSYS_FORCE_SLEEP | - EXYNOS_5250_USBOTGSYS_SIDDQ_UOTG); - otg |= EXYNOS_5250_USBOTGSYS_PHY_SW_RST | - EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET | - EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG | - EXYNOS_5250_USBOTGSYS_OTGDISABLE; - /* Ref clock */ - otg &= ~EXYNOS_5250_USBOTGSYS_REFCLKSEL_MASK; - otg |= EXYNOS_5250_REFCLKSEL_CLKCORE << - EXYNOS_5250_USBOTGSYS_REFCLKSEL_SHIFT; - writel(otg, drv->reg_phy + EXYNOS_5250_USBOTGSYS); - udelay(100); - otg &= ~(EXYNOS_5250_USBOTGSYS_PHY_SW_RST | - EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG | - EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET | - EXYNOS_5250_USBOTGSYS_OTGDISABLE); - writel(otg, drv->reg_phy + EXYNOS_5250_USBOTGSYS); - - - break; - case EXYNOS5250_HOST: - case EXYNOS5250_HSIC0: - case EXYNOS5250_HSIC1: - /* Host registers configuration */ - ctrl0 = readl(drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0); - /* The clock */ - ctrl0 &= ~EXYNOS_5250_HOSTPHYCTRL0_FSEL_MASK; - ctrl0 |= drv->ref_reg_val << - EXYNOS_5250_HOSTPHYCTRL0_FSEL_SHIFT; - - /* Reset */ - ctrl0 &= ~(EXYNOS_5250_HOSTPHYCTRL0_PHYSWRST | - EXYNOS_5250_HOSTPHYCTRL0_PHYSWRSTALL | - EXYNOS_5250_HOSTPHYCTRL0_SIDDQ | - EXYNOS_5250_HOSTPHYCTRL0_FORCESUSPEND | - EXYNOS_5250_HOSTPHYCTRL0_FORCESLEEP); - ctrl0 |= EXYNOS_5250_HOSTPHYCTRL0_LINKSWRST | - EXYNOS_5250_HOSTPHYCTRL0_UTMISWRST | - EXYNOS_5250_HOSTPHYCTRL0_COMMON_ON_N; - writel(ctrl0, drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0); - udelay(10); - ctrl0 &= ~(EXYNOS_5250_HOSTPHYCTRL0_LINKSWRST | - EXYNOS_5250_HOSTPHYCTRL0_UTMISWRST); - writel(ctrl0, drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0); - - /* OTG configuration */ - otg = readl(drv->reg_phy + EXYNOS_5250_USBOTGSYS); - /* The clock */ - otg &= ~EXYNOS_5250_USBOTGSYS_FSEL_MASK; - otg |= drv->ref_reg_val << EXYNOS_5250_USBOTGSYS_FSEL_SHIFT; - /* Reset */ - otg &= ~(EXYNOS_5250_USBOTGSYS_FORCE_SUSPEND | - EXYNOS_5250_USBOTGSYS_FORCE_SLEEP | - EXYNOS_5250_USBOTGSYS_SIDDQ_UOTG); - otg |= EXYNOS_5250_USBOTGSYS_PHY_SW_RST | - EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET | - EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG | - EXYNOS_5250_USBOTGSYS_OTGDISABLE; - /* Ref clock */ - otg &= ~EXYNOS_5250_USBOTGSYS_REFCLKSEL_MASK; - otg |= EXYNOS_5250_REFCLKSEL_CLKCORE << - EXYNOS_5250_USBOTGSYS_REFCLKSEL_SHIFT; - writel(otg, drv->reg_phy + EXYNOS_5250_USBOTGSYS); - udelay(10); - otg &= ~(EXYNOS_5250_USBOTGSYS_PHY_SW_RST | - EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG | - EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET); - - /* HSIC phy configuration */ - hsic = (EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_12 | - EXYNOS_5250_HSICPHYCTRLX_REFCLKSEL_DEFAULT | - EXYNOS_5250_HSICPHYCTRLX_PHYSWRST); - writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL1); - writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL2); - udelay(10); - hsic &= ~EXYNOS_5250_HSICPHYCTRLX_PHYSWRST; - writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL1); - writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL2); - /* The following delay is necessary for the reset sequence to be - * completed */ - udelay(80); - - /* Enable EHCI DMA burst */ - ehci = readl(drv->reg_phy + EXYNOS_5250_HOSTEHCICTRL); - ehci |= EXYNOS_5250_HOSTEHCICTRL_ENAINCRXALIGN | - EXYNOS_5250_HOSTEHCICTRL_ENAINCR4 | - EXYNOS_5250_HOSTEHCICTRL_ENAINCR8 | - EXYNOS_5250_HOSTEHCICTRL_ENAINCR16; - writel(ehci, drv->reg_phy + EXYNOS_5250_HOSTEHCICTRL); - - /* OHCI settings */ - ohci = readl(drv->reg_phy + EXYNOS_5250_HOSTOHCICTRL); - /* Following code is based on the old driver */ - ohci |= 0x1 << 3; - writel(ohci, drv->reg_phy + EXYNOS_5250_HOSTOHCICTRL); - - break; - } - exynos5250_isol(inst, 0); - - return 0; -} - -static int exynos5250_power_off(struct samsung_usb2_phy_instance *inst) -{ - struct samsung_usb2_phy_driver *drv = inst->drv; - u32 ctrl0; - u32 otg; - u32 hsic; - - exynos5250_isol(inst, 1); - - switch (inst->cfg->id) { - case EXYNOS5250_DEVICE: - otg = readl(drv->reg_phy + EXYNOS_5250_USBOTGSYS); - otg |= (EXYNOS_5250_USBOTGSYS_FORCE_SUSPEND | - EXYNOS_5250_USBOTGSYS_SIDDQ_UOTG | - EXYNOS_5250_USBOTGSYS_FORCE_SLEEP); - writel(otg, drv->reg_phy + EXYNOS_5250_USBOTGSYS); - break; - case EXYNOS5250_HOST: - ctrl0 = readl(drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0); - ctrl0 |= (EXYNOS_5250_HOSTPHYCTRL0_SIDDQ | - EXYNOS_5250_HOSTPHYCTRL0_FORCESUSPEND | - EXYNOS_5250_HOSTPHYCTRL0_FORCESLEEP | - EXYNOS_5250_HOSTPHYCTRL0_PHYSWRST | - EXYNOS_5250_HOSTPHYCTRL0_PHYSWRSTALL); - writel(ctrl0, drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0); - break; - case EXYNOS5250_HSIC0: - case EXYNOS5250_HSIC1: - hsic = (EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_12 | - EXYNOS_5250_HSICPHYCTRLX_REFCLKSEL_DEFAULT | - EXYNOS_5250_HSICPHYCTRLX_SIDDQ | - EXYNOS_5250_HSICPHYCTRLX_FORCESLEEP | - EXYNOS_5250_HSICPHYCTRLX_FORCESUSPEND - ); - writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL1); - writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL2); - break; - } - - return 0; -} - - -static const struct samsung_usb2_common_phy exynos5250_phys[] = { - { - .label = "device", - .id = EXYNOS5250_DEVICE, - .power_on = exynos5250_power_on, - .power_off = exynos5250_power_off, - }, - { - .label = "host", - .id = EXYNOS5250_HOST, - .power_on = exynos5250_power_on, - .power_off = exynos5250_power_off, - }, - { - .label = "hsic0", - .id = EXYNOS5250_HSIC0, - .power_on = exynos5250_power_on, - .power_off = exynos5250_power_off, - }, - { - .label = "hsic1", - .id = EXYNOS5250_HSIC1, - .power_on = exynos5250_power_on, - .power_off = exynos5250_power_off, - }, - {}, -}; - -const struct samsung_usb2_phy_config exynos5250_usb2_phy_config = { - .has_mode_switch = 1, - .num_phys = EXYNOS5250_NUM_PHYS, - .phys = exynos5250_phys, - .rate_to_clk = exynos5250_rate_to_clk, -}; diff --git a/drivers/phy/phy-hix5hd2-sata.c b/drivers/phy/phy-hix5hd2-sata.c deleted file mode 100644 index d5d978085c6d..000000000000 --- a/drivers/phy/phy-hix5hd2-sata.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2014 Linaro Ltd. - * Copyright (c) 2014 Hisilicon Limited. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include - -#define SATA_PHY0_CTLL 0xa0 -#define MPLL_MULTIPLIER_SHIFT 1 -#define MPLL_MULTIPLIER_MASK 0xfe -#define MPLL_MULTIPLIER_50M 0x3c -#define MPLL_MULTIPLIER_100M 0x1e -#define PHY_RESET BIT(0) -#define REF_SSP_EN BIT(9) -#define SSC_EN BIT(10) -#define REF_USE_PAD BIT(23) - -#define SATA_PORT_PHYCTL 0x174 -#define SPEED_MODE_MASK 0x6f0000 -#define HALF_RATE_SHIFT 16 -#define PHY_CONFIG_SHIFT 18 -#define GEN2_EN_SHIFT 21 -#define SPEED_CTRL BIT(20) - -#define SATA_PORT_PHYCTL1 0x148 -#define AMPLITUDE_MASK 0x3ffffe -#define AMPLITUDE_GEN3 0x68 -#define AMPLITUDE_GEN3_SHIFT 15 -#define AMPLITUDE_GEN2 0x56 -#define AMPLITUDE_GEN2_SHIFT 8 -#define AMPLITUDE_GEN1 0x56 -#define AMPLITUDE_GEN1_SHIFT 1 - -#define SATA_PORT_PHYCTL2 0x14c -#define PREEMPH_MASK 0x3ffff -#define PREEMPH_GEN3 0x20 -#define PREEMPH_GEN3_SHIFT 12 -#define PREEMPH_GEN2 0x15 -#define PREEMPH_GEN2_SHIFT 6 -#define PREEMPH_GEN1 0x5 -#define PREEMPH_GEN1_SHIFT 0 - -struct hix5hd2_priv { - void __iomem *base; - struct regmap *peri_ctrl; -}; - -enum phy_speed_mode { - SPEED_MODE_GEN1 = 0, - SPEED_MODE_GEN2 = 1, - SPEED_MODE_GEN3 = 2, -}; - -static int hix5hd2_sata_phy_init(struct phy *phy) -{ - struct hix5hd2_priv *priv = phy_get_drvdata(phy); - u32 val, data[2]; - int ret; - - if (priv->peri_ctrl) { - ret = of_property_read_u32_array(phy->dev.of_node, - "hisilicon,power-reg", - &data[0], 2); - if (ret) { - dev_err(&phy->dev, "Fail read hisilicon,power-reg\n"); - return ret; - } - - regmap_update_bits(priv->peri_ctrl, data[0], - BIT(data[1]), BIT(data[1])); - } - - /* reset phy */ - val = readl_relaxed(priv->base + SATA_PHY0_CTLL); - val &= ~(MPLL_MULTIPLIER_MASK | REF_USE_PAD); - val |= MPLL_MULTIPLIER_50M << MPLL_MULTIPLIER_SHIFT | - REF_SSP_EN | PHY_RESET; - writel_relaxed(val, priv->base + SATA_PHY0_CTLL); - msleep(20); - val &= ~PHY_RESET; - writel_relaxed(val, priv->base + SATA_PHY0_CTLL); - - val = readl_relaxed(priv->base + SATA_PORT_PHYCTL1); - val &= ~AMPLITUDE_MASK; - val |= AMPLITUDE_GEN3 << AMPLITUDE_GEN3_SHIFT | - AMPLITUDE_GEN2 << AMPLITUDE_GEN2_SHIFT | - AMPLITUDE_GEN1 << AMPLITUDE_GEN1_SHIFT; - writel_relaxed(val, priv->base + SATA_PORT_PHYCTL1); - - val = readl_relaxed(priv->base + SATA_PORT_PHYCTL2); - val &= ~PREEMPH_MASK; - val |= PREEMPH_GEN3 << PREEMPH_GEN3_SHIFT | - PREEMPH_GEN2 << PREEMPH_GEN2_SHIFT | - PREEMPH_GEN1 << PREEMPH_GEN1_SHIFT; - writel_relaxed(val, priv->base + SATA_PORT_PHYCTL2); - - /* ensure PHYCTRL setting takes effect */ - val = readl_relaxed(priv->base + SATA_PORT_PHYCTL); - val &= ~SPEED_MODE_MASK; - val |= SPEED_MODE_GEN1 << HALF_RATE_SHIFT | - SPEED_MODE_GEN1 << PHY_CONFIG_SHIFT | - SPEED_MODE_GEN1 << GEN2_EN_SHIFT | SPEED_CTRL; - writel_relaxed(val, priv->base + SATA_PORT_PHYCTL); - - msleep(20); - val &= ~SPEED_MODE_MASK; - val |= SPEED_MODE_GEN3 << HALF_RATE_SHIFT | - SPEED_MODE_GEN3 << PHY_CONFIG_SHIFT | - SPEED_MODE_GEN3 << GEN2_EN_SHIFT | SPEED_CTRL; - writel_relaxed(val, priv->base + SATA_PORT_PHYCTL); - - val &= ~(SPEED_MODE_MASK | SPEED_CTRL); - val |= SPEED_MODE_GEN2 << HALF_RATE_SHIFT | - SPEED_MODE_GEN2 << PHY_CONFIG_SHIFT | - SPEED_MODE_GEN2 << GEN2_EN_SHIFT; - writel_relaxed(val, priv->base + SATA_PORT_PHYCTL); - - return 0; -} - -static struct phy_ops hix5hd2_sata_phy_ops = { - .init = hix5hd2_sata_phy_init, - .owner = THIS_MODULE, -}; - -static int hix5hd2_sata_phy_probe(struct platform_device *pdev) -{ - struct phy_provider *phy_provider; - struct device *dev = &pdev->dev; - struct resource *res; - struct phy *phy; - struct hix5hd2_priv *priv; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - priv->base = devm_ioremap(dev, res->start, resource_size(res)); - if (!priv->base) - return -ENOMEM; - - priv->peri_ctrl = syscon_regmap_lookup_by_phandle(dev->of_node, - "hisilicon,peripheral-syscon"); - if (IS_ERR(priv->peri_ctrl)) - priv->peri_ctrl = NULL; - - phy = devm_phy_create(dev, NULL, &hix5hd2_sata_phy_ops, NULL); - if (IS_ERR(phy)) { - dev_err(dev, "failed to create PHY\n"); - return PTR_ERR(phy); - } - - phy_set_drvdata(phy, priv); - phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); - if (IS_ERR(phy_provider)) - return PTR_ERR(phy_provider); - - return 0; -} - -static const struct of_device_id hix5hd2_sata_phy_of_match[] = { - {.compatible = "hisilicon,hix5hd2-sata-phy",}, - { }, -}; -MODULE_DEVICE_TABLE(of, hix5hd2_sata_phy_of_match); - -static struct platform_driver hix5hd2_sata_phy_driver = { - .probe = hix5hd2_sata_phy_probe, - .driver = { - .name = "hix5hd2-sata-phy", - .of_match_table = hix5hd2_sata_phy_of_match, - } -}; -module_platform_driver(hix5hd2_sata_phy_driver); - -MODULE_AUTHOR("Jiancheng Xue "); -MODULE_DESCRIPTION("HISILICON HIX5HD2 SATA PHY driver"); -MODULE_ALIAS("platform:hix5hd2-sata-phy"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/phy-miphy365x.c b/drivers/phy/phy-miphy365x.c deleted file mode 100644 index 801afaf2d449..000000000000 --- a/drivers/phy/phy-miphy365x.c +++ /dev/null @@ -1,636 +0,0 @@ -/* - * Copyright (C) 2014 STMicroelectronics – All Rights Reserved - * - * STMicroelectronics PHY driver MiPHY365 (for SoC STiH416). - * - * Authors: Alexandre Torgue - * Lee Jones - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define HFC_TIMEOUT 100 - -#define SYSCFG_SELECT_SATA_MASK BIT(1) -#define SYSCFG_SELECT_SATA_POS 1 - -/* MiPHY365x register definitions */ -#define RESET_REG 0x00 -#define RST_PLL BIT(1) -#define RST_PLL_CAL BIT(2) -#define RST_RX BIT(4) -#define RST_MACRO BIT(7) - -#define STATUS_REG 0x01 -#define IDLL_RDY BIT(0) -#define PLL_RDY BIT(1) -#define DES_BIT_LOCK BIT(2) -#define DES_SYMBOL_LOCK BIT(3) - -#define CTRL_REG 0x02 -#define TERM_EN BIT(0) -#define PCI_EN BIT(2) -#define DES_BIT_LOCK_EN BIT(3) -#define TX_POL BIT(5) - -#define INT_CTRL_REG 0x03 - -#define BOUNDARY1_REG 0x10 -#define SPDSEL_SEL BIT(0) - -#define BOUNDARY3_REG 0x12 -#define TX_SPDSEL_GEN1_VAL 0 -#define TX_SPDSEL_GEN2_VAL 0x01 -#define TX_SPDSEL_GEN3_VAL 0x02 -#define RX_SPDSEL_GEN1_VAL 0 -#define RX_SPDSEL_GEN2_VAL (0x01 << 3) -#define RX_SPDSEL_GEN3_VAL (0x02 << 3) - -#define PCIE_REG 0x16 - -#define BUF_SEL_REG 0x20 -#define CONF_GEN_SEL_GEN3 0x02 -#define CONF_GEN_SEL_GEN2 0x01 -#define PD_VDDTFILTER BIT(4) - -#define TXBUF1_REG 0x21 -#define SWING_VAL 0x04 -#define SWING_VAL_GEN1 0x03 -#define PREEMPH_VAL (0x3 << 5) - -#define TXBUF2_REG 0x22 -#define TXSLEW_VAL 0x2 -#define TXSLEW_VAL_GEN1 0x4 - -#define RXBUF_OFFSET_CTRL_REG 0x23 - -#define RXBUF_REG 0x25 -#define SDTHRES_VAL 0x01 -#define EQ_ON3 (0x03 << 4) -#define EQ_ON1 (0x01 << 4) - -#define COMP_CTRL1_REG 0x40 -#define START_COMSR BIT(0) -#define START_COMZC BIT(1) -#define COMSR_DONE BIT(2) -#define COMZC_DONE BIT(3) -#define COMP_AUTO_LOAD BIT(4) - -#define COMP_CTRL2_REG 0x41 -#define COMP_2MHZ_RAT_GEN1 0x1e -#define COMP_2MHZ_RAT 0xf - -#define COMP_CTRL3_REG 0x42 -#define COMSR_COMP_REF 0x33 - -#define COMP_IDLL_REG 0x47 -#define COMZC_IDLL 0x2a - -#define PLL_CTRL1_REG 0x50 -#define PLL_START_CAL BIT(0) -#define BUF_EN BIT(2) -#define SYNCHRO_TX BIT(3) -#define SSC_EN BIT(6) -#define CONFIG_PLL BIT(7) - -#define PLL_CTRL2_REG 0x51 -#define BYPASS_PLL_CAL BIT(1) - -#define PLL_RAT_REG 0x52 - -#define PLL_SSC_STEP_MSB_REG 0x56 -#define PLL_SSC_STEP_MSB_VAL 0x03 - -#define PLL_SSC_STEP_LSB_REG 0x57 -#define PLL_SSC_STEP_LSB_VAL 0x63 - -#define PLL_SSC_PER_MSB_REG 0x58 -#define PLL_SSC_PER_MSB_VAL 0 - -#define PLL_SSC_PER_LSB_REG 0x59 -#define PLL_SSC_PER_LSB_VAL 0xf1 - -#define IDLL_TEST_REG 0x72 -#define START_CLK_HF BIT(6) - -#define DES_BITLOCK_REG 0x86 -#define BIT_LOCK_LEVEL 0x01 -#define BIT_LOCK_CNT_512 (0x03 << 5) - -struct miphy365x_phy { - struct phy *phy; - void __iomem *base; - bool pcie_tx_pol_inv; - bool sata_tx_pol_inv; - u32 sata_gen; - u64 ctrlreg; - u8 type; -}; - -struct miphy365x_dev { - struct device *dev; - struct regmap *regmap; - struct mutex miphy_mutex; - struct miphy365x_phy **phys; -}; - -/* - * These values are represented in Device tree. They are considered to be ABI - * and although they can be extended any existing values must not change. - */ -enum miphy_sata_gen { - SATA_GEN1 = 1, - SATA_GEN2, - SATA_GEN3 -}; - -static u8 rx_tx_spd[] = { - 0, /* GEN0 doesn't exist. */ - TX_SPDSEL_GEN1_VAL | RX_SPDSEL_GEN1_VAL, - TX_SPDSEL_GEN2_VAL | RX_SPDSEL_GEN2_VAL, - TX_SPDSEL_GEN3_VAL | RX_SPDSEL_GEN3_VAL -}; - -/* - * This function selects the system configuration, - * either two SATA, one SATA and one PCIe, or two PCIe lanes. - */ -static int miphy365x_set_path(struct miphy365x_phy *miphy_phy, - struct miphy365x_dev *miphy_dev) -{ - bool sata = (miphy_phy->type == MIPHY_TYPE_SATA); - - return regmap_update_bits(miphy_dev->regmap, - (unsigned int)miphy_phy->ctrlreg, - SYSCFG_SELECT_SATA_MASK, - sata << SYSCFG_SELECT_SATA_POS); -} - -static int miphy365x_init_pcie_port(struct miphy365x_phy *miphy_phy, - struct miphy365x_dev *miphy_dev) -{ - u8 val; - - if (miphy_phy->pcie_tx_pol_inv) { - /* Invert Tx polarity and clear pci_txdetect_pol bit */ - val = TERM_EN | PCI_EN | DES_BIT_LOCK_EN | TX_POL; - writeb_relaxed(val, miphy_phy->base + CTRL_REG); - writeb_relaxed(0x00, miphy_phy->base + PCIE_REG); - } - - return 0; -} - -static inline int miphy365x_hfc_not_rdy(struct miphy365x_phy *miphy_phy, - struct miphy365x_dev *miphy_dev) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(HFC_TIMEOUT); - u8 mask = IDLL_RDY | PLL_RDY; - u8 regval; - - do { - regval = readb_relaxed(miphy_phy->base + STATUS_REG); - if (!(regval & mask)) - return 0; - - usleep_range(2000, 2500); - } while (time_before(jiffies, timeout)); - - dev_err(miphy_dev->dev, "HFC ready timeout!\n"); - return -EBUSY; -} - -static inline int miphy365x_rdy(struct miphy365x_phy *miphy_phy, - struct miphy365x_dev *miphy_dev) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(HFC_TIMEOUT); - u8 mask = IDLL_RDY | PLL_RDY; - u8 regval; - - do { - regval = readb_relaxed(miphy_phy->base + STATUS_REG); - if ((regval & mask) == mask) - return 0; - - usleep_range(2000, 2500); - } while (time_before(jiffies, timeout)); - - dev_err(miphy_dev->dev, "PHY not ready timeout!\n"); - return -EBUSY; -} - -static inline void miphy365x_set_comp(struct miphy365x_phy *miphy_phy, - struct miphy365x_dev *miphy_dev) -{ - u8 val, mask; - - if (miphy_phy->sata_gen == SATA_GEN1) - writeb_relaxed(COMP_2MHZ_RAT_GEN1, - miphy_phy->base + COMP_CTRL2_REG); - else - writeb_relaxed(COMP_2MHZ_RAT, - miphy_phy->base + COMP_CTRL2_REG); - - if (miphy_phy->sata_gen != SATA_GEN3) { - writeb_relaxed(COMSR_COMP_REF, - miphy_phy->base + COMP_CTRL3_REG); - /* - * Force VCO current to value defined by address 0x5A - * and disable PCIe100Mref bit - * Enable auto load compensation for pll_i_bias - */ - writeb_relaxed(BYPASS_PLL_CAL, miphy_phy->base + PLL_CTRL2_REG); - writeb_relaxed(COMZC_IDLL, miphy_phy->base + COMP_IDLL_REG); - } - - /* - * Force restart compensation and enable auto load - * for Comzc_Tx, Comzc_Rx and Comsr on macro - */ - val = START_COMSR | START_COMZC | COMP_AUTO_LOAD; - writeb_relaxed(val, miphy_phy->base + COMP_CTRL1_REG); - - mask = COMSR_DONE | COMZC_DONE; - while ((readb_relaxed(miphy_phy->base + COMP_CTRL1_REG) & mask) != mask) - cpu_relax(); -} - -static inline void miphy365x_set_ssc(struct miphy365x_phy *miphy_phy, - struct miphy365x_dev *miphy_dev) -{ - u8 val; - - /* - * SSC Settings. SSC will be enabled through Link - * SSC Ampl. = 0.4% - * SSC Freq = 31KHz - */ - writeb_relaxed(PLL_SSC_STEP_MSB_VAL, - miphy_phy->base + PLL_SSC_STEP_MSB_REG); - writeb_relaxed(PLL_SSC_STEP_LSB_VAL, - miphy_phy->base + PLL_SSC_STEP_LSB_REG); - writeb_relaxed(PLL_SSC_PER_MSB_VAL, - miphy_phy->base + PLL_SSC_PER_MSB_REG); - writeb_relaxed(PLL_SSC_PER_LSB_VAL, - miphy_phy->base + PLL_SSC_PER_LSB_REG); - - /* SSC Settings complete */ - if (miphy_phy->sata_gen == SATA_GEN1) { - val = PLL_START_CAL | BUF_EN | SYNCHRO_TX | CONFIG_PLL; - writeb_relaxed(val, miphy_phy->base + PLL_CTRL1_REG); - } else { - val = SSC_EN | PLL_START_CAL | BUF_EN | SYNCHRO_TX | CONFIG_PLL; - writeb_relaxed(val, miphy_phy->base + PLL_CTRL1_REG); - } -} - -static int miphy365x_init_sata_port(struct miphy365x_phy *miphy_phy, - struct miphy365x_dev *miphy_dev) -{ - int ret; - u8 val; - - /* - * Force PHY macro reset, PLL calibration reset, PLL reset - * and assert Deserializer Reset - */ - val = RST_PLL | RST_PLL_CAL | RST_RX | RST_MACRO; - writeb_relaxed(val, miphy_phy->base + RESET_REG); - - if (miphy_phy->sata_tx_pol_inv) - writeb_relaxed(TX_POL, miphy_phy->base + CTRL_REG); - - /* - * Force macro1 to use rx_lspd, tx_lspd - * Force Rx_Clock on first I-DLL phase - * Force Des in HP mode on macro, rx_lspd, tx_lspd for Gen2/3 - */ - writeb_relaxed(SPDSEL_SEL, miphy_phy->base + BOUNDARY1_REG); - writeb_relaxed(START_CLK_HF, miphy_phy->base + IDLL_TEST_REG); - val = rx_tx_spd[miphy_phy->sata_gen]; - writeb_relaxed(val, miphy_phy->base + BOUNDARY3_REG); - - /* Wait for HFC_READY = 0 */ - ret = miphy365x_hfc_not_rdy(miphy_phy, miphy_dev); - if (ret) - return ret; - - /* Compensation Recalibration */ - miphy365x_set_comp(miphy_phy, miphy_dev); - - switch (miphy_phy->sata_gen) { - case SATA_GEN3: - /* - * TX Swing target 550-600mv peak to peak diff - * Tx Slew target 90-110ps rising/falling time - * Rx Eq ON3, Sigdet threshold SDTH1 - */ - val = PD_VDDTFILTER | CONF_GEN_SEL_GEN3; - writeb_relaxed(val, miphy_phy->base + BUF_SEL_REG); - val = SWING_VAL | PREEMPH_VAL; - writeb_relaxed(val, miphy_phy->base + TXBUF1_REG); - writeb_relaxed(TXSLEW_VAL, miphy_phy->base + TXBUF2_REG); - writeb_relaxed(0x00, miphy_phy->base + RXBUF_OFFSET_CTRL_REG); - val = SDTHRES_VAL | EQ_ON3; - writeb_relaxed(val, miphy_phy->base + RXBUF_REG); - break; - case SATA_GEN2: - /* - * conf gen sel=0x1 to program Gen2 banked registers - * VDDT filter ON - * Tx Swing target 550-600mV peak-to-peak diff - * Tx Slew target 90-110 ps rising/falling time - * RX Equalization ON1, Sigdet threshold SDTH1 - */ - writeb_relaxed(CONF_GEN_SEL_GEN2, - miphy_phy->base + BUF_SEL_REG); - writeb_relaxed(SWING_VAL, miphy_phy->base + TXBUF1_REG); - writeb_relaxed(TXSLEW_VAL, miphy_phy->base + TXBUF2_REG); - val = SDTHRES_VAL | EQ_ON1; - writeb_relaxed(val, miphy_phy->base + RXBUF_REG); - break; - case SATA_GEN1: - /* - * conf gen sel = 00b to program Gen1 banked registers - * VDDT filter ON - * Tx Swing target 500-550mV peak-to-peak diff - * Tx Slew target120-140 ps rising/falling time - */ - writeb_relaxed(PD_VDDTFILTER, miphy_phy->base + BUF_SEL_REG); - writeb_relaxed(SWING_VAL_GEN1, miphy_phy->base + TXBUF1_REG); - writeb_relaxed(TXSLEW_VAL_GEN1, miphy_phy->base + TXBUF2_REG); - break; - default: - break; - } - - /* Force Macro1 in partial mode & release pll cal reset */ - writeb_relaxed(RST_RX, miphy_phy->base + RESET_REG); - usleep_range(100, 150); - - miphy365x_set_ssc(miphy_phy, miphy_dev); - - /* Wait for phy_ready */ - ret = miphy365x_rdy(miphy_phy, miphy_dev); - if (ret) - return ret; - - /* - * Enable macro1 to use rx_lspd & tx_lspd - * Release Rx_Clock on first I-DLL phase on macro1 - * Assert deserializer reset - * des_bit_lock_en is set - * bit lock detection strength - * Deassert deserializer reset - */ - writeb_relaxed(0x00, miphy_phy->base + BOUNDARY1_REG); - writeb_relaxed(0x00, miphy_phy->base + IDLL_TEST_REG); - writeb_relaxed(RST_RX, miphy_phy->base + RESET_REG); - val = miphy_phy->sata_tx_pol_inv ? - (TX_POL | DES_BIT_LOCK_EN) : DES_BIT_LOCK_EN; - writeb_relaxed(val, miphy_phy->base + CTRL_REG); - - val = BIT_LOCK_CNT_512 | BIT_LOCK_LEVEL; - writeb_relaxed(val, miphy_phy->base + DES_BITLOCK_REG); - writeb_relaxed(0x00, miphy_phy->base + RESET_REG); - - return 0; -} - -static int miphy365x_init(struct phy *phy) -{ - struct miphy365x_phy *miphy_phy = phy_get_drvdata(phy); - struct miphy365x_dev *miphy_dev = dev_get_drvdata(phy->dev.parent); - int ret = 0; - - mutex_lock(&miphy_dev->miphy_mutex); - - ret = miphy365x_set_path(miphy_phy, miphy_dev); - if (ret) { - mutex_unlock(&miphy_dev->miphy_mutex); - return ret; - } - - /* Initialise Miphy for PCIe or SATA */ - if (miphy_phy->type == MIPHY_TYPE_PCIE) - ret = miphy365x_init_pcie_port(miphy_phy, miphy_dev); - else - ret = miphy365x_init_sata_port(miphy_phy, miphy_dev); - - mutex_unlock(&miphy_dev->miphy_mutex); - - return ret; -} - -int miphy365x_get_addr(struct device *dev, struct miphy365x_phy *miphy_phy, - int index) -{ - struct device_node *phynode = miphy_phy->phy->dev.of_node; - const char *name; - const __be32 *taddr; - int type = miphy_phy->type; - int ret; - - ret = of_property_read_string_index(phynode, "reg-names", index, &name); - if (ret) { - dev_err(dev, "no reg-names property not found\n"); - return ret; - } - - if (!strncmp(name, "syscfg", 6)) { - taddr = of_get_address(phynode, index, NULL, NULL); - if (!taddr) { - dev_err(dev, "failed to fetch syscfg address\n"); - return -EINVAL; - } - - miphy_phy->ctrlreg = of_translate_address(phynode, taddr); - if (miphy_phy->ctrlreg == OF_BAD_ADDR) { - dev_err(dev, "failed to translate syscfg address\n"); - return -EINVAL; - } - - return 0; - } - - if (!((!strncmp(name, "sata", 4) && type == MIPHY_TYPE_SATA) || - (!strncmp(name, "pcie", 4) && type == MIPHY_TYPE_PCIE))) - return 0; - - miphy_phy->base = of_iomap(phynode, index); - if (!miphy_phy->base) { - dev_err(dev, "Failed to map %s\n", phynode->full_name); - return -EINVAL; - } - - return 0; -} - -static struct phy *miphy365x_xlate(struct device *dev, - struct of_phandle_args *args) -{ - struct miphy365x_dev *miphy_dev = dev_get_drvdata(dev); - struct miphy365x_phy *miphy_phy = NULL; - struct device_node *phynode = args->np; - int ret, index; - - if (!of_device_is_available(phynode)) { - dev_warn(dev, "Requested PHY is disabled\n"); - return ERR_PTR(-ENODEV); - } - - if (args->args_count != 1) { - dev_err(dev, "Invalid number of cells in 'phy' property\n"); - return ERR_PTR(-EINVAL); - } - - for (index = 0; index < of_get_child_count(dev->of_node); index++) - if (phynode == miphy_dev->phys[index]->phy->dev.of_node) { - miphy_phy = miphy_dev->phys[index]; - break; - } - - if (!miphy_phy) { - dev_err(dev, "Failed to find appropriate phy\n"); - return ERR_PTR(-EINVAL); - } - - miphy_phy->type = args->args[0]; - - if (!(miphy_phy->type == MIPHY_TYPE_SATA || - miphy_phy->type == MIPHY_TYPE_PCIE)) { - dev_err(dev, "Unsupported device type: %d\n", miphy_phy->type); - return ERR_PTR(-EINVAL); - } - - /* Each port handles SATA and PCIE - third entry is always sysconf. */ - for (index = 0; index < 3; index++) { - ret = miphy365x_get_addr(dev, miphy_phy, index); - if (ret < 0) - return ERR_PTR(ret); - } - - return miphy_phy->phy; -} - -static struct phy_ops miphy365x_ops = { - .init = miphy365x_init, - .owner = THIS_MODULE, -}; - -static int miphy365x_of_probe(struct device_node *phynode, - struct miphy365x_phy *miphy_phy) -{ - of_property_read_u32(phynode, "st,sata-gen", &miphy_phy->sata_gen); - if (!miphy_phy->sata_gen) - miphy_phy->sata_gen = SATA_GEN1; - - miphy_phy->pcie_tx_pol_inv = - of_property_read_bool(phynode, "st,pcie-tx-pol-inv"); - - miphy_phy->sata_tx_pol_inv = - of_property_read_bool(phynode, "st,sata-tx-pol-inv"); - - return 0; -} - -static int miphy365x_probe(struct platform_device *pdev) -{ - struct device_node *child, *np = pdev->dev.of_node; - struct miphy365x_dev *miphy_dev; - struct phy_provider *provider; - struct phy *phy; - int chancount, port = 0; - int ret; - - miphy_dev = devm_kzalloc(&pdev->dev, sizeof(*miphy_dev), GFP_KERNEL); - if (!miphy_dev) - return -ENOMEM; - - chancount = of_get_child_count(np); - miphy_dev->phys = devm_kzalloc(&pdev->dev, sizeof(phy) * chancount, - GFP_KERNEL); - if (!miphy_dev->phys) - return -ENOMEM; - - miphy_dev->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg"); - if (IS_ERR(miphy_dev->regmap)) { - dev_err(miphy_dev->dev, "No syscfg phandle specified\n"); - return PTR_ERR(miphy_dev->regmap); - } - - miphy_dev->dev = &pdev->dev; - - dev_set_drvdata(&pdev->dev, miphy_dev); - - mutex_init(&miphy_dev->miphy_mutex); - - for_each_child_of_node(np, child) { - struct miphy365x_phy *miphy_phy; - - miphy_phy = devm_kzalloc(&pdev->dev, sizeof(*miphy_phy), - GFP_KERNEL); - if (!miphy_phy) - return -ENOMEM; - - miphy_dev->phys[port] = miphy_phy; - - phy = devm_phy_create(&pdev->dev, child, &miphy365x_ops, NULL); - if (IS_ERR(phy)) { - dev_err(&pdev->dev, "failed to create PHY\n"); - return PTR_ERR(phy); - } - - miphy_dev->phys[port]->phy = phy; - - ret = miphy365x_of_probe(child, miphy_phy); - if (ret) - return ret; - - phy_set_drvdata(phy, miphy_dev->phys[port]); - port++; - } - - provider = devm_of_phy_provider_register(&pdev->dev, miphy365x_xlate); - if (IS_ERR(provider)) - return PTR_ERR(provider); - - return 0; -} - -static const struct of_device_id miphy365x_of_match[] = { - { .compatible = "st,miphy365x-phy", }, - { }, -}; -MODULE_DEVICE_TABLE(of, miphy365x_of_match); - -static struct platform_driver miphy365x_driver = { - .probe = miphy365x_probe, - .driver = { - .name = "miphy365x-phy", - .of_match_table = miphy365x_of_match, - } -}; -module_platform_driver(miphy365x_driver); - -MODULE_AUTHOR("Alexandre Torgue "); -MODULE_DESCRIPTION("STMicroelectronics miphy365x driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/phy-mvebu-sata.c b/drivers/phy/phy-mvebu-sata.c deleted file mode 100644 index d395558cb12e..000000000000 --- a/drivers/phy/phy-mvebu-sata.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * phy-mvebu-sata.c: SATA Phy driver for the Marvell mvebu SoCs. - * - * Copyright (C) 2013 Andrew Lunn - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include - -struct priv { - struct clk *clk; - void __iomem *base; -}; - -#define SATA_PHY_MODE_2 0x0330 -#define MODE_2_FORCE_PU_TX BIT(0) -#define MODE_2_FORCE_PU_RX BIT(1) -#define MODE_2_PU_PLL BIT(2) -#define MODE_2_PU_IVREF BIT(3) -#define SATA_IF_CTRL 0x0050 -#define CTRL_PHY_SHUTDOWN BIT(9) - -static int phy_mvebu_sata_power_on(struct phy *phy) -{ - struct priv *priv = phy_get_drvdata(phy); - u32 reg; - - clk_prepare_enable(priv->clk); - - /* Enable PLL and IVREF */ - reg = readl(priv->base + SATA_PHY_MODE_2); - reg |= (MODE_2_FORCE_PU_TX | MODE_2_FORCE_PU_RX | - MODE_2_PU_PLL | MODE_2_PU_IVREF); - writel(reg , priv->base + SATA_PHY_MODE_2); - - /* Enable PHY */ - reg = readl(priv->base + SATA_IF_CTRL); - reg &= ~CTRL_PHY_SHUTDOWN; - writel(reg, priv->base + SATA_IF_CTRL); - - clk_disable_unprepare(priv->clk); - - return 0; -} - -static int phy_mvebu_sata_power_off(struct phy *phy) -{ - struct priv *priv = phy_get_drvdata(phy); - u32 reg; - - clk_prepare_enable(priv->clk); - - /* Disable PLL and IVREF */ - reg = readl(priv->base + SATA_PHY_MODE_2); - reg &= ~(MODE_2_FORCE_PU_TX | MODE_2_FORCE_PU_RX | - MODE_2_PU_PLL | MODE_2_PU_IVREF); - writel(reg, priv->base + SATA_PHY_MODE_2); - - /* Disable PHY */ - reg = readl(priv->base + SATA_IF_CTRL); - reg |= CTRL_PHY_SHUTDOWN; - writel(reg, priv->base + SATA_IF_CTRL); - - clk_disable_unprepare(priv->clk); - - return 0; -} - -static struct phy_ops phy_mvebu_sata_ops = { - .power_on = phy_mvebu_sata_power_on, - .power_off = phy_mvebu_sata_power_off, - .owner = THIS_MODULE, -}; - -static int phy_mvebu_sata_probe(struct platform_device *pdev) -{ - struct phy_provider *phy_provider; - struct resource *res; - struct priv *priv; - struct phy *phy; - - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - priv->base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); - - priv->clk = devm_clk_get(&pdev->dev, "sata"); - if (IS_ERR(priv->clk)) - return PTR_ERR(priv->clk); - - phy = devm_phy_create(&pdev->dev, NULL, &phy_mvebu_sata_ops, NULL); - if (IS_ERR(phy)) - return PTR_ERR(phy); - - phy_set_drvdata(phy, priv); - - phy_provider = devm_of_phy_provider_register(&pdev->dev, - of_phy_simple_xlate); - if (IS_ERR(phy_provider)) - return PTR_ERR(phy_provider); - - /* The boot loader may of left it on. Turn it off. */ - phy_mvebu_sata_power_off(phy); - - return 0; -} - -static const struct of_device_id phy_mvebu_sata_of_match[] = { - { .compatible = "marvell,mvebu-sata-phy" }, - { }, -}; -MODULE_DEVICE_TABLE(of, phy_mvebu_sata_of_match); - -static struct platform_driver phy_mvebu_sata_driver = { - .probe = phy_mvebu_sata_probe, - .driver = { - .name = "phy-mvebu-sata", - .of_match_table = phy_mvebu_sata_of_match, - } -}; -module_platform_driver(phy_mvebu_sata_driver); - -MODULE_AUTHOR("Andrew Lunn "); -MODULE_DESCRIPTION("Marvell MVEBU SATA PHY driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/phy-omap-control.c b/drivers/phy/phy-omap-control.c deleted file mode 100644 index c96e8183a8ff..000000000000 --- a/drivers/phy/phy-omap-control.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - * omap-control-phy.c - The PHY part of control module. - * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Author: Kishon Vijay Abraham I - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * omap_control_pcie_pcs - set the PCS delay count - * @dev: the control module device - * @id: index of the pcie PHY (should be 1 or 2) - * @delay: 8 bit delay value - */ -void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay) -{ - u32 val; - struct omap_control_phy *control_phy; - - if (IS_ERR(dev) || !dev) { - pr_err("%s: invalid device\n", __func__); - return; - } - - control_phy = dev_get_drvdata(dev); - if (!control_phy) { - dev_err(dev, "%s: invalid control phy device\n", __func__); - return; - } - - if (control_phy->type != OMAP_CTRL_TYPE_PCIE) { - dev_err(dev, "%s: unsupported operation\n", __func__); - return; - } - - val = readl(control_phy->pcie_pcs); - val &= ~(OMAP_CTRL_PCIE_PCS_MASK << - (id * OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT)); - val |= delay << (id * OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT); - writel(val, control_phy->pcie_pcs); -} -EXPORT_SYMBOL_GPL(omap_control_pcie_pcs); - -/** - * omap_control_phy_power - power on/off the phy using control module reg - * @dev: the control module device - * @on: 0 or 1, based on powering on or off the PHY - */ -void omap_control_phy_power(struct device *dev, int on) -{ - u32 val; - unsigned long rate; - struct omap_control_phy *control_phy; - - if (IS_ERR(dev) || !dev) { - pr_err("%s: invalid device\n", __func__); - return; - } - - control_phy = dev_get_drvdata(dev); - if (!control_phy) { - dev_err(dev, "%s: invalid control phy device\n", __func__); - return; - } - - if (control_phy->type == OMAP_CTRL_TYPE_OTGHS) - return; - - val = readl(control_phy->power); - - switch (control_phy->type) { - case OMAP_CTRL_TYPE_USB2: - if (on) - val &= ~OMAP_CTRL_DEV_PHY_PD; - else - val |= OMAP_CTRL_DEV_PHY_PD; - break; - - case OMAP_CTRL_TYPE_PCIE: - case OMAP_CTRL_TYPE_PIPE3: - rate = clk_get_rate(control_phy->sys_clk); - rate = rate/1000000; - - if (on) { - val &= ~(OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK | - OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_MASK); - val |= OMAP_CTRL_PIPE3_PHY_TX_RX_POWERON << - OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT; - val |= rate << - OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_SHIFT; - } else { - val &= ~OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK; - val |= OMAP_CTRL_PIPE3_PHY_TX_RX_POWEROFF << - OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT; - } - break; - - case OMAP_CTRL_TYPE_DRA7USB2: - if (on) - val &= ~OMAP_CTRL_USB2_PHY_PD; - else - val |= OMAP_CTRL_USB2_PHY_PD; - break; - - case OMAP_CTRL_TYPE_AM437USB2: - if (on) { - val &= ~(AM437X_CTRL_USB2_PHY_PD | - AM437X_CTRL_USB2_OTG_PD); - val |= (AM437X_CTRL_USB2_OTGVDET_EN | - AM437X_CTRL_USB2_OTGSESSEND_EN); - } else { - val &= ~(AM437X_CTRL_USB2_OTGVDET_EN | - AM437X_CTRL_USB2_OTGSESSEND_EN); - val |= (AM437X_CTRL_USB2_PHY_PD | - AM437X_CTRL_USB2_OTG_PD); - } - break; - default: - dev_err(dev, "%s: type %d not recognized\n", - __func__, control_phy->type); - break; - } - - writel(val, control_phy->power); -} -EXPORT_SYMBOL_GPL(omap_control_phy_power); - -/** - * omap_control_usb_host_mode - set AVALID, VBUSVALID and ID pin in grounded - * @ctrl_phy: struct omap_control_phy * - * - * Writes to the mailbox register to notify the usb core that a usb - * device has been connected. - */ -static void omap_control_usb_host_mode(struct omap_control_phy *ctrl_phy) -{ - u32 val; - - val = readl(ctrl_phy->otghs_control); - val &= ~(OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_SESSEND); - val |= OMAP_CTRL_DEV_AVALID | OMAP_CTRL_DEV_VBUSVALID; - writel(val, ctrl_phy->otghs_control); -} - -/** - * omap_control_usb_device_mode - set AVALID, VBUSVALID and ID pin in high - * impedance - * @ctrl_phy: struct omap_control_phy * - * - * Writes to the mailbox register to notify the usb core that it has been - * connected to a usb host. - */ -static void omap_control_usb_device_mode(struct omap_control_phy *ctrl_phy) -{ - u32 val; - - val = readl(ctrl_phy->otghs_control); - val &= ~OMAP_CTRL_DEV_SESSEND; - val |= OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_AVALID | - OMAP_CTRL_DEV_VBUSVALID; - writel(val, ctrl_phy->otghs_control); -} - -/** - * omap_control_usb_set_sessionend - Enable SESSIONEND and IDIG to high - * impedance - * @ctrl_phy: struct omap_control_phy * - * - * Writes to the mailbox register to notify the usb core it's now in - * disconnected state. - */ -static void omap_control_usb_set_sessionend(struct omap_control_phy *ctrl_phy) -{ - u32 val; - - val = readl(ctrl_phy->otghs_control); - val &= ~(OMAP_CTRL_DEV_AVALID | OMAP_CTRL_DEV_VBUSVALID); - val |= OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_SESSEND; - writel(val, ctrl_phy->otghs_control); -} - -/** - * omap_control_usb_set_mode - Calls to functions to set USB in one of host mode - * or device mode or to denote disconnected state - * @dev: the control module device - * @mode: The mode to which usb should be configured - * - * This is an API to write to the mailbox register to notify the usb core that - * a usb device has been connected. - */ -void omap_control_usb_set_mode(struct device *dev, - enum omap_control_usb_mode mode) -{ - struct omap_control_phy *ctrl_phy; - - if (IS_ERR(dev) || !dev) - return; - - ctrl_phy = dev_get_drvdata(dev); - - if (!ctrl_phy) { - dev_err(dev, "Invalid control phy device\n"); - return; - } - - if (ctrl_phy->type != OMAP_CTRL_TYPE_OTGHS) - return; - - switch (mode) { - case USB_MODE_HOST: - omap_control_usb_host_mode(ctrl_phy); - break; - case USB_MODE_DEVICE: - omap_control_usb_device_mode(ctrl_phy); - break; - case USB_MODE_DISCONNECT: - omap_control_usb_set_sessionend(ctrl_phy); - break; - default: - dev_vdbg(dev, "invalid omap control usb mode\n"); - } -} -EXPORT_SYMBOL_GPL(omap_control_usb_set_mode); - -#ifdef CONFIG_OF - -static const enum omap_control_phy_type otghs_data = OMAP_CTRL_TYPE_OTGHS; -static const enum omap_control_phy_type usb2_data = OMAP_CTRL_TYPE_USB2; -static const enum omap_control_phy_type pipe3_data = OMAP_CTRL_TYPE_PIPE3; -static const enum omap_control_phy_type pcie_data = OMAP_CTRL_TYPE_PCIE; -static const enum omap_control_phy_type dra7usb2_data = OMAP_CTRL_TYPE_DRA7USB2; -static const enum omap_control_phy_type am437usb2_data = OMAP_CTRL_TYPE_AM437USB2; - -static const struct of_device_id omap_control_phy_id_table[] = { - { - .compatible = "ti,control-phy-otghs", - .data = &otghs_data, - }, - { - .compatible = "ti,control-phy-usb2", - .data = &usb2_data, - }, - { - .compatible = "ti,control-phy-pipe3", - .data = &pipe3_data, - }, - { - .compatible = "ti,control-phy-pcie", - .data = &pcie_data, - }, - { - .compatible = "ti,control-phy-usb2-dra7", - .data = &dra7usb2_data, - }, - { - .compatible = "ti,control-phy-usb2-am437", - .data = &am437usb2_data, - }, - {}, -}; -MODULE_DEVICE_TABLE(of, omap_control_phy_id_table); -#endif - - -static int omap_control_phy_probe(struct platform_device *pdev) -{ - struct resource *res; - const struct of_device_id *of_id; - struct omap_control_phy *control_phy; - - of_id = of_match_device(of_match_ptr(omap_control_phy_id_table), - &pdev->dev); - if (!of_id) - return -EINVAL; - - control_phy = devm_kzalloc(&pdev->dev, sizeof(*control_phy), - GFP_KERNEL); - if (!control_phy) - return -ENOMEM; - - control_phy->dev = &pdev->dev; - control_phy->type = *(enum omap_control_phy_type *)of_id->data; - - if (control_phy->type == OMAP_CTRL_TYPE_OTGHS) { - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "otghs_control"); - control_phy->otghs_control = devm_ioremap_resource( - &pdev->dev, res); - if (IS_ERR(control_phy->otghs_control)) - return PTR_ERR(control_phy->otghs_control); - } else { - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "power"); - control_phy->power = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(control_phy->power)) { - dev_err(&pdev->dev, "Couldn't get power register\n"); - return PTR_ERR(control_phy->power); - } - } - - if (control_phy->type == OMAP_CTRL_TYPE_PIPE3 || - control_phy->type == OMAP_CTRL_TYPE_PCIE) { - control_phy->sys_clk = devm_clk_get(control_phy->dev, - "sys_clkin"); - if (IS_ERR(control_phy->sys_clk)) { - pr_err("%s: unable to get sys_clkin\n", __func__); - return -EINVAL; - } - } - - if (control_phy->type == OMAP_CTRL_TYPE_PCIE) { - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "pcie_pcs"); - control_phy->pcie_pcs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(control_phy->pcie_pcs)) - return PTR_ERR(control_phy->pcie_pcs); - } - - dev_set_drvdata(control_phy->dev, control_phy); - - return 0; -} - -static struct platform_driver omap_control_phy_driver = { - .probe = omap_control_phy_probe, - .driver = { - .name = "omap-control-phy", - .of_match_table = of_match_ptr(omap_control_phy_id_table), - }, -}; - -static int __init omap_control_phy_init(void) -{ - return platform_driver_register(&omap_control_phy_driver); -} -subsys_initcall(omap_control_phy_init); - -static void __exit omap_control_phy_exit(void) -{ - platform_driver_unregister(&omap_control_phy_driver); -} -module_exit(omap_control_phy_exit); - -MODULE_ALIAS("platform: omap_control_phy"); -MODULE_AUTHOR("Texas Instruments Inc."); -MODULE_DESCRIPTION("OMAP Control Module PHY Driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c deleted file mode 100644 index 08f2da270837..000000000000 --- a/drivers/phy/phy-omap-usb2.c +++ /dev/null @@ -1,389 +0,0 @@ -/* - * omap-usb2.c - USB PHY, talking to musb controller in OMAP. - * - * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Author: Kishon Vijay Abraham I - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define USB2PHY_DISCON_BYP_LATCH (1 << 31) -#define USB2PHY_ANA_CONFIG1 0x4c - -/** - * omap_usb2_set_comparator - links the comparator present in the sytem with - * this phy - * @comparator - the companion phy(comparator) for this phy - * - * The phy companion driver should call this API passing the phy_companion - * filled with set_vbus and start_srp to be used by usb phy. - * - * For use by phy companion driver - */ -int omap_usb2_set_comparator(struct phy_companion *comparator) -{ - struct omap_usb *phy; - struct usb_phy *x = usb_get_phy(USB_PHY_TYPE_USB2); - - if (IS_ERR(x)) - return -ENODEV; - - phy = phy_to_omapusb(x); - phy->comparator = comparator; - return 0; -} -EXPORT_SYMBOL_GPL(omap_usb2_set_comparator); - -static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled) -{ - struct omap_usb *phy = phy_to_omapusb(otg->usb_phy); - - if (!phy->comparator) - return -ENODEV; - - return phy->comparator->set_vbus(phy->comparator, enabled); -} - -static int omap_usb_start_srp(struct usb_otg *otg) -{ - struct omap_usb *phy = phy_to_omapusb(otg->usb_phy); - - if (!phy->comparator) - return -ENODEV; - - return phy->comparator->start_srp(phy->comparator); -} - -static int omap_usb_set_host(struct usb_otg *otg, struct usb_bus *host) -{ - otg->host = host; - if (!host) - otg->state = OTG_STATE_UNDEFINED; - - return 0; -} - -static int omap_usb_set_peripheral(struct usb_otg *otg, - struct usb_gadget *gadget) -{ - otg->gadget = gadget; - if (!gadget) - otg->state = OTG_STATE_UNDEFINED; - - return 0; -} - -static int omap_usb_power_off(struct phy *x) -{ - struct omap_usb *phy = phy_get_drvdata(x); - - omap_control_phy_power(phy->control_dev, 0); - - return 0; -} - -static int omap_usb_power_on(struct phy *x) -{ - struct omap_usb *phy = phy_get_drvdata(x); - - omap_control_phy_power(phy->control_dev, 1); - - return 0; -} - -static int omap_usb_init(struct phy *x) -{ - struct omap_usb *phy = phy_get_drvdata(x); - u32 val; - - if (phy->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) { - /* - * - * Reduce the sensitivity of internal PHY by enabling the - * DISCON_BYP_LATCH of the USB2PHY_ANA_CONFIG1 register. This - * resolves issues with certain devices which can otherwise - * be prone to false disconnects. - * - */ - val = omap_usb_readl(phy->phy_base, USB2PHY_ANA_CONFIG1); - val |= USB2PHY_DISCON_BYP_LATCH; - omap_usb_writel(phy->phy_base, USB2PHY_ANA_CONFIG1, val); - } - - return 0; -} - -static struct phy_ops ops = { - .init = omap_usb_init, - .power_on = omap_usb_power_on, - .power_off = omap_usb_power_off, - .owner = THIS_MODULE, -}; - -#ifdef CONFIG_OF -static const struct usb_phy_data omap_usb2_data = { - .label = "omap_usb2", - .flags = OMAP_USB2_HAS_START_SRP | OMAP_USB2_HAS_SET_VBUS, -}; - -static const struct usb_phy_data omap5_usb2_data = { - .label = "omap5_usb2", - .flags = 0, -}; - -static const struct usb_phy_data dra7x_usb2_data = { - .label = "dra7x_usb2", - .flags = OMAP_USB2_CALIBRATE_FALSE_DISCONNECT, -}; - -static const struct usb_phy_data am437x_usb2_data = { - .label = "am437x_usb2", - .flags = 0, -}; - -static const struct of_device_id omap_usb2_id_table[] = { - { - .compatible = "ti,omap-usb2", - .data = &omap_usb2_data, - }, - { - .compatible = "ti,omap5-usb2", - .data = &omap5_usb2_data, - }, - { - .compatible = "ti,dra7x-usb2", - .data = &dra7x_usb2_data, - }, - { - .compatible = "ti,am437x-usb2", - .data = &am437x_usb2_data, - }, - {}, -}; -MODULE_DEVICE_TABLE(of, omap_usb2_id_table); -#endif - -static int omap_usb2_probe(struct platform_device *pdev) -{ - struct omap_usb *phy; - struct phy *generic_phy; - struct resource *res; - struct phy_provider *phy_provider; - struct usb_otg *otg; - struct device_node *node = pdev->dev.of_node; - struct device_node *control_node; - struct platform_device *control_pdev; - const struct of_device_id *of_id; - struct usb_phy_data *phy_data; - - of_id = of_match_device(of_match_ptr(omap_usb2_id_table), &pdev->dev); - - if (!of_id) - return -EINVAL; - - phy_data = (struct usb_phy_data *)of_id->data; - - phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); - if (!phy) - return -ENOMEM; - - otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); - if (!otg) - return -ENOMEM; - - phy->dev = &pdev->dev; - - phy->phy.dev = phy->dev; - phy->phy.label = phy_data->label; - phy->phy.otg = otg; - phy->phy.type = USB_PHY_TYPE_USB2; - - if (phy_data->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) { - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - phy->phy_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(phy->phy_base)) - return PTR_ERR(phy->phy_base); - phy->flags |= OMAP_USB2_CALIBRATE_FALSE_DISCONNECT; - } - - control_node = of_parse_phandle(node, "ctrl-module", 0); - if (!control_node) { - dev_err(&pdev->dev, "Failed to get control device phandle\n"); - return -EINVAL; - } - - control_pdev = of_find_device_by_node(control_node); - if (!control_pdev) { - dev_err(&pdev->dev, "Failed to get control device\n"); - return -EINVAL; - } - - phy->control_dev = &control_pdev->dev; - omap_control_phy_power(phy->control_dev, 0); - - otg->set_host = omap_usb_set_host; - otg->set_peripheral = omap_usb_set_peripheral; - if (phy_data->flags & OMAP_USB2_HAS_SET_VBUS) - otg->set_vbus = omap_usb_set_vbus; - if (phy_data->flags & OMAP_USB2_HAS_START_SRP) - otg->start_srp = omap_usb_start_srp; - otg->usb_phy = &phy->phy; - - platform_set_drvdata(pdev, phy); - pm_runtime_enable(phy->dev); - - generic_phy = devm_phy_create(phy->dev, NULL, &ops, NULL); - if (IS_ERR(generic_phy)) { - pm_runtime_disable(phy->dev); - return PTR_ERR(generic_phy); - } - - phy_set_drvdata(generic_phy, phy); - - phy_provider = devm_of_phy_provider_register(phy->dev, - of_phy_simple_xlate); - if (IS_ERR(phy_provider)) { - pm_runtime_disable(phy->dev); - return PTR_ERR(phy_provider); - } - - phy->wkupclk = devm_clk_get(phy->dev, "wkupclk"); - if (IS_ERR(phy->wkupclk)) { - dev_warn(&pdev->dev, "unable to get wkupclk, trying old name\n"); - phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); - if (IS_ERR(phy->wkupclk)) { - dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); - return PTR_ERR(phy->wkupclk); - } else { - dev_warn(&pdev->dev, - "found usb_phy_cm_clk32k, please fix DTS\n"); - } - } - clk_prepare(phy->wkupclk); - - phy->optclk = devm_clk_get(phy->dev, "refclk"); - if (IS_ERR(phy->optclk)) { - dev_dbg(&pdev->dev, "unable to get refclk, trying old name\n"); - phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m"); - if (IS_ERR(phy->optclk)) { - dev_dbg(&pdev->dev, - "unable to get usb_otg_ss_refclk960m\n"); - } else { - dev_warn(&pdev->dev, - "found usb_otg_ss_refclk960m, please fix DTS\n"); - } - } else { - clk_prepare(phy->optclk); - } - - usb_add_phy_dev(&phy->phy); - - return 0; -} - -static int omap_usb2_remove(struct platform_device *pdev) -{ - struct omap_usb *phy = platform_get_drvdata(pdev); - - clk_unprepare(phy->wkupclk); - if (!IS_ERR(phy->optclk)) - clk_unprepare(phy->optclk); - usb_remove_phy(&phy->phy); - pm_runtime_disable(phy->dev); - - return 0; -} - -#ifdef CONFIG_PM_RUNTIME - -static int omap_usb2_runtime_suspend(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct omap_usb *phy = platform_get_drvdata(pdev); - - clk_disable(phy->wkupclk); - if (!IS_ERR(phy->optclk)) - clk_disable(phy->optclk); - - return 0; -} - -static int omap_usb2_runtime_resume(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct omap_usb *phy = platform_get_drvdata(pdev); - int ret; - - ret = clk_enable(phy->wkupclk); - if (ret < 0) { - dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret); - goto err0; - } - - if (!IS_ERR(phy->optclk)) { - ret = clk_enable(phy->optclk); - if (ret < 0) { - dev_err(phy->dev, "Failed to enable optclk %d\n", ret); - goto err1; - } - } - - return 0; - -err1: - clk_disable(phy->wkupclk); - -err0: - return ret; -} - -static const struct dev_pm_ops omap_usb2_pm_ops = { - SET_RUNTIME_PM_OPS(omap_usb2_runtime_suspend, omap_usb2_runtime_resume, - NULL) -}; - -#define DEV_PM_OPS (&omap_usb2_pm_ops) -#else -#define DEV_PM_OPS NULL -#endif - -static struct platform_driver omap_usb2_driver = { - .probe = omap_usb2_probe, - .remove = omap_usb2_remove, - .driver = { - .name = "omap-usb2", - .pm = DEV_PM_OPS, - .of_match_table = of_match_ptr(omap_usb2_id_table), - }, -}; - -module_platform_driver(omap_usb2_driver); - -MODULE_ALIAS("platform: omap_usb2"); -MODULE_AUTHOR("Texas Instruments Inc."); -MODULE_DESCRIPTION("OMAP USB2 phy driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/phy-qcom-apq8064-sata.c b/drivers/phy/phy-qcom-apq8064-sata.c deleted file mode 100644 index 7b3ddfb65898..000000000000 --- a/drivers/phy/phy-qcom-apq8064-sata.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (c) 2014, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* PHY registers */ -#define UNIPHY_PLL_REFCLK_CFG 0x000 -#define UNIPHY_PLL_PWRGEN_CFG 0x014 -#define UNIPHY_PLL_GLB_CFG 0x020 -#define UNIPHY_PLL_SDM_CFG0 0x038 -#define UNIPHY_PLL_SDM_CFG1 0x03C -#define UNIPHY_PLL_SDM_CFG2 0x040 -#define UNIPHY_PLL_SDM_CFG3 0x044 -#define UNIPHY_PLL_SDM_CFG4 0x048 -#define UNIPHY_PLL_SSC_CFG0 0x04C -#define UNIPHY_PLL_SSC_CFG1 0x050 -#define UNIPHY_PLL_SSC_CFG2 0x054 -#define UNIPHY_PLL_SSC_CFG3 0x058 -#define UNIPHY_PLL_LKDET_CFG0 0x05C -#define UNIPHY_PLL_LKDET_CFG1 0x060 -#define UNIPHY_PLL_LKDET_CFG2 0x064 -#define UNIPHY_PLL_CAL_CFG0 0x06C -#define UNIPHY_PLL_CAL_CFG8 0x08C -#define UNIPHY_PLL_CAL_CFG9 0x090 -#define UNIPHY_PLL_CAL_CFG10 0x094 -#define UNIPHY_PLL_CAL_CFG11 0x098 -#define UNIPHY_PLL_STATUS 0x0C0 - -#define SATA_PHY_SER_CTRL 0x100 -#define SATA_PHY_TX_DRIV_CTRL0 0x104 -#define SATA_PHY_TX_DRIV_CTRL1 0x108 -#define SATA_PHY_TX_IMCAL0 0x11C -#define SATA_PHY_TX_IMCAL2 0x124 -#define SATA_PHY_RX_IMCAL0 0x128 -#define SATA_PHY_EQUAL 0x13C -#define SATA_PHY_OOB_TERM 0x144 -#define SATA_PHY_CDR_CTRL0 0x148 -#define SATA_PHY_CDR_CTRL1 0x14C -#define SATA_PHY_CDR_CTRL2 0x150 -#define SATA_PHY_CDR_CTRL3 0x154 -#define SATA_PHY_PI_CTRL0 0x168 -#define SATA_PHY_POW_DWN_CTRL0 0x180 -#define SATA_PHY_POW_DWN_CTRL1 0x184 -#define SATA_PHY_TX_DATA_CTRL 0x188 -#define SATA_PHY_ALIGNP 0x1A4 -#define SATA_PHY_TX_IMCAL_STAT 0x1E4 -#define SATA_PHY_RX_IMCAL_STAT 0x1E8 - -#define UNIPHY_PLL_LOCK BIT(0) -#define SATA_PHY_TX_CAL BIT(0) -#define SATA_PHY_RX_CAL BIT(0) - -/* default timeout set to 1 sec */ -#define TIMEOUT_MS 10000 -#define DELAY_INTERVAL_US 100 - -struct qcom_apq8064_sata_phy { - void __iomem *mmio; - struct clk *cfg_clk; - struct device *dev; -}; - -/* Helper function to do poll and timeout */ -static int read_poll_timeout(void __iomem *addr, u32 mask) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS); - - do { - if (readl_relaxed(addr) & mask) - return 0; - - usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50); - } while (!time_after(jiffies, timeout)); - - return (readl_relaxed(addr) & mask) ? 0 : -ETIMEDOUT; -} - -static int qcom_apq8064_sata_phy_init(struct phy *generic_phy) -{ - struct qcom_apq8064_sata_phy *phy = phy_get_drvdata(generic_phy); - void __iomem *base = phy->mmio; - int ret = 0; - - /* SATA phy initialization */ - writel_relaxed(0x01, base + SATA_PHY_SER_CTRL); - writel_relaxed(0xB1, base + SATA_PHY_POW_DWN_CTRL0); - /* Make sure the power down happens before power up */ - mb(); - usleep_range(10, 60); - - writel_relaxed(0x01, base + SATA_PHY_POW_DWN_CTRL0); - writel_relaxed(0x3E, base + SATA_PHY_POW_DWN_CTRL1); - writel_relaxed(0x01, base + SATA_PHY_RX_IMCAL0); - writel_relaxed(0x01, base + SATA_PHY_TX_IMCAL0); - writel_relaxed(0x02, base + SATA_PHY_TX_IMCAL2); - - /* Write UNIPHYPLL registers to configure PLL */ - writel_relaxed(0x04, base + UNIPHY_PLL_REFCLK_CFG); - writel_relaxed(0x00, base + UNIPHY_PLL_PWRGEN_CFG); - - writel_relaxed(0x0A, base + UNIPHY_PLL_CAL_CFG0); - writel_relaxed(0xF3, base + UNIPHY_PLL_CAL_CFG8); - writel_relaxed(0x01, base + UNIPHY_PLL_CAL_CFG9); - writel_relaxed(0xED, base + UNIPHY_PLL_CAL_CFG10); - writel_relaxed(0x02, base + UNIPHY_PLL_CAL_CFG11); - - writel_relaxed(0x36, base + UNIPHY_PLL_SDM_CFG0); - writel_relaxed(0x0D, base + UNIPHY_PLL_SDM_CFG1); - writel_relaxed(0xA3, base + UNIPHY_PLL_SDM_CFG2); - writel_relaxed(0xF0, base + UNIPHY_PLL_SDM_CFG3); - writel_relaxed(0x00, base + UNIPHY_PLL_SDM_CFG4); - - writel_relaxed(0x19, base + UNIPHY_PLL_SSC_CFG0); - writel_relaxed(0xE1, base + UNIPHY_PLL_SSC_CFG1); - writel_relaxed(0x00, base + UNIPHY_PLL_SSC_CFG2); - writel_relaxed(0x11, base + UNIPHY_PLL_SSC_CFG3); - - writel_relaxed(0x04, base + UNIPHY_PLL_LKDET_CFG0); - writel_relaxed(0xFF, base + UNIPHY_PLL_LKDET_CFG1); - - writel_relaxed(0x02, base + UNIPHY_PLL_GLB_CFG); - /* make sure global config LDO power down happens before power up */ - mb(); - - writel_relaxed(0x03, base + UNIPHY_PLL_GLB_CFG); - writel_relaxed(0x05, base + UNIPHY_PLL_LKDET_CFG2); - - /* PLL Lock wait */ - ret = read_poll_timeout(base + UNIPHY_PLL_STATUS, UNIPHY_PLL_LOCK); - if (ret) { - dev_err(phy->dev, "poll timeout UNIPHY_PLL_STATUS\n"); - return ret; - } - - /* TX Calibration */ - ret = read_poll_timeout(base + SATA_PHY_TX_IMCAL_STAT, SATA_PHY_TX_CAL); - if (ret) { - dev_err(phy->dev, "poll timeout SATA_PHY_TX_IMCAL_STAT\n"); - return ret; - } - - /* RX Calibration */ - ret = read_poll_timeout(base + SATA_PHY_RX_IMCAL_STAT, SATA_PHY_RX_CAL); - if (ret) { - dev_err(phy->dev, "poll timeout SATA_PHY_RX_IMCAL_STAT\n"); - return ret; - } - - /* SATA phy calibrated succesfully, power up to functional mode */ - writel_relaxed(0x3E, base + SATA_PHY_POW_DWN_CTRL1); - writel_relaxed(0x01, base + SATA_PHY_RX_IMCAL0); - writel_relaxed(0x01, base + SATA_PHY_TX_IMCAL0); - - writel_relaxed(0x00, base + SATA_PHY_POW_DWN_CTRL1); - writel_relaxed(0x59, base + SATA_PHY_CDR_CTRL0); - writel_relaxed(0x04, base + SATA_PHY_CDR_CTRL1); - writel_relaxed(0x00, base + SATA_PHY_CDR_CTRL2); - writel_relaxed(0x00, base + SATA_PHY_PI_CTRL0); - writel_relaxed(0x00, base + SATA_PHY_CDR_CTRL3); - writel_relaxed(0x01, base + SATA_PHY_POW_DWN_CTRL0); - - writel_relaxed(0x11, base + SATA_PHY_TX_DATA_CTRL); - writel_relaxed(0x43, base + SATA_PHY_ALIGNP); - writel_relaxed(0x04, base + SATA_PHY_OOB_TERM); - - writel_relaxed(0x01, base + SATA_PHY_EQUAL); - writel_relaxed(0x09, base + SATA_PHY_TX_DRIV_CTRL0); - writel_relaxed(0x09, base + SATA_PHY_TX_DRIV_CTRL1); - - return 0; -} - -static int qcom_apq8064_sata_phy_exit(struct phy *generic_phy) -{ - struct qcom_apq8064_sata_phy *phy = phy_get_drvdata(generic_phy); - void __iomem *base = phy->mmio; - - /* Power down PHY */ - writel_relaxed(0xF8, base + SATA_PHY_POW_DWN_CTRL0); - writel_relaxed(0xFE, base + SATA_PHY_POW_DWN_CTRL1); - - /* Power down PLL block */ - writel_relaxed(0x00, base + UNIPHY_PLL_GLB_CFG); - - return 0; -} - -static struct phy_ops qcom_apq8064_sata_phy_ops = { - .init = qcom_apq8064_sata_phy_init, - .exit = qcom_apq8064_sata_phy_exit, - .owner = THIS_MODULE, -}; - -static int qcom_apq8064_sata_phy_probe(struct platform_device *pdev) -{ - struct qcom_apq8064_sata_phy *phy; - struct device *dev = &pdev->dev; - struct resource *res; - struct phy_provider *phy_provider; - struct phy *generic_phy; - int ret; - - phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); - if (!phy) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - phy->mmio = devm_ioremap_resource(dev, res); - if (IS_ERR(phy->mmio)) - return PTR_ERR(phy->mmio); - - generic_phy = devm_phy_create(dev, NULL, &qcom_apq8064_sata_phy_ops, - NULL); - if (IS_ERR(generic_phy)) { - dev_err(dev, "%s: failed to create phy\n", __func__); - return PTR_ERR(generic_phy); - } - - phy->dev = dev; - phy_set_drvdata(generic_phy, phy); - platform_set_drvdata(pdev, phy); - - phy->cfg_clk = devm_clk_get(dev, "cfg"); - if (IS_ERR(phy->cfg_clk)) { - dev_err(dev, "Failed to get sata cfg clock\n"); - return PTR_ERR(phy->cfg_clk); - } - - ret = clk_prepare_enable(phy->cfg_clk); - if (ret) - return ret; - - phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); - if (IS_ERR(phy_provider)) { - clk_disable_unprepare(phy->cfg_clk); - dev_err(dev, "%s: failed to register phy\n", __func__); - return PTR_ERR(phy_provider); - } - - return 0; -} - -static int qcom_apq8064_sata_phy_remove(struct platform_device *pdev) -{ - struct qcom_apq8064_sata_phy *phy = platform_get_drvdata(pdev); - - clk_disable_unprepare(phy->cfg_clk); - - return 0; -} - -static const struct of_device_id qcom_apq8064_sata_phy_of_match[] = { - { .compatible = "qcom,apq8064-sata-phy" }, - { }, -}; -MODULE_DEVICE_TABLE(of, qcom_apq8064_sata_phy_of_match); - -static struct platform_driver qcom_apq8064_sata_phy_driver = { - .probe = qcom_apq8064_sata_phy_probe, - .remove = qcom_apq8064_sata_phy_remove, - .driver = { - .name = "qcom-apq8064-sata-phy", - .of_match_table = qcom_apq8064_sata_phy_of_match, - } -}; -module_platform_driver(qcom_apq8064_sata_phy_driver); - -MODULE_DESCRIPTION("QCOM apq8064 SATA PHY driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/phy-qcom-ipq806x-sata.c b/drivers/phy/phy-qcom-ipq806x-sata.c deleted file mode 100644 index 759b0bf5b6b3..000000000000 --- a/drivers/phy/phy-qcom-ipq806x-sata.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (c) 2014, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct qcom_ipq806x_sata_phy { - void __iomem *mmio; - struct clk *cfg_clk; - struct device *dev; -}; - -#define __set(v, a, b) (((v) << (b)) & GENMASK(a, b)) - -#define SATA_PHY_P0_PARAM0 0x200 -#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3(x) __set(x, 17, 12) -#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3_MASK GENMASK(17, 12) -#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2(x) __set(x, 11, 6) -#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2_MASK GENMASK(11, 6) -#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1(x) __set(x, 5, 0) -#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1_MASK GENMASK(5, 0) - -#define SATA_PHY_P0_PARAM1 0x204 -#define SATA_PHY_P0_PARAM1_RESERVED_BITS31_21(x) __set(x, 31, 21) -#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3(x) __set(x, 20, 14) -#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3_MASK GENMASK(20, 14) -#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2(x) __set(x, 13, 7) -#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2_MASK GENMASK(13, 7) -#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1(x) __set(x, 6, 0) -#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1_MASK GENMASK(6, 0) - -#define SATA_PHY_P0_PARAM2 0x208 -#define SATA_PHY_P0_PARAM2_RX_EQ(x) __set(x, 20, 18) -#define SATA_PHY_P0_PARAM2_RX_EQ_MASK GENMASK(20, 18) - -#define SATA_PHY_P0_PARAM3 0x20C -#define SATA_PHY_SSC_EN 0x8 -#define SATA_PHY_P0_PARAM4 0x210 -#define SATA_PHY_REF_SSP_EN 0x2 -#define SATA_PHY_RESET 0x1 - -static int qcom_ipq806x_sata_phy_init(struct phy *generic_phy) -{ - struct qcom_ipq806x_sata_phy *phy = phy_get_drvdata(generic_phy); - u32 reg; - - /* Setting SSC_EN to 1 */ - reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM3); - reg = reg | SATA_PHY_SSC_EN; - writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM3); - - reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM0) & - ~(SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3_MASK | - SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2_MASK | - SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1_MASK); - reg |= SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3(0xf); - writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM0); - - reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM1) & - ~(SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3_MASK | - SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2_MASK | - SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1_MASK); - reg |= SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3(0x55) | - SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2(0x55) | - SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1(0x55); - writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM1); - - reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM2) & - ~SATA_PHY_P0_PARAM2_RX_EQ_MASK; - reg |= SATA_PHY_P0_PARAM2_RX_EQ(0x3); - writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM2); - - /* Setting PHY_RESET to 1 */ - reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4); - reg = reg | SATA_PHY_RESET; - writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4); - - /* Setting REF_SSP_EN to 1 */ - reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4); - reg = reg | SATA_PHY_REF_SSP_EN | SATA_PHY_RESET; - writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4); - - /* make sure all changes complete before we let the PHY out of reset */ - mb(); - - /* sleep for max. 50us more to combine processor wakeups */ - usleep_range(20, 20 + 50); - - /* Clearing PHY_RESET to 0 */ - reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4); - reg = reg & ~SATA_PHY_RESET; - writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4); - - return 0; -} - -static int qcom_ipq806x_sata_phy_exit(struct phy *generic_phy) -{ - struct qcom_ipq806x_sata_phy *phy = phy_get_drvdata(generic_phy); - u32 reg; - - /* Setting PHY_RESET to 1 */ - reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4); - reg = reg | SATA_PHY_RESET; - writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4); - - return 0; -} - -static struct phy_ops qcom_ipq806x_sata_phy_ops = { - .init = qcom_ipq806x_sata_phy_init, - .exit = qcom_ipq806x_sata_phy_exit, - .owner = THIS_MODULE, -}; - -static int qcom_ipq806x_sata_phy_probe(struct platform_device *pdev) -{ - struct qcom_ipq806x_sata_phy *phy; - struct device *dev = &pdev->dev; - struct resource *res; - struct phy_provider *phy_provider; - struct phy *generic_phy; - int ret; - - phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); - if (!phy) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - phy->mmio = devm_ioremap_resource(dev, res); - if (IS_ERR(phy->mmio)) - return PTR_ERR(phy->mmio); - - generic_phy = devm_phy_create(dev, NULL, &qcom_ipq806x_sata_phy_ops, - NULL); - if (IS_ERR(generic_phy)) { - dev_err(dev, "%s: failed to create phy\n", __func__); - return PTR_ERR(generic_phy); - } - - phy->dev = dev; - phy_set_drvdata(generic_phy, phy); - platform_set_drvdata(pdev, phy); - - phy->cfg_clk = devm_clk_get(dev, "cfg"); - if (IS_ERR(phy->cfg_clk)) { - dev_err(dev, "Failed to get sata cfg clock\n"); - return PTR_ERR(phy->cfg_clk); - } - - ret = clk_prepare_enable(phy->cfg_clk); - if (ret) - return ret; - - phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); - if (IS_ERR(phy_provider)) { - clk_disable_unprepare(phy->cfg_clk); - dev_err(dev, "%s: failed to register phy\n", __func__); - return PTR_ERR(phy_provider); - } - - return 0; -} - -static int qcom_ipq806x_sata_phy_remove(struct platform_device *pdev) -{ - struct qcom_ipq806x_sata_phy *phy = platform_get_drvdata(pdev); - - clk_disable_unprepare(phy->cfg_clk); - - return 0; -} - -static const struct of_device_id qcom_ipq806x_sata_phy_of_match[] = { - { .compatible = "qcom,ipq806x-sata-phy" }, - { }, -}; -MODULE_DEVICE_TABLE(of, qcom_ipq806x_sata_phy_of_match); - -static struct platform_driver qcom_ipq806x_sata_phy_driver = { - .probe = qcom_ipq806x_sata_phy_probe, - .remove = qcom_ipq806x_sata_phy_remove, - .driver = { - .name = "qcom-ipq806x-sata-phy", - .of_match_table = qcom_ipq806x_sata_phy_of_match, - } -}; -module_platform_driver(qcom_ipq806x_sata_phy_driver); - -MODULE_DESCRIPTION("QCOM IPQ806x SATA PHY driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/phy-rcar-gen2.c b/drivers/phy/phy-rcar-gen2.c deleted file mode 100644 index 2793af17799f..000000000000 --- a/drivers/phy/phy-rcar-gen2.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Renesas R-Car Gen2 PHY driver - * - * Copyright (C) 2014 Renesas Solutions Corp. - * Copyright (C) 2014 Cogent Embedded, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define USBHS_LPSTS 0x02 -#define USBHS_UGCTRL 0x80 -#define USBHS_UGCTRL2 0x84 -#define USBHS_UGSTS 0x88 /* The manuals have 0x90 */ - -/* Low Power Status register (LPSTS) */ -#define USBHS_LPSTS_SUSPM 0x4000 - -/* USB General control register (UGCTRL) */ -#define USBHS_UGCTRL_CONNECT 0x00000004 -#define USBHS_UGCTRL_PLLRESET 0x00000001 - -/* USB General control register 2 (UGCTRL2) */ -#define USBHS_UGCTRL2_USB2SEL 0x80000000 -#define USBHS_UGCTRL2_USB2SEL_PCI 0x00000000 -#define USBHS_UGCTRL2_USB2SEL_USB30 0x80000000 -#define USBHS_UGCTRL2_USB0SEL 0x00000030 -#define USBHS_UGCTRL2_USB0SEL_PCI 0x00000010 -#define USBHS_UGCTRL2_USB0SEL_HS_USB 0x00000030 - -/* USB General status register (UGSTS) */ -#define USBHS_UGSTS_LOCK 0x00000300 /* The manuals have 0x3 */ - -#define PHYS_PER_CHANNEL 2 - -struct rcar_gen2_phy { - struct phy *phy; - struct rcar_gen2_channel *channel; - int number; - u32 select_value; -}; - -struct rcar_gen2_channel { - struct device_node *of_node; - struct rcar_gen2_phy_driver *drv; - struct rcar_gen2_phy phys[PHYS_PER_CHANNEL]; - int selected_phy; - u32 select_mask; -}; - -struct rcar_gen2_phy_driver { - void __iomem *base; - struct clk *clk; - spinlock_t lock; - int num_channels; - struct rcar_gen2_channel *channels; -}; - -static int rcar_gen2_phy_init(struct phy *p) -{ - struct rcar_gen2_phy *phy = phy_get_drvdata(p); - struct rcar_gen2_channel *channel = phy->channel; - struct rcar_gen2_phy_driver *drv = channel->drv; - unsigned long flags; - u32 ugctrl2; - - /* - * Try to acquire exclusive access to PHY. The first driver calling - * phy_init() on a given channel wins, and all attempts to use another - * PHY on this channel will fail until phy_exit() is called by the first - * driver. Achieving this with cmpxcgh() should be SMP-safe. - */ - if (cmpxchg(&channel->selected_phy, -1, phy->number) != -1) - return -EBUSY; - - clk_prepare_enable(drv->clk); - - spin_lock_irqsave(&drv->lock, flags); - ugctrl2 = readl(drv->base + USBHS_UGCTRL2); - ugctrl2 &= ~channel->select_mask; - ugctrl2 |= phy->select_value; - writel(ugctrl2, drv->base + USBHS_UGCTRL2); - spin_unlock_irqrestore(&drv->lock, flags); - return 0; -} - -static int rcar_gen2_phy_exit(struct phy *p) -{ - struct rcar_gen2_phy *phy = phy_get_drvdata(p); - struct rcar_gen2_channel *channel = phy->channel; - - clk_disable_unprepare(channel->drv->clk); - - channel->selected_phy = -1; - - return 0; -} - -static int rcar_gen2_phy_power_on(struct phy *p) -{ - struct rcar_gen2_phy *phy = phy_get_drvdata(p); - struct rcar_gen2_phy_driver *drv = phy->channel->drv; - void __iomem *base = drv->base; - unsigned long flags; - u32 value; - int err = 0, i; - - /* Skip if it's not USBHS */ - if (phy->select_value != USBHS_UGCTRL2_USB0SEL_HS_USB) - return 0; - - spin_lock_irqsave(&drv->lock, flags); - - /* Power on USBHS PHY */ - value = readl(base + USBHS_UGCTRL); - value &= ~USBHS_UGCTRL_PLLRESET; - writel(value, base + USBHS_UGCTRL); - - value = readw(base + USBHS_LPSTS); - value |= USBHS_LPSTS_SUSPM; - writew(value, base + USBHS_LPSTS); - - for (i = 0; i < 20; i++) { - value = readl(base + USBHS_UGSTS); - if ((value & USBHS_UGSTS_LOCK) == USBHS_UGSTS_LOCK) { - value = readl(base + USBHS_UGCTRL); - value |= USBHS_UGCTRL_CONNECT; - writel(value, base + USBHS_UGCTRL); - goto out; - } - udelay(1); - } - - /* Timed out waiting for the PLL lock */ - err = -ETIMEDOUT; - -out: - spin_unlock_irqrestore(&drv->lock, flags); - - return err; -} - -static int rcar_gen2_phy_power_off(struct phy *p) -{ - struct rcar_gen2_phy *phy = phy_get_drvdata(p); - struct rcar_gen2_phy_driver *drv = phy->channel->drv; - void __iomem *base = drv->base; - unsigned long flags; - u32 value; - - /* Skip if it's not USBHS */ - if (phy->select_value != USBHS_UGCTRL2_USB0SEL_HS_USB) - return 0; - - spin_lock_irqsave(&drv->lock, flags); - - /* Power off USBHS PHY */ - value = readl(base + USBHS_UGCTRL); - value &= ~USBHS_UGCTRL_CONNECT; - writel(value, base + USBHS_UGCTRL); - - value = readw(base + USBHS_LPSTS); - value &= ~USBHS_LPSTS_SUSPM; - writew(value, base + USBHS_LPSTS); - - value = readl(base + USBHS_UGCTRL); - value |= USBHS_UGCTRL_PLLRESET; - writel(value, base + USBHS_UGCTRL); - - spin_unlock_irqrestore(&drv->lock, flags); - - return 0; -} - -static struct phy_ops rcar_gen2_phy_ops = { - .init = rcar_gen2_phy_init, - .exit = rcar_gen2_phy_exit, - .power_on = rcar_gen2_phy_power_on, - .power_off = rcar_gen2_phy_power_off, - .owner = THIS_MODULE, -}; - -static const struct of_device_id rcar_gen2_phy_match_table[] = { - { .compatible = "renesas,usb-phy-r8a7790" }, - { .compatible = "renesas,usb-phy-r8a7791" }, - { } -}; -MODULE_DEVICE_TABLE(of, rcar_gen2_phy_match_table); - -static struct phy *rcar_gen2_phy_xlate(struct device *dev, - struct of_phandle_args *args) -{ - struct rcar_gen2_phy_driver *drv; - struct device_node *np = args->np; - int i; - - if (!of_device_is_available(np)) { - dev_warn(dev, "Requested PHY is disabled\n"); - return ERR_PTR(-ENODEV); - } - - drv = dev_get_drvdata(dev); - if (!drv) - return ERR_PTR(-EINVAL); - - for (i = 0; i < drv->num_channels; i++) { - if (np == drv->channels[i].of_node) - break; - } - - if (i >= drv->num_channels || args->args[0] >= 2) - return ERR_PTR(-ENODEV); - - return drv->channels[i].phys[args->args[0]].phy; -} - -static const u32 select_mask[] = { - [0] = USBHS_UGCTRL2_USB0SEL, - [2] = USBHS_UGCTRL2_USB2SEL, -}; - -static const u32 select_value[][PHYS_PER_CHANNEL] = { - [0] = { USBHS_UGCTRL2_USB0SEL_PCI, USBHS_UGCTRL2_USB0SEL_HS_USB }, - [2] = { USBHS_UGCTRL2_USB2SEL_PCI, USBHS_UGCTRL2_USB2SEL_USB30 }, -}; - -static int rcar_gen2_phy_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct rcar_gen2_phy_driver *drv; - struct phy_provider *provider; - struct device_node *np; - struct resource *res; - void __iomem *base; - struct clk *clk; - int i = 0; - - if (!dev->of_node) { - dev_err(dev, - "This driver is required to be instantiated from device tree\n"); - return -EINVAL; - } - - clk = devm_clk_get(dev, "usbhs"); - if (IS_ERR(clk)) { - dev_err(dev, "Can't get USBHS clock\n"); - return PTR_ERR(clk); - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); - if (IS_ERR(base)) - return PTR_ERR(base); - - drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL); - if (!drv) - return -ENOMEM; - - spin_lock_init(&drv->lock); - - drv->clk = clk; - drv->base = base; - - drv->num_channels = of_get_child_count(dev->of_node); - drv->channels = devm_kcalloc(dev, drv->num_channels, - sizeof(struct rcar_gen2_channel), - GFP_KERNEL); - if (!drv->channels) - return -ENOMEM; - - for_each_child_of_node(dev->of_node, np) { - struct rcar_gen2_channel *channel = drv->channels + i; - u32 channel_num; - int error, n; - - channel->of_node = np; - channel->drv = drv; - channel->selected_phy = -1; - - error = of_property_read_u32(np, "reg", &channel_num); - if (error || channel_num > 2) { - dev_err(dev, "Invalid \"reg\" property\n"); - return error; - } - channel->select_mask = select_mask[channel_num]; - - for (n = 0; n < PHYS_PER_CHANNEL; n++) { - struct rcar_gen2_phy *phy = &channel->phys[n]; - - phy->channel = channel; - phy->number = n; - phy->select_value = select_value[channel_num][n]; - - phy->phy = devm_phy_create(dev, NULL, - &rcar_gen2_phy_ops, NULL); - if (IS_ERR(phy->phy)) { - dev_err(dev, "Failed to create PHY\n"); - return PTR_ERR(phy->phy); - } - phy_set_drvdata(phy->phy, phy); - } - - i++; - } - - provider = devm_of_phy_provider_register(dev, rcar_gen2_phy_xlate); - if (IS_ERR(provider)) { - dev_err(dev, "Failed to register PHY provider\n"); - return PTR_ERR(provider); - } - - dev_set_drvdata(dev, drv); - - return 0; -} - -static struct platform_driver rcar_gen2_phy_driver = { - .driver = { - .name = "phy_rcar_gen2", - .of_match_table = rcar_gen2_phy_match_table, - }, - .probe = rcar_gen2_phy_probe, -}; - -module_platform_driver(rcar_gen2_phy_driver); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Renesas R-Car Gen2 PHY"); -MODULE_AUTHOR("Sergei Shtylyov "); diff --git a/drivers/phy/phy-rockchip-usb.c b/drivers/phy/phy-rockchip-usb.c deleted file mode 100644 index 2586b767bcb2..000000000000 --- a/drivers/phy/phy-rockchip-usb.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Rockchip usb PHY driver - * - * Copyright (C) 2014 Roy Li - * Copyright (C) 2014 ROCKCHIP, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ROCKCHIP_RK3288_UOC(n) (0x320 + n * 0x14) - -#define SIDDQ_MSK (1 << (13 + 16)) -#define SIDDQ_ON (1 << 13) -#define SIDDQ_OFF (0 << 13) - -enum rk3288_phy_id { - RK3288_OTG, - RK3288_HOST0, - RK3288_HOST1, - RK3288_NUM_PHYS, -}; - -struct rockchip_usb_phy { - struct regmap *reg_base; - unsigned int reg_offset; - struct clk *clk; - struct phy *phy; -}; - -static int rockchip_usb_phy_power(struct rockchip_usb_phy *phy, - bool siddq) -{ - return regmap_write(phy->reg_base, phy->reg_offset, - SIDDQ_MSK | (siddq ? SIDDQ_ON : SIDDQ_OFF)); -} - -static int rockchip_usb_phy_power_off(struct phy *_phy) -{ - struct rockchip_usb_phy *phy = phy_get_drvdata(_phy); - int ret = 0; - - /* Power down usb phy analog blocks by set siddq 1*/ - ret = rockchip_usb_phy_power(phy, 1); - if (ret) - return ret; - - clk_disable_unprepare(phy->clk); - if (ret) - return ret; - - return 0; -} - -static int rockchip_usb_phy_power_on(struct phy *_phy) -{ - struct rockchip_usb_phy *phy = phy_get_drvdata(_phy); - int ret = 0; - - ret = clk_prepare_enable(phy->clk); - if (ret) - return ret; - - /* Power up usb phy analog blocks by set siddq 0*/ - ret = rockchip_usb_phy_power(phy, 0); - if (ret) - return ret; - - return 0; -} - -static struct phy *rockchip_usb_phy_xlate(struct device *dev, - struct of_phandle_args *args) -{ - struct rockchip_usb_phy *phy_array = dev_get_drvdata(dev); - - if (WARN_ON(args->args[0] == 0 || args->args[0] >= RK3288_NUM_PHYS)) - return ERR_PTR(-ENODEV); - - return (phy_array + args->args[0])->phy; -} - -static struct phy_ops ops = { - .power_on = rockchip_usb_phy_power_on, - .power_off = rockchip_usb_phy_power_off, - .owner = THIS_MODULE, -}; - -static int rockchip_usb_phy_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct rockchip_usb_phy *rk_phy; - struct rockchip_usb_phy *phy_array; - struct phy_provider *phy_provider; - struct regmap *grf; - char clk_name[16]; - int i; - - grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); - if (IS_ERR(grf)) { - dev_err(&pdev->dev, "Missing rockchip,grf property\n"); - return PTR_ERR(grf); - } - - phy_array = devm_kzalloc(dev, RK3288_NUM_PHYS * sizeof(*rk_phy), - GFP_KERNEL); - if (!phy_array) - return -ENOMEM; - - for (i = 0; i < RK3288_NUM_PHYS; i++) { - rk_phy = &phy_array[i]; - - rk_phy->reg_base = grf; - - rk_phy->reg_offset = ROCKCHIP_RK3288_UOC(i); - - snprintf(clk_name, sizeof(clk_name), "usbphy%d", i); - rk_phy->clk = devm_clk_get(dev, clk_name); - if (IS_ERR(rk_phy->clk)) { - dev_warn(dev, "failed to get clock %s\n", clk_name); - rk_phy->clk = NULL; - } - - rk_phy->phy = devm_phy_create(dev, NULL, &ops, NULL); - if (IS_ERR(rk_phy->phy)) { - dev_err(dev, "failed to create PHY %d\n", i); - return PTR_ERR(rk_phy->phy); - } - phy_set_drvdata(rk_phy->phy, rk_phy); - } - - platform_set_drvdata(pdev, phy_array); - - phy_provider = devm_of_phy_provider_register(dev, - rockchip_usb_phy_xlate); - return PTR_ERR_OR_ZERO(phy_provider); -} - -static const struct of_device_id rockchip_usb_phy_dt_ids[] = { - { .compatible = "rockchip,rk3288-usb-phy" }, - {} -}; - -MODULE_DEVICE_TABLE(of, rockchip_usb_phy_dt_ids); - -static struct platform_driver rockchip_usb_driver = { - .probe = rockchip_usb_phy_probe, - .driver = { - .name = "rockchip-usb-phy", - .owner = THIS_MODULE, - .of_match_table = rockchip_usb_phy_dt_ids, - }, -}; - -module_platform_driver(rockchip_usb_driver); - -MODULE_AUTHOR("Roy Li "); -MODULE_DESCRIPTION("Rockchip USB 2.0 PHY driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/phy-s5pv210-usb2.c b/drivers/phy/phy-s5pv210-usb2.c deleted file mode 100644 index 004d320767e4..000000000000 --- a/drivers/phy/phy-s5pv210-usb2.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Samsung SoC USB 1.1/2.0 PHY driver - S5PV210 support - * - * Copyright (C) 2013 Samsung Electronics Co., Ltd. - * Authors: Kamil Debski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include "phy-samsung-usb2.h" - -/* Exynos USB PHY registers */ - -/* PHY power control */ -#define S5PV210_UPHYPWR 0x0 - -#define S5PV210_UPHYPWR_PHY0_SUSPEND BIT(0) -#define S5PV210_UPHYPWR_PHY0_PWR BIT(3) -#define S5PV210_UPHYPWR_PHY0_OTG_PWR BIT(4) -#define S5PV210_UPHYPWR_PHY0 ( \ - S5PV210_UPHYPWR_PHY0_SUSPEND | \ - S5PV210_UPHYPWR_PHY0_PWR | \ - S5PV210_UPHYPWR_PHY0_OTG_PWR) - -#define S5PV210_UPHYPWR_PHY1_SUSPEND BIT(6) -#define S5PV210_UPHYPWR_PHY1_PWR BIT(7) -#define S5PV210_UPHYPWR_PHY1 ( \ - S5PV210_UPHYPWR_PHY1_SUSPEND | \ - S5PV210_UPHYPWR_PHY1_PWR) - -/* PHY clock control */ -#define S5PV210_UPHYCLK 0x4 - -#define S5PV210_UPHYCLK_PHYFSEL_MASK (0x3 << 0) -#define S5PV210_UPHYCLK_PHYFSEL_48MHZ (0x0 << 0) -#define S5PV210_UPHYCLK_PHYFSEL_24MHZ (0x3 << 0) -#define S5PV210_UPHYCLK_PHYFSEL_12MHZ (0x2 << 0) - -#define S5PV210_UPHYCLK_PHY0_ID_PULLUP BIT(2) -#define S5PV210_UPHYCLK_PHY0_COMMON_ON BIT(4) -#define S5PV210_UPHYCLK_PHY1_COMMON_ON BIT(7) - -/* PHY reset control */ -#define S5PV210_UPHYRST 0x8 - -#define S5PV210_URSTCON_PHY0 BIT(0) -#define S5PV210_URSTCON_OTG_HLINK BIT(1) -#define S5PV210_URSTCON_OTG_PHYLINK BIT(2) -#define S5PV210_URSTCON_PHY1_ALL BIT(3) -#define S5PV210_URSTCON_HOST_LINK_ALL BIT(4) - -/* Isolation, configured in the power management unit */ -#define S5PV210_USB_ISOL_OFFSET 0x680c -#define S5PV210_USB_ISOL_DEVICE BIT(0) -#define S5PV210_USB_ISOL_HOST BIT(1) - - -enum s5pv210_phy_id { - S5PV210_DEVICE, - S5PV210_HOST, - S5PV210_NUM_PHYS, -}; - -/* - * s5pv210_rate_to_clk() converts the supplied clock rate to the value that - * can be written to the phy register. - */ -static int s5pv210_rate_to_clk(unsigned long rate, u32 *reg) -{ - switch (rate) { - case 12 * MHZ: - *reg = S5PV210_UPHYCLK_PHYFSEL_12MHZ; - break; - case 24 * MHZ: - *reg = S5PV210_UPHYCLK_PHYFSEL_24MHZ; - break; - case 48 * MHZ: - *reg = S5PV210_UPHYCLK_PHYFSEL_48MHZ; - break; - default: - return -EINVAL; - } - - return 0; -} - -static void s5pv210_isol(struct samsung_usb2_phy_instance *inst, bool on) -{ - struct samsung_usb2_phy_driver *drv = inst->drv; - u32 mask; - - switch (inst->cfg->id) { - case S5PV210_DEVICE: - mask = S5PV210_USB_ISOL_DEVICE; - break; - case S5PV210_HOST: - mask = S5PV210_USB_ISOL_HOST; - break; - default: - return; - }; - - regmap_update_bits(drv->reg_pmu, S5PV210_USB_ISOL_OFFSET, - mask, on ? 0 : mask); -} - -static void s5pv210_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on) -{ - struct samsung_usb2_phy_driver *drv = inst->drv; - u32 rstbits = 0; - u32 phypwr = 0; - u32 rst; - u32 pwr; - - switch (inst->cfg->id) { - case S5PV210_DEVICE: - phypwr = S5PV210_UPHYPWR_PHY0; - rstbits = S5PV210_URSTCON_PHY0; - break; - case S5PV210_HOST: - phypwr = S5PV210_UPHYPWR_PHY1; - rstbits = S5PV210_URSTCON_PHY1_ALL | - S5PV210_URSTCON_HOST_LINK_ALL; - break; - }; - - if (on) { - writel(drv->ref_reg_val, drv->reg_phy + S5PV210_UPHYCLK); - - pwr = readl(drv->reg_phy + S5PV210_UPHYPWR); - pwr &= ~phypwr; - writel(pwr, drv->reg_phy + S5PV210_UPHYPWR); - - rst = readl(drv->reg_phy + S5PV210_UPHYRST); - rst |= rstbits; - writel(rst, drv->reg_phy + S5PV210_UPHYRST); - udelay(10); - rst &= ~rstbits; - writel(rst, drv->reg_phy + S5PV210_UPHYRST); - } else { - pwr = readl(drv->reg_phy + S5PV210_UPHYPWR); - pwr |= phypwr; - writel(pwr, drv->reg_phy + S5PV210_UPHYPWR); - } -} - -static int s5pv210_power_on(struct samsung_usb2_phy_instance *inst) -{ - s5pv210_isol(inst, 0); - s5pv210_phy_pwr(inst, 1); - - return 0; -} - -static int s5pv210_power_off(struct samsung_usb2_phy_instance *inst) -{ - s5pv210_phy_pwr(inst, 0); - s5pv210_isol(inst, 1); - - return 0; -} - -static const struct samsung_usb2_common_phy s5pv210_phys[S5PV210_NUM_PHYS] = { - [S5PV210_DEVICE] = { - .label = "device", - .id = S5PV210_DEVICE, - .power_on = s5pv210_power_on, - .power_off = s5pv210_power_off, - }, - [S5PV210_HOST] = { - .label = "host", - .id = S5PV210_HOST, - .power_on = s5pv210_power_on, - .power_off = s5pv210_power_off, - }, -}; - -const struct samsung_usb2_phy_config s5pv210_usb2_phy_config = { - .num_phys = ARRAY_SIZE(s5pv210_phys), - .phys = s5pv210_phys, - .rate_to_clk = s5pv210_rate_to_clk, -}; diff --git a/drivers/phy/phy-samsung-usb2.c b/drivers/phy/phy-samsung-usb2.c deleted file mode 100644 index 908949dfb4db..000000000000 --- a/drivers/phy/phy-samsung-usb2.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Samsung SoC USB 1.1/2.0 PHY driver - * - * Copyright (C) 2013 Samsung Electronics Co., Ltd. - * Author: Kamil Debski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "phy-samsung-usb2.h" - -static int samsung_usb2_phy_power_on(struct phy *phy) -{ - struct samsung_usb2_phy_instance *inst = phy_get_drvdata(phy); - struct samsung_usb2_phy_driver *drv = inst->drv; - int ret; - - dev_dbg(drv->dev, "Request to power_on \"%s\" usb phy\n", - inst->cfg->label); - ret = clk_prepare_enable(drv->clk); - if (ret) - goto err_main_clk; - ret = clk_prepare_enable(drv->ref_clk); - if (ret) - goto err_instance_clk; - if (inst->cfg->power_on) { - spin_lock(&drv->lock); - ret = inst->cfg->power_on(inst); - spin_unlock(&drv->lock); - } - - return 0; - -err_instance_clk: - clk_disable_unprepare(drv->clk); -err_main_clk: - return ret; -} - -static int samsung_usb2_phy_power_off(struct phy *phy) -{ - struct samsung_usb2_phy_instance *inst = phy_get_drvdata(phy); - struct samsung_usb2_phy_driver *drv = inst->drv; - int ret = 0; - - dev_dbg(drv->dev, "Request to power_off \"%s\" usb phy\n", - inst->cfg->label); - if (inst->cfg->power_off) { - spin_lock(&drv->lock); - ret = inst->cfg->power_off(inst); - spin_unlock(&drv->lock); - } - clk_disable_unprepare(drv->ref_clk); - clk_disable_unprepare(drv->clk); - return ret; -} - -static struct phy_ops samsung_usb2_phy_ops = { - .power_on = samsung_usb2_phy_power_on, - .power_off = samsung_usb2_phy_power_off, - .owner = THIS_MODULE, -}; - -static struct phy *samsung_usb2_phy_xlate(struct device *dev, - struct of_phandle_args *args) -{ - struct samsung_usb2_phy_driver *drv; - - drv = dev_get_drvdata(dev); - if (!drv) - return ERR_PTR(-EINVAL); - - if (WARN_ON(args->args[0] >= drv->cfg->num_phys)) - return ERR_PTR(-ENODEV); - - return drv->instances[args->args[0]].phy; -} - -static const struct of_device_id samsung_usb2_phy_of_match[] = { -#ifdef CONFIG_PHY_EXYNOS4X12_USB2 - { - .compatible = "samsung,exynos3250-usb2-phy", - .data = &exynos3250_usb2_phy_config, - }, -#endif -#ifdef CONFIG_PHY_EXYNOS4210_USB2 - { - .compatible = "samsung,exynos4210-usb2-phy", - .data = &exynos4210_usb2_phy_config, - }, -#endif -#ifdef CONFIG_PHY_EXYNOS4X12_USB2 - { - .compatible = "samsung,exynos4x12-usb2-phy", - .data = &exynos4x12_usb2_phy_config, - }, -#endif -#ifdef CONFIG_PHY_EXYNOS5250_USB2 - { - .compatible = "samsung,exynos5250-usb2-phy", - .data = &exynos5250_usb2_phy_config, - }, -#endif -#ifdef CONFIG_PHY_S5PV210_USB2 - { - .compatible = "samsung,s5pv210-usb2-phy", - .data = &s5pv210_usb2_phy_config, - }, -#endif - { }, -}; -MODULE_DEVICE_TABLE(of, samsung_usb2_phy_of_match); - -static int samsung_usb2_phy_probe(struct platform_device *pdev) -{ - const struct of_device_id *match; - const struct samsung_usb2_phy_config *cfg; - struct device *dev = &pdev->dev; - struct phy_provider *phy_provider; - struct resource *mem; - struct samsung_usb2_phy_driver *drv; - int i, ret; - - if (!pdev->dev.of_node) { - dev_err(dev, "This driver is required to be instantiated from device tree\n"); - return -EINVAL; - } - - match = of_match_node(samsung_usb2_phy_of_match, pdev->dev.of_node); - if (!match) { - dev_err(dev, "of_match_node() failed\n"); - return -EINVAL; - } - cfg = match->data; - - drv = devm_kzalloc(dev, sizeof(struct samsung_usb2_phy_driver) + - cfg->num_phys * sizeof(struct samsung_usb2_phy_instance), - GFP_KERNEL); - if (!drv) - return -ENOMEM; - - dev_set_drvdata(dev, drv); - spin_lock_init(&drv->lock); - - drv->cfg = cfg; - drv->dev = dev; - - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - drv->reg_phy = devm_ioremap_resource(dev, mem); - if (IS_ERR(drv->reg_phy)) { - dev_err(dev, "Failed to map register memory (phy)\n"); - return PTR_ERR(drv->reg_phy); - } - - drv->reg_pmu = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, - "samsung,pmureg-phandle"); - if (IS_ERR(drv->reg_pmu)) { - dev_err(dev, "Failed to map PMU registers (via syscon)\n"); - return PTR_ERR(drv->reg_pmu); - } - - if (drv->cfg->has_mode_switch) { - drv->reg_sys = syscon_regmap_lookup_by_phandle( - pdev->dev.of_node, "samsung,sysreg-phandle"); - if (IS_ERR(drv->reg_sys)) { - dev_err(dev, "Failed to map system registers (via syscon)\n"); - return PTR_ERR(drv->reg_sys); - } - } - - drv->clk = devm_clk_get(dev, "phy"); - if (IS_ERR(drv->clk)) { - dev_err(dev, "Failed to get clock of phy controller\n"); - return PTR_ERR(drv->clk); - } - - drv->ref_clk = devm_clk_get(dev, "ref"); - if (IS_ERR(drv->ref_clk)) { - dev_err(dev, "Failed to get reference clock for the phy controller\n"); - return PTR_ERR(drv->ref_clk); - } - - drv->ref_rate = clk_get_rate(drv->ref_clk); - if (drv->cfg->rate_to_clk) { - ret = drv->cfg->rate_to_clk(drv->ref_rate, &drv->ref_reg_val); - if (ret) - return ret; - } - - for (i = 0; i < drv->cfg->num_phys; i++) { - char *label = drv->cfg->phys[i].label; - struct samsung_usb2_phy_instance *p = &drv->instances[i]; - - dev_dbg(dev, "Creating phy \"%s\"\n", label); - p->phy = devm_phy_create(dev, NULL, &samsung_usb2_phy_ops, - NULL); - if (IS_ERR(p->phy)) { - dev_err(drv->dev, "Failed to create usb2_phy \"%s\"\n", - label); - return PTR_ERR(p->phy); - } - - p->cfg = &drv->cfg->phys[i]; - p->drv = drv; - phy_set_bus_width(p->phy, 8); - phy_set_drvdata(p->phy, p); - } - - phy_provider = devm_of_phy_provider_register(dev, - samsung_usb2_phy_xlate); - if (IS_ERR(phy_provider)) { - dev_err(drv->dev, "Failed to register phy provider\n"); - return PTR_ERR(phy_provider); - } - - return 0; -} - -static struct platform_driver samsung_usb2_phy_driver = { - .probe = samsung_usb2_phy_probe, - .driver = { - .of_match_table = samsung_usb2_phy_of_match, - .name = "samsung-usb2-phy", - } -}; - -module_platform_driver(samsung_usb2_phy_driver); -MODULE_DESCRIPTION("Samsung S5P/EXYNOS SoC USB PHY driver"); -MODULE_AUTHOR("Kamil Debski "); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:samsung-usb2-phy"); diff --git a/drivers/phy/phy-samsung-usb2.h b/drivers/phy/phy-samsung-usb2.h deleted file mode 100644 index 44bead9b8f34..000000000000 --- a/drivers/phy/phy-samsung-usb2.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Samsung SoC USB 1.1/2.0 PHY driver - * - * Copyright (C) 2013 Samsung Electronics Co., Ltd. - * Author: Kamil Debski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _PHY_EXYNOS_USB2_H -#define _PHY_EXYNOS_USB2_H - -#include -#include -#include -#include -#include - -#define KHZ 1000 -#define MHZ (KHZ * KHZ) - -struct samsung_usb2_phy_driver; -struct samsung_usb2_phy_instance; -struct samsung_usb2_phy_config; - -struct samsung_usb2_phy_instance { - const struct samsung_usb2_common_phy *cfg; - struct phy *phy; - struct samsung_usb2_phy_driver *drv; - int int_cnt; - int ext_cnt; -}; - -struct samsung_usb2_phy_driver { - const struct samsung_usb2_phy_config *cfg; - struct clk *clk; - struct clk *ref_clk; - unsigned long ref_rate; - u32 ref_reg_val; - struct device *dev; - void __iomem *reg_phy; - struct regmap *reg_pmu; - struct regmap *reg_sys; - spinlock_t lock; - struct samsung_usb2_phy_instance instances[0]; -}; - -struct samsung_usb2_common_phy { - int (*power_on)(struct samsung_usb2_phy_instance *); - int (*power_off)(struct samsung_usb2_phy_instance *); - unsigned int id; - char *label; -}; - - -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; - bool has_refclk_sel; -}; - -extern const struct samsung_usb2_phy_config exynos3250_usb2_phy_config; -extern const struct samsung_usb2_phy_config exynos4210_usb2_phy_config; -extern const struct samsung_usb2_phy_config exynos4x12_usb2_phy_config; -extern const struct samsung_usb2_phy_config exynos5250_usb2_phy_config; -extern const struct samsung_usb2_phy_config s5pv210_usb2_phy_config; -#endif diff --git a/drivers/phy/phy-spear1310-miphy.c b/drivers/phy/phy-spear1310-miphy.c deleted file mode 100644 index 5f4c586ee951..000000000000 --- a/drivers/phy/phy-spear1310-miphy.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - * ST SPEAr1310-miphy driver - * - * Copyright (C) 2014 ST Microelectronics - * Pratyush Anand - * Mohit Kumar - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* SPEAr1310 Registers */ -#define SPEAR1310_PCIE_SATA_CFG 0x3A4 - #define SPEAR1310_PCIE_SATA2_SEL_PCIE (0 << 31) - #define SPEAR1310_PCIE_SATA1_SEL_PCIE (0 << 30) - #define SPEAR1310_PCIE_SATA0_SEL_PCIE (0 << 29) - #define SPEAR1310_PCIE_SATA2_SEL_SATA BIT(31) - #define SPEAR1310_PCIE_SATA1_SEL_SATA BIT(30) - #define SPEAR1310_PCIE_SATA0_SEL_SATA BIT(29) - #define SPEAR1310_SATA2_CFG_TX_CLK_EN BIT(27) - #define SPEAR1310_SATA2_CFG_RX_CLK_EN BIT(26) - #define SPEAR1310_SATA2_CFG_POWERUP_RESET BIT(25) - #define SPEAR1310_SATA2_CFG_PM_CLK_EN BIT(24) - #define SPEAR1310_SATA1_CFG_TX_CLK_EN BIT(23) - #define SPEAR1310_SATA1_CFG_RX_CLK_EN BIT(22) - #define SPEAR1310_SATA1_CFG_POWERUP_RESET BIT(21) - #define SPEAR1310_SATA1_CFG_PM_CLK_EN BIT(20) - #define SPEAR1310_SATA0_CFG_TX_CLK_EN BIT(19) - #define SPEAR1310_SATA0_CFG_RX_CLK_EN BIT(18) - #define SPEAR1310_SATA0_CFG_POWERUP_RESET BIT(17) - #define SPEAR1310_SATA0_CFG_PM_CLK_EN BIT(16) - #define SPEAR1310_PCIE2_CFG_DEVICE_PRESENT BIT(11) - #define SPEAR1310_PCIE2_CFG_POWERUP_RESET BIT(10) - #define SPEAR1310_PCIE2_CFG_CORE_CLK_EN BIT(9) - #define SPEAR1310_PCIE2_CFG_AUX_CLK_EN BIT(8) - #define SPEAR1310_PCIE1_CFG_DEVICE_PRESENT BIT(7) - #define SPEAR1310_PCIE1_CFG_POWERUP_RESET BIT(6) - #define SPEAR1310_PCIE1_CFG_CORE_CLK_EN BIT(5) - #define SPEAR1310_PCIE1_CFG_AUX_CLK_EN BIT(4) - #define SPEAR1310_PCIE0_CFG_DEVICE_PRESENT BIT(3) - #define SPEAR1310_PCIE0_CFG_POWERUP_RESET BIT(2) - #define SPEAR1310_PCIE0_CFG_CORE_CLK_EN BIT(1) - #define SPEAR1310_PCIE0_CFG_AUX_CLK_EN BIT(0) - - #define SPEAR1310_PCIE_CFG_MASK(x) ((0xF << (x * 4)) | BIT((x + 29))) - #define SPEAR1310_SATA_CFG_MASK(x) ((0xF << (x * 4 + 16)) | \ - BIT((x + 29))) - #define SPEAR1310_PCIE_CFG_VAL(x) \ - (SPEAR1310_PCIE_SATA##x##_SEL_PCIE | \ - SPEAR1310_PCIE##x##_CFG_AUX_CLK_EN | \ - SPEAR1310_PCIE##x##_CFG_CORE_CLK_EN | \ - SPEAR1310_PCIE##x##_CFG_POWERUP_RESET | \ - SPEAR1310_PCIE##x##_CFG_DEVICE_PRESENT) - #define SPEAR1310_SATA_CFG_VAL(x) \ - (SPEAR1310_PCIE_SATA##x##_SEL_SATA | \ - SPEAR1310_SATA##x##_CFG_PM_CLK_EN | \ - SPEAR1310_SATA##x##_CFG_POWERUP_RESET | \ - SPEAR1310_SATA##x##_CFG_RX_CLK_EN | \ - SPEAR1310_SATA##x##_CFG_TX_CLK_EN) - -#define SPEAR1310_PCIE_MIPHY_CFG_1 0x3A8 - #define SPEAR1310_MIPHY_DUAL_OSC_BYPASS_EXT BIT(31) - #define SPEAR1310_MIPHY_DUAL_CLK_REF_DIV2 BIT(28) - #define SPEAR1310_MIPHY_DUAL_PLL_RATIO_TOP(x) (x << 16) - #define SPEAR1310_MIPHY_SINGLE_OSC_BYPASS_EXT BIT(15) - #define SPEAR1310_MIPHY_SINGLE_CLK_REF_DIV2 BIT(12) - #define SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(x) (x << 0) - #define SPEAR1310_PCIE_SATA_MIPHY_CFG_SATA_MASK (0xFFFF) - #define SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE_MASK (0xFFFF << 16) - #define SPEAR1310_PCIE_SATA_MIPHY_CFG_SATA \ - (SPEAR1310_MIPHY_DUAL_OSC_BYPASS_EXT | \ - SPEAR1310_MIPHY_DUAL_CLK_REF_DIV2 | \ - SPEAR1310_MIPHY_DUAL_PLL_RATIO_TOP(60) | \ - SPEAR1310_MIPHY_SINGLE_OSC_BYPASS_EXT | \ - SPEAR1310_MIPHY_SINGLE_CLK_REF_DIV2 | \ - SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(60)) - #define SPEAR1310_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \ - (SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(120)) - #define SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE \ - (SPEAR1310_MIPHY_DUAL_OSC_BYPASS_EXT | \ - SPEAR1310_MIPHY_DUAL_PLL_RATIO_TOP(25) | \ - SPEAR1310_MIPHY_SINGLE_OSC_BYPASS_EXT | \ - SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(25)) - -#define SPEAR1310_PCIE_MIPHY_CFG_2 0x3AC - -enum spear1310_miphy_mode { - SATA, - PCIE, -}; - -struct spear1310_miphy_priv { - /* instance id of this phy */ - u32 id; - /* phy mode: 0 for SATA 1 for PCIe */ - enum spear1310_miphy_mode mode; - /* regmap for any soc specific misc registers */ - struct regmap *misc; - /* phy struct pointer */ - struct phy *phy; -}; - -static int spear1310_miphy_pcie_init(struct spear1310_miphy_priv *priv) -{ - u32 val; - - regmap_update_bits(priv->misc, SPEAR1310_PCIE_MIPHY_CFG_1, - SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE_MASK, - SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE); - - switch (priv->id) { - case 0: - val = SPEAR1310_PCIE_CFG_VAL(0); - break; - case 1: - val = SPEAR1310_PCIE_CFG_VAL(1); - break; - case 2: - val = SPEAR1310_PCIE_CFG_VAL(2); - break; - default: - return -EINVAL; - } - - regmap_update_bits(priv->misc, SPEAR1310_PCIE_SATA_CFG, - SPEAR1310_PCIE_CFG_MASK(priv->id), val); - - return 0; -} - -static int spear1310_miphy_pcie_exit(struct spear1310_miphy_priv *priv) -{ - regmap_update_bits(priv->misc, SPEAR1310_PCIE_SATA_CFG, - SPEAR1310_PCIE_CFG_MASK(priv->id), 0); - - regmap_update_bits(priv->misc, SPEAR1310_PCIE_MIPHY_CFG_1, - SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE_MASK, 0); - - return 0; -} - -static int spear1310_miphy_init(struct phy *phy) -{ - struct spear1310_miphy_priv *priv = phy_get_drvdata(phy); - int ret = 0; - - if (priv->mode == PCIE) - ret = spear1310_miphy_pcie_init(priv); - - return ret; -} - -static int spear1310_miphy_exit(struct phy *phy) -{ - struct spear1310_miphy_priv *priv = phy_get_drvdata(phy); - int ret = 0; - - if (priv->mode == PCIE) - ret = spear1310_miphy_pcie_exit(priv); - - return ret; -} - -static const struct of_device_id spear1310_miphy_of_match[] = { - { .compatible = "st,spear1310-miphy" }, - { }, -}; -MODULE_DEVICE_TABLE(of, spear1310_miphy_of_match); - -static struct phy_ops spear1310_miphy_ops = { - .init = spear1310_miphy_init, - .exit = spear1310_miphy_exit, - .owner = THIS_MODULE, -}; - -static struct phy *spear1310_miphy_xlate(struct device *dev, - struct of_phandle_args *args) -{ - struct spear1310_miphy_priv *priv = dev_get_drvdata(dev); - - if (args->args_count < 1) { - dev_err(dev, "DT did not pass correct no of args\n"); - return NULL; - } - - priv->mode = args->args[0]; - - if (priv->mode != SATA && priv->mode != PCIE) { - dev_err(dev, "DT did not pass correct phy mode\n"); - return NULL; - } - - return priv->phy; -} - -static int spear1310_miphy_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct spear1310_miphy_priv *priv; - struct phy_provider *phy_provider; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->misc = - syscon_regmap_lookup_by_phandle(dev->of_node, "misc"); - if (IS_ERR(priv->misc)) { - dev_err(dev, "failed to find misc regmap\n"); - return PTR_ERR(priv->misc); - } - - if (of_property_read_u32(dev->of_node, "phy-id", &priv->id)) { - dev_err(dev, "failed to find phy id\n"); - return -EINVAL; - } - - priv->phy = devm_phy_create(dev, NULL, &spear1310_miphy_ops, NULL); - if (IS_ERR(priv->phy)) { - dev_err(dev, "failed to create SATA PCIe PHY\n"); - return PTR_ERR(priv->phy); - } - - dev_set_drvdata(dev, priv); - phy_set_drvdata(priv->phy, priv); - - phy_provider = - devm_of_phy_provider_register(dev, spear1310_miphy_xlate); - if (IS_ERR(phy_provider)) { - dev_err(dev, "failed to register phy provider\n"); - return PTR_ERR(phy_provider); - } - - return 0; -} - -static struct platform_driver spear1310_miphy_driver = { - .probe = spear1310_miphy_probe, - .driver = { - .name = "spear1310-miphy", - .of_match_table = of_match_ptr(spear1310_miphy_of_match), - }, -}; - -module_platform_driver(spear1310_miphy_driver); - -MODULE_DESCRIPTION("ST SPEAR1310-MIPHY driver"); -MODULE_AUTHOR("Pratyush Anand "); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/phy-spear1340-miphy.c b/drivers/phy/phy-spear1340-miphy.c deleted file mode 100644 index 1ecd0945bad3..000000000000 --- a/drivers/phy/phy-spear1340-miphy.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * ST spear1340-miphy driver - * - * Copyright (C) 2014 ST Microelectronics - * Pratyush Anand - * Mohit Kumar - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* SPEAr1340 Registers */ -/* Power Management Registers */ -#define SPEAR1340_PCM_CFG 0x100 - #define SPEAR1340_PCM_CFG_SATA_POWER_EN BIT(11) -#define SPEAR1340_PCM_WKUP_CFG 0x104 -#define SPEAR1340_SWITCH_CTR 0x108 - -#define SPEAR1340_PERIP1_SW_RST 0x318 - #define SPEAR1340_PERIP1_SW_RSATA BIT(12) -#define SPEAR1340_PERIP2_SW_RST 0x31C -#define SPEAR1340_PERIP3_SW_RST 0x320 - -/* PCIE - SATA configuration registers */ -#define SPEAR1340_PCIE_SATA_CFG 0x424 - /* PCIE CFG MASks */ - #define SPEAR1340_PCIE_CFG_DEVICE_PRESENT BIT(11) - #define SPEAR1340_PCIE_CFG_POWERUP_RESET BIT(10) - #define SPEAR1340_PCIE_CFG_CORE_CLK_EN BIT(9) - #define SPEAR1340_PCIE_CFG_AUX_CLK_EN BIT(8) - #define SPEAR1340_SATA_CFG_TX_CLK_EN BIT(4) - #define SPEAR1340_SATA_CFG_RX_CLK_EN BIT(3) - #define SPEAR1340_SATA_CFG_POWERUP_RESET BIT(2) - #define SPEAR1340_SATA_CFG_PM_CLK_EN BIT(1) - #define SPEAR1340_PCIE_SATA_SEL_PCIE (0) - #define SPEAR1340_PCIE_SATA_SEL_SATA (1) - #define SPEAR1340_PCIE_SATA_CFG_MASK 0xF1F - #define SPEAR1340_PCIE_CFG_VAL (SPEAR1340_PCIE_SATA_SEL_PCIE | \ - SPEAR1340_PCIE_CFG_AUX_CLK_EN | \ - SPEAR1340_PCIE_CFG_CORE_CLK_EN | \ - SPEAR1340_PCIE_CFG_POWERUP_RESET | \ - SPEAR1340_PCIE_CFG_DEVICE_PRESENT) - #define SPEAR1340_SATA_CFG_VAL (SPEAR1340_PCIE_SATA_SEL_SATA | \ - SPEAR1340_SATA_CFG_PM_CLK_EN | \ - SPEAR1340_SATA_CFG_POWERUP_RESET | \ - SPEAR1340_SATA_CFG_RX_CLK_EN | \ - SPEAR1340_SATA_CFG_TX_CLK_EN) - -#define SPEAR1340_PCIE_MIPHY_CFG 0x428 - #define SPEAR1340_MIPHY_OSC_BYPASS_EXT BIT(31) - #define SPEAR1340_MIPHY_CLK_REF_DIV2 BIT(27) - #define SPEAR1340_MIPHY_CLK_REF_DIV4 (2 << 27) - #define SPEAR1340_MIPHY_CLK_REF_DIV8 (3 << 27) - #define SPEAR1340_MIPHY_PLL_RATIO_TOP(x) (x << 0) - #define SPEAR1340_PCIE_MIPHY_CFG_MASK 0xF80000FF - #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA \ - (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \ - SPEAR1340_MIPHY_CLK_REF_DIV2 | \ - SPEAR1340_MIPHY_PLL_RATIO_TOP(60)) - #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \ - (SPEAR1340_MIPHY_PLL_RATIO_TOP(120)) - #define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \ - (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \ - SPEAR1340_MIPHY_PLL_RATIO_TOP(25)) - -enum spear1340_miphy_mode { - SATA, - PCIE, -}; - -struct spear1340_miphy_priv { - /* phy mode: 0 for SATA 1 for PCIe */ - enum spear1340_miphy_mode mode; - /* regmap for any soc specific misc registers */ - struct regmap *misc; - /* phy struct pointer */ - struct phy *phy; -}; - -static int spear1340_miphy_sata_init(struct spear1340_miphy_priv *priv) -{ - regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG, - SPEAR1340_PCIE_SATA_CFG_MASK, - SPEAR1340_SATA_CFG_VAL); - regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG, - SPEAR1340_PCIE_MIPHY_CFG_MASK, - SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK); - /* Switch on sata power domain */ - regmap_update_bits(priv->misc, SPEAR1340_PCM_CFG, - SPEAR1340_PCM_CFG_SATA_POWER_EN, - SPEAR1340_PCM_CFG_SATA_POWER_EN); - /* Wait for SATA power domain on */ - msleep(20); - - /* Disable PCIE SATA Controller reset */ - regmap_update_bits(priv->misc, SPEAR1340_PERIP1_SW_RST, - SPEAR1340_PERIP1_SW_RSATA, 0); - /* Wait for SATA reset de-assert completion */ - msleep(20); - - return 0; -} - -static int spear1340_miphy_sata_exit(struct spear1340_miphy_priv *priv) -{ - regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG, - SPEAR1340_PCIE_SATA_CFG_MASK, 0); - regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG, - SPEAR1340_PCIE_MIPHY_CFG_MASK, 0); - - /* Enable PCIE SATA Controller reset */ - regmap_update_bits(priv->misc, SPEAR1340_PERIP1_SW_RST, - SPEAR1340_PERIP1_SW_RSATA, - SPEAR1340_PERIP1_SW_RSATA); - /* Wait for SATA power domain off */ - msleep(20); - /* Switch off sata power domain */ - regmap_update_bits(priv->misc, SPEAR1340_PCM_CFG, - SPEAR1340_PCM_CFG_SATA_POWER_EN, 0); - /* Wait for SATA reset assert completion */ - msleep(20); - - return 0; -} - -static int spear1340_miphy_pcie_init(struct spear1340_miphy_priv *priv) -{ - regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG, - SPEAR1340_PCIE_MIPHY_CFG_MASK, - SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE); - regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG, - SPEAR1340_PCIE_SATA_CFG_MASK, - SPEAR1340_PCIE_CFG_VAL); - - return 0; -} - -static int spear1340_miphy_pcie_exit(struct spear1340_miphy_priv *priv) -{ - regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG, - SPEAR1340_PCIE_MIPHY_CFG_MASK, 0); - regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG, - SPEAR1340_PCIE_SATA_CFG_MASK, 0); - - return 0; -} - -static int spear1340_miphy_init(struct phy *phy) -{ - struct spear1340_miphy_priv *priv = phy_get_drvdata(phy); - int ret = 0; - - if (priv->mode == SATA) - ret = spear1340_miphy_sata_init(priv); - else if (priv->mode == PCIE) - ret = spear1340_miphy_pcie_init(priv); - - return ret; -} - -static int spear1340_miphy_exit(struct phy *phy) -{ - struct spear1340_miphy_priv *priv = phy_get_drvdata(phy); - int ret = 0; - - if (priv->mode == SATA) - ret = spear1340_miphy_sata_exit(priv); - else if (priv->mode == PCIE) - ret = spear1340_miphy_pcie_exit(priv); - - return ret; -} - -static const struct of_device_id spear1340_miphy_of_match[] = { - { .compatible = "st,spear1340-miphy" }, - { }, -}; -MODULE_DEVICE_TABLE(of, spear1340_miphy_of_match); - -static struct phy_ops spear1340_miphy_ops = { - .init = spear1340_miphy_init, - .exit = spear1340_miphy_exit, - .owner = THIS_MODULE, -}; - -#ifdef CONFIG_PM_SLEEP -static int spear1340_miphy_suspend(struct device *dev) -{ - struct spear1340_miphy_priv *priv = dev_get_drvdata(dev); - int ret = 0; - - if (priv->mode == SATA) - ret = spear1340_miphy_sata_exit(priv); - - return ret; -} - -static int spear1340_miphy_resume(struct device *dev) -{ - struct spear1340_miphy_priv *priv = dev_get_drvdata(dev); - int ret = 0; - - if (priv->mode == SATA) - ret = spear1340_miphy_sata_init(priv); - - return ret; -} -#endif - -static SIMPLE_DEV_PM_OPS(spear1340_miphy_pm_ops, spear1340_miphy_suspend, - spear1340_miphy_resume); - -static struct phy *spear1340_miphy_xlate(struct device *dev, - struct of_phandle_args *args) -{ - struct spear1340_miphy_priv *priv = dev_get_drvdata(dev); - - if (args->args_count < 1) { - dev_err(dev, "DT did not pass correct no of args\n"); - return NULL; - } - - priv->mode = args->args[0]; - - if (priv->mode != SATA && priv->mode != PCIE) { - dev_err(dev, "DT did not pass correct phy mode\n"); - return NULL; - } - - return priv->phy; -} - -static int spear1340_miphy_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct spear1340_miphy_priv *priv; - struct phy_provider *phy_provider; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->misc = - syscon_regmap_lookup_by_phandle(dev->of_node, "misc"); - if (IS_ERR(priv->misc)) { - dev_err(dev, "failed to find misc regmap\n"); - return PTR_ERR(priv->misc); - } - - priv->phy = devm_phy_create(dev, NULL, &spear1340_miphy_ops, NULL); - if (IS_ERR(priv->phy)) { - dev_err(dev, "failed to create SATA PCIe PHY\n"); - return PTR_ERR(priv->phy); - } - - dev_set_drvdata(dev, priv); - phy_set_drvdata(priv->phy, priv); - - phy_provider = - devm_of_phy_provider_register(dev, spear1340_miphy_xlate); - if (IS_ERR(phy_provider)) { - dev_err(dev, "failed to register phy provider\n"); - return PTR_ERR(phy_provider); - } - - return 0; -} - -static struct platform_driver spear1340_miphy_driver = { - .probe = spear1340_miphy_probe, - .driver = { - .name = "spear1340-miphy", - .pm = &spear1340_miphy_pm_ops, - .of_match_table = of_match_ptr(spear1340_miphy_of_match), - }, -}; - -module_platform_driver(spear1340_miphy_driver); - -MODULE_DESCRIPTION("ST SPEAR1340-MIPHY driver"); -MODULE_AUTHOR("Pratyush Anand "); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/phy-stih407-usb.c b/drivers/phy/phy-stih407-usb.c deleted file mode 100644 index 42428d4181ea..000000000000 --- a/drivers/phy/phy-stih407-usb.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2014 STMicroelectronics - * - * STMicroelectronics Generic PHY driver for STiH407 USB2. - * - * Author: Giuseppe Cavallaro - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, as - * published by the Free Software Foundation. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Default PHY_SEL and REFCLKSEL configuration */ -#define STIH407_USB_PICOPHY_CTRL_PORT_CONF 0x6 -#define STIH407_USB_PICOPHY_CTRL_PORT_MASK 0x1f - -/* ports parameters overriding */ -#define STIH407_USB_PICOPHY_PARAM_DEF 0x39a4dc -#define STIH407_USB_PICOPHY_PARAM_MASK 0xffffffff - -struct stih407_usb2_picophy { - struct phy *phy; - struct regmap *regmap; - struct device *dev; - struct reset_control *rstc; - struct reset_control *rstport; - int ctrl; - int param; -}; - -static int stih407_usb2_pico_ctrl(struct stih407_usb2_picophy *phy_dev) -{ - reset_control_deassert(phy_dev->rstc); - - return regmap_update_bits(phy_dev->regmap, phy_dev->ctrl, - STIH407_USB_PICOPHY_CTRL_PORT_MASK, - STIH407_USB_PICOPHY_CTRL_PORT_CONF); -} - -static int stih407_usb2_init_port(struct phy *phy) -{ - int ret; - struct stih407_usb2_picophy *phy_dev = phy_get_drvdata(phy); - - stih407_usb2_pico_ctrl(phy_dev); - - ret = regmap_update_bits(phy_dev->regmap, - phy_dev->param, - STIH407_USB_PICOPHY_PARAM_MASK, - STIH407_USB_PICOPHY_PARAM_DEF); - if (ret) - return ret; - - return reset_control_deassert(phy_dev->rstport); -} - -static int stih407_usb2_exit_port(struct phy *phy) -{ - struct stih407_usb2_picophy *phy_dev = phy_get_drvdata(phy); - - /* - * Only port reset is asserted, phy global reset is kept untouched - * as other ports may still be active. When all ports are in reset - * state, assumption is made that power will be cut off on the phy, in - * case of suspend for instance. Theoretically, asserting individual - * reset (like here) or global reset should be equivalent. - */ - return reset_control_assert(phy_dev->rstport); -} - -static const struct phy_ops stih407_usb2_picophy_data = { - .init = stih407_usb2_init_port, - .exit = stih407_usb2_exit_port, - .owner = THIS_MODULE, -}; - -static int stih407_usb2_picophy_probe(struct platform_device *pdev) -{ - struct stih407_usb2_picophy *phy_dev; - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - struct phy_provider *phy_provider; - struct phy *phy; - struct resource *res; - - phy_dev = devm_kzalloc(dev, sizeof(*phy_dev), GFP_KERNEL); - if (!phy_dev) - return -ENOMEM; - - phy_dev->dev = dev; - dev_set_drvdata(dev, phy_dev); - - phy_dev->rstc = devm_reset_control_get(dev, "global"); - if (IS_ERR(phy_dev->rstc)) { - dev_err(dev, "failed to ctrl picoPHY reset\n"); - return PTR_ERR(phy_dev->rstc); - } - - phy_dev->rstport = devm_reset_control_get(dev, "port"); - if (IS_ERR(phy_dev->rstport)) { - dev_err(dev, "failed to ctrl picoPHY reset\n"); - return PTR_ERR(phy_dev->rstport); - } - - /* Reset port by default: only deassert it in phy init */ - reset_control_assert(phy_dev->rstport); - - phy_dev->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg"); - if (IS_ERR(phy_dev->regmap)) { - dev_err(dev, "No syscfg phandle specified\n"); - return PTR_ERR(phy_dev->regmap); - } - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl"); - if (!res) { - dev_err(dev, "No ctrl reg found\n"); - return -ENXIO; - } - phy_dev->ctrl = res->start; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "param"); - if (!res) { - dev_err(dev, "No param reg found\n"); - return -ENXIO; - } - phy_dev->param = res->start; - - phy = devm_phy_create(dev, NULL, &stih407_usb2_picophy_data, NULL); - if (IS_ERR(phy)) { - dev_err(dev, "failed to create Display Port PHY\n"); - return PTR_ERR(phy); - } - - phy_dev->phy = phy; - phy_set_drvdata(phy, phy_dev); - - phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); - if (IS_ERR(phy_provider)) - return PTR_ERR(phy_provider); - - dev_info(dev, "STiH407 USB Generic picoPHY driver probed!"); - - return 0; -} - -static const struct of_device_id stih407_usb2_picophy_of_match[] = { - { .compatible = "st,stih407-usb2-phy" }, - { /*sentinel */ }, -}; - -MODULE_DEVICE_TABLE(of, stih407_usb2_picophy_of_match); - -static struct platform_driver stih407_usb2_picophy_driver = { - .probe = stih407_usb2_picophy_probe, - .driver = { - .name = "stih407-usb-genphy", - .of_match_table = stih407_usb2_picophy_of_match, - } -}; - -module_platform_driver(stih407_usb2_picophy_driver); - -MODULE_AUTHOR("Giuseppe Cavallaro "); -MODULE_DESCRIPTION("STMicroelectronics Generic picoPHY driver for STiH407"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/phy-stih41x-usb.c b/drivers/phy/phy-stih41x-usb.c deleted file mode 100644 index 9f16cb8e01f4..000000000000 --- a/drivers/phy/phy-stih41x-usb.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (C) 2014 STMicroelectronics - * - * STMicroelectronics PHY driver for STiH41x USB. - * - * Author: Maxime Coquelin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SYSCFG332 0x80 -#define SYSCFG2520 0x820 - -/** - * struct stih41x_usb_cfg - SoC specific PHY register mapping - * @syscfg: Offset in syscfg registers bank - * @cfg_mask: Bits mask for PHY configuration - * @cfg: Static configuration value for PHY - * @oscok: Notify the PHY oscillator clock is ready - * Setting this bit enable the PHY - */ -struct stih41x_usb_cfg { - u32 syscfg; - u32 cfg_mask; - u32 cfg; - u32 oscok; -}; - -/** - * struct stih41x_usb_phy - Private data for the PHY - * @dev: device for this controller - * @regmap: Syscfg registers bank in which PHY is configured - * @cfg: SoC specific PHY register mapping - * @clk: Oscillator used by the PHY - */ -struct stih41x_usb_phy { - struct device *dev; - struct regmap *regmap; - const struct stih41x_usb_cfg *cfg; - struct clk *clk; -}; - -static struct stih41x_usb_cfg stih415_usb_phy_cfg = { - .syscfg = SYSCFG332, - .cfg_mask = 0x3f, - .cfg = 0x38, - .oscok = BIT(6), -}; - -static struct stih41x_usb_cfg stih416_usb_phy_cfg = { - .syscfg = SYSCFG2520, - .cfg_mask = 0x33f, - .cfg = 0x238, - .oscok = BIT(6), -}; - -static int stih41x_usb_phy_init(struct phy *phy) -{ - struct stih41x_usb_phy *phy_dev = phy_get_drvdata(phy); - - return regmap_update_bits(phy_dev->regmap, phy_dev->cfg->syscfg, - phy_dev->cfg->cfg_mask, phy_dev->cfg->cfg); -} - -static int stih41x_usb_phy_power_on(struct phy *phy) -{ - struct stih41x_usb_phy *phy_dev = phy_get_drvdata(phy); - int ret; - - ret = clk_prepare_enable(phy_dev->clk); - if (ret) { - dev_err(phy_dev->dev, "Failed to enable osc_phy clock\n"); - return ret; - } - - return regmap_update_bits(phy_dev->regmap, phy_dev->cfg->syscfg, - phy_dev->cfg->oscok, phy_dev->cfg->oscok); -} - -static int stih41x_usb_phy_power_off(struct phy *phy) -{ - struct stih41x_usb_phy *phy_dev = phy_get_drvdata(phy); - int ret; - - ret = regmap_update_bits(phy_dev->regmap, phy_dev->cfg->syscfg, - phy_dev->cfg->oscok, 0); - if (ret) { - dev_err(phy_dev->dev, "Failed to clear oscok bit\n"); - return ret; - } - - clk_disable_unprepare(phy_dev->clk); - - return 0; -} - -static struct phy_ops stih41x_usb_phy_ops = { - .init = stih41x_usb_phy_init, - .power_on = stih41x_usb_phy_power_on, - .power_off = stih41x_usb_phy_power_off, - .owner = THIS_MODULE, -}; - -static const struct of_device_id stih41x_usb_phy_of_match[]; - -static int stih41x_usb_phy_probe(struct platform_device *pdev) -{ - struct device_node *np = pdev->dev.of_node; - const struct of_device_id *match; - struct stih41x_usb_phy *phy_dev; - struct device *dev = &pdev->dev; - struct phy_provider *phy_provider; - struct phy *phy; - - phy_dev = devm_kzalloc(dev, sizeof(*phy_dev), GFP_KERNEL); - if (!phy_dev) - return -ENOMEM; - - match = of_match_device(stih41x_usb_phy_of_match, &pdev->dev); - if (!match) - return -ENODEV; - - phy_dev->cfg = match->data; - - phy_dev->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg"); - if (IS_ERR(phy_dev->regmap)) { - dev_err(dev, "No syscfg phandle specified\n"); - return PTR_ERR(phy_dev->regmap); - } - - phy_dev->clk = devm_clk_get(dev, "osc_phy"); - if (IS_ERR(phy_dev->clk)) { - dev_err(dev, "osc_phy clk not found\n"); - return PTR_ERR(phy_dev->clk); - } - - phy = devm_phy_create(dev, NULL, &stih41x_usb_phy_ops, NULL); - - if (IS_ERR(phy)) { - dev_err(dev, "failed to create phy\n"); - return PTR_ERR(phy); - } - - phy_dev->dev = dev; - - phy_set_drvdata(phy, phy_dev); - - phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); - if (IS_ERR(phy_provider)) - return PTR_ERR(phy_provider); - - return 0; -} - -static const struct of_device_id stih41x_usb_phy_of_match[] = { - { .compatible = "st,stih415-usb-phy", .data = &stih415_usb_phy_cfg }, - { .compatible = "st,stih416-usb-phy", .data = &stih416_usb_phy_cfg }, - { /* sentinel */ }, -}; -MODULE_DEVICE_TABLE(of, stih41x_usb_phy_of_match); - -static struct platform_driver stih41x_usb_phy_driver = { - .probe = stih41x_usb_phy_probe, - .driver = { - .name = "stih41x-usb-phy", - .of_match_table = stih41x_usb_phy_of_match, - } -}; -module_platform_driver(stih41x_usb_phy_driver); - -MODULE_AUTHOR("Maxime Coquelin "); -MODULE_DESCRIPTION("STMicroelectronics USB PHY driver for STiH41x series"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c deleted file mode 100644 index 0baf5efc8a40..000000000000 --- a/drivers/phy/phy-sun4i-usb.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Allwinner sun4i USB phy driver - * - * Copyright (C) 2014 Hans de Goede - * - * Based on code from - * Allwinner Technology Co., Ltd. - * - * Modelled after: Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY driver - * Copyright (C) 2013 Samsung Electronics Co., Ltd. - * Author: Sylwester Nawrocki - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define REG_ISCR 0x00 -#define REG_PHYCTL 0x04 -#define REG_PHYBIST 0x08 -#define REG_PHYTUNE 0x0c - -#define PHYCTL_DATA BIT(7) - -#define SUNXI_AHB_ICHR8_EN BIT(10) -#define SUNXI_AHB_INCR4_BURST_EN BIT(9) -#define SUNXI_AHB_INCRX_ALIGN_EN BIT(8) -#define SUNXI_ULPI_BYPASS_EN BIT(0) - -/* Common Control Bits for Both PHYs */ -#define PHY_PLL_BW 0x03 -#define PHY_RES45_CAL_EN 0x0c - -/* Private Control Bits for Each PHY */ -#define PHY_TX_AMPLITUDE_TUNE 0x20 -#define PHY_TX_SLEWRATE_TUNE 0x22 -#define PHY_VBUSVALID_TH_SEL 0x25 -#define PHY_PULLUP_RES_SEL 0x27 -#define PHY_OTG_FUNC_EN 0x28 -#define PHY_VBUS_DET_EN 0x29 -#define PHY_DISCON_TH_SEL 0x2a - -#define MAX_PHYS 3 - -struct sun4i_usb_phy_data { - void __iomem *base; - struct mutex mutex; - int num_phys; - u32 disc_thresh; - struct sun4i_usb_phy { - struct phy *phy; - void __iomem *pmu; - struct regulator *vbus; - struct reset_control *reset; - struct clk *clk; - int index; - } phys[MAX_PHYS]; -}; - -#define to_sun4i_usb_phy_data(phy) \ - container_of((phy), struct sun4i_usb_phy_data, phys[(phy)->index]) - -static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data, - int len) -{ - struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy); - u32 temp, usbc_bit = BIT(phy->index * 2); - int i; - - mutex_lock(&phy_data->mutex); - - for (i = 0; i < len; i++) { - temp = readl(phy_data->base + REG_PHYCTL); - - /* clear the address portion */ - temp &= ~(0xff << 8); - - /* set the address */ - temp |= ((addr + i) << 8); - writel(temp, phy_data->base + REG_PHYCTL); - - /* set the data bit and clear usbc bit*/ - temp = readb(phy_data->base + REG_PHYCTL); - if (data & 0x1) - temp |= PHYCTL_DATA; - else - temp &= ~PHYCTL_DATA; - temp &= ~usbc_bit; - writeb(temp, phy_data->base + REG_PHYCTL); - - /* pulse usbc_bit */ - temp = readb(phy_data->base + REG_PHYCTL); - temp |= usbc_bit; - writeb(temp, phy_data->base + REG_PHYCTL); - - temp = readb(phy_data->base + REG_PHYCTL); - temp &= ~usbc_bit; - writeb(temp, phy_data->base + REG_PHYCTL); - - data >>= 1; - } - mutex_unlock(&phy_data->mutex); -} - -static void sun4i_usb_phy_passby(struct sun4i_usb_phy *phy, int enable) -{ - u32 bits, reg_value; - - if (!phy->pmu) - return; - - bits = SUNXI_AHB_ICHR8_EN | SUNXI_AHB_INCR4_BURST_EN | - SUNXI_AHB_INCRX_ALIGN_EN | SUNXI_ULPI_BYPASS_EN; - - reg_value = readl(phy->pmu); - - if (enable) - reg_value |= bits; - else - reg_value &= ~bits; - - writel(reg_value, phy->pmu); -} - -static int sun4i_usb_phy_init(struct phy *_phy) -{ - struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); - struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy); - int ret; - - ret = clk_prepare_enable(phy->clk); - if (ret) - return ret; - - ret = reset_control_deassert(phy->reset); - if (ret) { - clk_disable_unprepare(phy->clk); - return ret; - } - - /* Adjust PHY's magnitude and rate */ - sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5); - - /* Disconnect threshold adjustment */ - sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, data->disc_thresh, 2); - - sun4i_usb_phy_passby(phy, 1); - - return 0; -} - -static int sun4i_usb_phy_exit(struct phy *_phy) -{ - struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); - - sun4i_usb_phy_passby(phy, 0); - reset_control_assert(phy->reset); - clk_disable_unprepare(phy->clk); - - return 0; -} - -static int sun4i_usb_phy_power_on(struct phy *_phy) -{ - struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); - int ret = 0; - - if (phy->vbus) - ret = regulator_enable(phy->vbus); - - return ret; -} - -static int sun4i_usb_phy_power_off(struct phy *_phy) -{ - struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); - - if (phy->vbus) - regulator_disable(phy->vbus); - - return 0; -} - -static struct phy_ops sun4i_usb_phy_ops = { - .init = sun4i_usb_phy_init, - .exit = sun4i_usb_phy_exit, - .power_on = sun4i_usb_phy_power_on, - .power_off = sun4i_usb_phy_power_off, - .owner = THIS_MODULE, -}; - -static struct phy *sun4i_usb_phy_xlate(struct device *dev, - struct of_phandle_args *args) -{ - struct sun4i_usb_phy_data *data = dev_get_drvdata(dev); - - if (WARN_ON(args->args[0] == 0 || args->args[0] >= data->num_phys)) - return ERR_PTR(-ENODEV); - - return data->phys[args->args[0]].phy; -} - -static int sun4i_usb_phy_probe(struct platform_device *pdev) -{ - struct sun4i_usb_phy_data *data; - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - struct phy_provider *phy_provider; - bool dedicated_clocks; - struct resource *res; - int i; - - data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - mutex_init(&data->mutex); - - if (of_device_is_compatible(np, "allwinner,sun5i-a13-usb-phy")) - data->num_phys = 2; - else - data->num_phys = 3; - - if (of_device_is_compatible(np, "allwinner,sun4i-a10-usb-phy")) - data->disc_thresh = 3; - else - data->disc_thresh = 2; - - if (of_device_is_compatible(np, "allwinner,sun6i-a31-usb-phy")) - dedicated_clocks = true; - else - dedicated_clocks = false; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_ctrl"); - data->base = devm_ioremap_resource(dev, res); - if (IS_ERR(data->base)) - return PTR_ERR(data->base); - - /* Skip 0, 0 is the phy for otg which is not yet supported. */ - for (i = 1; i < data->num_phys; i++) { - struct sun4i_usb_phy *phy = data->phys + i; - char name[16]; - - snprintf(name, sizeof(name), "usb%d_vbus", i); - phy->vbus = devm_regulator_get_optional(dev, name); - if (IS_ERR(phy->vbus)) { - if (PTR_ERR(phy->vbus) == -EPROBE_DEFER) - return -EPROBE_DEFER; - phy->vbus = NULL; - } - - if (dedicated_clocks) - snprintf(name, sizeof(name), "usb%d_phy", i); - else - strlcpy(name, "usb_phy", sizeof(name)); - - phy->clk = devm_clk_get(dev, name); - if (IS_ERR(phy->clk)) { - dev_err(dev, "failed to get clock %s\n", name); - return PTR_ERR(phy->clk); - } - - snprintf(name, sizeof(name), "usb%d_reset", i); - phy->reset = devm_reset_control_get(dev, name); - if (IS_ERR(phy->reset)) { - dev_err(dev, "failed to get reset %s\n", name); - return PTR_ERR(phy->reset); - } - - if (i) { /* No pmu for usbc0 */ - snprintf(name, sizeof(name), "pmu%d", i); - res = platform_get_resource_byname(pdev, - IORESOURCE_MEM, name); - phy->pmu = devm_ioremap_resource(dev, res); - if (IS_ERR(phy->pmu)) - return PTR_ERR(phy->pmu); - } - - phy->phy = devm_phy_create(dev, NULL, &sun4i_usb_phy_ops, NULL); - if (IS_ERR(phy->phy)) { - dev_err(dev, "failed to create PHY %d\n", i); - return PTR_ERR(phy->phy); - } - - phy->index = i; - phy_set_drvdata(phy->phy, &data->phys[i]); - } - - dev_set_drvdata(dev, data); - phy_provider = devm_of_phy_provider_register(dev, sun4i_usb_phy_xlate); - - return PTR_ERR_OR_ZERO(phy_provider); -} - -static const struct of_device_id sun4i_usb_phy_of_match[] = { - { .compatible = "allwinner,sun4i-a10-usb-phy" }, - { .compatible = "allwinner,sun5i-a13-usb-phy" }, - { .compatible = "allwinner,sun6i-a31-usb-phy" }, - { .compatible = "allwinner,sun7i-a20-usb-phy" }, - { }, -}; -MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match); - -static struct platform_driver sun4i_usb_phy_driver = { - .probe = sun4i_usb_phy_probe, - .driver = { - .of_match_table = sun4i_usb_phy_of_match, - .name = "sun4i-usb-phy", - } -}; -module_platform_driver(sun4i_usb_phy_driver); - -MODULE_DESCRIPTION("Allwinner sun4i USB phy driver"); -MODULE_AUTHOR("Hans de Goede "); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c deleted file mode 100644 index ab1e22d9a1e8..000000000000 --- a/drivers/phy/phy-ti-pipe3.c +++ /dev/null @@ -1,531 +0,0 @@ -/* - * phy-ti-pipe3 - PIPE3 PHY driver. - * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Author: Kishon Vijay Abraham I - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PLL_STATUS 0x00000004 -#define PLL_GO 0x00000008 -#define PLL_CONFIGURATION1 0x0000000C -#define PLL_CONFIGURATION2 0x00000010 -#define PLL_CONFIGURATION3 0x00000014 -#define PLL_CONFIGURATION4 0x00000020 - -#define PLL_REGM_MASK 0x001FFE00 -#define PLL_REGM_SHIFT 0x9 -#define PLL_REGM_F_MASK 0x0003FFFF -#define PLL_REGM_F_SHIFT 0x0 -#define PLL_REGN_MASK 0x000001FE -#define PLL_REGN_SHIFT 0x1 -#define PLL_SELFREQDCO_MASK 0x0000000E -#define PLL_SELFREQDCO_SHIFT 0x1 -#define PLL_SD_MASK 0x0003FC00 -#define PLL_SD_SHIFT 10 -#define SET_PLL_GO 0x1 -#define PLL_LDOPWDN BIT(15) -#define PLL_TICOPWDN BIT(16) -#define PLL_LOCK 0x2 -#define PLL_IDLE 0x1 - -/* - * This is an Empirical value that works, need to confirm the actual - * value required for the PIPE3PHY_PLL_CONFIGURATION2.PLL_IDLE status - * to be correctly reflected in the PIPE3PHY_PLL_STATUS register. - */ -#define PLL_IDLE_TIME 100 /* in milliseconds */ -#define PLL_LOCK_TIME 100 /* in milliseconds */ - -struct pipe3_dpll_params { - u16 m; - u8 n; - u8 freq:3; - u8 sd; - u32 mf; -}; - -struct pipe3_dpll_map { - unsigned long rate; - struct pipe3_dpll_params params; -}; - -struct ti_pipe3 { - void __iomem *pll_ctrl_base; - struct device *dev; - struct device *control_dev; - struct clk *wkupclk; - struct clk *sys_clk; - struct clk *refclk; - struct clk *div_clk; - struct pipe3_dpll_map *dpll_map; - u8 id; -}; - -static struct pipe3_dpll_map dpll_map_usb[] = { - {12000000, {1250, 5, 4, 20, 0} }, /* 12 MHz */ - {16800000, {3125, 20, 4, 20, 0} }, /* 16.8 MHz */ - {19200000, {1172, 8, 4, 20, 65537} }, /* 19.2 MHz */ - {20000000, {1000, 7, 4, 10, 0} }, /* 20 MHz */ - {26000000, {1250, 12, 4, 20, 0} }, /* 26 MHz */ - {38400000, {3125, 47, 4, 20, 92843} }, /* 38.4 MHz */ - { }, /* Terminator */ -}; - -static struct pipe3_dpll_map dpll_map_sata[] = { - {12000000, {1000, 7, 4, 6, 0} }, /* 12 MHz */ - {16800000, {714, 7, 4, 6, 0} }, /* 16.8 MHz */ - {19200000, {625, 7, 4, 6, 0} }, /* 19.2 MHz */ - {20000000, {600, 7, 4, 6, 0} }, /* 20 MHz */ - {26000000, {461, 7, 4, 6, 0} }, /* 26 MHz */ - {38400000, {312, 7, 4, 6, 0} }, /* 38.4 MHz */ - { }, /* Terminator */ -}; - -static inline u32 ti_pipe3_readl(void __iomem *addr, unsigned offset) -{ - return __raw_readl(addr + offset); -} - -static inline void ti_pipe3_writel(void __iomem *addr, unsigned offset, - u32 data) -{ - __raw_writel(data, addr + offset); -} - -static struct pipe3_dpll_params *ti_pipe3_get_dpll_params(struct ti_pipe3 *phy) -{ - unsigned long rate; - struct pipe3_dpll_map *dpll_map = phy->dpll_map; - - rate = clk_get_rate(phy->sys_clk); - - for (; dpll_map->rate; dpll_map++) { - if (rate == dpll_map->rate) - return &dpll_map->params; - } - - dev_err(phy->dev, "No DPLL configuration for %lu Hz SYS CLK\n", rate); - - return NULL; -} - -static int ti_pipe3_power_off(struct phy *x) -{ - struct ti_pipe3 *phy = phy_get_drvdata(x); - - omap_control_phy_power(phy->control_dev, 0); - - return 0; -} - -static int ti_pipe3_power_on(struct phy *x) -{ - struct ti_pipe3 *phy = phy_get_drvdata(x); - - omap_control_phy_power(phy->control_dev, 1); - - return 0; -} - -static int ti_pipe3_dpll_wait_lock(struct ti_pipe3 *phy) -{ - u32 val; - unsigned long timeout; - - timeout = jiffies + msecs_to_jiffies(PLL_LOCK_TIME); - do { - cpu_relax(); - val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); - if (val & PLL_LOCK) - break; - } while (!time_after(jiffies, timeout)); - - if (!(val & PLL_LOCK)) { - dev_err(phy->dev, "DPLL failed to lock\n"); - return -EBUSY; - } - - return 0; -} - -static int ti_pipe3_dpll_program(struct ti_pipe3 *phy) -{ - u32 val; - struct pipe3_dpll_params *dpll_params; - - dpll_params = ti_pipe3_get_dpll_params(phy); - if (!dpll_params) - return -EINVAL; - - val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); - val &= ~PLL_REGN_MASK; - val |= dpll_params->n << PLL_REGN_SHIFT; - ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); - - val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); - val &= ~PLL_SELFREQDCO_MASK; - val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT; - ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); - - val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); - val &= ~PLL_REGM_MASK; - val |= dpll_params->m << PLL_REGM_SHIFT; - ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); - - val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4); - val &= ~PLL_REGM_F_MASK; - val |= dpll_params->mf << PLL_REGM_F_SHIFT; - ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val); - - val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3); - val &= ~PLL_SD_MASK; - val |= dpll_params->sd << PLL_SD_SHIFT; - ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val); - - ti_pipe3_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO); - - return ti_pipe3_dpll_wait_lock(phy); -} - -static int ti_pipe3_init(struct phy *x) -{ - struct ti_pipe3 *phy = phy_get_drvdata(x); - u32 val; - int ret = 0; - - if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) { - omap_control_pcie_pcs(phy->control_dev, phy->id, 0xF1); - return 0; - } - - /* Bring it out of IDLE if it is IDLE */ - val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); - if (val & PLL_IDLE) { - val &= ~PLL_IDLE; - ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); - ret = ti_pipe3_dpll_wait_lock(phy); - } - - /* Program the DPLL only if not locked */ - val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); - if (!(val & PLL_LOCK)) - if (ti_pipe3_dpll_program(phy)) - return -EINVAL; - - return ret; -} - -static int ti_pipe3_exit(struct phy *x) -{ - struct ti_pipe3 *phy = phy_get_drvdata(x); - u32 val; - unsigned long timeout; - - /* SATA DPLL can't be powered down due to Errata i783 and PCIe - * does not have internal DPLL - */ - if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-sata") || - of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) - return 0; - - /* Put DPLL in IDLE mode */ - val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); - val |= PLL_IDLE; - ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); - - /* wait for LDO and Oscillator to power down */ - timeout = jiffies + msecs_to_jiffies(PLL_IDLE_TIME); - do { - cpu_relax(); - val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); - if ((val & PLL_TICOPWDN) && (val & PLL_LDOPWDN)) - break; - } while (!time_after(jiffies, timeout)); - - if (!(val & PLL_TICOPWDN) || !(val & PLL_LDOPWDN)) { - dev_err(phy->dev, "Failed to power down: PLL_STATUS 0x%x\n", - val); - return -EBUSY; - } - - return 0; -} -static struct phy_ops ops = { - .init = ti_pipe3_init, - .exit = ti_pipe3_exit, - .power_on = ti_pipe3_power_on, - .power_off = ti_pipe3_power_off, - .owner = THIS_MODULE, -}; - -#ifdef CONFIG_OF -static const struct of_device_id ti_pipe3_id_table[]; -#endif - -static int ti_pipe3_probe(struct platform_device *pdev) -{ - struct ti_pipe3 *phy; - struct phy *generic_phy; - struct phy_provider *phy_provider; - struct resource *res; - struct device_node *node = pdev->dev.of_node; - struct device_node *control_node; - struct platform_device *control_pdev; - const struct of_device_id *match; - struct clk *clk; - - phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); - if (!phy) - return -ENOMEM; - - phy->dev = &pdev->dev; - - if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { - match = of_match_device(of_match_ptr(ti_pipe3_id_table), - &pdev->dev); - if (!match) - return -EINVAL; - - phy->dpll_map = (struct pipe3_dpll_map *)match->data; - if (!phy->dpll_map) { - dev_err(&pdev->dev, "no DPLL data\n"); - return -EINVAL; - } - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "pll_ctrl"); - phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(phy->pll_ctrl_base)) - return PTR_ERR(phy->pll_ctrl_base); - - phy->sys_clk = devm_clk_get(phy->dev, "sysclk"); - if (IS_ERR(phy->sys_clk)) { - dev_err(&pdev->dev, "unable to get sysclk\n"); - return -EINVAL; - } - } - - if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) { - phy->wkupclk = devm_clk_get(phy->dev, "wkupclk"); - if (IS_ERR(phy->wkupclk)) { - dev_err(&pdev->dev, "unable to get wkupclk\n"); - return PTR_ERR(phy->wkupclk); - } - - phy->refclk = devm_clk_get(phy->dev, "refclk"); - if (IS_ERR(phy->refclk)) { - dev_err(&pdev->dev, "unable to get refclk\n"); - return PTR_ERR(phy->refclk); - } - } else { - phy->wkupclk = ERR_PTR(-ENODEV); - phy->refclk = ERR_PTR(-ENODEV); - } - - if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { - if (of_property_read_u8(node, "id", &phy->id) < 0) - phy->id = 1; - - clk = devm_clk_get(phy->dev, "dpll_ref"); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "unable to get dpll ref clk\n"); - return PTR_ERR(clk); - } - clk_set_rate(clk, 1500000000); - - clk = devm_clk_get(phy->dev, "dpll_ref_m2"); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "unable to get dpll ref m2 clk\n"); - return PTR_ERR(clk); - } - clk_set_rate(clk, 100000000); - - clk = devm_clk_get(phy->dev, "phy-div"); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "unable to get phy-div clk\n"); - return PTR_ERR(clk); - } - clk_set_rate(clk, 100000000); - - phy->div_clk = devm_clk_get(phy->dev, "div-clk"); - if (IS_ERR(phy->div_clk)) { - dev_err(&pdev->dev, "unable to get div-clk\n"); - return PTR_ERR(phy->div_clk); - } - } else { - phy->div_clk = ERR_PTR(-ENODEV); - } - - control_node = of_parse_phandle(node, "ctrl-module", 0); - if (!control_node) { - dev_err(&pdev->dev, "Failed to get control device phandle\n"); - return -EINVAL; - } - - control_pdev = of_find_device_by_node(control_node); - if (!control_pdev) { - dev_err(&pdev->dev, "Failed to get control device\n"); - return -EINVAL; - } - - phy->control_dev = &control_pdev->dev; - - omap_control_phy_power(phy->control_dev, 0); - - platform_set_drvdata(pdev, phy); - pm_runtime_enable(phy->dev); - - generic_phy = devm_phy_create(phy->dev, NULL, &ops, NULL); - if (IS_ERR(generic_phy)) - return PTR_ERR(generic_phy); - - phy_set_drvdata(generic_phy, phy); - phy_provider = devm_of_phy_provider_register(phy->dev, - of_phy_simple_xlate); - if (IS_ERR(phy_provider)) - return PTR_ERR(phy_provider); - - pm_runtime_get(&pdev->dev); - - return 0; -} - -static int ti_pipe3_remove(struct platform_device *pdev) -{ - if (!pm_runtime_suspended(&pdev->dev)) - pm_runtime_put(&pdev->dev); - pm_runtime_disable(&pdev->dev); - - return 0; -} - -#ifdef CONFIG_PM_RUNTIME - -static int ti_pipe3_runtime_suspend(struct device *dev) -{ - struct ti_pipe3 *phy = dev_get_drvdata(dev); - - if (!IS_ERR(phy->wkupclk)) - clk_disable_unprepare(phy->wkupclk); - if (!IS_ERR(phy->refclk)) - clk_disable_unprepare(phy->refclk); - if (!IS_ERR(phy->div_clk)) - clk_disable_unprepare(phy->div_clk); - - return 0; -} - -static int ti_pipe3_runtime_resume(struct device *dev) -{ - u32 ret = 0; - struct ti_pipe3 *phy = dev_get_drvdata(dev); - - if (!IS_ERR(phy->refclk)) { - ret = clk_prepare_enable(phy->refclk); - if (ret) { - dev_err(phy->dev, "Failed to enable refclk %d\n", ret); - goto err1; - } - } - - if (!IS_ERR(phy->wkupclk)) { - ret = clk_prepare_enable(phy->wkupclk); - if (ret) { - dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret); - goto err2; - } - } - - if (!IS_ERR(phy->div_clk)) { - ret = clk_prepare_enable(phy->div_clk); - if (ret) { - dev_err(phy->dev, "Failed to enable div_clk %d\n", ret); - goto err3; - } - } - return 0; - -err3: - if (!IS_ERR(phy->wkupclk)) - clk_disable_unprepare(phy->wkupclk); - -err2: - if (!IS_ERR(phy->refclk)) - clk_disable_unprepare(phy->refclk); - -err1: - return ret; -} - -static const struct dev_pm_ops ti_pipe3_pm_ops = { - SET_RUNTIME_PM_OPS(ti_pipe3_runtime_suspend, - ti_pipe3_runtime_resume, NULL) -}; - -#define DEV_PM_OPS (&ti_pipe3_pm_ops) -#else -#define DEV_PM_OPS NULL -#endif - -#ifdef CONFIG_OF -static const struct of_device_id ti_pipe3_id_table[] = { - { - .compatible = "ti,phy-usb3", - .data = dpll_map_usb, - }, - { - .compatible = "ti,omap-usb3", - .data = dpll_map_usb, - }, - { - .compatible = "ti,phy-pipe3-sata", - .data = dpll_map_sata, - }, - { - .compatible = "ti,phy-pipe3-pcie", - }, - {} -}; -MODULE_DEVICE_TABLE(of, ti_pipe3_id_table); -#endif - -static struct platform_driver ti_pipe3_driver = { - .probe = ti_pipe3_probe, - .remove = ti_pipe3_remove, - .driver = { - .name = "ti-pipe3", - .pm = DEV_PM_OPS, - .of_match_table = of_match_ptr(ti_pipe3_id_table), - }, -}; - -module_platform_driver(ti_pipe3_driver); - -MODULE_ALIAS("platform: ti_pipe3"); -MODULE_AUTHOR("Texas Instruments Inc."); -MODULE_DESCRIPTION("TI PIPE3 phy driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c deleted file mode 100644 index e2698d29f436..000000000000 --- a/drivers/phy/phy-twl4030-usb.c +++ /dev/null @@ -1,807 +0,0 @@ -/* - * twl4030_usb - TWL4030 USB transceiver, talking to OMAP OTG controller - * - * Copyright (C) 2004-2007 Texas Instruments - * Copyright (C) 2008 Nokia Corporation - * Contact: Felipe Balbi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Current status: - * - HS USB ULPI mode works. - * - 3-pin mode support may be added in future. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Register defines */ - -#define MCPC_CTRL 0x30 -#define MCPC_CTRL_RTSOL (1 << 7) -#define MCPC_CTRL_EXTSWR (1 << 6) -#define MCPC_CTRL_EXTSWC (1 << 5) -#define MCPC_CTRL_VOICESW (1 << 4) -#define MCPC_CTRL_OUT64K (1 << 3) -#define MCPC_CTRL_RTSCTSSW (1 << 2) -#define MCPC_CTRL_HS_UART (1 << 0) - -#define MCPC_IO_CTRL 0x33 -#define MCPC_IO_CTRL_MICBIASEN (1 << 5) -#define MCPC_IO_CTRL_CTS_NPU (1 << 4) -#define MCPC_IO_CTRL_RXD_PU (1 << 3) -#define MCPC_IO_CTRL_TXDTYP (1 << 2) -#define MCPC_IO_CTRL_CTSTYP (1 << 1) -#define MCPC_IO_CTRL_RTSTYP (1 << 0) - -#define MCPC_CTRL2 0x36 -#define MCPC_CTRL2_MCPC_CK_EN (1 << 0) - -#define OTHER_FUNC_CTRL 0x80 -#define OTHER_FUNC_CTRL_BDIS_ACON_EN (1 << 4) -#define OTHER_FUNC_CTRL_FIVEWIRE_MODE (1 << 2) - -#define OTHER_IFC_CTRL 0x83 -#define OTHER_IFC_CTRL_OE_INT_EN (1 << 6) -#define OTHER_IFC_CTRL_CEA2011_MODE (1 << 5) -#define OTHER_IFC_CTRL_FSLSSERIALMODE_4PIN (1 << 4) -#define OTHER_IFC_CTRL_HIZ_ULPI_60MHZ_OUT (1 << 3) -#define OTHER_IFC_CTRL_HIZ_ULPI (1 << 2) -#define OTHER_IFC_CTRL_ALT_INT_REROUTE (1 << 0) - -#define OTHER_INT_EN_RISE 0x86 -#define OTHER_INT_EN_FALL 0x89 -#define OTHER_INT_STS 0x8C -#define OTHER_INT_LATCH 0x8D -#define OTHER_INT_VB_SESS_VLD (1 << 7) -#define OTHER_INT_DM_HI (1 << 6) /* not valid for "latch" reg */ -#define OTHER_INT_DP_HI (1 << 5) /* not valid for "latch" reg */ -#define OTHER_INT_BDIS_ACON (1 << 3) /* not valid for "fall" regs */ -#define OTHER_INT_MANU (1 << 1) -#define OTHER_INT_ABNORMAL_STRESS (1 << 0) - -#define ID_STATUS 0x96 -#define ID_RES_FLOAT (1 << 4) -#define ID_RES_440K (1 << 3) -#define ID_RES_200K (1 << 2) -#define ID_RES_102K (1 << 1) -#define ID_RES_GND (1 << 0) - -#define POWER_CTRL 0xAC -#define POWER_CTRL_OTG_ENAB (1 << 5) - -#define OTHER_IFC_CTRL2 0xAF -#define OTHER_IFC_CTRL2_ULPI_STP_LOW (1 << 4) -#define OTHER_IFC_CTRL2_ULPI_TXEN_POL (1 << 3) -#define OTHER_IFC_CTRL2_ULPI_4PIN_2430 (1 << 2) -#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_MASK (3 << 0) /* bits 0 and 1 */ -#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_INT1N (0 << 0) -#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_INT2N (1 << 0) - -#define REG_CTRL_EN 0xB2 -#define REG_CTRL_ERROR 0xB5 -#define ULPI_I2C_CONFLICT_INTEN (1 << 0) - -#define OTHER_FUNC_CTRL2 0xB8 -#define OTHER_FUNC_CTRL2_VBAT_TIMER_EN (1 << 0) - -/* following registers do not have separate _clr and _set registers */ -#define VBUS_DEBOUNCE 0xC0 -#define ID_DEBOUNCE 0xC1 -#define VBAT_TIMER 0xD3 -#define PHY_PWR_CTRL 0xFD -#define PHY_PWR_PHYPWD (1 << 0) -#define PHY_CLK_CTRL 0xFE -#define PHY_CLK_CTRL_CLOCKGATING_EN (1 << 2) -#define PHY_CLK_CTRL_CLK32K_EN (1 << 1) -#define REQ_PHY_DPLL_CLK (1 << 0) -#define PHY_CLK_CTRL_STS 0xFF -#define PHY_DPLL_CLK (1 << 0) - -/* In module TWL_MODULE_PM_MASTER */ -#define STS_HW_CONDITIONS 0x0F - -/* In module TWL_MODULE_PM_RECEIVER */ -#define VUSB_DEDICATED1 0x7D -#define VUSB_DEDICATED2 0x7E -#define VUSB1V5_DEV_GRP 0x71 -#define VUSB1V5_TYPE 0x72 -#define VUSB1V5_REMAP 0x73 -#define VUSB1V8_DEV_GRP 0x74 -#define VUSB1V8_TYPE 0x75 -#define VUSB1V8_REMAP 0x76 -#define VUSB3V1_DEV_GRP 0x77 -#define VUSB3V1_TYPE 0x78 -#define VUSB3V1_REMAP 0x79 - -/* In module TWL4030_MODULE_INTBR */ -#define PMBR1 0x0D -#define GPIO_USB_4PIN_ULPI_2430C (3 << 0) - -struct twl4030_usb { - struct usb_phy phy; - struct device *dev; - - /* TWL4030 internal USB regulator supplies */ - struct regulator *usb1v5; - struct regulator *usb1v8; - struct regulator *usb3v1; - - /* for vbus reporting with irqs disabled */ - struct mutex lock; - - /* pin configuration */ - enum twl4030_usb_mode usb_mode; - - int irq; - enum omap_musb_vbus_id_status linkstat; - bool vbus_supplied; - - struct delayed_work id_workaround_work; -}; - -/* internal define on top of container_of */ -#define phy_to_twl(x) container_of((x), struct twl4030_usb, phy) - -/*-------------------------------------------------------------------------*/ - -static int twl4030_i2c_write_u8_verify(struct twl4030_usb *twl, - u8 module, u8 data, u8 address) -{ - u8 check; - - if ((twl_i2c_write_u8(module, data, address) >= 0) && - (twl_i2c_read_u8(module, &check, address) >= 0) && - (check == data)) - return 0; - dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n", - 1, module, address, check, data); - - /* Failed once: Try again */ - if ((twl_i2c_write_u8(module, data, address) >= 0) && - (twl_i2c_read_u8(module, &check, address) >= 0) && - (check == data)) - return 0; - dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n", - 2, module, address, check, data); - - /* Failed again: Return error */ - return -EBUSY; -} - -#define twl4030_usb_write_verify(twl, address, data) \ - twl4030_i2c_write_u8_verify(twl, TWL_MODULE_USB, (data), (address)) - -static inline int twl4030_usb_write(struct twl4030_usb *twl, - u8 address, u8 data) -{ - int ret = 0; - - ret = twl_i2c_write_u8(TWL_MODULE_USB, data, address); - if (ret < 0) - dev_dbg(twl->dev, - "TWL4030:USB:Write[0x%x] Error %d\n", address, ret); - return ret; -} - -static inline int twl4030_readb(struct twl4030_usb *twl, u8 module, u8 address) -{ - u8 data; - int ret = 0; - - ret = twl_i2c_read_u8(module, &data, address); - if (ret >= 0) - ret = data; - else - dev_dbg(twl->dev, - "TWL4030:readb[0x%x,0x%x] Error %d\n", - module, address, ret); - - return ret; -} - -static inline int twl4030_usb_read(struct twl4030_usb *twl, u8 address) -{ - return twl4030_readb(twl, TWL_MODULE_USB, address); -} - -/*-------------------------------------------------------------------------*/ - -static inline int -twl4030_usb_set_bits(struct twl4030_usb *twl, u8 reg, u8 bits) -{ - return twl4030_usb_write(twl, ULPI_SET(reg), bits); -} - -static inline int -twl4030_usb_clear_bits(struct twl4030_usb *twl, u8 reg, u8 bits) -{ - return twl4030_usb_write(twl, ULPI_CLR(reg), bits); -} - -/*-------------------------------------------------------------------------*/ - -static bool twl4030_is_driving_vbus(struct twl4030_usb *twl) -{ - int ret; - - ret = twl4030_usb_read(twl, PHY_CLK_CTRL_STS); - if (ret < 0 || !(ret & PHY_DPLL_CLK)) - /* - * if clocks are off, registers are not updated, - * but we can assume we don't drive VBUS in this case - */ - return false; - - ret = twl4030_usb_read(twl, ULPI_OTG_CTRL); - if (ret < 0) - return false; - - return (ret & (ULPI_OTG_DRVVBUS | ULPI_OTG_CHRGVBUS)) ? true : false; -} - -static enum omap_musb_vbus_id_status - twl4030_usb_linkstat(struct twl4030_usb *twl) -{ - int status; - enum omap_musb_vbus_id_status linkstat = OMAP_MUSB_UNKNOWN; - - twl->vbus_supplied = false; - - /* - * For ID/VBUS sensing, see manual section 15.4.8 ... - * except when using only battery backup power, two - * comparators produce VBUS_PRES and ID_PRES signals, - * which don't match docs elsewhere. But ... BIT(7) - * and BIT(2) of STS_HW_CONDITIONS, respectively, do - * seem to match up. If either is true the USB_PRES - * signal is active, the OTG module is activated, and - * its interrupt may be raised (may wake the system). - */ - status = twl4030_readb(twl, TWL_MODULE_PM_MASTER, STS_HW_CONDITIONS); - if (status < 0) - dev_err(twl->dev, "USB link status err %d\n", status); - else if (status & (BIT(7) | BIT(2))) { - if (status & BIT(7)) { - if (twl4030_is_driving_vbus(twl)) - status &= ~BIT(7); - else - twl->vbus_supplied = true; - } - - if (status & BIT(2)) - linkstat = OMAP_MUSB_ID_GROUND; - else if (status & BIT(7)) - linkstat = OMAP_MUSB_VBUS_VALID; - else - linkstat = OMAP_MUSB_VBUS_OFF; - } else { - if (twl->linkstat != OMAP_MUSB_UNKNOWN) - linkstat = OMAP_MUSB_VBUS_OFF; - } - - dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", - status, status, linkstat); - - /* REVISIT this assumes host and peripheral controllers - * are registered, and that both are active... - */ - - return linkstat; -} - -static void twl4030_usb_set_mode(struct twl4030_usb *twl, int mode) -{ - twl->usb_mode = mode; - - switch (mode) { - case T2_USB_MODE_ULPI: - twl4030_usb_clear_bits(twl, ULPI_IFC_CTRL, - ULPI_IFC_CTRL_CARKITMODE); - twl4030_usb_set_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); - twl4030_usb_clear_bits(twl, ULPI_FUNC_CTRL, - ULPI_FUNC_CTRL_XCVRSEL_MASK | - ULPI_FUNC_CTRL_OPMODE_MASK); - break; - case -1: - /* FIXME: power on defaults */ - break; - default: - dev_err(twl->dev, "unsupported T2 transceiver mode %d\n", - mode); - break; - } -} - -static void twl4030_i2c_access(struct twl4030_usb *twl, int on) -{ - unsigned long timeout; - int val = twl4030_usb_read(twl, PHY_CLK_CTRL); - - if (val >= 0) { - if (on) { - /* enable DPLL to access PHY registers over I2C */ - val |= REQ_PHY_DPLL_CLK; - WARN_ON(twl4030_usb_write_verify(twl, PHY_CLK_CTRL, - (u8)val) < 0); - - timeout = jiffies + HZ; - while (!(twl4030_usb_read(twl, PHY_CLK_CTRL_STS) & - PHY_DPLL_CLK) - && time_before(jiffies, timeout)) - udelay(10); - if (!(twl4030_usb_read(twl, PHY_CLK_CTRL_STS) & - PHY_DPLL_CLK)) - dev_err(twl->dev, "Timeout setting T2 HSUSB " - "PHY DPLL clock\n"); - } else { - /* let ULPI control the DPLL clock */ - val &= ~REQ_PHY_DPLL_CLK; - WARN_ON(twl4030_usb_write_verify(twl, PHY_CLK_CTRL, - (u8)val) < 0); - } - } -} - -static void __twl4030_phy_power(struct twl4030_usb *twl, int on) -{ - u8 pwr = twl4030_usb_read(twl, PHY_PWR_CTRL); - - if (on) - pwr &= ~PHY_PWR_PHYPWD; - else - pwr |= PHY_PWR_PHYPWD; - - WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); -} - -static int twl4030_usb_runtime_suspend(struct device *dev) -{ - struct twl4030_usb *twl = dev_get_drvdata(dev); - - dev_dbg(twl->dev, "%s\n", __func__); - if (pm_runtime_suspended(dev)) - return 0; - - __twl4030_phy_power(twl, 0); - regulator_disable(twl->usb1v5); - regulator_disable(twl->usb1v8); - regulator_disable(twl->usb3v1); - - return 0; -} - -static int twl4030_usb_runtime_resume(struct device *dev) -{ - struct twl4030_usb *twl = dev_get_drvdata(dev); - int res; - - dev_dbg(twl->dev, "%s\n", __func__); - if (pm_runtime_active(dev)) - return 0; - - res = regulator_enable(twl->usb3v1); - if (res) - dev_err(twl->dev, "Failed to enable usb3v1\n"); - - res = regulator_enable(twl->usb1v8); - if (res) - dev_err(twl->dev, "Failed to enable usb1v8\n"); - - /* - * Disabling usb3v1 regulator (= writing 0 to VUSB3V1_DEV_GRP - * in twl4030) resets the VUSB_DEDICATED2 register. This reset - * enables VUSB3V1_SLEEP bit that remaps usb3v1 ACTIVE state to - * SLEEP. We work around this by clearing the bit after usv3v1 - * is re-activated. This ensures that VUSB3V1 is really active. - */ - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2); - - res = regulator_enable(twl->usb1v5); - if (res) - dev_err(twl->dev, "Failed to enable usb1v5\n"); - - __twl4030_phy_power(twl, 1); - twl4030_usb_write(twl, PHY_CLK_CTRL, - twl4030_usb_read(twl, PHY_CLK_CTRL) | - (PHY_CLK_CTRL_CLOCKGATING_EN | - PHY_CLK_CTRL_CLK32K_EN)); - - return 0; -} - -static int twl4030_phy_power_off(struct phy *phy) -{ - struct twl4030_usb *twl = phy_get_drvdata(phy); - - dev_dbg(twl->dev, "%s\n", __func__); - pm_runtime_mark_last_busy(twl->dev); - pm_runtime_put_autosuspend(twl->dev); - - return 0; -} - -static int twl4030_phy_power_on(struct phy *phy) -{ - struct twl4030_usb *twl = phy_get_drvdata(phy); - - dev_dbg(twl->dev, "%s\n", __func__); - pm_runtime_get_sync(twl->dev); - twl4030_i2c_access(twl, 1); - twl4030_usb_set_mode(twl, twl->usb_mode); - if (twl->usb_mode == T2_USB_MODE_ULPI) - twl4030_i2c_access(twl, 0); - schedule_delayed_work(&twl->id_workaround_work, 0); - - return 0; -} - -static int twl4030_usb_ldo_init(struct twl4030_usb *twl) -{ - /* Enable writing to power configuration registers */ - twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1, - TWL4030_PM_MASTER_PROTECT_KEY); - - twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2, - TWL4030_PM_MASTER_PROTECT_KEY); - - /* Keep VUSB3V1 LDO in sleep state until VBUS/ID change detected*/ - /*twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);*/ - - /* input to VUSB3V1 LDO is from VBAT, not VBUS */ - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1); - - /* Initialize 3.1V regulator */ - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP); - - twl->usb3v1 = devm_regulator_get(twl->dev, "usb3v1"); - if (IS_ERR(twl->usb3v1)) - return -ENODEV; - - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE); - - /* Initialize 1.5V regulator */ - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP); - - twl->usb1v5 = devm_regulator_get(twl->dev, "usb1v5"); - if (IS_ERR(twl->usb1v5)) - return -ENODEV; - - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE); - - /* Initialize 1.8V regulator */ - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP); - - twl->usb1v8 = devm_regulator_get(twl->dev, "usb1v8"); - if (IS_ERR(twl->usb1v8)) - return -ENODEV; - - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE); - - /* disable access to power configuration registers */ - twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0, - TWL4030_PM_MASTER_PROTECT_KEY); - - return 0; -} - -static ssize_t twl4030_usb_vbus_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct twl4030_usb *twl = dev_get_drvdata(dev); - int ret = -EINVAL; - - mutex_lock(&twl->lock); - ret = sprintf(buf, "%s\n", - twl->vbus_supplied ? "on" : "off"); - mutex_unlock(&twl->lock); - - return ret; -} -static DEVICE_ATTR(vbus, 0444, twl4030_usb_vbus_show, NULL); - -static irqreturn_t twl4030_usb_irq(int irq, void *_twl) -{ - struct twl4030_usb *twl = _twl; - enum omap_musb_vbus_id_status status; - bool status_changed = false; - - status = twl4030_usb_linkstat(twl); - - mutex_lock(&twl->lock); - if (status >= 0 && status != twl->linkstat) { - twl->linkstat = status; - status_changed = true; - } - mutex_unlock(&twl->lock); - - if (status_changed) { - /* FIXME add a set_power() method so that B-devices can - * configure the charger appropriately. It's not always - * correct to consume VBUS power, and how much current to - * consume is a function of the USB configuration chosen - * by the host. - * - * REVISIT usb_gadget_vbus_connect(...) as needed, ditto - * its disconnect() sibling, when changing to/from the - * USB_LINK_VBUS state. musb_hdrc won't care until it - * starts to handle softconnect right. - */ - if ((status == OMAP_MUSB_VBUS_VALID) || - (status == OMAP_MUSB_ID_GROUND)) { - if (pm_runtime_suspended(twl->dev)) - pm_runtime_get_sync(twl->dev); - } else { - if (pm_runtime_active(twl->dev)) { - pm_runtime_mark_last_busy(twl->dev); - pm_runtime_put_autosuspend(twl->dev); - } - } - omap_musb_mailbox(status); - } - - /* don't schedule during sleep - irq works right then */ - if (status == OMAP_MUSB_ID_GROUND && pm_runtime_active(twl->dev)) { - cancel_delayed_work(&twl->id_workaround_work); - schedule_delayed_work(&twl->id_workaround_work, HZ); - } - - if (irq) - sysfs_notify(&twl->dev->kobj, NULL, "vbus"); - - return IRQ_HANDLED; -} - -static void twl4030_id_workaround_work(struct work_struct *work) -{ - struct twl4030_usb *twl = container_of(work, struct twl4030_usb, - id_workaround_work.work); - - twl4030_usb_irq(0, twl); -} - -static int twl4030_phy_init(struct phy *phy) -{ - struct twl4030_usb *twl = phy_get_drvdata(phy); - - pm_runtime_get_sync(twl->dev); - schedule_delayed_work(&twl->id_workaround_work, 0); - pm_runtime_mark_last_busy(twl->dev); - pm_runtime_put_autosuspend(twl->dev); - - return 0; -} - -static int twl4030_set_peripheral(struct usb_otg *otg, - struct usb_gadget *gadget) -{ - if (!otg) - return -ENODEV; - - otg->gadget = gadget; - if (!gadget) - otg->state = OTG_STATE_UNDEFINED; - - return 0; -} - -static int twl4030_set_host(struct usb_otg *otg, struct usb_bus *host) -{ - if (!otg) - return -ENODEV; - - otg->host = host; - if (!host) - otg->state = OTG_STATE_UNDEFINED; - - return 0; -} - -static const struct phy_ops ops = { - .init = twl4030_phy_init, - .power_on = twl4030_phy_power_on, - .power_off = twl4030_phy_power_off, - .owner = THIS_MODULE, -}; - -static const struct dev_pm_ops twl4030_usb_pm_ops = { - SET_RUNTIME_PM_OPS(twl4030_usb_runtime_suspend, - twl4030_usb_runtime_resume, NULL) -}; - -static int twl4030_usb_probe(struct platform_device *pdev) -{ - struct twl4030_usb_data *pdata = dev_get_platdata(&pdev->dev); - struct twl4030_usb *twl; - struct phy *phy; - int status, err; - struct usb_otg *otg; - struct device_node *np = pdev->dev.of_node; - struct phy_provider *phy_provider; - struct phy_init_data *init_data = NULL; - - twl = devm_kzalloc(&pdev->dev, sizeof(*twl), GFP_KERNEL); - if (!twl) - return -ENOMEM; - - if (np) - of_property_read_u32(np, "usb_mode", - (enum twl4030_usb_mode *)&twl->usb_mode); - else if (pdata) { - twl->usb_mode = pdata->usb_mode; - init_data = pdata->init_data; - } else { - dev_err(&pdev->dev, "twl4030 initialized without pdata\n"); - return -EINVAL; - } - - otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); - if (!otg) - return -ENOMEM; - - twl->dev = &pdev->dev; - twl->irq = platform_get_irq(pdev, 0); - twl->vbus_supplied = false; - twl->linkstat = -EINVAL; - twl->linkstat = OMAP_MUSB_UNKNOWN; - - twl->phy.dev = twl->dev; - twl->phy.label = "twl4030"; - twl->phy.otg = otg; - twl->phy.type = USB_PHY_TYPE_USB2; - - otg->usb_phy = &twl->phy; - otg->set_host = twl4030_set_host; - otg->set_peripheral = twl4030_set_peripheral; - - phy = devm_phy_create(twl->dev, NULL, &ops, init_data); - if (IS_ERR(phy)) { - dev_dbg(&pdev->dev, "Failed to create PHY\n"); - return PTR_ERR(phy); - } - - phy_set_drvdata(phy, twl); - - phy_provider = devm_of_phy_provider_register(twl->dev, - of_phy_simple_xlate); - if (IS_ERR(phy_provider)) - return PTR_ERR(phy_provider); - - /* init mutex for workqueue */ - mutex_init(&twl->lock); - - INIT_DELAYED_WORK(&twl->id_workaround_work, twl4030_id_workaround_work); - - err = twl4030_usb_ldo_init(twl); - if (err) { - dev_err(&pdev->dev, "ldo init failed\n"); - return err; - } - usb_add_phy_dev(&twl->phy); - - platform_set_drvdata(pdev, twl); - if (device_create_file(&pdev->dev, &dev_attr_vbus)) - dev_warn(&pdev->dev, "could not create sysfs file\n"); - - ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier); - - pm_runtime_use_autosuspend(&pdev->dev); - pm_runtime_set_autosuspend_delay(&pdev->dev, 2000); - pm_runtime_enable(&pdev->dev); - pm_runtime_get_sync(&pdev->dev); - - /* Our job is to use irqs and status from the power module - * to keep the transceiver disabled when nothing's connected. - * - * FIXME we actually shouldn't start enabling it until the - * USB controller drivers have said they're ready, by calling - * set_host() and/or set_peripheral() ... OTG_capable boards - * need both handles, otherwise just one suffices. - */ - status = devm_request_threaded_irq(twl->dev, twl->irq, NULL, - twl4030_usb_irq, IRQF_TRIGGER_FALLING | - IRQF_TRIGGER_RISING | IRQF_ONESHOT, "twl4030_usb", twl); - if (status < 0) { - dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", - twl->irq, status); - return status; - } - - pm_runtime_mark_last_busy(&pdev->dev); - pm_runtime_put_autosuspend(twl->dev); - - dev_info(&pdev->dev, "Initialized TWL4030 USB module\n"); - return 0; -} - -static int twl4030_usb_remove(struct platform_device *pdev) -{ - struct twl4030_usb *twl = platform_get_drvdata(pdev); - int val; - - pm_runtime_get_sync(twl->dev); - cancel_delayed_work(&twl->id_workaround_work); - device_remove_file(twl->dev, &dev_attr_vbus); - - /* set transceiver mode to power on defaults */ - twl4030_usb_set_mode(twl, -1); - - /* autogate 60MHz ULPI clock, - * clear dpll clock request for i2c access, - * disable 32KHz - */ - val = twl4030_usb_read(twl, PHY_CLK_CTRL); - if (val >= 0) { - val |= PHY_CLK_CTRL_CLOCKGATING_EN; - val &= ~(PHY_CLK_CTRL_CLK32K_EN | REQ_PHY_DPLL_CLK); - twl4030_usb_write(twl, PHY_CLK_CTRL, (u8)val); - } - - /* disable complete OTG block */ - twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); - pm_runtime_mark_last_busy(twl->dev); - pm_runtime_put(twl->dev); - - return 0; -} - -#ifdef CONFIG_OF -static const struct of_device_id twl4030_usb_id_table[] = { - { .compatible = "ti,twl4030-usb" }, - {} -}; -MODULE_DEVICE_TABLE(of, twl4030_usb_id_table); -#endif - -static struct platform_driver twl4030_usb_driver = { - .probe = twl4030_usb_probe, - .remove = twl4030_usb_remove, - .driver = { - .name = "twl4030_usb", - .pm = &twl4030_usb_pm_ops, - .of_match_table = of_match_ptr(twl4030_usb_id_table), - }, -}; - -static int __init twl4030_usb_init(void) -{ - return platform_driver_register(&twl4030_usb_driver); -} -subsys_initcall(twl4030_usb_init); - -static void __exit twl4030_usb_exit(void) -{ - platform_driver_unregister(&twl4030_usb_driver); -} -module_exit(twl4030_usb_exit); - -MODULE_ALIAS("platform:twl4030_usb"); -MODULE_AUTHOR("Texas Instruments, Inc, Nokia Corporation"); -MODULE_DESCRIPTION("TWL4030 USB transceiver driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/phy/phy-xgene.c b/drivers/phy/phy-xgene.c deleted file mode 100644 index f8a51b16ade8..000000000000 --- a/drivers/phy/phy-xgene.c +++ /dev/null @@ -1,1749 +0,0 @@ -/* - * AppliedMicro X-Gene Multi-purpose PHY driver - * - * Copyright (c) 2014, Applied Micro Circuits Corporation - * Author: Loc Ho - * Tuan Phan - * Suman Tripathi - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * The APM X-Gene PHY consists of two PLL clock macro's (CMU) and lanes. - * The first PLL clock macro is used for internal reference clock. The second - * PLL clock macro is used to generate the clock for the PHY. This driver - * configures the first PLL CMU, the second PLL CMU, and programs the PHY to - * operate according to the mode of operation. The first PLL CMU is only - * required if internal clock is enabled. - * - * Logical Layer Out Of HW module units: - * - * ----------------- - * | Internal | |------| - * | Ref PLL CMU |----| | ------------- --------- - * ------------ ---- | MUX |-----|PHY PLL CMU|----| Serdes| - * | | | | --------- - * External Clock ------| | ------------- - * |------| - * - * The Ref PLL CMU CSR (Configuration System Registers) is accessed - * indirectly from the SDS offset at 0x2000. It is only required for - * internal reference clock. - * The PHY PLL CMU CSR is accessed indirectly from the SDS offset at 0x0000. - * The Serdes CSR is accessed indirectly from the SDS offset at 0x0400. - * - * The Ref PLL CMU can be located within the same PHY IP or outside the PHY IP - * due to shared Ref PLL CMU. For PHY with Ref PLL CMU shared with another IP, - * it is located outside the PHY IP. This is the case for the PHY located - * at 0x1f23a000 (SATA Port 4/5). For such PHY, another resource is required - * to located the SDS/Ref PLL CMU module and its clock for that IP enabled. - * - * Currently, this driver only supports Gen3 SATA mode with external clock. - */ -#include -#include -#include -#include -#include -#include - -/* Max 2 lanes per a PHY unit */ -#define MAX_LANE 2 - -/* Register offset inside the PHY */ -#define SERDES_PLL_INDIRECT_OFFSET 0x0000 -#define SERDES_PLL_REF_INDIRECT_OFFSET 0x2000 -#define SERDES_INDIRECT_OFFSET 0x0400 -#define SERDES_LANE_STRIDE 0x0200 - -/* Some default Serdes parameters */ -#define DEFAULT_SATA_TXBOOST_GAIN { 0x1e, 0x1e, 0x1e } -#define DEFAULT_SATA_TXEYEDIRECTION { 0x0, 0x0, 0x0 } -#define DEFAULT_SATA_TXEYETUNING { 0xa, 0xa, 0xa } -#define DEFAULT_SATA_SPD_SEL { 0x1, 0x3, 0x7 } -#define DEFAULT_SATA_TXAMP { 0x8, 0x8, 0x8 } -#define DEFAULT_SATA_TXCN1 { 0x2, 0x2, 0x2 } -#define DEFAULT_SATA_TXCN2 { 0x0, 0x0, 0x0 } -#define DEFAULT_SATA_TXCP1 { 0xa, 0xa, 0xa } - -#define SATA_SPD_SEL_GEN3 0x7 -#define SATA_SPD_SEL_GEN2 0x3 -#define SATA_SPD_SEL_GEN1 0x1 - -#define SSC_DISABLE 0 -#define SSC_ENABLE 1 - -#define FBDIV_VAL_50M 0x77 -#define REFDIV_VAL_50M 0x1 -#define FBDIV_VAL_100M 0x3B -#define REFDIV_VAL_100M 0x0 - -/* SATA Clock/Reset CSR */ -#define SATACLKENREG 0x00000000 -#define SATA0_CORE_CLKEN 0x00000002 -#define SATA1_CORE_CLKEN 0x00000004 -#define SATASRESETREG 0x00000004 -#define SATA_MEM_RESET_MASK 0x00000020 -#define SATA_MEM_RESET_RD(src) (((src) & 0x00000020) >> 5) -#define SATA_SDS_RESET_MASK 0x00000004 -#define SATA_CSR_RESET_MASK 0x00000001 -#define SATA_CORE_RESET_MASK 0x00000002 -#define SATA_PMCLK_RESET_MASK 0x00000010 -#define SATA_PCLK_RESET_MASK 0x00000008 - -/* SDS CSR used for PHY Indirect access */ -#define SATA_ENET_SDS_PCS_CTL0 0x00000000 -#define REGSPEC_CFG_I_TX_WORDMODE0_SET(dst, src) \ - (((dst) & ~0x00070000) | (((u32) (src) << 16) & 0x00070000)) -#define REGSPEC_CFG_I_RX_WORDMODE0_SET(dst, src) \ - (((dst) & ~0x00e00000) | (((u32) (src) << 21) & 0x00e00000)) -#define SATA_ENET_SDS_CTL0 0x0000000c -#define REGSPEC_CFG_I_CUSTOMER_PIN_MODE0_SET(dst, src) \ - (((dst) & ~0x00007fff) | (((u32) (src)) & 0x00007fff)) -#define SATA_ENET_SDS_CTL1 0x00000010 -#define CFG_I_SPD_SEL_CDR_OVR1_SET(dst, src) \ - (((dst) & ~0x0000000f) | (((u32) (src)) & 0x0000000f)) -#define SATA_ENET_SDS_RST_CTL 0x00000024 -#define SATA_ENET_SDS_IND_CMD_REG 0x0000003c -#define CFG_IND_WR_CMD_MASK 0x00000001 -#define CFG_IND_RD_CMD_MASK 0x00000002 -#define CFG_IND_CMD_DONE_MASK 0x00000004 -#define CFG_IND_ADDR_SET(dst, src) \ - (((dst) & ~0x003ffff0) | (((u32) (src) << 4) & 0x003ffff0)) -#define SATA_ENET_SDS_IND_RDATA_REG 0x00000040 -#define SATA_ENET_SDS_IND_WDATA_REG 0x00000044 -#define SATA_ENET_CLK_MACRO_REG 0x0000004c -#define I_RESET_B_SET(dst, src) \ - (((dst) & ~0x00000001) | (((u32) (src)) & 0x00000001)) -#define I_PLL_FBDIV_SET(dst, src) \ - (((dst) & ~0x001ff000) | (((u32) (src) << 12) & 0x001ff000)) -#define I_CUSTOMEROV_SET(dst, src) \ - (((dst) & ~0x00000f80) | (((u32) (src) << 7) & 0x00000f80)) -#define O_PLL_LOCK_RD(src) (((src) & 0x40000000) >> 30) -#define O_PLL_READY_RD(src) (((src) & 0x80000000) >> 31) - -/* PLL Clock Macro Unit (CMU) CSR accessing from SDS indirectly */ -#define CMU_REG0 0x00000 -#define CMU_REG0_PLL_REF_SEL_MASK 0x00002000 -#define CMU_REG0_PLL_REF_SEL_SET(dst, src) \ - (((dst) & ~0x00002000) | (((u32) (src) << 13) & 0x00002000)) -#define CMU_REG0_PDOWN_MASK 0x00004000 -#define CMU_REG0_CAL_COUNT_RESOL_SET(dst, src) \ - (((dst) & ~0x000000e0) | (((u32) (src) << 5) & 0x000000e0)) -#define CMU_REG1 0x00002 -#define CMU_REG1_PLL_CP_SET(dst, src) \ - (((dst) & ~0x00003c00) | (((u32) (src) << 10) & 0x00003c00)) -#define CMU_REG1_PLL_MANUALCAL_SET(dst, src) \ - (((dst) & ~0x00000008) | (((u32) (src) << 3) & 0x00000008)) -#define CMU_REG1_PLL_CP_SEL_SET(dst, src) \ - (((dst) & ~0x000003e0) | (((u32) (src) << 5) & 0x000003e0)) -#define CMU_REG1_REFCLK_CMOS_SEL_MASK 0x00000001 -#define CMU_REG1_REFCLK_CMOS_SEL_SET(dst, src) \ - (((dst) & ~0x00000001) | (((u32) (src) << 0) & 0x00000001)) -#define CMU_REG2 0x00004 -#define CMU_REG2_PLL_REFDIV_SET(dst, src) \ - (((dst) & ~0x0000c000) | (((u32) (src) << 14) & 0x0000c000)) -#define CMU_REG2_PLL_LFRES_SET(dst, src) \ - (((dst) & ~0x0000001e) | (((u32) (src) << 1) & 0x0000001e)) -#define CMU_REG2_PLL_FBDIV_SET(dst, src) \ - (((dst) & ~0x00003fe0) | (((u32) (src) << 5) & 0x00003fe0)) -#define CMU_REG3 0x00006 -#define CMU_REG3_VCOVARSEL_SET(dst, src) \ - (((dst) & ~0x0000000f) | (((u32) (src) << 0) & 0x0000000f)) -#define CMU_REG3_VCO_MOMSEL_INIT_SET(dst, src) \ - (((dst) & ~0x000003f0) | (((u32) (src) << 4) & 0x000003f0)) -#define CMU_REG3_VCO_MANMOMSEL_SET(dst, src) \ - (((dst) & ~0x0000fc00) | (((u32) (src) << 10) & 0x0000fc00)) -#define CMU_REG4 0x00008 -#define CMU_REG5 0x0000a -#define CMU_REG5_PLL_LFSMCAP_SET(dst, src) \ - (((dst) & ~0x0000c000) | (((u32) (src) << 14) & 0x0000c000)) -#define CMU_REG5_PLL_LOCK_RESOLUTION_SET(dst, src) \ - (((dst) & ~0x0000000e) | (((u32) (src) << 1) & 0x0000000e)) -#define CMU_REG5_PLL_LFCAP_SET(dst, src) \ - (((dst) & ~0x00003000) | (((u32) (src) << 12) & 0x00003000)) -#define CMU_REG5_PLL_RESETB_MASK 0x00000001 -#define CMU_REG6 0x0000c -#define CMU_REG6_PLL_VREGTRIM_SET(dst, src) \ - (((dst) & ~0x00000600) | (((u32) (src) << 9) & 0x00000600)) -#define CMU_REG6_MAN_PVT_CAL_SET(dst, src) \ - (((dst) & ~0x00000004) | (((u32) (src) << 2) & 0x00000004)) -#define CMU_REG7 0x0000e -#define CMU_REG7_PLL_CALIB_DONE_RD(src) ((0x00004000 & (u32) (src)) >> 14) -#define CMU_REG7_VCO_CAL_FAIL_RD(src) ((0x00000c00 & (u32) (src)) >> 10) -#define CMU_REG8 0x00010 -#define CMU_REG9 0x00012 -#define CMU_REG9_WORD_LEN_8BIT 0x000 -#define CMU_REG9_WORD_LEN_10BIT 0x001 -#define CMU_REG9_WORD_LEN_16BIT 0x002 -#define CMU_REG9_WORD_LEN_20BIT 0x003 -#define CMU_REG9_WORD_LEN_32BIT 0x004 -#define CMU_REG9_WORD_LEN_40BIT 0x005 -#define CMU_REG9_WORD_LEN_64BIT 0x006 -#define CMU_REG9_WORD_LEN_66BIT 0x007 -#define CMU_REG9_TX_WORD_MODE_CH1_SET(dst, src) \ - (((dst) & ~0x00000380) | (((u32) (src) << 7) & 0x00000380)) -#define CMU_REG9_TX_WORD_MODE_CH0_SET(dst, src) \ - (((dst) & ~0x00000070) | (((u32) (src) << 4) & 0x00000070)) -#define CMU_REG9_PLL_POST_DIVBY2_SET(dst, src) \ - (((dst) & ~0x00000008) | (((u32) (src) << 3) & 0x00000008)) -#define CMU_REG9_VBG_BYPASSB_SET(dst, src) \ - (((dst) & ~0x00000004) | (((u32) (src) << 2) & 0x00000004)) -#define CMU_REG9_IGEN_BYPASS_SET(dst, src) \ - (((dst) & ~0x00000002) | (((u32) (src) << 1) & 0x00000002)) -#define CMU_REG10 0x00014 -#define CMU_REG10_VREG_REFSEL_SET(dst, src) \ - (((dst) & ~0x00000001) | (((u32) (src) << 0) & 0x00000001)) -#define CMU_REG11 0x00016 -#define CMU_REG12 0x00018 -#define CMU_REG12_STATE_DELAY9_SET(dst, src) \ - (((dst) & ~0x000000f0) | (((u32) (src) << 4) & 0x000000f0)) -#define CMU_REG13 0x0001a -#define CMU_REG14 0x0001c -#define CMU_REG15 0x0001e -#define CMU_REG16 0x00020 -#define CMU_REG16_PVT_DN_MAN_ENA_MASK 0x00000001 -#define CMU_REG16_PVT_UP_MAN_ENA_MASK 0x00000002 -#define CMU_REG16_VCOCAL_WAIT_BTW_CODE_SET(dst, src) \ - (((dst) & ~0x0000001c) | (((u32) (src) << 2) & 0x0000001c)) -#define CMU_REG16_CALIBRATION_DONE_OVERRIDE_SET(dst, src) \ - (((dst) & ~0x00000040) | (((u32) (src) << 6) & 0x00000040)) -#define CMU_REG16_BYPASS_PLL_LOCK_SET(dst, src) \ - (((dst) & ~0x00000020) | (((u32) (src) << 5) & 0x00000020)) -#define CMU_REG17 0x00022 -#define CMU_REG17_PVT_CODE_R2A_SET(dst, src) \ - (((dst) & ~0x00007f00) | (((u32) (src) << 8) & 0x00007f00)) -#define CMU_REG17_RESERVED_7_SET(dst, src) \ - (((dst) & ~0x000000e0) | (((u32) (src) << 5) & 0x000000e0)) -#define CMU_REG17_PVT_TERM_MAN_ENA_MASK 0x00008000 -#define CMU_REG18 0x00024 -#define CMU_REG19 0x00026 -#define CMU_REG20 0x00028 -#define CMU_REG21 0x0002a -#define CMU_REG22 0x0002c -#define CMU_REG23 0x0002e -#define CMU_REG24 0x00030 -#define CMU_REG25 0x00032 -#define CMU_REG26 0x00034 -#define CMU_REG26_FORCE_PLL_LOCK_SET(dst, src) \ - (((dst) & ~0x00000001) | (((u32) (src) << 0) & 0x00000001)) -#define CMU_REG27 0x00036 -#define CMU_REG28 0x00038 -#define CMU_REG29 0x0003a -#define CMU_REG30 0x0003c -#define CMU_REG30_LOCK_COUNT_SET(dst, src) \ - (((dst) & ~0x00000006) | (((u32) (src) << 1) & 0x00000006)) -#define CMU_REG30_PCIE_MODE_SET(dst, src) \ - (((dst) & ~0x00000008) | (((u32) (src) << 3) & 0x00000008)) -#define CMU_REG31 0x0003e -#define CMU_REG32 0x00040 -#define CMU_REG32_FORCE_VCOCAL_START_MASK 0x00004000 -#define CMU_REG32_PVT_CAL_WAIT_SEL_SET(dst, src) \ - (((dst) & ~0x00000006) | (((u32) (src) << 1) & 0x00000006)) -#define CMU_REG32_IREF_ADJ_SET(dst, src) \ - (((dst) & ~0x00000180) | (((u32) (src) << 7) & 0x00000180)) -#define CMU_REG33 0x00042 -#define CMU_REG34 0x00044 -#define CMU_REG34_VCO_CAL_VTH_LO_MAX_SET(dst, src) \ - (((dst) & ~0x0000000f) | (((u32) (src) << 0) & 0x0000000f)) -#define CMU_REG34_VCO_CAL_VTH_HI_MAX_SET(dst, src) \ - (((dst) & ~0x00000f00) | (((u32) (src) << 8) & 0x00000f00)) -#define CMU_REG34_VCO_CAL_VTH_LO_MIN_SET(dst, src) \ - (((dst) & ~0x000000f0) | (((u32) (src) << 4) & 0x000000f0)) -#define CMU_REG34_VCO_CAL_VTH_HI_MIN_SET(dst, src) \ - (((dst) & ~0x0000f000) | (((u32) (src) << 12) & 0x0000f000)) -#define CMU_REG35 0x00046 -#define CMU_REG35_PLL_SSC_MOD_SET(dst, src) \ - (((dst) & ~0x0000fe00) | (((u32) (src) << 9) & 0x0000fe00)) -#define CMU_REG36 0x00048 -#define CMU_REG36_PLL_SSC_EN_SET(dst, src) \ - (((dst) & ~0x00000010) | (((u32) (src) << 4) & 0x00000010)) -#define CMU_REG36_PLL_SSC_VSTEP_SET(dst, src) \ - (((dst) & ~0x0000ffc0) | (((u32) (src) << 6) & 0x0000ffc0)) -#define CMU_REG36_PLL_SSC_DSMSEL_SET(dst, src) \ - (((dst) & ~0x00000020) | (((u32) (src) << 5) & 0x00000020)) -#define CMU_REG37 0x0004a -#define CMU_REG38 0x0004c -#define CMU_REG39 0x0004e - -/* PHY lane CSR accessing from SDS indirectly */ -#define RXTX_REG0 0x000 -#define RXTX_REG0_CTLE_EQ_HR_SET(dst, src) \ - (((dst) & ~0x0000f800) | (((u32) (src) << 11) & 0x0000f800)) -#define RXTX_REG0_CTLE_EQ_QR_SET(dst, src) \ - (((dst) & ~0x000007c0) | (((u32) (src) << 6) & 0x000007c0)) -#define RXTX_REG0_CTLE_EQ_FR_SET(dst, src) \ - (((dst) & ~0x0000003e) | (((u32) (src) << 1) & 0x0000003e)) -#define RXTX_REG1 0x002 -#define RXTX_REG1_RXACVCM_SET(dst, src) \ - (((dst) & ~0x0000f000) | (((u32) (src) << 12) & 0x0000f000)) -#define RXTX_REG1_CTLE_EQ_SET(dst, src) \ - (((dst) & ~0x00000f80) | (((u32) (src) << 7) & 0x00000f80)) -#define RXTX_REG1_RXVREG1_SET(dst, src) \ - (((dst) & ~0x00000060) | (((u32) (src) << 5) & 0x00000060)) -#define RXTX_REG1_RXIREF_ADJ_SET(dst, src) \ - (((dst) & ~0x00000006) | (((u32) (src) << 1) & 0x00000006)) -#define RXTX_REG2 0x004 -#define RXTX_REG2_VTT_ENA_SET(dst, src) \ - (((dst) & ~0x00000100) | (((u32) (src) << 8) & 0x00000100)) -#define RXTX_REG2_TX_FIFO_ENA_SET(dst, src) \ - (((dst) & ~0x00000020) | (((u32) (src) << 5) & 0x00000020)) -#define RXTX_REG2_VTT_SEL_SET(dst, src) \ - (((dst) & ~0x000000c0) | (((u32) (src) << 6) & 0x000000c0)) -#define RXTX_REG4 0x008 -#define RXTX_REG4_TX_LOOPBACK_BUF_EN_MASK 0x00000040 -#define RXTX_REG4_TX_DATA_RATE_SET(dst, src) \ - (((dst) & ~0x0000c000) | (((u32) (src) << 14) & 0x0000c000)) -#define RXTX_REG4_TX_WORD_MODE_SET(dst, src) \ - (((dst) & ~0x00003800) | (((u32) (src) << 11) & 0x00003800)) -#define RXTX_REG5 0x00a -#define RXTX_REG5_TX_CN1_SET(dst, src) \ - (((dst) & ~0x0000f800) | (((u32) (src) << 11) & 0x0000f800)) -#define RXTX_REG5_TX_CP1_SET(dst, src) \ - (((dst) & ~0x000007e0) | (((u32) (src) << 5) & 0x000007e0)) -#define RXTX_REG5_TX_CN2_SET(dst, src) \ - (((dst) & ~0x0000001f) | (((u32) (src) << 0) & 0x0000001f)) -#define RXTX_REG6 0x00c -#define RXTX_REG6_TXAMP_CNTL_SET(dst, src) \ - (((dst) & ~0x00000780) | (((u32) (src) << 7) & 0x00000780)) -#define RXTX_REG6_TXAMP_ENA_SET(dst, src) \ - (((dst) & ~0x00000040) | (((u32) (src) << 6) & 0x00000040)) -#define RXTX_REG6_RX_BIST_ERRCNT_RD_SET(dst, src) \ - (((dst) & ~0x00000001) | (((u32) (src) << 0) & 0x00000001)) -#define RXTX_REG6_TX_IDLE_SET(dst, src) \ - (((dst) & ~0x00000008) | (((u32) (src) << 3) & 0x00000008)) -#define RXTX_REG6_RX_BIST_RESYNC_SET(dst, src) \ - (((dst) & ~0x00000002) | (((u32) (src) << 1) & 0x00000002)) -#define RXTX_REG7 0x00e -#define RXTX_REG7_RESETB_RXD_MASK 0x00000100 -#define RXTX_REG7_RESETB_RXA_MASK 0x00000080 -#define RXTX_REG7_BIST_ENA_RX_SET(dst, src) \ - (((dst) & ~0x00000040) | (((u32) (src) << 6) & 0x00000040)) -#define RXTX_REG7_RX_WORD_MODE_SET(dst, src) \ - (((dst) & ~0x00003800) | (((u32) (src) << 11) & 0x00003800)) -#define RXTX_REG8 0x010 -#define RXTX_REG8_CDR_LOOP_ENA_SET(dst, src) \ - (((dst) & ~0x00004000) | (((u32) (src) << 14) & 0x00004000)) -#define RXTX_REG8_CDR_BYPASS_RXLOS_SET(dst, src) \ - (((dst) & ~0x00000800) | (((u32) (src) << 11) & 0x00000800)) -#define RXTX_REG8_SSC_ENABLE_SET(dst, src) \ - (((dst) & ~0x00000200) | (((u32) (src) << 9) & 0x00000200)) -#define RXTX_REG8_SD_VREF_SET(dst, src) \ - (((dst) & ~0x000000f0) | (((u32) (src) << 4) & 0x000000f0)) -#define RXTX_REG8_SD_DISABLE_SET(dst, src) \ - (((dst) & ~0x00000100) | (((u32) (src) << 8) & 0x00000100)) -#define RXTX_REG7 0x00e -#define RXTX_REG7_RESETB_RXD_SET(dst, src) \ - (((dst) & ~0x00000100) | (((u32) (src) << 8) & 0x00000100)) -#define RXTX_REG7_RESETB_RXA_SET(dst, src) \ - (((dst) & ~0x00000080) | (((u32) (src) << 7) & 0x00000080)) -#define RXTX_REG7_LOOP_BACK_ENA_CTLE_MASK 0x00004000 -#define RXTX_REG7_LOOP_BACK_ENA_CTLE_SET(dst, src) \ - (((dst) & ~0x00004000) | (((u32) (src) << 14) & 0x00004000)) -#define RXTX_REG11 0x016 -#define RXTX_REG11_PHASE_ADJUST_LIMIT_SET(dst, src) \ - (((dst) & ~0x0000f800) | (((u32) (src) << 11) & 0x0000f800)) -#define RXTX_REG12 0x018 -#define RXTX_REG12_LATCH_OFF_ENA_SET(dst, src) \ - (((dst) & ~0x00002000) | (((u32) (src) << 13) & 0x00002000)) -#define RXTX_REG12_SUMOS_ENABLE_SET(dst, src) \ - (((dst) & ~0x00000004) | (((u32) (src) << 2) & 0x00000004)) -#define RXTX_REG12_RX_DET_TERM_ENABLE_MASK 0x00000002 -#define RXTX_REG12_RX_DET_TERM_ENABLE_SET(dst, src) \ - (((dst) & ~0x00000002) | (((u32) (src) << 1) & 0x00000002)) -#define RXTX_REG13 0x01a -#define RXTX_REG14 0x01c -#define RXTX_REG14_CLTE_LATCAL_MAN_PROG_SET(dst, src) \ - (((dst) & ~0x0000003f) | (((u32) (src) << 0) & 0x0000003f)) -#define RXTX_REG14_CTLE_LATCAL_MAN_ENA_SET(dst, src) \ - (((dst) & ~0x00000040) | (((u32) (src) << 6) & 0x00000040)) -#define RXTX_REG26 0x034 -#define RXTX_REG26_PERIOD_ERROR_LATCH_SET(dst, src) \ - (((dst) & ~0x00003800) | (((u32) (src) << 11) & 0x00003800)) -#define RXTX_REG26_BLWC_ENA_SET(dst, src) \ - (((dst) & ~0x00000008) | (((u32) (src) << 3) & 0x00000008)) -#define RXTX_REG21 0x02a -#define RXTX_REG21_DO_LATCH_CALOUT_RD(src) ((0x0000fc00 & (u32) (src)) >> 10) -#define RXTX_REG21_XO_LATCH_CALOUT_RD(src) ((0x000003f0 & (u32) (src)) >> 4) -#define RXTX_REG21_LATCH_CAL_FAIL_ODD_RD(src) ((0x0000000f & (u32)(src))) -#define RXTX_REG22 0x02c -#define RXTX_REG22_SO_LATCH_CALOUT_RD(src) ((0x000003f0 & (u32) (src)) >> 4) -#define RXTX_REG22_EO_LATCH_CALOUT_RD(src) ((0x0000fc00 & (u32) (src)) >> 10) -#define RXTX_REG22_LATCH_CAL_FAIL_EVEN_RD(src) ((0x0000000f & (u32)(src))) -#define RXTX_REG23 0x02e -#define RXTX_REG23_DE_LATCH_CALOUT_RD(src) ((0x0000fc00 & (u32) (src)) >> 10) -#define RXTX_REG23_XE_LATCH_CALOUT_RD(src) ((0x000003f0 & (u32) (src)) >> 4) -#define RXTX_REG24 0x030 -#define RXTX_REG24_EE_LATCH_CALOUT_RD(src) ((0x0000fc00 & (u32) (src)) >> 10) -#define RXTX_REG24_SE_LATCH_CALOUT_RD(src) ((0x000003f0 & (u32) (src)) >> 4) -#define RXTX_REG27 0x036 -#define RXTX_REG28 0x038 -#define RXTX_REG31 0x03e -#define RXTX_REG38 0x04c -#define RXTX_REG38_CUSTOMER_PINMODE_INV_SET(dst, src) \ - (((dst) & 0x0000fffe) | (((u32) (src) << 1) & 0x0000fffe)) -#define RXTX_REG39 0x04e -#define RXTX_REG40 0x050 -#define RXTX_REG41 0x052 -#define RXTX_REG42 0x054 -#define RXTX_REG43 0x056 -#define RXTX_REG44 0x058 -#define RXTX_REG45 0x05a -#define RXTX_REG46 0x05c -#define RXTX_REG47 0x05e -#define RXTX_REG48 0x060 -#define RXTX_REG49 0x062 -#define RXTX_REG50 0x064 -#define RXTX_REG51 0x066 -#define RXTX_REG52 0x068 -#define RXTX_REG53 0x06a -#define RXTX_REG54 0x06c -#define RXTX_REG55 0x06e -#define RXTX_REG61 0x07a -#define RXTX_REG61_ISCAN_INBERT_SET(dst, src) \ - (((dst) & ~0x00000010) | (((u32) (src) << 4) & 0x00000010)) -#define RXTX_REG61_LOADFREQ_SHIFT_SET(dst, src) \ - (((dst) & ~0x00000008) | (((u32) (src) << 3) & 0x00000008)) -#define RXTX_REG61_EYE_COUNT_WIDTH_SEL_SET(dst, src) \ - (((dst) & ~0x000000c0) | (((u32) (src) << 6) & 0x000000c0)) -#define RXTX_REG61_SPD_SEL_CDR_SET(dst, src) \ - (((dst) & ~0x00003c00) | (((u32) (src) << 10) & 0x00003c00)) -#define RXTX_REG62 0x07c -#define RXTX_REG62_PERIOD_H1_QLATCH_SET(dst, src) \ - (((dst) & ~0x00003800) | (((u32) (src) << 11) & 0x00003800)) -#define RXTX_REG81 0x0a2 -#define RXTX_REG89_MU_TH7_SET(dst, src) \ - (((dst) & ~0x0000f800) | (((u32) (src) << 11) & 0x0000f800)) -#define RXTX_REG89_MU_TH8_SET(dst, src) \ - (((dst) & ~0x000007c0) | (((u32) (src) << 6) & 0x000007c0)) -#define RXTX_REG89_MU_TH9_SET(dst, src) \ - (((dst) & ~0x0000003e) | (((u32) (src) << 1) & 0x0000003e)) -#define RXTX_REG96 0x0c0 -#define RXTX_REG96_MU_FREQ1_SET(dst, src) \ - (((dst) & ~0x0000f800) | (((u32) (src) << 11) & 0x0000f800)) -#define RXTX_REG96_MU_FREQ2_SET(dst, src) \ - (((dst) & ~0x000007c0) | (((u32) (src) << 6) & 0x000007c0)) -#define RXTX_REG96_MU_FREQ3_SET(dst, src) \ - (((dst) & ~0x0000003e) | (((u32) (src) << 1) & 0x0000003e)) -#define RXTX_REG99 0x0c6 -#define RXTX_REG99_MU_PHASE1_SET(dst, src) \ - (((dst) & ~0x0000f800) | (((u32) (src) << 11) & 0x0000f800)) -#define RXTX_REG99_MU_PHASE2_SET(dst, src) \ - (((dst) & ~0x000007c0) | (((u32) (src) << 6) & 0x000007c0)) -#define RXTX_REG99_MU_PHASE3_SET(dst, src) \ - (((dst) & ~0x0000003e) | (((u32) (src) << 1) & 0x0000003e)) -#define RXTX_REG102 0x0cc -#define RXTX_REG102_FREQLOOP_LIMIT_SET(dst, src) \ - (((dst) & ~0x00000060) | (((u32) (src) << 5) & 0x00000060)) -#define RXTX_REG114 0x0e4 -#define RXTX_REG121 0x0f2 -#define RXTX_REG121_SUMOS_CAL_CODE_RD(src) ((0x0000003e & (u32)(src)) >> 0x1) -#define RXTX_REG125 0x0fa -#define RXTX_REG125_PQ_REG_SET(dst, src) \ - (((dst) & ~0x0000fe00) | (((u32) (src) << 9) & 0x0000fe00)) -#define RXTX_REG125_SIGN_PQ_SET(dst, src) \ - (((dst) & ~0x00000100) | (((u32) (src) << 8) & 0x00000100)) -#define RXTX_REG125_SIGN_PQ_2C_SET(dst, src) \ - (((dst) & ~0x00000080) | (((u32) (src) << 7) & 0x00000080)) -#define RXTX_REG125_PHZ_MANUALCODE_SET(dst, src) \ - (((dst) & ~0x0000007c) | (((u32) (src) << 2) & 0x0000007c)) -#define RXTX_REG125_PHZ_MANUAL_SET(dst, src) \ - (((dst) & ~0x00000002) | (((u32) (src) << 1) & 0x00000002)) -#define RXTX_REG127 0x0fe -#define RXTX_REG127_FORCE_SUM_CAL_START_MASK 0x00000002 -#define RXTX_REG127_FORCE_LAT_CAL_START_MASK 0x00000004 -#define RXTX_REG127_FORCE_SUM_CAL_START_SET(dst, src) \ - (((dst) & ~0x00000002) | (((u32) (src) << 1) & 0x00000002)) -#define RXTX_REG127_FORCE_LAT_CAL_START_SET(dst, src) \ - (((dst) & ~0x00000004) | (((u32) (src) << 2) & 0x00000004)) -#define RXTX_REG127_LATCH_MAN_CAL_ENA_SET(dst, src) \ - (((dst) & ~0x00000008) | (((u32) (src) << 3) & 0x00000008)) -#define RXTX_REG127_DO_LATCH_MANCAL_SET(dst, src) \ - (((dst) & ~0x0000fc00) | (((u32) (src) << 10) & 0x0000fc00)) -#define RXTX_REG127_XO_LATCH_MANCAL_SET(dst, src) \ - (((dst) & ~0x000003f0) | (((u32) (src) << 4) & 0x000003f0)) -#define RXTX_REG128 0x100 -#define RXTX_REG128_LATCH_CAL_WAIT_SEL_SET(dst, src) \ - (((dst) & ~0x0000000c) | (((u32) (src) << 2) & 0x0000000c)) -#define RXTX_REG128_EO_LATCH_MANCAL_SET(dst, src) \ - (((dst) & ~0x0000fc00) | (((u32) (src) << 10) & 0x0000fc00)) -#define RXTX_REG128_SO_LATCH_MANCAL_SET(dst, src) \ - (((dst) & ~0x000003f0) | (((u32) (src) << 4) & 0x000003f0)) -#define RXTX_REG129 0x102 -#define RXTX_REG129_DE_LATCH_MANCAL_SET(dst, src) \ - (((dst) & ~0x0000fc00) | (((u32) (src) << 10) & 0x0000fc00)) -#define RXTX_REG129_XE_LATCH_MANCAL_SET(dst, src) \ - (((dst) & ~0x000003f0) | (((u32) (src) << 4) & 0x000003f0)) -#define RXTX_REG130 0x104 -#define RXTX_REG130_EE_LATCH_MANCAL_SET(dst, src) \ - (((dst) & ~0x0000fc00) | (((u32) (src) << 10) & 0x0000fc00)) -#define RXTX_REG130_SE_LATCH_MANCAL_SET(dst, src) \ - (((dst) & ~0x000003f0) | (((u32) (src) << 4) & 0x000003f0)) -#define RXTX_REG145 0x122 -#define RXTX_REG145_TX_IDLE_SATA_SET(dst, src) \ - (((dst) & ~0x00000001) | (((u32) (src) << 0) & 0x00000001)) -#define RXTX_REG145_RXES_ENA_SET(dst, src) \ - (((dst) & ~0x00000002) | (((u32) (src) << 1) & 0x00000002)) -#define RXTX_REG145_RXDFE_CONFIG_SET(dst, src) \ - (((dst) & ~0x0000c000) | (((u32) (src) << 14) & 0x0000c000)) -#define RXTX_REG145_RXVWES_LATENA_SET(dst, src) \ - (((dst) & ~0x00000004) | (((u32) (src) << 2) & 0x00000004)) -#define RXTX_REG147 0x126 -#define RXTX_REG148 0x128 - -/* Clock macro type */ -enum cmu_type_t { - REF_CMU = 0, /* Clock macro is the internal reference clock */ - PHY_CMU = 1, /* Clock macro is the PLL for the Serdes */ -}; - -enum mux_type_t { - MUX_SELECT_ATA = 0, /* Switch the MUX to ATA */ - MUX_SELECT_SGMMII = 0, /* Switch the MUX to SGMII */ -}; - -enum clk_type_t { - CLK_EXT_DIFF = 0, /* External differential */ - CLK_INT_DIFF = 1, /* Internal differential */ - CLK_INT_SING = 2, /* Internal single ended */ -}; - -enum phy_mode { - MODE_SATA = 0, /* List them for simple reference */ - MODE_SGMII = 1, - MODE_PCIE = 2, - MODE_USB = 3, - MODE_XFI = 4, - MODE_MAX -}; - -struct xgene_sata_override_param { - u32 speed[MAX_LANE]; /* Index for override parameter per lane */ - u32 txspeed[3]; /* Tx speed */ - u32 txboostgain[MAX_LANE*3]; /* Tx freq boost and gain control */ - u32 txeyetuning[MAX_LANE*3]; /* Tx eye tuning */ - u32 txeyedirection[MAX_LANE*3]; /* Tx eye tuning direction */ - u32 txamplitude[MAX_LANE*3]; /* Tx amplitude control */ - u32 txprecursor_cn1[MAX_LANE*3]; /* Tx emphasis taps 1st pre-cursor */ - u32 txprecursor_cn2[MAX_LANE*3]; /* Tx emphasis taps 2nd pre-cursor */ - u32 txpostcursor_cp1[MAX_LANE*3]; /* Tx emphasis taps post-cursor */ -}; - -struct xgene_phy_ctx { - struct device *dev; - struct phy *phy; - enum phy_mode mode; /* Mode of operation */ - enum clk_type_t clk_type; /* Input clock selection */ - void __iomem *sds_base; /* PHY CSR base addr */ - struct clk *clk; /* Optional clock */ - - /* Override Serdes parameters */ - struct xgene_sata_override_param sata_param; -}; - -/* - * For chip earlier than A3 version, enable this flag. - * To enable, pass boot argument phy_xgene.preA3Chip=1 - */ -static int preA3Chip; -MODULE_PARM_DESC(preA3Chip, "Enable pre-A3 chip support (1=enable 0=disable)"); -module_param_named(preA3Chip, preA3Chip, int, 0444); - -static void sds_wr(void __iomem *csr_base, u32 indirect_cmd_reg, - u32 indirect_data_reg, u32 addr, u32 data) -{ - unsigned long deadline = jiffies + HZ; - u32 val; - u32 cmd; - - cmd = CFG_IND_WR_CMD_MASK | CFG_IND_CMD_DONE_MASK; - cmd = CFG_IND_ADDR_SET(cmd, addr); - writel(data, csr_base + indirect_data_reg); - readl(csr_base + indirect_data_reg); /* Force a barrier */ - writel(cmd, csr_base + indirect_cmd_reg); - readl(csr_base + indirect_cmd_reg); /* Force a barrier */ - do { - val = readl(csr_base + indirect_cmd_reg); - } while (!(val & CFG_IND_CMD_DONE_MASK) && - time_before(jiffies, deadline)); - if (!(val & CFG_IND_CMD_DONE_MASK)) - pr_err("SDS WR timeout at 0x%p offset 0x%08X value 0x%08X\n", - csr_base + indirect_cmd_reg, addr, data); -} - -static void sds_rd(void __iomem *csr_base, u32 indirect_cmd_reg, - u32 indirect_data_reg, u32 addr, u32 *data) -{ - unsigned long deadline = jiffies + HZ; - u32 val; - u32 cmd; - - cmd = CFG_IND_RD_CMD_MASK | CFG_IND_CMD_DONE_MASK; - cmd = CFG_IND_ADDR_SET(cmd, addr); - writel(cmd, csr_base + indirect_cmd_reg); - readl(csr_base + indirect_cmd_reg); /* Force a barrier */ - do { - val = readl(csr_base + indirect_cmd_reg); - } while (!(val & CFG_IND_CMD_DONE_MASK) && - time_before(jiffies, deadline)); - *data = readl(csr_base + indirect_data_reg); - if (!(val & CFG_IND_CMD_DONE_MASK)) - pr_err("SDS WR timeout at 0x%p offset 0x%08X value 0x%08X\n", - csr_base + indirect_cmd_reg, addr, *data); -} - -static void cmu_wr(struct xgene_phy_ctx *ctx, enum cmu_type_t cmu_type, - u32 reg, u32 data) -{ - void __iomem *sds_base = ctx->sds_base; - u32 val; - - if (cmu_type == REF_CMU) - reg += SERDES_PLL_REF_INDIRECT_OFFSET; - else - reg += SERDES_PLL_INDIRECT_OFFSET; - sds_wr(sds_base, SATA_ENET_SDS_IND_CMD_REG, - SATA_ENET_SDS_IND_WDATA_REG, reg, data); - sds_rd(sds_base, SATA_ENET_SDS_IND_CMD_REG, - SATA_ENET_SDS_IND_RDATA_REG, reg, &val); - pr_debug("CMU WR addr 0x%X value 0x%08X <-> 0x%08X\n", reg, data, val); -} - -static void cmu_rd(struct xgene_phy_ctx *ctx, enum cmu_type_t cmu_type, - u32 reg, u32 *data) -{ - void __iomem *sds_base = ctx->sds_base; - - if (cmu_type == REF_CMU) - reg += SERDES_PLL_REF_INDIRECT_OFFSET; - else - reg += SERDES_PLL_INDIRECT_OFFSET; - sds_rd(sds_base, SATA_ENET_SDS_IND_CMD_REG, - SATA_ENET_SDS_IND_RDATA_REG, reg, data); - pr_debug("CMU RD addr 0x%X value 0x%08X\n", reg, *data); -} - -static void cmu_toggle1to0(struct xgene_phy_ctx *ctx, enum cmu_type_t cmu_type, - u32 reg, u32 bits) -{ - u32 val; - - cmu_rd(ctx, cmu_type, reg, &val); - val |= bits; - cmu_wr(ctx, cmu_type, reg, val); - cmu_rd(ctx, cmu_type, reg, &val); - val &= ~bits; - cmu_wr(ctx, cmu_type, reg, val); -} - -static void cmu_clrbits(struct xgene_phy_ctx *ctx, enum cmu_type_t cmu_type, - u32 reg, u32 bits) -{ - u32 val; - - cmu_rd(ctx, cmu_type, reg, &val); - val &= ~bits; - cmu_wr(ctx, cmu_type, reg, val); -} - -static void cmu_setbits(struct xgene_phy_ctx *ctx, enum cmu_type_t cmu_type, - u32 reg, u32 bits) -{ - u32 val; - - cmu_rd(ctx, cmu_type, reg, &val); - val |= bits; - cmu_wr(ctx, cmu_type, reg, val); -} - -static void serdes_wr(struct xgene_phy_ctx *ctx, int lane, u32 reg, u32 data) -{ - void __iomem *sds_base = ctx->sds_base; - u32 val; - - reg += SERDES_INDIRECT_OFFSET; - reg += lane * SERDES_LANE_STRIDE; - sds_wr(sds_base, SATA_ENET_SDS_IND_CMD_REG, - SATA_ENET_SDS_IND_WDATA_REG, reg, data); - sds_rd(sds_base, SATA_ENET_SDS_IND_CMD_REG, - SATA_ENET_SDS_IND_RDATA_REG, reg, &val); - pr_debug("SERDES WR addr 0x%X value 0x%08X <-> 0x%08X\n", reg, data, - val); -} - -static void serdes_rd(struct xgene_phy_ctx *ctx, int lane, u32 reg, u32 *data) -{ - void __iomem *sds_base = ctx->sds_base; - - reg += SERDES_INDIRECT_OFFSET; - reg += lane * SERDES_LANE_STRIDE; - sds_rd(sds_base, SATA_ENET_SDS_IND_CMD_REG, - SATA_ENET_SDS_IND_RDATA_REG, reg, data); - pr_debug("SERDES RD addr 0x%X value 0x%08X\n", reg, *data); -} - -static void serdes_clrbits(struct xgene_phy_ctx *ctx, int lane, u32 reg, - u32 bits) -{ - u32 val; - - serdes_rd(ctx, lane, reg, &val); - val &= ~bits; - serdes_wr(ctx, lane, reg, val); -} - -static void serdes_setbits(struct xgene_phy_ctx *ctx, int lane, u32 reg, - u32 bits) -{ - u32 val; - - serdes_rd(ctx, lane, reg, &val); - val |= bits; - serdes_wr(ctx, lane, reg, val); -} - -static void xgene_phy_cfg_cmu_clk_type(struct xgene_phy_ctx *ctx, - enum cmu_type_t cmu_type, - enum clk_type_t clk_type) -{ - u32 val; - - /* Set the reset sequence delay for TX ready assertion */ - cmu_rd(ctx, cmu_type, CMU_REG12, &val); - val = CMU_REG12_STATE_DELAY9_SET(val, 0x1); - cmu_wr(ctx, cmu_type, CMU_REG12, val); - /* Set the programmable stage delays between various enable stages */ - cmu_wr(ctx, cmu_type, CMU_REG13, 0x0222); - cmu_wr(ctx, cmu_type, CMU_REG14, 0x2225); - - /* Configure clock type */ - if (clk_type == CLK_EXT_DIFF) { - /* Select external clock mux */ - cmu_rd(ctx, cmu_type, CMU_REG0, &val); - val = CMU_REG0_PLL_REF_SEL_SET(val, 0x0); - cmu_wr(ctx, cmu_type, CMU_REG0, val); - /* Select CMOS as reference clock */ - cmu_rd(ctx, cmu_type, CMU_REG1, &val); - val = CMU_REG1_REFCLK_CMOS_SEL_SET(val, 0x0); - cmu_wr(ctx, cmu_type, CMU_REG1, val); - dev_dbg(ctx->dev, "Set external reference clock\n"); - } else if (clk_type == CLK_INT_DIFF) { - /* Select internal clock mux */ - cmu_rd(ctx, cmu_type, CMU_REG0, &val); - val = CMU_REG0_PLL_REF_SEL_SET(val, 0x1); - cmu_wr(ctx, cmu_type, CMU_REG0, val); - /* Select CMOS as reference clock */ - cmu_rd(ctx, cmu_type, CMU_REG1, &val); - val = CMU_REG1_REFCLK_CMOS_SEL_SET(val, 0x1); - cmu_wr(ctx, cmu_type, CMU_REG1, val); - dev_dbg(ctx->dev, "Set internal reference clock\n"); - } else if (clk_type == CLK_INT_SING) { - /* - * NOTE: This clock type is NOT support for controller - * whose internal clock shared in the PCIe controller - * - * Select internal clock mux - */ - cmu_rd(ctx, cmu_type, CMU_REG1, &val); - val = CMU_REG1_REFCLK_CMOS_SEL_SET(val, 0x1); - cmu_wr(ctx, cmu_type, CMU_REG1, val); - /* Select CML as reference clock */ - cmu_rd(ctx, cmu_type, CMU_REG1, &val); - val = CMU_REG1_REFCLK_CMOS_SEL_SET(val, 0x0); - cmu_wr(ctx, cmu_type, CMU_REG1, val); - dev_dbg(ctx->dev, - "Set internal single ended reference clock\n"); - } -} - -static void xgene_phy_sata_cfg_cmu_core(struct xgene_phy_ctx *ctx, - enum cmu_type_t cmu_type, - enum clk_type_t clk_type) -{ - u32 val; - int ref_100MHz; - - if (cmu_type == REF_CMU) { - /* Set VCO calibration voltage threshold */ - cmu_rd(ctx, cmu_type, CMU_REG34, &val); - val = CMU_REG34_VCO_CAL_VTH_LO_MAX_SET(val, 0x7); - val = CMU_REG34_VCO_CAL_VTH_HI_MAX_SET(val, 0xc); - val = CMU_REG34_VCO_CAL_VTH_LO_MIN_SET(val, 0x3); - val = CMU_REG34_VCO_CAL_VTH_HI_MIN_SET(val, 0x8); - cmu_wr(ctx, cmu_type, CMU_REG34, val); - } - - /* Set the VCO calibration counter */ - cmu_rd(ctx, cmu_type, CMU_REG0, &val); - if (cmu_type == REF_CMU || preA3Chip) - val = CMU_REG0_CAL_COUNT_RESOL_SET(val, 0x4); - else - val = CMU_REG0_CAL_COUNT_RESOL_SET(val, 0x7); - cmu_wr(ctx, cmu_type, CMU_REG0, val); - - /* Configure PLL for calibration */ - cmu_rd(ctx, cmu_type, CMU_REG1, &val); - val = CMU_REG1_PLL_CP_SET(val, 0x1); - if (cmu_type == REF_CMU || preA3Chip) - val = CMU_REG1_PLL_CP_SEL_SET(val, 0x5); - else - val = CMU_REG1_PLL_CP_SEL_SET(val, 0x3); - if (cmu_type == REF_CMU) - val = CMU_REG1_PLL_MANUALCAL_SET(val, 0x0); - else - val = CMU_REG1_PLL_MANUALCAL_SET(val, 0x1); - cmu_wr(ctx, cmu_type, CMU_REG1, val); - - if (cmu_type != REF_CMU) - cmu_clrbits(ctx, cmu_type, CMU_REG5, CMU_REG5_PLL_RESETB_MASK); - - /* Configure the PLL for either 100MHz or 50MHz */ - cmu_rd(ctx, cmu_type, CMU_REG2, &val); - if (cmu_type == REF_CMU) { - val = CMU_REG2_PLL_LFRES_SET(val, 0xa); - ref_100MHz = 1; - } else { - val = CMU_REG2_PLL_LFRES_SET(val, 0x3); - if (clk_type == CLK_EXT_DIFF) - ref_100MHz = 0; - else - ref_100MHz = 1; - } - if (ref_100MHz) { - val = CMU_REG2_PLL_FBDIV_SET(val, FBDIV_VAL_100M); - val = CMU_REG2_PLL_REFDIV_SET(val, REFDIV_VAL_100M); - } else { - val = CMU_REG2_PLL_FBDIV_SET(val, FBDIV_VAL_50M); - val = CMU_REG2_PLL_REFDIV_SET(val, REFDIV_VAL_50M); - } - cmu_wr(ctx, cmu_type, CMU_REG2, val); - - /* Configure the VCO */ - cmu_rd(ctx, cmu_type, CMU_REG3, &val); - if (cmu_type == REF_CMU) { - val = CMU_REG3_VCOVARSEL_SET(val, 0x3); - val = CMU_REG3_VCO_MOMSEL_INIT_SET(val, 0x10); - } else { - val = CMU_REG3_VCOVARSEL_SET(val, 0xF); - if (preA3Chip) - val = CMU_REG3_VCO_MOMSEL_INIT_SET(val, 0x15); - else - val = CMU_REG3_VCO_MOMSEL_INIT_SET(val, 0x1a); - val = CMU_REG3_VCO_MANMOMSEL_SET(val, 0x15); - } - cmu_wr(ctx, cmu_type, CMU_REG3, val); - - /* Disable force PLL lock */ - cmu_rd(ctx, cmu_type, CMU_REG26, &val); - val = CMU_REG26_FORCE_PLL_LOCK_SET(val, 0x0); - cmu_wr(ctx, cmu_type, CMU_REG26, val); - - /* Setup PLL loop filter */ - cmu_rd(ctx, cmu_type, CMU_REG5, &val); - val = CMU_REG5_PLL_LFSMCAP_SET(val, 0x3); - val = CMU_REG5_PLL_LFCAP_SET(val, 0x3); - if (cmu_type == REF_CMU || !preA3Chip) - val = CMU_REG5_PLL_LOCK_RESOLUTION_SET(val, 0x7); - else - val = CMU_REG5_PLL_LOCK_RESOLUTION_SET(val, 0x4); - cmu_wr(ctx, cmu_type, CMU_REG5, val); - - /* Enable or disable manual calibration */ - cmu_rd(ctx, cmu_type, CMU_REG6, &val); - val = CMU_REG6_PLL_VREGTRIM_SET(val, preA3Chip ? 0x0 : 0x2); - val = CMU_REG6_MAN_PVT_CAL_SET(val, preA3Chip ? 0x1 : 0x0); - cmu_wr(ctx, cmu_type, CMU_REG6, val); - - /* Configure lane for 20-bits */ - if (cmu_type == PHY_CMU) { - cmu_rd(ctx, cmu_type, CMU_REG9, &val); - val = CMU_REG9_TX_WORD_MODE_CH1_SET(val, - CMU_REG9_WORD_LEN_20BIT); - val = CMU_REG9_TX_WORD_MODE_CH0_SET(val, - CMU_REG9_WORD_LEN_20BIT); - val = CMU_REG9_PLL_POST_DIVBY2_SET(val, 0x1); - if (!preA3Chip) { - val = CMU_REG9_VBG_BYPASSB_SET(val, 0x0); - val = CMU_REG9_IGEN_BYPASS_SET(val , 0x0); - } - cmu_wr(ctx, cmu_type, CMU_REG9, val); - - if (!preA3Chip) { - cmu_rd(ctx, cmu_type, CMU_REG10, &val); - val = CMU_REG10_VREG_REFSEL_SET(val, 0x1); - cmu_wr(ctx, cmu_type, CMU_REG10, val); - } - } - - cmu_rd(ctx, cmu_type, CMU_REG16, &val); - val = CMU_REG16_CALIBRATION_DONE_OVERRIDE_SET(val, 0x1); - val = CMU_REG16_BYPASS_PLL_LOCK_SET(val, 0x1); - if (cmu_type == REF_CMU || preA3Chip) - val = CMU_REG16_VCOCAL_WAIT_BTW_CODE_SET(val, 0x4); - else - val = CMU_REG16_VCOCAL_WAIT_BTW_CODE_SET(val, 0x7); - cmu_wr(ctx, cmu_type, CMU_REG16, val); - - /* Configure for SATA */ - cmu_rd(ctx, cmu_type, CMU_REG30, &val); - val = CMU_REG30_PCIE_MODE_SET(val, 0x0); - val = CMU_REG30_LOCK_COUNT_SET(val, 0x3); - cmu_wr(ctx, cmu_type, CMU_REG30, val); - - /* Disable state machine bypass */ - cmu_wr(ctx, cmu_type, CMU_REG31, 0xF); - - cmu_rd(ctx, cmu_type, CMU_REG32, &val); - val = CMU_REG32_PVT_CAL_WAIT_SEL_SET(val, 0x3); - if (cmu_type == REF_CMU || preA3Chip) - val = CMU_REG32_IREF_ADJ_SET(val, 0x3); - else - val = CMU_REG32_IREF_ADJ_SET(val, 0x1); - cmu_wr(ctx, cmu_type, CMU_REG32, val); - - /* Set VCO calibration threshold */ - if (cmu_type != REF_CMU && preA3Chip) - cmu_wr(ctx, cmu_type, CMU_REG34, 0x8d27); - else - cmu_wr(ctx, cmu_type, CMU_REG34, 0x873c); - - /* Set CTLE Override and override waiting from state machine */ - cmu_wr(ctx, cmu_type, CMU_REG37, 0xF00F); -} - -static void xgene_phy_ssc_enable(struct xgene_phy_ctx *ctx, - enum cmu_type_t cmu_type) -{ - u32 val; - - /* Set SSC modulation value */ - cmu_rd(ctx, cmu_type, CMU_REG35, &val); - val = CMU_REG35_PLL_SSC_MOD_SET(val, 98); - cmu_wr(ctx, cmu_type, CMU_REG35, val); - - /* Enable SSC, set vertical step and DSM value */ - cmu_rd(ctx, cmu_type, CMU_REG36, &val); - val = CMU_REG36_PLL_SSC_VSTEP_SET(val, 30); - val = CMU_REG36_PLL_SSC_EN_SET(val, 1); - val = CMU_REG36_PLL_SSC_DSMSEL_SET(val, 1); - cmu_wr(ctx, cmu_type, CMU_REG36, val); - - /* Reset the PLL */ - cmu_clrbits(ctx, cmu_type, CMU_REG5, CMU_REG5_PLL_RESETB_MASK); - cmu_setbits(ctx, cmu_type, CMU_REG5, CMU_REG5_PLL_RESETB_MASK); - - /* Force VCO calibration to restart */ - cmu_toggle1to0(ctx, cmu_type, CMU_REG32, - CMU_REG32_FORCE_VCOCAL_START_MASK); -} - -static void xgene_phy_sata_cfg_lanes(struct xgene_phy_ctx *ctx) -{ - u32 val; - u32 reg; - int i; - int lane; - - for (lane = 0; lane < MAX_LANE; lane++) { - serdes_wr(ctx, lane, RXTX_REG147, 0x6); - - /* Set boost control for quarter, half, and full rate */ - serdes_rd(ctx, lane, RXTX_REG0, &val); - val = RXTX_REG0_CTLE_EQ_HR_SET(val, 0x10); - val = RXTX_REG0_CTLE_EQ_QR_SET(val, 0x10); - val = RXTX_REG0_CTLE_EQ_FR_SET(val, 0x10); - serdes_wr(ctx, lane, RXTX_REG0, val); - - /* Set boost control value */ - serdes_rd(ctx, lane, RXTX_REG1, &val); - val = RXTX_REG1_RXACVCM_SET(val, 0x7); - val = RXTX_REG1_CTLE_EQ_SET(val, - ctx->sata_param.txboostgain[lane * 3 + - ctx->sata_param.speed[lane]]); - serdes_wr(ctx, lane, RXTX_REG1, val); - - /* Latch VTT value based on the termination to ground and - enable TX FIFO */ - serdes_rd(ctx, lane, RXTX_REG2, &val); - val = RXTX_REG2_VTT_ENA_SET(val, 0x1); - val = RXTX_REG2_VTT_SEL_SET(val, 0x1); - val = RXTX_REG2_TX_FIFO_ENA_SET(val, 0x1); - serdes_wr(ctx, lane, RXTX_REG2, val); - - /* Configure Tx for 20-bits */ - serdes_rd(ctx, lane, RXTX_REG4, &val); - val = RXTX_REG4_TX_WORD_MODE_SET(val, CMU_REG9_WORD_LEN_20BIT); - serdes_wr(ctx, lane, RXTX_REG4, val); - - if (!preA3Chip) { - serdes_rd(ctx, lane, RXTX_REG1, &val); - val = RXTX_REG1_RXVREG1_SET(val, 0x2); - val = RXTX_REG1_RXIREF_ADJ_SET(val, 0x2); - serdes_wr(ctx, lane, RXTX_REG1, val); - } - - /* Set pre-emphasis first 1 and 2, and post-emphasis values */ - serdes_rd(ctx, lane, RXTX_REG5, &val); - val = RXTX_REG5_TX_CN1_SET(val, - ctx->sata_param.txprecursor_cn1[lane * 3 + - ctx->sata_param.speed[lane]]); - val = RXTX_REG5_TX_CP1_SET(val, - ctx->sata_param.txpostcursor_cp1[lane * 3 + - ctx->sata_param.speed[lane]]); - val = RXTX_REG5_TX_CN2_SET(val, - ctx->sata_param.txprecursor_cn2[lane * 3 + - ctx->sata_param.speed[lane]]); - serdes_wr(ctx, lane, RXTX_REG5, val); - - /* Set TX amplitude value */ - serdes_rd(ctx, lane, RXTX_REG6, &val); - val = RXTX_REG6_TXAMP_CNTL_SET(val, - ctx->sata_param.txamplitude[lane * 3 + - ctx->sata_param.speed[lane]]); - val = RXTX_REG6_TXAMP_ENA_SET(val, 0x1); - val = RXTX_REG6_TX_IDLE_SET(val, 0x0); - val = RXTX_REG6_RX_BIST_RESYNC_SET(val, 0x0); - val = RXTX_REG6_RX_BIST_ERRCNT_RD_SET(val, 0x0); - serdes_wr(ctx, lane, RXTX_REG6, val); - - /* Configure Rx for 20-bits */ - serdes_rd(ctx, lane, RXTX_REG7, &val); - val = RXTX_REG7_BIST_ENA_RX_SET(val, 0x0); - val = RXTX_REG7_RX_WORD_MODE_SET(val, CMU_REG9_WORD_LEN_20BIT); - serdes_wr(ctx, lane, RXTX_REG7, val); - - /* Set CDR and LOS values and enable Rx SSC */ - serdes_rd(ctx, lane, RXTX_REG8, &val); - val = RXTX_REG8_CDR_LOOP_ENA_SET(val, 0x1); - val = RXTX_REG8_CDR_BYPASS_RXLOS_SET(val, 0x0); - val = RXTX_REG8_SSC_ENABLE_SET(val, 0x1); - val = RXTX_REG8_SD_DISABLE_SET(val, 0x0); - val = RXTX_REG8_SD_VREF_SET(val, 0x4); - serdes_wr(ctx, lane, RXTX_REG8, val); - - /* Set phase adjust upper/lower limits */ - serdes_rd(ctx, lane, RXTX_REG11, &val); - val = RXTX_REG11_PHASE_ADJUST_LIMIT_SET(val, 0x0); - serdes_wr(ctx, lane, RXTX_REG11, val); - - /* Enable Latch Off; disable SUMOS and Tx termination */ - serdes_rd(ctx, lane, RXTX_REG12, &val); - val = RXTX_REG12_LATCH_OFF_ENA_SET(val, 0x1); - val = RXTX_REG12_SUMOS_ENABLE_SET(val, 0x0); - val = RXTX_REG12_RX_DET_TERM_ENABLE_SET(val, 0x0); - serdes_wr(ctx, lane, RXTX_REG12, val); - - /* Set period error latch to 512T and enable BWL */ - serdes_rd(ctx, lane, RXTX_REG26, &val); - val = RXTX_REG26_PERIOD_ERROR_LATCH_SET(val, 0x0); - val = RXTX_REG26_BLWC_ENA_SET(val, 0x1); - serdes_wr(ctx, lane, RXTX_REG26, val); - - serdes_wr(ctx, lane, RXTX_REG28, 0x0); - - /* Set DFE loop preset value */ - serdes_wr(ctx, lane, RXTX_REG31, 0x0); - - /* Set Eye Monitor counter width to 12-bit */ - serdes_rd(ctx, lane, RXTX_REG61, &val); - val = RXTX_REG61_ISCAN_INBERT_SET(val, 0x1); - val = RXTX_REG61_LOADFREQ_SHIFT_SET(val, 0x0); - val = RXTX_REG61_EYE_COUNT_WIDTH_SEL_SET(val, 0x0); - serdes_wr(ctx, lane, RXTX_REG61, val); - - serdes_rd(ctx, lane, RXTX_REG62, &val); - val = RXTX_REG62_PERIOD_H1_QLATCH_SET(val, 0x0); - serdes_wr(ctx, lane, RXTX_REG62, val); - - /* Set BW select tap X for DFE loop */ - for (i = 0; i < 9; i++) { - reg = RXTX_REG81 + i * 2; - serdes_rd(ctx, lane, reg, &val); - val = RXTX_REG89_MU_TH7_SET(val, 0xe); - val = RXTX_REG89_MU_TH8_SET(val, 0xe); - val = RXTX_REG89_MU_TH9_SET(val, 0xe); - serdes_wr(ctx, lane, reg, val); - } - - /* Set BW select tap X for frequency adjust loop */ - for (i = 0; i < 3; i++) { - reg = RXTX_REG96 + i * 2; - serdes_rd(ctx, lane, reg, &val); - val = RXTX_REG96_MU_FREQ1_SET(val, 0x10); - val = RXTX_REG96_MU_FREQ2_SET(val, 0x10); - val = RXTX_REG96_MU_FREQ3_SET(val, 0x10); - serdes_wr(ctx, lane, reg, val); - } - - /* Set BW select tap X for phase adjust loop */ - for (i = 0; i < 3; i++) { - reg = RXTX_REG99 + i * 2; - serdes_rd(ctx, lane, reg, &val); - val = RXTX_REG99_MU_PHASE1_SET(val, 0x7); - val = RXTX_REG99_MU_PHASE2_SET(val, 0x7); - val = RXTX_REG99_MU_PHASE3_SET(val, 0x7); - serdes_wr(ctx, lane, reg, val); - } - - serdes_rd(ctx, lane, RXTX_REG102, &val); - val = RXTX_REG102_FREQLOOP_LIMIT_SET(val, 0x0); - serdes_wr(ctx, lane, RXTX_REG102, val); - - serdes_wr(ctx, lane, RXTX_REG114, 0xffe0); - - serdes_rd(ctx, lane, RXTX_REG125, &val); - val = RXTX_REG125_SIGN_PQ_SET(val, - ctx->sata_param.txeyedirection[lane * 3 + - ctx->sata_param.speed[lane]]); - val = RXTX_REG125_PQ_REG_SET(val, - ctx->sata_param.txeyetuning[lane * 3 + - ctx->sata_param.speed[lane]]); - val = RXTX_REG125_PHZ_MANUAL_SET(val, 0x1); - serdes_wr(ctx, lane, RXTX_REG125, val); - - serdes_rd(ctx, lane, RXTX_REG127, &val); - val = RXTX_REG127_LATCH_MAN_CAL_ENA_SET(val, 0x0); - serdes_wr(ctx, lane, RXTX_REG127, val); - - serdes_rd(ctx, lane, RXTX_REG128, &val); - val = RXTX_REG128_LATCH_CAL_WAIT_SEL_SET(val, 0x3); - serdes_wr(ctx, lane, RXTX_REG128, val); - - serdes_rd(ctx, lane, RXTX_REG145, &val); - val = RXTX_REG145_RXDFE_CONFIG_SET(val, 0x3); - val = RXTX_REG145_TX_IDLE_SATA_SET(val, 0x0); - if (preA3Chip) { - val = RXTX_REG145_RXES_ENA_SET(val, 0x1); - val = RXTX_REG145_RXVWES_LATENA_SET(val, 0x1); - } else { - val = RXTX_REG145_RXES_ENA_SET(val, 0x0); - val = RXTX_REG145_RXVWES_LATENA_SET(val, 0x0); - } - serdes_wr(ctx, lane, RXTX_REG145, val); - - /* - * Set Rx LOS filter clock rate, sample rate, and threshold - * windows - */ - for (i = 0; i < 4; i++) { - reg = RXTX_REG148 + i * 2; - serdes_wr(ctx, lane, reg, 0xFFFF); - } - } -} - -static int xgene_phy_cal_rdy_chk(struct xgene_phy_ctx *ctx, - enum cmu_type_t cmu_type, - enum clk_type_t clk_type) -{ - void __iomem *csr_serdes = ctx->sds_base; - int loop; - u32 val; - - /* Release PHY main reset */ - writel(0xdf, csr_serdes + SATA_ENET_SDS_RST_CTL); - readl(csr_serdes + SATA_ENET_SDS_RST_CTL); /* Force a barrier */ - - if (cmu_type != REF_CMU) { - cmu_setbits(ctx, cmu_type, CMU_REG5, CMU_REG5_PLL_RESETB_MASK); - /* - * As per PHY design spec, the PLL reset requires a minimum - * of 800us. - */ - usleep_range(800, 1000); - - cmu_rd(ctx, cmu_type, CMU_REG1, &val); - val = CMU_REG1_PLL_MANUALCAL_SET(val, 0x0); - cmu_wr(ctx, cmu_type, CMU_REG1, val); - /* - * As per PHY design spec, the PLL auto calibration requires - * a minimum of 800us. - */ - usleep_range(800, 1000); - - cmu_toggle1to0(ctx, cmu_type, CMU_REG32, - CMU_REG32_FORCE_VCOCAL_START_MASK); - /* - * As per PHY design spec, the PLL requires a minimum of - * 800us to settle. - */ - usleep_range(800, 1000); - } - - if (!preA3Chip) - goto skip_manual_cal; - - /* - * Configure the termination resister calibration - * The serial receive pins, RXP/RXN, have TERMination resistor - * that is required to be calibrated. - */ - cmu_rd(ctx, cmu_type, CMU_REG17, &val); - val = CMU_REG17_PVT_CODE_R2A_SET(val, 0x12); - val = CMU_REG17_RESERVED_7_SET(val, 0x0); - cmu_wr(ctx, cmu_type, CMU_REG17, val); - cmu_toggle1to0(ctx, cmu_type, CMU_REG17, - CMU_REG17_PVT_TERM_MAN_ENA_MASK); - /* - * The serial transmit pins, TXP/TXN, have Pull-UP and Pull-DOWN - * resistors that are required to the calibrated. - * Configure the pull DOWN calibration - */ - cmu_rd(ctx, cmu_type, CMU_REG17, &val); - val = CMU_REG17_PVT_CODE_R2A_SET(val, 0x29); - val = CMU_REG17_RESERVED_7_SET(val, 0x0); - cmu_wr(ctx, cmu_type, CMU_REG17, val); - cmu_toggle1to0(ctx, cmu_type, CMU_REG16, - CMU_REG16_PVT_DN_MAN_ENA_MASK); - /* Configure the pull UP calibration */ - cmu_rd(ctx, cmu_type, CMU_REG17, &val); - val = CMU_REG17_PVT_CODE_R2A_SET(val, 0x28); - val = CMU_REG17_RESERVED_7_SET(val, 0x0); - cmu_wr(ctx, cmu_type, CMU_REG17, val); - cmu_toggle1to0(ctx, cmu_type, CMU_REG16, - CMU_REG16_PVT_UP_MAN_ENA_MASK); - -skip_manual_cal: - /* Poll the PLL calibration completion status for at least 1 ms */ - loop = 100; - do { - cmu_rd(ctx, cmu_type, CMU_REG7, &val); - if (CMU_REG7_PLL_CALIB_DONE_RD(val)) - break; - /* - * As per PHY design spec, PLL calibration status requires - * a minimum of 10us to be updated. - */ - usleep_range(10, 100); - } while (--loop > 0); - - cmu_rd(ctx, cmu_type, CMU_REG7, &val); - dev_dbg(ctx->dev, "PLL calibration %s\n", - CMU_REG7_PLL_CALIB_DONE_RD(val) ? "done" : "failed"); - if (CMU_REG7_VCO_CAL_FAIL_RD(val)) { - dev_err(ctx->dev, - "PLL calibration failed due to VCO failure\n"); - return -1; - } - dev_dbg(ctx->dev, "PLL calibration successful\n"); - - cmu_rd(ctx, cmu_type, CMU_REG15, &val); - dev_dbg(ctx->dev, "PHY Tx is %sready\n", val & 0x300 ? "" : "not "); - return 0; -} - -static void xgene_phy_pdwn_force_vco(struct xgene_phy_ctx *ctx, - enum cmu_type_t cmu_type, - enum clk_type_t clk_type) -{ - u32 val; - - dev_dbg(ctx->dev, "Reset VCO and re-start again\n"); - if (cmu_type == PHY_CMU) { - cmu_rd(ctx, cmu_type, CMU_REG16, &val); - val = CMU_REG16_VCOCAL_WAIT_BTW_CODE_SET(val, 0x7); - cmu_wr(ctx, cmu_type, CMU_REG16, val); - } - - cmu_toggle1to0(ctx, cmu_type, CMU_REG0, CMU_REG0_PDOWN_MASK); - cmu_toggle1to0(ctx, cmu_type, CMU_REG32, - CMU_REG32_FORCE_VCOCAL_START_MASK); -} - -static int xgene_phy_hw_init_sata(struct xgene_phy_ctx *ctx, - enum clk_type_t clk_type, int ssc_enable) -{ - void __iomem *sds_base = ctx->sds_base; - u32 val; - int i; - - /* Configure the PHY for operation */ - dev_dbg(ctx->dev, "Reset PHY\n"); - /* Place PHY into reset */ - writel(0x0, sds_base + SATA_ENET_SDS_RST_CTL); - val = readl(sds_base + SATA_ENET_SDS_RST_CTL); /* Force a barrier */ - /* Release PHY lane from reset (active high) */ - writel(0x20, sds_base + SATA_ENET_SDS_RST_CTL); - readl(sds_base + SATA_ENET_SDS_RST_CTL); /* Force a barrier */ - /* Release all PHY module out of reset except PHY main reset */ - writel(0xde, sds_base + SATA_ENET_SDS_RST_CTL); - readl(sds_base + SATA_ENET_SDS_RST_CTL); /* Force a barrier */ - - /* Set the operation speed */ - val = readl(sds_base + SATA_ENET_SDS_CTL1); - val = CFG_I_SPD_SEL_CDR_OVR1_SET(val, - ctx->sata_param.txspeed[ctx->sata_param.speed[0]]); - writel(val, sds_base + SATA_ENET_SDS_CTL1); - - dev_dbg(ctx->dev, "Set the customer pin mode to SATA\n"); - val = readl(sds_base + SATA_ENET_SDS_CTL0); - val = REGSPEC_CFG_I_CUSTOMER_PIN_MODE0_SET(val, 0x4421); - writel(val, sds_base + SATA_ENET_SDS_CTL0); - - /* Configure the clock macro unit (CMU) clock type */ - xgene_phy_cfg_cmu_clk_type(ctx, PHY_CMU, clk_type); - - /* Configure the clock macro */ - xgene_phy_sata_cfg_cmu_core(ctx, PHY_CMU, clk_type); - - /* Enable SSC if enabled */ - if (ssc_enable) - xgene_phy_ssc_enable(ctx, PHY_CMU); - - /* Configure PHY lanes */ - xgene_phy_sata_cfg_lanes(ctx); - - /* Set Rx/Tx 20-bit */ - val = readl(sds_base + SATA_ENET_SDS_PCS_CTL0); - val = REGSPEC_CFG_I_RX_WORDMODE0_SET(val, 0x3); - val = REGSPEC_CFG_I_TX_WORDMODE0_SET(val, 0x3); - writel(val, sds_base + SATA_ENET_SDS_PCS_CTL0); - - /* Start PLL calibration and try for three times */ - i = 10; - do { - if (!xgene_phy_cal_rdy_chk(ctx, PHY_CMU, clk_type)) - break; - /* If failed, toggle the VCO power signal and start again */ - xgene_phy_pdwn_force_vco(ctx, PHY_CMU, clk_type); - } while (--i > 0); - /* Even on failure, allow to continue any way */ - if (i <= 0) - dev_err(ctx->dev, "PLL calibration failed\n"); - - return 0; -} - -static int xgene_phy_hw_initialize(struct xgene_phy_ctx *ctx, - enum clk_type_t clk_type, - int ssc_enable) -{ - int rc; - - dev_dbg(ctx->dev, "PHY init clk type %d\n", clk_type); - - if (ctx->mode == MODE_SATA) { - rc = xgene_phy_hw_init_sata(ctx, clk_type, ssc_enable); - if (rc) - return rc; - } else { - dev_err(ctx->dev, "Un-supported customer pin mode %d\n", - ctx->mode); - return -ENODEV; - } - - return 0; -} - -/* - * Receiver Offset Calibration: - * - * Calibrate the receiver signal path offset in two steps - summar and - * latch calibrations - */ -static void xgene_phy_force_lat_summer_cal(struct xgene_phy_ctx *ctx, int lane) -{ - int i; - struct { - u32 reg; - u32 val; - } serdes_reg[] = { - {RXTX_REG38, 0x0}, - {RXTX_REG39, 0xff00}, - {RXTX_REG40, 0xffff}, - {RXTX_REG41, 0xffff}, - {RXTX_REG42, 0xffff}, - {RXTX_REG43, 0xffff}, - {RXTX_REG44, 0xffff}, - {RXTX_REG45, 0xffff}, - {RXTX_REG46, 0xffff}, - {RXTX_REG47, 0xfffc}, - {RXTX_REG48, 0x0}, - {RXTX_REG49, 0x0}, - {RXTX_REG50, 0x0}, - {RXTX_REG51, 0x0}, - {RXTX_REG52, 0x0}, - {RXTX_REG53, 0x0}, - {RXTX_REG54, 0x0}, - {RXTX_REG55, 0x0}, - }; - - /* Start SUMMER calibration */ - serdes_setbits(ctx, lane, RXTX_REG127, - RXTX_REG127_FORCE_SUM_CAL_START_MASK); - /* - * As per PHY design spec, the Summer calibration requires a minimum - * of 100us to complete. - */ - usleep_range(100, 500); - serdes_clrbits(ctx, lane, RXTX_REG127, - RXTX_REG127_FORCE_SUM_CAL_START_MASK); - /* - * As per PHY design spec, the auto calibration requires a minimum - * of 100us to complete. - */ - usleep_range(100, 500); - - /* Start latch calibration */ - serdes_setbits(ctx, lane, RXTX_REG127, - RXTX_REG127_FORCE_LAT_CAL_START_MASK); - /* - * As per PHY design spec, the latch calibration requires a minimum - * of 100us to complete. - */ - usleep_range(100, 500); - serdes_clrbits(ctx, lane, RXTX_REG127, - RXTX_REG127_FORCE_LAT_CAL_START_MASK); - - /* Configure the PHY lane for calibration */ - serdes_wr(ctx, lane, RXTX_REG28, 0x7); - serdes_wr(ctx, lane, RXTX_REG31, 0x7e00); - serdes_clrbits(ctx, lane, RXTX_REG4, - RXTX_REG4_TX_LOOPBACK_BUF_EN_MASK); - serdes_clrbits(ctx, lane, RXTX_REG7, - RXTX_REG7_LOOP_BACK_ENA_CTLE_MASK); - for (i = 0; i < ARRAY_SIZE(serdes_reg); i++) - serdes_wr(ctx, lane, serdes_reg[i].reg, - serdes_reg[i].val); -} - -static void xgene_phy_reset_rxd(struct xgene_phy_ctx *ctx, int lane) -{ - /* Reset digital Rx */ - serdes_clrbits(ctx, lane, RXTX_REG7, RXTX_REG7_RESETB_RXD_MASK); - /* As per PHY design spec, the reset requires a minimum of 100us. */ - usleep_range(100, 150); - serdes_setbits(ctx, lane, RXTX_REG7, RXTX_REG7_RESETB_RXD_MASK); -} - -static int xgene_phy_get_avg(int accum, int samples) -{ - return (accum + (samples / 2)) / samples; -} - -static void xgene_phy_gen_avg_val(struct xgene_phy_ctx *ctx, int lane) -{ - int max_loop = 10; - int avg_loop = 0; - int lat_do = 0, lat_xo = 0, lat_eo = 0, lat_so = 0; - int lat_de = 0, lat_xe = 0, lat_ee = 0, lat_se = 0; - int sum_cal = 0; - int lat_do_itr, lat_xo_itr, lat_eo_itr, lat_so_itr; - int lat_de_itr, lat_xe_itr, lat_ee_itr, lat_se_itr; - int sum_cal_itr; - int fail_even; - int fail_odd; - u32 val; - - dev_dbg(ctx->dev, "Generating avg calibration value for lane %d\n", - lane); - - /* Enable RX Hi-Z termination */ - serdes_setbits(ctx, lane, RXTX_REG12, - RXTX_REG12_RX_DET_TERM_ENABLE_MASK); - /* Turn off DFE */ - serdes_wr(ctx, lane, RXTX_REG28, 0x0000); - /* DFE Presets to zero */ - serdes_wr(ctx, lane, RXTX_REG31, 0x0000); - - /* - * Receiver Offset Calibration: - * Calibrate the receiver signal path offset in two steps - summar - * and latch calibration. - * Runs the "Receiver Offset Calibration multiple times to determine - * the average value to use. - */ - while (avg_loop < max_loop) { - /* Start the calibration */ - xgene_phy_force_lat_summer_cal(ctx, lane); - - serdes_rd(ctx, lane, RXTX_REG21, &val); - lat_do_itr = RXTX_REG21_DO_LATCH_CALOUT_RD(val); - lat_xo_itr = RXTX_REG21_XO_LATCH_CALOUT_RD(val); - fail_odd = RXTX_REG21_LATCH_CAL_FAIL_ODD_RD(val); - - serdes_rd(ctx, lane, RXTX_REG22, &val); - lat_eo_itr = RXTX_REG22_EO_LATCH_CALOUT_RD(val); - lat_so_itr = RXTX_REG22_SO_LATCH_CALOUT_RD(val); - fail_even = RXTX_REG22_LATCH_CAL_FAIL_EVEN_RD(val); - - serdes_rd(ctx, lane, RXTX_REG23, &val); - lat_de_itr = RXTX_REG23_DE_LATCH_CALOUT_RD(val); - lat_xe_itr = RXTX_REG23_XE_LATCH_CALOUT_RD(val); - - serdes_rd(ctx, lane, RXTX_REG24, &val); - lat_ee_itr = RXTX_REG24_EE_LATCH_CALOUT_RD(val); - lat_se_itr = RXTX_REG24_SE_LATCH_CALOUT_RD(val); - - serdes_rd(ctx, lane, RXTX_REG121, &val); - sum_cal_itr = RXTX_REG121_SUMOS_CAL_CODE_RD(val); - - /* Check for failure. If passed, sum them for averaging */ - if ((fail_even == 0 || fail_even == 1) && - (fail_odd == 0 || fail_odd == 1)) { - lat_do += lat_do_itr; - lat_xo += lat_xo_itr; - lat_eo += lat_eo_itr; - lat_so += lat_so_itr; - lat_de += lat_de_itr; - lat_xe += lat_xe_itr; - lat_ee += lat_ee_itr; - lat_se += lat_se_itr; - sum_cal += sum_cal_itr; - - dev_dbg(ctx->dev, "Iteration %d:\n", avg_loop); - dev_dbg(ctx->dev, "DO 0x%x XO 0x%x EO 0x%x SO 0x%x\n", - lat_do_itr, lat_xo_itr, lat_eo_itr, - lat_so_itr); - dev_dbg(ctx->dev, "DE 0x%x XE 0x%x EE 0x%x SE 0x%x\n", - lat_de_itr, lat_xe_itr, lat_ee_itr, - lat_se_itr); - dev_dbg(ctx->dev, "SUM 0x%x\n", sum_cal_itr); - ++avg_loop; - } else { - dev_err(ctx->dev, - "Receiver calibration failed at %d loop\n", - avg_loop); - } - xgene_phy_reset_rxd(ctx, lane); - } - - /* Update latch manual calibration with average value */ - serdes_rd(ctx, lane, RXTX_REG127, &val); - val = RXTX_REG127_DO_LATCH_MANCAL_SET(val, - xgene_phy_get_avg(lat_do, max_loop)); - val = RXTX_REG127_XO_LATCH_MANCAL_SET(val, - xgene_phy_get_avg(lat_xo, max_loop)); - serdes_wr(ctx, lane, RXTX_REG127, val); - - serdes_rd(ctx, lane, RXTX_REG128, &val); - val = RXTX_REG128_EO_LATCH_MANCAL_SET(val, - xgene_phy_get_avg(lat_eo, max_loop)); - val = RXTX_REG128_SO_LATCH_MANCAL_SET(val, - xgene_phy_get_avg(lat_so, max_loop)); - serdes_wr(ctx, lane, RXTX_REG128, val); - - serdes_rd(ctx, lane, RXTX_REG129, &val); - val = RXTX_REG129_DE_LATCH_MANCAL_SET(val, - xgene_phy_get_avg(lat_de, max_loop)); - val = RXTX_REG129_XE_LATCH_MANCAL_SET(val, - xgene_phy_get_avg(lat_xe, max_loop)); - serdes_wr(ctx, lane, RXTX_REG129, val); - - serdes_rd(ctx, lane, RXTX_REG130, &val); - val = RXTX_REG130_EE_LATCH_MANCAL_SET(val, - xgene_phy_get_avg(lat_ee, max_loop)); - val = RXTX_REG130_SE_LATCH_MANCAL_SET(val, - xgene_phy_get_avg(lat_se, max_loop)); - serdes_wr(ctx, lane, RXTX_REG130, val); - - /* Update SUMMER calibration with average value */ - serdes_rd(ctx, lane, RXTX_REG14, &val); - val = RXTX_REG14_CLTE_LATCAL_MAN_PROG_SET(val, - xgene_phy_get_avg(sum_cal, max_loop)); - serdes_wr(ctx, lane, RXTX_REG14, val); - - dev_dbg(ctx->dev, "Average Value:\n"); - dev_dbg(ctx->dev, "DO 0x%x XO 0x%x EO 0x%x SO 0x%x\n", - xgene_phy_get_avg(lat_do, max_loop), - xgene_phy_get_avg(lat_xo, max_loop), - xgene_phy_get_avg(lat_eo, max_loop), - xgene_phy_get_avg(lat_so, max_loop)); - dev_dbg(ctx->dev, "DE 0x%x XE 0x%x EE 0x%x SE 0x%x\n", - xgene_phy_get_avg(lat_de, max_loop), - xgene_phy_get_avg(lat_xe, max_loop), - xgene_phy_get_avg(lat_ee, max_loop), - xgene_phy_get_avg(lat_se, max_loop)); - dev_dbg(ctx->dev, "SUM 0x%x\n", - xgene_phy_get_avg(sum_cal, max_loop)); - - serdes_rd(ctx, lane, RXTX_REG14, &val); - val = RXTX_REG14_CTLE_LATCAL_MAN_ENA_SET(val, 0x1); - serdes_wr(ctx, lane, RXTX_REG14, val); - dev_dbg(ctx->dev, "Enable Manual Summer calibration\n"); - - serdes_rd(ctx, lane, RXTX_REG127, &val); - val = RXTX_REG127_LATCH_MAN_CAL_ENA_SET(val, 0x1); - dev_dbg(ctx->dev, "Enable Manual Latch calibration\n"); - serdes_wr(ctx, lane, RXTX_REG127, val); - - /* Disable RX Hi-Z termination */ - serdes_rd(ctx, lane, RXTX_REG12, &val); - val = RXTX_REG12_RX_DET_TERM_ENABLE_SET(val, 0); - serdes_wr(ctx, lane, RXTX_REG12, val); - /* Turn on DFE */ - serdes_wr(ctx, lane, RXTX_REG28, 0x0007); - /* Set DFE preset */ - serdes_wr(ctx, lane, RXTX_REG31, 0x7e00); -} - -static int xgene_phy_hw_init(struct phy *phy) -{ - struct xgene_phy_ctx *ctx = phy_get_drvdata(phy); - int rc; - int i; - - rc = xgene_phy_hw_initialize(ctx, CLK_EXT_DIFF, SSC_DISABLE); - if (rc) { - dev_err(ctx->dev, "PHY initialize failed %d\n", rc); - return rc; - } - - /* Setup clock properly after PHY configuration */ - if (!IS_ERR(ctx->clk)) { - /* HW requires an toggle of the clock */ - clk_prepare_enable(ctx->clk); - clk_disable_unprepare(ctx->clk); - clk_prepare_enable(ctx->clk); - } - - /* Compute average value */ - for (i = 0; i < MAX_LANE; i++) - xgene_phy_gen_avg_val(ctx, i); - - dev_dbg(ctx->dev, "PHY initialized\n"); - return 0; -} - -static const struct phy_ops xgene_phy_ops = { - .init = xgene_phy_hw_init, - .owner = THIS_MODULE, -}; - -static struct phy *xgene_phy_xlate(struct device *dev, - struct of_phandle_args *args) -{ - struct xgene_phy_ctx *ctx = dev_get_drvdata(dev); - - if (args->args_count <= 0) - return ERR_PTR(-EINVAL); - if (args->args[0] < MODE_SATA || args->args[0] >= MODE_MAX) - return ERR_PTR(-EINVAL); - - ctx->mode = args->args[0]; - return ctx->phy; -} - -static void xgene_phy_get_param(struct platform_device *pdev, - const char *name, u32 *buffer, - int count, u32 *default_val, - u32 conv_factor) -{ - int i; - - if (!of_property_read_u32_array(pdev->dev.of_node, name, buffer, - count)) { - for (i = 0; i < count; i++) - buffer[i] /= conv_factor; - return; - } - /* Does not exist, load default */ - for (i = 0; i < count; i++) - buffer[i] = default_val[i % 3]; -} - -static int xgene_phy_probe(struct platform_device *pdev) -{ - struct phy_provider *phy_provider; - struct xgene_phy_ctx *ctx; - struct resource *res; - int rc = 0; - u32 default_spd[] = DEFAULT_SATA_SPD_SEL; - u32 default_txboost_gain[] = DEFAULT_SATA_TXBOOST_GAIN; - u32 default_txeye_direction[] = DEFAULT_SATA_TXEYEDIRECTION; - u32 default_txeye_tuning[] = DEFAULT_SATA_TXEYETUNING; - u32 default_txamp[] = DEFAULT_SATA_TXAMP; - u32 default_txcn1[] = DEFAULT_SATA_TXCN1; - u32 default_txcn2[] = DEFAULT_SATA_TXCN2; - u32 default_txcp1[] = DEFAULT_SATA_TXCP1; - int i; - - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - ctx->dev = &pdev->dev; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - ctx->sds_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(ctx->sds_base)) { - rc = PTR_ERR(ctx->sds_base); - goto error; - } - - /* Retrieve optional clock */ - ctx->clk = clk_get(&pdev->dev, NULL); - - /* Load override paramaters */ - xgene_phy_get_param(pdev, "apm,tx-eye-tuning", - ctx->sata_param.txeyetuning, 6, default_txeye_tuning, 1); - xgene_phy_get_param(pdev, "apm,tx-eye-direction", - ctx->sata_param.txeyedirection, 6, default_txeye_direction, 1); - xgene_phy_get_param(pdev, "apm,tx-boost-gain", - ctx->sata_param.txboostgain, 6, default_txboost_gain, 1); - xgene_phy_get_param(pdev, "apm,tx-amplitude", - ctx->sata_param.txamplitude, 6, default_txamp, 13300); - xgene_phy_get_param(pdev, "apm,tx-pre-cursor1", - ctx->sata_param.txprecursor_cn1, 6, default_txcn1, 18200); - xgene_phy_get_param(pdev, "apm,tx-pre-cursor2", - ctx->sata_param.txprecursor_cn2, 6, default_txcn2, 18200); - xgene_phy_get_param(pdev, "apm,tx-post-cursor", - ctx->sata_param.txpostcursor_cp1, 6, default_txcp1, 18200); - xgene_phy_get_param(pdev, "apm,tx-speed", - ctx->sata_param.txspeed, 3, default_spd, 1); - for (i = 0; i < MAX_LANE; i++) - ctx->sata_param.speed[i] = 2; /* Default to Gen3 */ - - ctx->dev = &pdev->dev; - platform_set_drvdata(pdev, ctx); - - ctx->phy = devm_phy_create(ctx->dev, NULL, &xgene_phy_ops, NULL); - if (IS_ERR(ctx->phy)) { - dev_dbg(&pdev->dev, "Failed to create PHY\n"); - rc = PTR_ERR(ctx->phy); - goto error; - } - phy_set_drvdata(ctx->phy, ctx); - - phy_provider = devm_of_phy_provider_register(ctx->dev, - xgene_phy_xlate); - if (IS_ERR(phy_provider)) { - rc = PTR_ERR(phy_provider); - goto error; - } - - return 0; - -error: - return rc; -} - -static const struct of_device_id xgene_phy_of_match[] = { - {.compatible = "apm,xgene-phy",}, - {}, -}; -MODULE_DEVICE_TABLE(of, xgene_phy_of_match); - -static struct platform_driver xgene_phy_driver = { - .probe = xgene_phy_probe, - .driver = { - .name = "xgene-phy", - .of_match_table = xgene_phy_of_match, - }, -}; -module_platform_driver(xgene_phy_driver); - -MODULE_DESCRIPTION("APM X-Gene Multi-Purpose PHY driver"); -MODULE_AUTHOR("Loc Ho "); -MODULE_LICENSE("GPL v2"); -MODULE_VERSION("0.1"); diff --git a/include/linux/phy/omap_control_phy.h b/include/linux/phy/omap_control_phy.h deleted file mode 100644 index e9e6cfbfbb58..000000000000 --- a/include/linux/phy/omap_control_phy.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * omap_control_phy.h - Header file for the PHY part of control module. - * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Author: Kishon Vijay Abraham I - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __OMAP_CONTROL_PHY_H__ -#define __OMAP_CONTROL_PHY_H__ - -enum omap_control_phy_type { - OMAP_CTRL_TYPE_OTGHS = 1, /* Mailbox OTGHS_CONTROL */ - OMAP_CTRL_TYPE_USB2, /* USB2_PHY, power down in CONTROL_DEV_CONF */ - OMAP_CTRL_TYPE_PIPE3, /* PIPE3 PHY, DPLL & seperate Rx/Tx power */ - OMAP_CTRL_TYPE_PCIE, /* RX TX control of ACSPCIE */ - OMAP_CTRL_TYPE_DRA7USB2, /* USB2 PHY, power and power_aux e.g. DRA7 */ - OMAP_CTRL_TYPE_AM437USB2, /* USB2 PHY, power e.g. AM437x */ -}; - -struct omap_control_phy { - struct device *dev; - - u32 __iomem *otghs_control; - u32 __iomem *power; - u32 __iomem *power_aux; - u32 __iomem *pcie_pcs; - - struct clk *sys_clk; - - enum omap_control_phy_type type; -}; - -enum omap_control_usb_mode { - USB_MODE_UNDEFINED = 0, - USB_MODE_HOST, - USB_MODE_DEVICE, - USB_MODE_DISCONNECT, -}; - -#define OMAP_CTRL_DEV_PHY_PD BIT(0) - -#define OMAP_CTRL_DEV_AVALID BIT(0) -#define OMAP_CTRL_DEV_BVALID BIT(1) -#define OMAP_CTRL_DEV_VBUSVALID BIT(2) -#define OMAP_CTRL_DEV_SESSEND BIT(3) -#define OMAP_CTRL_DEV_IDDIG BIT(4) - -#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK 0x003FC000 -#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT 0xE - -#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_MASK 0xFFC00000 -#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_SHIFT 0x16 - -#define OMAP_CTRL_PIPE3_PHY_TX_RX_POWERON 0x3 -#define OMAP_CTRL_PIPE3_PHY_TX_RX_POWEROFF 0x0 - -#define OMAP_CTRL_PCIE_PCS_MASK 0xff -#define OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT 0x8 - -#define OMAP_CTRL_USB2_PHY_PD BIT(28) - -#define AM437X_CTRL_USB2_PHY_PD BIT(0) -#define AM437X_CTRL_USB2_OTG_PD BIT(1) -#define AM437X_CTRL_USB2_OTGVDET_EN BIT(19) -#define AM437X_CTRL_USB2_OTGSESSEND_EN BIT(20) - -#if IS_ENABLED(CONFIG_OMAP_CONTROL_PHY) -void omap_control_phy_power(struct device *dev, int on); -void omap_control_usb_set_mode(struct device *dev, - enum omap_control_usb_mode mode); -void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay); -#else - -static inline void omap_control_phy_power(struct device *dev, int on) -{ -} - -static inline void omap_control_usb_set_mode(struct device *dev, - enum omap_control_usb_mode mode) -{ -} - -static inline void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay) -{ -} -#endif - -#endif /* __OMAP_CONTROL_PHY_H__ */ diff --git a/include/linux/phy/omap_usb.h b/include/linux/phy/omap_usb.h deleted file mode 100644 index dc2c541a619b..000000000000 --- a/include/linux/phy/omap_usb.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * omap_usb.h -- omap usb2 phy header file - * - * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Author: Kishon Vijay Abraham I - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __DRIVERS_OMAP_USB2_H -#define __DRIVERS_OMAP_USB2_H - -#include -#include - -struct usb_dpll_params { - u16 m; - u8 n; - u8 freq:3; - u8 sd; - u32 mf; -}; - -struct omap_usb { - struct usb_phy phy; - struct phy_companion *comparator; - void __iomem *pll_ctrl_base; - void __iomem *phy_base; - struct device *dev; - struct device *control_dev; - struct clk *wkupclk; - struct clk *optclk; - u8 flags; -}; - -struct usb_phy_data { - const char *label; - u8 flags; -}; - -/* Driver Flags */ -#define OMAP_USB2_HAS_START_SRP (1 << 0) -#define OMAP_USB2_HAS_SET_VBUS (1 << 1) -#define OMAP_USB2_CALIBRATE_FALSE_DISCONNECT (1 << 2) - -#define phy_to_omapusb(x) container_of((x), struct omap_usb, phy) - -#if defined(CONFIG_OMAP_USB2) || defined(CONFIG_OMAP_USB2_MODULE) -extern int omap_usb2_set_comparator(struct phy_companion *comparator); -#else -static inline int omap_usb2_set_comparator(struct phy_companion *comparator) -{ - return -ENODEV; -} -#endif - -static inline u32 omap_usb_readl(void __iomem *addr, unsigned offset) -{ - return __raw_readl(addr + offset); -} - -static inline void omap_usb_writel(void __iomem *addr, unsigned offset, - u32 data) -{ - __raw_writel(data, addr + offset); -} - -#endif /* __DRIVERS_OMAP_USB_H */ diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h deleted file mode 100644 index 8cb6f815475b..000000000000 --- a/include/linux/phy/phy.h +++ /dev/null @@ -1,350 +0,0 @@ -/* - * phy.h -- generic phy header file - * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com - * - * Author: Kishon Vijay Abraham I - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef __DRIVERS_PHY_H -#define __DRIVERS_PHY_H - -#include -#include -#include -#include -#include - -struct phy; - -/** - * struct phy_ops - set of function pointers for performing phy operations - * @init: operation to be performed for initializing phy - * @exit: operation to be performed while exiting - * @power_on: powering on the phy - * @power_off: powering off the phy - * @owner: the module owner containing the ops - */ -struct phy_ops { - int (*init)(struct phy *phy); - int (*exit)(struct phy *phy); - int (*power_on)(struct phy *phy); - int (*power_off)(struct phy *phy); - struct module *owner; -}; - -/** - * struct phy_attrs - represents phy attributes - * @bus_width: Data path width implemented by PHY - */ -struct phy_attrs { - u32 bus_width; -}; - -/** - * struct phy - represents the phy device - * @dev: phy device - * @id: id of the phy device - * @ops: function pointers for performing phy operations - * @init_data: list of PHY consumers (non-dt only) - * @mutex: mutex to protect phy_ops - * @init_count: used to protect when the PHY is used by multiple consumers - * @power_count: used to protect when the PHY is used by multiple consumers - * @phy_attrs: used to specify PHY specific attributes - */ -struct phy { - struct device dev; - int id; - const struct phy_ops *ops; - struct phy_init_data *init_data; - struct mutex mutex; - int init_count; - int power_count; - struct phy_attrs attrs; - struct regulator *pwr; -}; - -/** - * struct phy_provider - represents the phy provider - * @dev: phy provider device - * @owner: the module owner having of_xlate - * @of_xlate: function pointer to obtain phy instance from phy pointer - * @list: to maintain a linked list of PHY providers - */ -struct phy_provider { - struct device *dev; - struct module *owner; - struct list_head list; - struct phy * (*of_xlate)(struct device *dev, - struct of_phandle_args *args); -}; - -/** - * struct phy_consumer - represents the phy consumer - * @dev_name: the device name of the controller that will use this PHY device - * @port: name given to the consumer port - */ -struct phy_consumer { - const char *dev_name; - const char *port; -}; - -/** - * struct phy_init_data - contains the list of PHY consumers - * @num_consumers: number of consumers for this PHY device - * @consumers: list of PHY consumers - */ -struct phy_init_data { - unsigned int num_consumers; - struct phy_consumer *consumers; -}; - -#define PHY_CONSUMER(_dev_name, _port) \ -{ \ - .dev_name = _dev_name, \ - .port = _port, \ -} - -#define to_phy(dev) (container_of((dev), struct phy, dev)) - -#define of_phy_provider_register(dev, xlate) \ - __of_phy_provider_register((dev), THIS_MODULE, (xlate)) - -#define devm_of_phy_provider_register(dev, xlate) \ - __devm_of_phy_provider_register((dev), THIS_MODULE, (xlate)) - -static inline void phy_set_drvdata(struct phy *phy, void *data) -{ - dev_set_drvdata(&phy->dev, data); -} - -static inline void *phy_get_drvdata(struct phy *phy) -{ - return dev_get_drvdata(&phy->dev); -} - -#if IS_ENABLED(CONFIG_GENERIC_PHY) -int phy_pm_runtime_get(struct phy *phy); -int phy_pm_runtime_get_sync(struct phy *phy); -int phy_pm_runtime_put(struct phy *phy); -int phy_pm_runtime_put_sync(struct phy *phy); -void phy_pm_runtime_allow(struct phy *phy); -void phy_pm_runtime_forbid(struct phy *phy); -int phy_init(struct phy *phy); -int phy_exit(struct phy *phy); -int phy_power_on(struct phy *phy); -int phy_power_off(struct phy *phy); -static inline int phy_get_bus_width(struct phy *phy) -{ - return phy->attrs.bus_width; -} -static inline void phy_set_bus_width(struct phy *phy, int bus_width) -{ - phy->attrs.bus_width = bus_width; -} -struct phy *phy_get(struct device *dev, const char *string); -struct phy *phy_optional_get(struct device *dev, const char *string); -struct phy *devm_phy_get(struct device *dev, const char *string); -struct phy *devm_phy_optional_get(struct device *dev, const char *string); -struct phy *devm_of_phy_get(struct device *dev, struct device_node *np, - const char *con_id); -void phy_put(struct phy *phy); -void devm_phy_put(struct device *dev, struct phy *phy); -struct phy *of_phy_get(struct device_node *np, const char *con_id); -struct phy *of_phy_simple_xlate(struct device *dev, - struct of_phandle_args *args); -struct phy *phy_create(struct device *dev, struct device_node *node, - const struct phy_ops *ops, - struct phy_init_data *init_data); -struct phy *devm_phy_create(struct device *dev, struct device_node *node, - const struct phy_ops *ops, struct phy_init_data *init_data); -void phy_destroy(struct phy *phy); -void devm_phy_destroy(struct device *dev, struct phy *phy); -struct phy_provider *__of_phy_provider_register(struct device *dev, - struct module *owner, struct phy * (*of_xlate)(struct device *dev, - struct of_phandle_args *args)); -struct phy_provider *__devm_of_phy_provider_register(struct device *dev, - struct module *owner, struct phy * (*of_xlate)(struct device *dev, - struct of_phandle_args *args)); -void of_phy_provider_unregister(struct phy_provider *phy_provider); -void devm_of_phy_provider_unregister(struct device *dev, - struct phy_provider *phy_provider); -#else -static inline int phy_pm_runtime_get(struct phy *phy) -{ - if (!phy) - return 0; - return -ENOSYS; -} - -static inline int phy_pm_runtime_get_sync(struct phy *phy) -{ - if (!phy) - return 0; - return -ENOSYS; -} - -static inline int phy_pm_runtime_put(struct phy *phy) -{ - if (!phy) - return 0; - return -ENOSYS; -} - -static inline int phy_pm_runtime_put_sync(struct phy *phy) -{ - if (!phy) - return 0; - return -ENOSYS; -} - -static inline void phy_pm_runtime_allow(struct phy *phy) -{ - return; -} - -static inline void phy_pm_runtime_forbid(struct phy *phy) -{ - return; -} - -static inline int phy_init(struct phy *phy) -{ - if (!phy) - return 0; - return -ENOSYS; -} - -static inline int phy_exit(struct phy *phy) -{ - if (!phy) - return 0; - return -ENOSYS; -} - -static inline int phy_power_on(struct phy *phy) -{ - if (!phy) - return 0; - return -ENOSYS; -} - -static inline int phy_power_off(struct phy *phy) -{ - if (!phy) - return 0; - return -ENOSYS; -} - -static inline int phy_get_bus_width(struct phy *phy) -{ - return -ENOSYS; -} - -static inline void phy_set_bus_width(struct phy *phy, int bus_width) -{ - return; -} - -static inline struct phy *phy_get(struct device *dev, const char *string) -{ - return ERR_PTR(-ENOSYS); -} - -static inline struct phy *phy_optional_get(struct device *dev, - const char *string) -{ - return ERR_PTR(-ENOSYS); -} - -static inline struct phy *devm_phy_get(struct device *dev, const char *string) -{ - return ERR_PTR(-ENOSYS); -} - -static inline struct phy *devm_phy_optional_get(struct device *dev, - const char *string) -{ - return ERR_PTR(-ENOSYS); -} - -static inline struct phy *devm_of_phy_get(struct device *dev, - struct device_node *np, - const char *con_id) -{ - return ERR_PTR(-ENOSYS); -} - -static inline void phy_put(struct phy *phy) -{ -} - -static inline void devm_phy_put(struct device *dev, struct phy *phy) -{ -} - -static inline struct phy *of_phy_get(struct device_node *np, const char *con_id) -{ - return ERR_PTR(-ENOSYS); -} - -static inline struct phy *of_phy_simple_xlate(struct device *dev, - struct of_phandle_args *args) -{ - return ERR_PTR(-ENOSYS); -} - -static inline struct phy *phy_create(struct device *dev, - struct device_node *node, - const struct phy_ops *ops, - struct phy_init_data *init_data) -{ - return ERR_PTR(-ENOSYS); -} - -static inline struct phy *devm_phy_create(struct device *dev, - struct device_node *node, - const struct phy_ops *ops, - struct phy_init_data *init_data) -{ - return ERR_PTR(-ENOSYS); -} - -static inline void phy_destroy(struct phy *phy) -{ -} - -static inline void devm_phy_destroy(struct device *dev, struct phy *phy) -{ -} - -static inline struct phy_provider *__of_phy_provider_register( - struct device *dev, struct module *owner, struct phy * (*of_xlate)( - struct device *dev, struct of_phandle_args *args)) -{ - return ERR_PTR(-ENOSYS); -} - -static inline struct phy_provider *__devm_of_phy_provider_register(struct device - *dev, struct module *owner, struct phy * (*of_xlate)(struct device *dev, - struct of_phandle_args *args)) -{ - return ERR_PTR(-ENOSYS); -} - -static inline void of_phy_provider_unregister(struct phy_provider *phy_provider) -{ -} - -static inline void devm_of_phy_provider_unregister(struct device *dev, - struct phy_provider *phy_provider) -{ -} -#endif - -#endif /* __DRIVERS_PHY_H */