Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
80525cc2
Commit
80525cc2
authored
Mar 19, 2020
by
Thierry Reding
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-5.7/phy' into for-5.7/usb
parents
ca9e742b
6835bdc9
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
609 additions
and
91 deletions
+609
-91
drivers/phy/tegra/Kconfig
drivers/phy/tegra/Kconfig
+2
-0
drivers/phy/tegra/Makefile
drivers/phy/tegra/Makefile
+1
-0
drivers/phy/tegra/xusb-tegra124.c
drivers/phy/tegra/xusb-tegra124.c
+6
-0
drivers/phy/tegra/xusb-tegra186.c
drivers/phy/tegra/xusb-tegra186.c
+208
-57
drivers/phy/tegra/xusb-tegra210.c
drivers/phy/tegra/xusb-tegra210.c
+109
-27
drivers/phy/tegra/xusb.c
drivers/phy/tegra/xusb.c
+256
-7
drivers/phy/tegra/xusb.h
drivers/phy/tegra/xusb.h
+25
-0
include/linux/phy/tegra/xusb.h
include/linux/phy/tegra/xusb.h
+2
-0
No files found.
drivers/phy/tegra/Kconfig
View file @
80525cc2
...
...
@@ -2,6 +2,8 @@
config PHY_TEGRA_XUSB
tristate "NVIDIA Tegra XUSB pad controller driver"
depends on ARCH_TEGRA
select USB_CONN_GPIO
select USB_PHY
help
Choose this option if you have an NVIDIA Tegra SoC.
...
...
drivers/phy/tegra/Makefile
View file @
80525cc2
...
...
@@ -6,4 +6,5 @@ phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_124_SOC) += xusb-tegra124.o
phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_132_SOC)
+=
xusb-tegra124.o
phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_210_SOC)
+=
xusb-tegra210.o
phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_186_SOC)
+=
xusb-tegra186.o
phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_194_SOC)
+=
xusb-tegra186.o
obj-$(CONFIG_PHY_TEGRA194_P2U)
+=
phy-tegra194-p2u.o
drivers/phy/tegra/xusb-tegra124.c
View file @
80525cc2
...
...
@@ -1422,6 +1422,8 @@ tegra124_usb2_port_map(struct tegra_xusb_port *port)
}
static
const
struct
tegra_xusb_port_ops
tegra124_usb2_port_ops
=
{
.
release
=
tegra_xusb_usb2_port_release
,
.
remove
=
tegra_xusb_usb2_port_remove
,
.
enable
=
tegra124_usb2_port_enable
,
.
disable
=
tegra124_usb2_port_disable
,
.
map
=
tegra124_usb2_port_map
,
...
...
@@ -1443,6 +1445,7 @@ tegra124_ulpi_port_map(struct tegra_xusb_port *port)
}
static
const
struct
tegra_xusb_port_ops
tegra124_ulpi_port_ops
=
{
.
release
=
tegra_xusb_ulpi_port_release
,
.
enable
=
tegra124_ulpi_port_enable
,
.
disable
=
tegra124_ulpi_port_disable
,
.
map
=
tegra124_ulpi_port_map
,
...
...
@@ -1464,6 +1467,7 @@ tegra124_hsic_port_map(struct tegra_xusb_port *port)
}
static
const
struct
tegra_xusb_port_ops
tegra124_hsic_port_ops
=
{
.
release
=
tegra_xusb_hsic_port_release
,
.
enable
=
tegra124_hsic_port_enable
,
.
disable
=
tegra124_hsic_port_disable
,
.
map
=
tegra124_hsic_port_map
,
...
...
@@ -1647,6 +1651,8 @@ tegra124_usb3_port_map(struct tegra_xusb_port *port)
}
static
const
struct
tegra_xusb_port_ops
tegra124_usb3_port_ops
=
{
.
release
=
tegra_xusb_usb3_port_release
,
.
remove
=
tegra_xusb_usb3_port_remove
,
.
enable
=
tegra124_usb3_port_enable
,
.
disable
=
tegra124_usb3_port_disable
,
.
map
=
tegra124_usb3_port_map
,
...
...
drivers/phy/tegra/xusb-tegra186.c
View file @
80525cc2
...
...
@@ -63,6 +63,10 @@
#define SSPX_ELPG_CLAMP_EN(x) BIT(0 + (x) * 3)
#define SSPX_ELPG_CLAMP_EN_EARLY(x) BIT(1 + (x) * 3)
#define SSPX_ELPG_VCORE_DOWN(x) BIT(2 + (x) * 3)
#define XUSB_PADCTL_SS_PORT_CFG 0x2c
#define PORTX_SPEED_SUPPORT_SHIFT(x) ((x) * 4)
#define PORTX_SPEED_SUPPORT_MASK (0x3)
#define PORT_SPEED_SUPPORT_GEN1 (0x0)
#define XUSB_PADCTL_USB2_OTG_PADX_CTL0(x) (0x88 + (x) * 0x40)
#define HS_CURR_LEVEL(x) ((x) & 0x3f)
...
...
@@ -301,6 +305,97 @@ static void tegra_phy_xusb_utmi_pad_power_down(struct phy *phy)
tegra186_utmi_bias_pad_power_off
(
padctl
);
}
static
int
tegra186_xusb_padctl_vbus_override
(
struct
tegra_xusb_padctl
*
padctl
,
bool
status
)
{
u32
value
;
dev_dbg
(
padctl
->
dev
,
"%s vbus override
\n
"
,
status
?
"set"
:
"clear"
);
value
=
padctl_readl
(
padctl
,
USB2_VBUS_ID
);
if
(
status
)
{
value
|=
VBUS_OVERRIDE
;
value
&=
~
ID_OVERRIDE
(
~
0
);
value
|=
ID_OVERRIDE_FLOATING
;
}
else
{
value
&=
~
VBUS_OVERRIDE
;
}
padctl_writel
(
padctl
,
value
,
USB2_VBUS_ID
);
return
0
;
}
static
int
tegra186_xusb_padctl_id_override
(
struct
tegra_xusb_padctl
*
padctl
,
bool
status
)
{
u32
value
;
dev_dbg
(
padctl
->
dev
,
"%s id override
\n
"
,
status
?
"set"
:
"clear"
);
value
=
padctl_readl
(
padctl
,
USB2_VBUS_ID
);
if
(
status
)
{
if
(
value
&
VBUS_OVERRIDE
)
{
value
&=
~
VBUS_OVERRIDE
;
padctl_writel
(
padctl
,
value
,
USB2_VBUS_ID
);
usleep_range
(
1000
,
2000
);
value
=
padctl_readl
(
padctl
,
USB2_VBUS_ID
);
}
value
&=
~
ID_OVERRIDE
(
~
0
);
value
|=
ID_OVERRIDE_GROUNDED
;
}
else
{
value
&=
~
ID_OVERRIDE
(
~
0
);
value
|=
ID_OVERRIDE_FLOATING
;
}
padctl_writel
(
padctl
,
value
,
USB2_VBUS_ID
);
return
0
;
}
static
int
tegra186_utmi_phy_set_mode
(
struct
phy
*
phy
,
enum
phy_mode
mode
,
int
submode
)
{
struct
tegra_xusb_lane
*
lane
=
phy_get_drvdata
(
phy
);
struct
tegra_xusb_padctl
*
padctl
=
lane
->
pad
->
padctl
;
struct
tegra_xusb_usb2_port
*
port
=
tegra_xusb_find_usb2_port
(
padctl
,
lane
->
index
);
int
err
=
0
;
mutex_lock
(
&
padctl
->
lock
);
dev_dbg
(
&
port
->
base
.
dev
,
"%s: mode %d"
,
__func__
,
mode
);
if
(
mode
==
PHY_MODE_USB_OTG
)
{
if
(
submode
==
USB_ROLE_HOST
)
{
tegra186_xusb_padctl_id_override
(
padctl
,
true
);
err
=
regulator_enable
(
port
->
supply
);
}
else
if
(
submode
==
USB_ROLE_DEVICE
)
{
tegra186_xusb_padctl_vbus_override
(
padctl
,
true
);
}
else
if
(
submode
==
USB_ROLE_NONE
)
{
/*
* When port is peripheral only or role transitions to
* USB_ROLE_NONE from USB_ROLE_DEVICE, regulator is not
* enabled.
*/
if
(
regulator_is_enabled
(
port
->
supply
))
regulator_disable
(
port
->
supply
);
tegra186_xusb_padctl_id_override
(
padctl
,
false
);
tegra186_xusb_padctl_vbus_override
(
padctl
,
false
);
}
}
mutex_unlock
(
&
padctl
->
lock
);
return
err
;
}
static
int
tegra186_utmi_phy_power_on
(
struct
phy
*
phy
)
{
struct
tegra_xusb_lane
*
lane
=
phy_get_drvdata
(
phy
);
...
...
@@ -439,6 +534,7 @@ static const struct phy_ops utmi_phy_ops = {
.
exit
=
tegra186_utmi_phy_exit
,
.
power_on
=
tegra186_utmi_phy_power_on
,
.
power_off
=
tegra186_utmi_phy_power_off
,
.
set_mode
=
tegra186_utmi_phy_set_mode
,
.
owner
=
THIS_MODULE
,
};
...
...
@@ -503,19 +599,6 @@ static const char * const tegra186_usb2_functions[] = {
"xusb"
,
};
static
const
struct
tegra_xusb_lane_soc
tegra186_usb2_lanes
[]
=
{
TEGRA186_LANE
(
"usb2-0"
,
0
,
0
,
0
,
usb2
),
TEGRA186_LANE
(
"usb2-1"
,
0
,
0
,
0
,
usb2
),
TEGRA186_LANE
(
"usb2-2"
,
0
,
0
,
0
,
usb2
),
};
static
const
struct
tegra_xusb_pad_soc
tegra186_usb2_pad
=
{
.
name
=
"usb2"
,
.
num_lanes
=
ARRAY_SIZE
(
tegra186_usb2_lanes
),
.
lanes
=
tegra186_usb2_lanes
,
.
ops
=
&
tegra186_usb2_pad_ops
,
};
static
int
tegra186_usb2_port_enable
(
struct
tegra_xusb_port
*
port
)
{
return
0
;
...
...
@@ -532,6 +615,8 @@ tegra186_usb2_port_map(struct tegra_xusb_port *port)
}
static
const
struct
tegra_xusb_port_ops
tegra186_usb2_port_ops
=
{
.
release
=
tegra_xusb_usb2_port_release
,
.
remove
=
tegra_xusb_usb2_port_remove
,
.
enable
=
tegra186_usb2_port_enable
,
.
disable
=
tegra186_usb2_port_disable
,
.
map
=
tegra186_usb2_port_map
,
...
...
@@ -591,6 +676,8 @@ tegra186_usb3_port_map(struct tegra_xusb_port *port)
}
static
const
struct
tegra_xusb_port_ops
tegra186_usb3_port_ops
=
{
.
release
=
tegra_xusb_usb3_port_release
,
.
remove
=
tegra_xusb_usb3_port_remove
,
.
enable
=
tegra186_usb3_port_enable
,
.
disable
=
tegra186_usb3_port_disable
,
.
map
=
tegra186_usb3_port_map
,
...
...
@@ -635,6 +722,15 @@ static int tegra186_usb3_phy_power_on(struct phy *phy)
padctl_writel
(
padctl
,
value
,
XUSB_PADCTL_SS_PORT_CAP
);
if
(
padctl
->
soc
->
supports_gen2
&&
port
->
disable_gen2
)
{
value
=
padctl_readl
(
padctl
,
XUSB_PADCTL_SS_PORT_CFG
);
value
&=
~
(
PORTX_SPEED_SUPPORT_MASK
<<
PORTX_SPEED_SUPPORT_SHIFT
(
index
));
value
|=
(
PORT_SPEED_SUPPORT_GEN1
<<
PORTX_SPEED_SUPPORT_SHIFT
(
index
));
padctl_writel
(
padctl
,
value
,
XUSB_PADCTL_SS_PORT_CFG
);
}
value
=
padctl_readl
(
padctl
,
XUSB_PADCTL_ELPG_PROGRAM_1
);
value
&=
~
SSPX_ELPG_VCORE_DOWN
(
index
);
padctl_writel
(
padctl
,
value
,
XUSB_PADCTL_ELPG_PROGRAM_1
);
...
...
@@ -765,27 +861,6 @@ static const char * const tegra186_usb3_functions[] = {
"xusb"
,
};
static
const
struct
tegra_xusb_lane_soc
tegra186_usb3_lanes
[]
=
{
TEGRA186_LANE
(
"usb3-0"
,
0
,
0
,
0
,
usb3
),
TEGRA186_LANE
(
"usb3-1"
,
0
,
0
,
0
,
usb3
),
TEGRA186_LANE
(
"usb3-2"
,
0
,
0
,
0
,
usb3
),
};
static
const
struct
tegra_xusb_pad_soc
tegra186_usb3_pad
=
{
.
name
=
"usb3"
,
.
num_lanes
=
ARRAY_SIZE
(
tegra186_usb3_lanes
),
.
lanes
=
tegra186_usb3_lanes
,
.
ops
=
&
tegra186_usb3_pad_ops
,
};
static
const
struct
tegra_xusb_pad_soc
*
const
tegra186_pads
[]
=
{
&
tegra186_usb2_pad
,
&
tegra186_usb3_pad
,
#if 0 /* TODO implement */
&tegra186_hsic_pad,
#endif
};
static
int
tegra186_xusb_read_fuse_calibration
(
struct
tegra186_xusb_padctl
*
padctl
)
{
...
...
@@ -802,7 +877,9 @@ tegra186_xusb_read_fuse_calibration(struct tegra186_xusb_padctl *padctl)
err
=
tegra_fuse_readl
(
TEGRA_FUSE_SKU_CALIB_0
,
&
value
);
if
(
err
)
{
dev_err
(
dev
,
"failed to read calibration fuse: %d
\n
"
,
err
);
if
(
err
!=
-
EPROBE_DEFER
)
dev_err
(
dev
,
"failed to read calibration fuse: %d
\n
"
,
err
);
return
err
;
}
...
...
@@ -857,34 +934,13 @@ static void tegra186_xusb_padctl_remove(struct tegra_xusb_padctl *padctl)
{
}
static
int
tegra186_xusb_padctl_vbus_override
(
struct
tegra_xusb_padctl
*
padctl
,
bool
status
)
{
u32
value
;
dev_dbg
(
padctl
->
dev
,
"%s vbus override
\n
"
,
status
?
"set"
:
"clear"
);
value
=
padctl_readl
(
padctl
,
USB2_VBUS_ID
);
if
(
status
)
{
value
|=
VBUS_OVERRIDE
;
value
&=
~
ID_OVERRIDE
(
~
0
);
value
|=
ID_OVERRIDE_FLOATING
;
}
else
{
value
&=
~
VBUS_OVERRIDE
;
}
padctl_writel
(
padctl
,
value
,
USB2_VBUS_ID
);
return
0
;
}
static
const
struct
tegra_xusb_padctl_ops
tegra186_xusb_padctl_ops
=
{
.
probe
=
tegra186_xusb_padctl_probe
,
.
remove
=
tegra186_xusb_padctl_remove
,
.
vbus_override
=
tegra186_xusb_padctl_vbus_override
,
};
#if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC)
static
const
char
*
const
tegra186_xusb_padctl_supply_names
[]
=
{
"avdd-pll-erefeut"
,
"avdd-usb"
,
...
...
@@ -892,6 +948,40 @@ static const char * const tegra186_xusb_padctl_supply_names[] = {
"vddio-hsic"
,
};
static
const
struct
tegra_xusb_lane_soc
tegra186_usb2_lanes
[]
=
{
TEGRA186_LANE
(
"usb2-0"
,
0
,
0
,
0
,
usb2
),
TEGRA186_LANE
(
"usb2-1"
,
0
,
0
,
0
,
usb2
),
TEGRA186_LANE
(
"usb2-2"
,
0
,
0
,
0
,
usb2
),
};
static
const
struct
tegra_xusb_pad_soc
tegra186_usb2_pad
=
{
.
name
=
"usb2"
,
.
num_lanes
=
ARRAY_SIZE
(
tegra186_usb2_lanes
),
.
lanes
=
tegra186_usb2_lanes
,
.
ops
=
&
tegra186_usb2_pad_ops
,
};
static
const
struct
tegra_xusb_lane_soc
tegra186_usb3_lanes
[]
=
{
TEGRA186_LANE
(
"usb3-0"
,
0
,
0
,
0
,
usb3
),
TEGRA186_LANE
(
"usb3-1"
,
0
,
0
,
0
,
usb3
),
TEGRA186_LANE
(
"usb3-2"
,
0
,
0
,
0
,
usb3
),
};
static
const
struct
tegra_xusb_pad_soc
tegra186_usb3_pad
=
{
.
name
=
"usb3"
,
.
num_lanes
=
ARRAY_SIZE
(
tegra186_usb3_lanes
),
.
lanes
=
tegra186_usb3_lanes
,
.
ops
=
&
tegra186_usb3_pad_ops
,
};
static
const
struct
tegra_xusb_pad_soc
*
const
tegra186_pads
[]
=
{
&
tegra186_usb2_pad
,
&
tegra186_usb3_pad
,
#if 0 /* TODO implement */
&tegra186_hsic_pad,
#endif
};
const
struct
tegra_xusb_padctl_soc
tegra186_xusb_padctl_soc
=
{
.
num_pads
=
ARRAY_SIZE
(
tegra186_pads
),
.
pads
=
tegra186_pads
,
...
...
@@ -916,6 +1006,67 @@ const struct tegra_xusb_padctl_soc tegra186_xusb_padctl_soc = {
.
num_supplies
=
ARRAY_SIZE
(
tegra186_xusb_padctl_supply_names
),
};
EXPORT_SYMBOL_GPL
(
tegra186_xusb_padctl_soc
);
#endif
#if IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC)
static
const
char
*
const
tegra194_xusb_padctl_supply_names
[]
=
{
"avdd-usb"
,
"vclamp-usb"
,
};
static
const
struct
tegra_xusb_lane_soc
tegra194_usb2_lanes
[]
=
{
TEGRA186_LANE
(
"usb2-0"
,
0
,
0
,
0
,
usb2
),
TEGRA186_LANE
(
"usb2-1"
,
0
,
0
,
0
,
usb2
),
TEGRA186_LANE
(
"usb2-2"
,
0
,
0
,
0
,
usb2
),
TEGRA186_LANE
(
"usb2-3"
,
0
,
0
,
0
,
usb2
),
};
static
const
struct
tegra_xusb_pad_soc
tegra194_usb2_pad
=
{
.
name
=
"usb2"
,
.
num_lanes
=
ARRAY_SIZE
(
tegra194_usb2_lanes
),
.
lanes
=
tegra194_usb2_lanes
,
.
ops
=
&
tegra186_usb2_pad_ops
,
};
static
const
struct
tegra_xusb_lane_soc
tegra194_usb3_lanes
[]
=
{
TEGRA186_LANE
(
"usb3-0"
,
0
,
0
,
0
,
usb3
),
TEGRA186_LANE
(
"usb3-1"
,
0
,
0
,
0
,
usb3
),
TEGRA186_LANE
(
"usb3-2"
,
0
,
0
,
0
,
usb3
),
TEGRA186_LANE
(
"usb3-3"
,
0
,
0
,
0
,
usb3
),
};
static
const
struct
tegra_xusb_pad_soc
tegra194_usb3_pad
=
{
.
name
=
"usb3"
,
.
num_lanes
=
ARRAY_SIZE
(
tegra194_usb3_lanes
),
.
lanes
=
tegra194_usb3_lanes
,
.
ops
=
&
tegra186_usb3_pad_ops
,
};
static
const
struct
tegra_xusb_pad_soc
*
const
tegra194_pads
[]
=
{
&
tegra194_usb2_pad
,
&
tegra194_usb3_pad
,
};
const
struct
tegra_xusb_padctl_soc
tegra194_xusb_padctl_soc
=
{
.
num_pads
=
ARRAY_SIZE
(
tegra194_pads
),
.
pads
=
tegra194_pads
,
.
ports
=
{
.
usb2
=
{
.
ops
=
&
tegra186_usb2_port_ops
,
.
count
=
4
,
},
.
usb3
=
{
.
ops
=
&
tegra186_usb3_port_ops
,
.
count
=
4
,
},
},
.
ops
=
&
tegra186_xusb_padctl_ops
,
.
supply_names
=
tegra194_xusb_padctl_supply_names
,
.
num_supplies
=
ARRAY_SIZE
(
tegra194_xusb_padctl_supply_names
),
.
supports_gen2
=
true
,
};
EXPORT_SYMBOL_GPL
(
tegra194_xusb_padctl_soc
);
#endif
MODULE_AUTHOR
(
"JC Kuo <jckuo@nvidia.com>"
);
MODULE_DESCRIPTION
(
"NVIDIA Tegra186 XUSB Pad Controller driver"
);
...
...
drivers/phy/tegra/xusb-tegra210.c
View file @
80525cc2
...
...
@@ -236,6 +236,7 @@
#define XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT 18
#define XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_MASK 0xf
#define XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_FLOATING 8
#define XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_GROUNDED 0
struct
tegra210_xusb_fuse_calibration
{
u32
hs_curr_level
[
4
];
...
...
@@ -935,6 +936,103 @@ static int tegra210_usb2_phy_exit(struct phy *phy)
return
tegra210_xusb_padctl_disable
(
lane
->
pad
->
padctl
);
}
static
int
tegra210_xusb_padctl_vbus_override
(
struct
tegra_xusb_padctl
*
padctl
,
bool
status
)
{
u32
value
;
dev_dbg
(
padctl
->
dev
,
"%s vbus override
\n
"
,
status
?
"set"
:
"clear"
);
value
=
padctl_readl
(
padctl
,
XUSB_PADCTL_USB2_VBUS_ID
);
if
(
status
)
{
value
|=
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON
;
value
&=
~
(
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_MASK
<<
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT
);
value
|=
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_FLOATING
<<
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT
;
}
else
{
value
&=
~
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON
;
}
padctl_writel
(
padctl
,
value
,
XUSB_PADCTL_USB2_VBUS_ID
);
return
0
;
}
static
int
tegra210_xusb_padctl_id_override
(
struct
tegra_xusb_padctl
*
padctl
,
bool
status
)
{
u32
value
;
dev_dbg
(
padctl
->
dev
,
"%s id override
\n
"
,
status
?
"set"
:
"clear"
);
value
=
padctl_readl
(
padctl
,
XUSB_PADCTL_USB2_VBUS_ID
);
if
(
status
)
{
if
(
value
&
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON
)
{
value
&=
~
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON
;
padctl_writel
(
padctl
,
value
,
XUSB_PADCTL_USB2_VBUS_ID
);
usleep_range
(
1000
,
2000
);
value
=
padctl_readl
(
padctl
,
XUSB_PADCTL_USB2_VBUS_ID
);
}
value
&=
~
(
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_MASK
<<
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT
);
value
|=
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_GROUNDED
<<
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT
;
}
else
{
value
&=
~
(
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_MASK
<<
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT
);
value
|=
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_FLOATING
<<
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT
;
}
padctl_writel
(
padctl
,
value
,
XUSB_PADCTL_USB2_VBUS_ID
);
return
0
;
}
static
int
tegra210_usb2_phy_set_mode
(
struct
phy
*
phy
,
enum
phy_mode
mode
,
int
submode
)
{
struct
tegra_xusb_lane
*
lane
=
phy_get_drvdata
(
phy
);
struct
tegra_xusb_padctl
*
padctl
=
lane
->
pad
->
padctl
;
struct
tegra_xusb_usb2_port
*
port
=
tegra_xusb_find_usb2_port
(
padctl
,
lane
->
index
);
int
err
=
0
;
mutex_lock
(
&
padctl
->
lock
);
dev_dbg
(
&
port
->
base
.
dev
,
"%s: mode %d"
,
__func__
,
mode
);
if
(
mode
==
PHY_MODE_USB_OTG
)
{
if
(
submode
==
USB_ROLE_HOST
)
{
tegra210_xusb_padctl_id_override
(
padctl
,
true
);
err
=
regulator_enable
(
port
->
supply
);
}
else
if
(
submode
==
USB_ROLE_DEVICE
)
{
tegra210_xusb_padctl_vbus_override
(
padctl
,
true
);
}
else
if
(
submode
==
USB_ROLE_NONE
)
{
/*
* When port is peripheral only or role transitions to
* USB_ROLE_NONE from USB_ROLE_DEVICE, regulator is not
* be enabled.
*/
if
(
regulator_is_enabled
(
port
->
supply
))
regulator_disable
(
port
->
supply
);
tegra210_xusb_padctl_id_override
(
padctl
,
false
);
tegra210_xusb_padctl_vbus_override
(
padctl
,
false
);
}
}
mutex_unlock
(
&
padctl
->
lock
);
return
err
;
}
static
int
tegra210_usb2_phy_power_on
(
struct
phy
*
phy
)
{
struct
tegra_xusb_lane
*
lane
=
phy_get_drvdata
(
phy
);
...
...
@@ -1048,9 +1146,11 @@ static int tegra210_usb2_phy_power_on(struct phy *phy)
padctl_writel
(
padctl
,
value
,
XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADX_CTL1
(
index
));
err
=
regulator_enable
(
port
->
supply
);
if
(
err
)
return
err
;
if
(
port
->
supply
&&
port
->
mode
==
USB_DR_MODE_HOST
)
{
err
=
regulator_enable
(
port
->
supply
);
if
(
err
)
return
err
;
}
mutex_lock
(
&
padctl
->
lock
);
...
...
@@ -1164,6 +1264,7 @@ static const struct phy_ops tegra210_usb2_phy_ops = {
.
exit
=
tegra210_usb2_phy_exit
,
.
power_on
=
tegra210_usb2_phy_power_on
,
.
power_off
=
tegra210_usb2_phy_power_off
,
.
set_mode
=
tegra210_usb2_phy_set_mode
,
.
owner
=
THIS_MODULE
,
};
...
...
@@ -1852,6 +1953,8 @@ tegra210_usb2_port_map(struct tegra_xusb_port *port)
}
static
const
struct
tegra_xusb_port_ops
tegra210_usb2_port_ops
=
{
.
release
=
tegra_xusb_usb2_port_release
,
.
remove
=
tegra_xusb_usb2_port_remove
,
.
enable
=
tegra210_usb2_port_enable
,
.
disable
=
tegra210_usb2_port_disable
,
.
map
=
tegra210_usb2_port_map
,
...
...
@@ -1873,6 +1976,7 @@ tegra210_hsic_port_map(struct tegra_xusb_port *port)
}
static
const
struct
tegra_xusb_port_ops
tegra210_hsic_port_ops
=
{
.
release
=
tegra_xusb_hsic_port_release
,
.
enable
=
tegra210_hsic_port_enable
,
.
disable
=
tegra210_hsic_port_disable
,
.
map
=
tegra210_hsic_port_map
,
...
...
@@ -2018,35 +2122,13 @@ tegra210_usb3_port_map(struct tegra_xusb_port *port)
}
static
const
struct
tegra_xusb_port_ops
tegra210_usb3_port_ops
=
{
.
release
=
tegra_xusb_usb3_port_release
,
.
remove
=
tegra_xusb_usb3_port_remove
,
.
enable
=
tegra210_usb3_port_enable
,
.
disable
=
tegra210_usb3_port_disable
,
.
map
=
tegra210_usb3_port_map
,
};
static
int
tegra210_xusb_padctl_vbus_override
(
struct
tegra_xusb_padctl
*
padctl
,
bool
status
)
{
u32
value
;
dev_dbg
(
padctl
->
dev
,
"%s vbus override
\n
"
,
status
?
"set"
:
"clear"
);
value
=
padctl_readl
(
padctl
,
XUSB_PADCTL_USB2_VBUS_ID
);
if
(
status
)
{
value
|=
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON
;
value
&=
~
(
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_MASK
<<
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT
);
value
|=
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_FLOATING
<<
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT
;
}
else
{
value
&=
~
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON
;
}
padctl_writel
(
padctl
,
value
,
XUSB_PADCTL_USB2_VBUS_ID
);
return
0
;
}
static
int
tegra210_utmi_port_reset
(
struct
phy
*
phy
)
{
struct
tegra_xusb_padctl
*
padctl
;
...
...
drivers/phy/tegra/xusb.c
View file @
80525cc2
...
...
@@ -65,6 +65,12 @@ static const struct of_device_id tegra_xusb_padctl_of_match[] = {
.
compatible
=
"nvidia,tegra186-xusb-padctl"
,
.
data
=
&
tegra186_xusb_padctl_soc
,
},
#endif
#if defined(CONFIG_ARCH_TEGRA_194_SOC)
{
.
compatible
=
"nvidia,tegra194-xusb-padctl"
,
.
data
=
&
tegra194_xusb_padctl_soc
,
},
#endif
{
}
};
...
...
@@ -501,6 +507,10 @@ tegra_xusb_find_usb3_port(struct tegra_xusb_padctl *padctl, unsigned int index)
static
void
tegra_xusb_port_release
(
struct
device
*
dev
)
{
struct
tegra_xusb_port
*
port
=
to_tegra_xusb_port
(
dev
);
if
(
port
->
ops
->
release
)
port
->
ops
->
release
(
port
);
}
static
struct
device_type
tegra_xusb_port_type
=
{
...
...
@@ -541,6 +551,16 @@ static int tegra_xusb_port_init(struct tegra_xusb_port *port,
static
void
tegra_xusb_port_unregister
(
struct
tegra_xusb_port
*
port
)
{
if
(
!
IS_ERR_OR_NULL
(
port
->
usb_role_sw
))
{
of_platform_depopulate
(
&
port
->
dev
);
usb_role_switch_unregister
(
port
->
usb_role_sw
);
cancel_work_sync
(
&
port
->
usb_phy_work
);
usb_remove_phy
(
&
port
->
usb_phy
);
}
if
(
port
->
ops
->
remove
)
port
->
ops
->
remove
(
port
);
device_unregister
(
&
port
->
dev
);
}
...
...
@@ -551,11 +571,146 @@ static const char *const modes[] = {
[
USB_DR_MODE_OTG
]
=
"otg"
,
};
static
const
char
*
const
usb_roles
[]
=
{
[
USB_ROLE_NONE
]
=
"none"
,
[
USB_ROLE_HOST
]
=
"host"
,
[
USB_ROLE_DEVICE
]
=
"device"
,
};
static
enum
usb_phy_events
to_usb_phy_event
(
enum
usb_role
role
)
{
switch
(
role
)
{
case
USB_ROLE_DEVICE
:
return
USB_EVENT_VBUS
;
case
USB_ROLE_HOST
:
return
USB_EVENT_ID
;
default:
return
USB_EVENT_NONE
;
}
}
static
void
tegra_xusb_usb_phy_work
(
struct
work_struct
*
work
)
{
struct
tegra_xusb_port
*
port
=
container_of
(
work
,
struct
tegra_xusb_port
,
usb_phy_work
);
enum
usb_role
role
=
usb_role_switch_get_role
(
port
->
usb_role_sw
);
usb_phy_set_event
(
&
port
->
usb_phy
,
to_usb_phy_event
(
role
));
dev_dbg
(
&
port
->
dev
,
"%s(): calling notifier for role %s
\n
"
,
__func__
,
usb_roles
[
role
]);
atomic_notifier_call_chain
(
&
port
->
usb_phy
.
notifier
,
0
,
&
port
->
usb_phy
);
}
static
int
tegra_xusb_role_sw_set
(
struct
usb_role_switch
*
sw
,
enum
usb_role
role
)
{
struct
tegra_xusb_port
*
port
=
usb_role_switch_get_drvdata
(
sw
);
dev_dbg
(
&
port
->
dev
,
"%s(): role %s
\n
"
,
__func__
,
usb_roles
[
role
]);
schedule_work
(
&
port
->
usb_phy_work
);
return
0
;
}
static
int
tegra_xusb_set_peripheral
(
struct
usb_otg
*
otg
,
struct
usb_gadget
*
gadget
)
{
struct
tegra_xusb_port
*
port
=
container_of
(
otg
->
usb_phy
,
struct
tegra_xusb_port
,
usb_phy
);
if
(
gadget
!=
NULL
)
schedule_work
(
&
port
->
usb_phy_work
);
return
0
;
}
static
int
tegra_xusb_set_host
(
struct
usb_otg
*
otg
,
struct
usb_bus
*
host
)
{
struct
tegra_xusb_port
*
port
=
container_of
(
otg
->
usb_phy
,
struct
tegra_xusb_port
,
usb_phy
);
if
(
host
!=
NULL
)
schedule_work
(
&
port
->
usb_phy_work
);
return
0
;
}
static
int
tegra_xusb_setup_usb_role_switch
(
struct
tegra_xusb_port
*
port
)
{
struct
tegra_xusb_lane
*
lane
;
struct
usb_role_switch_desc
role_sx_desc
=
{
.
fwnode
=
dev_fwnode
(
&
port
->
dev
),
.
set
=
tegra_xusb_role_sw_set
,
};
int
err
=
0
;
/*
* USB role switch driver needs parent driver owner info. This is a
* suboptimal solution. TODO: Need to revisit this in a follow-up patch
* where an optimal solution is possible with changes to USB role
* switch driver.
*/
port
->
dev
.
driver
=
devm_kzalloc
(
&
port
->
dev
,
sizeof
(
struct
device_driver
),
GFP_KERNEL
);
port
->
dev
.
driver
->
owner
=
THIS_MODULE
;
port
->
usb_role_sw
=
usb_role_switch_register
(
&
port
->
dev
,
&
role_sx_desc
);
if
(
IS_ERR
(
port
->
usb_role_sw
))
{
err
=
PTR_ERR
(
port
->
usb_role_sw
);
dev_err
(
&
port
->
dev
,
"failed to register USB role switch: %d"
,
err
);
return
err
;
}
INIT_WORK
(
&
port
->
usb_phy_work
,
tegra_xusb_usb_phy_work
);
usb_role_switch_set_drvdata
(
port
->
usb_role_sw
,
port
);
port
->
usb_phy
.
otg
=
devm_kzalloc
(
&
port
->
dev
,
sizeof
(
struct
usb_otg
),
GFP_KERNEL
);
if
(
!
port
->
usb_phy
.
otg
)
return
-
ENOMEM
;
lane
=
tegra_xusb_find_lane
(
port
->
padctl
,
"usb2"
,
port
->
index
);
/*
* Assign phy dev to usb-phy dev. Host/device drivers can use phy
* reference to retrieve usb-phy details.
*/
port
->
usb_phy
.
dev
=
&
lane
->
pad
->
lanes
[
port
->
index
]
->
dev
;
port
->
usb_phy
.
dev
->
driver
=
port
->
padctl
->
dev
->
driver
;
port
->
usb_phy
.
otg
->
usb_phy
=
&
port
->
usb_phy
;
port
->
usb_phy
.
otg
->
set_peripheral
=
tegra_xusb_set_peripheral
;
port
->
usb_phy
.
otg
->
set_host
=
tegra_xusb_set_host
;
err
=
usb_add_phy_dev
(
&
port
->
usb_phy
);
if
(
err
<
0
)
{
dev_err
(
&
port
->
dev
,
"Failed to add USB PHY: %d
\n
"
,
err
);
return
err
;
}
/* populate connector entry */
of_platform_populate
(
port
->
dev
.
of_node
,
NULL
,
NULL
,
&
port
->
dev
);
return
err
;
}
static
int
tegra_xusb_usb2_port_parse_dt
(
struct
tegra_xusb_usb2_port
*
usb2
)
{
struct
tegra_xusb_port
*
port
=
&
usb2
->
base
;
struct
device_node
*
np
=
port
->
dev
.
of_node
;
const
char
*
mode
;
int
err
;
usb2
->
internal
=
of_property_read_bool
(
np
,
"nvidia,internal"
);
...
...
@@ -572,7 +727,21 @@ static int tegra_xusb_usb2_port_parse_dt(struct tegra_xusb_usb2_port *usb2)
usb2
->
mode
=
USB_DR_MODE_HOST
;
}
usb2
->
supply
=
devm_regulator_get
(
&
port
->
dev
,
"vbus"
);
/* usb-role-switch property is mandatory for OTG/Peripheral modes */
if
(
usb2
->
mode
==
USB_DR_MODE_PERIPHERAL
||
usb2
->
mode
==
USB_DR_MODE_OTG
)
{
if
(
of_property_read_bool
(
np
,
"usb-role-switch"
))
{
err
=
tegra_xusb_setup_usb_role_switch
(
port
);
if
(
err
<
0
)
return
err
;
}
else
{
dev_err
(
&
port
->
dev
,
"usb-role-switch not found for %s mode"
,
modes
[
usb2
->
mode
]);
return
-
EINVAL
;
}
}
usb2
->
supply
=
regulator_get
(
&
port
->
dev
,
"vbus"
);
return
PTR_ERR_OR_ZERO
(
usb2
->
supply
);
}
...
...
@@ -591,7 +760,7 @@ static int tegra_xusb_add_usb2_port(struct tegra_xusb_padctl *padctl,
if
(
!
np
||
!
of_device_is_available
(
np
))
goto
out
;
usb2
=
devm_kzalloc
(
padctl
->
dev
,
sizeof
(
*
usb2
),
GFP_KERNEL
);
usb2
=
kzalloc
(
sizeof
(
*
usb2
),
GFP_KERNEL
);
if
(
!
usb2
)
{
err
=
-
ENOMEM
;
goto
out
;
...
...
@@ -622,6 +791,20 @@ static int tegra_xusb_add_usb2_port(struct tegra_xusb_padctl *padctl,
return
err
;
}
void
tegra_xusb_usb2_port_release
(
struct
tegra_xusb_port
*
port
)
{
struct
tegra_xusb_usb2_port
*
usb2
=
to_usb2_port
(
port
);
kfree
(
usb2
);
}
void
tegra_xusb_usb2_port_remove
(
struct
tegra_xusb_port
*
port
)
{
struct
tegra_xusb_usb2_port
*
usb2
=
to_usb2_port
(
port
);
regulator_put
(
usb2
->
supply
);
}
static
int
tegra_xusb_ulpi_port_parse_dt
(
struct
tegra_xusb_ulpi_port
*
ulpi
)
{
struct
tegra_xusb_port
*
port
=
&
ulpi
->
base
;
...
...
@@ -643,7 +826,7 @@ static int tegra_xusb_add_ulpi_port(struct tegra_xusb_padctl *padctl,
if
(
!
np
||
!
of_device_is_available
(
np
))
goto
out
;
ulpi
=
devm_kzalloc
(
padctl
->
dev
,
sizeof
(
*
ulpi
),
GFP_KERNEL
);
ulpi
=
kzalloc
(
sizeof
(
*
ulpi
),
GFP_KERNEL
);
if
(
!
ulpi
)
{
err
=
-
ENOMEM
;
goto
out
;
...
...
@@ -674,6 +857,13 @@ static int tegra_xusb_add_ulpi_port(struct tegra_xusb_padctl *padctl,
return
err
;
}
void
tegra_xusb_ulpi_port_release
(
struct
tegra_xusb_port
*
port
)
{
struct
tegra_xusb_ulpi_port
*
ulpi
=
to_ulpi_port
(
port
);
kfree
(
ulpi
);
}
static
int
tegra_xusb_hsic_port_parse_dt
(
struct
tegra_xusb_hsic_port
*
hsic
)
{
/* XXX */
...
...
@@ -691,7 +881,7 @@ static int tegra_xusb_add_hsic_port(struct tegra_xusb_padctl *padctl,
if
(
!
np
||
!
of_device_is_available
(
np
))
goto
out
;
hsic
=
devm_kzalloc
(
padctl
->
dev
,
sizeof
(
*
hsic
),
GFP_KERNEL
);
hsic
=
kzalloc
(
sizeof
(
*
hsic
),
GFP_KERNEL
);
if
(
!
hsic
)
{
err
=
-
ENOMEM
;
goto
out
;
...
...
@@ -722,10 +912,18 @@ static int tegra_xusb_add_hsic_port(struct tegra_xusb_padctl *padctl,
return
err
;
}
void
tegra_xusb_hsic_port_release
(
struct
tegra_xusb_port
*
port
)
{
struct
tegra_xusb_hsic_port
*
hsic
=
to_hsic_port
(
port
);
kfree
(
hsic
);
}
static
int
tegra_xusb_usb3_port_parse_dt
(
struct
tegra_xusb_usb3_port
*
usb3
)
{
struct
tegra_xusb_port
*
port
=
&
usb3
->
base
;
struct
device_node
*
np
=
port
->
dev
.
of_node
;
enum
usb_device_speed
maximum_speed
;
u32
value
;
int
err
;
...
...
@@ -739,7 +937,17 @@ static int tegra_xusb_usb3_port_parse_dt(struct tegra_xusb_usb3_port *usb3)
usb3
->
internal
=
of_property_read_bool
(
np
,
"nvidia,internal"
);
usb3
->
supply
=
devm_regulator_get
(
&
port
->
dev
,
"vbus"
);
if
(
device_property_present
(
&
port
->
dev
,
"maximum-speed"
))
{
maximum_speed
=
usb_get_maximum_speed
(
&
port
->
dev
);
if
(
maximum_speed
==
USB_SPEED_SUPER
)
usb3
->
disable_gen2
=
true
;
else
if
(
maximum_speed
==
USB_SPEED_SUPER_PLUS
)
usb3
->
disable_gen2
=
false
;
else
return
-
EINVAL
;
}
usb3
->
supply
=
regulator_get
(
&
port
->
dev
,
"vbus"
);
return
PTR_ERR_OR_ZERO
(
usb3
->
supply
);
}
...
...
@@ -759,7 +967,7 @@ static int tegra_xusb_add_usb3_port(struct tegra_xusb_padctl *padctl,
if
(
!
np
||
!
of_device_is_available
(
np
))
goto
out
;
usb3
=
devm_kzalloc
(
padctl
->
dev
,
sizeof
(
*
usb3
),
GFP_KERNEL
);
usb3
=
kzalloc
(
sizeof
(
*
usb3
),
GFP_KERNEL
);
if
(
!
usb3
)
{
err
=
-
ENOMEM
;
goto
out
;
...
...
@@ -790,6 +998,20 @@ static int tegra_xusb_add_usb3_port(struct tegra_xusb_padctl *padctl,
return
err
;
}
void
tegra_xusb_usb3_port_release
(
struct
tegra_xusb_port
*
port
)
{
struct
tegra_xusb_usb3_port
*
usb3
=
to_usb3_port
(
port
);
kfree
(
usb3
);
}
void
tegra_xusb_usb3_port_remove
(
struct
tegra_xusb_port
*
port
)
{
struct
tegra_xusb_usb3_port
*
usb3
=
to_usb3_port
(
port
);
regulator_put
(
usb3
->
supply
);
}
static
void
__tegra_xusb_remove_ports
(
struct
tegra_xusb_padctl
*
padctl
)
{
struct
tegra_xusb_port
*
port
,
*
tmp
;
...
...
@@ -1001,7 +1223,13 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev)
err
=
tegra_xusb_setup_ports
(
padctl
);
if
(
err
)
{
dev_err
(
&
pdev
->
dev
,
"failed to setup XUSB ports: %d
\n
"
,
err
);
const
char
*
level
=
KERN_ERR
;
if
(
err
==
-
EPROBE_DEFER
)
level
=
KERN_DEBUG
;
dev_printk
(
level
,
&
pdev
->
dev
,
dev_fmt
(
"failed to setup XUSB ports: %d
\n
"
),
err
);
goto
remove_pads
;
}
...
...
@@ -1143,6 +1371,27 @@ int tegra_phy_xusb_utmi_port_reset(struct phy *phy)
}
EXPORT_SYMBOL_GPL
(
tegra_phy_xusb_utmi_port_reset
);
int
tegra_xusb_padctl_get_usb3_companion
(
struct
tegra_xusb_padctl
*
padctl
,
unsigned
int
port
)
{
struct
tegra_xusb_usb2_port
*
usb2
;
struct
tegra_xusb_usb3_port
*
usb3
;
int
i
;
usb2
=
tegra_xusb_find_usb2_port
(
padctl
,
port
);
if
(
!
usb2
)
return
-
EINVAL
;
for
(
i
=
0
;
i
<
padctl
->
soc
->
ports
.
usb3
.
count
;
i
++
)
{
usb3
=
tegra_xusb_find_usb3_port
(
padctl
,
i
);
if
(
usb3
&&
usb3
->
port
==
usb2
->
base
.
index
)
return
usb3
->
base
.
index
;
}
return
-
ENODEV
;
}
EXPORT_SYMBOL_GPL
(
tegra_xusb_padctl_get_usb3_companion
);
MODULE_AUTHOR
(
"Thierry Reding <treding@nvidia.com>"
);
MODULE_DESCRIPTION
(
"Tegra XUSB Pad Controller driver"
);
MODULE_LICENSE
(
"GPL v2"
);
drivers/phy/tegra/xusb.h
View file @
80525cc2
...
...
@@ -12,6 +12,7 @@
#include <linux/workqueue.h>
#include <linux/usb/otg.h>
#include <linux/usb/role.h>
/* legacy entry points for backwards-compatibility */
int
tegra_xusb_padctl_legacy_probe
(
struct
platform_device
*
pdev
);
...
...
@@ -266,9 +267,18 @@ struct tegra_xusb_port {
struct
list_head
list
;
struct
device
dev
;
struct
usb_role_switch
*
usb_role_sw
;
struct
work_struct
usb_phy_work
;
struct
usb_phy
usb_phy
;
const
struct
tegra_xusb_port_ops
*
ops
;
};
static
inline
struct
tegra_xusb_port
*
to_tegra_xusb_port
(
struct
device
*
dev
)
{
return
container_of
(
dev
,
struct
tegra_xusb_port
,
dev
);
}
struct
tegra_xusb_lane_map
{
unsigned
int
port
;
const
char
*
type
;
...
...
@@ -303,6 +313,8 @@ to_usb2_port(struct tegra_xusb_port *port)
struct
tegra_xusb_usb2_port
*
tegra_xusb_find_usb2_port
(
struct
tegra_xusb_padctl
*
padctl
,
unsigned
int
index
);
void
tegra_xusb_usb2_port_release
(
struct
tegra_xusb_port
*
port
);
void
tegra_xusb_usb2_port_remove
(
struct
tegra_xusb_port
*
port
);
struct
tegra_xusb_ulpi_port
{
struct
tegra_xusb_port
base
;
...
...
@@ -317,6 +329,8 @@ to_ulpi_port(struct tegra_xusb_port *port)
return
container_of
(
port
,
struct
tegra_xusb_ulpi_port
,
base
);
}
void
tegra_xusb_ulpi_port_release
(
struct
tegra_xusb_port
*
port
);
struct
tegra_xusb_hsic_port
{
struct
tegra_xusb_port
base
;
};
...
...
@@ -327,12 +341,15 @@ to_hsic_port(struct tegra_xusb_port *port)
return
container_of
(
port
,
struct
tegra_xusb_hsic_port
,
base
);
}
void
tegra_xusb_hsic_port_release
(
struct
tegra_xusb_port
*
port
);
struct
tegra_xusb_usb3_port
{
struct
tegra_xusb_port
base
;
struct
regulator
*
supply
;
bool
context_saved
;
unsigned
int
port
;
bool
internal
;
bool
disable_gen2
;
u32
tap1
;
u32
amp
;
...
...
@@ -349,8 +366,12 @@ to_usb3_port(struct tegra_xusb_port *port)
struct
tegra_xusb_usb3_port
*
tegra_xusb_find_usb3_port
(
struct
tegra_xusb_padctl
*
padctl
,
unsigned
int
index
);
void
tegra_xusb_usb3_port_release
(
struct
tegra_xusb_port
*
port
);
void
tegra_xusb_usb3_port_remove
(
struct
tegra_xusb_port
*
port
);
struct
tegra_xusb_port_ops
{
void
(
*
release
)(
struct
tegra_xusb_port
*
port
);
void
(
*
remove
)(
struct
tegra_xusb_port
*
port
);
int
(
*
enable
)(
struct
tegra_xusb_port
*
port
);
void
(
*
disable
)(
struct
tegra_xusb_port
*
port
);
struct
tegra_xusb_lane
*
(
*
map
)(
struct
tegra_xusb_port
*
port
);
...
...
@@ -392,6 +413,7 @@ struct tegra_xusb_padctl_soc {
const
char
*
const
*
supply_names
;
unsigned
int
num_supplies
;
bool
supports_gen2
;
bool
need_fake_usb3_port
;
};
...
...
@@ -448,5 +470,8 @@ extern const struct tegra_xusb_padctl_soc tegra210_xusb_padctl_soc;
#if defined(CONFIG_ARCH_TEGRA_186_SOC)
extern
const
struct
tegra_xusb_padctl_soc
tegra186_xusb_padctl_soc
;
#endif
#if defined(CONFIG_ARCH_TEGRA_194_SOC)
extern
const
struct
tegra_xusb_padctl_soc
tegra194_xusb_padctl_soc
;
#endif
#endif
/* __PHY_TEGRA_XUSB_H */
include/linux/phy/tegra/xusb.h
View file @
80525cc2
...
...
@@ -21,4 +21,6 @@ int tegra_xusb_padctl_usb3_set_lfps_detect(struct tegra_xusb_padctl *padctl,
int
tegra_xusb_padctl_set_vbus_override
(
struct
tegra_xusb_padctl
*
padctl
,
bool
val
);
int
tegra_phy_xusb_utmi_port_reset
(
struct
phy
*
phy
);
int
tegra_xusb_padctl_get_usb3_companion
(
struct
tegra_xusb_padctl
*
padctl
,
unsigned
int
port
);
#endif
/* PHY_TEGRA_XUSB_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment