diff options
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r-- | drivers/usb/host/xhci.c | 251 |
1 files changed, 182 insertions, 69 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index b4aa79d154b2..8be34f838bd4 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -218,7 +218,7 @@ static int xhci_setup_msi(struct xhci_hcd *xhci) | |||
218 | return ret; | 218 | return ret; |
219 | } | 219 | } |
220 | 220 | ||
221 | ret = request_irq(pdev->irq, (irq_handler_t)xhci_msi_irq, | 221 | ret = request_irq(pdev->irq, xhci_msi_irq, |
222 | 0, "xhci_hcd", xhci_to_hcd(xhci)); | 222 | 0, "xhci_hcd", xhci_to_hcd(xhci)); |
223 | if (ret) { | 223 | if (ret) { |
224 | xhci_dbg(xhci, "disable MSI interrupt\n"); | 224 | xhci_dbg(xhci, "disable MSI interrupt\n"); |
@@ -290,7 +290,7 @@ static int xhci_setup_msix(struct xhci_hcd *xhci) | |||
290 | 290 | ||
291 | for (i = 0; i < xhci->msix_count; i++) { | 291 | for (i = 0; i < xhci->msix_count; i++) { |
292 | ret = request_irq(xhci->msix_entries[i].vector, | 292 | ret = request_irq(xhci->msix_entries[i].vector, |
293 | (irq_handler_t)xhci_msi_irq, | 293 | xhci_msi_irq, |
294 | 0, "xhci_hcd", xhci_to_hcd(xhci)); | 294 | 0, "xhci_hcd", xhci_to_hcd(xhci)); |
295 | if (ret) | 295 | if (ret) |
296 | goto disable_msix; | 296 | goto disable_msix; |
@@ -1111,6 +1111,16 @@ unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc) | |||
1111 | return index; | 1111 | return index; |
1112 | } | 1112 | } |
1113 | 1113 | ||
1114 | /* The reverse operation to xhci_get_endpoint_index. Calculate the USB endpoint | ||
1115 | * address from the XHCI endpoint index. | ||
1116 | */ | ||
1117 | unsigned int xhci_get_endpoint_address(unsigned int ep_index) | ||
1118 | { | ||
1119 | unsigned int number = DIV_ROUND_UP(ep_index, 2); | ||
1120 | unsigned int direction = ep_index % 2 ? USB_DIR_OUT : USB_DIR_IN; | ||
1121 | return direction | number; | ||
1122 | } | ||
1123 | |||
1114 | /* Find the flag for this endpoint (for use in the control context). Use the | 1124 | /* Find the flag for this endpoint (for use in the control context). Use the |
1115 | * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is | 1125 | * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is |
1116 | * bit 1, etc. | 1126 | * bit 1, etc. |
@@ -3805,6 +3815,56 @@ int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1) | |||
3805 | return raw_port; | 3815 | return raw_port; |
3806 | } | 3816 | } |
3807 | 3817 | ||
3818 | /* | ||
3819 | * Issue an Evaluate Context command to change the Maximum Exit Latency in the | ||
3820 | * slot context. If that succeeds, store the new MEL in the xhci_virt_device. | ||
3821 | */ | ||
3822 | static int xhci_change_max_exit_latency(struct xhci_hcd *xhci, | ||
3823 | struct usb_device *udev, u16 max_exit_latency) | ||
3824 | { | ||
3825 | struct xhci_virt_device *virt_dev; | ||
3826 | struct xhci_command *command; | ||
3827 | struct xhci_input_control_ctx *ctrl_ctx; | ||
3828 | struct xhci_slot_ctx *slot_ctx; | ||
3829 | unsigned long flags; | ||
3830 | int ret; | ||
3831 | |||
3832 | spin_lock_irqsave(&xhci->lock, flags); | ||
3833 | if (max_exit_latency == xhci->devs[udev->slot_id]->current_mel) { | ||
3834 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
3835 | return 0; | ||
3836 | } | ||
3837 | |||
3838 | /* Attempt to issue an Evaluate Context command to change the MEL. */ | ||
3839 | virt_dev = xhci->devs[udev->slot_id]; | ||
3840 | command = xhci->lpm_command; | ||
3841 | xhci_slot_copy(xhci, command->in_ctx, virt_dev->out_ctx); | ||
3842 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
3843 | |||
3844 | ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); | ||
3845 | ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG); | ||
3846 | slot_ctx = xhci_get_slot_ctx(xhci, command->in_ctx); | ||
3847 | slot_ctx->dev_info2 &= cpu_to_le32(~((u32) MAX_EXIT)); | ||
3848 | slot_ctx->dev_info2 |= cpu_to_le32(max_exit_latency); | ||
3849 | |||
3850 | xhci_dbg(xhci, "Set up evaluate context for LPM MEL change.\n"); | ||
3851 | xhci_dbg(xhci, "Slot %u Input Context:\n", udev->slot_id); | ||
3852 | xhci_dbg_ctx(xhci, command->in_ctx, 0); | ||
3853 | |||
3854 | /* Issue and wait for the evaluate context command. */ | ||
3855 | ret = xhci_configure_endpoint(xhci, udev, command, | ||
3856 | true, true); | ||
3857 | xhci_dbg(xhci, "Slot %u Output Context:\n", udev->slot_id); | ||
3858 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, 0); | ||
3859 | |||
3860 | if (!ret) { | ||
3861 | spin_lock_irqsave(&xhci->lock, flags); | ||
3862 | virt_dev->current_mel = max_exit_latency; | ||
3863 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
3864 | } | ||
3865 | return ret; | ||
3866 | } | ||
3867 | |||
3808 | #ifdef CONFIG_PM_RUNTIME | 3868 | #ifdef CONFIG_PM_RUNTIME |
3809 | 3869 | ||
3810 | /* BESL to HIRD Encoding array for USB2 LPM */ | 3870 | /* BESL to HIRD Encoding array for USB2 LPM */ |
@@ -3846,6 +3906,28 @@ static int xhci_calculate_hird_besl(struct xhci_hcd *xhci, | |||
3846 | return besl; | 3906 | return besl; |
3847 | } | 3907 | } |
3848 | 3908 | ||
3909 | /* Calculate BESLD, L1 timeout and HIRDM for USB2 PORTHLPMC */ | ||
3910 | static int xhci_calculate_usb2_hw_lpm_params(struct usb_device *udev) | ||
3911 | { | ||
3912 | u32 field; | ||
3913 | int l1; | ||
3914 | int besld = 0; | ||
3915 | int hirdm = 0; | ||
3916 | |||
3917 | field = le32_to_cpu(udev->bos->ext_cap->bmAttributes); | ||
3918 | |||
3919 | /* xHCI l1 is set in steps of 256us, xHCI 1.0 section 5.4.11.2 */ | ||
3920 | l1 = udev->l1_params.timeout / 256; | ||
3921 | |||
3922 | /* device has preferred BESLD */ | ||
3923 | if (field & USB_BESL_DEEP_VALID) { | ||
3924 | besld = USB_GET_BESL_DEEP(field); | ||
3925 | hirdm = 1; | ||
3926 | } | ||
3927 | |||
3928 | return PORT_BESLD(besld) | PORT_L1_TIMEOUT(l1) | PORT_HIRDM(hirdm); | ||
3929 | } | ||
3930 | |||
3849 | static int xhci_usb2_software_lpm_test(struct usb_hcd *hcd, | 3931 | static int xhci_usb2_software_lpm_test(struct usb_hcd *hcd, |
3850 | struct usb_device *udev) | 3932 | struct usb_device *udev) |
3851 | { | 3933 | { |
@@ -3901,7 +3983,7 @@ static int xhci_usb2_software_lpm_test(struct usb_hcd *hcd, | |||
3901 | * Check device's USB 2.0 extension descriptor to determine whether | 3983 | * Check device's USB 2.0 extension descriptor to determine whether |
3902 | * HIRD or BESL shoule be used. See USB2.0 LPM errata. | 3984 | * HIRD or BESL shoule be used. See USB2.0 LPM errata. |
3903 | */ | 3985 | */ |
3904 | pm_addr = port_array[port_num] + 1; | 3986 | pm_addr = port_array[port_num] + PORTPMSC; |
3905 | hird = xhci_calculate_hird_besl(xhci, udev); | 3987 | hird = xhci_calculate_hird_besl(xhci, udev); |
3906 | temp = PORT_L1DS(udev->slot_id) | PORT_HIRD(hird); | 3988 | temp = PORT_L1DS(udev->slot_id) | PORT_HIRD(hird); |
3907 | xhci_writel(xhci, temp, pm_addr); | 3989 | xhci_writel(xhci, temp, pm_addr); |
@@ -3978,11 +4060,12 @@ int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd, | |||
3978 | { | 4060 | { |
3979 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 4061 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
3980 | __le32 __iomem **port_array; | 4062 | __le32 __iomem **port_array; |
3981 | __le32 __iomem *pm_addr; | 4063 | __le32 __iomem *pm_addr, *hlpm_addr; |
3982 | u32 temp; | 4064 | u32 pm_val, hlpm_val, field; |
3983 | unsigned int port_num; | 4065 | unsigned int port_num; |
3984 | unsigned long flags; | 4066 | unsigned long flags; |
3985 | int hird; | 4067 | int hird, exit_latency; |
4068 | int ret; | ||
3986 | 4069 | ||
3987 | if (hcd->speed == HCD_USB3 || !xhci->hw_lpm_support || | 4070 | if (hcd->speed == HCD_USB3 || !xhci->hw_lpm_support || |
3988 | !udev->lpm_capable) | 4071 | !udev->lpm_capable) |
@@ -3999,40 +4082,120 @@ int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd, | |||
3999 | 4082 | ||
4000 | port_array = xhci->usb2_ports; | 4083 | port_array = xhci->usb2_ports; |
4001 | port_num = udev->portnum - 1; | 4084 | port_num = udev->portnum - 1; |
4002 | pm_addr = port_array[port_num] + 1; | 4085 | pm_addr = port_array[port_num] + PORTPMSC; |
4003 | temp = xhci_readl(xhci, pm_addr); | 4086 | pm_val = xhci_readl(xhci, pm_addr); |
4087 | hlpm_addr = port_array[port_num] + PORTHLPMC; | ||
4088 | field = le32_to_cpu(udev->bos->ext_cap->bmAttributes); | ||
4004 | 4089 | ||
4005 | xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n", | 4090 | xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n", |
4006 | enable ? "enable" : "disable", port_num); | 4091 | enable ? "enable" : "disable", port_num); |
4007 | 4092 | ||
4008 | hird = xhci_calculate_hird_besl(xhci, udev); | ||
4009 | |||
4010 | if (enable) { | 4093 | if (enable) { |
4011 | temp &= ~PORT_HIRD_MASK; | 4094 | /* Host supports BESL timeout instead of HIRD */ |
4012 | temp |= PORT_HIRD(hird) | PORT_RWE; | 4095 | if (udev->usb2_hw_lpm_besl_capable) { |
4013 | xhci_writel(xhci, temp, pm_addr); | 4096 | /* if device doesn't have a preferred BESL value use a |
4014 | temp = xhci_readl(xhci, pm_addr); | 4097 | * default one which works with mixed HIRD and BESL |
4015 | temp |= PORT_HLE; | 4098 | * systems. See XHCI_DEFAULT_BESL definition in xhci.h |
4016 | xhci_writel(xhci, temp, pm_addr); | 4099 | */ |
4100 | if ((field & USB_BESL_SUPPORT) && | ||
4101 | (field & USB_BESL_BASELINE_VALID)) | ||
4102 | hird = USB_GET_BESL_BASELINE(field); | ||
4103 | else | ||
4104 | hird = udev->l1_params.besl; | ||
4105 | |||
4106 | exit_latency = xhci_besl_encoding[hird]; | ||
4107 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
4108 | |||
4109 | /* USB 3.0 code dedicate one xhci->lpm_command->in_ctx | ||
4110 | * input context for link powermanagement evaluate | ||
4111 | * context commands. It is protected by hcd->bandwidth | ||
4112 | * mutex and is shared by all devices. We need to set | ||
4113 | * the max ext latency in USB 2 BESL LPM as well, so | ||
4114 | * use the same mutex and xhci_change_max_exit_latency() | ||
4115 | */ | ||
4116 | mutex_lock(hcd->bandwidth_mutex); | ||
4117 | ret = xhci_change_max_exit_latency(xhci, udev, | ||
4118 | exit_latency); | ||
4119 | mutex_unlock(hcd->bandwidth_mutex); | ||
4120 | |||
4121 | if (ret < 0) | ||
4122 | return ret; | ||
4123 | spin_lock_irqsave(&xhci->lock, flags); | ||
4124 | |||
4125 | hlpm_val = xhci_calculate_usb2_hw_lpm_params(udev); | ||
4126 | xhci_writel(xhci, hlpm_val, hlpm_addr); | ||
4127 | /* flush write */ | ||
4128 | xhci_readl(xhci, hlpm_addr); | ||
4129 | } else { | ||
4130 | hird = xhci_calculate_hird_besl(xhci, udev); | ||
4131 | } | ||
4132 | |||
4133 | pm_val &= ~PORT_HIRD_MASK; | ||
4134 | pm_val |= PORT_HIRD(hird) | PORT_RWE; | ||
4135 | xhci_writel(xhci, pm_val, pm_addr); | ||
4136 | pm_val = xhci_readl(xhci, pm_addr); | ||
4137 | pm_val |= PORT_HLE; | ||
4138 | xhci_writel(xhci, pm_val, pm_addr); | ||
4139 | /* flush write */ | ||
4140 | xhci_readl(xhci, pm_addr); | ||
4017 | } else { | 4141 | } else { |
4018 | temp &= ~(PORT_HLE | PORT_RWE | PORT_HIRD_MASK); | 4142 | pm_val &= ~(PORT_HLE | PORT_RWE | PORT_HIRD_MASK); |
4019 | xhci_writel(xhci, temp, pm_addr); | 4143 | xhci_writel(xhci, pm_val, pm_addr); |
4144 | /* flush write */ | ||
4145 | xhci_readl(xhci, pm_addr); | ||
4146 | if (udev->usb2_hw_lpm_besl_capable) { | ||
4147 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
4148 | mutex_lock(hcd->bandwidth_mutex); | ||
4149 | xhci_change_max_exit_latency(xhci, udev, 0); | ||
4150 | mutex_unlock(hcd->bandwidth_mutex); | ||
4151 | return 0; | ||
4152 | } | ||
4020 | } | 4153 | } |
4021 | 4154 | ||
4022 | spin_unlock_irqrestore(&xhci->lock, flags); | 4155 | spin_unlock_irqrestore(&xhci->lock, flags); |
4023 | return 0; | 4156 | return 0; |
4024 | } | 4157 | } |
4025 | 4158 | ||
4159 | /* check if a usb2 port supports a given extened capability protocol | ||
4160 | * only USB2 ports extended protocol capability values are cached. | ||
4161 | * Return 1 if capability is supported | ||
4162 | */ | ||
4163 | static int xhci_check_usb2_port_capability(struct xhci_hcd *xhci, int port, | ||
4164 | unsigned capability) | ||
4165 | { | ||
4166 | u32 port_offset, port_count; | ||
4167 | int i; | ||
4168 | |||
4169 | for (i = 0; i < xhci->num_ext_caps; i++) { | ||
4170 | if (xhci->ext_caps[i] & capability) { | ||
4171 | /* port offsets starts at 1 */ | ||
4172 | port_offset = XHCI_EXT_PORT_OFF(xhci->ext_caps[i]) - 1; | ||
4173 | port_count = XHCI_EXT_PORT_COUNT(xhci->ext_caps[i]); | ||
4174 | if (port >= port_offset && | ||
4175 | port < port_offset + port_count) | ||
4176 | return 1; | ||
4177 | } | ||
4178 | } | ||
4179 | return 0; | ||
4180 | } | ||
4181 | |||
4026 | int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev) | 4182 | int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev) |
4027 | { | 4183 | { |
4028 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 4184 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
4029 | int ret; | 4185 | int ret; |
4186 | int portnum = udev->portnum - 1; | ||
4030 | 4187 | ||
4031 | ret = xhci_usb2_software_lpm_test(hcd, udev); | 4188 | ret = xhci_usb2_software_lpm_test(hcd, udev); |
4032 | if (!ret) { | 4189 | if (!ret) { |
4033 | xhci_dbg(xhci, "software LPM test succeed\n"); | 4190 | xhci_dbg(xhci, "software LPM test succeed\n"); |
4034 | if (xhci->hw_lpm_support == 1) { | 4191 | if (xhci->hw_lpm_support == 1 && |
4192 | xhci_check_usb2_port_capability(xhci, portnum, XHCI_HLC)) { | ||
4035 | udev->usb2_hw_lpm_capable = 1; | 4193 | udev->usb2_hw_lpm_capable = 1; |
4194 | udev->l1_params.timeout = XHCI_L1_TIMEOUT; | ||
4195 | udev->l1_params.besl = XHCI_DEFAULT_BESL; | ||
4196 | if (xhci_check_usb2_port_capability(xhci, portnum, | ||
4197 | XHCI_BLC)) | ||
4198 | udev->usb2_hw_lpm_besl_capable = 1; | ||
4036 | ret = xhci_set_usb2_hardware_lpm(hcd, udev, 1); | 4199 | ret = xhci_set_usb2_hardware_lpm(hcd, udev, 1); |
4037 | if (!ret) | 4200 | if (!ret) |
4038 | udev->usb2_hw_lpm_enabled = 1; | 4201 | udev->usb2_hw_lpm_enabled = 1; |
@@ -4363,56 +4526,6 @@ static u16 xhci_calculate_lpm_timeout(struct usb_hcd *hcd, | |||
4363 | return timeout; | 4526 | return timeout; |
4364 | } | 4527 | } |
4365 | 4528 | ||
4366 | /* | ||
4367 | * Issue an Evaluate Context command to change the Maximum Exit Latency in the | ||
4368 | * slot context. If that succeeds, store the new MEL in the xhci_virt_device. | ||
4369 | */ | ||
4370 | static int xhci_change_max_exit_latency(struct xhci_hcd *xhci, | ||
4371 | struct usb_device *udev, u16 max_exit_latency) | ||
4372 | { | ||
4373 | struct xhci_virt_device *virt_dev; | ||
4374 | struct xhci_command *command; | ||
4375 | struct xhci_input_control_ctx *ctrl_ctx; | ||
4376 | struct xhci_slot_ctx *slot_ctx; | ||
4377 | unsigned long flags; | ||
4378 | int ret; | ||
4379 | |||
4380 | spin_lock_irqsave(&xhci->lock, flags); | ||
4381 | if (max_exit_latency == xhci->devs[udev->slot_id]->current_mel) { | ||
4382 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
4383 | return 0; | ||
4384 | } | ||
4385 | |||
4386 | /* Attempt to issue an Evaluate Context command to change the MEL. */ | ||
4387 | virt_dev = xhci->devs[udev->slot_id]; | ||
4388 | command = xhci->lpm_command; | ||
4389 | xhci_slot_copy(xhci, command->in_ctx, virt_dev->out_ctx); | ||
4390 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
4391 | |||
4392 | ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); | ||
4393 | ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG); | ||
4394 | slot_ctx = xhci_get_slot_ctx(xhci, command->in_ctx); | ||
4395 | slot_ctx->dev_info2 &= cpu_to_le32(~((u32) MAX_EXIT)); | ||
4396 | slot_ctx->dev_info2 |= cpu_to_le32(max_exit_latency); | ||
4397 | |||
4398 | xhci_dbg(xhci, "Set up evaluate context for LPM MEL change.\n"); | ||
4399 | xhci_dbg(xhci, "Slot %u Input Context:\n", udev->slot_id); | ||
4400 | xhci_dbg_ctx(xhci, command->in_ctx, 0); | ||
4401 | |||
4402 | /* Issue and wait for the evaluate context command. */ | ||
4403 | ret = xhci_configure_endpoint(xhci, udev, command, | ||
4404 | true, true); | ||
4405 | xhci_dbg(xhci, "Slot %u Output Context:\n", udev->slot_id); | ||
4406 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, 0); | ||
4407 | |||
4408 | if (!ret) { | ||
4409 | spin_lock_irqsave(&xhci->lock, flags); | ||
4410 | virt_dev->current_mel = max_exit_latency; | ||
4411 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
4412 | } | ||
4413 | return ret; | ||
4414 | } | ||
4415 | |||
4416 | static int calculate_max_exit_latency(struct usb_device *udev, | 4529 | static int calculate_max_exit_latency(struct usb_device *udev, |
4417 | enum usb3_link_state state_changed, | 4530 | enum usb3_link_state state_changed, |
4418 | u16 hub_encoded_timeout) | 4531 | u16 hub_encoded_timeout) |