diff options
author | Thinh Nguyen <Thinh.Nguyen@synopsys.com> | 2020-04-11 19:20:01 -0700 |
---|---|---|
committer | Felipe Balbi <balbi@kernel.org> | 2020-05-25 11:09:40 +0300 |
commit | 9af21dd6faeba593fb47f5cceaf69b1e5a3ff95f (patch) | |
tree | ed12d18ee5161ecea71fc70e9c42ad6295e8158c /drivers/usb/dwc3/core.h | |
parent | 88607a821ffc04034dea91747f79f2d83fe5c232 (diff) | |
download | kernel_replicant_linux-9af21dd6faeba593fb47f5cceaf69b1e5a3ff95f.tar.gz kernel_replicant_linux-9af21dd6faeba593fb47f5cceaf69b1e5a3ff95f.tar.bz2 kernel_replicant_linux-9af21dd6faeba593fb47f5cceaf69b1e5a3ff95f.zip |
usb: dwc3: Add support for DWC_usb32 IP
Synopsys introduces a new controller DWC_usb32. It supports dual-lane
and speed up to 20 Gbps, and the DWC3 driver will drive this controller.
Currently the driver uses a single field dwc->revision to ID both
DWC_usb3 and DWC_usb31 and their version number. This was sufficient for
two IPs, but this method doesn't work with additional IPs. As a result,
let's separate the dwc->revision field to 2 separate fields: ip and
revision. The ip field now stores the ID of the controller's IP while
the revision field stores the controller's version number.
This new scheme enforces DWC3 to compare the revision within the same IP
only. As a result, we must update all the revision check of the
controller to check its corresponding IP.
To help with this enforcement, we create a few macros to help with
the common version checks:
DWC3_IP_IS(IP)
DWC3_VER_IS(IP, VERSION)
DWC3_VER_IS_PRIOR(IP, VERSION)
DWC3_VER_IS_WITHIN(IP, LOWER_VERSION, UPPER_VERSION)
DWC3_VER_TYPE_IS_WITHIN(IP, VERSION,
LOWER_VERSION_TYPE,
UPPER_VERSION_TYPE)
The DWC_usb32 controller operates using the same programming model and
with very similar configurations as its previous controllers. Please
note that the various IP and revision checks in this patch match the
current checks for DWC_usb31 version 1.90a. Additional configurations
that are unique to DWC_usb32 are applied separately.
Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Diffstat (limited to 'drivers/usb/dwc3/core.h')
-rw-r--r-- | drivers/usb/dwc3/core.h | 66 |
1 files changed, 37 insertions, 29 deletions
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index e054a79024c7..b2903492437a 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -69,6 +69,7 @@ #define DWC3_GEVNTCOUNT_EHB BIT(31) #define DWC3_GSNPSID_MASK 0xffff0000 #define DWC3_GSNPSREV_MASK 0xffff +#define DWC3_GSNPS_ID(p) (((p) & DWC3_GSNPSID_MASK) >> 16) /* DWC3 registers memory space boundries */ #define DWC3_XHCI_REGS_START 0x0 @@ -949,7 +950,8 @@ struct dwc3_scratchpad_array { * @nr_scratch: number of scratch buffers * @u1u2: only used on revisions <1.83a for workaround * @maximum_speed: maximum speed requested (mainly for testing purposes) - * @revision: revision register contents + * @ip: controller's ID + * @revision: controller's version of an IP * @version_type: VERSIONTYPE register contents, a sub release of a revision * @dr_mode: requested mode of operation * @current_dr_role: current role of operation when in dual-role mode @@ -1110,15 +1112,15 @@ struct dwc3 { u32 u1u2; u32 maximum_speed; - /* - * All 3.1 IP version constants are greater than the 3.0 IP - * version constants. This works for most version checks in - * dwc3. However, in the future, this may not apply as - * features may be developed on newer versions of the 3.0 IP - * that are not in the 3.1 IP. - */ + u32 ip; + +#define DWC3_IP 0x5533 +#define DWC31_IP 0x3331 +#define DWC32_IP 0x3332 + u32 revision; +#define DWC3_REVISION_ANY 0x0 #define DWC3_REVISION_173A 0x5533173a #define DWC3_REVISION_175A 0x5533175a #define DWC3_REVISION_180A 0x5533180a @@ -1143,20 +1145,17 @@ struct dwc3 { #define DWC3_REVISION_310A 0x5533310a #define DWC3_REVISION_330A 0x5533330a -/* - * NOTICE: we're using bit 31 as a "is usb 3.1" flag. This is really - * just so dwc31 revisions are always larger than dwc3. - */ -#define DWC3_REVISION_IS_DWC31 0x80000000 -#define DWC3_USB31_REVISION_110A (0x3131302a | DWC3_REVISION_IS_DWC31) -#define DWC3_USB31_REVISION_120A (0x3132302a | DWC3_REVISION_IS_DWC31) -#define DWC3_USB31_REVISION_160A (0x3136302a | DWC3_REVISION_IS_DWC31) -#define DWC3_USB31_REVISION_170A (0x3137302a | DWC3_REVISION_IS_DWC31) -#define DWC3_USB31_REVISION_180A (0x3138302a | DWC3_REVISION_IS_DWC31) -#define DWC3_USB31_REVISION_190A (0x3139302a | DWC3_REVISION_IS_DWC31) +#define DWC31_REVISION_ANY 0x0 +#define DWC31_REVISION_110A 0x3131302a +#define DWC31_REVISION_120A 0x3132302a +#define DWC31_REVISION_160A 0x3136302a +#define DWC31_REVISION_170A 0x3137302a +#define DWC31_REVISION_180A 0x3138302a +#define DWC31_REVISION_190A 0x3139302a u32 version_type; +#define DWC31_VERSIONTYPE_ANY 0x0 #define DWC31_VERSIONTYPE_EA01 0x65613031 #define DWC31_VERSIONTYPE_EA02 0x65613032 #define DWC31_VERSIONTYPE_EA03 0x65613033 @@ -1400,17 +1399,26 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode); void dwc3_set_mode(struct dwc3 *dwc, u32 mode); u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type); -/* check whether we are on the DWC_usb3 core */ -static inline bool dwc3_is_usb3(struct dwc3 *dwc) -{ - return !(dwc->revision & DWC3_REVISION_IS_DWC31); -} +#define DWC3_IP_IS(_ip) \ + (dwc->ip == _ip##_IP) -/* check whether we are on the DWC_usb31 core */ -static inline bool dwc3_is_usb31(struct dwc3 *dwc) -{ - return !!(dwc->revision & DWC3_REVISION_IS_DWC31); -} +#define DWC3_VER_IS(_ip, _ver) \ + (DWC3_IP_IS(_ip) && dwc->revision == _ip##_REVISION_##_ver) + +#define DWC3_VER_IS_PRIOR(_ip, _ver) \ + (DWC3_IP_IS(_ip) && dwc->revision < _ip##_REVISION_##_ver) + +#define DWC3_VER_IS_WITHIN(_ip, _from, _to) \ + (DWC3_IP_IS(_ip) && \ + dwc->revision >= _ip##_REVISION_##_from && \ + (!(_ip##_REVISION_##_to) || \ + dwc->revision <= _ip##_REVISION_##_to)) + +#define DWC3_VER_TYPE_IS_WITHIN(_ip, _ver, _from, _to) \ + (DWC3_VER_IS(_ip, _ver) && \ + dwc->version_type >= _ip##_VERSIONTYPE_##_from && \ + (!(_ip##_VERSIONTYPE_##_to) || \ + dwc->version_type <= _ip##_VERSIONTYPE_##_to)) bool dwc3_has_imod(struct dwc3 *dwc); |