diff options
-rw-r--r-- | Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt | 20 | ||||
-rw-r--r-- | drivers/usb/chipidea/bits.h | 12 | ||||
-rw-r--r-- | drivers/usb/chipidea/ci.h | 4 | ||||
-rw-r--r-- | drivers/usb/chipidea/ci_hdrc_imx.c | 17 | ||||
-rw-r--r-- | drivers/usb/chipidea/core.c | 113 | ||||
-rw-r--r-- | drivers/usb/chipidea/debug.c | 6 | ||||
-rw-r--r-- | drivers/usb/chipidea/host.c | 26 | ||||
-rw-r--r-- | drivers/usb/chipidea/otg_fsm.c | 1 | ||||
-rw-r--r-- | drivers/usb/chipidea/udc.c | 9 | ||||
-rw-r--r-- | drivers/usb/chipidea/usbmisc_imx.c | 12 | ||||
-rw-r--r-- | include/linux/usb/chipidea.h | 14 |
11 files changed, 202 insertions, 32 deletions
diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt index 553e2fae3a76..d71ef07bca5d 100644 --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt | |||
@@ -30,6 +30,21 @@ Optional properties: | |||
30 | argument that indicate usb controller index | 30 | argument that indicate usb controller index |
31 | - disable-over-current: (FSL only) disable over current detect | 31 | - disable-over-current: (FSL only) disable over current detect |
32 | - external-vbus-divider: (FSL only) enables off-chip resistor divider for Vbus | 32 | - external-vbus-divider: (FSL only) enables off-chip resistor divider for Vbus |
33 | - itc-setting: interrupt threshold control register control, the setting | ||
34 | should be aligned with ITC bits at register USBCMD. | ||
35 | - ahb-burst-config: it is vendor dependent, the required value should be | ||
36 | aligned with AHBBRST at SBUSCFG, the range is from 0x0 to 0x7. This | ||
37 | property is used to change AHB burst configuration, check the chipidea | ||
38 | spec for meaning of each value. If this property is not existed, it | ||
39 | will use the reset value. | ||
40 | - tx-burst-size-dword: it is vendor dependent, the tx burst size in dword | ||
41 | (4 bytes), This register represents the maximum length of a the burst | ||
42 | in 32-bit words while moving data from system memory to the USB | ||
43 | bus, changing this value takes effect only the SBUSCFG.AHBBRST is 0. | ||
44 | - rx-burst-size-dword: it is vendor dependent, the rx burst size in dword | ||
45 | (4 bytes), This register represents the maximum length of a the burst | ||
46 | in 32-bit words while moving data from the USB bus to system memory, | ||
47 | changing this value takes effect only the SBUSCFG.AHBBRST is 0. | ||
33 | 48 | ||
34 | Example: | 49 | Example: |
35 | 50 | ||
@@ -41,4 +56,9 @@ Example: | |||
41 | phys = <&usb_phy0>; | 56 | phys = <&usb_phy0>; |
42 | phy-names = "usb-phy"; | 57 | phy-names = "usb-phy"; |
43 | vbus-supply = <®_usb0_vbus>; | 58 | vbus-supply = <®_usb0_vbus>; |
59 | gadget-itc-setting = <0x4>; /* 4 micro-frames */ | ||
60 | /* Incremental burst of unspecified length */ | ||
61 | ahb-burst-config = <0x0>; | ||
62 | tx-burst-size-dword = <0x10>; /* 64 bytes */ | ||
63 | rx-burst-size-dword = <0x10>; | ||
44 | }; | 64 | }; |
diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h index 3cb9bda51ddf..e462f55c8b99 100644 --- a/drivers/usb/chipidea/bits.h +++ b/drivers/usb/chipidea/bits.h | |||
@@ -25,6 +25,9 @@ | |||
25 | #define VERSION (0xF << 25) | 25 | #define VERSION (0xF << 25) |
26 | #define CIVERSION (0x7 << 29) | 26 | #define CIVERSION (0x7 << 29) |
27 | 27 | ||
28 | /* SBUSCFG */ | ||
29 | #define AHBBRST_MASK 0x7 | ||
30 | |||
28 | /* HCCPARAMS */ | 31 | /* HCCPARAMS */ |
29 | #define HCCPARAMS_LEN BIT(17) | 32 | #define HCCPARAMS_LEN BIT(17) |
30 | 33 | ||
@@ -53,6 +56,15 @@ | |||
53 | #define DEVICEADDR_USBADRA BIT(24) | 56 | #define DEVICEADDR_USBADRA BIT(24) |
54 | #define DEVICEADDR_USBADR (0x7FUL << 25) | 57 | #define DEVICEADDR_USBADR (0x7FUL << 25) |
55 | 58 | ||
59 | /* TTCTRL */ | ||
60 | #define TTCTRL_TTHA_MASK (0x7fUL << 24) | ||
61 | /* Set non-zero value for internal TT Hub address representation */ | ||
62 | #define TTCTRL_TTHA (0x7fUL << 24) | ||
63 | |||
64 | /* BURSTSIZE */ | ||
65 | #define RX_BURST_MASK 0xff | ||
66 | #define TX_BURST_MASK 0xff00 | ||
67 | |||
56 | /* PORTSC */ | 68 | /* PORTSC */ |
57 | #define PORTSC_CCS BIT(0) | 69 | #define PORTSC_CCS BIT(0) |
58 | #define PORTSC_CSC BIT(1) | 70 | #define PORTSC_CSC BIT(1) |
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index f243f0b431c3..41d7cf6d63ba 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h | |||
@@ -50,6 +50,8 @@ enum ci_hw_regs { | |||
50 | OP_USBINTR, | 50 | OP_USBINTR, |
51 | OP_DEVICEADDR, | 51 | OP_DEVICEADDR, |
52 | OP_ENDPTLISTADDR, | 52 | OP_ENDPTLISTADDR, |
53 | OP_TTCTRL, | ||
54 | OP_BURSTSIZE, | ||
53 | OP_PORTSC, | 55 | OP_PORTSC, |
54 | OP_DEVLC, | 56 | OP_DEVLC, |
55 | OP_OTGSC, | 57 | OP_OTGSC, |
@@ -429,4 +431,6 @@ u8 hw_port_test_get(struct ci_hdrc *ci); | |||
429 | int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask, | 431 | int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask, |
430 | u32 value, unsigned int timeout_ms); | 432 | u32 value, unsigned int timeout_ms); |
431 | 433 | ||
434 | void ci_platform_configure(struct ci_hdrc *ci); | ||
435 | |||
432 | #endif /* __DRIVERS_USB_CHIPIDEA_CI_H */ | 436 | #endif /* __DRIVERS_USB_CHIPIDEA_CI_H */ |
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 389f0e034259..867e9f3f3859 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c | |||
@@ -29,26 +29,31 @@ struct ci_hdrc_imx_platform_flag { | |||
29 | }; | 29 | }; |
30 | 30 | ||
31 | static const struct ci_hdrc_imx_platform_flag imx27_usb_data = { | 31 | static const struct ci_hdrc_imx_platform_flag imx27_usb_data = { |
32 | CI_HDRC_DISABLE_STREAMING, | ||
32 | }; | 33 | }; |
33 | 34 | ||
34 | static const struct ci_hdrc_imx_platform_flag imx28_usb_data = { | 35 | static const struct ci_hdrc_imx_platform_flag imx28_usb_data = { |
35 | .flags = CI_HDRC_IMX28_WRITE_FIX | | 36 | .flags = CI_HDRC_IMX28_WRITE_FIX | |
36 | CI_HDRC_TURN_VBUS_EARLY_ON, | 37 | CI_HDRC_TURN_VBUS_EARLY_ON | |
38 | CI_HDRC_DISABLE_STREAMING, | ||
37 | }; | 39 | }; |
38 | 40 | ||
39 | static const struct ci_hdrc_imx_platform_flag imx6q_usb_data = { | 41 | static const struct ci_hdrc_imx_platform_flag imx6q_usb_data = { |
40 | .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | | 42 | .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | |
41 | CI_HDRC_TURN_VBUS_EARLY_ON, | 43 | CI_HDRC_TURN_VBUS_EARLY_ON | |
44 | CI_HDRC_DISABLE_STREAMING, | ||
42 | }; | 45 | }; |
43 | 46 | ||
44 | static const struct ci_hdrc_imx_platform_flag imx6sl_usb_data = { | 47 | static const struct ci_hdrc_imx_platform_flag imx6sl_usb_data = { |
45 | .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | | 48 | .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | |
46 | CI_HDRC_TURN_VBUS_EARLY_ON, | 49 | CI_HDRC_TURN_VBUS_EARLY_ON | |
50 | CI_HDRC_DISABLE_HOST_STREAMING, | ||
47 | }; | 51 | }; |
48 | 52 | ||
49 | static const struct ci_hdrc_imx_platform_flag imx6sx_usb_data = { | 53 | static const struct ci_hdrc_imx_platform_flag imx6sx_usb_data = { |
50 | .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | | 54 | .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | |
51 | CI_HDRC_TURN_VBUS_EARLY_ON, | 55 | CI_HDRC_TURN_VBUS_EARLY_ON | |
56 | CI_HDRC_DISABLE_HOST_STREAMING, | ||
52 | }; | 57 | }; |
53 | 58 | ||
54 | static const struct of_device_id ci_hdrc_imx_dt_ids[] = { | 59 | static const struct of_device_id ci_hdrc_imx_dt_ids[] = { |
@@ -104,7 +109,7 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev) | |||
104 | misc_pdev = of_find_device_by_node(args.np); | 109 | misc_pdev = of_find_device_by_node(args.np); |
105 | of_node_put(args.np); | 110 | of_node_put(args.np); |
106 | 111 | ||
107 | if (!misc_pdev) | 112 | if (!misc_pdev || !platform_get_drvdata(misc_pdev)) |
108 | return ERR_PTR(-EPROBE_DEFER); | 113 | return ERR_PTR(-EPROBE_DEFER); |
109 | 114 | ||
110 | data->dev = &misc_pdev->dev; | 115 | data->dev = &misc_pdev->dev; |
@@ -126,7 +131,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) | |||
126 | struct ci_hdrc_platform_data pdata = { | 131 | struct ci_hdrc_platform_data pdata = { |
127 | .name = dev_name(&pdev->dev), | 132 | .name = dev_name(&pdev->dev), |
128 | .capoffset = DEF_CAPOFFSET, | 133 | .capoffset = DEF_CAPOFFSET, |
129 | .flags = CI_HDRC_DISABLE_STREAMING, | 134 | .flags = CI_HDRC_SET_NON_ZERO_TTHA, |
130 | }; | 135 | }; |
131 | int ret; | 136 | int ret; |
132 | const struct of_device_id *of_id = | 137 | const struct of_device_id *of_id = |
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index ab6212e888e1..3feebf7f31f0 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c | |||
@@ -64,6 +64,7 @@ | |||
64 | #include <linux/of.h> | 64 | #include <linux/of.h> |
65 | #include <linux/phy.h> | 65 | #include <linux/phy.h> |
66 | #include <linux/regulator/consumer.h> | 66 | #include <linux/regulator/consumer.h> |
67 | #include <linux/usb/ehci_def.h> | ||
67 | 68 | ||
68 | #include "ci.h" | 69 | #include "ci.h" |
69 | #include "udc.h" | 70 | #include "udc.h" |
@@ -84,6 +85,8 @@ static const u8 ci_regs_nolpm[] = { | |||
84 | [OP_USBINTR] = 0x08U, | 85 | [OP_USBINTR] = 0x08U, |
85 | [OP_DEVICEADDR] = 0x14U, | 86 | [OP_DEVICEADDR] = 0x14U, |
86 | [OP_ENDPTLISTADDR] = 0x18U, | 87 | [OP_ENDPTLISTADDR] = 0x18U, |
88 | [OP_TTCTRL] = 0x1CU, | ||
89 | [OP_BURSTSIZE] = 0x20U, | ||
87 | [OP_PORTSC] = 0x44U, | 90 | [OP_PORTSC] = 0x44U, |
88 | [OP_DEVLC] = 0x84U, | 91 | [OP_DEVLC] = 0x84U, |
89 | [OP_OTGSC] = 0x64U, | 92 | [OP_OTGSC] = 0x64U, |
@@ -106,6 +109,8 @@ static const u8 ci_regs_lpm[] = { | |||
106 | [OP_USBINTR] = 0x08U, | 109 | [OP_USBINTR] = 0x08U, |
107 | [OP_DEVICEADDR] = 0x14U, | 110 | [OP_DEVICEADDR] = 0x14U, |
108 | [OP_ENDPTLISTADDR] = 0x18U, | 111 | [OP_ENDPTLISTADDR] = 0x18U, |
112 | [OP_TTCTRL] = 0x1CU, | ||
113 | [OP_BURSTSIZE] = 0x20U, | ||
109 | [OP_PORTSC] = 0x44U, | 114 | [OP_PORTSC] = 0x44U, |
110 | [OP_DEVLC] = 0x84U, | 115 | [OP_DEVLC] = 0x84U, |
111 | [OP_OTGSC] = 0xC4U, | 116 | [OP_OTGSC] = 0xC4U, |
@@ -118,7 +123,7 @@ static const u8 ci_regs_lpm[] = { | |||
118 | [OP_ENDPTCTRL] = 0xECU, | 123 | [OP_ENDPTCTRL] = 0xECU, |
119 | }; | 124 | }; |
120 | 125 | ||
121 | static int hw_alloc_regmap(struct ci_hdrc *ci, bool is_lpm) | 126 | static void hw_alloc_regmap(struct ci_hdrc *ci, bool is_lpm) |
122 | { | 127 | { |
123 | int i; | 128 | int i; |
124 | 129 | ||
@@ -134,7 +139,6 @@ static int hw_alloc_regmap(struct ci_hdrc *ci, bool is_lpm) | |||
134 | ? ci_regs_lpm[OP_ENDPTCTRL] | 139 | ? ci_regs_lpm[OP_ENDPTCTRL] |
135 | : ci_regs_nolpm[OP_ENDPTCTRL]); | 140 | : ci_regs_nolpm[OP_ENDPTCTRL]); |
136 | 141 | ||
137 | return 0; | ||
138 | } | 142 | } |
139 | 143 | ||
140 | static enum ci_revision ci_get_revision(struct ci_hdrc *ci) | 144 | static enum ci_revision ci_get_revision(struct ci_hdrc *ci) |
@@ -403,6 +407,55 @@ static int ci_usb_phy_init(struct ci_hdrc *ci) | |||
403 | return ret; | 407 | return ret; |
404 | } | 408 | } |
405 | 409 | ||
410 | |||
411 | /** | ||
412 | * ci_platform_configure: do controller configure | ||
413 | * @ci: the controller | ||
414 | * | ||
415 | */ | ||
416 | void ci_platform_configure(struct ci_hdrc *ci) | ||
417 | { | ||
418 | bool is_device_mode, is_host_mode; | ||
419 | |||
420 | is_device_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_DC; | ||
421 | is_host_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_HC; | ||
422 | |||
423 | if (is_device_mode && | ||
424 | (ci->platdata->flags & CI_HDRC_DISABLE_DEVICE_STREAMING)) | ||
425 | hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS); | ||
426 | |||
427 | if (is_host_mode && | ||
428 | (ci->platdata->flags & CI_HDRC_DISABLE_HOST_STREAMING)) | ||
429 | hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS); | ||
430 | |||
431 | if (ci->platdata->flags & CI_HDRC_FORCE_FULLSPEED) { | ||
432 | if (ci->hw_bank.lpm) | ||
433 | hw_write(ci, OP_DEVLC, DEVLC_PFSC, DEVLC_PFSC); | ||
434 | else | ||
435 | hw_write(ci, OP_PORTSC, PORTSC_PFSC, PORTSC_PFSC); | ||
436 | } | ||
437 | |||
438 | if (ci->platdata->flags & CI_HDRC_SET_NON_ZERO_TTHA) | ||
439 | hw_write(ci, OP_TTCTRL, TTCTRL_TTHA_MASK, TTCTRL_TTHA); | ||
440 | |||
441 | hw_write(ci, OP_USBCMD, 0xff0000, ci->platdata->itc_setting << 16); | ||
442 | |||
443 | if (ci->platdata->flags & CI_HDRC_OVERRIDE_AHB_BURST) | ||
444 | hw_write_id_reg(ci, ID_SBUSCFG, AHBBRST_MASK, | ||
445 | ci->platdata->ahb_burst_config); | ||
446 | |||
447 | /* override burst size, take effect only when ahb_burst_config is 0 */ | ||
448 | if (!hw_read_id_reg(ci, ID_SBUSCFG, AHBBRST_MASK)) { | ||
449 | if (ci->platdata->flags & CI_HDRC_OVERRIDE_TX_BURST) | ||
450 | hw_write(ci, OP_BURSTSIZE, TX_BURST_MASK, | ||
451 | ci->platdata->tx_burst_size << __ffs(TX_BURST_MASK)); | ||
452 | |||
453 | if (ci->platdata->flags & CI_HDRC_OVERRIDE_RX_BURST) | ||
454 | hw_write(ci, OP_BURSTSIZE, RX_BURST_MASK, | ||
455 | ci->platdata->rx_burst_size); | ||
456 | } | ||
457 | } | ||
458 | |||
406 | /** | 459 | /** |
407 | * hw_controller_reset: do controller reset | 460 | * hw_controller_reset: do controller reset |
408 | * @ci: the controller | 461 | * @ci: the controller |
@@ -447,16 +500,6 @@ int hw_device_reset(struct ci_hdrc *ci) | |||
447 | ci->platdata->notify_event(ci, | 500 | ci->platdata->notify_event(ci, |
448 | CI_HDRC_CONTROLLER_RESET_EVENT); | 501 | CI_HDRC_CONTROLLER_RESET_EVENT); |
449 | 502 | ||
450 | if (ci->platdata->flags & CI_HDRC_DISABLE_STREAMING) | ||
451 | hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS); | ||
452 | |||
453 | if (ci->platdata->flags & CI_HDRC_FORCE_FULLSPEED) { | ||
454 | if (ci->hw_bank.lpm) | ||
455 | hw_write(ci, OP_DEVLC, DEVLC_PFSC, DEVLC_PFSC); | ||
456 | else | ||
457 | hw_write(ci, OP_PORTSC, PORTSC_PFSC, PORTSC_PFSC); | ||
458 | } | ||
459 | |||
460 | /* USBMODE should be configured step by step */ | 503 | /* USBMODE should be configured step by step */ |
461 | hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE); | 504 | hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE); |
462 | hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_DC); | 505 | hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_DC); |
@@ -469,6 +512,8 @@ int hw_device_reset(struct ci_hdrc *ci) | |||
469 | return -ENODEV; | 512 | return -ENODEV; |
470 | } | 513 | } |
471 | 514 | ||
515 | ci_platform_configure(ci); | ||
516 | |||
472 | return 0; | 517 | return 0; |
473 | } | 518 | } |
474 | 519 | ||
@@ -606,6 +651,50 @@ static int ci_get_platdata(struct device *dev, | |||
606 | if (of_usb_get_maximum_speed(dev->of_node) == USB_SPEED_FULL) | 651 | if (of_usb_get_maximum_speed(dev->of_node) == USB_SPEED_FULL) |
607 | platdata->flags |= CI_HDRC_FORCE_FULLSPEED; | 652 | platdata->flags |= CI_HDRC_FORCE_FULLSPEED; |
608 | 653 | ||
654 | platdata->itc_setting = 1; | ||
655 | if (of_find_property(dev->of_node, "itc-setting", NULL)) { | ||
656 | ret = of_property_read_u32(dev->of_node, "itc-setting", | ||
657 | &platdata->itc_setting); | ||
658 | if (ret) { | ||
659 | dev_err(dev, | ||
660 | "failed to get itc-setting\n"); | ||
661 | return ret; | ||
662 | } | ||
663 | } | ||
664 | |||
665 | if (of_find_property(dev->of_node, "ahb-burst-config", NULL)) { | ||
666 | ret = of_property_read_u32(dev->of_node, "ahb-burst-config", | ||
667 | &platdata->ahb_burst_config); | ||
668 | if (ret) { | ||
669 | dev_err(dev, | ||
670 | "failed to get ahb-burst-config\n"); | ||
671 | return ret; | ||
672 | } | ||
673 | platdata->flags |= CI_HDRC_OVERRIDE_AHB_BURST; | ||
674 | } | ||
675 | |||
676 | if (of_find_property(dev->of_node, "tx-burst-size-dword", NULL)) { | ||
677 | ret = of_property_read_u32(dev->of_node, "tx-burst-size-dword", | ||
678 | &platdata->tx_burst_size); | ||
679 | if (ret) { | ||
680 | dev_err(dev, | ||
681 | "failed to get tx-burst-size-dword\n"); | ||
682 | return ret; | ||
683 | } | ||
684 | platdata->flags |= CI_HDRC_OVERRIDE_TX_BURST; | ||
685 | } | ||
686 | |||
687 | if (of_find_property(dev->of_node, "rx-burst-size-dword", NULL)) { | ||
688 | ret = of_property_read_u32(dev->of_node, "rx-burst-size-dword", | ||
689 | &platdata->rx_burst_size); | ||
690 | if (ret) { | ||
691 | dev_err(dev, | ||
692 | "failed to get rx-burst-size-dword\n"); | ||
693 | return ret; | ||
694 | } | ||
695 | platdata->flags |= CI_HDRC_OVERRIDE_RX_BURST; | ||
696 | } | ||
697 | |||
609 | return 0; | 698 | return 0; |
610 | } | 699 | } |
611 | 700 | ||
diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 3869c6d75515..080b7be3daf0 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c | |||
@@ -67,9 +67,11 @@ static int ci_port_test_show(struct seq_file *s, void *data) | |||
67 | unsigned long flags; | 67 | unsigned long flags; |
68 | unsigned mode; | 68 | unsigned mode; |
69 | 69 | ||
70 | pm_runtime_get_sync(ci->dev); | ||
70 | spin_lock_irqsave(&ci->lock, flags); | 71 | spin_lock_irqsave(&ci->lock, flags); |
71 | mode = hw_port_test_get(ci); | 72 | mode = hw_port_test_get(ci); |
72 | spin_unlock_irqrestore(&ci->lock, flags); | 73 | spin_unlock_irqrestore(&ci->lock, flags); |
74 | pm_runtime_put_sync(ci->dev); | ||
73 | 75 | ||
74 | seq_printf(s, "mode = %u\n", mode); | 76 | seq_printf(s, "mode = %u\n", mode); |
75 | 77 | ||
@@ -99,9 +101,11 @@ static ssize_t ci_port_test_write(struct file *file, const char __user *ubuf, | |||
99 | if (sscanf(buf, "%u", &mode) != 1) | 101 | if (sscanf(buf, "%u", &mode) != 1) |
100 | return -EINVAL; | 102 | return -EINVAL; |
101 | 103 | ||
104 | pm_runtime_get_sync(ci->dev); | ||
102 | spin_lock_irqsave(&ci->lock, flags); | 105 | spin_lock_irqsave(&ci->lock, flags); |
103 | ret = hw_port_test_set(ci, mode); | 106 | ret = hw_port_test_set(ci, mode); |
104 | spin_unlock_irqrestore(&ci->lock, flags); | 107 | spin_unlock_irqrestore(&ci->lock, flags); |
108 | pm_runtime_put_sync(ci->dev); | ||
105 | 109 | ||
106 | return ret ? ret : count; | 110 | return ret ? ret : count; |
107 | } | 111 | } |
@@ -317,8 +321,10 @@ static ssize_t ci_role_write(struct file *file, const char __user *ubuf, | |||
317 | if (role == CI_ROLE_END || role == ci->role) | 321 | if (role == CI_ROLE_END || role == ci->role) |
318 | return -EINVAL; | 322 | return -EINVAL; |
319 | 323 | ||
324 | pm_runtime_get_sync(ci->dev); | ||
320 | ci_role_stop(ci); | 325 | ci_role_stop(ci); |
321 | ret = ci_role_start(ci, role); | 326 | ret = ci_role_start(ci, role); |
327 | pm_runtime_put_sync(ci->dev); | ||
322 | 328 | ||
323 | return ret ? ret : count; | 329 | return ret ? ret : count; |
324 | } | 330 | } |
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index 7161439def19..3d24304405b3 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c | |||
@@ -37,15 +37,14 @@ static int (*orig_bus_suspend)(struct usb_hcd *hcd); | |||
37 | 37 | ||
38 | struct ehci_ci_priv { | 38 | struct ehci_ci_priv { |
39 | struct regulator *reg_vbus; | 39 | struct regulator *reg_vbus; |
40 | struct ci_hdrc *ci; | ||
41 | }; | 40 | }; |
42 | 41 | ||
43 | static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable) | 42 | static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable) |
44 | { | 43 | { |
45 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | 44 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
46 | struct ehci_ci_priv *priv = (struct ehci_ci_priv *)ehci->priv; | 45 | struct ehci_ci_priv *priv = (struct ehci_ci_priv *)ehci->priv; |
47 | struct ci_hdrc *ci = priv->ci; | ||
48 | struct device *dev = hcd->self.controller; | 46 | struct device *dev = hcd->self.controller; |
47 | struct ci_hdrc *ci = dev_get_drvdata(dev); | ||
49 | int ret = 0; | 48 | int ret = 0; |
50 | int port = HCS_N_PORTS(ehci->hcs_params); | 49 | int port = HCS_N_PORTS(ehci->hcs_params); |
51 | 50 | ||
@@ -78,9 +77,25 @@ static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable) | |||
78 | return 0; | 77 | return 0; |
79 | }; | 78 | }; |
80 | 79 | ||
80 | static int ehci_ci_reset(struct usb_hcd *hcd) | ||
81 | { | ||
82 | struct device *dev = hcd->self.controller; | ||
83 | struct ci_hdrc *ci = dev_get_drvdata(dev); | ||
84 | int ret; | ||
85 | |||
86 | ret = ehci_setup(hcd); | ||
87 | if (ret) | ||
88 | return ret; | ||
89 | |||
90 | ci_platform_configure(ci); | ||
91 | |||
92 | return ret; | ||
93 | } | ||
94 | |||
81 | static const struct ehci_driver_overrides ehci_ci_overrides = { | 95 | static const struct ehci_driver_overrides ehci_ci_overrides = { |
82 | .extra_priv_size = sizeof(struct ehci_ci_priv), | 96 | .extra_priv_size = sizeof(struct ehci_ci_priv), |
83 | .port_power = ehci_ci_portpower, | 97 | .port_power = ehci_ci_portpower, |
98 | .reset = ehci_ci_reset, | ||
84 | }; | 99 | }; |
85 | 100 | ||
86 | static irqreturn_t host_irq(struct ci_hdrc *ci) | 101 | static irqreturn_t host_irq(struct ci_hdrc *ci) |
@@ -123,7 +138,6 @@ static int host_start(struct ci_hdrc *ci) | |||
123 | 138 | ||
124 | priv = (struct ehci_ci_priv *)ehci->priv; | 139 | priv = (struct ehci_ci_priv *)ehci->priv; |
125 | priv->reg_vbus = NULL; | 140 | priv->reg_vbus = NULL; |
126 | priv->ci = ci; | ||
127 | 141 | ||
128 | if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci)) { | 142 | if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci)) { |
129 | if (ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON) { | 143 | if (ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON) { |
@@ -153,12 +167,6 @@ static int host_start(struct ci_hdrc *ci) | |||
153 | } | 167 | } |
154 | } | 168 | } |
155 | 169 | ||
156 | if (ci->platdata->flags & CI_HDRC_DISABLE_STREAMING) | ||
157 | hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS); | ||
158 | |||
159 | if (ci->platdata->flags & CI_HDRC_FORCE_FULLSPEED) | ||
160 | hw_write(ci, OP_PORTSC, PORTSC_PFSC, PORTSC_PFSC); | ||
161 | |||
162 | return ret; | 170 | return ret; |
163 | 171 | ||
164 | disable_reg: | 172 | disable_reg: |
diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index 19d655a743b5..00ab59d45da1 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c | |||
@@ -525,7 +525,6 @@ static int ci_otg_start_host(struct otg_fsm *fsm, int on) | |||
525 | ci_role_start(ci, CI_ROLE_HOST); | 525 | ci_role_start(ci, CI_ROLE_HOST); |
526 | } else { | 526 | } else { |
527 | ci_role_stop(ci); | 527 | ci_role_stop(ci); |
528 | hw_device_reset(ci); | ||
529 | ci_role_start(ci, CI_ROLE_GADGET); | 528 | ci_role_start(ci, CI_ROLE_GADGET); |
530 | } | 529 | } |
531 | return 0; | 530 | return 0; |
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index c592b6f0fe21..a637da25dda0 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c | |||
@@ -445,7 +445,7 @@ static int _hardware_enqueue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) | |||
445 | rest -= count; | 445 | rest -= count; |
446 | } | 446 | } |
447 | 447 | ||
448 | if (hwreq->req.zero && hwreq->req.length | 448 | if (hwreq->req.zero && hwreq->req.length && hwep->dir == TX |
449 | && (hwreq->req.length % hwep->ep.maxpacket == 0)) | 449 | && (hwreq->req.length % hwep->ep.maxpacket == 0)) |
450 | add_td_to_list(hwep, hwreq, 0); | 450 | add_td_to_list(hwep, hwreq, 0); |
451 | 451 | ||
@@ -1090,6 +1090,13 @@ __acquires(ci->lock) | |||
1090 | if (ci_otg_is_fsm_mode(ci)) | 1090 | if (ci_otg_is_fsm_mode(ci)) |
1091 | err = otg_a_alt_hnp_support(ci); | 1091 | err = otg_a_alt_hnp_support(ci); |
1092 | break; | 1092 | break; |
1093 | case USB_DEVICE_A_HNP_SUPPORT: | ||
1094 | if (ci_otg_is_fsm_mode(ci)) { | ||
1095 | ci->gadget.a_hnp_support = 1; | ||
1096 | err = isr_setup_status_phase( | ||
1097 | ci); | ||
1098 | } | ||
1099 | break; | ||
1093 | default: | 1100 | default: |
1094 | goto delegate; | 1101 | goto delegate; |
1095 | } | 1102 | } |
diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index 3cefd49ddb00..5ddab30ee240 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #define MX53_USB_PHYCTRL1_PLLDIV_MASK 0x3 | 54 | #define MX53_USB_PHYCTRL1_PLLDIV_MASK 0x3 |
55 | #define MX53_USB_PLL_DIV_24_MHZ 0x01 | 55 | #define MX53_USB_PLL_DIV_24_MHZ 0x01 |
56 | 56 | ||
57 | #define MX6_BM_NON_BURST_SETTING BIT(1) | ||
57 | #define MX6_BM_OVER_CUR_DIS BIT(7) | 58 | #define MX6_BM_OVER_CUR_DIS BIT(7) |
58 | #define MX6_BM_WAKEUP_ENABLE BIT(10) | 59 | #define MX6_BM_WAKEUP_ENABLE BIT(10) |
59 | #define MX6_BM_ID_WAKEUP BIT(16) | 60 | #define MX6_BM_ID_WAKEUP BIT(16) |
@@ -255,14 +256,21 @@ static int usbmisc_imx6q_init(struct imx_usbmisc_data *data) | |||
255 | if (data->index > 3) | 256 | if (data->index > 3) |
256 | return -EINVAL; | 257 | return -EINVAL; |
257 | 258 | ||
259 | spin_lock_irqsave(&usbmisc->lock, flags); | ||
260 | |||
258 | if (data->disable_oc) { | 261 | if (data->disable_oc) { |
259 | spin_lock_irqsave(&usbmisc->lock, flags); | ||
260 | reg = readl(usbmisc->base + data->index * 4); | 262 | reg = readl(usbmisc->base + data->index * 4); |
261 | writel(reg | MX6_BM_OVER_CUR_DIS, | 263 | writel(reg | MX6_BM_OVER_CUR_DIS, |
262 | usbmisc->base + data->index * 4); | 264 | usbmisc->base + data->index * 4); |
263 | spin_unlock_irqrestore(&usbmisc->lock, flags); | ||
264 | } | 265 | } |
265 | 266 | ||
267 | /* SoC non-burst setting */ | ||
268 | reg = readl(usbmisc->base + data->index * 4); | ||
269 | writel(reg | MX6_BM_NON_BURST_SETTING, | ||
270 | usbmisc->base + data->index * 4); | ||
271 | |||
272 | spin_unlock_irqrestore(&usbmisc->lock, flags); | ||
273 | |||
266 | usbmisc_imx6q_set_wakeup(data, false); | 274 | usbmisc_imx6q_set_wakeup(data, false); |
267 | 275 | ||
268 | return 0; | 276 | return 0; |
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h index e10cefc721ad..a41833cd184c 100644 --- a/include/linux/usb/chipidea.h +++ b/include/linux/usb/chipidea.h | |||
@@ -19,8 +19,11 @@ struct ci_hdrc_platform_data { | |||
19 | enum usb_phy_interface phy_mode; | 19 | enum usb_phy_interface phy_mode; |
20 | unsigned long flags; | 20 | unsigned long flags; |
21 | #define CI_HDRC_REGS_SHARED BIT(0) | 21 | #define CI_HDRC_REGS_SHARED BIT(0) |
22 | #define CI_HDRC_DISABLE_DEVICE_STREAMING BIT(1) | ||
22 | #define CI_HDRC_SUPPORTS_RUNTIME_PM BIT(2) | 23 | #define CI_HDRC_SUPPORTS_RUNTIME_PM BIT(2) |
23 | #define CI_HDRC_DISABLE_STREAMING BIT(3) | 24 | #define CI_HDRC_DISABLE_HOST_STREAMING BIT(3) |
25 | #define CI_HDRC_DISABLE_STREAMING (CI_HDRC_DISABLE_DEVICE_STREAMING | \ | ||
26 | CI_HDRC_DISABLE_HOST_STREAMING) | ||
24 | /* | 27 | /* |
25 | * Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1, | 28 | * Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1, |
26 | * but otg is not supported (no register otgsc). | 29 | * but otg is not supported (no register otgsc). |
@@ -29,6 +32,10 @@ struct ci_hdrc_platform_data { | |||
29 | #define CI_HDRC_IMX28_WRITE_FIX BIT(5) | 32 | #define CI_HDRC_IMX28_WRITE_FIX BIT(5) |
30 | #define CI_HDRC_FORCE_FULLSPEED BIT(6) | 33 | #define CI_HDRC_FORCE_FULLSPEED BIT(6) |
31 | #define CI_HDRC_TURN_VBUS_EARLY_ON BIT(7) | 34 | #define CI_HDRC_TURN_VBUS_EARLY_ON BIT(7) |
35 | #define CI_HDRC_SET_NON_ZERO_TTHA BIT(8) | ||
36 | #define CI_HDRC_OVERRIDE_AHB_BURST BIT(9) | ||
37 | #define CI_HDRC_OVERRIDE_TX_BURST BIT(10) | ||
38 | #define CI_HDRC_OVERRIDE_RX_BURST BIT(11) | ||
32 | enum usb_dr_mode dr_mode; | 39 | enum usb_dr_mode dr_mode; |
33 | #define CI_HDRC_CONTROLLER_RESET_EVENT 0 | 40 | #define CI_HDRC_CONTROLLER_RESET_EVENT 0 |
34 | #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 | 41 | #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 |
@@ -36,6 +43,11 @@ struct ci_hdrc_platform_data { | |||
36 | struct regulator *reg_vbus; | 43 | struct regulator *reg_vbus; |
37 | struct usb_otg_caps ci_otg_caps; | 44 | struct usb_otg_caps ci_otg_caps; |
38 | bool tpl_support; | 45 | bool tpl_support; |
46 | /* interrupt threshold setting */ | ||
47 | u32 itc_setting; | ||
48 | u32 ahb_burst_config; | ||
49 | u32 tx_burst_size; | ||
50 | u32 rx_burst_size; | ||
39 | }; | 51 | }; |
40 | 52 | ||
41 | /* Default offset of capability registers */ | 53 | /* Default offset of capability registers */ |