.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Rockchip usb PHY driver |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2014 Yunzhi Li <lyz@rock-chips.com> |
---|
5 | 6 | * 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 | 7 | */ |
---|
16 | 8 | |
---|
17 | 9 | #include <linux/clk.h> |
---|
.. | .. |
---|
42 | 34 | #define HIWORD_UPDATE(val, mask) \ |
---|
43 | 35 | ((val) | (mask) << 16) |
---|
44 | 36 | |
---|
45 | | -#define UOC_CON0_SIDDQ BIT(13) |
---|
| 37 | +#define UOC_CON0 0x00 |
---|
| 38 | +#define UOC_CON0_SIDDQ BIT(13) |
---|
| 39 | +#define UOC_CON0_DISABLE BIT(4) |
---|
| 40 | +#define UOC_CON0_COMMON_ON_N BIT(0) |
---|
| 41 | + |
---|
| 42 | +#define UOC_CON2 0x08 |
---|
| 43 | +#define UOC_CON2_SOFT_CON_SEL BIT(2) |
---|
| 44 | + |
---|
| 45 | +#define UOC_CON3 0x0c |
---|
| 46 | +/* bits present on rk3188 and rk3288 phys */ |
---|
| 47 | +#define UOC_CON3_UTMI_TERMSEL_FULLSPEED BIT(5) |
---|
| 48 | +#define UOC_CON3_UTMI_XCVRSEELCT_FSTRANSC (1 << 3) |
---|
| 49 | +#define UOC_CON3_UTMI_XCVRSEELCT_MASK (3 << 3) |
---|
| 50 | +#define UOC_CON3_UTMI_OPMODE_NODRIVING (1 << 1) |
---|
| 51 | +#define UOC_CON3_UTMI_OPMODE_MASK (3 << 1) |
---|
| 52 | +#define UOC_CON3_UTMI_SUSPENDN BIT(0) |
---|
46 | 53 | |
---|
47 | 54 | #define RK3288_UOC0_CON0 0x320 |
---|
48 | 55 | #define RK3288_UOC0_CON0_COMMON_ON_N BIT(0) |
---|
.. | .. |
---|
115 | 122 | struct rockchip_usb_phy_base; |
---|
116 | 123 | struct rockchip_usb_phy_pdata { |
---|
117 | 124 | struct rockchip_usb_phys *phys; |
---|
118 | | - int (*init_usb_uart)(struct regmap *grf); |
---|
| 125 | + int (*init_usb_uart)(struct regmap *grf, |
---|
| 126 | + const struct rockchip_usb_phy_pdata *pdata); |
---|
119 | 127 | int usb_uart_phy; |
---|
120 | 128 | }; |
---|
121 | 129 | |
---|
.. | .. |
---|
648 | 656 | rk_phy->chg_type = POWER_SUPPLY_TYPE_USB_DCP; |
---|
649 | 657 | else |
---|
650 | 658 | rk_phy->chg_type = POWER_SUPPLY_TYPE_USB_CDP; |
---|
651 | | - /* fall through */ |
---|
| 659 | + fallthrough; |
---|
652 | 660 | case USB_CHG_STATE_SECONDARY_DONE: |
---|
653 | 661 | rk_phy->chg_state = USB_CHG_STATE_DETECTED; |
---|
654 | | - /* fall through */ |
---|
| 662 | + fallthrough; |
---|
655 | 663 | case USB_CHG_STATE_DETECTED: |
---|
656 | 664 | /* put the controller in normal mode */ |
---|
657 | 665 | val = HIWORD_UPDATE(0, RK3288_UOC0_CON2_SOFT_CON_SEL); |
---|
.. | .. |
---|
795 | 803 | mutex_init(&rk_phy->mutex); |
---|
796 | 804 | |
---|
797 | 805 | if (of_property_read_u32(child, "reg", ®_offset)) { |
---|
798 | | - dev_err(base->dev, "missing reg property in node %s\n", |
---|
799 | | - child->name); |
---|
| 806 | + dev_err(base->dev, "missing reg property in node %pOFn\n", |
---|
| 807 | + child); |
---|
800 | 808 | return -EINVAL; |
---|
801 | 809 | } |
---|
802 | 810 | |
---|
.. | .. |
---|
906 | 914 | }, |
---|
907 | 915 | }; |
---|
908 | 916 | |
---|
| 917 | +static int __init rockchip_init_usb_uart_common(struct regmap *grf, |
---|
| 918 | + const struct rockchip_usb_phy_pdata *pdata) |
---|
| 919 | +{ |
---|
| 920 | + int regoffs = pdata->phys[pdata->usb_uart_phy].reg; |
---|
| 921 | + int ret; |
---|
| 922 | + u32 val; |
---|
| 923 | + |
---|
| 924 | + /* |
---|
| 925 | + * COMMON_ON and DISABLE settings are described in the TRM, |
---|
| 926 | + * but were not present in the original code. |
---|
| 927 | + * Also disable the analog phy components to save power. |
---|
| 928 | + */ |
---|
| 929 | + val = HIWORD_UPDATE(UOC_CON0_COMMON_ON_N |
---|
| 930 | + | UOC_CON0_DISABLE |
---|
| 931 | + | UOC_CON0_SIDDQ, |
---|
| 932 | + UOC_CON0_COMMON_ON_N |
---|
| 933 | + | UOC_CON0_DISABLE |
---|
| 934 | + | UOC_CON0_SIDDQ); |
---|
| 935 | + ret = regmap_write(grf, regoffs + UOC_CON0, val); |
---|
| 936 | + if (ret) |
---|
| 937 | + return ret; |
---|
| 938 | + |
---|
| 939 | + val = HIWORD_UPDATE(UOC_CON2_SOFT_CON_SEL, |
---|
| 940 | + UOC_CON2_SOFT_CON_SEL); |
---|
| 941 | + ret = regmap_write(grf, regoffs + UOC_CON2, val); |
---|
| 942 | + if (ret) |
---|
| 943 | + return ret; |
---|
| 944 | + |
---|
| 945 | + val = HIWORD_UPDATE(UOC_CON3_UTMI_OPMODE_NODRIVING |
---|
| 946 | + | UOC_CON3_UTMI_XCVRSEELCT_FSTRANSC |
---|
| 947 | + | UOC_CON3_UTMI_TERMSEL_FULLSPEED, |
---|
| 948 | + UOC_CON3_UTMI_SUSPENDN |
---|
| 949 | + | UOC_CON3_UTMI_OPMODE_MASK |
---|
| 950 | + | UOC_CON3_UTMI_XCVRSEELCT_MASK |
---|
| 951 | + | UOC_CON3_UTMI_TERMSEL_FULLSPEED); |
---|
| 952 | + ret = regmap_write(grf, UOC_CON3, val); |
---|
| 953 | + if (ret) |
---|
| 954 | + return ret; |
---|
| 955 | + |
---|
| 956 | + return 0; |
---|
| 957 | +} |
---|
| 958 | + |
---|
| 959 | +#define RK3188_UOC0_CON0 0x10c |
---|
| 960 | +#define RK3188_UOC0_CON0_BYPASSSEL BIT(9) |
---|
| 961 | +#define RK3188_UOC0_CON0_BYPASSDMEN BIT(8) |
---|
| 962 | + |
---|
| 963 | +/* |
---|
| 964 | + * Enable the bypass of uart2 data through the otg usb phy. |
---|
| 965 | + * See description of rk3288-variant for details. |
---|
| 966 | + */ |
---|
| 967 | +static int __init rk3188_init_usb_uart(struct regmap *grf, |
---|
| 968 | + const struct rockchip_usb_phy_pdata *pdata) |
---|
| 969 | +{ |
---|
| 970 | + u32 val; |
---|
| 971 | + int ret; |
---|
| 972 | + |
---|
| 973 | + ret = rockchip_init_usb_uart_common(grf, pdata); |
---|
| 974 | + if (ret) |
---|
| 975 | + return ret; |
---|
| 976 | + |
---|
| 977 | + val = HIWORD_UPDATE(RK3188_UOC0_CON0_BYPASSSEL |
---|
| 978 | + | RK3188_UOC0_CON0_BYPASSDMEN, |
---|
| 979 | + RK3188_UOC0_CON0_BYPASSSEL |
---|
| 980 | + | RK3188_UOC0_CON0_BYPASSDMEN); |
---|
| 981 | + ret = regmap_write(grf, RK3188_UOC0_CON0, val); |
---|
| 982 | + if (ret) |
---|
| 983 | + return ret; |
---|
| 984 | + |
---|
| 985 | + return 0; |
---|
| 986 | +} |
---|
| 987 | + |
---|
909 | 988 | static const struct rockchip_usb_phy_pdata rk3188_pdata = { |
---|
910 | 989 | .phys = (struct rockchip_usb_phys[]){ |
---|
911 | 990 | { .reg = 0x10c, .pll_name = "sclk_otgphy0_480m" }, |
---|
912 | 991 | { .reg = 0x11c, .pll_name = "sclk_otgphy1_480m" }, |
---|
913 | 992 | { /* sentinel */ } |
---|
914 | 993 | }, |
---|
| 994 | + .init_usb_uart = rk3188_init_usb_uart, |
---|
| 995 | + .usb_uart_phy = 0, |
---|
915 | 996 | }; |
---|
916 | 997 | |
---|
917 | 998 | /* |
---|
.. | .. |
---|
929 | 1010 | * |
---|
930 | 1011 | * The actual code in the vendor kernel does some things differently. |
---|
931 | 1012 | */ |
---|
932 | | -static int __init rk3288_init_usb_uart(struct regmap *grf) |
---|
| 1013 | +static int __init rk3288_init_usb_uart(struct regmap *grf, |
---|
| 1014 | + const struct rockchip_usb_phy_pdata *pdata) |
---|
933 | 1015 | { |
---|
934 | 1016 | u32 val; |
---|
935 | 1017 | int ret; |
---|
936 | 1018 | |
---|
937 | | - /* |
---|
938 | | - * COMMON_ON and DISABLE settings are described in the TRM, |
---|
939 | | - * but were not present in the original code. |
---|
940 | | - * Also disable the analog phy components to save power. |
---|
941 | | - */ |
---|
942 | | - val = HIWORD_UPDATE(RK3288_UOC0_CON0_COMMON_ON_N |
---|
943 | | - | RK3288_UOC0_CON0_DISABLE |
---|
944 | | - | UOC_CON0_SIDDQ, |
---|
945 | | - RK3288_UOC0_CON0_COMMON_ON_N |
---|
946 | | - | RK3288_UOC0_CON0_DISABLE |
---|
947 | | - | UOC_CON0_SIDDQ); |
---|
948 | | - ret = regmap_write(grf, RK3288_UOC0_CON0, val); |
---|
949 | | - if (ret) |
---|
950 | | - return ret; |
---|
951 | | - |
---|
952 | | - val = HIWORD_UPDATE(RK3288_UOC0_CON2_SOFT_CON_SEL, |
---|
953 | | - RK3288_UOC0_CON2_SOFT_CON_SEL); |
---|
954 | | - ret = regmap_write(grf, RK3288_UOC0_CON2, val); |
---|
955 | | - if (ret) |
---|
956 | | - return ret; |
---|
957 | | - |
---|
958 | | - val = HIWORD_UPDATE(RK3288_UOC0_CON3_UTMI_OPMODE_NODRIVING |
---|
959 | | - | RK3288_UOC0_CON3_UTMI_XCVRSEELCT_FSTRANSC |
---|
960 | | - | RK3288_UOC0_CON3_UTMI_TERMSEL_FULLSPEED, |
---|
961 | | - RK3288_UOC0_CON3_UTMI_SUSPENDN |
---|
962 | | - | RK3288_UOC0_CON3_UTMI_OPMODE_MASK |
---|
963 | | - | RK3288_UOC0_CON3_UTMI_XCVRSEELCT_MASK |
---|
964 | | - | RK3288_UOC0_CON3_UTMI_TERMSEL_FULLSPEED); |
---|
965 | | - ret = regmap_write(grf, RK3288_UOC0_CON3, val); |
---|
| 1019 | + ret = rockchip_init_usb_uart_common(grf, pdata); |
---|
966 | 1020 | if (ret) |
---|
967 | 1021 | return ret; |
---|
968 | 1022 | |
---|
.. | .. |
---|
1097 | 1151 | return PTR_ERR(grf); |
---|
1098 | 1152 | } |
---|
1099 | 1153 | |
---|
1100 | | - ret = data->init_usb_uart(grf); |
---|
| 1154 | + ret = data->init_usb_uart(grf, data); |
---|
1101 | 1155 | if (ret) { |
---|
1102 | 1156 | pr_err("%s: could not init usb_uart, %d\n", __func__, ret); |
---|
1103 | 1157 | enable_usb_uart = 0; |
---|