diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-01-31 11:56:27 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-01-31 11:56:27 -0500 |
commit | 6b629f2826419ab0fde54d04d97531fe4ce972bf (patch) | |
tree | f350600aa48940b0e3fd1f6aa8f2091fdf9dbe16 | |
parent | dd3217408168a96de0546aeb53cfd79a9f68dc95 (diff) | |
parent | bbd3ce86c768928d5db334881e20116c6da4d0c7 (diff) |
Merge tag 'for-3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy into usb-testing
Kishon writes:
Adds a new Rockchip PHY driver and contains miscellaneous fixes.
-rw-r--r-- | Documentation/devicetree/bindings/phy/phy-miphy28lp.txt | 43 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/phy/phy-miphy365x.txt | 15 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/phy/phy-stih407-usb.txt | 10 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt | 37 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/phy/samsung-phy.txt | 2 | ||||
-rw-r--r-- | arch/arm/boot/dts/stih416.dtsi | 10 | ||||
-rw-r--r-- | drivers/phy/Kconfig | 7 | ||||
-rw-r--r-- | drivers/phy/Makefile | 1 | ||||
-rw-r--r-- | drivers/phy/phy-armada375-usb2.c | 4 | ||||
-rw-r--r-- | drivers/phy/phy-exynos-mipi-video.c | 89 | ||||
-rw-r--r-- | drivers/phy/phy-miphy28lp.c | 61 | ||||
-rw-r--r-- | drivers/phy/phy-miphy365x.c | 29 | ||||
-rw-r--r-- | drivers/phy/phy-rockchip-usb.c | 158 | ||||
-rw-r--r-- | drivers/phy/phy-stih407-usb.c | 25 | ||||
-rw-r--r-- | drivers/phy/phy-ti-pipe3.c | 143 | ||||
-rw-r--r-- | include/linux/mfd/syscon/exynos4-pmu.h | 21 |
16 files changed, 483 insertions, 172 deletions
diff --git a/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt b/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt index 46a135dae6b3..89caa885d08c 100644 --- a/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt +++ b/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt | |||
@@ -26,6 +26,7 @@ Required properties (port (child) node): | |||
26 | filled in "reg". It can also contain the offset of the system configuration | 26 | filled in "reg". It can also contain the offset of the system configuration |
27 | registers used as glue-logic to setup the device for SATA/PCIe or USB3 | 27 | registers used as glue-logic to setup the device for SATA/PCIe or USB3 |
28 | devices. | 28 | devices. |
29 | - st,syscfg : Offset of the parent configuration register. | ||
29 | - resets : phandle to the parent reset controller. | 30 | - resets : phandle to the parent reset controller. |
30 | - reset-names : Associated name must be "miphy-sw-rst". | 31 | - reset-names : Associated name must be "miphy-sw-rst". |
31 | 32 | ||
@@ -54,18 +55,12 @@ example: | |||
54 | phy_port0: port@9b22000 { | 55 | phy_port0: port@9b22000 { |
55 | reg = <0x9b22000 0xff>, | 56 | reg = <0x9b22000 0xff>, |
56 | <0x9b09000 0xff>, | 57 | <0x9b09000 0xff>, |
57 | <0x9b04000 0xff>, | 58 | <0x9b04000 0xff>; |
58 | <0x114 0x4>, /* sysctrl MiPHY cntrl */ | ||
59 | <0x818 0x4>, /* sysctrl MiPHY status*/ | ||
60 | <0xe0 0x4>, /* sysctrl PCIe */ | ||
61 | <0xec 0x4>; /* sysctrl SATA */ | ||
62 | reg-names = "sata-up", | 59 | reg-names = "sata-up", |
63 | "pcie-up", | 60 | "pcie-up", |
64 | "pipew", | 61 | "pipew"; |
65 | "miphy-ctrl-glue", | 62 | |
66 | "miphy-status-glue", | 63 | st,syscfg = <0x114 0x818 0xe0 0xec>; |
67 | "pcie-glue", | ||
68 | "sata-glue"; | ||
69 | #phy-cells = <1>; | 64 | #phy-cells = <1>; |
70 | st,osc-rdy; | 65 | st,osc-rdy; |
71 | reset-names = "miphy-sw-rst"; | 66 | reset-names = "miphy-sw-rst"; |
@@ -75,18 +70,13 @@ example: | |||
75 | phy_port1: port@9b2a000 { | 70 | phy_port1: port@9b2a000 { |
76 | reg = <0x9b2a000 0xff>, | 71 | reg = <0x9b2a000 0xff>, |
77 | <0x9b19000 0xff>, | 72 | <0x9b19000 0xff>, |
78 | <0x9b14000 0xff>, | 73 | <0x9b14000 0xff>; |
79 | <0x118 0x4>, | ||
80 | <0x81c 0x4>, | ||
81 | <0xe4 0x4>, | ||
82 | <0xf0 0x4>; | ||
83 | reg-names = "sata-up", | 74 | reg-names = "sata-up", |
84 | "pcie-up", | 75 | "pcie-up", |
85 | "pipew", | 76 | "pipew"; |
86 | "miphy-ctrl-glue", | 77 | |
87 | "miphy-status-glue", | 78 | st,syscfg = <0x118 0x81c 0xe4 0xf0>; |
88 | "pcie-glue", | 79 | |
89 | "sata-glue"; | ||
90 | #phy-cells = <1>; | 80 | #phy-cells = <1>; |
91 | st,osc-force-ext; | 81 | st,osc-force-ext; |
92 | reset-names = "miphy-sw-rst"; | 82 | reset-names = "miphy-sw-rst"; |
@@ -95,13 +85,12 @@ example: | |||
95 | 85 | ||
96 | phy_port2: port@8f95000 { | 86 | phy_port2: port@8f95000 { |
97 | reg = <0x8f95000 0xff>, | 87 | reg = <0x8f95000 0xff>, |
98 | <0x8f90000 0xff>, | 88 | <0x8f90000 0xff>; |
99 | <0x11c 0x4>, | ||
100 | <0x820 0x4>; | ||
101 | reg-names = "pipew", | 89 | reg-names = "pipew", |
102 | "usb3-up", | 90 | "usb3-up"; |
103 | "miphy-ctrl-glue", | 91 | |
104 | "miphy-status-glue"; | 92 | st,syscfg = <0x11c 0x820>; |
93 | |||
105 | #phy-cells = <1>; | 94 | #phy-cells = <1>; |
106 | reset-names = "miphy-sw-rst"; | 95 | reset-names = "miphy-sw-rst"; |
107 | resets = <&softreset STIH407_MIPHY2_SOFTRESET>; | 96 | resets = <&softreset STIH407_MIPHY2_SOFTRESET>; |
@@ -125,4 +114,4 @@ example: | |||
125 | 114 | ||
126 | Macro definitions for the supported miphy configuration can be found in: | 115 | Macro definitions for the supported miphy configuration can be found in: |
127 | 116 | ||
128 | include/dt-bindings/phy/phy-miphy28lp.h | 117 | include/dt-bindings/phy/phy.h |
diff --git a/Documentation/devicetree/bindings/phy/phy-miphy365x.txt b/Documentation/devicetree/bindings/phy/phy-miphy365x.txt index 42c880886cf7..9802d5d911aa 100644 --- a/Documentation/devicetree/bindings/phy/phy-miphy365x.txt +++ b/Documentation/devicetree/bindings/phy/phy-miphy365x.txt | |||
@@ -6,8 +6,10 @@ for SATA and PCIe. | |||
6 | 6 | ||
7 | Required properties (controller (parent) node): | 7 | Required properties (controller (parent) node): |
8 | - compatible : Should be "st,miphy365x-phy" | 8 | - compatible : Should be "st,miphy365x-phy" |
9 | - st,syscfg : Should be a phandle of the system configuration register group | 9 | - st,syscfg : Phandle / integer array property. Phandle of sysconfig group |
10 | which contain the SATA, PCIe mode setting bits | 10 | containing the miphy registers and integer array should contain |
11 | an entry for each port sub-node, specifying the control | ||
12 | register offset inside the sysconfig group. | ||
11 | 13 | ||
12 | Required nodes : A sub-node is required for each channel the controller | 14 | Required nodes : A sub-node is required for each channel the controller |
13 | provides. Address range information including the usual | 15 | provides. Address range information including the usual |
@@ -26,7 +28,6 @@ Required properties (port (child) node): | |||
26 | registers filled in "reg": | 28 | registers filled in "reg": |
27 | - sata: For SATA devices | 29 | - sata: For SATA devices |
28 | - pcie: For PCIe devices | 30 | - pcie: For PCIe devices |
29 | - syscfg: To specify the syscfg based config register | ||
30 | 31 | ||
31 | Optional properties (port (child) node): | 32 | Optional properties (port (child) node): |
32 | - st,sata-gen : Generation of locally attached SATA IP. Expected values | 33 | - st,sata-gen : Generation of locally attached SATA IP. Expected values |
@@ -39,20 +40,20 @@ Example: | |||
39 | 40 | ||
40 | miphy365x_phy: miphy365x@fe382000 { | 41 | miphy365x_phy: miphy365x@fe382000 { |
41 | compatible = "st,miphy365x-phy"; | 42 | compatible = "st,miphy365x-phy"; |
42 | st,syscfg = <&syscfg_rear>; | 43 | st,syscfg = <&syscfg_rear 0x824 0x828>; |
43 | #address-cells = <1>; | 44 | #address-cells = <1>; |
44 | #size-cells = <1>; | 45 | #size-cells = <1>; |
45 | ranges; | 46 | ranges; |
46 | 47 | ||
47 | phy_port0: port@fe382000 { | 48 | phy_port0: port@fe382000 { |
48 | reg = <0xfe382000 0x100>, <0xfe394000 0x100>, <0x824 0x4>; | 49 | reg = <0xfe382000 0x100>, <0xfe394000 0x100>; |
49 | reg-names = "sata", "pcie", "syscfg"; | 50 | reg-names = "sata", "pcie"; |
50 | #phy-cells = <1>; | 51 | #phy-cells = <1>; |
51 | st,sata-gen = <3>; | 52 | st,sata-gen = <3>; |
52 | }; | 53 | }; |
53 | 54 | ||
54 | phy_port1: port@fe38a000 { | 55 | phy_port1: port@fe38a000 { |
55 | reg = <0xfe38a000 0x100>, <0xfe804000 0x100>, <0x828 0x4>;; | 56 | reg = <0xfe38a000 0x100>, <0xfe804000 0x100>;; |
56 | reg-names = "sata", "pcie", "syscfg"; | 57 | reg-names = "sata", "pcie", "syscfg"; |
57 | #phy-cells = <1>; | 58 | #phy-cells = <1>; |
58 | st,pcie-tx-pol-inv; | 59 | st,pcie-tx-pol-inv; |
diff --git a/Documentation/devicetree/bindings/phy/phy-stih407-usb.txt b/Documentation/devicetree/bindings/phy/phy-stih407-usb.txt index 1ef8228db73b..de6a706abcdb 100644 --- a/Documentation/devicetree/bindings/phy/phy-stih407-usb.txt +++ b/Documentation/devicetree/bindings/phy/phy-stih407-usb.txt | |||
@@ -5,10 +5,7 @@ host controllers (when controlling usb2/1.1 devices) available on STiH407 SoC fa | |||
5 | 5 | ||
6 | Required properties: | 6 | Required properties: |
7 | - compatible : should be "st,stih407-usb2-phy" | 7 | - compatible : should be "st,stih407-usb2-phy" |
8 | - reg : contain the offset and length of the system configuration registers | 8 | - st,syscfg : phandle of sysconfig bank plus integer array containing phyparam and phyctrl register offsets |
9 | used as glue logic to control & parameter phy | ||
10 | - reg-names : the names of the system configuration registers in "reg", should be "param" and "reg" | ||
11 | - st,syscfg : sysconfig register to manage phy parameter at driver level | ||
12 | - resets : list of phandle and reset specifier pairs. There should be two entries, one | 9 | - resets : list of phandle and reset specifier pairs. There should be two entries, one |
13 | for the whole phy and one for the port | 10 | for the whole phy and one for the port |
14 | - reset-names : list of reset signal names. Should be "global" and "port" | 11 | - reset-names : list of reset signal names. Should be "global" and "port" |
@@ -19,11 +16,8 @@ Example: | |||
19 | 16 | ||
20 | usb2_picophy0: usbpicophy@f8 { | 17 | usb2_picophy0: usbpicophy@f8 { |
21 | compatible = "st,stih407-usb2-phy"; | 18 | compatible = "st,stih407-usb2-phy"; |
22 | reg = <0xf8 0x04>, /* syscfg 5062 */ | ||
23 | <0xf4 0x04>; /* syscfg 5061 */ | ||
24 | reg-names = "param", "ctrl"; | ||
25 | #phy-cells = <0>; | 19 | #phy-cells = <0>; |
26 | st,syscfg = <&syscfg_core>; | 20 | st,syscfg = <&syscfg_core 0x100 0xf4>; |
27 | resets = <&softreset STIH407_PICOPHY_SOFTRESET>, | 21 | resets = <&softreset STIH407_PICOPHY_SOFTRESET>, |
28 | <&picophyreset STIH407_PICOPHY0_RESET>; | 22 | <&picophyreset STIH407_PICOPHY0_RESET>; |
29 | reset-names = "global", "port"; | 23 | reset-names = "global", "port"; |
diff --git a/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt new file mode 100644 index 000000000000..826454ac43bb --- /dev/null +++ b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt | |||
@@ -0,0 +1,37 @@ | |||
1 | ROCKCHIP USB2 PHY | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: rockchip,rk3288-usb-phy | ||
5 | - rockchip,grf : phandle to the syscon managing the "general | ||
6 | register files" | ||
7 | - #address-cells: should be 1 | ||
8 | - #size-cells: should be 0 | ||
9 | |||
10 | Sub-nodes: | ||
11 | Each PHY should be represented as a sub-node. | ||
12 | |||
13 | Sub-nodes | ||
14 | required properties: | ||
15 | - #phy-cells: should be 0 | ||
16 | - reg: PHY configure reg address offset in GRF | ||
17 | "0x320" - for PHY attach to OTG controller | ||
18 | "0x334" - for PHY attach to HOST0 controller | ||
19 | "0x348" - for PHY attach to HOST1 controller | ||
20 | |||
21 | Optional Properties: | ||
22 | - clocks : phandle + clock specifier for the phy clocks | ||
23 | - clock-names: string, clock name, must be "phyclk" | ||
24 | |||
25 | Example: | ||
26 | |||
27 | usbphy: phy { | ||
28 | compatible = "rockchip,rk3288-usb-phy"; | ||
29 | rockchip,grf = <&grf>; | ||
30 | #address-cells = <1>; | ||
31 | #size-cells = <0>; | ||
32 | |||
33 | usbphy0: usb-phy0 { | ||
34 | #phy-cells = <0>; | ||
35 | reg = <0x320>; | ||
36 | }; | ||
37 | }; | ||
diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt index d5bad920827f..91e38cfe1f8f 100644 --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt | |||
@@ -3,8 +3,8 @@ Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY | |||
3 | 3 | ||
4 | Required properties: | 4 | Required properties: |
5 | - compatible : should be "samsung,s5pv210-mipi-video-phy"; | 5 | - compatible : should be "samsung,s5pv210-mipi-video-phy"; |
6 | - reg : offset and length of the MIPI DPHY register set; | ||
7 | - #phy-cells : from the generic phy bindings, must be 1; | 6 | - #phy-cells : from the generic phy bindings, must be 1; |
7 | - syscon - phandle to the PMU system controller; | ||
8 | 8 | ||
9 | For "samsung,s5pv210-mipi-video-phy" compatible PHYs the second cell in | 9 | For "samsung,s5pv210-mipi-video-phy" compatible PHYs the second cell in |
10 | the PHY specifier identifies the PHY and its meaning is as follows: | 10 | the PHY specifier identifies the PHY and its meaning is as follows: |
diff --git a/arch/arm/boot/dts/stih416.dtsi b/arch/arm/boot/dts/stih416.dtsi index fad9073ddeed..85afe01c34fa 100644 --- a/arch/arm/boot/dts/stih416.dtsi +++ b/arch/arm/boot/dts/stih416.dtsi | |||
@@ -283,21 +283,21 @@ | |||
283 | 283 | ||
284 | miphy365x_phy: phy@fe382000 { | 284 | miphy365x_phy: phy@fe382000 { |
285 | compatible = "st,miphy365x-phy"; | 285 | compatible = "st,miphy365x-phy"; |
286 | st,syscfg = <&syscfg_rear>; | 286 | st,syscfg = <&syscfg_rear 0x824 0x828>; |
287 | #address-cells = <1>; | 287 | #address-cells = <1>; |
288 | #size-cells = <1>; | 288 | #size-cells = <1>; |
289 | ranges; | 289 | ranges; |
290 | 290 | ||
291 | phy_port0: port@fe382000 { | 291 | phy_port0: port@fe382000 { |
292 | #phy-cells = <1>; | 292 | #phy-cells = <1>; |
293 | reg = <0xfe382000 0x100>, <0xfe394000 0x100>, <0x824 0x4>; | 293 | reg = <0xfe382000 0x100>, <0xfe394000 0x100>; |
294 | reg-names = "sata", "pcie", "syscfg"; | 294 | reg-names = "sata", "pcie"; |
295 | }; | 295 | }; |
296 | 296 | ||
297 | phy_port1: port@fe38a000 { | 297 | phy_port1: port@fe38a000 { |
298 | #phy-cells = <1>; | 298 | #phy-cells = <1>; |
299 | reg = <0xfe38a000 0x100>, <0xfe804000 0x100>, <0x828 0x4>; | 299 | reg = <0xfe38a000 0x100>, <0xfe804000 0x100>; |
300 | reg-names = "sata", "pcie", "syscfg"; | 300 | reg-names = "sata", "pcie"; |
301 | }; | 301 | }; |
302 | }; | 302 | }; |
303 | 303 | ||
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index ccad8809ecb1..b24500afba25 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig | |||
@@ -239,6 +239,13 @@ config PHY_QCOM_IPQ806X_SATA | |||
239 | depends on OF | 239 | depends on OF |
240 | select GENERIC_PHY | 240 | select GENERIC_PHY |
241 | 241 | ||
242 | config PHY_ROCKCHIP_USB | ||
243 | tristate "Rockchip USB2 PHY Driver" | ||
244 | depends on ARCH_ROCKCHIP && OF | ||
245 | select GENERIC_PHY | ||
246 | help | ||
247 | Enable this to support the Rockchip USB 2.0 PHY. | ||
248 | |||
242 | config PHY_ST_SPEAR1310_MIPHY | 249 | config PHY_ST_SPEAR1310_MIPHY |
243 | tristate "ST SPEAR1310-MIPHY driver" | 250 | tristate "ST SPEAR1310-MIPHY driver" |
244 | select GENERIC_PHY | 251 | select GENERIC_PHY |
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index aa74f961e44e..48bf5a15f161 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile | |||
@@ -28,6 +28,7 @@ phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o | |||
28 | phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o | 28 | phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o |
29 | obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o | 29 | obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o |
30 | obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o | 30 | obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o |
31 | obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o | ||
31 | obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o | 32 | obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o |
32 | obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o | 33 | obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o |
33 | obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o | 34 | obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o |
diff --git a/drivers/phy/phy-armada375-usb2.c b/drivers/phy/phy-armada375-usb2.c index ac7d99d01cb3..7c99ca256f05 100644 --- a/drivers/phy/phy-armada375-usb2.c +++ b/drivers/phy/phy-armada375-usb2.c | |||
@@ -118,8 +118,8 @@ static int armada375_usb_phy_probe(struct platform_device *pdev) | |||
118 | 118 | ||
119 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 119 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
120 | usb_cluster_base = devm_ioremap_resource(&pdev->dev, res); | 120 | usb_cluster_base = devm_ioremap_resource(&pdev->dev, res); |
121 | if (!usb_cluster_base) | 121 | if (IS_ERR(usb_cluster_base)) |
122 | return -ENOMEM; | 122 | return PTR_ERR(usb_cluster_base); |
123 | 123 | ||
124 | phy = devm_phy_create(dev, NULL, &armada375_usb_phy_ops); | 124 | phy = devm_phy_create(dev, NULL, &armada375_usb_phy_ops); |
125 | if (IS_ERR(phy)) { | 125 | if (IS_ERR(phy)) { |
diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c index 943e0f88a120..f017b2f2a54e 100644 --- a/drivers/phy/phy-exynos-mipi-video.c +++ b/drivers/phy/phy-exynos-mipi-video.c | |||
@@ -12,19 +12,18 @@ | |||
12 | #include <linux/err.h> | 12 | #include <linux/err.h> |
13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/mfd/syscon/exynos4-pmu.h> | ||
15 | #include <linux/module.h> | 16 | #include <linux/module.h> |
16 | #include <linux/of.h> | 17 | #include <linux/of.h> |
17 | #include <linux/of_address.h> | 18 | #include <linux/of_address.h> |
18 | #include <linux/phy/phy.h> | 19 | #include <linux/phy/phy.h> |
19 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/regmap.h> | ||
20 | #include <linux/spinlock.h> | 22 | #include <linux/spinlock.h> |
23 | #include <linux/mfd/syscon.h> | ||
21 | 24 | ||
22 | /* MIPI_PHYn_CONTROL register offset: n = 0..1 */ | 25 | /* MIPI_PHYn_CONTROL reg. offset (for base address from ioremap): n = 0..1 */ |
23 | #define EXYNOS_MIPI_PHY_CONTROL(n) ((n) * 4) | 26 | #define EXYNOS_MIPI_PHY_CONTROL(n) ((n) * 4) |
24 | #define EXYNOS_MIPI_PHY_ENABLE (1 << 0) | ||
25 | #define EXYNOS_MIPI_PHY_SRESETN (1 << 1) | ||
26 | #define EXYNOS_MIPI_PHY_MRESETN (1 << 2) | ||
27 | #define EXYNOS_MIPI_PHY_RESET_MASK (3 << 1) | ||
28 | 27 | ||
29 | enum exynos_mipi_phy_id { | 28 | enum exynos_mipi_phy_id { |
30 | EXYNOS_MIPI_PHY_ID_CSIS0, | 29 | EXYNOS_MIPI_PHY_ID_CSIS0, |
@@ -38,43 +37,62 @@ enum exynos_mipi_phy_id { | |||
38 | ((id) == EXYNOS_MIPI_PHY_ID_DSIM0 || (id) == EXYNOS_MIPI_PHY_ID_DSIM1) | 37 | ((id) == EXYNOS_MIPI_PHY_ID_DSIM0 || (id) == EXYNOS_MIPI_PHY_ID_DSIM1) |
39 | 38 | ||
40 | struct exynos_mipi_video_phy { | 39 | struct exynos_mipi_video_phy { |
41 | spinlock_t slock; | ||
42 | struct video_phy_desc { | 40 | struct video_phy_desc { |
43 | struct phy *phy; | 41 | struct phy *phy; |
44 | unsigned int index; | 42 | unsigned int index; |
45 | } phys[EXYNOS_MIPI_PHYS_NUM]; | 43 | } phys[EXYNOS_MIPI_PHYS_NUM]; |
44 | spinlock_t slock; | ||
46 | void __iomem *regs; | 45 | void __iomem *regs; |
46 | struct mutex mutex; | ||
47 | struct regmap *regmap; | ||
47 | }; | 48 | }; |
48 | 49 | ||
49 | static int __set_phy_state(struct exynos_mipi_video_phy *state, | 50 | static int __set_phy_state(struct exynos_mipi_video_phy *state, |
50 | enum exynos_mipi_phy_id id, unsigned int on) | 51 | enum exynos_mipi_phy_id id, unsigned int on) |
51 | { | 52 | { |
53 | const unsigned int offset = EXYNOS4_MIPI_PHY_CONTROL(id / 2); | ||
52 | void __iomem *addr; | 54 | void __iomem *addr; |
53 | u32 reg, reset; | 55 | u32 val, reset; |
54 | |||
55 | addr = state->regs + EXYNOS_MIPI_PHY_CONTROL(id / 2); | ||
56 | 56 | ||
57 | if (is_mipi_dsim_phy_id(id)) | 57 | if (is_mipi_dsim_phy_id(id)) |
58 | reset = EXYNOS_MIPI_PHY_MRESETN; | 58 | reset = EXYNOS4_MIPI_PHY_MRESETN; |
59 | else | ||
60 | reset = EXYNOS_MIPI_PHY_SRESETN; | ||
61 | |||
62 | spin_lock(&state->slock); | ||
63 | reg = readl(addr); | ||
64 | if (on) | ||
65 | reg |= reset; | ||
66 | else | 59 | else |
67 | reg &= ~reset; | 60 | reset = EXYNOS4_MIPI_PHY_SRESETN; |
68 | writel(reg, addr); | 61 | |
69 | 62 | if (state->regmap) { | |
70 | /* Clear ENABLE bit only if MRESETN, SRESETN bits are not set. */ | 63 | mutex_lock(&state->mutex); |
71 | if (on) | 64 | regmap_read(state->regmap, offset, &val); |
72 | reg |= EXYNOS_MIPI_PHY_ENABLE; | 65 | if (on) |
73 | else if (!(reg & EXYNOS_MIPI_PHY_RESET_MASK)) | 66 | val |= reset; |
74 | reg &= ~EXYNOS_MIPI_PHY_ENABLE; | 67 | else |
68 | val &= ~reset; | ||
69 | regmap_write(state->regmap, offset, val); | ||
70 | if (on) | ||
71 | val |= EXYNOS4_MIPI_PHY_ENABLE; | ||
72 | else if (!(val & EXYNOS4_MIPI_PHY_RESET_MASK)) | ||
73 | val &= ~EXYNOS4_MIPI_PHY_ENABLE; | ||
74 | regmap_write(state->regmap, offset, val); | ||
75 | mutex_unlock(&state->mutex); | ||
76 | } else { | ||
77 | addr = state->regs + EXYNOS_MIPI_PHY_CONTROL(id / 2); | ||
78 | |||
79 | spin_lock(&state->slock); | ||
80 | val = readl(addr); | ||
81 | if (on) | ||
82 | val |= reset; | ||
83 | else | ||
84 | val &= ~reset; | ||
85 | writel(val, addr); | ||
86 | /* Clear ENABLE bit only if MRESETN, SRESETN bits are not set */ | ||
87 | if (on) | ||
88 | val |= EXYNOS4_MIPI_PHY_ENABLE; | ||
89 | else if (!(val & EXYNOS4_MIPI_PHY_RESET_MASK)) | ||
90 | val &= ~EXYNOS4_MIPI_PHY_ENABLE; | ||
91 | |||
92 | writel(val, addr); | ||
93 | spin_unlock(&state->slock); | ||
94 | } | ||
75 | 95 | ||
76 | writel(reg, addr); | ||
77 | spin_unlock(&state->slock); | ||
78 | return 0; | 96 | return 0; |
79 | } | 97 | } |
80 | 98 | ||
@@ -118,7 +136,6 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev) | |||
118 | { | 136 | { |
119 | struct exynos_mipi_video_phy *state; | 137 | struct exynos_mipi_video_phy *state; |
120 | struct device *dev = &pdev->dev; | 138 | struct device *dev = &pdev->dev; |
121 | struct resource *res; | ||
122 | struct phy_provider *phy_provider; | 139 | struct phy_provider *phy_provider; |
123 | unsigned int i; | 140 | unsigned int i; |
124 | 141 | ||
@@ -126,14 +143,22 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev) | |||
126 | if (!state) | 143 | if (!state) |
127 | return -ENOMEM; | 144 | return -ENOMEM; |
128 | 145 | ||
129 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 146 | state->regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon"); |
147 | if (IS_ERR(state->regmap)) { | ||
148 | struct resource *res; | ||
130 | 149 | ||
131 | state->regs = devm_ioremap_resource(dev, res); | 150 | dev_info(dev, "regmap lookup failed: %ld\n", |
132 | if (IS_ERR(state->regs)) | 151 | PTR_ERR(state->regmap)); |
133 | return PTR_ERR(state->regs); | 152 | |
153 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
154 | state->regs = devm_ioremap_resource(dev, res); | ||
155 | if (IS_ERR(state->regs)) | ||
156 | return PTR_ERR(state->regs); | ||
157 | } | ||
134 | 158 | ||
135 | dev_set_drvdata(dev, state); | 159 | dev_set_drvdata(dev, state); |
136 | spin_lock_init(&state->slock); | 160 | spin_lock_init(&state->slock); |
161 | mutex_init(&state->mutex); | ||
137 | 162 | ||
138 | for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) { | 163 | for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) { |
139 | struct phy *phy = devm_phy_create(dev, NULL, | 164 | struct phy *phy = devm_phy_create(dev, NULL, |
diff --git a/drivers/phy/phy-miphy28lp.c b/drivers/phy/phy-miphy28lp.c index 27fa62ce6136..9b2848e6115d 100644 --- a/drivers/phy/phy-miphy28lp.c +++ b/drivers/phy/phy-miphy28lp.c | |||
@@ -194,6 +194,14 @@ | |||
194 | #define MIPHY_SATA_BANK_NB 3 | 194 | #define MIPHY_SATA_BANK_NB 3 |
195 | #define MIPHY_PCIE_BANK_NB 2 | 195 | #define MIPHY_PCIE_BANK_NB 2 |
196 | 196 | ||
197 | enum { | ||
198 | SYSCFG_CTRL, | ||
199 | SYSCFG_STATUS, | ||
200 | SYSCFG_PCI, | ||
201 | SYSCFG_SATA, | ||
202 | SYSCFG_REG_MAX, | ||
203 | }; | ||
204 | |||
197 | struct miphy28lp_phy { | 205 | struct miphy28lp_phy { |
198 | struct phy *phy; | 206 | struct phy *phy; |
199 | struct miphy28lp_dev *phydev; | 207 | struct miphy28lp_dev *phydev; |
@@ -211,10 +219,7 @@ struct miphy28lp_phy { | |||
211 | u32 sata_gen; | 219 | u32 sata_gen; |
212 | 220 | ||
213 | /* Sysconfig registers offsets needed to configure the device */ | 221 | /* Sysconfig registers offsets needed to configure the device */ |
214 | u32 syscfg_miphy_ctrl; | 222 | u32 syscfg_reg[SYSCFG_REG_MAX]; |
215 | u32 syscfg_miphy_status; | ||
216 | u32 syscfg_pci; | ||
217 | u32 syscfg_sata; | ||
218 | u8 type; | 223 | u8 type; |
219 | }; | 224 | }; |
220 | 225 | ||
@@ -834,12 +839,12 @@ static int miphy_osc_is_ready(struct miphy28lp_phy *miphy_phy) | |||
834 | if (!miphy_phy->osc_rdy) | 839 | if (!miphy_phy->osc_rdy) |
835 | return 0; | 840 | return 0; |
836 | 841 | ||
837 | if (!miphy_phy->syscfg_miphy_status) | 842 | if (!miphy_phy->syscfg_reg[SYSCFG_STATUS]) |
838 | return -EINVAL; | 843 | return -EINVAL; |
839 | 844 | ||
840 | do { | 845 | do { |
841 | regmap_read(miphy_dev->regmap, miphy_phy->syscfg_miphy_status, | 846 | regmap_read(miphy_dev->regmap, |
842 | &val); | 847 | miphy_phy->syscfg_reg[SYSCFG_STATUS], &val); |
843 | 848 | ||
844 | if ((val & MIPHY_OSC_RDY) != MIPHY_OSC_RDY) | 849 | if ((val & MIPHY_OSC_RDY) != MIPHY_OSC_RDY) |
845 | cpu_relax(); | 850 | cpu_relax(); |
@@ -888,7 +893,7 @@ static int miphy28lp_setup(struct miphy28lp_phy *miphy_phy, u32 miphy_val) | |||
888 | int err; | 893 | int err; |
889 | struct miphy28lp_dev *miphy_dev = miphy_phy->phydev; | 894 | struct miphy28lp_dev *miphy_dev = miphy_phy->phydev; |
890 | 895 | ||
891 | if (!miphy_phy->syscfg_miphy_ctrl) | 896 | if (!miphy_phy->syscfg_reg[SYSCFG_CTRL]) |
892 | return -EINVAL; | 897 | return -EINVAL; |
893 | 898 | ||
894 | err = reset_control_assert(miphy_phy->miphy_rst); | 899 | err = reset_control_assert(miphy_phy->miphy_rst); |
@@ -900,7 +905,8 @@ static int miphy28lp_setup(struct miphy28lp_phy *miphy_phy, u32 miphy_val) | |||
900 | if (miphy_phy->osc_force_ext) | 905 | if (miphy_phy->osc_force_ext) |
901 | miphy_val |= MIPHY_OSC_FORCE_EXT; | 906 | miphy_val |= MIPHY_OSC_FORCE_EXT; |
902 | 907 | ||
903 | regmap_update_bits(miphy_dev->regmap, miphy_phy->syscfg_miphy_ctrl, | 908 | regmap_update_bits(miphy_dev->regmap, |
909 | miphy_phy->syscfg_reg[SYSCFG_CTRL], | ||
904 | MIPHY_CTRL_MASK, miphy_val); | 910 | MIPHY_CTRL_MASK, miphy_val); |
905 | 911 | ||
906 | err = reset_control_deassert(miphy_phy->miphy_rst); | 912 | err = reset_control_deassert(miphy_phy->miphy_rst); |
@@ -917,8 +923,9 @@ static int miphy28lp_init_sata(struct miphy28lp_phy *miphy_phy) | |||
917 | struct miphy28lp_dev *miphy_dev = miphy_phy->phydev; | 923 | struct miphy28lp_dev *miphy_dev = miphy_phy->phydev; |
918 | int err, sata_conf = SATA_CTRL_SELECT_SATA; | 924 | int err, sata_conf = SATA_CTRL_SELECT_SATA; |
919 | 925 | ||
920 | if ((!miphy_phy->syscfg_sata) || (!miphy_phy->syscfg_pci) | 926 | if ((!miphy_phy->syscfg_reg[SYSCFG_SATA]) || |
921 | || (!miphy_phy->base)) | 927 | (!miphy_phy->syscfg_reg[SYSCFG_PCI]) || |
928 | (!miphy_phy->base)) | ||
922 | return -EINVAL; | 929 | return -EINVAL; |
923 | 930 | ||
924 | dev_info(miphy_dev->dev, "sata-up mode, addr 0x%p\n", miphy_phy->base); | 931 | dev_info(miphy_dev->dev, "sata-up mode, addr 0x%p\n", miphy_phy->base); |
@@ -926,10 +933,11 @@ static int miphy28lp_init_sata(struct miphy28lp_phy *miphy_phy) | |||
926 | /* Configure the glue-logic */ | 933 | /* Configure the glue-logic */ |
927 | sata_conf |= ((miphy_phy->sata_gen - SATA_GEN1) << SATA_SPDMODE); | 934 | sata_conf |= ((miphy_phy->sata_gen - SATA_GEN1) << SATA_SPDMODE); |
928 | 935 | ||
929 | regmap_update_bits(miphy_dev->regmap, miphy_phy->syscfg_sata, | 936 | regmap_update_bits(miphy_dev->regmap, |
937 | miphy_phy->syscfg_reg[SYSCFG_SATA], | ||
930 | SATA_CTRL_MASK, sata_conf); | 938 | SATA_CTRL_MASK, sata_conf); |
931 | 939 | ||
932 | regmap_update_bits(miphy_dev->regmap, miphy_phy->syscfg_pci, | 940 | regmap_update_bits(miphy_dev->regmap, miphy_phy->syscfg_reg[SYSCFG_PCI], |
933 | PCIE_CTRL_MASK, SATA_CTRL_SELECT_PCIE); | 941 | PCIE_CTRL_MASK, SATA_CTRL_SELECT_PCIE); |
934 | 942 | ||
935 | /* MiPHY path and clocking init */ | 943 | /* MiPHY path and clocking init */ |
@@ -951,17 +959,19 @@ static int miphy28lp_init_pcie(struct miphy28lp_phy *miphy_phy) | |||
951 | struct miphy28lp_dev *miphy_dev = miphy_phy->phydev; | 959 | struct miphy28lp_dev *miphy_dev = miphy_phy->phydev; |
952 | int err; | 960 | int err; |
953 | 961 | ||
954 | if ((!miphy_phy->syscfg_sata) || (!miphy_phy->syscfg_pci) | 962 | if ((!miphy_phy->syscfg_reg[SYSCFG_SATA]) || |
963 | (!miphy_phy->syscfg_reg[SYSCFG_PCI]) | ||
955 | || (!miphy_phy->base) || (!miphy_phy->pipebase)) | 964 | || (!miphy_phy->base) || (!miphy_phy->pipebase)) |
956 | return -EINVAL; | 965 | return -EINVAL; |
957 | 966 | ||
958 | dev_info(miphy_dev->dev, "pcie-up mode, addr 0x%p\n", miphy_phy->base); | 967 | dev_info(miphy_dev->dev, "pcie-up mode, addr 0x%p\n", miphy_phy->base); |
959 | 968 | ||
960 | /* Configure the glue-logic */ | 969 | /* Configure the glue-logic */ |
961 | regmap_update_bits(miphy_dev->regmap, miphy_phy->syscfg_sata, | 970 | regmap_update_bits(miphy_dev->regmap, |
971 | miphy_phy->syscfg_reg[SYSCFG_SATA], | ||
962 | SATA_CTRL_MASK, SATA_CTRL_SELECT_PCIE); | 972 | SATA_CTRL_MASK, SATA_CTRL_SELECT_PCIE); |
963 | 973 | ||
964 | regmap_update_bits(miphy_dev->regmap, miphy_phy->syscfg_pci, | 974 | regmap_update_bits(miphy_dev->regmap, miphy_phy->syscfg_reg[SYSCFG_PCI], |
965 | PCIE_CTRL_MASK, SYSCFG_PCIE_PCIE_VAL); | 975 | PCIE_CTRL_MASK, SYSCFG_PCIE_PCIE_VAL); |
966 | 976 | ||
967 | /* MiPHY path and clocking init */ | 977 | /* MiPHY path and clocking init */ |
@@ -1156,7 +1166,8 @@ static int miphy28lp_probe_resets(struct device_node *node, | |||
1156 | static int miphy28lp_of_probe(struct device_node *np, | 1166 | static int miphy28lp_of_probe(struct device_node *np, |
1157 | struct miphy28lp_phy *miphy_phy) | 1167 | struct miphy28lp_phy *miphy_phy) |
1158 | { | 1168 | { |
1159 | struct resource res; | 1169 | int i; |
1170 | u32 ctrlreg; | ||
1160 | 1171 | ||
1161 | miphy_phy->osc_force_ext = | 1172 | miphy_phy->osc_force_ext = |
1162 | of_property_read_bool(np, "st,osc-force-ext"); | 1173 | of_property_read_bool(np, "st,osc-force-ext"); |
@@ -1175,18 +1186,10 @@ static int miphy28lp_of_probe(struct device_node *np, | |||
1175 | if (!miphy_phy->sata_gen) | 1186 | if (!miphy_phy->sata_gen) |
1176 | miphy_phy->sata_gen = SATA_GEN1; | 1187 | miphy_phy->sata_gen = SATA_GEN1; |
1177 | 1188 | ||
1178 | if (!miphy28lp_get_resource_byname(np, "miphy-ctrl-glue", &res)) | 1189 | for (i = 0; i < SYSCFG_REG_MAX; i++) { |
1179 | miphy_phy->syscfg_miphy_ctrl = res.start; | 1190 | if (!of_property_read_u32_index(np, "st,syscfg", i, &ctrlreg)) |
1180 | 1191 | miphy_phy->syscfg_reg[i] = ctrlreg; | |
1181 | if (!miphy28lp_get_resource_byname(np, "miphy-status-glue", &res)) | 1192 | } |
1182 | miphy_phy->syscfg_miphy_status = res.start; | ||
1183 | |||
1184 | if (!miphy28lp_get_resource_byname(np, "pcie-glue", &res)) | ||
1185 | miphy_phy->syscfg_pci = res.start; | ||
1186 | |||
1187 | if (!miphy28lp_get_resource_byname(np, "sata-glue", &res)) | ||
1188 | miphy_phy->syscfg_sata = res.start; | ||
1189 | |||
1190 | 1193 | ||
1191 | return 0; | 1194 | return 0; |
1192 | } | 1195 | } |
diff --git a/drivers/phy/phy-miphy365x.c b/drivers/phy/phy-miphy365x.c index 6ab43a814ad2..6c80154e8bff 100644 --- a/drivers/phy/phy-miphy365x.c +++ b/drivers/phy/phy-miphy365x.c | |||
@@ -141,7 +141,7 @@ struct miphy365x_phy { | |||
141 | bool pcie_tx_pol_inv; | 141 | bool pcie_tx_pol_inv; |
142 | bool sata_tx_pol_inv; | 142 | bool sata_tx_pol_inv; |
143 | u32 sata_gen; | 143 | u32 sata_gen; |
144 | u64 ctrlreg; | 144 | u32 ctrlreg; |
145 | u8 type; | 145 | u8 type; |
146 | }; | 146 | }; |
147 | 147 | ||
@@ -179,7 +179,7 @@ static int miphy365x_set_path(struct miphy365x_phy *miphy_phy, | |||
179 | bool sata = (miphy_phy->type == MIPHY_TYPE_SATA); | 179 | bool sata = (miphy_phy->type == MIPHY_TYPE_SATA); |
180 | 180 | ||
181 | return regmap_update_bits(miphy_dev->regmap, | 181 | return regmap_update_bits(miphy_dev->regmap, |
182 | (unsigned int)miphy_phy->ctrlreg, | 182 | miphy_phy->ctrlreg, |
183 | SYSCFG_SELECT_SATA_MASK, | 183 | SYSCFG_SELECT_SATA_MASK, |
184 | sata << SYSCFG_SELECT_SATA_POS); | 184 | sata << SYSCFG_SELECT_SATA_POS); |
185 | } | 185 | } |
@@ -445,7 +445,6 @@ int miphy365x_get_addr(struct device *dev, struct miphy365x_phy *miphy_phy, | |||
445 | { | 445 | { |
446 | struct device_node *phynode = miphy_phy->phy->dev.of_node; | 446 | struct device_node *phynode = miphy_phy->phy->dev.of_node; |
447 | const char *name; | 447 | const char *name; |
448 | const __be32 *taddr; | ||
449 | int type = miphy_phy->type; | 448 | int type = miphy_phy->type; |
450 | int ret; | 449 | int ret; |
451 | 450 | ||
@@ -455,22 +454,6 @@ int miphy365x_get_addr(struct device *dev, struct miphy365x_phy *miphy_phy, | |||
455 | return ret; | 454 | return ret; |
456 | } | 455 | } |
457 | 456 | ||
458 | if (!strncmp(name, "syscfg", 6)) { | ||
459 | taddr = of_get_address(phynode, index, NULL, NULL); | ||
460 | if (!taddr) { | ||
461 | dev_err(dev, "failed to fetch syscfg address\n"); | ||
462 | return -EINVAL; | ||
463 | } | ||
464 | |||
465 | miphy_phy->ctrlreg = of_translate_address(phynode, taddr); | ||
466 | if (miphy_phy->ctrlreg == OF_BAD_ADDR) { | ||
467 | dev_err(dev, "failed to translate syscfg address\n"); | ||
468 | return -EINVAL; | ||
469 | } | ||
470 | |||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | if (!((!strncmp(name, "sata", 4) && type == MIPHY_TYPE_SATA) || | 457 | if (!((!strncmp(name, "sata", 4) && type == MIPHY_TYPE_SATA) || |
475 | (!strncmp(name, "pcie", 4) && type == MIPHY_TYPE_PCIE))) | 458 | (!strncmp(name, "pcie", 4) && type == MIPHY_TYPE_PCIE))) |
476 | return 0; | 459 | return 0; |
@@ -606,7 +589,15 @@ static int miphy365x_probe(struct platform_device *pdev) | |||
606 | return ret; | 589 | return ret; |
607 | 590 | ||
608 | phy_set_drvdata(phy, miphy_dev->phys[port]); | 591 | phy_set_drvdata(phy, miphy_dev->phys[port]); |
592 | |||
609 | port++; | 593 | port++; |
594 | /* sysconfig offsets are indexed from 1 */ | ||
595 | ret = of_property_read_u32_index(np, "st,syscfg", port, | ||
596 | &miphy_phy->ctrlreg); | ||
597 | if (ret) { | ||
598 | dev_err(&pdev->dev, "No sysconfig offset found\n"); | ||
599 | return ret; | ||
600 | } | ||
610 | } | 601 | } |
611 | 602 | ||
612 | provider = devm_of_phy_provider_register(&pdev->dev, miphy365x_xlate); | 603 | provider = devm_of_phy_provider_register(&pdev->dev, miphy365x_xlate); |
diff --git a/drivers/phy/phy-rockchip-usb.c b/drivers/phy/phy-rockchip-usb.c new file mode 100644 index 000000000000..22011c3b6a4b --- /dev/null +++ b/drivers/phy/phy-rockchip-usb.c | |||
@@ -0,0 +1,158 @@ | |||
1 | /* | ||
2 | * Rockchip usb PHY driver | ||
3 | * | ||
4 | * Copyright (C) 2014 Yunzhi Li <lyz@rock-chips.com> | ||
5 | * Copyright (C) 2014 ROCKCHIP, Inc. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/clk.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/mutex.h> | ||
22 | #include <linux/of.h> | ||
23 | #include <linux/of_address.h> | ||
24 | #include <linux/phy/phy.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/regulator/consumer.h> | ||
27 | #include <linux/reset.h> | ||
28 | #include <linux/regmap.h> | ||
29 | #include <linux/mfd/syscon.h> | ||
30 | |||
31 | /* | ||
32 | * The higher 16-bit of this register is used for write protection | ||
33 | * only if BIT(13 + 16) set to 1 the BIT(13) can be written. | ||
34 | */ | ||
35 | #define SIDDQ_WRITE_ENA BIT(29) | ||
36 | #define SIDDQ_ON BIT(13) | ||
37 | #define SIDDQ_OFF (0 << 13) | ||
38 | |||
39 | struct rockchip_usb_phy { | ||
40 | unsigned int reg_offset; | ||
41 | struct regmap *reg_base; | ||
42 | struct clk *clk; | ||
43 | struct phy *phy; | ||
44 | }; | ||
45 | |||
46 | static int rockchip_usb_phy_power(struct rockchip_usb_phy *phy, | ||
47 | bool siddq) | ||
48 | { | ||
49 | return regmap_write(phy->reg_base, phy->reg_offset, | ||
50 | SIDDQ_WRITE_ENA | (siddq ? SIDDQ_ON : SIDDQ_OFF)); | ||
51 | } | ||
52 | |||
53 | static int rockchip_usb_phy_power_off(struct phy *_phy) | ||
54 | { | ||
55 | struct rockchip_usb_phy *phy = phy_get_drvdata(_phy); | ||
56 | int ret = 0; | ||
57 | |||
58 | /* Power down usb phy analog blocks by set siddq 1 */ | ||
59 | ret = rockchip_usb_phy_power(phy, 1); | ||
60 | if (ret) | ||
61 | return ret; | ||
62 | |||
63 | clk_disable_unprepare(phy->clk); | ||
64 | if (ret) | ||
65 | return ret; | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static int rockchip_usb_phy_power_on(struct phy *_phy) | ||
71 | { | ||
72 | struct rockchip_usb_phy *phy = phy_get_drvdata(_phy); | ||
73 | int ret = 0; | ||
74 | |||
75 | ret = clk_prepare_enable(phy->clk); | ||
76 | if (ret) | ||
77 | return ret; | ||
78 | |||
79 | /* Power up usb phy analog blocks by set siddq 0 */ | ||
80 | ret = rockchip_usb_phy_power(phy, 0); | ||
81 | if (ret) | ||
82 | return ret; | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static struct phy_ops ops = { | ||
88 | .power_on = rockchip_usb_phy_power_on, | ||
89 | .power_off = rockchip_usb_phy_power_off, | ||
90 | .owner = THIS_MODULE, | ||
91 | }; | ||
92 | |||
93 | static int rockchip_usb_phy_probe(struct platform_device *pdev) | ||
94 | { | ||
95 | struct device *dev = &pdev->dev; | ||
96 | struct rockchip_usb_phy *rk_phy; | ||
97 | struct phy_provider *phy_provider; | ||
98 | struct device_node *child; | ||
99 | struct regmap *grf; | ||
100 | unsigned int reg_offset; | ||
101 | |||
102 | grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); | ||
103 | if (IS_ERR(grf)) { | ||
104 | dev_err(&pdev->dev, "Missing rockchip,grf property\n"); | ||
105 | return PTR_ERR(grf); | ||
106 | } | ||
107 | |||
108 | for_each_available_child_of_node(dev->of_node, child) { | ||
109 | rk_phy = devm_kzalloc(dev, sizeof(*rk_phy), GFP_KERNEL); | ||
110 | if (!rk_phy) | ||
111 | return -ENOMEM; | ||
112 | |||
113 | if (of_property_read_u32(child, "reg", ®_offset)) { | ||
114 | dev_err(dev, "missing reg property in node %s\n", | ||
115 | child->name); | ||
116 | return -EINVAL; | ||
117 | } | ||
118 | |||
119 | rk_phy->reg_offset = reg_offset; | ||
120 | rk_phy->reg_base = grf; | ||
121 | |||
122 | rk_phy->clk = of_clk_get_by_name(child, "phyclk"); | ||
123 | if (IS_ERR(rk_phy->clk)) | ||
124 | rk_phy->clk = NULL; | ||
125 | |||
126 | rk_phy->phy = devm_phy_create(dev, child, &ops); | ||
127 | if (IS_ERR(rk_phy->phy)) { | ||
128 | dev_err(dev, "failed to create PHY\n"); | ||
129 | return PTR_ERR(rk_phy->phy); | ||
130 | } | ||
131 | phy_set_drvdata(rk_phy->phy, rk_phy); | ||
132 | } | ||
133 | |||
134 | phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); | ||
135 | return PTR_ERR_OR_ZERO(phy_provider); | ||
136 | } | ||
137 | |||
138 | static const struct of_device_id rockchip_usb_phy_dt_ids[] = { | ||
139 | { .compatible = "rockchip,rk3288-usb-phy" }, | ||
140 | {} | ||
141 | }; | ||
142 | |||
143 | MODULE_DEVICE_TABLE(of, rockchip_usb_phy_dt_ids); | ||
144 | |||
145 | static struct platform_driver rockchip_usb_driver = { | ||
146 | .probe = rockchip_usb_phy_probe, | ||
147 | .driver = { | ||
148 | .name = "rockchip-usb-phy", | ||
149 | .owner = THIS_MODULE, | ||
150 | .of_match_table = rockchip_usb_phy_dt_ids, | ||
151 | }, | ||
152 | }; | ||
153 | |||
154 | module_platform_driver(rockchip_usb_driver); | ||
155 | |||
156 | MODULE_AUTHOR("Yunzhi Li <lyz@rock-chips.com>"); | ||
157 | MODULE_DESCRIPTION("Rockchip USB 2.0 PHY driver"); | ||
158 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/phy/phy-stih407-usb.c b/drivers/phy/phy-stih407-usb.c index 74f0fab3cd8a..1d5ae5f8ef69 100644 --- a/drivers/phy/phy-stih407-usb.c +++ b/drivers/phy/phy-stih407-usb.c | |||
@@ -22,6 +22,9 @@ | |||
22 | #include <linux/mfd/syscon.h> | 22 | #include <linux/mfd/syscon.h> |
23 | #include <linux/phy/phy.h> | 23 | #include <linux/phy/phy.h> |
24 | 24 | ||
25 | #define PHYPARAM_REG 1 | ||
26 | #define PHYCTRL_REG 2 | ||
27 | |||
25 | /* Default PHY_SEL and REFCLKSEL configuration */ | 28 | /* Default PHY_SEL and REFCLKSEL configuration */ |
26 | #define STIH407_USB_PICOPHY_CTRL_PORT_CONF 0x6 | 29 | #define STIH407_USB_PICOPHY_CTRL_PORT_CONF 0x6 |
27 | #define STIH407_USB_PICOPHY_CTRL_PORT_MASK 0x1f | 30 | #define STIH407_USB_PICOPHY_CTRL_PORT_MASK 0x1f |
@@ -93,7 +96,7 @@ static int stih407_usb2_picophy_probe(struct platform_device *pdev) | |||
93 | struct device_node *np = dev->of_node; | 96 | struct device_node *np = dev->of_node; |
94 | struct phy_provider *phy_provider; | 97 | struct phy_provider *phy_provider; |
95 | struct phy *phy; | 98 | struct phy *phy; |
96 | struct resource *res; | 99 | int ret; |
97 | 100 | ||
98 | phy_dev = devm_kzalloc(dev, sizeof(*phy_dev), GFP_KERNEL); | 101 | phy_dev = devm_kzalloc(dev, sizeof(*phy_dev), GFP_KERNEL); |
99 | if (!phy_dev) | 102 | if (!phy_dev) |
@@ -123,19 +126,19 @@ static int stih407_usb2_picophy_probe(struct platform_device *pdev) | |||
123 | return PTR_ERR(phy_dev->regmap); | 126 | return PTR_ERR(phy_dev->regmap); |
124 | } | 127 | } |
125 | 128 | ||
126 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl"); | 129 | ret = of_property_read_u32_index(np, "st,syscfg", PHYPARAM_REG, |
127 | if (!res) { | 130 | &phy_dev->param); |
128 | dev_err(dev, "No ctrl reg found\n"); | 131 | if (ret) { |
129 | return -ENXIO; | 132 | dev_err(dev, "can't get phyparam offset (%d)\n", ret); |
133 | return ret; | ||
130 | } | 134 | } |
131 | phy_dev->ctrl = res->start; | ||
132 | 135 | ||
133 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "param"); | 136 | ret = of_property_read_u32_index(np, "st,syscfg", PHYCTRL_REG, |
134 | if (!res) { | 137 | &phy_dev->ctrl); |
135 | dev_err(dev, "No param reg found\n"); | 138 | if (ret) { |
136 | return -ENXIO; | 139 | dev_err(dev, "can't get phyctrl offset (%d)\n", ret); |
140 | return ret; | ||
137 | } | 141 | } |
138 | phy_dev->param = res->start; | ||
139 | 142 | ||
140 | phy = devm_phy_create(dev, NULL, &stih407_usb2_picophy_data); | 143 | phy = devm_phy_create(dev, NULL, &stih407_usb2_picophy_data); |
141 | if (IS_ERR(phy)) { | 144 | if (IS_ERR(phy)) { |
diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c index 465de2c800f2..95c88f929f27 100644 --- a/drivers/phy/phy-ti-pipe3.c +++ b/drivers/phy/phy-ti-pipe3.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/phy/omap_control_phy.h> | 29 | #include <linux/phy/omap_control_phy.h> |
30 | #include <linux/of_platform.h> | 30 | #include <linux/of_platform.h> |
31 | #include <linux/spinlock.h> | ||
31 | 32 | ||
32 | #define PLL_STATUS 0x00000004 | 33 | #define PLL_STATUS 0x00000004 |
33 | #define PLL_GO 0x00000008 | 34 | #define PLL_GO 0x00000008 |
@@ -82,6 +83,10 @@ struct ti_pipe3 { | |||
82 | struct clk *refclk; | 83 | struct clk *refclk; |
83 | struct clk *div_clk; | 84 | struct clk *div_clk; |
84 | struct pipe3_dpll_map *dpll_map; | 85 | struct pipe3_dpll_map *dpll_map; |
86 | bool enabled; | ||
87 | spinlock_t lock; /* serialize clock enable/disable */ | ||
88 | /* the below flag is needed specifically for SATA */ | ||
89 | bool refclk_enabled; | ||
85 | }; | 90 | }; |
86 | 91 | ||
87 | static struct pipe3_dpll_map dpll_map_usb[] = { | 92 | static struct pipe3_dpll_map dpll_map_usb[] = { |
@@ -307,6 +312,7 @@ static int ti_pipe3_probe(struct platform_device *pdev) | |||
307 | return -ENOMEM; | 312 | return -ENOMEM; |
308 | 313 | ||
309 | phy->dev = &pdev->dev; | 314 | phy->dev = &pdev->dev; |
315 | spin_lock_init(&phy->lock); | ||
310 | 316 | ||
311 | if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { | 317 | if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { |
312 | match = of_match_device(of_match_ptr(ti_pipe3_id_table), | 318 | match = of_match_device(of_match_ptr(ti_pipe3_id_table), |
@@ -333,21 +339,24 @@ static int ti_pipe3_probe(struct platform_device *pdev) | |||
333 | } | 339 | } |
334 | } | 340 | } |
335 | 341 | ||
342 | phy->refclk = devm_clk_get(phy->dev, "refclk"); | ||
343 | if (IS_ERR(phy->refclk)) { | ||
344 | dev_err(&pdev->dev, "unable to get refclk\n"); | ||
345 | /* older DTBs have missing refclk in SATA PHY | ||
346 | * so don't bail out in case of SATA PHY. | ||
347 | */ | ||
348 | if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) | ||
349 | return PTR_ERR(phy->refclk); | ||
350 | } | ||
351 | |||
336 | if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) { | 352 | if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) { |
337 | phy->wkupclk = devm_clk_get(phy->dev, "wkupclk"); | 353 | phy->wkupclk = devm_clk_get(phy->dev, "wkupclk"); |
338 | if (IS_ERR(phy->wkupclk)) { | 354 | if (IS_ERR(phy->wkupclk)) { |
339 | dev_err(&pdev->dev, "unable to get wkupclk\n"); | 355 | dev_err(&pdev->dev, "unable to get wkupclk\n"); |
340 | return PTR_ERR(phy->wkupclk); | 356 | return PTR_ERR(phy->wkupclk); |
341 | } | 357 | } |
342 | |||
343 | phy->refclk = devm_clk_get(phy->dev, "refclk"); | ||
344 | if (IS_ERR(phy->refclk)) { | ||
345 | dev_err(&pdev->dev, "unable to get refclk\n"); | ||
346 | return PTR_ERR(phy->refclk); | ||
347 | } | ||
348 | } else { | 358 | } else { |
349 | phy->wkupclk = ERR_PTR(-ENODEV); | 359 | phy->wkupclk = ERR_PTR(-ENODEV); |
350 | phy->refclk = ERR_PTR(-ENODEV); | ||
351 | } | 360 | } |
352 | 361 | ||
353 | if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { | 362 | if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { |
@@ -426,33 +435,42 @@ static int ti_pipe3_remove(struct platform_device *pdev) | |||
426 | } | 435 | } |
427 | 436 | ||
428 | #ifdef CONFIG_PM | 437 | #ifdef CONFIG_PM |
429 | 438 | static int ti_pipe3_enable_refclk(struct ti_pipe3 *phy) | |
430 | static int ti_pipe3_runtime_suspend(struct device *dev) | ||
431 | { | 439 | { |
432 | struct ti_pipe3 *phy = dev_get_drvdata(dev); | 440 | if (!IS_ERR(phy->refclk) && !phy->refclk_enabled) { |
441 | int ret; | ||
433 | 442 | ||
434 | if (!IS_ERR(phy->wkupclk)) | 443 | ret = clk_prepare_enable(phy->refclk); |
435 | clk_disable_unprepare(phy->wkupclk); | 444 | if (ret) { |
445 | dev_err(phy->dev, "Failed to enable refclk %d\n", ret); | ||
446 | return ret; | ||
447 | } | ||
448 | phy->refclk_enabled = true; | ||
449 | } | ||
450 | |||
451 | return 0; | ||
452 | } | ||
453 | |||
454 | static void ti_pipe3_disable_refclk(struct ti_pipe3 *phy) | ||
455 | { | ||
436 | if (!IS_ERR(phy->refclk)) | 456 | if (!IS_ERR(phy->refclk)) |
437 | clk_disable_unprepare(phy->refclk); | 457 | clk_disable_unprepare(phy->refclk); |
438 | if (!IS_ERR(phy->div_clk)) | ||
439 | clk_disable_unprepare(phy->div_clk); | ||
440 | 458 | ||
441 | return 0; | 459 | phy->refclk_enabled = false; |
442 | } | 460 | } |
443 | 461 | ||
444 | static int ti_pipe3_runtime_resume(struct device *dev) | 462 | static int ti_pipe3_enable_clocks(struct ti_pipe3 *phy) |
445 | { | 463 | { |
446 | u32 ret = 0; | 464 | int ret = 0; |
447 | struct ti_pipe3 *phy = dev_get_drvdata(dev); | 465 | unsigned long flags; |
448 | 466 | ||
449 | if (!IS_ERR(phy->refclk)) { | 467 | spin_lock_irqsave(&phy->lock, flags); |
450 | ret = clk_prepare_enable(phy->refclk); | 468 | if (phy->enabled) |
451 | if (ret) { | 469 | goto err1; |
452 | dev_err(phy->dev, "Failed to enable refclk %d\n", ret); | 470 | |
453 | goto err1; | 471 | ret = ti_pipe3_enable_refclk(phy); |
454 | } | 472 | if (ret) |
455 | } | 473 | goto err1; |
456 | 474 | ||
457 | if (!IS_ERR(phy->wkupclk)) { | 475 | if (!IS_ERR(phy->wkupclk)) { |
458 | ret = clk_prepare_enable(phy->wkupclk); | 476 | ret = clk_prepare_enable(phy->wkupclk); |
@@ -469,6 +487,9 @@ static int ti_pipe3_runtime_resume(struct device *dev) | |||
469 | goto err3; | 487 | goto err3; |
470 | } | 488 | } |
471 | } | 489 | } |
490 | |||
491 | phy->enabled = true; | ||
492 | spin_unlock_irqrestore(&phy->lock, flags); | ||
472 | return 0; | 493 | return 0; |
473 | 494 | ||
474 | err3: | 495 | err3: |
@@ -479,20 +500,80 @@ err2: | |||
479 | if (!IS_ERR(phy->refclk)) | 500 | if (!IS_ERR(phy->refclk)) |
480 | clk_disable_unprepare(phy->refclk); | 501 | clk_disable_unprepare(phy->refclk); |
481 | 502 | ||
503 | ti_pipe3_disable_refclk(phy); | ||
482 | err1: | 504 | err1: |
505 | spin_unlock_irqrestore(&phy->lock, flags); | ||
483 | return ret; | 506 | return ret; |
484 | } | 507 | } |
485 | 508 | ||
509 | static void ti_pipe3_disable_clocks(struct ti_pipe3 *phy) | ||
510 | { | ||
511 | unsigned long flags; | ||
512 | |||
513 | spin_lock_irqsave(&phy->lock, flags); | ||
514 | if (!phy->enabled) { | ||
515 | spin_unlock_irqrestore(&phy->lock, flags); | ||
516 | return; | ||
517 | } | ||
518 | |||
519 | if (!IS_ERR(phy->wkupclk)) | ||
520 | clk_disable_unprepare(phy->wkupclk); | ||
521 | /* Don't disable refclk for SATA PHY due to Errata i783 */ | ||
522 | if (!of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-sata")) | ||
523 | ti_pipe3_disable_refclk(phy); | ||
524 | if (!IS_ERR(phy->div_clk)) | ||
525 | clk_disable_unprepare(phy->div_clk); | ||
526 | phy->enabled = false; | ||
527 | spin_unlock_irqrestore(&phy->lock, flags); | ||
528 | } | ||
529 | |||
530 | static int ti_pipe3_runtime_suspend(struct device *dev) | ||
531 | { | ||
532 | struct ti_pipe3 *phy = dev_get_drvdata(dev); | ||
533 | |||
534 | ti_pipe3_disable_clocks(phy); | ||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static int ti_pipe3_runtime_resume(struct device *dev) | ||
539 | { | ||
540 | struct ti_pipe3 *phy = dev_get_drvdata(dev); | ||
541 | int ret = 0; | ||
542 | |||
543 | ret = ti_pipe3_enable_clocks(phy); | ||
544 | return ret; | ||
545 | } | ||
546 | |||
547 | static int ti_pipe3_suspend(struct device *dev) | ||
548 | { | ||
549 | struct ti_pipe3 *phy = dev_get_drvdata(dev); | ||
550 | |||
551 | ti_pipe3_disable_clocks(phy); | ||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | static int ti_pipe3_resume(struct device *dev) | ||
556 | { | ||
557 | struct ti_pipe3 *phy = dev_get_drvdata(dev); | ||
558 | int ret; | ||
559 | |||
560 | ret = ti_pipe3_enable_clocks(phy); | ||
561 | if (ret) | ||
562 | return ret; | ||
563 | |||
564 | pm_runtime_disable(dev); | ||
565 | pm_runtime_set_active(dev); | ||
566 | pm_runtime_enable(dev); | ||
567 | return 0; | ||
568 | } | ||
569 | #endif | ||
570 | |||
486 | static const struct dev_pm_ops ti_pipe3_pm_ops = { | 571 | static const struct dev_pm_ops ti_pipe3_pm_ops = { |
487 | SET_RUNTIME_PM_OPS(ti_pipe3_runtime_suspend, | 572 | SET_RUNTIME_PM_OPS(ti_pipe3_runtime_suspend, |
488 | ti_pipe3_runtime_resume, NULL) | 573 | ti_pipe3_runtime_resume, NULL) |
574 | SET_SYSTEM_SLEEP_PM_OPS(ti_pipe3_suspend, ti_pipe3_resume) | ||
489 | }; | 575 | }; |
490 | 576 | ||
491 | #define DEV_PM_OPS (&ti_pipe3_pm_ops) | ||
492 | #else | ||
493 | #define DEV_PM_OPS NULL | ||
494 | #endif | ||
495 | |||
496 | #ifdef CONFIG_OF | 577 | #ifdef CONFIG_OF |
497 | static const struct of_device_id ti_pipe3_id_table[] = { | 578 | static const struct of_device_id ti_pipe3_id_table[] = { |
498 | { | 579 | { |
@@ -520,7 +601,7 @@ static struct platform_driver ti_pipe3_driver = { | |||
520 | .remove = ti_pipe3_remove, | 601 | .remove = ti_pipe3_remove, |
521 | .driver = { | 602 | .driver = { |
522 | .name = "ti-pipe3", | 603 | .name = "ti-pipe3", |
523 | .pm = DEV_PM_OPS, | 604 | .pm = &ti_pipe3_pm_ops, |
524 | .of_match_table = of_match_ptr(ti_pipe3_id_table), | 605 | .of_match_table = of_match_ptr(ti_pipe3_id_table), |
525 | }, | 606 | }, |
526 | }; | 607 | }; |
diff --git a/include/linux/mfd/syscon/exynos4-pmu.h b/include/linux/mfd/syscon/exynos4-pmu.h new file mode 100644 index 000000000000..278b1b1549e9 --- /dev/null +++ b/include/linux/mfd/syscon/exynos4-pmu.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Samsung Electronics Co., Ltd. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #ifndef _LINUX_MFD_SYSCON_PMU_EXYNOS4_H_ | ||
10 | #define _LINUX_MFD_SYSCON_PMU_EXYNOS4_H_ | ||
11 | |||
12 | /* Exynos4 PMU register definitions */ | ||
13 | |||
14 | /* MIPI_PHYn_CONTROL register offset: n = 0..1 */ | ||
15 | #define EXYNOS4_MIPI_PHY_CONTROL(n) (0x710 + (n) * 4) | ||
16 | #define EXYNOS4_MIPI_PHY_ENABLE (1 << 0) | ||
17 | #define EXYNOS4_MIPI_PHY_SRESETN (1 << 1) | ||
18 | #define EXYNOS4_MIPI_PHY_MRESETN (1 << 2) | ||
19 | #define EXYNOS4_MIPI_PHY_RESET_MASK (3 << 1) | ||
20 | |||
21 | #endif /* _LINUX_MFD_SYSCON_PMU_EXYNOS4_H_ */ | ||