usb: chipidea: add ttctrl.ttha control interface
authorPeter Chen <peter.chen@freescale.com>
Thu, 18 Jun 2015 03:51:53 +0000 (11:51 +0800)
committerPeter Chen <peter.chen@freescale.com>
Fri, 14 Aug 2015 01:13:10 +0000 (09:13 +0800)
The register of ttctrl.ttha describes like below:
- Internal TT Hub Address Representation
- RW
- Default = 0000000b
This field is used to match against the Hub Address field in QH & siTD
to determine if the packet is routed to the internal TT for directly
attached FS/LS devices. If the Hub Address in the QH or siTD does not
match this address then the packet will be broadcast on the High Speed
ports destined for a downstream High Speed hub with the address in the QH/siTD.

In silicon RTL, this entry only affects QH and siTD, and the hub.addr at
both QH and siTD are 0 in ehci core for chipidea (with hcd->has_tt = 1).

So, for QH, if the "usage_tt" flag at RTL is 0, set CI_HDRC_SET_NON_ZERO_TTHA
will not affect QH (with non-hs device); for siTD, set this flag
will change remaining space requirement for the last transaction from 1023
bytes to 188 bytes, it can increase the number of transactions within one
frame, ehci periodic schedule code will not queue the packet if the frame space
is full, so it is safe to set this flag for siTD.

With this flag, it can fix the problem Alan Stern reported below:
http://www.spinics.net/lists/linux-usb/msg123125.html
And may fix Michael Tessier's problem too.
http://www.spinics.net/lists/linux-usb/msg118679.html

CC: stern@rowland.harvard.edu
CC: michael.tessier@axiontech.ca
Signed-off-by: Peter Chen <peter.chen@freescale.com>
drivers/usb/chipidea/bits.h
drivers/usb/chipidea/ci.h
drivers/usb/chipidea/core.c
drivers/usb/chipidea/host.c
include/linux/usb/chipidea.h

index 3cb9bda51ddfde76f991581736af7fb6e111a4e3..831a8f645ea5bf4f665aa95f5fad3ce1e987b200 100644 (file)
 #define DEVICEADDR_USBADRA    BIT(24)
 #define DEVICEADDR_USBADR     (0x7FUL << 25)
 
+/* TTCTRL */
+#define TTCTRL_TTHA_MASK       (0x7fUL << 24)
+/* Set non-zero value for internal TT Hub address representation */
+#define TTCTRL_TTHA            (0x7fUL << 24)
+
 /* PORTSC */
 #define PORTSC_CCS            BIT(0)
 #define PORTSC_CSC            BIT(1)
index 6d6200e37b71e02b0e0d4a67cdd35f160f61de3b..df57e49ed4ef7082f6446931ac5d8141d376f595 100644 (file)
@@ -50,6 +50,7 @@ enum ci_hw_regs {
        OP_USBINTR,
        OP_DEVICEADDR,
        OP_ENDPTLISTADDR,
+       OP_TTCTRL,
        OP_PORTSC,
        OP_DEVLC,
        OP_OTGSC,
index 3ad48e1c0c57e1722311c8393ad3bd21712fa1e7..b0d01f26cd5e7b8ff46cd01ebec8e71a3e1e46aa 100644 (file)
@@ -84,6 +84,7 @@ static const u8 ci_regs_nolpm[] = {
        [OP_USBINTR]            = 0x08U,
        [OP_DEVICEADDR]         = 0x14U,
        [OP_ENDPTLISTADDR]      = 0x18U,
+       [OP_TTCTRL]             = 0x1CU,
        [OP_PORTSC]             = 0x44U,
        [OP_DEVLC]              = 0x84U,
        [OP_OTGSC]              = 0x64U,
@@ -106,6 +107,7 @@ static const u8 ci_regs_lpm[] = {
        [OP_USBINTR]            = 0x08U,
        [OP_DEVICEADDR]         = 0x14U,
        [OP_ENDPTLISTADDR]      = 0x18U,
+       [OP_TTCTRL]             = 0x1CU,
        [OP_PORTSC]             = 0x44U,
        [OP_DEVLC]              = 0x84U,
        [OP_OTGSC]              = 0xC4U,
index 7161439def19aa265c9f36530d3d97d63ecc51a7..b01716c8c66b456fb8f000bc744e08648987fdf9 100644 (file)
@@ -159,6 +159,9 @@ static int host_start(struct ci_hdrc *ci)
        if (ci->platdata->flags & CI_HDRC_FORCE_FULLSPEED)
                hw_write(ci, OP_PORTSC, PORTSC_PFSC, PORTSC_PFSC);
 
+       if (ci->platdata->flags & CI_HDRC_SET_NON_ZERO_TTHA)
+               hw_write(ci, OP_TTCTRL, TTCTRL_TTHA_MASK, TTCTRL_TTHA);
+
        return ret;
 
 disable_reg:
index ab94f78c4dd15ee4554a4eff996c862b7a6fd869..d1e1285a971dffc60f00ba5196d29d523a41cfdf 100644 (file)
@@ -29,6 +29,7 @@ struct ci_hdrc_platform_data {
 #define CI_HDRC_IMX28_WRITE_FIX                BIT(5)
 #define CI_HDRC_FORCE_FULLSPEED                BIT(6)
 #define CI_HDRC_TURN_VBUS_EARLY_ON     BIT(7)
+#define CI_HDRC_SET_NON_ZERO_TTHA      BIT(8)
        enum usb_dr_mode        dr_mode;
 #define CI_HDRC_CONTROLLER_RESET_EVENT         0
 #define CI_HDRC_CONTROLLER_STOPPED_EVENT       1